#101 Gestion des status de surprise
La demi-surprise ou surprise dépend des états: - les TMRs sont ouvertes (sauf visu) - le personnage est sonné - un status parmi: prone, restrain - si inconscient ou aveugle, surprise totale Ajout de la possibilité de filtrer les status
This commit is contained in:
156
module/actor.js
156
module/actor.js
@ -18,6 +18,8 @@ import { RdDAudio } from "./rdd-audio.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { RdDItemArme } from "./item-arme.js";
|
||||
import { RdDAlchimie } from "./rdd-alchimie.js";
|
||||
import { StatusEffects } from "./status-effects.js";
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
@ -27,7 +29,11 @@ import { RdDAlchimie } from "./rdd-alchimie.js";
|
||||
export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
static init() {
|
||||
Hooks.on("deleteActiveEffect", (actor, effect, options) => actor.onDeleteActiveEffect(effect, options));
|
||||
Hooks.on("createActiveEffect", (actor, effect, options) => actor.onCreateActiveEffect(effect, options));
|
||||
Hooks.on("updateToken", (scene, token, data, options) => { RdDActor.onUpdateToken(scene, token, data, options) });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
* Override the create() function to provide additional RdD functionality.
|
||||
@ -249,24 +255,19 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getSurprise() {
|
||||
// TODO: gérer une liste de flags demi-surprise (avec icône sur le token)?
|
||||
if (this.getSonne()) {
|
||||
getSurprise(isCombat = true) {
|
||||
let niveauSurprise = Array.from(this.effects?.values() ?? [])
|
||||
.map(effect => StatusEffects.valeurSurprise(effect.data, isCombat))
|
||||
.reduce((a,b)=> a+b, 0);
|
||||
if (niveauSurprise>1) {
|
||||
return 'totale';
|
||||
}
|
||||
if (niveauSurprise==1 || this.getSonne()) {
|
||||
return 'demi';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isDemiSurprise() {
|
||||
return this.getSurprise() == 'demi';
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isSurpriseTotale() {
|
||||
return this.getSurprise() == 'totale';
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async dormirChateauDormant() {
|
||||
let message = {
|
||||
@ -1059,17 +1060,31 @@ export class RdDActor extends Actor {
|
||||
return !this.isEntiteCauchemar() && (this.data.data.sante.sonne?.value ?? false);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getSConst() {
|
||||
|
||||
if (!this.isEntiteCauchemar() && this.data.data.attributs) {
|
||||
return this.data.data.attributs.sconst.value;
|
||||
async setSonne(sonne = true) {
|
||||
if (this.isEntiteCauchemar()) {
|
||||
return;
|
||||
}
|
||||
return 0;
|
||||
await this.setStatusSonne(sonne);
|
||||
await this.setStateSonne(sonne);
|
||||
}
|
||||
|
||||
async setStateSonne(sonne) {
|
||||
if (this.isEntiteCauchemar()) {
|
||||
return;
|
||||
}
|
||||
await this.update({ "data.sante.sonne.value": sonne });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
testSiSonne(sante, endurance) {
|
||||
getSConst() {
|
||||
if (this.isEntiteCauchemar()) {
|
||||
return 0;
|
||||
}
|
||||
return this.data.data.attributs?.sconst?.value ?? 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async testSiSonne(sante, endurance) {
|
||||
const roll = new Roll("1d20").roll();
|
||||
roll.showDice = true;
|
||||
RdDDice.show(roll);
|
||||
@ -1084,6 +1099,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
if (result.sonne) {
|
||||
// 20 is always a failure
|
||||
await this.setSonne();
|
||||
sante.sonne.value = true;
|
||||
}
|
||||
return result;
|
||||
@ -1156,7 +1172,7 @@ export class RdDActor extends Actor {
|
||||
const perte = compteur.value - result.newValue;
|
||||
if (perte > 1) {
|
||||
// Peut-être sonné si 2 points d'endurance perdus d'un coup
|
||||
const testIsSonne = this.testSiSonne(sante, result.newValue);
|
||||
const testIsSonne = await this.testSiSonne(sante, result.newValue);
|
||||
result.sonne = testIsSonne.sonne;
|
||||
result.jetEndurance = testIsSonne.roll.total;
|
||||
} else if (inc > 0) {
|
||||
@ -2589,6 +2605,100 @@ export class RdDActor extends Actor {
|
||||
await this.update( { 'data.subacteurs.suivants': newSuivants });
|
||||
await this.update( { 'data.subacteurs.montures': newMontures });
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async onCreateActiveEffect(effect, options) {
|
||||
switch (StatusEffects.statusId(effect)) {
|
||||
case 'sonne':
|
||||
await this.setStateSonne(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onDeleteActiveEffect(effect, options) {
|
||||
switch (StatusEffects.statusId(effect)) {
|
||||
case 'sonne':
|
||||
await this.setStateSonne(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
enleverTousLesEffets() {
|
||||
this.deleteEmbeddedEntity('ActiveEffect', Array.from(this.effects?.keys() ?? []));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
listeEffets(matching = it => true) {
|
||||
const all = Array.from(this.effects?.values() ?? []);
|
||||
const filtered = all.filter(it => matching(it.data));
|
||||
return filtered;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async setStatusDemiReve(status) {
|
||||
const options = { renderSheet: true/*, noHook: from == 'hook' */ };
|
||||
if (status) {
|
||||
await this.addEffect(StatusEffects.demiReve(), options)
|
||||
}
|
||||
else {
|
||||
this.deleteEffect(StatusEffects.demiReve(), options)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async setStatusSonne(sonne) {
|
||||
if (this.isEntiteCauchemar()) {
|
||||
return;
|
||||
}
|
||||
const id = 'sonne';
|
||||
const options = { renderSheet: true/*, noHook: from == 'hook' */ };
|
||||
|
||||
if (sonne) {
|
||||
await this.addById(id, options);
|
||||
}
|
||||
else /* if (!sonne)*/ {
|
||||
this.deleteById(id, options)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
deleteById(id, options) {
|
||||
const effects = Array.from(this.effects?.values())
|
||||
.filter(it => it.data.flags.core?.statusId == id);
|
||||
this._deleteAll(effects, options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
deleteEffect(effect, options) {
|
||||
const toDelete = Array.from(this.effects?.values())
|
||||
.filter(it => StatusEffects.statusId(it.data) == StatusEffects.statusId(effect));
|
||||
this._deleteAll(toDelete, options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_deleteAll(effects, options) {
|
||||
this._deleteAllIds(effects.map(it => it.id), options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_deleteAllIds(effectIds, options) {
|
||||
this.deleteEmbeddedEntity('ActiveEffect', effectIds, options);
|
||||
this.applyActiveEffects();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async addById(id, options) {
|
||||
const statusEffect = CONFIG.statusEffects.find(it => it.id == id);
|
||||
await this.addEffect(statusEffect, options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async addEffect(statusEffect, options) {
|
||||
this.deleteById(statusEffect.id, options);
|
||||
const effet = duplicate(statusEffect);
|
||||
effet["flags.core.statusId"] = effet.id;
|
||||
await this.createEmbeddedEntity('ActiveEffect', effet, options);
|
||||
this.applyActiveEffects();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user