Iteam cleanup + less migration
This commit is contained in:
@@ -2,7 +2,6 @@ export { default as OathHammerCharacter } from "./character.mjs"
|
||||
export { default as OathHammerNPC } from "./npc.mjs"
|
||||
export { default as OathHammerWeapon } from "./weapon.mjs"
|
||||
export { default as OathHammerArmor } from "./armor.mjs"
|
||||
export { default as OathHammerShield } from "./shield.mjs"
|
||||
export { default as OathHammerAmmunition } from "./ammunition.mjs"
|
||||
export { default as OathHammerEquipment } from "./equipment.mjs"
|
||||
export { default as OathHammerSpell } from "./spell.mjs"
|
||||
@@ -10,4 +9,3 @@ export { default as OathHammerMiracle } from "./miracle.mjs"
|
||||
export { default as OathHammerMagicItem } from "./magic-item.mjs"
|
||||
export { default as OathHammerAbility } from "./ability.mjs"
|
||||
export { default as OathHammerOath } from "./oath.mjs"
|
||||
export { default as OathHammerCondition } from "./condition.mjs"
|
||||
|
||||
@@ -3,13 +3,28 @@ import { SYSTEM } from "../config/system.mjs"
|
||||
export default class OathHammerAbility extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const requiredInteger = { required: true, nullable: false, integer: true }
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.abilityType = new fields.StringField({ required: true, initial: "class-ability", choices: SYSTEM.ABILITY_TYPE_CHOICES })
|
||||
|
||||
// lineage-trait (racial) or class-ability (starting or advancement trait)
|
||||
schema.abilityType = new fields.StringField({
|
||||
required: true, initial: "class-ability", choices: SYSTEM.ABILITY_TYPE_CHOICES
|
||||
})
|
||||
|
||||
// Which class or lineage this trait belongs to (e.g. "Berserker", "Wood Elf")
|
||||
schema.source = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.prerequisite = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.passiveBonus = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// When uses reset: none = passive (always on), encounter, day
|
||||
schema.usagePeriod = new fields.StringField({
|
||||
required: true, initial: "none", choices: SYSTEM.ABILITY_USAGE_PERIOD
|
||||
})
|
||||
|
||||
// Maximum uses per period. 0 = passive / unlimited.
|
||||
// Use a descriptive string when the limit is formula-based
|
||||
// (e.g. "equal to Fate ranks") — store the note in the description.
|
||||
schema.maxUses = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
@@ -7,11 +7,21 @@ export default class OathHammerAmmunition extends foundry.abstract.TypeDataModel
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.ammoType = new fields.StringField({ required: true, initial: "arrow", choices: SYSTEM.AMMO_TYPE_CHOICES })
|
||||
schema.quantity = new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 })
|
||||
schema.properties = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.cost = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.currency = new fields.StringField({ required: true, initial: "gp", choices: SYSTEM.CURRENCY_CHOICES })
|
||||
|
||||
// Ammo type determines special effect (p.88):
|
||||
// bodkin → −1 to target's armor roll
|
||||
// envenomed → poison damage
|
||||
// incendiary → flaming damage
|
||||
schema.ammoType = new fields.StringField({ required: true, initial: "standard", choices: SYSTEM.AMMO_TYPE_CHOICES })
|
||||
|
||||
// Quantity of individual arrows/bolts in this stack
|
||||
schema.quantity = new fields.NumberField({ ...requiredInteger, initial: 20, min: 0 })
|
||||
|
||||
// Rarity: DV for Fortune check when purchasing; 0 = always available
|
||||
schema.rarity = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 6 })
|
||||
|
||||
schema.cost = new fields.NumberField({ required: true, nullable: false, initial: 0, min: 0 })
|
||||
schema.currency = new fields.StringField({ required: true, initial: "sp", choices: SYSTEM.CURRENCY_CHOICES })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
@@ -7,14 +7,41 @@ export default class OathHammerArmor extends foundry.abstract.TypeDataModel {
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
// Proficiency group: light / medium / heavy (p.88)
|
||||
schema.armorType = new fields.StringField({ required: true, initial: "light", choices: SYSTEM.ARMOR_TYPE_CHOICES })
|
||||
schema.armorRating = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.movementPenalty = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.equipped = new fields.BooleanField({ required: true, initial: false })
|
||||
schema.encumbrance = new fields.NumberField({ required: true, initial: 1, min: 0 })
|
||||
schema.cost = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
// Armor Value (AV): number of armor dice rolled when receiving damage
|
||||
schema.armorValue = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 12 })
|
||||
|
||||
// Penalty: modifier to Acrobatics checks AND defense rolls (0, -1, -2, -3…)
|
||||
schema.penalty = new fields.NumberField({ ...requiredInteger, initial: 0, min: -5, max: 0 })
|
||||
|
||||
// Item slots occupied while worn or stowed
|
||||
schema.slots = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
// Armor traits: Clanging (−1 Stealth) / Reinforced (red dice for armor rolls)
|
||||
schema.traits = new fields.SetField(
|
||||
new fields.StringField({ choices: SYSTEM.ARMOR_TRAITS })
|
||||
)
|
||||
|
||||
// Rarity: DV for Fortune check when purchasing; 0 = always available
|
||||
schema.rarity = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 6 })
|
||||
|
||||
schema.equipped = new fields.BooleanField({ initial: false })
|
||||
schema.cost = new fields.NumberField({ required: true, nullable: false, initial: 0, min: 0 })
|
||||
schema.currency = new fields.StringField({ required: true, initial: "gp", choices: SYSTEM.CURRENCY_CHOICES })
|
||||
|
||||
// --- Magic properties (only relevant when isMagic = true) ---
|
||||
schema.isMagic = new fields.BooleanField({ initial: false })
|
||||
schema.magicQuality = new fields.StringField({
|
||||
required: false, nullable: true, initial: null, choices: SYSTEM.MAGIC_QUALITY_CHOICES
|
||||
})
|
||||
schema.isCursed = new fields.BooleanField({ initial: false })
|
||||
schema.magicEffect = new fields.HTMLField({ required: false, textSearch: true })
|
||||
// Class/lineage restriction, e.g. "Dwarves only" (empty = no restriction)
|
||||
schema.classRestriction = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ export default class OathHammerCharacter extends foundry.abstract.TypeDataModel
|
||||
|
||||
schema.biodata = new fields.SchemaField({
|
||||
lineage: new fields.StringField({ required: true, initial: "dwarf", choices: SYSTEM.LINEAGE_CHOICES }),
|
||||
class: new fields.StringField({ required: true, initial: "fighter", choices: SYSTEM.CLASS_CHOICES }),
|
||||
class: new fields.StringField({ required: true, initial: "soldier", choices: SYSTEM.CLASS_CHOICES }),
|
||||
age: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
gender: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
height: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
|
||||
export default class OathHammerCondition extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.conditionType = new fields.StringField({ required: true, initial: "stunned", choices: SYSTEM.CONDITION_TYPE_CHOICES })
|
||||
schema.duration = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.source = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
static LOCALIZATION_PREFIXES = ["OATHHAMMER.Condition"]
|
||||
}
|
||||
@@ -7,10 +7,22 @@ export default class OathHammerEquipment extends foundry.abstract.TypeDataModel
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
// Sub-category matching the rulebook sections (pp.90-96)
|
||||
schema.itemType = new fields.StringField({ required: true, initial: "misc", choices: SYSTEM.EQUIPMENT_TYPE_CHOICES })
|
||||
|
||||
schema.quantity = new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 })
|
||||
schema.weight = new fields.NumberField({ required: true, initial: 0, min: 0 })
|
||||
schema.cost = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
// Item slots occupied when carried. 0 = small item (no slots).
|
||||
schema.slots = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
// Rarity: DV for Fortune check when purchasing; 0 = always available
|
||||
schema.rarity = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 6 })
|
||||
|
||||
// Light radius in feet — only relevant for light-source items (Candle/Lamp/Lantern/Torch)
|
||||
schema.lightRadius = new fields.NumberField({ required: false, nullable: true, initial: null, min: 0 })
|
||||
|
||||
schema.cost = new fields.NumberField({ required: true, nullable: false, initial: 0, min: 0 })
|
||||
schema.currency = new fields.StringField({ required: true, initial: "gp", choices: SYSTEM.CURRENCY_CHOICES })
|
||||
|
||||
return schema
|
||||
|
||||
@@ -6,18 +6,39 @@ export default class OathHammerMagicItem extends foundry.abstract.TypeDataModel
|
||||
const requiredInteger = { required: true, nullable: false, integer: true }
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.itemType = new fields.StringField({ required: true, initial: "wondrous", choices: SYSTEM.MAGIC_ITEM_TYPE_CHOICES })
|
||||
schema.rarity = new fields.StringField({ required: true, initial: "common", choices: SYSTEM.RARITY_CHOICES })
|
||||
schema.attunement = new fields.BooleanField({ required: true, initial: false })
|
||||
schema.charges = new fields.SchemaField({
|
||||
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||||
max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
// The magical effect / description of the item
|
||||
schema.effect = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
// Sub-type: Focus (arcane/divine instrument), Talisman (worn item), Trinket (misc object)
|
||||
// Note: magic weapons and armor use the weapon/armor item types with isMagic=true instead.
|
||||
schema.itemType = new fields.StringField({
|
||||
required: true, initial: "talisman", choices: SYSTEM.MAGIC_ITEM_TYPE_CHOICES
|
||||
})
|
||||
schema.recharge = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.equipped = new fields.BooleanField({ required: true, initial: false })
|
||||
schema.cost = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.currency = new fields.StringField({ required: true, initial: "gp", choices: SYSTEM.CURRENCY_CHOICES })
|
||||
|
||||
// Quality: lesser / greater / legendary (determines power and how found, p.136)
|
||||
schema.quality = new fields.StringField({
|
||||
required: true, initial: "lesser", choices: SYSTEM.MAGIC_QUALITY_CHOICES
|
||||
})
|
||||
|
||||
// Cursed items impose a bane that cannot be removed until the curse is broken
|
||||
schema.isCursed = new fields.BooleanField({ initial: false })
|
||||
|
||||
// Legendary items bond to a single character (cannot be shared, p.136)
|
||||
schema.isBonded = new fields.BooleanField({ initial: false })
|
||||
|
||||
// Class/lineage restriction printed in the item's type line, e.g. "Troubadour Only"
|
||||
schema.classRestriction = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// Limited-use items (e.g. "once per day"); none = always active
|
||||
schema.usagePeriod = new fields.StringField({
|
||||
required: true, initial: "none", choices: SYSTEM.ABILITY_USAGE_PERIOD
|
||||
})
|
||||
schema.maxUses = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
// Item slots occupied when carried; 0 = small item (no slots)
|
||||
schema.slots = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
schema.equipped = new fields.BooleanField({ initial: false })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
@@ -7,17 +7,28 @@ export default class OathHammerMiracle extends foundry.abstract.TypeDataModel {
|
||||
const schema = {}
|
||||
|
||||
schema.effect = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.piety = new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 })
|
||||
schema.castingTime = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.range = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.duration = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.components = new fields.SchemaField({
|
||||
verbal: new fields.BooleanField(),
|
||||
somatic: new fields.BooleanField(),
|
||||
material: new fields.BooleanField()
|
||||
|
||||
// Divine tradition (Druidic / Profane / Sanctified)
|
||||
schema.divineTradition = new fields.StringField({
|
||||
required: true, initial: "sanctified", choices: SYSTEM.DIVINE_TRADITIONS
|
||||
})
|
||||
schema.materialComponent = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.savingThrow = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// Difficulty Value: 0 = scales dynamically (1st = DV1, 2nd = DV2…).
|
||||
// Non-zero only for Ritual miracles which have a fixed DV (p.129).
|
||||
schema.difficultyValue = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 10 })
|
||||
|
||||
// Ritual miracles require 1 hour; need a holy book; fixed DV; don't
|
||||
// increment the daily miracle counter (p.129).
|
||||
schema.isRitual = new fields.BooleanField({ initial: false })
|
||||
|
||||
// Range: "Touch", "Self", "20", "100", "1 mile", etc.
|
||||
schema.range = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// Duration: "1 hour", "Encounter", "1 day", etc. Empty = instantaneous.
|
||||
schema.duration = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// Spell Save: e.g. "DV4 Athletics", "DV5 Fortune". Empty = no save.
|
||||
schema.spellSave = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ export default class OathHammerOath extends foundry.abstract.TypeDataModel {
|
||||
const fields = foundry.data.fields
|
||||
const schema = {}
|
||||
|
||||
schema.benefit = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.violation = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.oathType = new fields.StringField({ required: true, initial: "oath-of-justice", choices: SYSTEM.OATH_TYPES })
|
||||
schema.tenet = new fields.HTMLField({ required: false, textSearch: true })
|
||||
schema.boon = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.bane = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.violated = new fields.BooleanField({ required: true, initial: false })
|
||||
|
||||
return schema
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
|
||||
export default class OathHammerShield extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const requiredInteger = { required: true, nullable: false, integer: true }
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.shieldBonus = new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 })
|
||||
schema.equipped = new fields.BooleanField({ required: true, initial: false })
|
||||
schema.encumbrance = new fields.NumberField({ required: true, initial: 1, min: 0 })
|
||||
schema.cost = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.currency = new fields.StringField({ required: true, initial: "gp", choices: SYSTEM.CURRENCY_CHOICES })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
static LOCALIZATION_PREFIXES = ["OATHHAMMER.Shield"]
|
||||
}
|
||||
@@ -7,20 +7,42 @@ export default class OathHammerSpell extends foundry.abstract.TypeDataModel {
|
||||
const schema = {}
|
||||
|
||||
schema.effect = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.tradition = new fields.StringField({ required: true, initial: "elemental", choices: SYSTEM.SORCEROUS_TRADITIONS })
|
||||
schema.level = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1, max: 6 })
|
||||
schema.castingTime = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.range = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.duration = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.arcaneStress = new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 })
|
||||
schema.components = new fields.SchemaField({
|
||||
verbal: new fields.BooleanField(),
|
||||
somatic: new fields.BooleanField(),
|
||||
material: new fields.BooleanField()
|
||||
|
||||
// Arcane tradition (Elemental / Illusionist / Imperial / Infernal / Runic / Stygian)
|
||||
schema.tradition = new fields.StringField({
|
||||
required: true, initial: "elemental", choices: SYSTEM.SORCEROUS_TRADITIONS
|
||||
})
|
||||
schema.materialComponent = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.savingThrow = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.enhancement = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// Difficulty Value: the Magic check DV needed to cast this spell
|
||||
schema.difficultyValue = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1, max: 10 })
|
||||
|
||||
// Ritual spells take 1 hour to cast; DV is listed with "(Ritual)" in the book
|
||||
schema.isRitual = new fields.BooleanField({ initial: false })
|
||||
|
||||
// Magic Missile spells can be intercepted like ranged attacks (p.101)
|
||||
schema.isMagicMissile = new fields.BooleanField({ initial: false })
|
||||
|
||||
// Range: "Touch", "Self", "40", "200", "Cone AoE", "Large AoE", etc.
|
||||
schema.range = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// Duration: "1 hour", "Encounter", "2d3 rounds", etc. Empty = instantaneous.
|
||||
schema.duration = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// Spell Save: e.g. "DV5 Resilience", "DV3 Acrobatics". Empty = no save.
|
||||
schema.spellSave = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
// Elemental tradition only — sub-element (Air / Earth / Fire / Water / Varies)
|
||||
schema.element = new fields.StringField({
|
||||
required: false, nullable: true, initial: null, choices: SYSTEM.ELEMENTAL_CHOICES
|
||||
})
|
||||
|
||||
// Runic tradition only — what surface/object the rune is inscribed upon
|
||||
schema.runeType = new fields.StringField({
|
||||
required: false, nullable: true, initial: null, choices: SYSTEM.RUNE_TYPE_CHOICES
|
||||
})
|
||||
|
||||
// Runic tradition only — exalted runes activate once then vanish (p.120)
|
||||
schema.isExalted = new fields.BooleanField({ initial: false })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
@@ -7,20 +7,69 @@ export default class OathHammerWeapon extends foundry.abstract.TypeDataModel {
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.weaponType = new fields.StringField({ required: true, initial: "melee", choices: SYSTEM.WEAPON_TYPE_CHOICES })
|
||||
schema.damageFormula = new fields.StringField({ required: true, nullable: false, initial: "1d6" })
|
||||
schema.damageType = new fields.StringField({ required: true, initial: "slashing", choices: SYSTEM.DAMAGE_TYPE_CHOICES })
|
||||
schema.attributeBonus = new fields.StringField({ required: true, initial: "might", choices: SYSTEM.ATTRIBUTE_BONUS_CHOICES })
|
||||
schema.range = new fields.StringField({ required: true, initial: "short", choices: SYSTEM.RANGE_CHOICES })
|
||||
schema.hands = new fields.StringField({ required: true, initial: "one-handed", choices: SYSTEM.HANDS_CHOICES })
|
||||
schema.properties = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.equipped = new fields.BooleanField({ required: true, initial: false })
|
||||
schema.encumbrance = new fields.NumberField({ required: true, initial: 1, min: 0 })
|
||||
schema.cost = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.currency = new fields.StringField({ required: true, initial: "gp", choices: SYSTEM.CURRENCY_CHOICES })
|
||||
|
||||
// Proficiency group (Common, Dueling, Heavy, Polearms, Bows, Throwing)
|
||||
schema.proficiencyGroup = new fields.StringField({
|
||||
required: true, initial: "common", choices: SYSTEM.WEAPON_PROFICIENCY_GROUPS
|
||||
})
|
||||
|
||||
// Damage: melee = Might rank + damageMod dice; bows = baseDice (fixed, no Might)
|
||||
// usesMight=true → formula displayed as "M+2", "M-1", etc.
|
||||
// usesMight=false → formula displayed as e.g. "6" (fixed dice for bows)
|
||||
schema.usesMight = new fields.BooleanField({ required: true, initial: true })
|
||||
schema.damageMod = new fields.NumberField({ ...requiredInteger, initial: 0, min: -4, max: 5 })
|
||||
|
||||
// AP (Armor Penetration): penalty imposed on armor/defense rolls
|
||||
schema.ap = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 6 })
|
||||
|
||||
// Reach (melee, in ft: 5 / 10 / 15) — ignored for ranged/throwing
|
||||
schema.reach = new fields.NumberField({ ...requiredInteger, initial: 5, min: 5 })
|
||||
|
||||
// Range (ranged & throwing, in ft): short and long
|
||||
schema.shortRange = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.longRange = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
|
||||
// Traits — stored as a Set of trait keys (Block, Brutal, Nimble, Parry, etc.)
|
||||
schema.traits = new fields.SetField(
|
||||
new fields.StringField({ choices: SYSTEM.WEAPON_TRAITS }),
|
||||
{ required: true, initial: [] }
|
||||
)
|
||||
|
||||
// Item slots (when stowed; 0 = does not occupy slots)
|
||||
schema.slots = new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 })
|
||||
|
||||
// Rarity (DV for Fortune check to find item for sale)
|
||||
schema.rarity = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 5 })
|
||||
|
||||
schema.equipped = new fields.BooleanField({ required: true, initial: false })
|
||||
schema.cost = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||||
schema.currency = new fields.StringField({ required: true, initial: "gp", choices: SYSTEM.CURRENCY_CHOICES })
|
||||
|
||||
// --- Magic properties (only relevant when isMagic = true) ---
|
||||
schema.isMagic = new fields.BooleanField({ initial: false })
|
||||
schema.magicQuality = new fields.StringField({
|
||||
required: false, nullable: true, initial: null, choices: SYSTEM.MAGIC_QUALITY_CHOICES
|
||||
})
|
||||
schema.isCursed = new fields.BooleanField({ initial: false })
|
||||
// Enchantment description (displayed when isMagic is true)
|
||||
schema.magicEffect = new fields.HTMLField({ required: false, textSearch: true })
|
||||
// Class/lineage restriction, e.g. "Dwarves only" (empty = no restriction)
|
||||
schema.classRestriction = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
static LOCALIZATION_PREFIXES = ["OATHHAMMER.Weapon"]
|
||||
|
||||
/**
|
||||
* Human-readable damage formula for display, e.g. "M+2", "M-1", "6"
|
||||
*/
|
||||
get damageLabel() {
|
||||
if (this.usesMight) {
|
||||
const mod = this.damageMod
|
||||
if (mod === 0) return "M+0"
|
||||
return mod > 0 ? `M+${mod}` : `M${mod}`
|
||||
}
|
||||
return String(this.damageMod) // bows: store base dice count in damageMod
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user