forked from public/foundryvtt-reve-de-dragon
Séparation de l'Actor Entités
This commit is contained in:
638
module/actor.js
638
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 { RdDRollDialogEthylisme } from "./rdd-roll-ethylisme.js";
|
||||
import { RdDRoll } from "./rdd-roll.js";
|
||||
@ -10,13 +10,9 @@ import { RdDRollTables } from "./rdd-rolltables.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { RdDItemSort } from "./item-sort.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 { RdDItemArme } from "./item-arme.js";
|
||||
import { RdDAlchimie } from "./rdd-alchimie.js";
|
||||
import { STATUSES, StatusEffects } from "./settings/status-effects.js";
|
||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||
import { STATUSES } from "./settings/status-effects.js";
|
||||
import { RdDItemSigneDraconique } from "./item/signedraconique.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.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 { RollDataAjustements } from "./rolldata-ajustements.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 { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
|
||||
import { RdDRencontre } from "./item/rencontre.js";
|
||||
import { Targets } from "./targets.js";
|
||||
import { DialogRepos } from "./sommeil/dialog-repos.js";
|
||||
import { RdDBaseActor } from "./actor/base-actor.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 { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js";
|
||||
import { TYPES } from "./item.js";
|
||||
import { RdDBaseActorVivant } from "./actor/base-actor-vivant.js";
|
||||
|
||||
const POSSESSION_SANS_DRACONIC = {
|
||||
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.
|
||||
* @extends {Actor}
|
||||
*/
|
||||
export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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();
|
||||
}
|
||||
export class RdDActor extends RdDBaseActorVivant {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
* 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
|
||||
RdDCarac.computeCarac(actorData.system)
|
||||
this.$computeCaracDerivee()
|
||||
this.computeIsHautRevant();
|
||||
await this.cleanupConteneurs();
|
||||
await this.computeEncTotal();
|
||||
this.cleanupConteneurs();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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)
|
||||
}
|
||||
$computeCaracDerivee() {
|
||||
this.system.carac.force.value = Math.min(this.system.carac.force.value, parseInt(this.system.carac.taille.value) + 4);
|
||||
|
||||
this.system.carac.derobee.value = Math.floor(parseInt(((21 - this.system.carac.taille.value)) + parseInt(this.system.carac.agilite.value)) / 2);
|
||||
let bonusDomKey = Math.floor((parseInt(this.system.carac.force.value) + parseInt(this.system.carac.taille.value)) / 2);
|
||||
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) {
|
||||
if (this.isCreature()) {
|
||||
return item.type == TYPES.competencecreature || item.isInventaire();
|
||||
}
|
||||
if (this.isEntite()) {
|
||||
return item.type == 'competencecreature';
|
||||
}
|
||||
if (this.isPersonnage()) {
|
||||
switch (item.type) {
|
||||
case 'competencecreature': case 'tarot': case 'service':
|
||||
@ -121,27 +118,13 @@ export class RdDActor extends RdDBaseActor {
|
||||
isHautRevant() {
|
||||
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() {
|
||||
switch (this.type) {
|
||||
case 'personnage':
|
||||
return Misc.toInt(this.system.reve?.reve?.value ?? this.carac.reve.value);
|
||||
case 'creature':
|
||||
case 'entite':
|
||||
return Misc.toInt(this.system.carac.reve?.value)
|
||||
default:
|
||||
return 0;
|
||||
@ -158,9 +141,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getForce() {
|
||||
if (this.isEntite()) {
|
||||
return Misc.toInt(this.system.carac.reve?.value);
|
||||
}
|
||||
return Misc.toInt(this.system.carac.force?.value);
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
@ -168,7 +148,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
switch (this.type) {
|
||||
case 'personnage': return Misc.toInt(this.system.carac.agilite?.value);
|
||||
case 'creature': return Misc.toInt(this.system.carac.force?.value);
|
||||
case 'entite': return Misc.toInt(this.system.carac.reve?.value);
|
||||
}
|
||||
return 10;
|
||||
}
|
||||
@ -214,28 +193,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
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) {
|
||||
return this.findItemLike(id, 'tache');
|
||||
@ -285,15 +242,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
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() {
|
||||
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
|
||||
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()
|
||||
});
|
||||
|
||||
await this._openRollDialog({
|
||||
await this.openRollDialog({
|
||||
name: `jet-${this.id}`,
|
||||
label: `Jet de ${this.name}`,
|
||||
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) {
|
||||
if (consigne.ignorer) {
|
||||
return;
|
||||
@ -606,9 +523,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async remiseANeuf() {
|
||||
if (this.isEntite([ENTITE_NONINCARNE])) {
|
||||
return;
|
||||
}
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
||||
content: 'Remise à neuf de ' + this.name
|
||||
@ -701,7 +615,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
return 'eveil';
|
||||
}
|
||||
else {
|
||||
if (!ReglesOptionnelles.isUsing("recuperation-reve")) {
|
||||
if (!ReglesOptionnelles.isUsing("recuperation-reve")) {
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name),
|
||||
content: `Pas de récupération de rêve (${reve} points ignorés)`
|
||||
@ -751,7 +665,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
async recupererFatigue(message) {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
let fatigue = this.system.sante.fatigue.value;
|
||||
const fatigueMin = this._computeFatigueMin();
|
||||
const fatigueMin = this.$getFatigueMin();
|
||||
if (fatigue <= fatigueMin) {
|
||||
return;
|
||||
}
|
||||
@ -878,7 +792,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
this.setPointsDeChance(to);
|
||||
}
|
||||
}
|
||||
let selectedCarac = RdDActor._findCaracByName(this.system.carac, caracName);
|
||||
let selectedCarac = RdDBaseActorVivant._findCaracByName(this.system.carac, caracName);
|
||||
const from = selectedCarac.value
|
||||
await this.update({ [`system.carac.${caracName}.value`]: to });
|
||||
await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName);
|
||||
@ -889,7 +803,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
if (caracName == 'Taille') {
|
||||
return;
|
||||
}
|
||||
let selectedCarac = RdDActor._findCaracByName(this.system.carac, caracName);
|
||||
let selectedCarac = RdDBaseActorVivant._findCaracByName(this.system.carac, caracName);
|
||||
if (!selectedCarac.derivee) {
|
||||
const from = Number(selectedCarac.xp);
|
||||
await this.update({ [`system.carac.${caracName}.xp`]: to });
|
||||
@ -903,7 +817,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
if (caracName == 'Taille') {
|
||||
return;
|
||||
}
|
||||
let carac = RdDActor._findCaracByName(this.system.carac, caracName);
|
||||
let carac = RdDBaseActorVivant._findCaracByName(this.system.carac, caracName);
|
||||
if (carac) {
|
||||
carac = duplicate(carac);
|
||||
const fromXp = Number(carac.xp);
|
||||
@ -1117,18 +1031,12 @@ export class RdDActor extends RdDBaseActor {
|
||||
await this.update({ [`system.attributs.${fieldName}.value`]: fieldValue });
|
||||
}
|
||||
|
||||
|
||||
|
||||
isSurenc() {
|
||||
return this.isPersonnage() ? (this.computeMalusSurEncombrement() < 0) : false
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
computeMalusSurEncombrement() {
|
||||
switch (this.type) {
|
||||
case 'entite':
|
||||
return 0;
|
||||
}
|
||||
return Math.min(0, Math.floor(this.getEncombrementMax() - this.encTotal));
|
||||
}
|
||||
|
||||
@ -1138,12 +1046,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getEncombrementMax() {
|
||||
switch (this.type) {
|
||||
case 'entite':
|
||||
return 0;
|
||||
default:
|
||||
return this.system.attributs.encombrement.value
|
||||
}
|
||||
return this.system.attributs.encombrement.value
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -1184,12 +1087,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
recompute() {
|
||||
if (this.type == 'entite') {
|
||||
// Pas d'état général pour les entités forçage à 0
|
||||
this.system.compteurs.etat.value = 0;
|
||||
return
|
||||
}
|
||||
async computeEtatGeneral() {
|
||||
this.system.compteurs.etat.value = this.$malusVie() + this.$malusFatigue() + this.$malusEthylisme();
|
||||
}
|
||||
|
||||
@ -1202,19 +1100,42 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
$malusFatigue() {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && this.system.sante.fatigue) {
|
||||
const max = Math.max(1, Math.min(this.system.sante.endurance.max, 60));
|
||||
getEnduranceActuelle() {
|
||||
return Number(this.system.sante.endurance.value);
|
||||
}
|
||||
|
||||
let fatigueTab = RdDUtility.getSegmentsFatigue(max);
|
||||
let reste = Math.min(max * 2, Math.max(0, this.system.sante.fatigue.value));
|
||||
for (let idx = 0; idx < fatigueTab.length; idx++) {
|
||||
reste -= fatigueTab[idx];
|
||||
if (reste <= 0) {
|
||||
return fatigueMalus[idx];
|
||||
}
|
||||
}
|
||||
return -7; // This is the max !
|
||||
getFatigueActuelle() {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && this.isPersonnage()) {
|
||||
return Math.max(0, Math.min(this.$getFatigueMax(), this.system.sante.fatigue?.value));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -1436,9 +1357,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async setSonne(sonne = true) {
|
||||
if (this.isEntite()) {
|
||||
return;
|
||||
}
|
||||
if (!game.combat && sonne) {
|
||||
ui.notifications.info("Le personnage est hors combat, il ne reste donc pas sonné");
|
||||
return;
|
||||
@ -1448,9 +1366,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getSConst() {
|
||||
if (this.isEntite()) {
|
||||
return 0;
|
||||
}
|
||||
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));
|
||||
//console.log("New value ", inc, minValue, result.newValue);
|
||||
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
|
||||
sante.vie.value--;
|
||||
result.perteVie = true;
|
||||
@ -1580,23 +1495,18 @@ export class RdDActor extends RdDBaseActor {
|
||||
compteur.value = result.newValue;
|
||||
// If endurance lost, then the same amount of fatigue cannot be recovered
|
||||
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 })
|
||||
if (this.isDead()) {
|
||||
await this.setEffect(STATUSES.StatusComma, true);
|
||||
}
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
isDead() {
|
||||
return !this.isEntite() && this.system.sante.vie.value < -this.getSConst()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_computeFatigueMin() {
|
||||
return this.system.sante.endurance.max - this.system.sante.endurance.value;
|
||||
return this.system.sante.vie.value < -this.getSConst()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -2003,7 +1913,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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) {
|
||||
const niveauSuivant = Number(carac.value) + 1;
|
||||
let xpNeeded = RdDCarac.getCaracNextXp(niveauSuivant);
|
||||
@ -2152,7 +2062,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
const draconicList = this.computeDraconicAndSortIndex(sorts);
|
||||
const reve = duplicate(this.system.carac.reve);
|
||||
|
||||
const dialog = await this._openRollDialog({
|
||||
const dialog = await this.openRollDialog({
|
||||
name: 'lancer-un-sort',
|
||||
label: 'Lancer un sort',
|
||||
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);
|
||||
if (countInertieDraconique > 0) {
|
||||
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
|
||||
* @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 }) {
|
||||
const nomTache = "Lire " + item.name;
|
||||
@ -2405,7 +2253,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
|
||||
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')
|
||||
}
|
||||
|
||||
@ -2423,7 +2270,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
const competence = this.getCompetence(compName);
|
||||
await this._openRollDialog({
|
||||
await this.openRollDialog({
|
||||
name: 'jet-competence',
|
||||
label: 'Jet ' + Grammar.apostrophe('de', competence.name),
|
||||
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)
|
||||
compData.system.defaut_carac = tacheData.system.carac; // Patch !
|
||||
|
||||
await this._openRollDialog({
|
||||
await this.openRollDialog({
|
||||
name: 'jet-competence',
|
||||
label: 'Jet de Tâche ' + tacheData.name,
|
||||
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]);
|
||||
}
|
||||
|
||||
await this._openRollDialog({
|
||||
await this.openRollDialog({
|
||||
name: `jet-${artData.art}`,
|
||||
label: `${artData.verbe} ${oeuvre.name}`,
|
||||
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,
|
||||
{
|
||||
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',
|
||||
@ -2765,6 +2612,10 @@ export class RdDActor extends RdDBaseActor {
|
||||
this.tmrApp?.setTMRPendingAction(dialog);
|
||||
}
|
||||
|
||||
async _onCloseRollDialog(html) {
|
||||
this.tmrApp?.restoreTMRAfterAction()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _rollLireSigneDraconique(rollData) {
|
||||
const compData = rollData.competence;
|
||||
@ -2786,7 +2637,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollAppelChance(onSuccess = () => { }, onEchec = () => { }) {
|
||||
await this._openRollDialog({
|
||||
await this.openRollDialog({
|
||||
name: 'appelChance',
|
||||
label: 'Appel à la chance',
|
||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
|
||||
@ -2838,7 +2689,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
ajustementAstrologique() {
|
||||
if (this.isCreatureEntite()) {
|
||||
if (this.isCreature()) {
|
||||
return 0;
|
||||
}
|
||||
// selon l'heure de naissance...
|
||||
@ -2904,7 +2755,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
async _xpCarac(xpData) {
|
||||
if (xpData.xpCarac > 0) {
|
||||
let carac = duplicate(this.system.carac);
|
||||
let selectedCarac = RdDActor._findCaracByName(carac, xpData.caracName);
|
||||
let selectedCarac = RdDBaseActorVivant._findCaracByName(carac, xpData.caracName);
|
||||
if (!selectedCarac.derivee) {
|
||||
const from = Number(selectedCarac.xp);
|
||||
const to = from + xpData.xpCarac;
|
||||
@ -2957,51 +2808,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
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
|
||||
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) {
|
||||
const blessure = blesse.blessuresASoigner().find(it => it.id == blessureId);
|
||||
if (blessure) {
|
||||
@ -3207,12 +2958,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
RdDPossession.onConjurerPossession(this, possession)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getArmeParade(armeParadeId) {
|
||||
const item = armeParadeId ? this.getEmbeddedDocument('Item', armeParadeId) : undefined;
|
||||
return RdDItemArme.getArme(item);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
verifierForceMin(item) {
|
||||
if (item.type == 'arme' && item.system.force > this.system.carac.force.value) {
|
||||
@ -3229,7 +2974,7 @@ export class RdDActor extends RdDBaseActor {
|
||||
if (item?.isEquipable()) {
|
||||
const isEquipe = !item.system.equipe;
|
||||
await this.updateEmbeddedDocuments('Item', [{ _id: item.id, "system.equipe": isEquipe }]);
|
||||
this.computeEncTotal(); // Mise à jour encombrement
|
||||
this.computeEncTotal();
|
||||
if (isEquipe)
|
||||
this.verifierForceMin(item);
|
||||
}
|
||||
@ -3264,79 +3009,24 @@ export class RdDActor extends RdDBaseActor {
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
async onAppliquerJetEncaissement(encaissement, attacker) {
|
||||
const santeOrig = duplicate(this.system.sante);
|
||||
const blessure = await this.ajouterBlessure(encaissement, attacker); // Will update the result table
|
||||
const perteVie = this.isEntite()
|
||||
? { newValue: 0 }
|
||||
: await this.santeIncDec("vie", -encaissement.vie);
|
||||
const perteVie = await this.santeIncDec("vie", -encaissement.vie);
|
||||
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique());
|
||||
|
||||
mergeObject(encaissement, {
|
||||
alias: this.name,
|
||||
hasPlayerOwner: this.hasPlayerOwner,
|
||||
resteEndurance: this.system.sante.endurance.value,
|
||||
resteEndurance: perteEndurance.newValue,
|
||||
sonne: perteEndurance.sonne,
|
||||
jetEndurance: perteEndurance.jetEndurance,
|
||||
endurance: santeOrig.endurance.value - perteEndurance.newValue,
|
||||
vie: this.isEntite() ? 0 : (santeOrig.vie.value - perteVie.newValue),
|
||||
blessure: blessure,
|
||||
show: show ?? {}
|
||||
endurance: perteEndurance.perte,
|
||||
vie: santeOrig.vie.value - perteVie.newValue,
|
||||
blessure: blessure
|
||||
});
|
||||
|
||||
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) {
|
||||
if (this.isEntite()) return; // Une entité n'a pas de blessures
|
||||
if (encaissement.gravite < 0) return;
|
||||
if (encaissement.gravite > 0) {
|
||||
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);
|
||||
if (blessure.isCritique()) {
|
||||
encaissement.endurance = endActuelle;
|
||||
@ -3392,71 +3082,6 @@ export class RdDActor extends RdDBaseActor {
|
||||
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) {
|
||||
let recetteData = this.findItemLike(recetteId, 'recettealchimique');
|
||||
@ -3760,43 +3385,8 @@ export class RdDActor extends RdDBaseActor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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.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);
|
||||
}
|
||||
isEffectAllowed(statusId) {
|
||||
return true
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
Reference in New Issue
Block a user