Basic actor sheet

This commit is contained in:
2024-12-29 23:09:27 +01:00
parent cffd6827fd
commit 79ce247f57
47 changed files with 739 additions and 526 deletions

View File

@ -46,7 +46,7 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
// Challenges
const challengeField = (label) => {
const schema = {
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
value: new fields.StringField({ initial: "0", required: true, nullable: false }),
}
return new fields.SchemaField(schema, { label })
}
@ -129,6 +129,24 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
}
}
this.grit.starting = Math.round(grit / 6)
let strDef = SYSTEM.CHARACTERISTICS_TABLES.str.find(s => s.value === this.characteristics.str.value)
this.challenges.str.value = strDef.challenge
let dexDef = SYSTEM.CHARACTERISTICS_TABLES.dex.find(s => s.value === this.characteristics.dex.value)
this.challenges.agility.value = dexDef.challenge
this.saves.dodge.value = dexDef.dodge
let wisDef = SYSTEM.CHARACTERISTICS_TABLES.wis.find(s => s.value === this.characteristics.wis.value)
this.saves.will.value = wisDef.willpower_save
let conDef = SYSTEM.CHARACTERISTICS_TABLES.con.find(s => s.value === this.characteristics.con.value)
this.saves.pain.value = conDef.pain_save
this.saves.toughness.value = conDef.toughness_save
this.challenges.dying.value = conDef.stabilization_dice
this.saves.contagion.value = this.characteristics.con.value
this.saves.poison.value = this.characteristics.con.value
}
/**
@ -138,46 +156,16 @@ export default class LethalFantasyCharacter extends foundry.abstract.TypeDataMod
* @param {"="|"+"|"++"|"-"|"--"} rollAdvantage If there is an avantage (+), a disadvantage (-), a double advantage (++), a double disadvantage (--) or a normal roll (=).
* @returns {Promise<null>} - A promise that resolves to null if the roll is cancelled.
*/
async roll(rollType, rollTarget, rollAdvantage = "=") {
let rollValue
let opponentTarget
switch (rollType) {
case ROLL_TYPE.SAVE:
rollValue = this.caracteristiques[rollTarget].valeur
opponentTarget = game.user.targets.first()
break
case ROLL_TYPE.DAMAGE:
rollValue = this.parent.items.get(rollTarget).system.degats
opponentTarget = game.user.targets.first()
break
default:
// Handle other cases or do nothing
break
}
await this._roll(rollType, rollTarget, rollValue, opponentTarget, rollAdvantage)
}
/**
* Rolls a dice for a character.
* @param {("save"|"resource|damage")} rollType The type of the roll.
* @param {number} rollTarget The target value for the roll. Which caracteristic or resource. If the roll is a damage roll, this is the id of the item.
* @param {number} rollValue The value of the roll. If the roll is a damage roll, this is the dice to roll.
* @param {Token} opponentTarget The target of the roll : used for save rolls to get the oppponent's malus.
* @param {"="|"+"|"++"|"-"|"--"} rollAdvantage If there is an avantage (+), a disadvantage (-), a double advantage (++), a double disadvantage (--) or a normal roll (=).
* @returns {Promise<null>} - A promise that resolves to null if the roll is cancelled.
*/
async _roll(rollType, rollTarget, rollValue, opponentTarget = undefined, rollAdvantage = "=") {
const hasTarget = opponentTarget !== undefined
async roll(rollType, rollTarget) {
const hasTarget = false
let roll = await LethalFantasyRoll.prompt({
rollType,
rollTarget,
rollValue,
actorId: this.parent.id,
actorName: this.parent.name,
actorImage: this.parent.img,
hasTarget,
target: opponentTarget,
rollAdvantage,
target: false
})
if (!roll) return null

View File

@ -10,10 +10,10 @@ export default class LethalFantasySkill extends foundry.abstract.TypeDataModel {
schema.category = new fields.StringField({ required: true, initial: "layperson", choices: SYSTEM.SKILL_CATEGORY })
schema.base = new fields.StringField({ required: true, initial: "WIS" })
schema.bonus = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
schema.cost = new fields.NumberField({ ...requiredInteger,required: true, initial: 0, min: 0 })
schema.cost = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
schema.weaponClass = new fields.StringField({ required: true, initial: "shortblade", choices: SYSTEM.WEAPON_CLASS })
schema.weaponBonus = new fields.SchemaField({
schema.weaponBonus = new fields.SchemaField({
attack: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
defense: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 }),
damage: new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
@ -34,20 +34,20 @@ export default class LethalFantasySkill extends foundry.abstract.TypeDataModel {
console.log(this)
let bonus = this._source.weaponBonus.attack + this._source.weaponBonus.defense + this._source.weaponBonus.damage
console.log(bonus, this._source.skillTotal)
if ( bonus > Math.floor(this._source.skillTotal / 10) ) {
ui.notifications.error(game.i18n.localize("LETHALFANTASY.Skill.error.weaponBonus"))
if (bonus > Math.floor(this._source.skillTotal / 10)) {
ui.notifications.error(game.i18n.localize("LETHALFANTASY.Skill.error.weaponBonus"))
isError = true
}
return isError
}
prepareDerivedData() {
super.prepareDerivedData();
this.skillTotal = this.computeBase();
if( this.category === "weapon" ) {
if (this.category === "weapon") {
this.totalBonus = this.weaponBonus.attack + this.weaponBonus.defense + this.weaponBonus.damage;
if ( Number(this.skillTotal) ) {
this.availableBonus = Math.max( Math.floor(this.skillTotal / 10) - 1, 0 )
if (Number(this.skillTotal)) {
this.availableBonus = Math.max(Math.floor(this.skillTotal / 10) - 1, 0)
} else {
this.availableBonus = "N/A"
}
@ -57,37 +57,52 @@ export default class LethalFantasySkill extends foundry.abstract.TypeDataModel {
computeBase() {
let actor = this.parent?.actor;
if (!actor) {
return `${this.base } + ${ String(this.bonus)}`;
return `${this.base} + ${String(this.bonus)}`;
}
if (this.base === "N/A" || this.base === "None") {
return this.bonus
}
// Split the base value per stat : WIS,DEX,STR,INT,CHA (example)
const base = this.base;
let baseSplit = base.split(",");
let baseSplitLength = baseSplit.length;
if ( baseSplitLength > 0) {
// Select the max stat value from the parent actor
let maxStat = 0;
for (let i = 0; i < baseSplitLength; i++) {
const stat = baseSplit[i];
const statValue = actor.system.characteristics[stat.toLowerCase()]?.value || 0;
if (statValue > maxStat) {
maxStat = statValue;
}
}
return maxStat + this.bonus
} else {
// Split with + calculate the total
baseSplit = base.split("+");
baseSplitLength = baseSplit.length;
if ( baseSplitLength > 0) {
let total = 0;
let base = this.base;
// Fix errors in the base value
base.replace("CHARISMA", "CHA");
if (base.match(/OR/)) {
let baseSplit = base.split("OR");
let baseSplitLength = baseSplit.length;
if (baseSplitLength > 0) {
// Select the max stat value from the parent actor
let maxStat = 0;
for (let i = 0; i < baseSplitLength; i++) {
const stat = baseSplit[i];
const stat = baseSplit[i].trim();
const statValue = actor.system.characteristics[stat.toLowerCase()]?.value || 0;
total += statValue;
if (statValue > maxStat) {
maxStat = statValue;
}
}
return total + this.bonus
}
return maxStat + this.bonus
}
} else {
if (base.match(/\+/)) {
// Split with + calculate the total
let baseSplit = base.split("+");
let baseSplitLength = baseSplit.length;
if (baseSplitLength > 0) {
let total = 0;
for (let i = 0; i < baseSplitLength; i++) {
const stat = baseSplit[i].trim();
const statValue = actor.system.characteristics[stat.toLowerCase()]?.value || 0;
total += statValue;
}
return total + this.bonus
}
} else {
// Single stat
const statValue = actor.system.characteristics[base.trim().toLowerCase()]?.value || 0;
return statValue + this.bonus
}
}
return `${this.base} + ${String(this.bonus)}`;
}

View File

@ -55,4 +55,5 @@ export default class LethalFantasySkill extends foundry.abstract.TypeDataModel {
get weaponCategory() {
return game.i18n.localize(CATEGORY[this.weaponType].label)
}
}