Compare commits

...
2 Commits
20 changed files with 424 additions and 133 deletions
@@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using System.Threading;
using Pf2eModel; using Pf2eModel;
using Slugify; using Slugify;
@@ -30,6 +31,8 @@ public class DatabaseHelper
/// </summary> /// </summary>
public int NextEntityId => ++_id; public int NextEntityId => ++_id;
public Lock IdLock { get; } = new();
public DatabaseHelper(Pf2eDbContext context, SlugHelper slugHelper) public DatabaseHelper(Pf2eDbContext context, SlugHelper slugHelper)
{ {
Context = context; Context = context;
@@ -43,6 +43,12 @@ internal class AonprdBuilderGlobals
/// </summary> /// </summary>
public Dictionary<string, string> MergeSources { get; } = []; public Dictionary<string, string> MergeSources { get; } = [];
/// <summary>
/// Словарь сущностей, которые нужно слить с другой/другими.
/// Ключ - пропускаемая сущность. Значение - целевая сущность.
/// </summary>
public Dictionary<string, string> SubclassGroups { get; } = [];
/// <summary> /// <summary>
/// Конструктор класса <see cref="AonprdBuilderGlobals"/>. /// Конструктор класса <see cref="AonprdBuilderGlobals"/>.
/// </summary> /// </summary>
@@ -60,6 +66,7 @@ internal class AonprdBuilderGlobals
SlugSuffixes = JsonToDictionary(json, "SlugSuffixes"); SlugSuffixes = JsonToDictionary(json, "SlugSuffixes");
LegacyRemasterExtra = JsonToDictionary(json, "LegacyRemasterExtra"); LegacyRemasterExtra = JsonToDictionary(json, "LegacyRemasterExtra");
MergeSources = JsonToDictionary(json, "MergeSources"); MergeSources = JsonToDictionary(json, "MergeSources");
SubclassGroups = JsonToDictionary(json, "SubclassGroups");
} }
} }
@@ -146,8 +146,12 @@ internal abstract class AbstractEntityProcessor(
/// Генерация основных полей корневой сущности. /// Генерация основных полей корневой сущности.
/// </summary> /// </summary>
protected virtual void AddEntity() protected virtual void AddEntity()
{
lock (Helper.IdLock)
{ {
Entity.Id = Helper.NextEntityId; Entity.Id = Helper.NextEntityId;
}
Entity.Type = Type; Entity.Type = Type;
Entity.Name[LocaleType.English] = Input.GetRequired<string>("name"); Entity.Name[LocaleType.English] = Input.GetRequired<string>("name");
Entity.Img = ""; Entity.Img = "";
@@ -63,39 +63,8 @@ internal abstract class AbstractSubclassProcessor(
/// <returns>CLR-представления группы подклассов.</returns> /// <returns>CLR-представления группы подклассов.</returns>
public SubclassGroup GetGroup() public SubclassGroup GetGroup()
{ {
SubclassGroup? group = Context.SubclassGroups.FirstOrDefault(g => return Context.SubclassGroups.First(g =>
Pf2eDbContext.LocaleSearch(g.Entity.Name, GroupName) Pf2eDbContext.LocaleSearch(g.Entity.Name, GroupName)
); );
if (group is not null)
{
return group;
}
Class? cl = ClassName is not null
? Context.Classes.FirstOrDefault(c =>
Pf2eDbContext.LocaleSearch(c.Entity.Name, GroupName)
)
: null;
Entity groupEntity = new()
{
Id = Helper.NextEntityId,
Type = EntityType.SubclassGroup,
Img = "",
Description = "",
Rarity = EntityRarity.Common,
IsTranslated = false,
IsChecked = false,
Name = { [LocaleType.English] = GroupName },
Slug = Helper.GenerateSlug(GroupName),
};
Context.Entities.Add(groupEntity);
group = new() { Entity = groupEntity, Class = cl };
Context.SubclassGroups.Add(group);
return group;
} }
} }
@@ -1,5 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.EntityFrameworkCore;
using Pf2eDataScrapper.Helpers; using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers; using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
using Pf2eDataScrapper.Processors; using Pf2eDataScrapper.Processors;
@@ -22,10 +24,8 @@ namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Subclasse
Description = "Apparitions", Description = "Apparitions",
Group = ProcessorGroupEnum.AonprdSubclasses Group = ProcessorGroupEnum.AonprdSubclasses
)] )]
[ProcessorDependencies( [ProcessorDependencies(["aonprd:subclass-group"])]
["aonprd:trait", "aonprd:source", "aonprd:class", "aonprd:spell", "aonprd:skill"] internal partial class ApparitionProcessor(
)]
internal class ApparitionProcessor(
ProcessorInput input, ProcessorInput input,
StringHelper stringHelper, StringHelper stringHelper,
DatabaseHelper helper, DatabaseHelper helper,
@@ -44,8 +44,17 @@ internal class ApparitionProcessor(
/// <inheritdoc/> /// <inheritdoc/>
public override void ProcessObject() public override void ProcessObject()
{ {
// Spells AddSpells(Input.GetRequired<string>("spell_markdown"));
string spellMd = Input.GetRequired<string>("spell_markdown"); AddFocal(Entity.Description);
AddTrainings(Input.GetRequired<string>("skill_markdown"));
}
/// <summary>
/// Добавление заклинаний.
/// </summary>
/// <param name="spellMd"></param>
public void AddSpells(string spellMd)
{
List<string> spellUrls = StringHelper List<string> spellUrls = StringHelper
.ParseMarkdownLinks(spellMd) .ParseMarkdownLinks(spellMd)
.Links.Select(l => l.Url) .Links.Select(l => l.Url)
@@ -65,10 +74,31 @@ internal class ApparitionProcessor(
{ {
Object.Entities.Add(spellEntity); Object.Entities.Add(spellEntity);
} }
}
// Trainings /// <summary>
string trainingMd = Input.GetRequired<string>("skill_markdown"); /// Добавление заклинания сосуда.
/// </summary>
/// <param name="description"></param>
public void AddFocal(string description)
{
Match match = VesselSpellMarkdownRegex().Match(description);
string aonprdId = $"spell-{match.Groups[1].Value}";
var entity = Context
.EntityExternals.Where(x => x.ExternalId == aonprdId)
.Select(x => x.Entity)
.First();
Object.Entities.Add(entity);
}
/// <summary>
/// Добавление тренировок.
/// </summary>
/// <param name="trainingMd"></param>
public void AddTrainings(string trainingMd)
{
List<string> trainingNames = trainingMd.Split(", ").ToList(); List<string> trainingNames = trainingMd.Split(", ").ToList();
List<Training> trainings = Context List<Training> trainings = Context
.Trainings.Where(t => Pf2eDbContext.LocaleSearchArray(t.Name, trainingNames)) .Trainings.Where(t => Pf2eDbContext.LocaleSearchArray(t.Name, trainingNames))
@@ -95,7 +125,10 @@ internal class ApparitionProcessor(
} }
/// <inheritdoc/> /// <inheritdoc/>
protected override string GetDescription() => //protected override string GetDescription() =>
base.GetDescription() // base.GetDescription()
+ AddedDescription(["skill_markdown", "spell_markdown", "summary_markdown"]); // + AddedDescription(["skill_markdown", "spell_markdown", "summary_markdown"]);
[GeneratedRegex(@"\*\*Vessel Spell\*\* \[.*?\]\(/Spells\.aspx\?ID=(\d+)\)")]
private static partial Regex VesselSpellMarkdownRegex();
} }
@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Finalization;
using Pf2eDataScrapper.Processors.Attributes;
using Pf2eDataScrapper.Processors.Definitions;
using Pf2eDataScrapper.Processors.Factory;
using Pf2eModel;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Common.I18n;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model.Structure;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Subclasses;
[ProcessorFactory(
"aonprd:subclass-group",
ProcessorType = typeof(SubclassGroupProcessor),
Description = "Группы подклассов",
Group = ProcessorGroupEnum.AonprdSubclasses,
Parallel = true
)]
[ProcessorDependencies(
["aonprd:trait", "aonprd:source", "aonprd:class", "aonprd:spell", "aonprd:skill"]
)]
internal class SubclassGroupProcessorFactory(
IServiceProvider serviceProvider,
AonprdBuilderGlobals globals
) : AbstractProcessorFactory
{
public IServiceProvider ServiceProvider { get; } = serviceProvider;
public AonprdBuilderGlobals Globals { get; } = globals;
public override int Count() => Globals.SubclassGroups.Count;
public override IEnumerable<Tuple<string, IProcessor>> GetEnumerator()
{
foreach ((string key, string value) in Globals.SubclassGroups)
{
var processor =
value == "_null"
? ActivatorUtilities.CreateInstance<SubclassGroupProcessor>(
ServiceProvider,
key
)
: ActivatorUtilities.CreateInstance<SubclassGroupProcessor>(
ServiceProvider,
key,
value
);
yield return new($"{key} -> {value}", processor);
}
}
}
internal class SubclassGroupProcessor(string groupName, string? className, DatabaseHelper helper)
: IProcessor
{
public string GroupName { get; } = groupName;
public string? ClassName { get; } = className;
public DatabaseHelper Helper { get; } = helper;
public SubclassGroupProcessor(string groupName, DatabaseHelper helper)
: this(groupName, null, helper) { }
public Pf2eDbContext Context { get; } = new();
public void Process()
{
Class? cl = ClassName is not null
? Context.Classes.FirstOrDefault(c =>
Pf2eDbContext.LocaleSearch(c.Entity.Name, GroupName)
)
: null;
int id;
lock (Helper.IdLock)
{
id = Helper.NextEntityId;
}
Entity groupEntity = new()
{
Id = id,
Type = EntityType.SubclassGroup,
Img = "",
Description = "",
Rarity = EntityRarity.Common,
IsTranslated = false,
IsChecked = false,
Name = { [LocaleType.English] = GroupName },
Slug = Helper.GenerateSlug(GroupName),
};
Context.Entities.Add(groupEntity);
SubclassGroup group = new() { Entity = groupEntity, Class = cl };
Context.SubclassGroups.Add(group);
}
public void Save()
{
Context.SaveChanges();
}
}
@@ -37,16 +37,19 @@ internal class AncestryProcessor(
/// <inheritdoc/> /// <inheritdoc/>
protected override void Add() => Context.Ancestries.Add(Object); protected override void Add() => Context.Ancestries.Add(Object);
public override void Check()
{
base.Check();
if (Input.GetRequired<string>("type") != "Ancestry")
{
throw new SkipItemException(Input.GetRequired<string>("name"), "не родословная");
}
}
/// <inheritdoc/> /// <inheritdoc/>
public override void Process() public override void Process()
{ {
string type = Input.GetRequired<string>("type");
if (type != "Ancestry")
{
throw new SkipItemException(Input.GetRequired<string>("name"), "not an ancestry");
}
base.Process(); base.Process();
Object.Size = Input Object.Size = Input
@@ -46,14 +46,7 @@ internal class FeatProcessor(
? FeatCategory.Class ? FeatCategory.Class
: FeatCategory.Uncategorized; : FeatCategory.Uncategorized;
AonprdProcessorInputExtension.ActionStruct action = Input.ResolveActionString( Object.Actions = Input.EnumOptional("actions", ActionEnum.Unknown);
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 = GenerateJsonString( Object.Extra = GenerateJsonString(
"archetype", "archetype",
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
using Pf2eDataScrapper.Processors;
using Pf2eDataScrapper.Processors.Attributes;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model.Structure;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Types;
[ProcessorCollection(
"aonprd:heritage",
InnerType = "heritage",
CompendiumType = ProcessorCompendiumEnum.Aonprd,
Description = "Наследства",
Group = ProcessorGroupEnum.AonprdEntities
)]
[ProcessorDependencies(["aonprd:ancestry"])]
internal class HeritageProcessor(
ProcessorInput input,
StringHelper stringHelper,
DatabaseHelper helper,
AonprdBuilderGlobals globals
) : AbstractEntityProcessor(input, stringHelper, helper, globals)
{
/// <inheritdoc/>
public override EntityType Type => EntityType.Heritage;
/// <inheritdoc/>
public override Heritage Object { get; } = new();
/// <inheritdoc/>
protected override void Add() => Context.Heritages.Add(Object);
/// <inheritdoc/>
public override void Process()
{
base.Process();
}
}
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
using Pf2eDataScrapper.Processors;
using Pf2eDataScrapper.Processors.Attributes;
using Pf2eModel.Model.Enum;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Types;
[ProcessorCollection(
"aonprd:skill-general-action",
InnerType = "skill-general-action",
CompendiumType = ProcessorCompendiumEnum.Aonprd,
Description = "Действия скиллов",
Group = ProcessorGroupEnum.AonprdEntities
)]
[ProcessorDependencies(["aonprd:trait", "aonprd:source"])]
internal class SkillActionsProcessor(
ProcessorInput input,
StringHelper stringHelper,
DatabaseHelper helper,
AonprdBuilderGlobals globals
) : AbstractEntityProcessor(input, stringHelper, helper, globals)
{
/// <inheritdoc/>
public override EntityType Type => EntityType.Action;
/// <inheritdoc/>
public override Pf2eModel.Model.Structure.Action Object { get; } = new();
/// <inheritdoc/>
protected override void Add() => Context.Actions.Add(Object);
/// <inheritdoc/>
public override void Process()
{
Check();
base.Process();
Object.Actions = ActionEnum.Other;
Object.Category = ActionCategory.SkillAction;
}
/// <inheritdoc/>
protected override string[] AddedDescriptionPaths() =>
[
"cost_markdown",
"trait_markdown",
"source_markdown",
"search_markdown",
"requirement_markdown",
"trigger_markdown",
"summary_markdown",
];
}
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Pf2eDataScrapper.Helpers;
using Pf2eDataScrapper.Importers.Implementations.Aonprd.Helpers;
using Pf2eDataScrapper.Processors;
using Pf2eDataScrapper.Processors.Attributes;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model.Structure;
namespace Pf2eDataScrapper.Importers.Implementations.Aonprd.Processors.Types;
[ProcessorCollection(
"aonprd:versitile-heritage",
InnerType = "ancestry",
CompendiumType = ProcessorCompendiumEnum.Aonprd,
Description = "Универсальные наследства",
Group = ProcessorGroupEnum.AonprdEntities
)]
[ProcessorDependencies(["aonprd:ancestry"])]
internal class VersitileHeritageProcessor(
ProcessorInput input,
StringHelper stringHelper,
DatabaseHelper helper,
AonprdBuilderGlobals globals
) : AbstractEntityProcessor(input, stringHelper, helper, globals)
{
/// <inheritdoc/>
public override EntityType Type => EntityType.Heritage;
/// <inheritdoc/>
public override Heritage Object { get; } = new();
/// <inheritdoc/>
protected override void Add() => Context.Heritages.Add(Object);
public override void Check()
{
base.Check();
if (Input.GetRequired<string>("type") == "Ancestry")
{
throw new SkipItemException(
Input.GetRequired<string>("name"),
"не универсальное наследие"
);
}
}
/// <inheritdoc/>
public override void Process()
{
base.Process();
}
}
@@ -77,6 +77,38 @@
"spell-571": "spell-1975", "spell-571": "spell-1975",
"spell-578": "spell-1566", "spell-578": "spell-1566",
"spell-654": "spell-819" "spell-654": "spell-819"
},
"SubclassGroups": {
"Research Field": "Alchemist",
"Apparition": "Animist",
"Practice": "Animist",
"Instinct": "Barbarian",
"Muse": "Bard",
"Cause": "Champion",
"Tenet": "Champion",
"Doctrine": "Cleric",
"Druidic Order": "Druid",
"Methodology": "Investigator",
"Element": "Kineticist",
"Hybrid Study": "Magus",
"Mystery": "Oracle",
"Conscious Mind": "Psychic",
"Subconscious Mind": "Psychic",
"Hunters Edge": "Ranger",
"Racket": "Rogue",
"Bloodline": "Sorcerer",
"Style": "Swashbuckler",
"Implement": "Thaumaturge",
"Lesson": "Witch",
"Patron": "Witch",
"Arcane School": "Wizard",
"Arcane Thesis": "Wizard",
"Way": "Gunslinger",
"Innovation": "Innovator",
"Ikon": "Exemplar",
"Epithet": "Exemplar",
"Hellknight Order": "_null",
"Eidolon": "_null"
} }
} }
} }
@@ -63,7 +63,7 @@ internal class EntityFormViewModel : ViewModelBase
private void LoadEntityTypes() private void LoadEntityTypes()
{ {
EntityTypes = Context.Entities.Select(e => e.Type).Distinct().ToList(); EntityTypes = Context.Entities.Select(e => e.Type).Distinct().Order().ToList();
OnPropertyChanged(nameof(EntityTypes)); OnPropertyChanged(nameof(EntityTypes));
SelectedEntityTypeStore.SelectedEntityType = EntityTypes.Any() ? EntityTypes.First() : null; SelectedEntityTypeStore.SelectedEntityType = EntityTypes.Any() ? EntityTypes.First() : null;
@@ -13,7 +13,7 @@ using Pf2eModel.Model.Enum;
namespace Pf2eModel.Migrations namespace Pf2eModel.Migrations
{ {
[DbContext(typeof(Pf2eDbContext))] [DbContext(typeof(Pf2eDbContext))]
[Migration("20250521155437_1")] [Migration("20250522130215_1")]
partial class _1 partial class _1
{ {
/// <inheritdoc /> /// <inheritdoc />
@@ -24,7 +24,7 @@ namespace Pf2eModel.Migrations
.HasAnnotation("ProductVersion", "9.0.4") .HasAnnotation("ProductVersion", "9.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_category", new[] { "archetype", "army_tactic", "army_war_action", "class-feat", "class-feature", "defensive", "familiar", "interaction", "kingdom_activity", "kingdom_feat", "kingdom_feature", "offensive", "unknown" }); NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_category", new[] { "archetype", "army_tactic", "army_war_action", "class-feat", "class-feature", "defensive", "familiar", "interaction", "kingdom_activity", "kingdom_feat", "kingdom_feature", "offensive", "skill-action", "unknown" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_enum", new[] { "1", "1 hour", "1 minute", "1-2", "1-3", "10 minutes", "2", "2-3", "2/2 rounds", "3", "30 minutes", "5 minutes", "free", "free/1", "other", "passive", "reaction", "reaction/1", "reaction/2", "reaction/3", "unknown" }); NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_enum", new[] { "1", "1 hour", "1 minute", "1-2", "1-3", "10 minutes", "2", "2-3", "2/2 rounds", "3", "30 minutes", "5 minutes", "free", "free/1", "other", "passive", "reaction", "reaction/1", "reaction/2", "reaction/3", "unknown" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "cha", "con", "dex", "free", "int", "str", "wis" }); NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "cha", "con", "dex", "free", "int", "str", "wis" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "class_progression_type", new[] { "ancestry_feat", "attribute_increase", "class_feat", "entity", "general_feat", "skill_feat", "skill_increase" }); NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "class_progression_type", new[] { "ancestry_feat", "attribute_increase", "class_feat", "entity", "general_feat", "skill_feat", "skill_increase" });
@@ -548,10 +548,16 @@ namespace Pf2eModel.Migrations
.HasColumnOrder(2) .HasColumnOrder(2)
.HasComment("Количество действий"); .HasComment("Количество действий");
b.Property<ActionCategory>("Category")
.HasColumnType("action_category")
.HasColumnName("category")
.HasColumnOrder(3)
.HasComment("Категория действия");
b.Property<string>("Extra") b.Property<string>("Extra")
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("extra") .HasColumnName("extra")
.HasColumnOrder(3) .HasColumnOrder(4)
.HasComment("Дополнительная информация"); .HasComment("Дополнительная информация");
b.HasKey("Id") b.HasKey("Id")
@@ -1239,8 +1245,8 @@ namespace Pf2eModel.Migrations
.HasColumnOrder(1) .HasColumnOrder(1)
.HasComment("Идентификатор"); .HasComment("Идентификатор");
b.Property<int?>("Actions") b.Property<ActionEnum>("Actions")
.HasColumnType("integer") .HasColumnType("action_enum")
.HasColumnName("actions") .HasColumnName("actions")
.HasColumnOrder(5) .HasColumnOrder(5)
.HasComment("Количество действий"); .HasComment("Количество действий");
@@ -1254,35 +1260,15 @@ namespace Pf2eModel.Migrations
b.Property<string>("Extra") b.Property<string>("Extra")
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("extra") .HasColumnName("extra")
.HasColumnOrder(10) .HasColumnOrder(6)
.HasComment("Дополнительная информация"); .HasComment("Дополнительная информация");
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") b.Property<int>("Level")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("level") .HasColumnName("level")
.HasColumnOrder(4) .HasColumnOrder(4)
.HasComment("Уровень способности"); .HasComment("Уровень способности");
b.Property<int?>("MaxActions")
.HasColumnType("integer")
.HasColumnName("max_actions")
.HasColumnOrder(6);
b.HasKey("Id") b.HasKey("Id")
.HasName("pk_feats"); .HasName("pk_feats");
@@ -14,7 +14,7 @@ namespace Pf2eModel.Migrations
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.AlterDatabase() migrationBuilder.AlterDatabase()
.Annotation("Npgsql:Enum:action_category", "archetype,army_tactic,army_war_action,class-feat,class-feature,defensive,familiar,interaction,kingdom_activity,kingdom_feat,kingdom_feature,offensive,unknown") .Annotation("Npgsql:Enum:action_category", "archetype,army_tactic,army_war_action,class-feat,class-feature,defensive,familiar,interaction,kingdom_activity,kingdom_feat,kingdom_feature,offensive,skill-action,unknown")
.Annotation("Npgsql:Enum:action_enum", "1,1 hour,1 minute,1-2,1-3,10 minutes,2,2-3,2/2 rounds,3,30 minutes,5 minutes,free,free/1,other,passive,reaction,reaction/1,reaction/2,reaction/3,unknown") .Annotation("Npgsql:Enum:action_enum", "1,1 hour,1 minute,1-2,1-3,10 minutes,2,2-3,2/2 rounds,3,30 minutes,5 minutes,free,free/1,other,passive,reaction,reaction/1,reaction/2,reaction/3,unknown")
.Annotation("Npgsql:Enum:attribute_values", "cha,con,dex,free,int,str,wis") .Annotation("Npgsql:Enum:attribute_values", "cha,con,dex,free,int,str,wis")
.Annotation("Npgsql:Enum:class_progression_type", "ancestry_feat,attribute_increase,class_feat,entity,general_feat,skill_feat,skill_increase") .Annotation("Npgsql:Enum:class_progression_type", "ancestry_feat,attribute_increase,class_feat,entity,general_feat,skill_feat,skill_increase")
@@ -136,6 +136,7 @@ namespace Pf2eModel.Migrations
{ {
id = table.Column<int>(type: "integer", nullable: false, comment: "Идентификатор"), id = table.Column<int>(type: "integer", nullable: false, comment: "Идентификатор"),
actions = table.Column<ActionEnum>(type: "action_enum", nullable: false, comment: "Количество действий"), actions = table.Column<ActionEnum>(type: "action_enum", nullable: false, comment: "Количество действий"),
category = table.Column<ActionCategory>(type: "action_category", nullable: false, comment: "Категория действия"),
extra = table.Column<string>(type: "text", nullable: true, comment: "Дополнительная информация") extra = table.Column<string>(type: "text", nullable: true, comment: "Дополнительная информация")
}, },
constraints: table => constraints: table =>
@@ -275,11 +276,7 @@ namespace Pf2eModel.Migrations
id = table.Column<int>(type: "integer", nullable: false, comment: "Идентификатор"), id = table.Column<int>(type: "integer", nullable: false, comment: "Идентификатор"),
category = table.Column<FeatCategory>(type: "feat_category", nullable: false, comment: "Категория способности"), category = table.Column<FeatCategory>(type: "feat_category", nullable: false, comment: "Категория способности"),
level = table.Column<int>(type: "integer", nullable: false, comment: "Уровень способности"), level = table.Column<int>(type: "integer", nullable: false, comment: "Уровень способности"),
actions = table.Column<int>(type: "integer", nullable: true, comment: "Количество действий"), actions = table.Column<ActionEnum>(type: "action_enum", nullable: false, comment: "Количество действий"),
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),
extra = table.Column<string>(type: "text", nullable: true, comment: "Дополнительная информация") extra = table.Column<string>(type: "text", nullable: true, comment: "Дополнительная информация")
}, },
constraints: table => constraints: table =>
@@ -21,7 +21,7 @@ namespace Pf2eModel.Migrations
.HasAnnotation("ProductVersion", "9.0.4") .HasAnnotation("ProductVersion", "9.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_category", new[] { "archetype", "army_tactic", "army_war_action", "class-feat", "class-feature", "defensive", "familiar", "interaction", "kingdom_activity", "kingdom_feat", "kingdom_feature", "offensive", "unknown" }); NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_category", new[] { "archetype", "army_tactic", "army_war_action", "class-feat", "class-feature", "defensive", "familiar", "interaction", "kingdom_activity", "kingdom_feat", "kingdom_feature", "offensive", "skill-action", "unknown" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_enum", new[] { "1", "1 hour", "1 minute", "1-2", "1-3", "10 minutes", "2", "2-3", "2/2 rounds", "3", "30 minutes", "5 minutes", "free", "free/1", "other", "passive", "reaction", "reaction/1", "reaction/2", "reaction/3", "unknown" }); NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "action_enum", new[] { "1", "1 hour", "1 minute", "1-2", "1-3", "10 minutes", "2", "2-3", "2/2 rounds", "3", "30 minutes", "5 minutes", "free", "free/1", "other", "passive", "reaction", "reaction/1", "reaction/2", "reaction/3", "unknown" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "cha", "con", "dex", "free", "int", "str", "wis" }); NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "attribute_values", new[] { "cha", "con", "dex", "free", "int", "str", "wis" });
NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "class_progression_type", new[] { "ancestry_feat", "attribute_increase", "class_feat", "entity", "general_feat", "skill_feat", "skill_increase" }); NpgsqlModelBuilderExtensions.HasPostgresEnum(modelBuilder, "class_progression_type", new[] { "ancestry_feat", "attribute_increase", "class_feat", "entity", "general_feat", "skill_feat", "skill_increase" });
@@ -545,10 +545,16 @@ namespace Pf2eModel.Migrations
.HasColumnOrder(2) .HasColumnOrder(2)
.HasComment("Количество действий"); .HasComment("Количество действий");
b.Property<ActionCategory>("Category")
.HasColumnType("action_category")
.HasColumnName("category")
.HasColumnOrder(3)
.HasComment("Категория действия");
b.Property<string>("Extra") b.Property<string>("Extra")
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("extra") .HasColumnName("extra")
.HasColumnOrder(3) .HasColumnOrder(4)
.HasComment("Дополнительная информация"); .HasComment("Дополнительная информация");
b.HasKey("Id") b.HasKey("Id")
@@ -1236,8 +1242,8 @@ namespace Pf2eModel.Migrations
.HasColumnOrder(1) .HasColumnOrder(1)
.HasComment("Идентификатор"); .HasComment("Идентификатор");
b.Property<int?>("Actions") b.Property<ActionEnum>("Actions")
.HasColumnType("integer") .HasColumnType("action_enum")
.HasColumnName("actions") .HasColumnName("actions")
.HasColumnOrder(5) .HasColumnOrder(5)
.HasComment("Количество действий"); .HasComment("Количество действий");
@@ -1251,35 +1257,15 @@ namespace Pf2eModel.Migrations
b.Property<string>("Extra") b.Property<string>("Extra")
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("extra") .HasColumnName("extra")
.HasColumnOrder(10) .HasColumnOrder(6)
.HasComment("Дополнительная информация"); .HasComment("Дополнительная информация");
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") b.Property<int>("Level")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("level") .HasColumnName("level")
.HasColumnOrder(4) .HasColumnOrder(4)
.HasComment("Уровень способности"); .HasComment("Уровень способности");
b.Property<int?>("MaxActions")
.HasColumnType("integer")
.HasColumnName("max_actions")
.HasColumnOrder(6);
b.HasKey("Id") b.HasKey("Id")
.HasName("pk_feats"); .HasName("pk_feats");
+3
View File
@@ -19,6 +19,9 @@ public enum ActionCategory
[PgName("archetype")] [PgName("archetype")]
Archetype, Archetype,
[PgName("skill-action")]
SkillAction,
[PgName("class-feature")] [PgName("class-feature")]
ClassFeature, ClassFeature,
+8 -1
View File
@@ -30,9 +30,16 @@ public class Action : IEntity
public ActionEnum Actions { get; set; } = ActionEnum.Unknown; public ActionEnum Actions { get; set; } = ActionEnum.Unknown;
/// <summary> /// <summary>
/// Дополнительная информация. /// Категория действия.
/// </summary> /// </summary>
[Column(Order = 3)] [Column(Order = 3)]
[Comment("Категория действия")]
public ActionCategory Category { get; set; } = ActionCategory.Unknown;
/// <summary>
/// Дополнительная информация.
/// </summary>
[Column(Order = 4)]
[Comment("Дополнительная информация")] [Comment("Дополнительная информация")]
public string? Extra { get; set; } public string? Extra { get; set; }
} }
+5 -14
View File
@@ -37,26 +37,17 @@ public class Feat : IEntity
[Comment("Уровень способности")] [Comment("Уровень способности")]
public int Level { get; set; } public int Level { get; set; }
/// <summary>
/// Количество действий, необходимых для применения фита.
/// </summary>
[Column(Order = 5)] [Column(Order = 5)]
[Comment("Количество действий")] [Comment("Количество действий")]
public int? Actions { get; set; } = null; public ActionEnum Actions { get; set; } = ActionEnum.Other;
[Column(Order = 6)]
public int? MaxActions { get; set; } = null;
[Column(Order = 7)]
public bool IsReaction { get; set; } = false;
[Column(Order = 8)]
public bool IsFreeAction { get; set; } = false;
[Column(Order = 9)]
public bool IsPassive { get; set; } = false;
/// <summary> /// <summary>
/// Дополнительная информация. /// Дополнительная информация.
/// </summary> /// </summary>
[Column(Order = 10)] [Column(Order = 6)]
[Comment("Дополнительная информация")] [Comment("Дополнительная информация")]
public string? Extra { get; set; } public string? Extra { get; set; }
+6 -1
View File
@@ -60,7 +60,7 @@ schema.AddValue(data); // Добавление данных
## Aonprd (Архивы Нефиса) ## Aonprd (Архивы Нефиса)
### Общее (14 из 36) ### Общее (15 из 36)
- [x] action.yaml - [x] action.yaml
- [x] ancestry.yaml - [x] ancestry.yaml
@@ -175,8 +175,13 @@ schema.AddValue(data); // Добавление данных
- [ ] class-kit.yaml - [ ] class-kit.yaml
- [ ] class-sample.yaml - [ ] class-sample.yaml
### Что не дополучено с Архивов
- Ссылка наследий (`heritage`) на родословные (`ancestry`).
# TODO # TODO
- Добавление экипировки - Добавление экипировки
- Добавление бестиария - Добавление бестиария