Séparation de l'Actor Entités
This commit is contained in:
parent
d4be2957a3
commit
1d3ae9bb1a
@ -6,6 +6,7 @@
|
|||||||
- La récupération d'éthylisme
|
- La récupération d'éthylisme
|
||||||
- La récupération de rêve (y compris fleurs de rêve et Rêves de Dragon: la rencontre a lieu, mais ne donne pas de rêve)
|
- La récupération de rêve (y compris fleurs de rêve et Rêves de Dragon: la rencontre a lieu, mais ne donne pas de rêve)
|
||||||
- Séparation des véhicules dans leur propre acteur
|
- Séparation des véhicules dans leur propre acteur
|
||||||
|
- Séparation des entités dans leur propre acteur
|
||||||
|
|
||||||
## v11.0.28 - les fractures de Khrachtchoum
|
## v11.0.28 - les fractures de Khrachtchoum
|
||||||
- La gravité de la blessure est affichée dans le résumé de l'encaissement
|
- La gravité de la blessure est affichée dans le résumé de l'encaissement
|
||||||
|
@ -11,17 +11,18 @@ import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
|||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||||
import { STATUSES } from "./settings/status-effects.js";
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
import { MAINS_DIRECTRICES } from "./actor.js";
|
import { MAINS_DIRECTRICES } from "./actor.js";
|
||||||
import { RdDBaseActorSheet } from "./actor/base-actor-sheet.js";
|
import { RdDBaseActorReveSheet } from "./actor/base-actor-reve-sheet.js";
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
import { RdDItemBlessure } from "./item/blessure.js";
|
import { RdDItemBlessure } from "./item/blessure.js";
|
||||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||||
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* Extend the basic ActorSheet with some very simple modifications
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
* @extends {ActorSheet}
|
* @extends {ActorSheet}
|
||||||
*/
|
*/
|
||||||
export class RdDActorSheet extends RdDBaseActorSheet {
|
export class RdDActorSheet extends RdDBaseActorReveSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
@ -56,7 +57,7 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
|
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
|
||||||
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
|
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
|
||||||
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
|
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
|
||||||
surEncombrementMessage: this.actor.getMessageSurEncombrement(),
|
surEncombrementMessage: this.actor.isSurenc() ? "Sur-Encombrement!" : "",
|
||||||
malusArmure: this.actor.getMalusArmure()
|
malusArmure: this.actor.getMalusArmure()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -115,7 +116,8 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */ /** @override */
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
|
||||||
@ -124,10 +126,10 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
// Everything below here is only needed if the sheet is editable
|
// Everything below here is only needed if the sheet is editable
|
||||||
if (!this.options.editable) return;
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
this.html.find('.item-action').click(async event => {
|
this.html.find('.sheet-possession-attack').click(async event => {
|
||||||
const item = RdDSheetUtility.getItem(event, this.actor);
|
const poss = RdDSheetUtility.getItem(event, this.actor)
|
||||||
item?.actionPrincipale(this.actor, async () => this.render())
|
this.actor.conjurerPossession(poss)
|
||||||
});
|
})
|
||||||
|
|
||||||
this.html.find('.subacteur-delete').click(async event => {
|
this.html.find('.subacteur-delete').click(async event => {
|
||||||
const li = RdDSheetUtility.getEventElement(event);
|
const li = RdDSheetUtility.getEventElement(event);
|
||||||
@ -158,18 +160,6 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.actor.updateCompteurValue("experience", parseInt(event.target.value));
|
this.actor.updateCompteurValue("experience", parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.html.find('.encaisser-direct').click(async event => {
|
|
||||||
this.actor.encaisser();
|
|
||||||
})
|
|
||||||
this.html.find('.sheet-possession-attack').click(async event => {
|
|
||||||
const poss = RdDSheetUtility.getItem(event, this.actor)
|
|
||||||
this.actor.conjurerPossession(poss)
|
|
||||||
})
|
|
||||||
this.html.find('.remise-a-neuf').click(async event => {
|
|
||||||
if (game.user.isGM) {
|
|
||||||
this.actor.remiseANeuf();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.html.find('.creer-tache').click(async event => {
|
this.html.find('.creer-tache').click(async event => {
|
||||||
this.createEmptyTache();
|
this.createEmptyTache();
|
||||||
});
|
});
|
||||||
@ -206,11 +196,6 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Roll Carac
|
// Roll Carac
|
||||||
this.html.find('.carac-label a').click(async event => {
|
|
||||||
let caracName = event.currentTarget.attributes.name.value;
|
|
||||||
this.actor.rollCarac(caracName.toLowerCase());
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('.chance-actuelle').click(async event => {
|
this.html.find('.chance-actuelle').click(async event => {
|
||||||
this.actor.rollCarac('chance-actuelle');
|
this.actor.rollCarac('chance-actuelle');
|
||||||
});
|
});
|
||||||
@ -219,14 +204,10 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.actor.rollAppelChance();
|
this.actor.rollAppelChance();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Roll Skill
|
||||||
this.html.find('[name="jet-astrologie"]').click(async event => {
|
this.html.find('[name="jet-astrologie"]').click(async event => {
|
||||||
this.actor.astrologieNombresAstraux();
|
this.actor.astrologieNombresAstraux();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Roll Skill
|
|
||||||
this.html.find('a.competence-label').click(async event => {
|
|
||||||
this.actor.rollCompetence(RdDSheetUtility.getItemId(event));
|
|
||||||
});
|
|
||||||
this.html.find('.tache-label a').click(async event => {
|
this.html.find('.tache-label a').click(async event => {
|
||||||
this.actor.rollTache(RdDSheetUtility.getItemId(event));
|
this.actor.rollTache(RdDSheetUtility.getItemId(event));
|
||||||
});
|
});
|
||||||
@ -292,35 +273,12 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.");
|
ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Display TMR, visualisation
|
// Display TMR
|
||||||
this.html.find('.visu-tmr').click(async event => {
|
this.html.find('.visu-tmr').click(async event => { this.actor.displayTMR("visu") })
|
||||||
this.actor.displayTMR("visu");
|
this.html.find('.monte-tmr').click(async event => { this.actor.displayTMR("normal") })
|
||||||
});
|
this.html.find('.monte-tmr-rapide').click(async event => { this.actor.displayTMR("rapide") })
|
||||||
|
|
||||||
// Display TMR, normal
|
this.html.find('.repos').click(async event => { await this.actor.repos() })
|
||||||
this.html.find('.monte-tmr').click(async event => {
|
|
||||||
this.actor.displayTMR("normal");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Display TMR, fast
|
|
||||||
this.html.find('.monte-tmr-rapide').click(async event => {
|
|
||||||
this.actor.displayTMR("rapide");
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('.repos').click(async event => {
|
|
||||||
await this.actor.repos();
|
|
||||||
});
|
|
||||||
this.html.find('.delete-active-effect').click(async event => {
|
|
||||||
if (game.user.isGM) {
|
|
||||||
let effect = this.html.find(event.currentTarget).parents(".active-effect").data('effect');
|
|
||||||
this.actor.removeEffect(effect);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.html.find('.enlever-tous-effets').click(async event => {
|
|
||||||
if (game.user.isGM) {
|
|
||||||
await this.actor.removeEffects();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.html.find('.carac-xp-augmenter').click(async event => {
|
this.html.find('.carac-xp-augmenter').click(async event => {
|
||||||
let caracName = event.currentTarget.name.replace("augmenter.", "");
|
let caracName = event.currentTarget.name.replace("augmenter.", "");
|
||||||
this.actor.updateCaracXPAuto(caracName);
|
this.actor.updateCaracXPAuto(caracName);
|
||||||
@ -334,30 +292,20 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
|
|
||||||
if (this.options.vueDetaillee) {
|
if (this.options.vueDetaillee) {
|
||||||
// On carac change
|
// On carac change
|
||||||
this.html.find('.carac-value').change(async event => {
|
|
||||||
let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
|
|
||||||
this.actor.updateCarac(caracName, parseInt(event.target.value));
|
|
||||||
});
|
|
||||||
this.html.find('input.carac-xp').change(async event => {
|
this.html.find('input.carac-xp').change(async event => {
|
||||||
let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "");
|
let caracName = event.currentTarget.name.replace(".xp", "").replace("system.carac.", "");
|
||||||
this.actor.updateCaracXP(caracName, parseInt(event.target.value));
|
this.actor.updateCaracXP(caracName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
// On competence change
|
|
||||||
this.html.find('.competence-value').change(async event => {
|
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
|
||||||
//console.log("Competence changed :", compName);
|
|
||||||
this.actor.updateCompetence(compName, parseInt(event.target.value));
|
|
||||||
});
|
|
||||||
// On competence xp change
|
// On competence xp change
|
||||||
this.html.find('input.competence-xp').change(async event => {
|
this.html.find('input.competence-xp').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCompetenceXP(compName, parseInt(event.target.value));
|
this.actor.updateCompetenceXP(compName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
// On competence xp change
|
|
||||||
this.html.find('input.competence-xp-sort').change(async event => {
|
this.html.find('input.competence-xp-sort').change(async event => {
|
||||||
let compName = event.currentTarget.attributes.compname.value;
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value));
|
this.actor.updateCompetenceXPSort(compName, parseInt(event.target.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.html.find('.toggle-archetype').click(async event => {
|
this.html.find('.toggle-archetype').click(async event => {
|
||||||
this.options.vueArchetype = !this.options.vueArchetype;
|
this.options.vueArchetype = !this.options.vueArchetype;
|
||||||
this.render(true);
|
this.render(true);
|
||||||
@ -394,11 +342,6 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.actor.setPointsDeSeuil(event.currentTarget.value);
|
this.actor.setPointsDeSeuil(event.currentTarget.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
// On stress change
|
|
||||||
this.html.find('.compteur-edit').change(async event => {
|
|
||||||
let fieldName = event.currentTarget.attributes.name.value;
|
|
||||||
this.actor.updateCompteurValue(fieldName, parseInt(event.target.value));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.html.find('.stress-test').click(async event => {
|
this.html.find('.stress-test').click(async event => {
|
||||||
this.actor.transformerStress();
|
this.actor.transformerStress();
|
||||||
@ -429,12 +372,6 @@ export class RdDActorSheet extends RdDBaseActorSheet {
|
|||||||
this.html.find('.vie-moins').click(async event => {
|
this.html.find('.vie-moins').click(async event => {
|
||||||
this.actor.santeIncDec("vie", -1);
|
this.actor.santeIncDec("vie", -1);
|
||||||
});
|
});
|
||||||
this.html.find('.endurance-plus').click(async event => {
|
|
||||||
this.actor.santeIncDec("endurance", 1);
|
|
||||||
});
|
|
||||||
this.html.find('.endurance-moins').click(async event => {
|
|
||||||
this.actor.santeIncDec("endurance", -1);
|
|
||||||
});
|
|
||||||
this.html.find('.ptreve-actuel-plus').click(async event => {
|
this.html.find('.ptreve-actuel-plus').click(async event => {
|
||||||
this.actor.reveActuelIncDec(1);
|
this.actor.reveActuelIncDec(1);
|
||||||
});
|
});
|
||||||
|
630
module/actor.js
630
module/actor.js
@ -1,4 +1,4 @@
|
|||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { MAX_ENDURANCE_FATIGUE, RdDUtility } from "./rdd-utility.js";
|
||||||
import { TMRUtility } from "./tmr-utility.js";
|
import { TMRUtility } from "./tmr-utility.js";
|
||||||
import { RdDRollDialogEthylisme } from "./rdd-roll-ethylisme.js";
|
import { RdDRollDialogEthylisme } from "./rdd-roll-ethylisme.js";
|
||||||
import { RdDRoll } from "./rdd-roll.js";
|
import { RdDRoll } from "./rdd-roll.js";
|
||||||
@ -10,13 +10,9 @@ import { RdDRollTables } from "./rdd-rolltables.js";
|
|||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { RdDItemSort } from "./item-sort.js";
|
import { RdDItemSort } from "./item-sort.js";
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { RdDEncaisser } from "./rdd-roll-encaisser.js";
|
|
||||||
import { RdDCombat } from "./rdd-combat.js";
|
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { RdDItemArme } from "./item-arme.js";
|
|
||||||
import { RdDAlchimie } from "./rdd-alchimie.js";
|
import { RdDAlchimie } from "./rdd-alchimie.js";
|
||||||
import { STATUSES, StatusEffects } from "./settings/status-effects.js";
|
import { STATUSES } from "./settings/status-effects.js";
|
||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
|
||||||
import { RdDItemSigneDraconique } from "./item/signedraconique.js";
|
import { RdDItemSigneDraconique } from "./item/signedraconique.js";
|
||||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||||
@ -26,11 +22,9 @@ import { DialogConsommer } from "./dialog-item-consommer.js";
|
|||||||
import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js";
|
import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js";
|
||||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||||
import { RdDPossession } from "./rdd-possession.js";
|
import { RdDPossession } from "./rdd-possession.js";
|
||||||
import { ENTITE_INCARNE, ENTITE_NONINCARNE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
import { SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||||
import { RdDConfirm } from "./rdd-confirm.js";
|
import { RdDConfirm } from "./rdd-confirm.js";
|
||||||
import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
|
|
||||||
import { RdDRencontre } from "./item/rencontre.js";
|
import { RdDRencontre } from "./item/rencontre.js";
|
||||||
import { Targets } from "./targets.js";
|
|
||||||
import { DialogRepos } from "./sommeil/dialog-repos.js";
|
import { DialogRepos } from "./sommeil/dialog-repos.js";
|
||||||
import { RdDBaseActor } from "./actor/base-actor.js";
|
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||||
@ -39,6 +33,7 @@ import { AppAstrologie } from "./sommeil/app-astrologie.js";
|
|||||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||||
import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js";
|
import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js";
|
||||||
import { TYPES } from "./item.js";
|
import { TYPES } from "./item.js";
|
||||||
|
import { RdDBaseActorVivant } from "./actor/base-actor-vivant.js";
|
||||||
|
|
||||||
const POSSESSION_SANS_DRACONIC = {
|
const POSSESSION_SANS_DRACONIC = {
|
||||||
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
|
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
|
||||||
@ -56,57 +51,59 @@ export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
|
|||||||
* Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
|
* Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
|
||||||
* @extends {Actor}
|
* @extends {Actor}
|
||||||
*/
|
*/
|
||||||
export class RdDActor extends RdDBaseActor {
|
export class RdDActor extends RdDBaseActorVivant {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
prepareData() {
|
|
||||||
super.prepareData();
|
|
||||||
|
|
||||||
// Dynamic computing fields
|
|
||||||
this.encTotal = 0;
|
|
||||||
// TODO: separate derived/base data preparation
|
|
||||||
// TODO: split by actor class
|
|
||||||
|
|
||||||
// Make separate methods for each Actor type (character, npc, etc.) to keep things organized.
|
|
||||||
if (this.isPersonnage()) this._prepareCharacterData(this)
|
|
||||||
if (this.isCreatureEntite()) this._prepareCreatureData(this)
|
|
||||||
this.recompute();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_prepareCreatureData(actorData) {
|
|
||||||
this.computeEncTotal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* Prepare Character type specific data
|
* Prepare Character type specific data
|
||||||
*/
|
*/
|
||||||
async _prepareCharacterData(actorData) {
|
prepareActorData() {
|
||||||
|
// TODO: separate derived/base data preparation
|
||||||
|
// TODO: split by actor class
|
||||||
|
if (this.isPersonnage()) this.$prepareCharacterData()
|
||||||
|
}
|
||||||
|
|
||||||
|
$prepareCharacterData() {
|
||||||
// Initialize empty items
|
// Initialize empty items
|
||||||
RdDCarac.computeCarac(actorData.system)
|
this.$computeCaracDerivee()
|
||||||
this.computeIsHautRevant();
|
this.computeIsHautRevant();
|
||||||
await this.cleanupConteneurs();
|
this.cleanupConteneurs();
|
||||||
await this.computeEncTotal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async cleanupConteneurs() {
|
$computeCaracDerivee() {
|
||||||
let updates = this.itemTypes['conteneur']
|
this.system.carac.force.value = Math.min(this.system.carac.force.value, parseInt(this.system.carac.taille.value) + 4);
|
||||||
.filter(c => c.system.contenu.filter(id => this.getItem(id) == undefined).length > 0)
|
|
||||||
.map(c => { return { _id: c._id, 'system.contenu': c.system.contenu.filter(id => this.getItem(id) != undefined) } });
|
this.system.carac.derobee.value = Math.floor(parseInt(((21 - this.system.carac.taille.value)) + parseInt(this.system.carac.agilite.value)) / 2);
|
||||||
if (updates.length > 0) {
|
let bonusDomKey = Math.floor((parseInt(this.system.carac.force.value) + parseInt(this.system.carac.taille.value)) / 2);
|
||||||
await this.updateEmbeddedDocuments("Item", updates)
|
let tailleData = RdDCarac.getCaracDerivee(bonusDomKey);
|
||||||
}
|
this.system.attributs.plusdom.value = tailleData.plusdom;
|
||||||
|
|
||||||
|
this.system.attributs.sconst.value = RdDCarac.calculSConst(this.system.carac.constitution.value);
|
||||||
|
this.system.attributs.sust.value = RdDCarac.getCaracDerivee(this.system.carac.taille.value).sust;
|
||||||
|
|
||||||
|
this.system.attributs.encombrement.value = (parseInt(this.system.carac.force.value) + parseInt(this.system.carac.taille.value)) / 2;
|
||||||
|
this.system.carac.melee.value = Math.floor((parseInt(this.system.carac.force.value) + parseInt(this.system.carac.agilite.value)) / 2);
|
||||||
|
this.system.carac.tir.value = Math.floor((parseInt(this.system.carac.vue.value) + parseInt(this.system.carac.dexterite.value)) / 2);
|
||||||
|
this.system.carac.lancer.value = Math.floor((parseInt(this.system.carac.tir.value) + parseInt(this.system.carac.force.value)) / 2);
|
||||||
|
|
||||||
|
this.system.sante.vie.max = Math.ceil((parseInt(this.system.carac.taille.value) + parseInt(this.system.carac.constitution.value)) / 2);
|
||||||
|
|
||||||
|
this.system.sante.vie.value = Math.min(this.system.sante.vie.value, this.system.sante.vie.max)
|
||||||
|
this.system.sante.endurance.max = Math.max(parseInt(this.system.carac.taille.value) + parseInt(this.system.carac.constitution.value), parseInt(this.system.sante.vie.max) + parseInt(this.system.carac.volonte.value));
|
||||||
|
this.system.sante.endurance.value = Math.min(this.system.sante.endurance.value, this.system.sante.endurance.max);
|
||||||
|
this.system.sante.fatigue.max = this.$getFatigueMax();
|
||||||
|
this.system.sante.fatigue.value = Math.min(this.system.sante.fatigue.value, this.system.sante.fatigue.max);
|
||||||
|
|
||||||
|
//Compteurs
|
||||||
|
this.system.reve.reve.max = this.system.carac.reve.value;
|
||||||
|
this.system.compteurs.chance.max = this.system.carac.chance.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
canReceive(item) {
|
canReceive(item) {
|
||||||
if (this.isCreature()) {
|
if (this.isCreature()) {
|
||||||
return item.type == TYPES.competencecreature || item.isInventaire();
|
return item.type == TYPES.competencecreature || item.isInventaire();
|
||||||
}
|
}
|
||||||
if (this.isEntite()) {
|
|
||||||
return item.type == 'competencecreature';
|
|
||||||
}
|
|
||||||
if (this.isPersonnage()) {
|
if (this.isPersonnage()) {
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case 'competencecreature': case 'tarot': case 'service':
|
case 'competencecreature': case 'tarot': case 'service':
|
||||||
@ -121,27 +118,13 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
isHautRevant() {
|
isHautRevant() {
|
||||||
return this.isPersonnage() && this.system.attributs.hautrevant.value != ""
|
return this.isPersonnage() && this.system.attributs.hautrevant.value != ""
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
|
||||||
getFatigueActuelle() {
|
|
||||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && this.isPersonnage()) {
|
|
||||||
return this.system.sante.fatigue?.value;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
getFatigueMax() {
|
|
||||||
if (!this.isPersonnage()) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return Misc.toInt(this.system.sante.fatigue?.max);
|
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getReveActuel() {
|
getReveActuel() {
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case 'personnage':
|
case 'personnage':
|
||||||
return Misc.toInt(this.system.reve?.reve?.value ?? this.carac.reve.value);
|
return Misc.toInt(this.system.reve?.reve?.value ?? this.carac.reve.value);
|
||||||
case 'creature':
|
case 'creature':
|
||||||
case 'entite':
|
|
||||||
return Misc.toInt(this.system.carac.reve?.value)
|
return Misc.toInt(this.system.carac.reve?.value)
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@ -158,9 +141,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getForce() {
|
getForce() {
|
||||||
if (this.isEntite()) {
|
|
||||||
return Misc.toInt(this.system.carac.reve?.value);
|
|
||||||
}
|
|
||||||
return Misc.toInt(this.system.carac.force?.value);
|
return Misc.toInt(this.system.carac.force?.value);
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -168,7 +148,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case 'personnage': return Misc.toInt(this.system.carac.agilite?.value);
|
case 'personnage': return Misc.toInt(this.system.carac.agilite?.value);
|
||||||
case 'creature': return Misc.toInt(this.system.carac.force?.value);
|
case 'creature': return Misc.toInt(this.system.carac.force?.value);
|
||||||
case 'entite': return Misc.toInt(this.system.carac.reve?.value);
|
|
||||||
}
|
}
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
@ -214,28 +193,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
getEncTotal() {
|
|
||||||
return Math.floor(this.encTotal ?? 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
getCompetence(idOrName, options = {}) {
|
|
||||||
if (idOrName instanceof Item) {
|
|
||||||
return idOrName.isCompetence() ? idOrName : undefined
|
|
||||||
}
|
|
||||||
return RdDItemCompetence.findCompetence(this.items, idOrName, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
getCompetences(name) {
|
|
||||||
return RdDItemCompetence.findCompetences(this.items, name)
|
|
||||||
}
|
|
||||||
getCompetenceCorpsACorps(options = {}) {
|
|
||||||
return this.getCompetence("Corps à corps", options)
|
|
||||||
}
|
|
||||||
getCompetencesEsquive() {
|
|
||||||
return this.getCompetences("esquive")
|
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getTache(id) {
|
getTache(id) {
|
||||||
return this.findItemLike(id, 'tache');
|
return this.findItemLike(id, 'tache');
|
||||||
@ -285,15 +242,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
return draconics[0];
|
return draconics[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
getPossession(possessionId) {
|
|
||||||
return this.itemTypes[TYPES.possession].find(it => it.system.possessionid == possessionId);
|
|
||||||
}
|
|
||||||
getPossessions() {
|
|
||||||
return this.itemTypes[TYPES.possession];
|
|
||||||
}
|
|
||||||
getEmpoignades() {
|
|
||||||
return this.itemTypes[TYPES.empoignade];
|
|
||||||
}
|
|
||||||
getDemiReve() {
|
getDemiReve() {
|
||||||
return this.system.reve.tmrpos.coord;
|
return this.system.reve.tmrpos.coord;
|
||||||
}
|
}
|
||||||
@ -322,20 +270,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
getSurprise(isCombat = undefined) {
|
|
||||||
let niveauSurprise = this.getEffects()
|
|
||||||
.map(effect => StatusEffects.valeurSurprise(effect, isCombat))
|
|
||||||
.reduce(Misc.sum(), 0);
|
|
||||||
if (niveauSurprise > 1) {
|
|
||||||
return 'totale';
|
|
||||||
}
|
|
||||||
if (niveauSurprise == 1) {
|
|
||||||
return 'demi';
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
hasArmeeMeleeEquipee() { // Return true si l'acteur possède au moins 1 arme de mêlée équipée
|
hasArmeeMeleeEquipee() { // Return true si l'acteur possède au moins 1 arme de mêlée équipée
|
||||||
return this.itemTypes['arme'].find(it => it.system.equipe && it.system.competence != "")
|
return this.itemTypes['arme'].find(it => it.system.equipe && it.system.competence != "")
|
||||||
@ -351,7 +285,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
'chance-actuelle': this.getCaracChanceActuelle()
|
'chance-actuelle': this.getCaracChanceActuelle()
|
||||||
});
|
});
|
||||||
|
|
||||||
await this._openRollDialog({
|
await this.openRollDialog({
|
||||||
name: `jet-${this.id}`,
|
name: `jet-${this.id}`,
|
||||||
label: `Jet de ${this.name}`,
|
label: `Jet de ${this.name}`,
|
||||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html',
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html',
|
||||||
@ -365,23 +299,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _openRollDialog({ name, label, template, rollData, callbackAction }) {
|
|
||||||
const dialog = await RdDRoll.create(this, rollData,
|
|
||||||
{ html: template, close: html => { this.tmrApp?.restoreTMRAfterAction() } },
|
|
||||||
{
|
|
||||||
name: name,
|
|
||||||
label: label,
|
|
||||||
callbacks: [
|
|
||||||
this.createCallbackExperience(),
|
|
||||||
this.createCallbackAppelAuMoral(),
|
|
||||||
{ action: callbackAction }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
dialog.render(true);
|
|
||||||
return dialog
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async prepareChateauDormant(consigne) {
|
async prepareChateauDormant(consigne) {
|
||||||
if (consigne.ignorer) {
|
if (consigne.ignorer) {
|
||||||
return;
|
return;
|
||||||
@ -606,9 +523,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async remiseANeuf() {
|
async remiseANeuf() {
|
||||||
if (this.isEntite([ENTITE_NONINCARNE])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
||||||
content: 'Remise à neuf de ' + this.name
|
content: 'Remise à neuf de ' + this.name
|
||||||
@ -751,7 +665,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
async recupererFatigue(message) {
|
async recupererFatigue(message) {
|
||||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||||
let fatigue = this.system.sante.fatigue.value;
|
let fatigue = this.system.sante.fatigue.value;
|
||||||
const fatigueMin = this._computeFatigueMin();
|
const fatigueMin = this.$getFatigueMin();
|
||||||
if (fatigue <= fatigueMin) {
|
if (fatigue <= fatigueMin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -878,7 +792,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
this.setPointsDeChance(to);
|
this.setPointsDeChance(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let selectedCarac = RdDActor._findCaracByName(this.system.carac, caracName);
|
let selectedCarac = RdDBaseActorVivant._findCaracByName(this.system.carac, caracName);
|
||||||
const from = selectedCarac.value
|
const from = selectedCarac.value
|
||||||
await this.update({ [`system.carac.${caracName}.value`]: to });
|
await this.update({ [`system.carac.${caracName}.value`]: to });
|
||||||
await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName);
|
await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName);
|
||||||
@ -889,7 +803,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
if (caracName == 'Taille') {
|
if (caracName == 'Taille') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let selectedCarac = RdDActor._findCaracByName(this.system.carac, caracName);
|
let selectedCarac = RdDBaseActorVivant._findCaracByName(this.system.carac, caracName);
|
||||||
if (!selectedCarac.derivee) {
|
if (!selectedCarac.derivee) {
|
||||||
const from = Number(selectedCarac.xp);
|
const from = Number(selectedCarac.xp);
|
||||||
await this.update({ [`system.carac.${caracName}.xp`]: to });
|
await this.update({ [`system.carac.${caracName}.xp`]: to });
|
||||||
@ -903,7 +817,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
if (caracName == 'Taille') {
|
if (caracName == 'Taille') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let carac = RdDActor._findCaracByName(this.system.carac, caracName);
|
let carac = RdDBaseActorVivant._findCaracByName(this.system.carac, caracName);
|
||||||
if (carac) {
|
if (carac) {
|
||||||
carac = duplicate(carac);
|
carac = duplicate(carac);
|
||||||
const fromXp = Number(carac.xp);
|
const fromXp = Number(carac.xp);
|
||||||
@ -1117,18 +1031,12 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
await this.update({ [`system.attributs.${fieldName}.value`]: fieldValue });
|
await this.update({ [`system.attributs.${fieldName}.value`]: fieldValue });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
isSurenc() {
|
isSurenc() {
|
||||||
return this.isPersonnage() ? (this.computeMalusSurEncombrement() < 0) : false
|
return this.isPersonnage() ? (this.computeMalusSurEncombrement() < 0) : false
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
computeMalusSurEncombrement() {
|
computeMalusSurEncombrement() {
|
||||||
switch (this.type) {
|
|
||||||
case 'entite':
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return Math.min(0, Math.floor(this.getEncombrementMax() - this.encTotal));
|
return Math.min(0, Math.floor(this.getEncombrementMax() - this.encTotal));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1138,13 +1046,8 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getEncombrementMax() {
|
getEncombrementMax() {
|
||||||
switch (this.type) {
|
|
||||||
case 'entite':
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
return this.system.attributs.encombrement.value
|
return this.system.attributs.encombrement.value
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
computeIsHautRevant() {
|
computeIsHautRevant() {
|
||||||
@ -1184,12 +1087,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
recompute() {
|
async computeEtatGeneral() {
|
||||||
if (this.type == 'entite') {
|
|
||||||
// Pas d'état général pour les entités forçage à 0
|
|
||||||
this.system.compteurs.etat.value = 0;
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.system.compteurs.etat.value = this.$malusVie() + this.$malusFatigue() + this.$malusEthylisme();
|
this.system.compteurs.etat.value = this.$malusVie() + this.$malusFatigue() + this.$malusEthylisme();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1202,19 +1100,42 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
$malusFatigue() {
|
getEnduranceActuelle() {
|
||||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && this.system.sante.fatigue) {
|
return Number(this.system.sante.endurance.value);
|
||||||
const max = Math.max(1, Math.min(this.system.sante.endurance.max, 60));
|
}
|
||||||
|
|
||||||
let fatigueTab = RdDUtility.getSegmentsFatigue(max);
|
getFatigueActuelle() {
|
||||||
let reste = Math.min(max * 2, Math.max(0, this.system.sante.fatigue.value));
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && this.isPersonnage()) {
|
||||||
for (let idx = 0; idx < fatigueTab.length; idx++) {
|
return Math.max(0, Math.min(this.$getFatigueMax(), this.system.sante.fatigue?.value));
|
||||||
reste -= fatigueTab[idx];
|
|
||||||
if (reste <= 0) {
|
|
||||||
return fatigueMalus[idx];
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return -7; // This is the max !
|
|
||||||
|
getFatigueRestante() {
|
||||||
|
return this.$getFatigueMax() - this.getFatigueActuelle();
|
||||||
|
}
|
||||||
|
|
||||||
|
getFatigueMax() {
|
||||||
|
return this.isPersonnage() ? this.$getFatigueMax() : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$getFatigueMin() {
|
||||||
|
return this.system.sante.endurance.max - this.system.sante.endurance.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$getFatigueMax() {
|
||||||
|
return this.$getEnduranceMax() * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
$getEnduranceMax() {
|
||||||
|
return Math.max(1, Math.min(this.system.sante.endurance.max, MAX_ENDURANCE_FATIGUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
$malusFatigue() {
|
||||||
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && this.isPersonnage()) {
|
||||||
|
const fatigueMax = this.$getFatigueMax();
|
||||||
|
const fatigue = this.getFatigueActuelle();
|
||||||
|
return RdDUtility.calculMalusFatigue(fatigue, this.$getEnduranceMax())
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1436,9 +1357,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async setSonne(sonne = true) {
|
async setSonne(sonne = true) {
|
||||||
if (this.isEntite()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!game.combat && sonne) {
|
if (!game.combat && sonne) {
|
||||||
ui.notifications.info("Le personnage est hors combat, il ne reste donc pas sonné");
|
ui.notifications.info("Le personnage est hors combat, il ne reste donc pas sonné");
|
||||||
return;
|
return;
|
||||||
@ -1448,9 +1366,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getSConst() {
|
getSConst() {
|
||||||
if (this.isEntite()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return RdDCarac.calculSConst(this.system.carac.constitution.value)
|
return RdDCarac.calculSConst(this.system.carac.constitution.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1554,7 +1469,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
result.newValue = Math.max(minValue, Math.min(compteur.value + inc, compteur.max));
|
result.newValue = Math.max(minValue, Math.min(compteur.value + inc, compteur.max));
|
||||||
//console.log("New value ", inc, minValue, result.newValue);
|
//console.log("New value ", inc, minValue, result.newValue);
|
||||||
let fatigue = 0;
|
let fatigue = 0;
|
||||||
if (name == "endurance" && !this.isEntite()) {
|
if (name == "endurance") {
|
||||||
if (result.newValue == 0 && inc < 0 && !isCritique) { // perte endurance et endurance devient 0 (sauf critique) -> -1 vie
|
if (result.newValue == 0 && inc < 0 && !isCritique) { // perte endurance et endurance devient 0 (sauf critique) -> -1 vie
|
||||||
sante.vie.value--;
|
sante.vie.value--;
|
||||||
result.perteVie = true;
|
result.perteVie = true;
|
||||||
@ -1580,23 +1495,18 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
compteur.value = result.newValue;
|
compteur.value = result.newValue;
|
||||||
// If endurance lost, then the same amount of fatigue cannot be recovered
|
// If endurance lost, then the same amount of fatigue cannot be recovered
|
||||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) {
|
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) {
|
||||||
sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this._computeFatigueMin());
|
sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this.$getFatigueMin());
|
||||||
}
|
}
|
||||||
await this.update({ "system.sante": sante })
|
await this.update({ "system.sante": sante })
|
||||||
if (this.isDead()) {
|
if (this.isDead()) {
|
||||||
await this.setEffect(STATUSES.StatusComma, true);
|
await this.setEffect(STATUSES.StatusComma, true);
|
||||||
}
|
}
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
isDead() {
|
isDead() {
|
||||||
return !this.isEntite() && this.system.sante.vie.value < -this.getSConst()
|
return this.system.sante.vie.value < -this.getSConst()
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_computeFatigueMin() {
|
|
||||||
return this.system.sante.endurance.max - this.system.sante.endurance.value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -2003,7 +1913,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async checkCaracXP(caracName, display = true) {
|
async checkCaracXP(caracName, display = true) {
|
||||||
let carac = RdDActor._findCaracByName(this.system.carac, caracName);
|
let carac = RdDBaseActorVivant._findCaracByName(this.system.carac, caracName);
|
||||||
if (carac && carac.xp > 0) {
|
if (carac && carac.xp > 0) {
|
||||||
const niveauSuivant = Number(carac.value) + 1;
|
const niveauSuivant = Number(carac.value) + 1;
|
||||||
let xpNeeded = RdDCarac.getCaracNextXp(niveauSuivant);
|
let xpNeeded = RdDCarac.getCaracNextXp(niveauSuivant);
|
||||||
@ -2152,7 +2062,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
const draconicList = this.computeDraconicAndSortIndex(sorts);
|
const draconicList = this.computeDraconicAndSortIndex(sorts);
|
||||||
const reve = duplicate(this.system.carac.reve);
|
const reve = duplicate(this.system.carac.reve);
|
||||||
|
|
||||||
const dialog = await this._openRollDialog({
|
const dialog = await this.openRollDialog({
|
||||||
name: 'lancer-un-sort',
|
name: 'lancer-un-sort',
|
||||||
label: 'Lancer un sort',
|
label: 'Lancer un sort',
|
||||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
|
||||||
@ -2196,7 +2106,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getTMRFatigue() { // Pour l'instant uniquement Inertie Draconique
|
getCoutFatigueTMR() { // Pour l'instant uniquement Inertie Draconique
|
||||||
let countInertieDraconique = EffetsDraconiques.countInertieDraconique(this);
|
let countInertieDraconique = EffetsDraconiques.countInertieDraconique(this);
|
||||||
if (countInertieDraconique > 0) {
|
if (countInertieDraconique > 0) {
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
@ -2272,29 +2182,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async rollCarac(caracName, jetResistance = undefined) {
|
|
||||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
|
||||||
let selectedCarac = this.getCaracByName(caracName)
|
|
||||||
await this._openRollDialog({
|
|
||||||
name: 'jet-' + caracName,
|
|
||||||
label: 'Jet ' + Grammar.apostrophe('de', selectedCarac.label),
|
|
||||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
|
|
||||||
rollData: {
|
|
||||||
selectedCarac: selectedCarac,
|
|
||||||
competences: this.itemTypes['competence'],
|
|
||||||
jetResistance: jetResistance ? caracName : undefined
|
|
||||||
},
|
|
||||||
callbackAction: r => this.$onRollCaracResult(r)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async $onRollCaracResult(rollData) {
|
|
||||||
// Final chat message
|
|
||||||
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Méthode pour faire un jet prédéterminer sans ouvrir la fenêtre de dialogue
|
* Méthode pour faire un jet prédéterminer sans ouvrir la fenêtre de dialogue
|
||||||
* @param {*} caracName
|
* @param {*} caracName
|
||||||
@ -2340,45 +2227,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async rollCompetence(idOrName, options = { tryTarget: true }) {
|
|
||||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
|
||||||
const competence = this.getCompetence(idOrName);
|
|
||||||
let rollData = { carac: this.system.carac, competence: competence }
|
|
||||||
if (competence.type == TYPES.competencecreature) {
|
|
||||||
const arme = RdDItemCompetenceCreature.armeCreature(competence)
|
|
||||||
if (arme && options.tryTarget && Targets.hasTargets()) {
|
|
||||||
Targets.selectOneToken(target => {
|
|
||||||
if (arme.action == "possession") {
|
|
||||||
RdDPossession.onAttaquePossession(target, this, competence)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Transformer la competence de créature
|
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
|
||||||
}
|
|
||||||
|
|
||||||
await this._openRollDialog({
|
|
||||||
name: 'jet-competence',
|
|
||||||
label: 'Jet ' + Grammar.apostrophe('de', competence.name),
|
|
||||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
|
||||||
rollData: rollData,
|
|
||||||
callbackAction: r => this.$onRollCompetence(r, options)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async $onRollCompetence(rollData, options) {
|
|
||||||
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
|
|
||||||
if (options?.onRollAutomate) {
|
|
||||||
options.onRollAutomate(rollData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async creerTacheDepuisLivre(item, options = { renderSheet: true }) {
|
async creerTacheDepuisLivre(item, options = { renderSheet: true }) {
|
||||||
const nomTache = "Lire " + item.name;
|
const nomTache = "Lire " + item.name;
|
||||||
@ -2405,7 +2253,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
blessuresASoigner() {
|
blessuresASoigner() {
|
||||||
// TODO or not TODO: filtrer les blessures poour lesquels on ne peut plus faire de premiers soins?
|
|
||||||
return this.filterItems(it => it.system.gravite > 0 && it.system.gravite <= 6 && !(it.system.premierssoins.done && it.system.soinscomplets.done), 'blessure')
|
return this.filterItems(it => it.system.gravite > 0 && it.system.gravite <= 6 && !(it.system.premierssoins.done && it.system.soinscomplets.done), 'blessure')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2423,7 +2270,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
|
async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
|
||||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||||
const competence = this.getCompetence(compName);
|
const competence = this.getCompetence(compName);
|
||||||
await this._openRollDialog({
|
await this.openRollDialog({
|
||||||
name: 'jet-competence',
|
name: 'jet-competence',
|
||||||
label: 'Jet ' + Grammar.apostrophe('de', competence.name),
|
label: 'Jet ' + Grammar.apostrophe('de', competence.name),
|
||||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
||||||
@ -2447,7 +2294,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
const compData = this.getCompetence(tacheData.system.competence)
|
const compData = this.getCompetence(tacheData.system.competence)
|
||||||
compData.system.defaut_carac = tacheData.system.carac; // Patch !
|
compData.system.defaut_carac = tacheData.system.carac; // Patch !
|
||||||
|
|
||||||
await this._openRollDialog({
|
await this.openRollDialog({
|
||||||
name: 'jet-competence',
|
name: 'jet-competence',
|
||||||
label: 'Jet de Tâche ' + tacheData.name,
|
label: 'Jet de Tâche ' + tacheData.name,
|
||||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
||||||
@ -2510,7 +2357,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
artData.forceCarac[selected] = duplicate(this.system.carac[selected]);
|
artData.forceCarac[selected] = duplicate(this.system.carac[selected]);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this._openRollDialog({
|
await this.openRollDialog({
|
||||||
name: `jet-${artData.art}`,
|
name: `jet-${artData.art}`,
|
||||||
label: `${artData.verbe} ${oeuvre.name}`,
|
label: `${artData.verbe} ${oeuvre.name}`,
|
||||||
template: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.html`,
|
template: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.html`,
|
||||||
@ -2750,7 +2597,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
const dialog = await RdDRoll.create(this, rollData,
|
const dialog = await RdDRoll.create(this, rollData,
|
||||||
{
|
{
|
||||||
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-signedraconique.html',
|
html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-signedraconique.html',
|
||||||
close: html => { this.tmrApp?.restoreTMRAfterAction() }
|
close: async html => await this._onCloseRollDialog(html)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'lire-signe-draconique',
|
name: 'lire-signe-draconique',
|
||||||
@ -2765,6 +2612,10 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
this.tmrApp?.setTMRPendingAction(dialog);
|
this.tmrApp?.setTMRPendingAction(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _onCloseRollDialog(html) {
|
||||||
|
this.tmrApp?.restoreTMRAfterAction()
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _rollLireSigneDraconique(rollData) {
|
async _rollLireSigneDraconique(rollData) {
|
||||||
const compData = rollData.competence;
|
const compData = rollData.competence;
|
||||||
@ -2786,7 +2637,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollAppelChance(onSuccess = () => { }, onEchec = () => { }) {
|
async rollAppelChance(onSuccess = () => { }, onEchec = () => { }) {
|
||||||
await this._openRollDialog({
|
await this.openRollDialog({
|
||||||
name: 'appelChance',
|
name: 'appelChance',
|
||||||
label: 'Appel à la chance',
|
label: 'Appel à la chance',
|
||||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
|
||||||
@ -2838,7 +2689,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
ajustementAstrologique() {
|
ajustementAstrologique() {
|
||||||
if (this.isCreatureEntite()) {
|
if (this.isCreature()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// selon l'heure de naissance...
|
// selon l'heure de naissance...
|
||||||
@ -2904,7 +2755,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
async _xpCarac(xpData) {
|
async _xpCarac(xpData) {
|
||||||
if (xpData.xpCarac > 0) {
|
if (xpData.xpCarac > 0) {
|
||||||
let carac = duplicate(this.system.carac);
|
let carac = duplicate(this.system.carac);
|
||||||
let selectedCarac = RdDActor._findCaracByName(carac, xpData.caracName);
|
let selectedCarac = RdDBaseActorVivant._findCaracByName(carac, xpData.caracName);
|
||||||
if (!selectedCarac.derivee) {
|
if (!selectedCarac.derivee) {
|
||||||
const from = Number(selectedCarac.xp);
|
const from = Number(selectedCarac.xp);
|
||||||
const to = from + xpData.xpCarac;
|
const to = from + xpData.xpCarac;
|
||||||
@ -2957,51 +2808,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
await AppAstrologie.create(this);
|
await AppAstrologie.create(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
getCaracByName(name) {
|
|
||||||
switch (Grammar.toLowerCaseNoAccent(name)) {
|
|
||||||
case 'reve-actuel': case 'reve actuel':
|
|
||||||
return this.getCaracReveActuel();
|
|
||||||
case 'chance-actuelle': case 'chance-actuelle':
|
|
||||||
return this.getCaracChanceActuelle();
|
|
||||||
}
|
|
||||||
return RdDActor._findCaracByName(this.system.carac, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
getCaracChanceActuelle() {
|
|
||||||
return {
|
|
||||||
label: 'Chance actuelle',
|
|
||||||
value: this.getChanceActuel(),
|
|
||||||
type: "number"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
getCaracReveActuel() {
|
|
||||||
return {
|
|
||||||
label: 'Rêve actuel',
|
|
||||||
value: this.getReveActuel(),
|
|
||||||
type: "number"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static _findCaracByName(carac, name) {
|
|
||||||
name = Grammar.toLowerCaseNoAccent(name);
|
|
||||||
switch (name) {
|
|
||||||
case 'reve-actuel': case 'reve actuel':
|
|
||||||
return carac.reve;
|
|
||||||
case 'chance-actuelle': case 'chance actuelle':
|
|
||||||
return carac.chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
const caracList = Object.entries(carac);
|
|
||||||
let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique' });
|
|
||||||
if (!entry || entry.length == 0) {
|
|
||||||
entry = Misc.findFirstLike(name, caracList, { mapper: it => it[1].label, description: 'caractéristique' });
|
|
||||||
}
|
|
||||||
return entry && entry.length > 0 ? carac[entry[0]] : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
countMonteeLaborieuse() { // Return +1 par queue/ombre/souffle Montée Laborieuse présente
|
countMonteeLaborieuse() { // Return +1 par queue/ombre/souffle Montée Laborieuse présente
|
||||||
let countMonteeLaborieuse = EffetsDraconiques.countMonteeLaborieuse(this);
|
let countMonteeLaborieuse = EffetsDraconiques.countMonteeLaborieuse(this);
|
||||||
@ -3076,61 +2882,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getCompetenceArme(arme, competenceName) {
|
|
||||||
switch (arme.type) {
|
|
||||||
case TYPES.competencecreature:
|
|
||||||
return arme.name
|
|
||||||
case TYPES.arme:
|
|
||||||
switch (competenceName) {
|
|
||||||
case 'competence': return arme.system.competence;
|
|
||||||
case 'unemain': return RdDItemArme.competence1Mains(arme);
|
|
||||||
case 'deuxmains': return RdDItemArme.competence2Mains(arme);
|
|
||||||
case 'tir': return arme.system.tir;
|
|
||||||
case 'lancer': return arme.system.lancer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {*} arme item d'arme/compétence de créature
|
|
||||||
* @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
rollArme(arme, categorieArme = "competence") {
|
|
||||||
let compToUse = this.getCompetenceArme(arme, categorieArme)
|
|
||||||
if (!Targets.hasTargets()) {
|
|
||||||
RdDConfirm.confirmer({
|
|
||||||
settingConfirmer: "confirmer-combat-sans-cible",
|
|
||||||
content: `<p>Voulez vous faire un jet de ${compToUse} sans choisir de cible valide?
|
|
||||||
<br>Tous les jets de combats devront être gérés à la main
|
|
||||||
</p>`,
|
|
||||||
title: 'Ne pas utiliser les automatisation de combat',
|
|
||||||
buttonLabel: "Pas d'automatisation",
|
|
||||||
onAction: async () => {
|
|
||||||
this.rollCompetence(compToUse, { tryTarget: false })
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Targets.selectOneToken(target => {
|
|
||||||
if (Targets.isTargetEntite(target)) {
|
|
||||||
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const competence = this.getCompetence(compToUse)
|
|
||||||
//console.log("RollArme", competence, arme)
|
|
||||||
if (competence.isCompetencePossession()) {
|
|
||||||
return RdDPossession.onAttaquePossession(target, this, competence);
|
|
||||||
}
|
|
||||||
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async rollSoins(blesse, blessureId) {
|
async rollSoins(blesse, blessureId) {
|
||||||
const blessure = blesse.blessuresASoigner().find(it => it.id == blessureId);
|
const blessure = blesse.blessuresASoigner().find(it => it.id == blessureId);
|
||||||
if (blessure) {
|
if (blessure) {
|
||||||
@ -3207,12 +2958,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
RdDPossession.onConjurerPossession(this, possession)
|
RdDPossession.onConjurerPossession(this, possession)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
getArmeParade(armeParadeId) {
|
|
||||||
const item = armeParadeId ? this.getEmbeddedDocument('Item', armeParadeId) : undefined;
|
|
||||||
return RdDItemArme.getArme(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
verifierForceMin(item) {
|
verifierForceMin(item) {
|
||||||
if (item.type == 'arme' && item.system.force > this.system.carac.force.value) {
|
if (item.type == 'arme' && item.system.force > this.system.carac.force.value) {
|
||||||
@ -3229,7 +2974,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
if (item?.isEquipable()) {
|
if (item?.isEquipable()) {
|
||||||
const isEquipe = !item.system.equipe;
|
const isEquipe = !item.system.equipe;
|
||||||
await this.updateEmbeddedDocuments('Item', [{ _id: item.id, "system.equipe": isEquipe }]);
|
await this.updateEmbeddedDocuments('Item', [{ _id: item.id, "system.equipe": isEquipe }]);
|
||||||
this.computeEncTotal(); // Mise à jour encombrement
|
this.computeEncTotal();
|
||||||
if (isEquipe)
|
if (isEquipe)
|
||||||
this.verifierForceMin(item);
|
this.verifierForceMin(item);
|
||||||
}
|
}
|
||||||
@ -3264,79 +3009,24 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async encaisser() {
|
async onAppliquerJetEncaissement(encaissement, attacker) {
|
||||||
await RdDEncaisser.encaisser(this);
|
const santeOrig = duplicate(this.system.sante);
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async encaisserDommages(rollData, attacker = undefined, show = undefined) {
|
|
||||||
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const attackerId = attacker?.id;
|
|
||||||
if (ReglesOptionnelles.isUsing('validation-encaissement-gr') && !game.user.isGM) {
|
|
||||||
RdDBaseActor.remoteActorCall({
|
|
||||||
tokenId: this.token?.id,
|
|
||||||
actorId: this.id,
|
|
||||||
method: 'appliquerEncaissement',
|
|
||||||
args: [rollData, show, attackerId]
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.appliquerEncaissement(rollData, show, attackerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
async appliquerEncaissement(rollData, show, attackerId) {
|
|
||||||
const armure = await this.computeArmure(rollData);
|
|
||||||
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) {
|
|
||||||
DialogValidationEncaissement.validerEncaissement(this, rollData, armure, show, attackerId, (encaissement, show, attackerId) => this._appliquerEncaissement(encaissement, show, attackerId));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE });
|
|
||||||
await this._appliquerEncaissement(encaissement, show, attackerId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async _appliquerEncaissement(encaissement, show, attackedId) {
|
|
||||||
const attacker = attackedId ? game.actors.get(attackedId) : undefined
|
|
||||||
let santeOrig = duplicate(this.system.sante);
|
|
||||||
|
|
||||||
const blessure = await this.ajouterBlessure(encaissement, attacker); // Will update the result table
|
const blessure = await this.ajouterBlessure(encaissement, attacker); // Will update the result table
|
||||||
const perteVie = this.isEntite()
|
const perteVie = await this.santeIncDec("vie", -encaissement.vie);
|
||||||
? { newValue: 0 }
|
|
||||||
: await this.santeIncDec("vie", -encaissement.vie);
|
|
||||||
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique());
|
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique());
|
||||||
|
|
||||||
mergeObject(encaissement, {
|
mergeObject(encaissement, {
|
||||||
alias: this.name,
|
resteEndurance: perteEndurance.newValue,
|
||||||
hasPlayerOwner: this.hasPlayerOwner,
|
|
||||||
resteEndurance: this.system.sante.endurance.value,
|
|
||||||
sonne: perteEndurance.sonne,
|
sonne: perteEndurance.sonne,
|
||||||
jetEndurance: perteEndurance.jetEndurance,
|
jetEndurance: perteEndurance.jetEndurance,
|
||||||
endurance: santeOrig.endurance.value - perteEndurance.newValue,
|
endurance: perteEndurance.perte,
|
||||||
vie: this.isEntite() ? 0 : (santeOrig.vie.value - perteVie.newValue),
|
vie: santeOrig.vie.value - perteVie.newValue,
|
||||||
blessure: blessure,
|
blessure: blessure
|
||||||
show: show ?? {}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await ChatUtility.createChatWithRollMode(this.name, {
|
|
||||||
roll: encaissement.roll,
|
|
||||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement)
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) {
|
|
||||||
encaissement = duplicate(encaissement);
|
|
||||||
encaissement.isGM = true;
|
|
||||||
ChatMessage.create({
|
|
||||||
whisper: ChatMessage.getWhisperRecipients("GM"),
|
|
||||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async ajouterBlessure(encaissement, attacker = undefined) {
|
async ajouterBlessure(encaissement, attacker = undefined) {
|
||||||
if (this.isEntite()) return; // Une entité n'a pas de blessures
|
|
||||||
if (encaissement.gravite < 0) return;
|
if (encaissement.gravite < 0) return;
|
||||||
if (encaissement.gravite > 0) {
|
if (encaissement.gravite > 0) {
|
||||||
while (this.countBlessures(it => it.system.gravite == encaissement.gravite) >= RdDItemBlessure.maxBlessures(encaissement.gravite) && encaissement.gravite <= 6) {
|
while (this.countBlessures(it => it.system.gravite == encaissement.gravite) >= RdDItemBlessure.maxBlessures(encaissement.gravite) && encaissement.gravite <= 6) {
|
||||||
@ -3347,7 +3037,7 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const endActuelle = Number(this.system.sante.endurance.value);
|
const endActuelle = this.getEnduranceActuelle();
|
||||||
const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg.loc.label, attacker);
|
const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg.loc.label, attacker);
|
||||||
if (blessure.isCritique()) {
|
if (blessure.isCritique()) {
|
||||||
encaissement.endurance = endActuelle;
|
encaissement.endurance = endActuelle;
|
||||||
@ -3392,71 +3082,6 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
return itemUse[itemId] ?? 0;
|
return itemUse[itemId] ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/* -- entites -- */
|
|
||||||
/* retourne true si on peut continuer, false si on ne peut pas continuer */
|
|
||||||
async targetEntiteNonAccordee(target, when = 'avant-encaissement') {
|
|
||||||
if (target) {
|
|
||||||
return !await this.accorder(target.actor, when);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async accorder(entite, when = 'avant-encaissement') {
|
|
||||||
if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
|
|
||||||
|| entite == undefined
|
|
||||||
|| !entite.isEntite([ENTITE_INCARNE])
|
|
||||||
|| entite.isEntiteAccordee(this)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.system.carac.niveau.value));
|
|
||||||
const rollData = {
|
|
||||||
alias: this.name,
|
|
||||||
rolled: rolled,
|
|
||||||
entite: entite.name,
|
|
||||||
selectedCarac: this.system.carac.reve
|
|
||||||
};
|
|
||||||
|
|
||||||
if (rolled.isSuccess) {
|
|
||||||
await entite.setEntiteReveAccordee(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.html');
|
|
||||||
if (rolled.isPart) {
|
|
||||||
await this.appliquerAjoutExperience(rollData, true);
|
|
||||||
}
|
|
||||||
return rolled.isSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
isEntite(typeentite = []) {
|
|
||||||
return this.type == 'entite' && (typeentite.length == 0 || typeentite.includes(this.system.definition.typeentite));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
isEntiteAccordee(attaquant) {
|
|
||||||
if (!this.isEntite([ENTITE_INCARNE])) { return true; }
|
|
||||||
let resonnance = this.system.sante.resonnance;
|
|
||||||
return (resonnance.actors.find(it => it == attaquant.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async setEntiteReveAccordee(attaquant) {
|
|
||||||
if (!this.isEntite([ENTITE_INCARNE])) {
|
|
||||||
ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entite de cauchemer/rêve");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let resonnance = duplicate(this.system.sante.resonnance);
|
|
||||||
if (resonnance.actors.find(it => it == attaquant.id)) {
|
|
||||||
// déjà accordé
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resonnance.actors.push(attaquant.id);
|
|
||||||
await this.update({ "system.sante.resonnance": resonnance });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async effectuerTacheAlchimie(recetteId, tacheAlchimie, texteTache) {
|
async effectuerTacheAlchimie(recetteId, tacheAlchimie, texteTache) {
|
||||||
let recetteData = this.findItemLike(recetteId, 'recettealchimique');
|
let recetteData = this.findItemLike(recetteId, 'recettealchimique');
|
||||||
@ -3760,43 +3385,8 @@ export class RdDActor extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getEffects(filter = e => true) {
|
isEffectAllowed(statusId) {
|
||||||
return this.getEmbeddedCollection("ActiveEffect").filter(filter);
|
return true
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
getEffect(statusId) {
|
|
||||||
return this.getEmbeddedCollection("ActiveEffect").find(it => it.flags?.core?.statusId == statusId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async setEffect(statusId, status) {
|
|
||||||
if (this.isEntite()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log("setEffect", statusId, status)
|
|
||||||
const effect = this.getEffect(statusId);
|
|
||||||
if (!status && effect) {
|
|
||||||
await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]);
|
|
||||||
}
|
|
||||||
if (status && !effect) {
|
|
||||||
await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.status(statusId)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async removeEffect(statusId) {
|
|
||||||
const effect = this.getEffect(statusId);
|
|
||||||
if (effect) {
|
|
||||||
await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async removeEffects(filter = e => true) {
|
|
||||||
if (game.user.isGM) {
|
|
||||||
const ids = this.getEffects(filter).map(it => it.id);
|
|
||||||
await this.deleteEmbeddedDocuments('ActiveEffect', ids);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
81
module/actor/base-actor-reve-sheet.js
Normal file
81
module/actor/base-actor-reve-sheet.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
||||||
|
import { RdDBaseActorSheet } from "./base-actor-sheet.js";
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
|
* @extends {ActorSheet}
|
||||||
|
*/
|
||||||
|
export class RdDBaseActorReveSheet extends RdDBaseActorSheet {
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/** @override */
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
// Everything below here is only needed if the sheet is editable
|
||||||
|
if (!this.options.editable) return;
|
||||||
|
|
||||||
|
this.html.find('.item-action').click(async event => {
|
||||||
|
const item = RdDSheetUtility.getItem(event, this.actor);
|
||||||
|
item?.actionPrincipale(this.actor, async () => this.render())
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('.encaisser-direct').click(async event => {
|
||||||
|
this.actor.encaisser();
|
||||||
|
})
|
||||||
|
this.html.find('.remise-a-neuf').click(async event => {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
this.actor.remiseANeuf();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('.carac-label a').click(async event => {
|
||||||
|
let caracName = event.currentTarget.attributes.name.value;
|
||||||
|
this.actor.rollCarac(caracName.toLowerCase());
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('a.competence-label').click(async event => {
|
||||||
|
this.actor.rollCompetence(RdDSheetUtility.getItemId(event));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('.delete-active-effect').click(async event => {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
let effect = this.html.find(event.currentTarget).parents(".active-effect").data('effect');
|
||||||
|
this.actor.removeEffect(effect);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.html.find('.enlever-tous-effets').click(async event => {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
await this.actor.removeEffects();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.options.vueDetaillee) {
|
||||||
|
// On carac change
|
||||||
|
this.html.find('.carac-value').change(async event => {
|
||||||
|
let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "");
|
||||||
|
this.actor.updateCarac(caracName, parseInt(event.target.value));
|
||||||
|
});
|
||||||
|
// On competence change
|
||||||
|
this.html.find('.competence-value').change(async event => {
|
||||||
|
let compName = event.currentTarget.attributes.compname.value;
|
||||||
|
//console.log("Competence changed :", compName);
|
||||||
|
this.actor.updateCompetence(compName, parseInt(event.target.value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.html.find('.vue-detaillee').click(async event => {
|
||||||
|
this.options.vueDetaillee = !this.options.vueDetaillee;
|
||||||
|
this.render(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.html.find('.endurance-plus').click(async event => {
|
||||||
|
this.actor.santeIncDec("endurance", 1);
|
||||||
|
});
|
||||||
|
this.html.find('.endurance-moins').click(async event => {
|
||||||
|
this.actor.santeIncDec("endurance", -1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
509
module/actor/base-actor-reve.js
Normal file
509
module/actor/base-actor-reve.js
Normal file
@ -0,0 +1,509 @@
|
|||||||
|
import { ChatUtility } from "../chat-utility.js";
|
||||||
|
import { DialogValidationEncaissement } from "../dialog-validation-encaissement.js";
|
||||||
|
import { Grammar } from "../grammar.js";
|
||||||
|
import { RdDItemCompetence } from "../item-competence.js";
|
||||||
|
import { Misc } from "../misc.js";
|
||||||
|
import { RdDEmpoignade } from "../rdd-empoignade.js";
|
||||||
|
import { RdDResolutionTable } from "../rdd-resolution-table.js";
|
||||||
|
import { RdDEncaisser } from "../rdd-roll-encaisser.js";
|
||||||
|
import { RdDRoll } from "../rdd-roll.js";
|
||||||
|
import { RdDUtility } from "../rdd-utility.js";
|
||||||
|
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||||
|
import { RdDBaseActor } from "./base-actor.js";
|
||||||
|
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
||||||
|
import { StatusEffects } from "../settings/status-effects.js";
|
||||||
|
import { TYPES } from "../item.js";
|
||||||
|
import { Targets } from "../targets.js";
|
||||||
|
import { RdDPossession } from "../rdd-possession.js";
|
||||||
|
import { RdDCombat } from "../rdd-combat.js";
|
||||||
|
import { RdDConfirm } from "../rdd-confirm.js";
|
||||||
|
import { ENTITE_INCARNE, SYSTEM_RDD } from "../constants.js";
|
||||||
|
import { RdDItemArme } from "../item-arme.js";
|
||||||
|
|
||||||
|
const POSSESSION_SANS_DRACONIC = {
|
||||||
|
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
|
||||||
|
name: 'Sans draconic',
|
||||||
|
system: {
|
||||||
|
niveau: 0,
|
||||||
|
defaut_carac: "reve-actuel",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe de base pour les acteurs disposant de rêve (donc, pas des objets)
|
||||||
|
* - Entités de rêve
|
||||||
|
* - Créatures de "sang": créatures et humanoides
|
||||||
|
*/
|
||||||
|
export class RdDBaseActorReve extends RdDBaseActor {
|
||||||
|
|
||||||
|
getCaracChanceActuelle() {
|
||||||
|
return {
|
||||||
|
label: 'Chance actuelle',
|
||||||
|
value: this.getChanceActuel(),
|
||||||
|
type: "number"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getCaracReveActuel() {
|
||||||
|
return {
|
||||||
|
label: 'Rêve actuel',
|
||||||
|
value: this.getReveActuel(),
|
||||||
|
type: "number"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getReveActuel() { return this.getReve() }
|
||||||
|
getChanceActuel() { return this.getChance() }
|
||||||
|
|
||||||
|
getReve() { return Number(this.system.carac.reve?.value ?? 0) }
|
||||||
|
getForce() { return this.getReve() }
|
||||||
|
getTaille() { return Number(this.system.carac.taille?.value ?? 0) }
|
||||||
|
getAgilite() { return this.getForce() }
|
||||||
|
getChance() { return this.getReve() }
|
||||||
|
getMoralTotal() { return 0 }
|
||||||
|
getBonusDegat() { return Number(this.system.attributs?.plusdom?.value ?? 0) }
|
||||||
|
getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) }
|
||||||
|
getSConst() { return 0 }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getEncombrementMax() { return 0 }
|
||||||
|
isSurenc() { return false }
|
||||||
|
computeMalusSurEncombrement() { return 0 }
|
||||||
|
|
||||||
|
ajustementAstrologique() { return 0 }
|
||||||
|
getMalusArmure() { return 0 }
|
||||||
|
|
||||||
|
getEnduranceActuelle() {
|
||||||
|
return Number(this.system.sante?.endurance?.value ?? 0);
|
||||||
|
}
|
||||||
|
async jetEndurance(resteEndurance = undefined) { return { jetEndurance: 0, sonne: false } }
|
||||||
|
isDead() { return false }
|
||||||
|
blessuresASoigner() { return [] }
|
||||||
|
getEtatGeneral(options = { ethylisme: false }) { return 0 }
|
||||||
|
|
||||||
|
async computeArmure(attackerRoll) { return this.getProtectionNaturelle() }
|
||||||
|
async remiseANeuf() { }
|
||||||
|
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { }
|
||||||
|
|
||||||
|
async santeIncDec(name, inc, isCritique = false) { }
|
||||||
|
|
||||||
|
async finDeRound(options = { terminer: false }) {
|
||||||
|
await this.$finDeRoundSuppressionEffetsTermines(options);
|
||||||
|
await this.finDeRoundBlessures();
|
||||||
|
await this.$finDeRoundSupprimerObsoletes();
|
||||||
|
await this.$finDeRoundEmpoignade();
|
||||||
|
}
|
||||||
|
|
||||||
|
async $finDeRoundSuppressionEffetsTermines(options) {
|
||||||
|
for (let effect of this.getEffects()) {
|
||||||
|
if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) {
|
||||||
|
await effect.delete();
|
||||||
|
ChatMessage.create({ content: `${this.name} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async finDeRoundBlessures() {
|
||||||
|
}
|
||||||
|
|
||||||
|
async $finDeRoundSupprimerObsoletes() {
|
||||||
|
const obsoletes = []
|
||||||
|
.concat(this.itemTypes[TYPES.empoignade].filter(it => it.system.pointsemp <= 0))
|
||||||
|
.concat(this.itemTypes[TYPES.possession].filter(it => it.system.compteur < -2 || it.system.compteur > 2))
|
||||||
|
.map(it => it.id);
|
||||||
|
await this.deleteEmbeddedDocuments('Item', obsoletes);
|
||||||
|
}
|
||||||
|
|
||||||
|
async $finDeRoundEmpoignade() {
|
||||||
|
const immobilisations = this.itemTypes[TYPES.empoignade].filter(it => it.system.pointsemp >= 2 && it.system.empoigneurid == this.id);
|
||||||
|
immobilisations.forEach(emp => RdDEmpoignade.onImmobilisation(this,
|
||||||
|
game.actors.get(emp.system.empoigneid),
|
||||||
|
emp
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
async setSonne(sonne = true) { }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getCompetence(idOrName, options = {}) {
|
||||||
|
if (idOrName instanceof Item) {
|
||||||
|
return idOrName.isCompetence() ? idOrName : undefined
|
||||||
|
}
|
||||||
|
return RdDItemCompetence.findCompetence(this.items, idOrName, options)
|
||||||
|
}
|
||||||
|
getCompetences(name) {
|
||||||
|
return RdDItemCompetence.findCompetences(this.items, name)
|
||||||
|
}
|
||||||
|
getCompetenceCorpsACorps(options = {}) {
|
||||||
|
return this.getCompetence("Corps à corps", options)
|
||||||
|
}
|
||||||
|
getCompetencesEsquive() {
|
||||||
|
return this.getCompetences("esquive")
|
||||||
|
}
|
||||||
|
|
||||||
|
getArmeParade(armeParadeId) {
|
||||||
|
const item = armeParadeId ? this.getEmbeddedDocument('Item', armeParadeId) : undefined;
|
||||||
|
return RdDItemArme.getArme(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDraconicOuPossession() {
|
||||||
|
return POSSESSION_SANS_DRACONIC
|
||||||
|
}
|
||||||
|
|
||||||
|
getPossession(possessionId) {
|
||||||
|
return this.itemTypes[TYPES.possession].find(it => it.system.possessionid == possessionId);
|
||||||
|
}
|
||||||
|
getPossessions() {
|
||||||
|
return this.itemTypes[TYPES.possession];
|
||||||
|
}
|
||||||
|
getEmpoignades() {
|
||||||
|
return this.itemTypes[TYPES.empoignade];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async updateCreatureCompetence(idOrName, fieldName, value) {
|
||||||
|
let competence = this.getCompetence(idOrName);
|
||||||
|
if (competence) {
|
||||||
|
function getFieldPath(fieldName) {
|
||||||
|
switch (fieldName) {
|
||||||
|
case "niveau": return 'system.niveau';
|
||||||
|
case "dommages": return 'system.dommages';
|
||||||
|
case "carac_value": return 'system.carac_value';
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
const path = getFieldPath(fieldName);
|
||||||
|
if (path) {
|
||||||
|
await this.updateEmbeddedDocuments('Item', [{ _id: competence.id, [path]: value }]); // updates one EmbeddedEntity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
isEffectAllowed(statusId) { return true }
|
||||||
|
|
||||||
|
getEffects(filter = e => true) {
|
||||||
|
return this.getEmbeddedCollection("ActiveEffect").filter(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
getEffect(statusId) {
|
||||||
|
return this.getEmbeddedCollection("ActiveEffect").find(it => it.flags?.core?.statusId == statusId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setEffect(statusId, status) {
|
||||||
|
if (this.isEffectAllowed(statusId)) {
|
||||||
|
const effect = this.getEffect(statusId);
|
||||||
|
if (!status && effect) {
|
||||||
|
await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]);
|
||||||
|
}
|
||||||
|
if (status && !effect) {
|
||||||
|
await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.status(statusId)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeEffect(statusId) {
|
||||||
|
const effect = this.getEffect(statusId);
|
||||||
|
if (effect) {
|
||||||
|
await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeEffects(filter = e => true) {
|
||||||
|
if (game.user.isGM) {
|
||||||
|
const ids = this.getEffects(filter).map(it => it.id);
|
||||||
|
await this.deleteEmbeddedDocuments('ActiveEffect', ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getSurprise(isCombat = undefined) {
|
||||||
|
let niveauSurprise = this.getEffects()
|
||||||
|
.map(effect => StatusEffects.valeurSurprise(effect, isCombat))
|
||||||
|
.reduce(Misc.sum(), 0);
|
||||||
|
if (niveauSurprise > 1) {
|
||||||
|
return 'totale';
|
||||||
|
}
|
||||||
|
if (niveauSurprise == 1) {
|
||||||
|
return 'demi';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async computeEtatGeneral() {
|
||||||
|
// Par défaut, on ne calcule pas d'état général, seuls les personnages/créatures sont affectés
|
||||||
|
this.system.compteurs.etat.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async openRollDialog({ name, label, template, rollData, callbackAction }) {
|
||||||
|
const dialog = await RdDRoll.create(this, rollData,
|
||||||
|
{ html: template, close: async html => await this._onCloseRollDialog(html) },
|
||||||
|
{
|
||||||
|
name: name,
|
||||||
|
label: label,
|
||||||
|
callbacks: [
|
||||||
|
this.createCallbackExperience(),
|
||||||
|
this.createCallbackAppelAuMoral(),
|
||||||
|
{ action: callbackAction }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
dialog.render(true);
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
createEmptyCallback() {
|
||||||
|
return {
|
||||||
|
condition: r => false,
|
||||||
|
action: r => { }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
createCallbackExperience() { return this.createEmptyCallback(); }
|
||||||
|
createCallbackAppelAuMoral() { return this.createEmptyCallback(); }
|
||||||
|
async _onCloseRollDialog(html) { }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async roll() {
|
||||||
|
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||||
|
|
||||||
|
const carac = this.getCarac()
|
||||||
|
const selectedCaracName = ['apparence', 'perception', 'force', 'reve'].find(it => carac[it] != undefined)
|
||||||
|
|
||||||
|
await this.openRollDialog({
|
||||||
|
name: `jet-${this.id}`,
|
||||||
|
label: `Jet de ${this.name}`,
|
||||||
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.html',
|
||||||
|
rollData: {
|
||||||
|
carac: carac,
|
||||||
|
selectedCarac: carac[selectedCaracName],
|
||||||
|
selectedCaracName: selectedCaracName,
|
||||||
|
competences: this.itemTypes['competence']
|
||||||
|
},
|
||||||
|
callbackAction: r => this.$onRollCaracResult(r)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getCarac() {
|
||||||
|
// TODO: le niveau d'une entité de cauchemar devrait être exclu...
|
||||||
|
const carac = mergeObject(duplicate(this.system.carac),
|
||||||
|
{
|
||||||
|
'reve-actuel': this.getCaracReveActuel(),
|
||||||
|
'chance-actuelle': this.getCaracChanceActuelle()
|
||||||
|
});
|
||||||
|
return carac;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollCarac(caracName, jetResistance = undefined) {
|
||||||
|
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||||
|
let selectedCarac = this.getCaracByName(caracName)
|
||||||
|
await this.openRollDialog({
|
||||||
|
name: 'jet-' + caracName,
|
||||||
|
label: 'Jet ' + Grammar.apostrophe('de', selectedCarac.label),
|
||||||
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
|
||||||
|
rollData: {
|
||||||
|
selectedCarac: selectedCarac,
|
||||||
|
competences: this.itemTypes['competence'],
|
||||||
|
jetResistance: jetResistance ? caracName : undefined
|
||||||
|
},
|
||||||
|
callbackAction: r => this.$onRollCaracResult(r)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async $onRollCaracResult(rollData) {
|
||||||
|
// Final chat message
|
||||||
|
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollCompetence(idOrName, options = { tryTarget: true }) {
|
||||||
|
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||||
|
const competence = this.getCompetence(idOrName);
|
||||||
|
let rollData = { carac: this.system.carac, competence: competence }
|
||||||
|
if (competence.type == TYPES.competencecreature) {
|
||||||
|
const arme = RdDItemCompetenceCreature.armeCreature(competence)
|
||||||
|
if (arme && options.tryTarget && Targets.hasTargets()) {
|
||||||
|
Targets.selectOneToken(target => {
|
||||||
|
if (arme.action == "possession") {
|
||||||
|
RdDPossession.onAttaquePossession(target, this, competence)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Transformer la competence de créature
|
||||||
|
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.openRollDialog({
|
||||||
|
name: 'jet-competence',
|
||||||
|
label: 'Jet ' + Grammar.apostrophe('de', competence.name),
|
||||||
|
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html',
|
||||||
|
rollData: rollData,
|
||||||
|
callbackAction: r => this.$onRollCompetence(r, options)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async $onRollCompetence(rollData, options) {
|
||||||
|
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
|
||||||
|
if (options?.onRollAutomate) {
|
||||||
|
options.onRollAutomate(rollData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** --------------------------------------------
|
||||||
|
* @param {*} arme item d'arme/compétence de créature
|
||||||
|
* @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
rollArme(arme, categorieArme = "competence") {
|
||||||
|
let compToUse = this.$getCompetenceArme(arme, categorieArme)
|
||||||
|
if (!Targets.hasTargets()) {
|
||||||
|
RdDConfirm.confirmer({
|
||||||
|
settingConfirmer: "confirmer-combat-sans-cible",
|
||||||
|
content: `<p>Voulez vous faire un jet de ${compToUse} sans choisir de cible valide?
|
||||||
|
<br>Tous les jets de combats devront être gérés à la main
|
||||||
|
</p>`,
|
||||||
|
title: 'Ne pas utiliser les automatisation de combat',
|
||||||
|
buttonLabel: "Pas d'automatisation",
|
||||||
|
onAction: async () => {
|
||||||
|
this.rollCompetence(compToUse, { tryTarget: false })
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Targets.selectOneToken(target => {
|
||||||
|
if (Targets.isTargetEntite(target)) {
|
||||||
|
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const competence = this.getCompetence(compToUse)
|
||||||
|
//console.log("RollArme", competence, arme)
|
||||||
|
if (competence.isCompetencePossession()) {
|
||||||
|
return RdDPossession.onAttaquePossession(target, this, competence);
|
||||||
|
}
|
||||||
|
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$getCompetenceArme(arme, competenceName) {
|
||||||
|
switch (arme.type) {
|
||||||
|
case TYPES.competencecreature:
|
||||||
|
return arme.name
|
||||||
|
case TYPES.arme:
|
||||||
|
switch (competenceName) {
|
||||||
|
case 'competence': return arme.system.competence;
|
||||||
|
case 'unemain': return RdDItemArme.competence1Mains(arme);
|
||||||
|
case 'deuxmains': return RdDItemArme.competence2Mains(arme);
|
||||||
|
case 'tir': return arme.system.tir;
|
||||||
|
case 'lancer': return arme.system.lancer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
verifierForceMin(item) {
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async resetItemUse() { }
|
||||||
|
async incDecItemUse(itemId, inc = 1) { }
|
||||||
|
getItemUse(itemId) { return 0; }
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async encaisser() { await RdDEncaisser.encaisser(this) }
|
||||||
|
|
||||||
|
async encaisserDommages(rollData, attacker = undefined, show = undefined) {
|
||||||
|
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const attackerId = attacker?.id;
|
||||||
|
if (ReglesOptionnelles.isUsing('validation-encaissement-gr') && !game.user.isGM) {
|
||||||
|
RdDBaseActor.remoteActorCall({
|
||||||
|
tokenId: this.token?.id,
|
||||||
|
actorId: this.id,
|
||||||
|
method: 'appliquerEncaissement',
|
||||||
|
args: [rollData, show, attackerId]
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const armure = await this.computeArmure(rollData);
|
||||||
|
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) {
|
||||||
|
DialogValidationEncaissement.validerEncaissement(this, rollData, armure,
|
||||||
|
jet => this.$onEncaissement(jet, show, attacker));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const jet = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE });
|
||||||
|
await this.$onEncaissement(jet, show, attacker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async $onEncaissement(jet, show, attacker) {
|
||||||
|
await this.onAppliquerJetEncaissement(jet, attacker);
|
||||||
|
await this.$afficherEncaissement(jet, show);
|
||||||
|
}
|
||||||
|
|
||||||
|
async onAppliquerJetEncaissement(encaissement, attacker) { }
|
||||||
|
|
||||||
|
async $afficherEncaissement(encaissement, show) {
|
||||||
|
mergeObject(encaissement, {
|
||||||
|
alias: this.name,
|
||||||
|
hasPlayerOwner: this.hasPlayerOwner,
|
||||||
|
show: show ?? {}
|
||||||
|
});
|
||||||
|
|
||||||
|
await ChatUtility.createChatWithRollMode(this.name, {
|
||||||
|
roll: encaissement.roll,
|
||||||
|
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) {
|
||||||
|
encaissement = duplicate(encaissement);
|
||||||
|
encaissement.isGM = true;
|
||||||
|
ChatMessage.create({
|
||||||
|
whisper: ChatMessage.getWhisperRecipients("GM"),
|
||||||
|
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async accorder(entite, when = 'avant-encaissement') {
|
||||||
|
if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
|
||||||
|
|| entite == undefined
|
||||||
|
|| !entite.isEntite([ENTITE_INCARNE])
|
||||||
|
|| entite.isEntiteAccordee(this)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.system.carac.niveau.value));
|
||||||
|
const rollData = {
|
||||||
|
alias: this.name,
|
||||||
|
rolled: rolled,
|
||||||
|
entite: entite.name,
|
||||||
|
selectedCarac: this.system.carac.reve
|
||||||
|
};
|
||||||
|
|
||||||
|
if (rolled.isSuccess) {
|
||||||
|
await entite.setEntiteReveAccordee(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.html');
|
||||||
|
if (rolled.isPart) {
|
||||||
|
await this.appliquerAjoutExperience(rollData, true);
|
||||||
|
}
|
||||||
|
return rolled.isSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEntiteAccordee(attacker) { return true }
|
||||||
|
|
||||||
|
async setEntiteReveAccordee(attacker) {
|
||||||
|
ui.notifications.error("Impossible de s'accorder à " + this.name + ": ce n'est pas une entite de cauchemer/rêve");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -31,7 +31,7 @@ export class RdDBaseActorSheet extends ActorSheet {
|
|||||||
async getData() {
|
async getData() {
|
||||||
Monnaie.validerMonnaies(this.actor.itemTypes['monnaie']);
|
Monnaie.validerMonnaies(this.actor.itemTypes['monnaie']);
|
||||||
|
|
||||||
this.actor.recompute();
|
this.actor.computeEtatGeneral();
|
||||||
let formData = {
|
let formData = {
|
||||||
title: this.title,
|
title: this.title,
|
||||||
id: this.actor.id,
|
id: this.actor.id,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { ChatUtility } from "../chat-utility.js";
|
import { ChatUtility } from "../chat-utility.js";
|
||||||
import { SYSTEM_SOCKET_ID } from "../constants.js";
|
import { SYSTEM_SOCKET_ID } from "../constants.js";
|
||||||
|
import { Grammar } from "../grammar.js";
|
||||||
import { Monnaie } from "../item-monnaie.js";
|
import { Monnaie } from "../item-monnaie.js";
|
||||||
import { Misc } from "../misc.js";
|
import { Misc } from "../misc.js";
|
||||||
import { RdDAudio } from "../rdd-audio.js";
|
import { RdDAudio } from "../rdd-audio.js";
|
||||||
@ -9,6 +10,33 @@ import { SystemCompendiums } from "../settings/system-compendiums.js";
|
|||||||
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
|
import { APP_ASTROLOGIE_REFRESH } from "../sommeil/app-astrologie.js";
|
||||||
|
|
||||||
export class RdDBaseActor extends Actor {
|
export class RdDBaseActor extends Actor {
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _findCaracByName(carac, name) {
|
||||||
|
name = Grammar.toLowerCaseNoAccent(name);
|
||||||
|
switch (name) {
|
||||||
|
case 'reve-actuel': case 'reve actuel':
|
||||||
|
return carac.reve;
|
||||||
|
case 'chance-actuelle': case 'chance actuelle':
|
||||||
|
return carac.chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
const caracList = Object.entries(carac);
|
||||||
|
let entry = Misc.findFirstLike(name, caracList, { mapper: it => it[0], description: 'caractéristique' });
|
||||||
|
if (!entry || entry.length == 0) {
|
||||||
|
entry = Misc.findFirstLike(name, caracList, { mapper: it => it[1].label, description: 'caractéristique' });
|
||||||
|
}
|
||||||
|
return entry && entry.length > 0 ? carac[entry[0]] : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCaracByName(name) {
|
||||||
|
switch (Grammar.toLowerCaseNoAccent(name)) {
|
||||||
|
case 'reve-actuel': case 'reve actuel':
|
||||||
|
return this.getCaracReveActuel();
|
||||||
|
case 'chance-actuelle': case 'chance-actuelle':
|
||||||
|
return this.getCaracChanceActuelle();
|
||||||
|
}
|
||||||
|
return RdDBaseActor._findCaracByName(this.system.carac, name);
|
||||||
|
}
|
||||||
|
|
||||||
static getDefaultImg(itemType) {
|
static getDefaultImg(itemType) {
|
||||||
return game.system.rdd.actorClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType];
|
return game.system.rdd.actorClasses[itemType]?.defaultIcon ?? defaultItemImg[itemType];
|
||||||
@ -124,11 +152,24 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
prepareData() {
|
||||||
|
super.prepareData()
|
||||||
|
this.prepareActorData()
|
||||||
|
this.cleanupConteneurs()
|
||||||
|
this.computeEtatGeneral()
|
||||||
|
this.computeEncTotal()
|
||||||
|
}
|
||||||
|
|
||||||
|
async prepareActorData() { }
|
||||||
|
async computeEtatGeneral() { }
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
isCreatureEntite() { return this.type == 'creature' || this.type == 'entite'; }
|
isCreatureEntite() { return this.type == 'creature' || this.type == 'entite'; }
|
||||||
isCreature() { return this.type == 'creature'; }
|
isCreature() { return this.type == 'creature'; }
|
||||||
isEntite() { return this.type == 'entite'; }
|
isEntite(typeentite = []) { return false }
|
||||||
isPersonnage() { return this.type == 'personnage'; }
|
isPersonnage() { return this.type == 'personnage'; }
|
||||||
isVehicule() { return this.type == 'vehicule'; }
|
isVehicule() { return this.type == 'vehicule'; }
|
||||||
|
|
||||||
getItem(id, type = undefined) {
|
getItem(id, type = undefined) {
|
||||||
const item = this.items.get(id);
|
const item = this.items.get(id);
|
||||||
if (type == undefined || (item?.type == type)) {
|
if (type == undefined || (item?.type == type)) {
|
||||||
@ -145,12 +186,7 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMonnaie(id) { return this.findItemLike(id, 'monnaie'); }
|
getMonnaie(id) { return this.findItemLike(id, 'monnaie'); }
|
||||||
getReveActuel() { return 0 }
|
|
||||||
computeMalusSurEncombrement() { return 0 }
|
|
||||||
getEncombrementMax() { return 0 }
|
getEncombrementMax() { return 0 }
|
||||||
recompute() { }
|
|
||||||
async setEffect(statusId, status) { }
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async onPreUpdateItem(item, change, options, id) { }
|
async onPreUpdateItem(item, change, options, id) { }
|
||||||
@ -179,6 +215,16 @@ export class RdDBaseActor extends Actor {
|
|||||||
await this.createEmbeddedDocuments('Item', [object])
|
await this.createEmbeddedDocuments('Item', [object])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async cleanupConteneurs() {
|
||||||
|
let updates = this.itemTypes['conteneur']
|
||||||
|
.filter(c => c.system.contenu.filter(id => this.getItem(id) == undefined).length > 0)
|
||||||
|
.map(c => { return { _id: c._id, 'system.contenu': c.system.contenu.filter(id => this.getItem(id) != undefined) } });
|
||||||
|
if (updates.length > 0) {
|
||||||
|
await this.updateEmbeddedDocuments("Item", updates)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getFortune() {
|
getFortune() {
|
||||||
return Monnaie.getFortune(this.itemTypes['monnaie']);
|
return Monnaie.getFortune(this.itemTypes['monnaie']);
|
||||||
@ -399,6 +445,10 @@ export class RdDBaseActor extends Actor {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEncTotal() {
|
||||||
|
return Math.floor(this.encTotal ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
async createItem(type, name = undefined) {
|
async createItem(type, name = undefined) {
|
||||||
if (!name) {
|
if (!name) {
|
||||||
name = 'Nouveau ' + Misc.typeName('Item', type);
|
name = 'Nouveau ' + Misc.typeName('Item', type);
|
||||||
@ -627,5 +677,12 @@ export class RdDBaseActor extends Actor {
|
|||||||
.then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride)));
|
.then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actionImpossible(action) {
|
||||||
|
ui.notifications.info(`${this.name} ne peut pas faire cette action: ${action}`)
|
||||||
|
|
||||||
|
}
|
||||||
|
async roll() { this.actionImpossible("jet de caractéristiques") }
|
||||||
|
async jetEthylisme() { this.actionImpossible("jet d'éthylisme") }
|
||||||
|
async rollAppelChance() { this.actionImpossible("appel à la chance") }
|
||||||
|
async jetDeMoral() { this.actionImpossible("jet de moral") }
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import { RdDActorSheet } from "./actor-sheet.js";
|
import { RdDBaseActorReveSheet } from "./base-actor-reve-sheet.js";
|
||||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "../rdd-utility.js";
|
||||||
|
|
||||||
export class RdDActorEntiteSheet extends RdDActorSheet {
|
export class RdDActorEntiteSheet extends RdDBaseActorReveSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
110
module/actor/entite.js
Normal file
110
module/actor/entite.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js";
|
||||||
|
import { TYPES } from "../item.js";
|
||||||
|
import { Misc } from "../misc.js";
|
||||||
|
import { RdDEncaisser } from "../rdd-roll-encaisser.js";
|
||||||
|
import { STATUSES } from "../settings/status-effects.js";
|
||||||
|
import { RdDBaseActorReve } from "./base-actor-reve.js";
|
||||||
|
|
||||||
|
export class RdDEntite extends RdDBaseActorReve {
|
||||||
|
|
||||||
|
static get defaultIcon() {
|
||||||
|
return "systems/foundryvtt-reve-de-dragon/icons/entites/darquoine.webp";
|
||||||
|
}
|
||||||
|
|
||||||
|
canReceive(item) {
|
||||||
|
return item.type == TYPES.competencecreature
|
||||||
|
}
|
||||||
|
|
||||||
|
isEntite(typeentite = []) {
|
||||||
|
return (typeentite.length == 0 || typeentite.includes(this.system.definition.typeentite));
|
||||||
|
}
|
||||||
|
isNonIncarnee() { return this.isEntite([ENTITE_NONINCARNE]) }
|
||||||
|
|
||||||
|
getReveActuel() {
|
||||||
|
return Misc.toInt(this.system.carac.reve?.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
getForce() { return this.getReve() }
|
||||||
|
getAgilite() { return this.getReve() }
|
||||||
|
getChance() { return this.getReve() }
|
||||||
|
|
||||||
|
getDraconicOuPossession() {
|
||||||
|
return this.itemTypes[TYPES.competencecreature]
|
||||||
|
.filter(it => it.system.categorie == 'possession')
|
||||||
|
.sort(Misc.descending(it => it.system.niveau))
|
||||||
|
.find(it => true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async remiseANeuf() {
|
||||||
|
await this.removeEffects(e => true);
|
||||||
|
if (!this.isNonIncarnee()) {
|
||||||
|
await this.update({
|
||||||
|
'system.sante.endurance.value': this.system.sante.endurance.max
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isDead() {
|
||||||
|
return this.isNonIncarnee() ? false : this.system.sante.endurance.value <= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
async santeIncDec(name, inc, isCritique = false) {
|
||||||
|
if (name == 'endurance' && !this.isNonIncarnee()) {
|
||||||
|
const oldValue = this.system.sante.endurance.value;
|
||||||
|
const endurance = Math.max(0,
|
||||||
|
Math.min(oldValue + inc,
|
||||||
|
this.system.sante.endurance.max));
|
||||||
|
await this.update({ "system.sante.endurance.value": endurance })
|
||||||
|
await this.setEffect(STATUSES.StatusComma, endurance <= 0);
|
||||||
|
return {
|
||||||
|
perte: oldValue - endurance,
|
||||||
|
newValue: endurance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
async encaisser() {
|
||||||
|
if (this.isNonIncarnee()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await RdDEncaisser.encaisser(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
isEffectAllowed(statusId) {
|
||||||
|
return [STATUSES.StatusComma].includes(statusId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async onAppliquerJetEncaissement(encaissement, attacker) {
|
||||||
|
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance);
|
||||||
|
mergeObject(encaissement, {
|
||||||
|
resteEndurance: perteEndurance.newValue,
|
||||||
|
endurance: perteEndurance.perte
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
isEntiteAccordee(attacker) {
|
||||||
|
if (this.isEntite([ENTITE_INCARNE])) {
|
||||||
|
let resonnance = this.system.sante.resonnance
|
||||||
|
return (resonnance.actors.find(it => it == attacker.id))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async setEntiteReveAccordee(attacker) {
|
||||||
|
if (this.isEntite([ENTITE_INCARNE])) {
|
||||||
|
let resonnance = duplicate(this.system.sante.resonnance);
|
||||||
|
if (resonnance.actors.find(it => it == attacker.id)) {
|
||||||
|
// déjà accordé
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resonnance.actors.push(attacker.id);
|
||||||
|
await this.update({ "system.sante.resonnance": resonnance });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.setEntiteReveAccordee(attacker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -7,20 +7,19 @@ import { RdDUtility } from "./rdd-utility.js";
|
|||||||
*/
|
*/
|
||||||
export class DialogValidationEncaissement extends Dialog {
|
export class DialogValidationEncaissement extends Dialog {
|
||||||
|
|
||||||
static async validerEncaissement(actor, rollData, armure, show, attackerId, onEncaisser) {
|
static async validerEncaissement(actor, rollData, armure, onEncaisser) {
|
||||||
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE });
|
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE });
|
||||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
|
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
|
||||||
actor: actor,
|
actor: actor,
|
||||||
rollData: rollData,
|
rollData: rollData,
|
||||||
encaissement: encaissement,
|
encaissement: encaissement
|
||||||
show: show
|
|
||||||
});
|
});
|
||||||
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, show, attackerId, onEncaisser);
|
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser);
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(html, actor, rollData, armure, encaissement, show, attackerId, onEncaisser) {
|
constructor(html, actor, rollData, armure, encaissement, onEncaisser) {
|
||||||
// Common conf
|
// Common conf
|
||||||
let buttons = {
|
let buttons = {
|
||||||
"valider": { label: "Valider", callback: html => this.onValider() },
|
"valider": { label: "Valider", callback: html => this.onValider() },
|
||||||
@ -47,8 +46,6 @@ export class DialogValidationEncaissement extends Dialog {
|
|||||||
this.rollData = rollData;
|
this.rollData = rollData;
|
||||||
this.armure = armure;
|
this.armure = armure;
|
||||||
this.encaissement = encaissement;
|
this.encaissement = encaissement;
|
||||||
this.show = show;
|
|
||||||
this.attackerId = attackerId;
|
|
||||||
this.onEncaisser = onEncaisser;
|
this.onEncaisser = onEncaisser;
|
||||||
this.forceDiceResult = {total: encaissement.roll.result };
|
this.forceDiceResult = {total: encaissement.roll.result };
|
||||||
}
|
}
|
||||||
@ -67,6 +64,6 @@ export class DialogValidationEncaissement extends Dialog {
|
|||||||
|
|
||||||
async onValider() {
|
async onValider() {
|
||||||
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
||||||
this.onEncaisser(this.encaissement, this.show, this.attackerId)
|
this.onEncaisser(this.encaissement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ const nomCategorieParade = {
|
|||||||
export class RdDItemArme extends Item {
|
export class RdDItemArme extends Item {
|
||||||
|
|
||||||
static isArme(item) {
|
static isArme(item) {
|
||||||
return RdDItemCompetenceCreature.getCategorieAttaque(item) || item.type == TYPES.arme;
|
return item.type == TYPES.arme || RdDItemCompetenceCreature.getCategorieAttaque(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -55,6 +55,20 @@ export class RdDItemCompetenceCreature extends Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
static isCompetenceAttaque(item) {
|
||||||
|
if (item.type == TYPES.competencecreature) {
|
||||||
|
switch (item.system.categorie) {
|
||||||
|
case "melee":
|
||||||
|
case "tir":
|
||||||
|
case "lancer":
|
||||||
|
case "naturelle":
|
||||||
|
case "possession":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
static getCategorieAttaque(item) {
|
static getCategorieAttaque(item) {
|
||||||
if (item.type == TYPES.competencecreature) {
|
if (item.type == TYPES.competencecreature) {
|
||||||
switch (item.system.categorie) {
|
switch (item.system.categorie) {
|
||||||
@ -63,6 +77,7 @@ export class RdDItemCompetenceCreature extends Item {
|
|||||||
case "lancer":
|
case "lancer":
|
||||||
case "naturelle":
|
case "naturelle":
|
||||||
case "possession":
|
case "possession":
|
||||||
|
case "parade":
|
||||||
return item.system.categorie
|
return item.system.categorie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,8 @@ export class Misc {
|
|||||||
|
|
||||||
static keepDecimals(num, decimals) {
|
static keepDecimals(num, decimals) {
|
||||||
if (decimals <= 0 || decimals > 6) return num;
|
if (decimals <= 0 || decimals > 6) return num;
|
||||||
const decimal = Math.pow(10, parseInt(decimals));
|
const power10n = Math.pow(10, parseInt(decimals));
|
||||||
return Math.round(num * decimal) / decimal;
|
return Math.round(num * power10n) / power10n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getFractionHtml(diviseur) {
|
static getFractionHtml(diviseur) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
|
|
||||||
const tableCaracDerivee = {
|
const TABLE_CARACTERISTIQUES_DERIVEES = {
|
||||||
// xp: coût pour passer du niveau inférieur à ce niveau
|
// xp: coût pour passer du niveau inférieur à ce niveau
|
||||||
1: { xp: 3, poids: "moins de 1kg", plusdom: -5, sconst: 0.5, sust: 0.1 },
|
1: { xp: 3, poids: "moins de 1kg", plusdom: -5, sconst: 0.5, sust: 0.1 },
|
||||||
2: { xp: 3, poids: "1-5", plusdom: -4, sconst: 0.5, sust: 0.3 },
|
2: { xp: 3, poids: "1-5", plusdom: -4, sconst: 0.5, sust: 0.3 },
|
||||||
@ -58,6 +58,10 @@ export class RdDCarac {
|
|||||||
selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/);
|
selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Dérobée|Mêlée|Tir|Lancer)/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getCaracDerivee(value) {
|
||||||
|
return TABLE_CARACTERISTIQUES_DERIVEES[Math.min(Math.max(Number(value), 1), 32)];
|
||||||
|
}
|
||||||
|
|
||||||
static computeTotal(carac, beaute = undefined) {
|
static computeTotal(carac, beaute = undefined) {
|
||||||
const total = Object.values(carac ?? {}).filter(c => !c.derivee)
|
const total = Object.values(carac ?? {}).filter(c => !c.derivee)
|
||||||
.map(it => parseInt(it.value))
|
.map(it => parseInt(it.value))
|
||||||
@ -73,7 +77,7 @@ export class RdDCarac {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static calculSConst(constitution) {
|
static calculSConst(constitution) {
|
||||||
return Number(tableCaracDerivee[Number(constitution)].sconst);
|
return RdDCarac.getCaracDerivee(constitution).sconst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -84,7 +88,7 @@ export class RdDCarac {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static getCaracXp(targetValue) {
|
static getCaracXp(targetValue) {
|
||||||
return tableCaracDerivee[targetValue]?.xp ?? 200;
|
return RdDCarac.getCaracDerivee(targetValue)?.xp ?? 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -97,37 +101,4 @@ export class RdDCarac {
|
|||||||
return Grammar.toLowerCaseNoAccent(selectedCarac?.label)?.match(/(apparence|force|agilite|dexterite|vue|ouie|odorat|empathie|melee|tir|lancer|derobee)/);
|
return Grammar.toLowerCaseNoAccent(selectedCarac?.label)?.match(/(apparence|force|agilite|dexterite|vue|ouie|odorat|empathie|melee|tir|lancer|derobee)/);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static computeCarac(system) {
|
|
||||||
system.carac.force.value = Math.min(system.carac.force.value, parseInt(system.carac.taille.value) + 4);
|
|
||||||
|
|
||||||
system.carac.derobee.value = Math.floor(parseInt(((21 - system.carac.taille.value)) + parseInt(system.carac.agilite.value)) / 2);
|
|
||||||
let bonusDomKey = Math.floor((parseInt(system.carac.force.value) + parseInt(system.carac.taille.value)) / 2);
|
|
||||||
bonusDomKey = Math.min(Math.max(bonusDomKey, 0), 32); // Clamp de securite
|
|
||||||
|
|
||||||
let tailleData = tableCaracDerivee[bonusDomKey];
|
|
||||||
system.attributs.plusdom.value = tailleData.plusdom;
|
|
||||||
|
|
||||||
system.attributs.sconst.value = RdDCarac.calculSConst(system.carac.constitution.value);
|
|
||||||
system.attributs.sust.value = tableCaracDerivee[Number(system.carac.taille.value)].sust;
|
|
||||||
|
|
||||||
system.attributs.encombrement.value = (parseInt(system.carac.force.value) + parseInt(system.carac.taille.value)) / 2;
|
|
||||||
system.carac.melee.value = Math.floor((parseInt(system.carac.force.value) + parseInt(system.carac.agilite.value)) / 2);
|
|
||||||
system.carac.tir.value = Math.floor((parseInt(system.carac.vue.value) + parseInt(system.carac.dexterite.value)) / 2);
|
|
||||||
system.carac.lancer.value = Math.floor((parseInt(system.carac.tir.value) + parseInt(system.carac.force.value)) / 2);
|
|
||||||
|
|
||||||
system.sante.vie.max = Math.ceil((parseInt(system.carac.taille.value) + parseInt(system.carac.constitution.value)) / 2);
|
|
||||||
|
|
||||||
system.sante.vie.value = Math.min(system.sante.vie.value, system.sante.vie.max)
|
|
||||||
system.sante.endurance.max = Math.max(parseInt(system.carac.taille.value) + parseInt(system.carac.constitution.value), parseInt(system.sante.vie.max) + parseInt(system.carac.volonte.value));
|
|
||||||
system.sante.endurance.value = Math.min(system.sante.endurance.value, system.sante.endurance.max);
|
|
||||||
system.sante.fatigue.max = system.sante.endurance.max * 2;
|
|
||||||
system.sante.fatigue.value = Math.min(system.sante.fatigue.value, system.sante.fatigue.max);
|
|
||||||
|
|
||||||
//Compteurs
|
|
||||||
system.reve.reve.max = system.carac.reve.value;
|
|
||||||
system.compteurs.chance.max = system.carac.chance.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ export class RdDCombatManager extends Combat {
|
|||||||
let rollFormula = formula ?? RdDCombatManager.formuleInitiative(2, 10, 0, 0);
|
let rollFormula = formula ?? RdDCombatManager.formuleInitiative(2, 10, 0, 0);
|
||||||
if (!formula) {
|
if (!formula) {
|
||||||
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
|
if (combatant.actor.type == 'creature' || combatant.actor.type == 'entite') {
|
||||||
const competence = combatant.actor.items.find(it => RdDItemCompetenceCreature.getCategorieAttaque(it))
|
const competence = combatant.actor.items.find(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
|
||||||
if (competence) {
|
if (competence) {
|
||||||
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, 0);
|
rollFormula = RdDCombatManager.formuleInitiative(2, competence.system.carac_value, competence.system.niveau, 0);
|
||||||
}
|
}
|
||||||
@ -229,7 +229,9 @@ export class RdDCombatManager extends Combat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static listActionsCreature(competences) {
|
static listActionsCreature(competences) {
|
||||||
return competences.map(it => RdDItemCompetenceCreature.armeCreature(it))
|
return competences
|
||||||
|
.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
|
||||||
|
.map(it => RdDItemCompetenceCreature.armeCreature(it))
|
||||||
.filter(it => it != undefined);
|
.filter(it => it != undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,11 +29,12 @@ import { Environnement } from "./environnement.js";
|
|||||||
import { RdDActor } from "./actor.js";
|
import { RdDActor } from "./actor.js";
|
||||||
import { RdDBaseActor } from "./actor/base-actor.js";
|
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||||
import { RdDCommerce } from "./actor/commerce.js";
|
import { RdDCommerce } from "./actor/commerce.js";
|
||||||
|
import { RdDEntite } from "./actor/entite.js";
|
||||||
import { RdDVehicule } from "./actor/vehicule.js";
|
import { RdDVehicule } from "./actor/vehicule.js";
|
||||||
import { RdDActorSheet } from "./actor-sheet.js";
|
import { RdDActorSheet } from "./actor-sheet.js";
|
||||||
import { RdDCommerceSheet } from "./actor/commerce-sheet.js";
|
import { RdDCommerceSheet } from "./actor/commerce-sheet.js";
|
||||||
import { RdDActorCreatureSheet } from "./actor-creature-sheet.js";
|
import { RdDActorCreatureSheet } from "./actor-creature-sheet.js";
|
||||||
import { RdDActorEntiteSheet } from "./actor-entite-sheet.js";
|
import { RdDActorEntiteSheet } from "./actor/entite-sheet.js";
|
||||||
import { RdDActorVehiculeSheet } from "./actor/vehicule-sheet.js";
|
import { RdDActorVehiculeSheet } from "./actor/vehicule-sheet.js";
|
||||||
|
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
@ -93,7 +94,7 @@ export class SystemReveDeDragon {
|
|||||||
this.actorClasses = {
|
this.actorClasses = {
|
||||||
commerce: RdDCommerce,
|
commerce: RdDCommerce,
|
||||||
creature: RdDActor,
|
creature: RdDActor,
|
||||||
entite: RdDActor,
|
entite: RdDEntite,
|
||||||
personnage: RdDActor,
|
personnage: RdDActor,
|
||||||
vehicule: RdDVehicule,
|
vehicule: RdDVehicule,
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ const reussites = [
|
|||||||
|
|
||||||
const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false }
|
const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false }
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const caracMaximumResolution = 60;
|
const CARAC_MAXIMUM_RESOLUTION = 40;
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDResolutionTable {
|
export class RdDResolutionTable {
|
||||||
static resolutionTable = this.build()
|
static resolutionTable = this.build()
|
||||||
@ -36,7 +36,7 @@ export class RdDResolutionTable {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static build() {
|
static build() {
|
||||||
let table = []
|
let table = []
|
||||||
for (var caracValue = 0; caracValue <= caracMaximumResolution; caracValue++) {
|
for (var caracValue = 0; caracValue <= CARAC_MAXIMUM_RESOLUTION; caracValue++) {
|
||||||
table[caracValue] = this._computeRow(caracValue);
|
table[caracValue] = this._computeRow(caracValue);
|
||||||
}
|
}
|
||||||
return table;
|
return table;
|
||||||
|
@ -55,7 +55,8 @@ function _cumulSegmentsFatigue(matrix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export const fatigueMatrix = _buildAllSegmentsFatigue(60);
|
export const MAX_ENDURANCE_FATIGUE = 60;
|
||||||
|
const fatigueMatrix = _buildAllSegmentsFatigue(MAX_ENDURANCE_FATIGUE);
|
||||||
const cumulFatigueMatrix = _cumulSegmentsFatigue(fatigueMatrix);
|
const cumulFatigueMatrix = _cumulSegmentsFatigue(fatigueMatrix);
|
||||||
|
|
||||||
const fatigueMalus = [0, 0, 0, -1, -1, -1, -2, -3, -4, -5, -6, -7]; // Provides the malus for each segment of fatigue
|
const fatigueMalus = [0, 0, 0, -1, -1, -1, -2, -3, -4, -5, -6, -7]; // Provides the malus for each segment of fatigue
|
||||||
@ -465,11 +466,10 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static calculMalusFatigue(fatigue, maxEnd) {
|
static calculMalusFatigue(fatigue, endurance) {
|
||||||
maxEnd = Math.max(maxEnd, 1);
|
endurance = Math.min(Math.max(endurance, 1), cumulFatigueMatrix.length);
|
||||||
maxEnd = Math.min(maxEnd, cumulFatigueMatrix.length);
|
let segments = cumulFatigueMatrix[endurance];
|
||||||
let segments = cumulFatigueMatrix[maxEnd];
|
for (let i = 0; i < segments.length; i++) {
|
||||||
for (let i = 0; i < 12; i++) {
|
|
||||||
if (fatigue <= segments[i]) {
|
if (fatigue <= segments[i]) {
|
||||||
return fatigueMalus[i]
|
return fatigueMalus[i]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user