diff --git a/src/module/item/ancestry/data.ts b/src/module/item/ancestry/data.ts index 812aa67a372..04c8954ac5d 100644 --- a/src/module/item/ancestry/data.ts +++ b/src/module/item/ancestry/data.ts @@ -1,8 +1,14 @@ -import { CreatureTrait, Language } from "@actor/creature/index.ts"; -import { AttributeString } from "@actor/types.ts"; -import { ABCSystemData, ABCSystemSource } from "@item/abc/index.ts"; -import { BaseItemSourcePF2e, ItemTraits } from "@item/base/data/system.ts"; -import { Size, TraitsWithRarity, ValuesList } from "@module/data.ts"; +import type { CreatureTrait, Language } from "@actor/creature/index.ts"; +import type { AttributeString } from "@actor/types.ts"; +import { ATTRIBUTE_ABBREVIATIONS } from "@actor/values.ts"; +import { ABCFeatureEntryField, type ABCSystemSource } from "@item/abc/index.ts"; +import { ItemSystemModel, type ItemSystemSchema } from "@item/base/data/model.ts"; +import type { BaseItemSourcePF2e, ItemTraits } from "@item/base/data/system.ts"; +import { SIZES, type Size, type TraitsWithRarity, type ValuesList } from "@module/data.ts"; +import { RarityField } from "@module/model.ts"; +import { RecordField, SlugField } from "@system/schema-data-fields.ts"; +import type { AncestryPF2e } from "./document.ts"; +import fields = foundry.data.fields; type AncestrySource = BaseItemSourcePF2e<"ancestry", AncestrySystemSource>; @@ -40,7 +46,155 @@ interface AncestrySystemSource extends ABCSystemSource { level?: never; } +class AncestrySystemData extends ItemSystemModel { + static override defineSchema(): AncestrySystemSchema { + return { + ...super.defineSchema(), + traits: new fields.SchemaField({ + otherTags: new fields.ArrayField( + new SlugField({ required: true, nullable: false, initial: undefined }), + ), + rarity: new RarityField(), + value: new fields.ArrayField(new fields.StringField({ required: true, blank: false })), + }), + items: new RecordField( + new fields.StringField({ required: true, nullable: false }), + new ABCFeatureEntryField(), + ), + additionalLanguages: new fields.SchemaField({ + count: new fields.NumberField({ nullable: false, initial: 1 }), + value: new fields.ArrayField(new fields.StringField({ required: true, blank: false })), + custom: new fields.StringField(), + }), + alternateAncestryBoosts: new fields.ArrayField( + new fields.StringField({ required: true, nullable: false, choices: [...ATTRIBUTE_ABBREVIATIONS] }), + ), + boosts: new RecordField( + new fields.StringField({ required: true, nullable: false }), + new fields.SchemaField({ + value: new fields.ArrayField( + new fields.StringField({ choices: [...ATTRIBUTE_ABBREVIATIONS], required: true }), + ), + selected: new fields.StringField({ nullable: true }), + }), + ), + flaws: new RecordField( + new fields.StringField({ required: true, nullable: false }), + new fields.SchemaField({ + value: new fields.ArrayField( + new fields.StringField({ choices: [...ATTRIBUTE_ABBREVIATIONS], required: true }), + ), + selected: new fields.StringField({ nullable: true }), + }), + ), + voluntary: new fields.SchemaField( + { + boost: new fields.StringField({ + nullable: true, + required: false, + initial: undefined, + choices: [...ATTRIBUTE_ABBREVIATIONS], + }), + flaws: new fields.ArrayField( + new fields.StringField({ choices: [...ATTRIBUTE_ABBREVIATIONS], required: true }), + ), + }, + { required: false, initial: undefined }, + ), + hp: new fields.NumberField({ required: true, initial: 6, min: 0, max: 12, step: 2, nullable: false }), + languages: new fields.SchemaField({ + value: new fields.ArrayField(new fields.StringField({ required: true, blank: false })), + }), + speed: new fields.NumberField({ required: true, initial: 25, min: 0, max: 60, step: 5, nullable: false }), + size: new fields.StringField({ required: true, nullable: false, initial: "med", choices: [...SIZES] }), + hands: new fields.NumberField({ required: true, initial: 2, min: 0, max: 12, step: 2, nullable: false }), + reach: new fields.NumberField({ required: true, initial: 5, min: 0, max: 25, step: 5, nullable: false }), + vision: new fields.StringField({ + required: true, + nullable: false, + initial: "normal", + choices: ["normal", "darkvision", "low-light-vision"], + }), + }; + } +} + +type BoostOrFlawSchema = { + value: fields.ArrayField>; + selected: fields.StringField; +}; + +type AncestrySystemSchema = Omit & { + traits: fields.SchemaField<{ + otherTags: fields.ArrayField>; + rarity: RarityField; + value: fields.ArrayField>; + }>; + items: RecordField, ABCFeatureEntryField, true, false, true, true>; + additionalLanguages: fields.SchemaField<{ + count: fields.NumberField; + value: fields.ArrayField>; + custom: fields.StringField; + }>; + alternateAncestryBoosts: fields.ArrayField< + fields.StringField + >; + boosts: RecordField< + fields.StringField, + fields.SchemaField, + true, + false, + true, + true + >; + flaws: RecordField< + fields.StringField, + fields.SchemaField, + true, + false, + true, + true + >; + voluntary: fields.SchemaField< + { + boost?: fields.StringField; + flaws: fields.ArrayField>; + }, + { + boost?: AttributeString | null; + flaws: AttributeString[]; + }, + { + boost?: AttributeString | null; + flaws: AttributeString[]; + }, + false, + false, + false + >; + hp: fields.NumberField; + languages: fields.SchemaField<{ + value: fields.ArrayField>; + }>; + speed: fields.NumberField; + size: fields.StringField; + hands: fields.NumberField; + reach: fields.NumberField; + vision: fields.StringField< + "normal" | "darkvision" | "low-light-vision", + "normal" | "darkvision" | "low-light-vision", + true, + false, + true + >; +}; + interface AncestrySystemData - extends Omit, Omit {} + extends + ItemSystemModel, + Omit, "description" | "traits" | "level"> { + traits: AncestryTraits; +} -export type { AncestrySource, AncestrySystemData, AncestrySystemSource, AncestryTraits, CreatureTraits }; +export { AncestrySystemData }; +export type { AncestrySource, AncestrySystemSource, AncestryTraits, CreatureTraits }; diff --git a/src/scripts/hooks/load.ts b/src/scripts/hooks/load.ts index d551e1cc749..2ee1e62021d 100644 --- a/src/scripts/hooks/load.ts +++ b/src/scripts/hooks/load.ts @@ -11,6 +11,7 @@ import { VehicleSystemData } from "@actor/vehicle/data.ts"; import { ItemProxyPF2e } from "@item"; import { AbilitySystemData } from "@item/ability/index.ts"; import { AfflictionSystemData } from "@item/affliction/data.ts"; +import { AncestrySystemData } from "@item/ancestry/data.ts"; import { CampaignFeatureSystemData } from "@item/campaign-feature/data.ts"; import { ClassSystemData } from "@item/class/data.ts"; import { ConditionSystemData } from "@item/condition/data.ts"; @@ -117,6 +118,7 @@ export class Load { CONFIG.Item.dataModels.affliction = AfflictionSystemData; } CONFIG.Item.dataModels.action = AbilitySystemData; + CONFIG.Item.dataModels.ancestry = AncestrySystemData; CONFIG.Item.dataModels.campaignFeature = CampaignFeatureSystemData; CONFIG.Item.dataModels.class = ClassSystemData; CONFIG.Item.dataModels.condition = ConditionSystemData;