First iteration over items

This commit is contained in:
2025-11-06 23:30:37 +01:00
parent 6b883f8126
commit 4a9f026a2a
109 changed files with 1535 additions and 715 deletions
+3 -1
View File
@@ -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"
-6
View File
@@ -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 })
+1 -1
View File
@@ -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({
+159
View File
@@ -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
}
}
-3
View File
@@ -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 })
-16
View File
@@ -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"]
}
-11
View File
@@ -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()
+107
View File
@@ -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}`)
}
}
+14
View File
@@ -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"]
}
+2 -42
View File
@@ -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 })
+4 -4
View File
@@ -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
View File
@@ -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
+3 -33
View File
@@ -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 }),