149 lines
3.9 KiB
JavaScript
149 lines
3.9 KiB
JavaScript
import { CORE_SKILLS_CHOICES, CORE_SKILL_BONUS, CORE_SKILLS } from "../config/skill.mjs"
|
|
import { SUB_ATTRIBUTES } from "../config/character.mjs"
|
|
|
|
/**
|
|
* Core Skill data model for Prism RPG
|
|
*
|
|
* Core Skills are skills in which the character is particularly proficient.
|
|
* - Basic skill checks: +5 modifier
|
|
* - Advanced skill checks: Only accessible with Core Skill
|
|
* - Core Skill Class: Gives access to a class based on archetype
|
|
* - Attribute Bonus: +2 to one of 3 associated attributes
|
|
*/
|
|
export default class PrismRPGSkill extends foundry.abstract.TypeDataModel {
|
|
static defineSchema() {
|
|
const fields = foundry.data.fields
|
|
const schema = {}
|
|
const requiredInteger = { required: true, nullable: false, integer: true }
|
|
|
|
schema.description = new fields.HTMLField({
|
|
required: true,
|
|
textSearch: true,
|
|
initial: ""
|
|
})
|
|
|
|
// Is this the character's chosen Core Skill?
|
|
schema.isCoreSkill = new fields.BooleanField({
|
|
required: true,
|
|
initial: false,
|
|
label: "Is Core Skill"
|
|
})
|
|
|
|
// First sub-attribute for this skill
|
|
schema.subAttribute1 = new fields.StringField({
|
|
required: true,
|
|
initial: "prowess",
|
|
label: "Sub-Attribute 1"
|
|
})
|
|
|
|
// Second sub-attribute for this skill
|
|
schema.subAttribute2 = new fields.StringField({
|
|
required: true,
|
|
initial: "initiative",
|
|
label: "Sub-Attribute 2"
|
|
})
|
|
|
|
// Skill modifier (includes Core Skill bonus if applicable)
|
|
schema.modifier = new fields.NumberField({
|
|
...requiredInteger,
|
|
required: true,
|
|
initial: 0,
|
|
label: "Skill Modifier"
|
|
})
|
|
|
|
// Can perform advanced checks
|
|
schema.canAdvancedCheck = new fields.BooleanField({
|
|
required: true,
|
|
initial: false,
|
|
label: "Can Perform Advanced Checks"
|
|
})
|
|
|
|
// Associated Core Skill Class (if any)
|
|
schema.coreSkillClass = new fields.StringField({
|
|
required: true,
|
|
initial: "",
|
|
label: "Core Skill Class"
|
|
})
|
|
|
|
// Notes/Custom description
|
|
schema.notes = new fields.HTMLField({
|
|
required: true,
|
|
initial: "",
|
|
label: "Notes"
|
|
})
|
|
|
|
return schema
|
|
}
|
|
|
|
/** @override */
|
|
static LOCALIZATION_PREFIXES = ["PRISMRPG.Skill"]
|
|
|
|
/**
|
|
* Get the Core Skill definition from SYSTEM
|
|
*/
|
|
get coreSkillDefinition() {
|
|
return CORE_SKILLS?.[this.coreSkill] || null
|
|
}
|
|
|
|
/**
|
|
* Get the localized Core Skill name
|
|
*/
|
|
get coreSkillLabel() {
|
|
const definition = this.coreSkillDefinition
|
|
return definition ? game.i18n.localize(definition.label) : this.coreSkill
|
|
}
|
|
|
|
/**
|
|
* Get the available attribute choices for this Core Skill
|
|
*/
|
|
get attributeChoices() {
|
|
const definition = this.coreSkillDefinition
|
|
return definition?.attributeChoices || []
|
|
}
|
|
|
|
/**
|
|
* Prepare derived data
|
|
*/
|
|
prepareDerivedData() {
|
|
super.prepareDerivedData()
|
|
|
|
// Core Skill gives +5 proficiency bonus
|
|
if (this.isCoreSkill) {
|
|
this.modifier = 5
|
|
this.canAdvancedCheck = true
|
|
} else {
|
|
this.modifier = 0
|
|
this.canAdvancedCheck = false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate skill check bonus
|
|
* @param {string} subAttributeKey The sub-attribute to use (prowess, vigor, etc.)
|
|
* @returns {number} Total skill check bonus
|
|
*/
|
|
getSkillCheckBonus(subAttributeKey) {
|
|
let actor = this.parent?.actor
|
|
if (!actor) return this.modifier
|
|
|
|
const subAttribute = actor.system.subAttributes?.[subAttributeKey]
|
|
const subAttributeMod = subAttribute?.value || 0
|
|
|
|
return subAttributeMod + this.modifier
|
|
}
|
|
|
|
/**
|
|
* Get the available sub-attribute choices for this skill
|
|
*/
|
|
get subAttributeChoices() {
|
|
const choices = {}
|
|
if (this.subAttribute1) {
|
|
choices[this.subAttribute1] = SUB_ATTRIBUTES[this.subAttribute1]?.label || this.subAttribute1
|
|
}
|
|
if (this.subAttribute2) {
|
|
choices[this.subAttribute2] = SUB_ATTRIBUTES[this.subAttribute2]?.label || this.subAttribute2
|
|
}
|
|
return choices
|
|
}
|
|
}
|