Большая пачка обновлений

This commit is contained in:
2025-04-21 08:36:46 +04:00
parent be8963a073
commit beb61b7449
39 changed files with 1068 additions and 301 deletions
@@ -1,4 +1,6 @@
using Microsoft.EntityFrameworkCore;
using LinqToDB.Reflection;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Pf2eModel;
using Pf2eModel.Model;
@@ -13,13 +15,13 @@ using System.Text.RegularExpressions;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
internal abstract partial class AbstractProcessor(ProcessorInput input)
internal abstract partial class AbstractProcessor(AonprdProcessorInput input)
{
protected DatabaseHelper Helper = DatabaseHelper.Instance;
public readonly Pf2eDbContext Context = DatabaseHelper.DbContext;
public readonly ProcessorInput Input = input;
public readonly AonprdProcessorInput Input = input;
public Entity Entity { get; set; } = new();
@@ -27,6 +29,8 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
public abstract IEntity Object { get; }
protected abstract void Add();
public virtual void Process()
{
if (Input.GetOptional<JArray>("remaster_id") is not null)
@@ -47,6 +51,7 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
public void Save()
{
Add();
Context.SaveChanges();
}
@@ -68,6 +73,7 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
Entity.IsTranslated = false;
Entity.IsChecked = false;
Object.Entity = Entity;
Object.Id = Entity.Id;
Context.Entities.Add(Entity);
@@ -229,6 +235,18 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
}
}
public string GenerateExtra(params string[] args)
{
Dictionary<string, object?> data = [];
foreach (string key in args)
{
data.Add(key, Input.Input.SelectToken(key));
}
return JsonConvert.SerializeObject(data, new JsonSerializerSettings() { });
}
public static string Md5(string input, bool isLowercase = false)
{
using MD5 md5 = MD5.Create();
@@ -247,4 +265,6 @@ internal abstract partial class AbstractProcessor(ProcessorInput input)
private static partial Regex SourceSuffixRegex();
public class LegacyItemException(string name) : Exception($"Item '{name}' is linked with newer version, skipping.") { }
public class SkipItemException(string name, string reason) : Exception($"Item '{name}' is skipped, reason: {reason}.") { }
}
@@ -39,7 +39,7 @@ internal class AonprdDataBuilder(AonprdLoader loader)
Window output = new(0, 4, Console.WindowWidth, Console.WindowHeight - 4, window);
ProgressBar bar1 = new(bars, Loader.ItemCount, 15);
ProgressBar bar1 = new(bars, Processors.Items.Count, 15);
ProgressBar bar2 = new(bars, 1, 15);
int i = 0;
@@ -66,6 +66,10 @@ internal class AonprdDataBuilder(AonprdLoader loader)
{
output.WriteLine(ex.Message);
}
catch (SkipItemException ex)
{
output.WriteLine(ex.Message);
}
}
bar2.Refresh(j, "Processor completed");
@@ -4,19 +4,6 @@ namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
public static class AonprdEnumResolver
{
private static readonly ICollection<Solver> Solvers = [
new Solver<ActionType>(new()
{
{ "Single Action", ActionType.SingleAction },
{ "Reaction or One Action", ActionType.SingleAction },
{ "Free Action or One Action", ActionType.SingleAction },
{ "Two Actions", ActionType.TwoActions },
{ "Three Actions", ActionType.ThreeActions },
{ "Single Action to Three Actions", ActionType.SingleToThreeActions },
{ "Single Action or more Actions", ActionType.SingleToThreeActions },
{ "Single Action or Two Actions", ActionType.SingleToTwoActions },
{ "Single Action to Two Actions", ActionType.SingleToTwoActions },
}),
new Solver<SourceCategory>(new()
{
{ "Rulebooks", SourceCategory.Rulebooks },
@@ -36,7 +23,9 @@ public static class AonprdEnumResolver
new Solver<AttributeValues>(new()
{
{ "Consitution", AttributeValues.Constitution }
{ "Consitution", AttributeValues.Constitution },
{ "Other", AttributeValues.Free },
{ "other", AttributeValues.Free },
})
];
@@ -9,13 +9,13 @@ public class AonprdProcessorAttribute(string name, string type, string[] depende
public readonly IEnumerable<string> Dependencies = dependencies;
public AonprdProcessorAttribute(string type) : this(type, type, ["trait"])
public AonprdProcessorAttribute(string type) : this(type, type, ["trait", "source"])
{
}
public AonprdProcessorAttribute(string type, string[] dependencies) : this(type, type, dependencies)
{
}
public AonprdProcessorAttribute(string name, string type) : this(name, type, ["trait"])
public AonprdProcessorAttribute(string name, string type) : this(name, type, ["trait", "source"])
{
}
}
@@ -31,7 +31,7 @@ internal class AonprdProcessorCollection
AonprdProcessorAttribute attribute = type.GetCustomAttribute<AonprdProcessorAttribute>()!;
ConstructorInfo constructor = type.GetConstructor([typeof(ProcessorInput)])!;
ConstructorInfo constructor = type.GetConstructor([typeof(AonprdProcessorInput)])!;
ProcessorItem? collision = Items.FirstOrDefault(i => i.Attribute.Name == attribute.Name);
if (collision is not null)
@@ -15,4 +15,80 @@ internal class AonprdProcessorInput(JObject input) : ProcessorInput(input)
return base.Enum<T>(value);
}
}
public ActionStruct ResolveActionString(string input)
{
ActionStruct result = new();
switch (input)
{
case "Single Action":
result.Actions = result.MaxActions = 1;
break;
case "Two Actions":
result.Actions = result.MaxActions = 2;
break;
case "Three Actions":
result.Actions = result.MaxActions = 3;
break;
case "Reaction":
result.IsReaction = true;
break;
case "Free Action":
result.IsFreeAction = false;
break;
case "Single Action to Three Actions":
case "Single Action or more Actions":
result.Actions = 1;
result.MaxActions = 3;
break;
case "Single Action or Two Actions":
case "Single Action to Two Actions":
result.Actions = 1;
result.MaxActions = 2;
break;
case "Two Actions or Three Actions":
result.Actions = 2;
result.MaxActions = 3;
break;
case "Reaction or One Action":
result.IsReaction = true;
result.Actions = result.MaxActions = 1;
break;
case "Reaction or Two Actions":
result.IsReaction = true;
result.Actions = result.MaxActions = 2;
break;
case "Free Action or One Action":
result.IsFreeAction = false;
result.Actions = result.MaxActions = 1;
break;
default:
result.IsPassive = true;
break;
}
return result;
}
public class ActionStruct
{
public int Actions = 0;
public int MaxActions = 0;
public bool IsPassive = false;
public bool IsReaction = false;
public bool IsFreeAction = false;
}
}
@@ -1,75 +1,31 @@
using Newtonsoft.Json.Linq;
using Pf2eModel.Model;
using Pf2eModel.Model.Enum;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
[AonprdProcessor("action")]
internal class ActionProcessor(ProcessorInput input) : AbstractProcessor(input)
internal class ActionProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
{
public override EntityType Type => EntityType.Action;
public override Pf2eModel.Model.Structure.Action Object { get; } = new();
protected override void Add() => Context.Actions.Add(Object);
public override void Process()
{
base.Process();
switch (Input.GetOptional<string>("actions"))
{
case "Single Action":
Object.Actions = Object.MaxActions = 1;
break;
AonprdProcessorInput.ActionStruct action = Input.ResolveActionString(Input.GetOptional<string>("actions") ?? "");
case "Two Actions":
Object.Actions = Object.MaxActions = 2;
break;
case "Three Actions":
Object.Actions = Object.MaxActions = 3;
break;
case "Reaction":
Object.IsReaction = true;
break;
case "Free Action":
Object.IsFreeAction = false;
break;
case "Single Action to Three Actions":
case "Single Action or more Actions":
Object.Actions = 1;
Object.MaxActions = 3;
break;
case "Single Action or Two Actions":
case "Single Action to Two Actions":
Object.Actions = 1;
Object.MaxActions = 2;
break;
case "Reaction or One Action":
Object.IsReaction = true;
Object.Actions = Object.MaxActions = 1;
break;
case "Free Action or One Action":
Object.IsFreeAction = false;
Object.Actions = Object.MaxActions = 1;
break;
default:
Object.IsPassive = true;
break;
}
Object.Extra = new JObject()
{
{ "school", Input.GetOptional<JToken>("school") },
}.ToString();
Context.Actions.Add(Object);
Object.Actions = action.Actions;
Object.MaxActions = action.MaxActions;
Object.IsFreeAction = action.IsFreeAction;
Object.IsPassive = action.IsPassive;
Object.IsReaction = action.IsReaction;
;
Object.Extra = GenerateExtra("school");
}
protected override string GetDescription()
@@ -9,11 +9,13 @@ using System.Text.RegularExpressions;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
[AonprdProcessor("ancestry", ["trait", "language"])]
internal class AncestryProcessor(ProcessorInput input) : AbstractProcessor(input)
internal class AncestryProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
{
public override EntityType Type { get; } = EntityType.Ancestry;
public override EntityType Type => EntityType.Ancestry;
public override Ancestry Object { get; } = new Ancestry();
public override Ancestry Object { get; } = new();
protected override void Add() => Context.Ancestries.Add(Object);
public override void Process()
{
@@ -21,7 +23,7 @@ internal class AncestryProcessor(ProcessorInput input) : AbstractProcessor(input
if (type != "Ancestry")
{
return;
throw new SkipItemException(Input.GetRequired<string>("name"), "not an ancestry");
}
base.Process();
@@ -66,13 +68,4 @@ internal class AncestryProcessor(ProcessorInput input) : AbstractProcessor(input
}
}
protected override string GetDescription()
=> base.GetDescription() + AddedDescription([
"source_markdown",
"summary_markdown",
"trait_markdown",
"search_markdown"
]);
}
@@ -0,0 +1,50 @@
using Newtonsoft.Json.Linq;
using Pf2eModel.Model;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model.Structure;
using Pf2eModel.Model.Structure.BackgroundRelation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
[AonprdProcessor("background")]
internal class BackgroundProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
{
public override EntityType Type => EntityType.Background;
public override Background Object { get; } = new();
protected override void Add() => Context.Backgrounds.Add(Object);
public override void Process()
{
base.Process();
foreach (JToken token in Input.GetOptional<JArray>("attribute") ?? [])
{
BackgroundBoost boost = new()
{
Background = Object,
Attribute = Input.Enum<AttributeValues>(token.ToString())
};
Object.BackgroundBoosts.Add(boost);
Context.BackgroundBoosts.Add(boost);
}
}
protected override string GetDescription()
=> base.GetDescription() + AddedDescription([
"feat_markdown",
"summary_markdown",
"skill_markdown",
"prerequisite_markdown",
]);
}
@@ -0,0 +1,195 @@
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using Pf2eModel.Model;
using Pf2eModel.Model.Common;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model.Structure;
using Pf2eModel.Model.Structure.ClassRelation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
[AonprdProcessor("class", ["trait", "source", "skill"])]
internal class ClassProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
{
public override EntityType Type => EntityType.Class;
public override Class Object { get; } = new();
protected override void Add() => Context.Classes.Add(Object);
public override void Process()
{
base.Process();
Object.Hp = Convert.ToInt32(Input.GetRequired<string>("hp_raw"));
AttributeValues[] attributes = Input.GetRequired<JArray>("attribute")
.Select(token => Input.Enum<AttributeValues>(token.ToString()))
.ToArray();
foreach (AttributeValues attribute in attributes)
{
ClassKeyAbility classKeyAbility = new ClassKeyAbility()
{
Class = Object,
Value = attribute
};
Context.ClassKeyAbilities.Add(classKeyAbility);
Object.ClassKeyAbilities.Add(classKeyAbility);
}
ClassTraining[] classTrainings =
[
.. ProcessTraining(Input.GetRequired<JArray>("attack_proficiency"), TrainingType.Weapon),
.. ProcessTraining(Input.GetRequired<JArray>("defense_proficiency"), TrainingType.Armor),
.. GetSkillTrainings(),
.. GetSaveTrainings(),
];
foreach (ClassTraining classTraining in classTrainings)
{
Context.ClassTrainings.Add(classTraining);
Object.ClassTrainings.Add(classTraining);
}
JArray tradition = Input.GetOptional<JArray>("tradition") ?? [];
switch (tradition.Count)
{
case 0:
Object.Spellcasting = false;
Object.Tradition = SpellTradition.None;
break;
case 1:
Object.Spellcasting = true;
Object.Tradition = Input.Enum<SpellTradition>(tradition[0].ToString());
break;
default:
Object.Spellcasting = true;
Object.Tradition = SpellTradition.All;
break;
}
}
protected ICollection<ClassTraining> GetSkillTrainings()
{
string[] skillNames = Input.GetRequired<JArray>("skill_proficiency")
.Select(token => token.ToString())
.ToArray();
Training[] skills = Context.Trainings.Where(t => skillNames.Contains(t.Name)).ToArray();
return skills.Select(skill => new ClassTraining()
{
Class = Object,
Training = skill,
Stage = TrainingStage.Trained,
}).ToArray();
}
protected ICollection<ClassTraining> ProcessTraining(JArray array, TrainingType type)
{
const string pattern = @"^(.*?) in\s+(?:the)?\s*(.*)$";
List<ClassTraining> trainings = [];
foreach (string value in array.Select(token => token.ToString()))
{
MatchCollection m = Regex.Matches(value, pattern);
if (m.Count == 0)
{
throw new Exception($"Can't parse training string '{value}'");
}
TrainingStage stage = Input.Enum<TrainingStage>(m[0].Groups[1].Value);
string[] parts = GetTrainingString(m[0].Groups[2].Value);
foreach (string part in parts)
{
Training? training = Context.Trainings
.FirstOrDefault(t => t.Name == part && t.Type == type);
if (training == null)
{
training = new Training()
{
Name = part,
Type = type,
};
Context.Trainings.Add(training);
}
ClassTraining classTraining = new()
{
Class = Object,
Training = training,
Stage = stage
};
trainings.Add(classTraining);
}
}
return trainings;
}
protected string[] GetTrainingString(string value)
{
if (value.StartsWith("favored weapon of your deity"))
{
return ["Favored weapon of your deity"];
}
if (value == "simple and martial weapons")
{
return ["Simple weapon", "Martial weapon"];
}
return Regex.Split(value, @"\s*(?:,|and)\s*")
.Where(s => s != "")
.Select(s => string.Concat(s[0].ToString().ToUpper(), s.AsSpan(1)))
.ToArray();
;
}
protected ICollection<ClassTraining> GetSaveTrainings()
{
Dictionary<string, Training> result = Context.Trainings
.Where(t => t.Type == TrainingType.Save)
.ToDictionary(t => t.Name);
foreach (string name in new[] { "Will", "Fortitude", "Reflex", "Perception" })
{
if (result.ContainsKey(name))
{
continue;
}
Training training = new() { Name = name, Type = (name == "Perception") ? TrainingType.Perception : TrainingType.Save };
result.Add(name, training);
Context.Trainings.Add(training);
}
return result.Select(pair =>
{
ClassTraining classTraining = new()
{
Class = Object,
Training = pair.Value,
Stage = Input.EnumRequired<TrainingStage>($"{pair.Key.ToLower()}_proficiency"),
};
return classTraining;
}).ToList();
}
}
@@ -0,0 +1,61 @@
using Newtonsoft.Json.Linq;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model.Structure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
[AonprdProcessor("feat", ["trait", "source", "skill"])]
internal class FeatProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
{
public override EntityType Type => EntityType.Feat;
public override Feat Object { get; } = new();
protected override void Add() => Context.Feats.Add(Object);
public override void Process()
{
base.Process();
Object.Level = Input.GetRequired<int>("level");
AonprdProcessorInput.ActionStruct action = Input.ResolveActionString(Input.GetOptional<string>("actions") ?? "");
Object.Actions = action.Actions;
Object.MaxActions = action.MaxActions;
Object.IsFreeAction = action.IsFreeAction;
Object.IsPassive = action.IsPassive;
Object.IsReaction = action.IsReaction;
Object.Extra = GenerateExtra(
"archetype",
"element",
"heighten",
"heighten_group",
"heighten_level",
"school",
"frequency"
);
}
protected override string GetDescription()
=> base.GetDescription() + AddedDescription([
"cost_markdown",
"feat_markdown",
"summary_markdown",
"prerequisite_markdown",
"requirement_markdown",
"trigger_markdown"
]);
}
@@ -4,10 +4,16 @@ using Pf2eModel.Model.Structure;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
[AonprdProcessor("language")]
internal class LanguageProcessor(ProcessorInput input) : AbstractProcessor(input)
internal class LanguageProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
{
public override EntityType Type { get; } = EntityType.Language;
public override EntityType Type => EntityType.Language;
public override Language Object { get; } = new Language();
public override Language Object { get; } = new();
protected override void Add() => Context.Languages.Add(Object);
public override void Process()
{
base.Process();
}
}
@@ -0,0 +1,35 @@
using Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder;
using Pf2eModel.Model;
using Pf2eModel.Model.Base.Source;
using Pf2eModel.Model.Enum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
[AonprdProcessor("source", new string[] { })]
internal class SourceProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
{
public override EntityType Type => EntityType.Unknown;
public override IEntity Object => null;
protected override void Add() { }
public override void Process()
{
// base.Process();
Source source = new()
{
Name = Input.GetRequired<string>("name"),
Category = Input.EnumRequired<SourceCategory>("primary_source_category"),
ReleaseDate = DateOnly.Parse(Input.GetRequired<string>("release_date")),
};
Context.Sources.Add(source);
}
}
@@ -0,0 +1,34 @@
using Pf2eModel.Model.Base.Source;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model;
using Pf2eModel.Model.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
[AonprdProcessor("skill", new string[] { })]
internal class TrainingProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
{
public override EntityType Type => EntityType.Unknown;
public override IEntity Object => null;
protected override void Add() { }
public override void Process()
{
// base.Process();
Training training = new()
{
Name = Input.GetRequired<string>("name"),
Type = TrainingType.Skill,
};
Context.Trainings.Add(training);
}
}
@@ -4,12 +4,14 @@ using Pf2eModel.Model.Structure;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.DataBuilder.Processors;
[AonprdProcessor("trait", new string[] { })]
internal class TraitProcessor(ProcessorInput input) : AbstractProcessor(input)
internal class TraitProcessor(AonprdProcessorInput input) : AbstractProcessor(input)
{
public override EntityType Type => EntityType.Trait;
public override Trait Object { get; } = new();
protected override void Add() => Context.Traits.Add(Object);
public override void Process()
{
base.Process();
@@ -13,7 +13,7 @@ using Pf2eModel.Model.Enum;
namespace Pf2eModel.Migrations
{
[DbContext(typeof(Pf2eDbContext))]
[Migration("20250418174520_1")]
[Migration("20250420145024_1")]
partial class _1
{
/// <inheritdoc />
@@ -25,7 +25,6 @@ namespace Pf2eModel.Migrations
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_category", new[] { "unknown", "offensive", "defensive", "interaction", "familiar", "army_tactic", "army_war_action", "kingdom_activity", "kingdom_feat", "kingdom_feature" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_type", new[] { "none", "1_action", "2_actions", "3_actions", "1-3_actions", "1-2_actions" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "alias_type", new[] { "legacy", "english", "legacy_english", "hobby", "other" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "ancestry_vision", new[] { "normal", "low-light-vision", "dark-vision" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "free", "str", "dex", "con", "int", "wis", "cha" });
@@ -35,7 +34,7 @@ namespace Pf2eModel.Migrations
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_rarity", new[] { "common", "uncommon", "rare", "unique" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "background", "backpack", "campaign_feature", "class", "condition", "deity", "feat", "heritage", "spell", "language" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "archetype", "background", "backpack", "campaign_feature", "class", "condition", "deity", "feat", "heritage", "spell", "language" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_action_type", new[] { "passive", "action", "reaction", "free" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_category", new[] { "ancestryfeature", "classfeature", "calling", "class", "skill", "general", "ancestry", "bonus", "deityboon", "curse", "pfsboon", "campaign_feature" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "size", new[] { "tiny", "small", "medium", "large" });
@@ -435,13 +434,18 @@ namespace Pf2eModel.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Key")
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("key")
.HasColumnName("name")
.HasColumnOrder(2);
b.Property<int>("Type")
.HasColumnType("integer")
.HasColumnName("type")
.HasColumnOrder(3);
b.HasKey("Id")
.HasName("pk_trainings");
@@ -485,11 +489,6 @@ namespace Pf2eModel.Migrations
.HasColumnName("max_actions")
.HasColumnOrder(4);
b.Property<ActionType>("Type")
.HasColumnType("action_type")
.HasColumnName("type")
.HasColumnOrder(2);
b.HasKey("Id")
.HasName("pk_actions");
@@ -616,6 +615,38 @@ namespace Pf2eModel.Migrations
b.ToTable("ancestry_languages", (string)null);
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Archetype", b =>
{
b.Property<int>("Id")
.HasColumnType("integer")
.HasColumnName("id")
.HasColumnOrder(1);
b.Property<int>("DedicationFeatId")
.HasColumnType("integer")
.HasColumnName("dedication_feat_id")
.HasColumnOrder(3);
b.Property<string>("Extra")
.HasColumnType("text")
.HasColumnName("extra")
.HasColumnOrder(4);
b.Property<int>("Level")
.HasColumnType("integer")
.HasColumnName("level")
.HasColumnOrder(2);
b.HasKey("Id")
.HasName("pk_archetype");
b.HasIndex("DedicationFeatId")
.IsUnique()
.HasDatabaseName("ix_archetype_dedication_feat_id");
b.ToTable("archetype", (string)null);
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Background", b =>
{
b.Property<int>("Id")
@@ -632,10 +663,13 @@ namespace Pf2eModel.Migrations
modelBuilder.Entity("Pf2eModel.Model.Structure.BackgroundRelation.BackgroundBoost", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id")
.HasColumnOrder(1);
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<AttributeValues>("Attribute")
.HasColumnType("attribute_values")
.HasColumnName("attribute")
@@ -725,7 +759,7 @@ namespace Pf2eModel.Migrations
b.Property<int>("AdditionalTrainedSkills")
.HasColumnType("integer")
.HasColumnName("additional_trained_skills")
.HasColumnOrder(6);
.HasColumnOrder(7);
b.Property<int>("Hp")
.HasColumnType("integer")
@@ -742,6 +776,11 @@ namespace Pf2eModel.Migrations
.HasColumnName("spellcasting")
.HasColumnOrder(5);
b.Property<int>("Tradition")
.HasColumnType("integer")
.HasColumnName("tradition")
.HasColumnOrder(6);
b.HasKey("Id")
.HasName("pk_classes");
@@ -840,8 +879,8 @@ namespace Pf2eModel.Migrations
.HasColumnName("name")
.HasColumnOrder(4);
b.Property<int>("Stage")
.HasColumnType("integer")
b.Property<TrainingStage>("Stage")
.HasColumnType("training_stage")
.HasColumnName("stage")
.HasColumnOrder(5);
@@ -1050,7 +1089,12 @@ namespace Pf2eModel.Migrations
b.Property<int?>("Actions")
.HasColumnType("integer")
.HasColumnName("actions")
.HasColumnOrder(4);
.HasColumnOrder(5);
b.Property<int>("ArchetypeId")
.HasColumnType("integer")
.HasColumnName("archetype_id")
.HasColumnOrder(10);
b.Property<ActionCategory>("Category")
.HasColumnType("action_category")
@@ -1060,42 +1104,39 @@ namespace Pf2eModel.Migrations
b.Property<string>("Extra")
.HasColumnType("text")
.HasColumnName("extra")
.HasColumnOrder(10);
.HasColumnOrder(11);
b.Property<bool>("IsFreeAction")
.HasColumnType("boolean")
.HasColumnName("is_free_action")
.HasColumnOrder(8);
b.Property<bool>("IsPassive")
.HasColumnType("boolean")
.HasColumnName("is_passive")
.HasColumnOrder(9);
b.Property<bool>("IsReaction")
.HasColumnType("boolean")
.HasColumnName("is_reaction")
.HasColumnOrder(7);
b.Property<int>("Level")
.HasColumnType("integer")
.HasColumnName("level")
.HasColumnOrder(5);
.HasColumnOrder(4);
b.Property<int?>("LevelTaken")
b.Property<int?>("MaxActions")
.HasColumnType("integer")
.HasColumnName("level_taken")
.HasColumnName("max_actions")
.HasColumnOrder(6);
b.Property<string>("Location")
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("location")
.HasColumnOrder(8);
b.Property<int?>("MaxTakable")
.HasColumnType("integer")
.HasColumnName("max_takable")
.HasColumnOrder(7);
b.Property<bool?>("OnlyLevel1")
.HasColumnType("boolean")
.HasColumnName("only_level1")
.HasColumnOrder(9);
b.Property<ActionType>("Type")
.HasColumnType("action_type")
.HasColumnName("type")
.HasColumnOrder(2);
b.HasKey("Id")
.HasName("pk_feats");
b.HasIndex("ArchetypeId")
.HasDatabaseName("ix_feats_archetype_id");
b.ToTable("feats", (string)null);
});
@@ -1628,6 +1669,27 @@ namespace Pf2eModel.Migrations
b.Navigation("Language");
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Archetype", b =>
{
b.HasOne("Pf2eModel.Model.Structure.Feat", "DedicationFeat")
.WithOne()
.HasForeignKey("Pf2eModel.Model.Structure.Archetype", "DedicationFeatId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_archetype_feats_dedication_feat_id");
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
.WithOne()
.HasForeignKey("Pf2eModel.Model.Structure.Archetype", "Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_archetype_entities_id");
b.Navigation("DedicationFeat");
b.Navigation("Entity");
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Background", b =>
{
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
@@ -1841,6 +1903,13 @@ namespace Pf2eModel.Migrations
modelBuilder.Entity("Pf2eModel.Model.Structure.Feat", b =>
{
b.HasOne("Pf2eModel.Model.Structure.Archetype", "Archetype")
.WithMany("Feats")
.HasForeignKey("ArchetypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_feats_archetype_archetype_id");
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
.WithOne()
.HasForeignKey("Pf2eModel.Model.Structure.Feat", "Id")
@@ -1848,6 +1917,8 @@ namespace Pf2eModel.Migrations
.IsRequired()
.HasConstraintName("fk_feats_entities_id");
b.Navigation("Archetype");
b.Navigation("Entity");
});
@@ -2000,6 +2071,11 @@ namespace Pf2eModel.Migrations
b.Navigation("Heritages");
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Archetype", b =>
{
b.Navigation("Feats");
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Background", b =>
{
b.Navigation("BackgroundBoosts");
@@ -15,7 +15,6 @@ namespace Pf2eModel.Migrations
{
migrationBuilder.AlterDatabase()
.Annotation("Npgsql:Enum:action_category", "unknown,offensive,defensive,interaction,familiar,army_tactic,army_war_action,kingdom_activity,kingdom_feat,kingdom_feature")
.Annotation("Npgsql:Enum:action_type", "none,1_action,2_actions,3_actions,1-3_actions,1-2_actions")
.Annotation("Npgsql:Enum:alias_type", "legacy,english,legacy_english,hobby,other")
.Annotation("Npgsql:Enum:ancestry_vision", "normal,low-light-vision,dark-vision")
.Annotation("Npgsql:Enum:attribute_values", "free,str,dex,con,int,wis,cha")
@@ -25,7 +24,7 @@ namespace Pf2eModel.Migrations
.Annotation("Npgsql:Enum:deity_fonts", "none,heal,harm,any")
.Annotation("Npgsql:Enum:deity_sanctification", "holy,unholy,any")
.Annotation("Npgsql:Enum:entity_rarity", "common,uncommon,rare,unique")
.Annotation("Npgsql:Enum:entity_type", "unknown,trait,action,ancestry,background,backpack,campaign_feature,class,condition,deity,feat,heritage,spell,language")
.Annotation("Npgsql:Enum:entity_type", "unknown,trait,action,ancestry,archetype,background,backpack,campaign_feature,class,condition,deity,feat,heritage,spell,language")
.Annotation("Npgsql:Enum:feat_action_type", "passive,action,reaction,free")
.Annotation("Npgsql:Enum:feat_category", "ancestryfeature,classfeature,calling,class,skill,general,ancestry,bonus,deityboon,curse,pfsboon,campaign_feature")
.Annotation("Npgsql:Enum:size", "tiny,small,medium,large")
@@ -120,7 +119,8 @@ namespace Pf2eModel.Migrations
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
key = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false)
name = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false),
type = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
@@ -132,7 +132,6 @@ namespace Pf2eModel.Migrations
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false),
type = table.Column<ActionType>(type: "action_type", nullable: false),
actions = table.Column<int>(type: "integer", nullable: true),
max_actions = table.Column<int>(type: "integer", nullable: true),
is_reaction = table.Column<bool>(type: "boolean", nullable: false),
@@ -197,6 +196,7 @@ namespace Pf2eModel.Migrations
hp = table.Column<int>(type: "integer", nullable: false),
perception = table.Column<int>(type: "integer", nullable: false),
spellcasting = table.Column<bool>(type: "boolean", nullable: false),
tradition = table.Column<int>(type: "integer", nullable: false),
additional_trained_skills = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
@@ -269,32 +269,6 @@ namespace Pf2eModel.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "feats",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false),
type = table.Column<ActionType>(type: "action_type", nullable: false),
category = table.Column<ActionCategory>(type: "action_category", nullable: false),
actions = table.Column<int>(type: "integer", nullable: true),
level = table.Column<int>(type: "integer", nullable: false),
level_taken = table.Column<int>(type: "integer", nullable: true),
max_takable = table.Column<int>(type: "integer", nullable: true),
location = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
only_level1 = table.Column<bool>(type: "boolean", nullable: true),
extra = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_feats", x => x.id);
table.ForeignKey(
name: "fk_feats_entities_id",
column: x => x.id,
principalTable: "entities",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "languages",
columns: table => new
@@ -529,7 +503,8 @@ namespace Pf2eModel.Migrations
name: "background_boosts",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false),
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
background_id = table.Column<int>(type: "integer", nullable: false),
attribute = table.Column<AttributeValues>(type: "attribute_values", nullable: false)
},
@@ -652,7 +627,7 @@ namespace Pf2eModel.Migrations
class_id = table.Column<int>(type: "integer", nullable: false),
training_id = table.Column<int>(type: "integer", nullable: true),
name = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
stage = table.Column<int>(type: "integer", nullable: false)
stage = table.Column<TrainingStage>(type: "training_stage", nullable: false)
},
constraints: table =>
{
@@ -754,26 +729,6 @@ namespace Pf2eModel.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "feat_prerequisites",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
feat_id = table.Column<int>(type: "integer", nullable: false),
value = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_feat_prerequisites", x => x.id);
table.ForeignKey(
name: "fk_feat_prerequisites_feats_feat_id",
column: x => x.feat_id,
principalTable: "feats",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ancestry_languages",
columns: table => new
@@ -938,6 +893,78 @@ namespace Pf2eModel.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "archetype",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false),
level = table.Column<int>(type: "integer", nullable: false),
dedication_feat_id = table.Column<int>(type: "integer", nullable: false),
extra = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_archetype", x => x.id);
table.ForeignKey(
name: "fk_archetype_entities_id",
column: x => x.id,
principalTable: "entities",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "feats",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false),
category = table.Column<ActionCategory>(type: "action_category", nullable: false),
level = table.Column<int>(type: "integer", nullable: false),
actions = table.Column<int>(type: "integer", nullable: true),
max_actions = table.Column<int>(type: "integer", nullable: true),
is_reaction = table.Column<bool>(type: "boolean", nullable: false),
is_free_action = table.Column<bool>(type: "boolean", nullable: false),
is_passive = table.Column<bool>(type: "boolean", nullable: false),
archetype_id = table.Column<int>(type: "integer", nullable: false),
extra = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_feats", x => x.id);
table.ForeignKey(
name: "fk_feats_archetype_archetype_id",
column: x => x.archetype_id,
principalTable: "archetype",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_feats_entities_id",
column: x => x.id,
principalTable: "entities",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "feat_prerequisites",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
feat_id = table.Column<int>(type: "integer", nullable: false),
value = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_feat_prerequisites", x => x.id);
table.ForeignKey(
name: "fk_feat_prerequisites_feats_feat_id",
column: x => x.feat_id,
principalTable: "feats",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "ix_ancestry_boosts_ancestry_id",
table: "ancestry_boosts",
@@ -953,6 +980,12 @@ namespace Pf2eModel.Migrations
table: "ancestry_languages",
column: "language_id");
migrationBuilder.CreateIndex(
name: "ix_archetype_dedication_feat_id",
table: "archetype",
column: "dedication_feat_id",
unique: true);
migrationBuilder.CreateIndex(
name: "ix_background_boosts_background_id",
table: "background_boosts",
@@ -1048,6 +1081,11 @@ namespace Pf2eModel.Migrations
table: "feat_prerequisites",
column: "feat_id");
migrationBuilder.CreateIndex(
name: "ix_feats_archetype_id",
table: "feats",
column: "archetype_id");
migrationBuilder.CreateIndex(
name: "ix_heritages_ancestry_id",
table: "heritages",
@@ -1072,11 +1110,31 @@ namespace Pf2eModel.Migrations
name: "ix_spell_defenses_spell_id",
table: "spell_defenses",
column: "spell_id");
migrationBuilder.AddForeignKey(
name: "fk_archetype_feats_dedication_feat_id",
table: "archetype",
column: "dedication_feat_id",
principalTable: "feats",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "fk_archetype_entities_id",
table: "archetype");
migrationBuilder.DropForeignKey(
name: "fk_feats_entities_id",
table: "feats");
migrationBuilder.DropForeignKey(
name: "fk_archetype_feats_dedication_feat_id",
table: "archetype");
migrationBuilder.DropTable(
name: "actions");
@@ -1188,9 +1246,6 @@ namespace Pf2eModel.Migrations
migrationBuilder.DropTable(
name: "traits");
migrationBuilder.DropTable(
name: "feats");
migrationBuilder.DropTable(
name: "ancestries");
@@ -1202,6 +1257,12 @@ namespace Pf2eModel.Migrations
migrationBuilder.DropTable(
name: "entities");
migrationBuilder.DropTable(
name: "feats");
migrationBuilder.DropTable(
name: "archetype");
}
}
}
@@ -22,7 +22,6 @@ namespace Pf2eModel.Migrations
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_category", new[] { "unknown", "offensive", "defensive", "interaction", "familiar", "army_tactic", "army_war_action", "kingdom_activity", "kingdom_feat", "kingdom_feature" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_type", new[] { "none", "1_action", "2_actions", "3_actions", "1-3_actions", "1-2_actions" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "alias_type", new[] { "legacy", "english", "legacy_english", "hobby", "other" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "ancestry_vision", new[] { "normal", "low-light-vision", "dark-vision" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "free", "str", "dex", "con", "int", "wis", "cha" });
@@ -32,7 +31,7 @@ namespace Pf2eModel.Migrations
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_fonts", new[] { "none", "heal", "harm", "any" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "deity_sanctification", new[] { "holy", "unholy", "any" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_rarity", new[] { "common", "uncommon", "rare", "unique" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "background", "backpack", "campaign_feature", "class", "condition", "deity", "feat", "heritage", "spell", "language" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "entity_type", new[] { "unknown", "trait", "action", "ancestry", "archetype", "background", "backpack", "campaign_feature", "class", "condition", "deity", "feat", "heritage", "spell", "language" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_action_type", new[] { "passive", "action", "reaction", "free" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "feat_category", new[] { "ancestryfeature", "classfeature", "calling", "class", "skill", "general", "ancestry", "bonus", "deityboon", "curse", "pfsboon", "campaign_feature" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "size", new[] { "tiny", "small", "medium", "large" });
@@ -432,13 +431,18 @@ namespace Pf2eModel.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Key")
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("key")
.HasColumnName("name")
.HasColumnOrder(2);
b.Property<int>("Type")
.HasColumnType("integer")
.HasColumnName("type")
.HasColumnOrder(3);
b.HasKey("Id")
.HasName("pk_trainings");
@@ -482,11 +486,6 @@ namespace Pf2eModel.Migrations
.HasColumnName("max_actions")
.HasColumnOrder(4);
b.Property<ActionType>("Type")
.HasColumnType("action_type")
.HasColumnName("type")
.HasColumnOrder(2);
b.HasKey("Id")
.HasName("pk_actions");
@@ -613,6 +612,38 @@ namespace Pf2eModel.Migrations
b.ToTable("ancestry_languages", (string)null);
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Archetype", b =>
{
b.Property<int>("Id")
.HasColumnType("integer")
.HasColumnName("id")
.HasColumnOrder(1);
b.Property<int>("DedicationFeatId")
.HasColumnType("integer")
.HasColumnName("dedication_feat_id")
.HasColumnOrder(3);
b.Property<string>("Extra")
.HasColumnType("text")
.HasColumnName("extra")
.HasColumnOrder(4);
b.Property<int>("Level")
.HasColumnType("integer")
.HasColumnName("level")
.HasColumnOrder(2);
b.HasKey("Id")
.HasName("pk_archetype");
b.HasIndex("DedicationFeatId")
.IsUnique()
.HasDatabaseName("ix_archetype_dedication_feat_id");
b.ToTable("archetype", (string)null);
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Background", b =>
{
b.Property<int>("Id")
@@ -629,10 +660,13 @@ namespace Pf2eModel.Migrations
modelBuilder.Entity("Pf2eModel.Model.Structure.BackgroundRelation.BackgroundBoost", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id")
.HasColumnOrder(1);
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<AttributeValues>("Attribute")
.HasColumnType("attribute_values")
.HasColumnName("attribute")
@@ -722,7 +756,7 @@ namespace Pf2eModel.Migrations
b.Property<int>("AdditionalTrainedSkills")
.HasColumnType("integer")
.HasColumnName("additional_trained_skills")
.HasColumnOrder(6);
.HasColumnOrder(7);
b.Property<int>("Hp")
.HasColumnType("integer")
@@ -739,6 +773,11 @@ namespace Pf2eModel.Migrations
.HasColumnName("spellcasting")
.HasColumnOrder(5);
b.Property<int>("Tradition")
.HasColumnType("integer")
.HasColumnName("tradition")
.HasColumnOrder(6);
b.HasKey("Id")
.HasName("pk_classes");
@@ -837,8 +876,8 @@ namespace Pf2eModel.Migrations
.HasColumnName("name")
.HasColumnOrder(4);
b.Property<int>("Stage")
.HasColumnType("integer")
b.Property<TrainingStage>("Stage")
.HasColumnType("training_stage")
.HasColumnName("stage")
.HasColumnOrder(5);
@@ -1047,7 +1086,12 @@ namespace Pf2eModel.Migrations
b.Property<int?>("Actions")
.HasColumnType("integer")
.HasColumnName("actions")
.HasColumnOrder(4);
.HasColumnOrder(5);
b.Property<int>("ArchetypeId")
.HasColumnType("integer")
.HasColumnName("archetype_id")
.HasColumnOrder(10);
b.Property<ActionCategory>("Category")
.HasColumnType("action_category")
@@ -1057,42 +1101,39 @@ namespace Pf2eModel.Migrations
b.Property<string>("Extra")
.HasColumnType("text")
.HasColumnName("extra")
.HasColumnOrder(10);
.HasColumnOrder(11);
b.Property<bool>("IsFreeAction")
.HasColumnType("boolean")
.HasColumnName("is_free_action")
.HasColumnOrder(8);
b.Property<bool>("IsPassive")
.HasColumnType("boolean")
.HasColumnName("is_passive")
.HasColumnOrder(9);
b.Property<bool>("IsReaction")
.HasColumnType("boolean")
.HasColumnName("is_reaction")
.HasColumnOrder(7);
b.Property<int>("Level")
.HasColumnType("integer")
.HasColumnName("level")
.HasColumnOrder(5);
.HasColumnOrder(4);
b.Property<int?>("LevelTaken")
b.Property<int?>("MaxActions")
.HasColumnType("integer")
.HasColumnName("level_taken")
.HasColumnName("max_actions")
.HasColumnOrder(6);
b.Property<string>("Location")
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("location")
.HasColumnOrder(8);
b.Property<int?>("MaxTakable")
.HasColumnType("integer")
.HasColumnName("max_takable")
.HasColumnOrder(7);
b.Property<bool?>("OnlyLevel1")
.HasColumnType("boolean")
.HasColumnName("only_level1")
.HasColumnOrder(9);
b.Property<ActionType>("Type")
.HasColumnType("action_type")
.HasColumnName("type")
.HasColumnOrder(2);
b.HasKey("Id")
.HasName("pk_feats");
b.HasIndex("ArchetypeId")
.HasDatabaseName("ix_feats_archetype_id");
b.ToTable("feats", (string)null);
});
@@ -1625,6 +1666,27 @@ namespace Pf2eModel.Migrations
b.Navigation("Language");
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Archetype", b =>
{
b.HasOne("Pf2eModel.Model.Structure.Feat", "DedicationFeat")
.WithOne()
.HasForeignKey("Pf2eModel.Model.Structure.Archetype", "DedicationFeatId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_archetype_feats_dedication_feat_id");
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
.WithOne()
.HasForeignKey("Pf2eModel.Model.Structure.Archetype", "Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_archetype_entities_id");
b.Navigation("DedicationFeat");
b.Navigation("Entity");
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Background", b =>
{
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
@@ -1838,6 +1900,13 @@ namespace Pf2eModel.Migrations
modelBuilder.Entity("Pf2eModel.Model.Structure.Feat", b =>
{
b.HasOne("Pf2eModel.Model.Structure.Archetype", "Archetype")
.WithMany("Feats")
.HasForeignKey("ArchetypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_feats_archetype_archetype_id");
b.HasOne("Pf2eModel.Model.Base.Entity", "Entity")
.WithOne()
.HasForeignKey("Pf2eModel.Model.Structure.Feat", "Id")
@@ -1845,6 +1914,8 @@ namespace Pf2eModel.Migrations
.IsRequired()
.HasConstraintName("fk_feats_entities_id");
b.Navigation("Archetype");
b.Navigation("Entity");
});
@@ -1997,6 +2068,11 @@ namespace Pf2eModel.Migrations
b.Navigation("Heritages");
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Archetype", b =>
{
b.Navigation("Feats");
});
modelBuilder.Entity("Pf2eModel.Model.Structure.Background", b =>
{
b.Navigation("BackgroundBoosts");
+6 -2
View File
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using Pf2eModel.Model.Enum;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Pf2eModel.Model.Common;
@@ -12,5 +13,8 @@ public partial class Training
[Column(Order = 2)]
[MaxLength(Pf2eDbContext.NameLength)]
public string Key { get; set; } = null!;
public string Name { get; set; } = null!;
[Column(Order = 3)]
public TrainingType Type { get; set; }
}
-24
View File
@@ -1,24 +0,0 @@
using NpgsqlTypes;
namespace Pf2eModel.Model.Enum;
public enum ActionType
{
[PgName("none")]
None,
[PgName("1_action")]
SingleAction,
[PgName("2_actions")]
TwoActions,
[PgName("3_actions")]
ThreeActions,
[PgName("1-3_actions")]
SingleToThreeActions,
[PgName("1-2_actions")]
SingleToTwoActions,
}
+3
View File
@@ -16,6 +16,9 @@ public enum EntityType
[PgName("ancestry")]
Ancestry,
[PgName("archetype")]
Archetype,
[PgName("background")]
Background,
+24
View File
@@ -0,0 +1,24 @@
using NpgsqlTypes;
namespace Pf2eModel.Model.Enum;
public enum SpellTradition
{
[PgName("none")]
None,
[PgName("divine")]
Divine,
[PgName("occult")]
Occult,
[PgName("arcane")]
Arcane,
[PgName("primal")]
Primal,
[PgName("all")]
All,
}
+23
View File
@@ -0,0 +1,23 @@
using NpgsqlTypes;
namespace Pf2eModel.Model.Enum;
public enum TrainingType
{
[PgName("perception")]
Perception,
[PgName("skill")]
Skill,
[PgName("lore")]
Lore,
[PgName("weapon")]
Weapon,
[PgName("armor")]
Armor,
[PgName("save")]
Save,
}
-3
View File
@@ -12,9 +12,6 @@ public partial class Action : IEntity
[Column(Order = 1)]
public int Id { get; set; }
[Column(Order = 2)]
public ActionType Type { get; set; }
[Column(Order = 3)]
public int? Actions { get; set; } = null;
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Pf2eModel.Model.Structure.AncestryRelation;
@@ -19,5 +20,6 @@ public partial class AncestryBoost
[Column(Order = 4)]
public Enum.AttributeValues Value { get; set; }
[JsonIgnore]
public virtual Ancestry Ancestry { get; set; } = null!;
}
+32
View File
@@ -0,0 +1,32 @@
using Pf2eModel.Model.Base;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pf2eModel.Model.Structure;
public class Archetype : IEntity
{
[Key]
[Column(Order = 1)]
public int Id { get; set; }
public Entity Entity { get; set; } = null!;
[Column(Order = 2)]
public int Level { get; set; }
[Column(Order = 3)]
public int DedicationFeatId { get; set; }
[Column(Order = 4)]
public string? Extra { get; set; }
public Feat DedicationFeat { get; set; } = null!;
public virtual ICollection<Feat> Feats { get; set; } = [];
}
@@ -1,4 +1,5 @@
using Pf2eModel.Model.Enum;
using Newtonsoft.Json;
using Pf2eModel.Model.Enum;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@@ -7,7 +8,7 @@ namespace Pf2eModel.Model.Structure.BackgroundRelation;
public partial class BackgroundBoost
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column(Order = 1)]
public int Id { get; set; }
@@ -17,5 +18,6 @@ public partial class BackgroundBoost
[Column(Order = 3)]
public AttributeValues Attribute { get; set; }
[JsonIgnore]
public virtual Background Background { get; set; } = null!;
}
@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Pf2eModel.Model.Base;
using System.ComponentModel.DataAnnotations.Schema;
@@ -16,6 +17,7 @@ public partial class BackgroundItem
[Column(Order = 3)]
public int? Level { get; set; }
[JsonIgnore]
public virtual Background Background { get; set; } = null!;
public virtual Entity Entity { get; set; } = null!;
@@ -1,4 +1,5 @@
using Pf2eModel.Model.Common;
using Newtonsoft.Json;
using Pf2eModel.Model.Common;
using Pf2eModel.Model.Enum;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@@ -21,6 +22,7 @@ public partial class BackgroundTraining
[Column(Order = 4)]
public TrainingStage Level { get; set; }
[JsonIgnore]
public virtual Background Background { get; set; } = null!;
public virtual Training Training { get; set; } = null!;
+3 -1
View File
@@ -13,7 +13,6 @@ public partial class Class : IEntity
[Column(Order = 1)]
public int Id { get; set; }
[Column(Order = 2)]
public Entity Entity { get; set; } = null!;
[Column(Order = 3)]
@@ -26,6 +25,9 @@ public partial class Class : IEntity
public bool Spellcasting { get; set; }
[Column(Order = 6)]
public SpellTradition Tradition { get; set; }
[Column(Order = 7)]
public int AdditionalTrainedSkills { get; set; }
public virtual ICollection<ClassKeyAbility> ClassKeyAbilities { get; set; } = [];
@@ -1,4 +1,5 @@
using Pf2eModel.Model.Enum;
using Newtonsoft.Json;
using Pf2eModel.Model.Enum;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@@ -17,5 +18,6 @@ public partial class ClassKeyAbility
[Column(Order = 3)]
public AttributeValues Value { get; set; }
[JsonIgnore]
public virtual Class Class { get; set; } = null!;
}
@@ -1,4 +1,5 @@
using Pf2eModel.Model.Base;
using Newtonsoft.Json;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Enum;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@@ -23,6 +24,7 @@ public partial class ClassProgression
[Column(Order = 5)]
public int? EntityId { get; set; }
[JsonIgnore]
public virtual Class Class { get; set; } = null!;
public virtual Entity? Entity { get; set; }
@@ -1,4 +1,6 @@
using Pf2eModel.Model.Common;
using Newtonsoft.Json;
using Pf2eModel.Model.Common;
using Pf2eModel.Model.Enum;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@@ -22,8 +24,9 @@ public partial class ClassTraining
public string? Name { get; set; }
[Column(Order = 5)]
public int Stage { get; set; }
public TrainingStage Stage { get; set; }
[JsonIgnore]
public virtual Class Class { get; set; } = null!;
public virtual Training? Training { get; set; }
+12 -11
View File
@@ -16,33 +16,34 @@ public partial class Feat : IEntity
public Entity Entity { get; set; } = null!;
[Column(Order = 2)]
public ActionType Type { get; set; }
[Column(Order = 3)]
public ActionCategory Category { get; set; }
[Column(Order = 4)]
public int? Actions { get; set; }
[Column(Order = 5)]
public int Level { get; set; }
[Column(Order = 5)]
public int? Actions { get; set; } = null;
[Column(Order = 6)]
public int? LevelTaken { get; set; }
public int? MaxActions { get; set; } = null;
[Column(Order = 7)]
public int? MaxTakable { get; set; }
public bool IsReaction { get; set; } = false;
[Column(Order = 8)]
[MaxLength(255)]
public string? Location { get; set; }
public bool IsFreeAction { get; set; } = false;
[Column(Order = 9)]
public bool? OnlyLevel1 { get; set; }
public bool IsPassive { get; set; } = false;
[Column(Order = 10)]
public int ArchetypeId { get; set; }
[Column(Order = 11)]
public string? Extra { get; set; }
public Archetype Archetype { get; set; } = null!;
public virtual ICollection<FeatPrerequisite> FeatPrerequisites { get; set; } = [];
}
-1
View File
@@ -125,7 +125,6 @@ public partial class Pf2eDbContext : DbContext
.MapEnum<EntityRarity>()
.MapEnum<AliasType>()
.MapEnum<TraitType>()
.MapEnum<ActionType>()
.MapEnum<ActionCategory>()
.MapEnum<Size>()
.MapEnum<AncestryVision>()
+14 -1
View File
@@ -38,7 +38,6 @@ public partial class Pf2eDbContext
.HasPostgresEnum<EntityRarity>()
.HasPostgresEnum<AliasType>()
.HasPostgresEnum<TraitType>()
.HasPostgresEnum<ActionType>()
.HasPostgresEnum<ActionCategory>()
.HasPostgresEnum<Size>()
.HasPostgresEnum<AncestryVision>()
@@ -171,6 +170,20 @@ public partial class Pf2eDbContext
.OnDelete(DeleteBehavior.Cascade);
});
// Archetype
modelBuilder.Entity<Archetype>(entity =>
{
BindEntity(entity);
entity.HasOne(a => a.DedicationFeat).WithOne()
.HasForeignKey<Archetype>(a => a.DedicationFeatId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasMany(a => a.Feats).WithOne(f => f.Archetype)
.HasForeignKey(f => f.ArchetypeId)
.OnDelete(DeleteBehavior.Cascade);
});
// Background
modelBuilder.Entity<Background>(entity =>
{
+5
View File
@@ -24,6 +24,11 @@ internal class EntityConverter : JsonConverter
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
{
if (property.Attributes.OfType<JsonIgnoreAttribute>().Any())
{
continue;
}
object? v = property.GetValue(source);
dictionary.Add(property.Name, v);
}
+59 -20
View File
@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using LinqToDB.Tools;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
@@ -7,6 +8,7 @@ using Pf2eModel;
using Pf2eModel.Model;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Enum;
using static LinqToDB.Common.Configuration;
namespace Pf2eViewer;
@@ -31,7 +33,7 @@ public partial class MainViewForm : Form
TypesListBox.SelectedIndex = 0;
}
public const int PerPage = 20;
public const int PerPage = 30;
public int Count;
@@ -50,6 +52,7 @@ public partial class MainViewForm : Form
private void UpdateTreeView()
{
EntityTreeView.Nodes.Clear();
EntityType type = (EntityType) TypesListBox.SelectedItem!;
Count = Context.Entities.Count(e => e.Type == type);
@@ -63,14 +66,6 @@ public partial class MainViewForm : Form
EntityGridView.DataSource = Context.Entities
.Where(e => e.Type == (EntityType) TypesListBox.SelectedItem)
.OrderBy(e => e.Id)
.Include(e => e.Sources)
.ThenInclude(s => s.Source)
.Include(e => e.Aliases)
.Include(e => e.Keywords)
.Include(e => e.Externals)
.ThenInclude(x => x.Target)
.Include(e => e.Traits)
.ThenInclude(t => t.Entity)
.Select(e => new EntityGridRow(e))
.Skip((Page - 1) * PerPage)
.Take(PerPage)
@@ -99,22 +94,18 @@ public partial class MainViewForm : Form
{
Page = 1;
}
private void PrevPageButton_Click(object sender, EventArgs e)
{
Page--;
}
private void NextPageButton_Click(object sender, EventArgs e)
{
Page++;
}
private void LastPageButton_Click(object sender, EventArgs e)
{
Page = MaxPage;
}
private void PageTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
@@ -141,13 +132,42 @@ public partial class MainViewForm : Form
EntityGridRow data = (EntityGridRow) row.DataBoundItem;
string json = SerializeEntity(data.GetEntity());
ViewEntity(data.Id);
}
public void ViewEntity(int id)
{
EntityTreeView.Nodes.Clear();
Entity? entity = Context.Entities
.Where(e => e.Id == id && e.Type == (EntityType) TypesListBox.SelectedItem!)
.Include(e => e.Sources)
.ThenInclude(s => s.Source)
.Include(e => e.Aliases)
.Include(e => e.Keywords)
.Include(e => e.Externals)
.ThenInclude(x => x.Target)
.Include(e => e.Traits)
.ThenInclude(t => t.Entity)
.FirstOrDefault()
;
if (entity == null)
{
DescriptionTextBox.Text = "Not found";
return;
}
string json = SerializeEntity(entity);
JsonToTreeview(EntityTreeView, json, "Entity");
DescriptionTextBox.Text = data.GetEntity().Description.Replace("\\r", "").Replace("\\n", "\\r\\n");
DescriptionTextBox.Text = entity.Description.Replace("\\r", "").Replace("\\n", "\\r\\n");
}
public string SerializeEntity(Entity entity)
{
JsonSerializerSettings settings = new()
@@ -161,21 +181,40 @@ public partial class MainViewForm : Form
string result = JsonConvert.SerializeObject(entity, settings);
Type type = EntityOfTypeAttribute.Resolve(entity);
string subResult = JsonConvert.SerializeObject(ResolveEntity(entity), settings);
string subResult = JsonConvert.SerializeObject(ResolveSubEntity(entity), settings);
return result[..^1] + $",\"SubEntity\":{subResult}}}";
}
public IEntity? ResolveEntity(Entity entity)
public IEntity? ResolveSubEntity(Entity entity)
{
switch (entity.Type)
{
case EntityType.Ancestry:
return Context.Ancestries
.Include(a => a.AncestryBoosts)
.FirstOrDefault(e => e.Id == entity.Id);
}
return null;
case EntityType.Background:
return Context.Backgrounds
.Include(b => b.BackgroundBoosts)
.Include(b => b.BackgroundSkills)
.ThenInclude(t => t.Training)
.Include(b => b.BackgroundItems)
.FirstOrDefault(e => e.Id == entity.Id);
case EntityType.Class:
return Context.Classes
.Include(c => c.ClassKeyAbilities)
.Include(c => c.ClassTrainings)
.ThenInclude(t => t.Training)
.Include(c => c.ClassProgressions)
.FirstOrDefault(c => c.Id == entity.Id);
default:
Type type = EntityOfTypeAttribute.Resolve(entity);
return (IEntity?) Context.Find(type, entity.Id);
}
}
public static void JsonToTreeview(TreeView treeView, string jsonString, string rootName)
+4 -4
View File
@@ -65,7 +65,7 @@ schema.AddValue(data); // Добавление данных
## Aonprd (Архивы Нефиса)
Готово: **4** из 70
Готово: **5** из 70
### Общее
- [x] action.yaml
@@ -97,7 +97,7 @@ schema.AddValue(data); // Добавление данных
- [ ] eidolon.yaml
- [ ] element.yaml
- [ ] epithet.yaml
- [ ] feat.yaml
- [x] feat.yaml
- [ ] hazard.yaml
- [ ] hellknight-order.yaml
- [ ] heritage.yaml
@@ -125,8 +125,8 @@ schema.AddValue(data); // Добавление данных
- [ ] rules.yaml
- [ ] sidebar.yaml
- [ ] skill-general-action.yaml
- [ ] skill.yaml
- [ ] source.yaml
- [x] skill.yaml
- [x] source.yaml
- [ ] spell.yaml
- [ ] style.yaml
- [ ] subconscious-mind.yaml