import { makeIntField, makeStringField, makeBoolField, makeHtmlField, makeArrayField, fields, } from './fields'; import { CASTING_MODES, SPELL_SCHOOLS, SACRED_DEITIES, SOURCE_BOOKS, AOE_SHAPES, SPELL_DAMAGE_TYPES, TRIGGER_EVENTS, TS_DEFAULT_THRESHOLD, TS_DEFAULT_REQUIRED, } from '../constants'; export class SpellData extends foundry.abstract.TypeDataModel { static defineSchema() { const f = fields(); return { // Identification circle: makeIntField(1, { min: 0, max: 9 }), school: makeStringField('', { blank: true, choices: SPELL_SCHOOLS as unknown as readonly string[] }), discipline: makeStringField(''), deity: makeStringField('', { blank: true, choices: SACRED_DEITIES as unknown as readonly string[] }), sourceBook: makeStringField('', { blank: true, choices: SOURCE_BOOKS as unknown as readonly string[] }), // Casting mode + resources castingMode: makeStringField('standard', { blank: false, choices: CASTING_MODES as unknown as readonly string[] }), manaCost: makeIntField(1, { min: 0 }), bloodCost: makeIntField(0, { min: 0 }), // Difficulty difficulty: new f.SchemaField({ threshold: makeIntField(TS_DEFAULT_THRESHOLD, { min: 2, max: 6 }), successes: makeIntField(TS_DEFAULT_REQUIRED, { min: 1, max: 10 }), }), // Components components: new f.SchemaField({ verbal: makeBoolField(false), somatic: makeBoolField(false), material: makeStringField(''), symbols: makeArrayField(new f.StringField({ blank: false })), }), // Timing & geometry castingTime: makeStringField('1 akcja'), castingTimeRounds: makeIntField(0, { min: 0 }), castingTimeMinutes: makeIntField(0, { min: 0 }), range: makeStringField(''), targets: makeStringField(''), duration: makeStringField(''), areaOfEffect: new f.SchemaField({ shape: makeStringField('point', { blank: false, choices: AOE_SHAPES as unknown as readonly string[] }), x: makeIntField(0, { min: 0 }), y: makeIntField(0, { min: 0 }), unit: makeStringField('m'), }), // Damage damageBase: makeStringField(''), damageType: makeStringField('magical', { blank: false, choices: SPELL_DAMAGE_TYPES as unknown as readonly string[] }), ignoresArmor: makeBoolField(false), // Status effects on hit statusEffects: makeArrayField(new f.StringField({ blank: false })), saveAttribute: makeStringField(''), saveSkill: makeStringField(''), // Requirements requirements: new f.SchemaField({ race: makeArrayField(new f.StringField({ blank: false })), talent: makeArrayField(new f.StringField({ blank: false })), discipline: makeArrayField(new f.StringField({ blank: false })), }), // Flags isSuperspell: makeBoolField(false), requiresGroupCast: makeBoolField(false), minCasters: makeIntField(1, { min: 1 }), nonCombatOnly: makeBoolField(false), // Overcast — structured overcastOptions: makeArrayField(new f.SchemaField({ description: makeStringField(''), manaPerStep: makeIntField(1, { min: 0 }), })), // Reactive triggers triggers: makeArrayField(new f.SchemaField({ event: makeStringField('killWithWeapon', { blank: false, choices: TRIGGER_EVENTS as unknown as readonly string[] }), effect: makeStringField(''), })), // Variable success summons (Przywołanie Istoty z Otchłani) variableSuccesses: makeArrayField(new f.SchemaField({ label: makeStringField(''), successes: makeIntField(1, { min: 1, max: 10 }), })), // Description description: makeHtmlField(''), higherCircles: makeHtmlField(''), // legacy — superseded by overcastOptions // Legacy fields (kept for migration; will be removed in a later release) overcasting: makeStringField(''), complexityLevel: makeIntField(0, { min: 0, max: 10 }), }; } }