Files
vermine2047/module/documents/actor.mjs
T
Erwan Lemaire c35e93975b pifpouf
2025-05-02 13:19:49 +02:00

196 lines
5.6 KiB
JavaScript

/**
* Extend the base Actor document by defining a custom roll data structure which is ideal for the Simple system.
* @extends {Actor}
*/
export class VermineActor extends Actor {
/** @override */
prepareData() {
// Prepare data for the actor. Calling the super version of this executes
// the following, in order: data reset (to clear active effects),
// prepareBaseData(), prepareEmbeddedDocuments() (including active effects),
// prepareDerivedData().
super.prepareData();
}
/** @override */
prepareBaseData() {
// Data modifications in this step occur before processing embedded
// documents or derived data.
if (this.type == 'character') {
}
}
/**
* @override
* Augment the basic actor data with additional dynamic data. Typically,
* you'll want to handle most of your calculated/derived data in this step.
* Data calculated in this step should generally not exist in template.json
* (such as ability modifiers rather than ability scores) and should be
* available both inside and outside of character sheets (such as if an actor
* is queried and has a roll executed directly from it).
*/
prepareDerivedData() {
const actorData = this;
const systemData = actorData.system;
const flags = actorData.flags.vermine2047 || {};
// Make separate methods for each Actor type (character, npc, etc.) to keep
// things organized.
switch (this.type) {
case "character":
this._prepareCharacterData(actorData);
break;
case "npc":
this._prepareNpcData(actorData);
break;
}
}
/**
* Prepare Character type specific data
*/
_prepareCharacterData(actorData) {
if (actorData.type !== 'character') return;
this._setAgeType();
this._setCharacterEffort();
this._setCharacterSelfControl();
this._setCharacterThresholds();
// Make modifications to data here. For example:
const systemData = actorData.system;
// Loop through ability scores, and add their modifiers to our sheet output.
for (let [key, ability] of Object.entries(systemData.abilities)) {
// Calculate the modifier using d20 rules.
ability.mod = Math.floor((ability.value - 10) / 2);
}
this.prepareCombatStatus();
}
prepareCombatStatus() {
//combat initiative reaction difficulty
switch (parseInt(this.system.combatStatus.difficulty)) {
case 5: this.system.combatStatus.label = "Offensif";
break;
case 7: this.system.combatStatus.label = "Actif";
break;
case 9: this.system.combatStatus.label = "Passif";
break;
default:
this.system.combatStatus.label = "Passif";
this.system.combatStatus.difficulty = "9";
break;
}
}
/**
* Prepare NPC type specific data.
*/
_prepareNpcData(actorData) {
if (actorData.type !== 'npc') return;
// Make modifications to data here. For example:
const systemData = actorData.system;
systemData.xp = (systemData.cr * systemData.cr) * 100;
this.prepareCombatStatus()
}
/**
* Override getRollData() that's supplied to rolls.
*/
getRollData() {
const data = super.getRollData();
// Prepare character roll data.
this._getCharacterRollData(data);
this._getNpcRollData(data);
return data;
}
/**
* Prepare character roll data.
*/
_getCharacterRollData(data) {
if (this.type !== 'character') return;
// Copy the ability scores to the top level, so that rolls can use
// formulas like `@str.mod + 4`.
if (data.abilities) {
for (let [k, v] of Object.entries(data.abilities)) {
data[k] = foundry.utils.deepClone(v);
}
}
// Add level for easier access, or fall back to 0.
if (data.attributes.level) {
data.lvl = data.attributes.level.value ?? 0;
}
}
/**
* Prepare NPC roll data.
*/
_getNpcRollData(data) {
if (this.type !== 'npc') return;
// Process additional NPC data here.
}
_setCharacterSelfControl() {
this.system.attributes.self_control.max = 0 + Object.values(this.system.abilities).filter(i => i.category === "mental" || i.category === "social").map((i) => i.value).reduce((acc, curr) => acc + curr, 0) + this.modFromAgeSelfControl;
}
_setCharacterEffort() {
this.system.attributes.effort.max = 0 + Object.values(this.system.abilities).filter(i => i.category === "physical" || i.category === "manual").map((i) => i.value).reduce((acc, curr) => acc + curr, 0) + this.modFromAgeEffort;
}
_setCharacterThresholds() {
const health = this.system.abilities.health.value;
this.system.minorWound.threshold = health;
this.system.majorWound.threshold = health + 3;
this.system.deadlyWound.threshold = (health + 7 < 11) ? health + 7 : 10;
this.system.minorWound.max = 4 + this.modFromAgeWounds.l;
this.system.majorWound.max = 3 + this.modFromAgeWounds.h;
this.system.deadlyWound.max = 2 + this.modFromAgeWounds.d;
}
_setAgeType() {
Object.keys(CONFIG.VERMINE.AgeTypes).forEach((type) => {
if (this.system.identity.age >= parseInt(CONFIG.VERMINE.AgeTypes[type].beginning, 10)) {
this.system.identity.ageType = type;
}
});
}
get ageType() {
return this.system.identity.ageType;
}
get modFromAgeSelfControl() {
return this.ageType == 1 ? -1 : 0;
}
get modFromAgeEffort() {
if (this.ageType == 1) return -1;
if (this.ageType == 3) return -2;
return 0;
}
get modFromAgeWounds() {
if (this.ageType == 1) return { l: 0, h: 0, d: -1 };
if (this.ageType == 3) return { l: -1, h: -1, d: -1 };
return { l: 0, h: 0, d: 0 };
}
}