#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:
Vincent Vandemeulebrouck
2021-01-13 03:42:13 +01:00
parent 1d56bff61d
commit a0213fb552
16 changed files with 371 additions and 96 deletions

View File

@ -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();
}
}