First iteration over items
This commit is contained in:
@@ -5,7 +5,9 @@ export { default as PrismRPGSpell } from "./spell.mjs"
|
||||
export { default as PrismRPGSkill } from "./skill.mjs"
|
||||
export { default as PrismRPGArmor } from "./armor.mjs"
|
||||
export { default as PrismRPGShield } from "./shield.mjs"
|
||||
export { default as PrismRPGGift } from "./gift.mjs"
|
||||
export { default as PrismRPGRacialAbility } from "./racial-ability.mjs"
|
||||
export { default as PrismRPGVulnerability } from "./vulnerability.mjs"
|
||||
export { default as PrismRPGEquipment } from "./equipment.mjs"
|
||||
export { default as PrismRPGMiracle } from "./miracle.mjs"
|
||||
export { default as PrismRPGRace } from "./race.mjs"
|
||||
export { default as PrismRPGClass } from "./class.mjs"
|
||||
@@ -19,12 +19,6 @@ export default class PrismRPGArmor extends foundry.abstract.TypeDataModel {
|
||||
schema.augment = new fields.StringField({ required: false, initial: "", label: "Armor Augment" })
|
||||
schema.augmentDescription = new fields.HTMLField({ required: false, textSearch: true, label: "Augment Description" })
|
||||
|
||||
// Legacy fields for compatibility
|
||||
schema.defense = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: -50 })
|
||||
schema.maximumMovement = new fields.StringField({ required: false, initial: "" })
|
||||
schema.hp = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
schema.damageReduction = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
|
||||
schema.encLoad = new fields.NumberField({ required: true, initial: 0, min: 0 })
|
||||
schema.equipped = new fields.BooleanField({ required: true, initial: false })
|
||||
schema.isHelmet = new fields.BooleanField({ required: true, initial: false })
|
||||
|
||||
@@ -173,7 +173,7 @@ export default class PrismRPGCharacter extends foundry.abstract.TypeDataModel {
|
||||
skill: new fields.StringField({
|
||||
required: true,
|
||||
initial: "",
|
||||
choices: Object.keys(SYSTEM.CORE_SKILLS || {}),
|
||||
choices: SYSTEM.CORE_SKILLS_CHOICES,
|
||||
label: "Selected Core Skill"
|
||||
}),
|
||||
attributeChoice: new fields.StringField({
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* Class data model for Prism RPG
|
||||
*
|
||||
* Classes in Prism provide:
|
||||
* - Archetype classification (Faith, Mana, Wanderer, Warrior)
|
||||
* - Class features gained at different levels
|
||||
* - Proficiencies and abilities
|
||||
* - Characters can have up to 3 classes simultaneously
|
||||
*/
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
|
||||
export default class PrismRPGClass extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({
|
||||
required: true,
|
||||
textSearch: true,
|
||||
initial: ""
|
||||
})
|
||||
|
||||
// Archetype (Faith, Mana, Wanderer, Warrior)
|
||||
schema.archetype = new fields.StringField({
|
||||
required: true,
|
||||
initial: "wanderer",
|
||||
choices: SYSTEM.CLASS_ARCHETYPE,
|
||||
label: "Archetype"
|
||||
})
|
||||
|
||||
// Is this a Core Class or Continental Class?
|
||||
schema.classType = new fields.StringField({
|
||||
required: true,
|
||||
initial: "core",
|
||||
choices: SYSTEM.CLASS_TYPE,
|
||||
label: "Class Type"
|
||||
})
|
||||
|
||||
// For Continental Classes, specify the continent
|
||||
schema.continent = new fields.StringField({
|
||||
required: false,
|
||||
initial: "",
|
||||
label: "Continent"
|
||||
})
|
||||
|
||||
// Current level in this class (for tracking progression)
|
||||
schema.level = new fields.NumberField({
|
||||
required: true,
|
||||
nullable: false,
|
||||
integer: true,
|
||||
initial: 1,
|
||||
min: 1,
|
||||
max: 10,
|
||||
label: "Class Level"
|
||||
})
|
||||
|
||||
// Class Features (structured data for features gained at each level)
|
||||
schema.features = new fields.SchemaField({
|
||||
level1: new fields.HTMLField({ initial: "" }),
|
||||
level2: new fields.HTMLField({ initial: "" }),
|
||||
level3: new fields.HTMLField({ initial: "" }),
|
||||
level4: new fields.HTMLField({ initial: "" }),
|
||||
level5: new fields.HTMLField({ initial: "" }),
|
||||
level6: new fields.HTMLField({ initial: "" }),
|
||||
level7: new fields.HTMLField({ initial: "" }),
|
||||
level8: new fields.HTMLField({ initial: "" }),
|
||||
level9: new fields.HTMLField({ initial: "" }),
|
||||
level10: new fields.HTMLField({ initial: "" })
|
||||
})
|
||||
|
||||
// Proficiencies granted by this class
|
||||
schema.weaponProficiencies = new fields.StringField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Weapon Proficiencies"
|
||||
})
|
||||
|
||||
schema.armorProficiencies = new fields.StringField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Armor Proficiencies"
|
||||
})
|
||||
|
||||
// Special abilities
|
||||
schema.spellcasting = new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: "Has Spellcasting"
|
||||
})
|
||||
|
||||
schema.spellcastingType = new fields.StringField({
|
||||
required: false,
|
||||
nullable: true,
|
||||
initial: null,
|
||||
blank: true,
|
||||
choices: SYSTEM.CLASS_SPELLCASTING_TYPE,
|
||||
label: "Spellcasting Type"
|
||||
})
|
||||
|
||||
// Attribute bonuses
|
||||
schema.attributeBonuses = new fields.HTMLField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Attribute Bonuses"
|
||||
})
|
||||
|
||||
// Additional notes
|
||||
schema.notes = new fields.HTMLField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Notes"
|
||||
})
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["PRISMRPG.Class"]
|
||||
|
||||
/**
|
||||
* Clean up data before validation
|
||||
* @override
|
||||
*/
|
||||
static cleanData(source = {}, options = {}) {
|
||||
// Convert empty string to null for spellcastingType
|
||||
if (source.spellcastingType === "") {
|
||||
source.spellcastingType = null
|
||||
}
|
||||
return super.cleanData(source, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the localized archetype label
|
||||
*/
|
||||
get archetypeLabel() {
|
||||
return game.i18n.localize(`PRISMRPG.Class.Archetype.${this.archetype}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current level's features
|
||||
*/
|
||||
get currentLevelFeatures() {
|
||||
return this.features[`level${this.level}`] || ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all features up to current level
|
||||
*/
|
||||
get allFeaturesUpToLevel() {
|
||||
const features = []
|
||||
for (let i = 1; i <= this.level; i++) {
|
||||
const feature = this.features[`level${i}`]
|
||||
if (feature) {
|
||||
features.push({ level: i, description: feature })
|
||||
}
|
||||
}
|
||||
return features
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,6 @@ export default class PrismRPGEquipment extends foundry.abstract.TypeDataModel {
|
||||
schema.category = new fields.StringField({ required: true, initial: "tinbit", choices: SYSTEM.EQUIPMENT_CATEGORIES })
|
||||
|
||||
schema.encLoad = new fields.NumberField({ required: true, initial: 0, min: 0 })
|
||||
schema.hi = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
schema.medium = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
schema.lo = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
schema.cost = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
schema.money = new fields.StringField({ required: true, initial: "tinbit", choices: SYSTEM.MONEY })
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
export default class PrismRPGGift 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.cost = new fields.NumberField({ required: true, initial: 0, min: 0 })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["PRISMRPG.Gift"]
|
||||
|
||||
}
|
||||
@@ -98,17 +98,6 @@ export default class PrismRPGMiracle extends foundry.abstract.TypeDataModel {
|
||||
initial: ""
|
||||
})
|
||||
|
||||
// Attack and power
|
||||
schema.attackRoll = new fields.StringField({
|
||||
required: true,
|
||||
initial: ""
|
||||
})
|
||||
|
||||
schema.powerRoll = new fields.StringField({
|
||||
required: true,
|
||||
initial: ""
|
||||
})
|
||||
|
||||
// Keywords
|
||||
schema.keywords = new fields.ArrayField(
|
||||
new fields.StringField()
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Race data model for Prism RPG
|
||||
*
|
||||
* Races provide:
|
||||
* - Racial Passive: Always-on ability
|
||||
* - Sub-race selection: Specific racial ability based on sub-race
|
||||
* - Basic information: Senses, size, age, language
|
||||
*/
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
|
||||
export default class PrismRPGRace extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({
|
||||
required: true,
|
||||
textSearch: true,
|
||||
initial: ""
|
||||
})
|
||||
|
||||
// Basic Information
|
||||
schema.senses = new fields.StringField({
|
||||
required: true,
|
||||
initial: "standard",
|
||||
label: "Senses"
|
||||
})
|
||||
|
||||
schema.size = new fields.StringField({
|
||||
required: true,
|
||||
initial: "medium",
|
||||
choices: SYSTEM.RACE_SIZE,
|
||||
label: "Size"
|
||||
})
|
||||
|
||||
schema.ageCategory = new fields.StringField({
|
||||
required: true,
|
||||
initial: "short",
|
||||
choices: SYSTEM.RACE_AGE_CATEGORY,
|
||||
label: "Age Category"
|
||||
})
|
||||
|
||||
schema.language = new fields.StringField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Language"
|
||||
})
|
||||
|
||||
// Racial Passive
|
||||
schema.racialPassive = new fields.StringField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Racial Passive Name"
|
||||
})
|
||||
|
||||
schema.racialPassiveDescription = new fields.HTMLField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Racial Passive Description"
|
||||
})
|
||||
|
||||
// Sub-race
|
||||
schema.subrace = new fields.StringField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Sub-race"
|
||||
})
|
||||
|
||||
schema.subraceAbility = new fields.StringField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Sub-race Ability Name"
|
||||
})
|
||||
|
||||
schema.subraceAbilityDescription = new fields.HTMLField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Sub-race Ability Description"
|
||||
})
|
||||
|
||||
// Additional notes
|
||||
schema.notes = new fields.HTMLField({
|
||||
required: true,
|
||||
initial: "",
|
||||
label: "Notes"
|
||||
})
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["PRISMRPG.Race"]
|
||||
|
||||
/**
|
||||
* Get the localized size label
|
||||
*/
|
||||
get sizeLabel() {
|
||||
return game.i18n.localize(`PRISMRPG.Race.Size.${this.size}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the localized age category label
|
||||
*/
|
||||
get ageCategoryLabel() {
|
||||
return game.i18n.localize(`PRISMRPG.Race.AgeCategory.${this.ageCategory}`)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export default class PrismRPGRacialAbility extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const schema = {}
|
||||
|
||||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static LOCALIZATION_PREFIXES = ["PRISMRPG.RacialAbility"]
|
||||
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export default class PrismRPGShield extends foundry.abstract.TypeDataModel {
|
||||
schema.shieldType = new fields.StringField({
|
||||
required: true,
|
||||
initial: "buckler",
|
||||
choices: Object.keys(SYSTEM.SHIELD_TYPE || {})
|
||||
choices: SYSTEM.SHIELD_TYPE_CHOICES
|
||||
})
|
||||
|
||||
// APC (Action Point Cost) for Block action
|
||||
@@ -58,47 +58,7 @@ export default class PrismRPGShield extends foundry.abstract.TypeDataModel {
|
||||
label: "Augment Description"
|
||||
})
|
||||
|
||||
// Legacy properties (kept for backward compatibility)
|
||||
schema.defense = new fields.StringField({
|
||||
required: true,
|
||||
initial: "d4",
|
||||
choices: SYSTEM.SHIELD_DEFENSE_DICE
|
||||
})
|
||||
|
||||
schema.movementreduction = new fields.NumberField({
|
||||
...requiredInteger,
|
||||
required: true,
|
||||
initial: 0,
|
||||
min: 0
|
||||
})
|
||||
|
||||
schema.hascover = new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false
|
||||
})
|
||||
|
||||
schema.standing = new fields.SchemaField({
|
||||
min: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
|
||||
max: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
})
|
||||
|
||||
schema.crouching = new fields.SchemaField({
|
||||
min: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
|
||||
max: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
})
|
||||
|
||||
schema.destruction = new fields.SchemaField({
|
||||
bashing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
|
||||
slashing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
|
||||
piercing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
})
|
||||
|
||||
schema.autodestruction = new fields.SchemaField({
|
||||
bashing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
|
||||
slashing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
|
||||
piercing: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
|
||||
})
|
||||
|
||||
// Equipment properties
|
||||
schema.encLoad = new fields.NumberField({ required: true, initial: 0, min: 0 })
|
||||
schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 })
|
||||
schema.money = new fields.StringField({ required: true, initial: "tinbit", choices: SYSTEM.MONEY })
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
import { CORE_SKILLS_CHOICES, CORE_SKILL_BONUS, CORE_SKILLS } from "../config/skill.mjs"
|
||||
|
||||
/**
|
||||
* Core Skill data model for Prism RPG
|
||||
@@ -25,7 +25,7 @@ export default class PrismRPGSkill extends foundry.abstract.TypeDataModel {
|
||||
schema.coreSkill = new fields.StringField({
|
||||
required: true,
|
||||
initial: "acrobatics",
|
||||
choices: Object.keys(SYSTEM.CORE_SKILLS || {}),
|
||||
choices: CORE_SKILLS_CHOICES,
|
||||
label: "Core Skill"
|
||||
})
|
||||
|
||||
@@ -82,7 +82,7 @@ export default class PrismRPGSkill extends foundry.abstract.TypeDataModel {
|
||||
* Get the Core Skill definition from SYSTEM
|
||||
*/
|
||||
get coreSkillDefinition() {
|
||||
return SYSTEM.CORE_SKILLS?.[this.coreSkill] || null
|
||||
return CORE_SKILLS?.[this.coreSkill] || null
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ export default class PrismRPGSkill extends foundry.abstract.TypeDataModel {
|
||||
|
||||
// If this is the character's Core Skill, apply bonuses
|
||||
if (this.isCoreSkill) {
|
||||
this.modifier = SYSTEM.CORE_SKILL_BONUS?.basic || 5
|
||||
this.modifier = CORE_SKILL_BONUS?.basic || 5
|
||||
this.canAdvancedCheck = true
|
||||
} else {
|
||||
this.modifier = 0
|
||||
|
||||
+13
-45
@@ -52,7 +52,7 @@ export default class PrismRPGSpell extends foundry.abstract.TypeDataModel {
|
||||
schema.color = new fields.StringField({
|
||||
required: true,
|
||||
initial: "violet",
|
||||
choices: Object.keys(SYSTEM.SPELL_COLORS || {}),
|
||||
choices: SYSTEM.SPELL_COLORS_CHOICES,
|
||||
label: "Spell Color"
|
||||
})
|
||||
|
||||
@@ -82,24 +82,6 @@ export default class PrismRPGSpell extends foundry.abstract.TypeDataModel {
|
||||
initial: false
|
||||
})
|
||||
|
||||
// Components
|
||||
schema.components = new fields.SchemaField({
|
||||
verbal: new fields.BooleanField({ initial: false }),
|
||||
somatic: new fields.BooleanField({ initial: false }),
|
||||
catalyst: new fields.BooleanField({ initial: false }),
|
||||
material: new fields.BooleanField({ initial: false }),
|
||||
})
|
||||
|
||||
schema.materialComponent = new fields.StringField({
|
||||
required: true,
|
||||
initial: ""
|
||||
})
|
||||
|
||||
schema.catalyst = new fields.StringField({
|
||||
required: true,
|
||||
initial: ""
|
||||
})
|
||||
|
||||
// Casting parameters
|
||||
schema.castingTime = new fields.StringField({
|
||||
required: true,
|
||||
@@ -126,39 +108,25 @@ export default class PrismRPGSpell extends foundry.abstract.TypeDataModel {
|
||||
initial: ""
|
||||
})
|
||||
|
||||
// Attack and damage
|
||||
schema.attackRoll = new fields.StringField({
|
||||
// Keywords (text field with comma-separated values)
|
||||
schema.keywords = new fields.StringField({
|
||||
required: true,
|
||||
initial: ""
|
||||
initial: "",
|
||||
label: "Keywords"
|
||||
})
|
||||
|
||||
schema.powerRoll = new fields.StringField({
|
||||
// Prism RPG: Targets
|
||||
schema.targets = new fields.StringField({
|
||||
required: true,
|
||||
initial: ""
|
||||
initial: "Single enemy",
|
||||
label: "Targets"
|
||||
})
|
||||
|
||||
// Keywords
|
||||
schema.keywords = new fields.ArrayField(
|
||||
new fields.StringField()
|
||||
)
|
||||
|
||||
// Legacy fields
|
||||
schema.cost = new fields.NumberField({
|
||||
...requiredInteger,
|
||||
// Prism RPG: Resolve method (Attack, Saving Throw, None)
|
||||
schema.resolve = new fields.StringField({
|
||||
required: true,
|
||||
initial: 0,
|
||||
min: 0
|
||||
})
|
||||
|
||||
schema.extraAetherPoints = new fields.StringField({
|
||||
required: true,
|
||||
initial: ""
|
||||
})
|
||||
|
||||
schema.criticalType = new fields.StringField({
|
||||
required: true,
|
||||
initial: "electric",
|
||||
choices: SYSTEM.SPELL_CRITICAL
|
||||
initial: "Attack",
|
||||
label: "Resolve"
|
||||
})
|
||||
|
||||
return schema
|
||||
|
||||
@@ -12,13 +12,13 @@ export default class PrismRPGWeapon extends foundry.abstract.TypeDataModel {
|
||||
schema.weaponType = new fields.StringField({
|
||||
required: true,
|
||||
initial: "light",
|
||||
choices: Object.keys(SYSTEM.WEAPON_TYPE || {})
|
||||
choices: SYSTEM.WEAPON_TYPE_CHOICES
|
||||
})
|
||||
|
||||
schema.weaponGroup = new fields.StringField({
|
||||
required: true,
|
||||
initial: "longsword",
|
||||
choices: Object.keys(SYSTEM.WEAPON_GROUP || {})
|
||||
choices: SYSTEM.WEAPON_GROUP_CHOICES
|
||||
})
|
||||
|
||||
// APC (Action Point Cost) - determined by weapon type
|
||||
@@ -105,37 +105,7 @@ export default class PrismRPGWeapon extends foundry.abstract.TypeDataModel {
|
||||
min: 0
|
||||
})
|
||||
|
||||
// Legacy properties (kept for backward compatibility)
|
||||
schema.hands = new fields.StringField({
|
||||
required: true,
|
||||
initial: "1",
|
||||
choices: { "1": "1", "2": "2" }
|
||||
})
|
||||
|
||||
schema.isAgile = new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false
|
||||
})
|
||||
|
||||
schema.applyStrengthDamageBonus = new fields.BooleanField({
|
||||
required: true,
|
||||
initial: true
|
||||
})
|
||||
|
||||
schema.defenseMax = new fields.NumberField({
|
||||
...requiredInteger,
|
||||
required: true,
|
||||
initial: 0,
|
||||
min: 0
|
||||
})
|
||||
|
||||
schema.defense = new fields.NumberField({
|
||||
...requiredInteger,
|
||||
required: true,
|
||||
initial: 0,
|
||||
min: 0
|
||||
})
|
||||
|
||||
// Bonuses (from magical enhancements, etc.)
|
||||
schema.bonuses = new fields.SchemaField({
|
||||
attackBonus: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
|
||||
damageBonus: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
|
||||
|
||||
Reference in New Issue
Block a user