diff --git a/module/actor-sheet.js b/module/actor-sheet.js
index 1cca5819..c72a189b 100644
--- a/module/actor-sheet.js
+++ b/module/actor-sheet.js
@@ -8,6 +8,7 @@ import { HtmlUtility } from "./html-utility.js";
import { RdDItem } from "./item.js";
import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js";
+import { RdDBonus } from "./rdd-bonus.js";
/* -------------------------------------------- */
export class RdDActorSheet extends ActorSheet {
@@ -108,6 +109,7 @@ export class RdDActorSheet extends ActorSheet {
// Common data
data.data.competenceByCategory = data.competenceByCategory;
data.data.encTotal = this.actor.encTotal;
+ data.data.surprise = RdDBonus.find(this.actor.getSurprise(false)).descr;
data.data.isGM = game.user.isGM;
data.ajustementsConditions = CONFIG.RDD.ajustementsConditions;
data.difficultesLibres = CONFIG.RDD.difficultesLibres;
@@ -126,7 +128,6 @@ export class RdDActorSheet extends ActorSheet {
data.data.vehiculesList = this.actor.buildVehiculesList();
data.data.monturesList = this.actor.buildMonturesList();
data.data.suivantsList = this.actor.buildSuivantsList();
-
return data;
}
@@ -332,7 +333,9 @@ export class RdDActorSheet extends ActorSheet {
html.find('#dormir-chateau-dormant').click((event) => {
this.actor.dormirChateauDormant();
});
-
+ html.find('#enlever-tous-effets').click((event) => {
+ this.actor.enleverTousLesEffets();
+ });
// Display info about queue
html.find('.queuesouffle-label a').click((event) => {
let myID = event.currentTarget.attributes['data-item-id'].value;
@@ -483,6 +486,10 @@ export class RdDActorSheet extends ActorSheet {
this.actor.santeIncDec("endurance", -1);
this.render(true);
});
+ html.find('.data-sante-sonne').click((event) => {
+ this.actor.setSonne(event.currentTarget.checked);
+ this.render(true);
+ });
html.find('#ptreve-actuel-plus').click((event) => {
this.actor.reveActuelIncDec(1);
this.render(true);
diff --git a/module/actor.js b/module/actor.js
index 9d8c0d55..f931bb56 100644
--- a/module/actor.js
+++ b/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();
+ }
}
-
-
diff --git a/module/rdd-bonus.js b/module/rdd-bonus.js
index a0d21036..bce20f3d 100644
--- a/module/rdd-bonus.js
+++ b/module/rdd-bonus.js
@@ -36,9 +36,9 @@ export class RdDBonus {
} else {
dmg.dmgArme = RdDBonus._dmgArme(rollData);
dmg.penetration = RdDBonus._peneration(rollData);
- dmg.dmgTactique = RdDBonus.dmgBonus(rollData.ajustements?.tactique);
+ dmg.dmgTactique = RdDBonus.dmgBonus(rollData.tactique);
dmg.dmgParticuliere = RdDBonus._dmgParticuliere(rollData);
- dmg.dmgSurprise = RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris);
+ dmg.dmgSurprise = RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used);
dmg.dmgActor = rollData.selectedCarac ? RdDBonus._dmgPerso(dmgActor, rollData.selectedCarac.label, dmg.dmgArme) : 0;
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
dmg.mortalite = RdDBonus._calculMortalite(rollData, isCauchemar)
diff --git a/module/rdd-combat.js b/module/rdd-combat.js
index 427030de..43cd3efa 100644
--- a/module/rdd-combat.js
+++ b/module/rdd-combat.js
@@ -387,10 +387,11 @@ export class RdDCombat {
passeArme: randomID(16),
coupsNonMortels: false,
competence: competence,
- surprise: this.attacker.getSurprise(),
- surpriseDefenseur: this.defender.getSurprise(),
+ surprise: this.attacker.getSurprise(true),
+ surpriseDefenseur: this.defender.getSurprise(true),
essais: {}
};
+ rollData.diviseurSignificative = this._getDiviseurSignificative(rollData);
if (this.attacker.isCreature()) {
RdDItemCompetence.setRollDataCreature(rollData);
@@ -456,7 +457,8 @@ export class RdDCombat {
const paramDemandeDefense = {
passeArme: attackerRoll.passeArme,
essais: attackerRoll.essais,
- surprise: this.defender.getSurprise(),
+ // surprise: this.defender.getSurprise(true),
+ // surprise: attackerRoll.ajustements.attaqueDefenseurSurpris.used,
defender: this.defender,
attackerId: this.attackerId,
defenderTokenId: this.defenderTokenId,
@@ -557,10 +559,9 @@ export class RdDCombat {
}
_prepareParade(attackerRoll, armeParade) {
- const isCreature = this.defender.isCreature();
const compName = armeParade.data.competence;
const armeAttaque = attackerRoll.arme;
-
+
let rollData = {
passeArme: attackerRoll.passeArme,
forceValue: this.defender.getForceValue(),
@@ -568,14 +569,15 @@ export class RdDCombat {
attackerRoll: attackerRoll,
competence: this.defender.getCompetence(compName),
arme: armeParade,
- surprise: this.defender.getSurprise(),
+ surprise: this.defender.getSurprise(true),
needParadeSignificative: RdDItemArme.needParadeSignificative(armeAttaque, armeParade),
needResist: RdDItemArme.needArmeResist(armeAttaque, armeParade),
carac: this.defender.data.data.carac,
show: {}
};
- rollData.diviseur = this._getDiviseurSignificative(rollData);
- if (isCreature) {
+ rollData.diviseurSignificative = this._getDiviseurSignificative(rollData);
+
+ if (this.defender.isCreature()) {
RdDItemCompetence.setRollDataCreature(rollData);
}
return rollData;
@@ -583,7 +585,13 @@ export class RdDCombat {
/* -------------------------------------------- */
_getDiviseurSignificative(defenderRoll) {
- let facteurSign = (this.defender.isDemiSurprise() || defenderRoll.needParadeSignificative) ? 2 : 1;
+ let facteurSign = 1;
+ if (defenderRoll.surprise == 'demi'){
+ facteurSign *= 2;
+ }
+ if (defenderRoll.needParadeSignificative) {
+ facteurSign *= 2;
+ }
if (RdDBonus.isDefenseAttaqueFinesse(defenderRoll)) {
facteurSign *= 2;
}
@@ -656,12 +664,12 @@ export class RdDCombat {
diffLibre: attackerRoll.diffLibre,
attackerRoll: attackerRoll,
competence: competence,
- surprise: this.defender.getSurprise(),
- surpriseDefenseur: this.defender.getSurprise(),
+ surprise: this.defender.getSurprise(true),
+ surpriseDefenseur: this.defender.getSurprise(true),
carac: this.defender.data.data.carac,
show: {}
};
- rollData.diviseur = this._getDiviseurSignificative(rollData);
+ rollData.diviseurSignificative = this._getDiviseurSignificative(rollData);
if (this.defender.isCreature()) {
RdDItemCompetence.setRollDataCreature(rollData);
@@ -678,21 +686,21 @@ export class RdDCombat {
}
/* -------------------------------------------- */
- async _onEsquiveNormale(rollData) {
- console.log("RdDCombat._onEsquiveNormal >>>", rollData);
- this._consumeDefense(rollData.passeArme);
- await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-esquive.html');
+ async _onEsquiveNormale(defenderRoll) {
+ console.log("RdDCombat._onEsquiveNormal >>>", defenderRoll);
+ this._consumeDefense(defenderRoll.passeArme);
+ await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html');
}
/* -------------------------------------------- */
- async _onEsquiveEchec(rollData) {
- console.log("RdDCombat._onEsquiveEchec >>>", rollData);
+ async _onEsquiveEchec(defenderRoll) {
+ console.log("RdDCombat._onEsquiveEchec >>>", defenderRoll);
- await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-esquive.html');
+ await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html');
- this.removeChatMessageActionsPasseArme(rollData.passeArme);
- this._sendMessageDefense(rollData.attackerRoll, { defense: true })
- this._storeDefense(rollData);
+ this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
+ this._sendMessageDefense(defenderRoll.attackerRoll, { defense: true })
+ this._storeDefense(defenderRoll);
}
/* -------------------------------------------- */
@@ -776,12 +784,6 @@ export class RdDCombat {
return Misc.toInt(this.defender.data.data.carac.taille.value) - (attaque.forceValue + attaque.arme.data.dommagesReels);
}
- /* -------------------------------------------- */
- _sendMessageEncaisser(rollData) {
- let message = "" + this.defender.name + " doit:" + this._buildMessageEncaisser(rollData);
- RdDCombat._sendRollMessage(this.attacker, this.defender, this.defenderTokenId, "msg_encaisser", message, rollData);
- }
-
/* -------------------------------------------- */
async encaisser(attackerRoll, defenderTokenId) {
defenderTokenId = defenderTokenId || this.defenderTokenId;
diff --git a/module/rdd-main.js b/module/rdd-main.js
index 80ed4442..fc513fa7 100644
--- a/module/rdd-main.js
+++ b/module/rdd-main.js
@@ -23,6 +23,7 @@ import { RdDCommands } from "./rdd-commands.js";
import { RdDCombat } from "./rdd-combat.js";
import { ChatUtility } from "./chat-utility.js";
import { RdDItemCompetence } from "./item-competence.js";
+import { StatusEffects } from "./status-effects.js";
/* -------------------------------------------- */
/* Foundry VTT Initialization */
@@ -104,9 +105,7 @@ Hooks.once("init", async function () {
// preload handlebars templates
RdDUtility.preloadHandlebarsTemplates();
// Create useful storage space
- game.system.rdd = {
- TMRUtility: TMRUtility
- }
+ game.system.rdd = { TMRUtility: TMRUtility }
/* -------------------------------------------- */
game.settings.register("foundryvtt-reve-de-dragon", "accorder-entite-cauchemar", {
@@ -180,7 +179,7 @@ Hooks.once("init", async function () {
// Set an initiative formula for the system
CONFIG.Combat.initiative = {
formula: "1d20",
- decimals: 2
+ decimals: 0
};
/* -------------------------------------------- */
@@ -202,23 +201,10 @@ Hooks.once("init", async function () {
/* -------------------------------------------- */
// Register sheet application classes
Actors.unregisterSheet("core", ActorSheet);
- Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorSheet, {
- types: ["personnage"],
- makeDefault: true
- }
- );
- Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorCreatureSheet, {
- types: ["creature"],
- makeDefault: true
- });
- Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorVehiculeSheet, {
- types: ["vehicule"],
- makeDefault: true
- });
- Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorEntiteSheet, {
- types: ["entite"],
- makeDefault: true
- });
+ Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorSheet, { types: ["personnage"], makeDefault: true });
+ Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorCreatureSheet, { types: ["creature"], makeDefault: true });
+ Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true });
+ Actors.registerSheet("foundryvtt-reve-de-dragon", RdDActorEntiteSheet, { types: ["entite"], makeDefault: true });
Items.unregisterSheet("core", ItemSheet);
Items.registerSheet("foundryvtt-reve-de-dragon", RdDItemSheet, { makeDefault: true });
@@ -232,6 +218,8 @@ Hooks.once("init", async function () {
RdDCommands.init();
RdDCombat.init();
RdDTokenHud.init();
+ RdDActor.init();
+ StatusEffects.init();
});
/* -------------------------------------------- */
diff --git a/module/rdd-resolution-table.js b/module/rdd-resolution-table.js
index fd516b21..16c2a806 100644
--- a/module/rdd-resolution-table.js
+++ b/module/rdd-resolution-table.js
@@ -82,7 +82,7 @@ export class RdDResolutionTable {
static explain(rolled) {
let message = "
Jet : " + rolled.roll + " sur " + rolled.score + "% ";
if (rolled.caracValue != null && rolled.finalLevel != null) {
- message += (rolled.diviseur > 1 ? `(1/${rolled.diviseur} de ` : "(")
+ message += (rolled.diviseurSignificative > 1 ? `(1/${rolled.diviseurSignificative} de ` : "(")
+ rolled.caracValue + " à " + Misc.toSignedString(rolled.finalLevel) + ") ";
}
message += '' + rolled.quality + ''
@@ -104,7 +104,7 @@ export class RdDResolutionTable {
/* -------------------------------------------- */
static async rollData(rollData) {
- rollData.rolled = await this.roll(rollData.caracValue, rollData.finalLevel, rollData.bonus, rollData.diviseur, rollData.showDice);
+ rollData.rolled = await this.roll(rollData.caracValue, rollData.finalLevel, rollData.bonus, rollData.diviseurSignificative, rollData.showDice);
return rollData;
}
diff --git a/module/rdd-roll.js b/module/rdd-roll.js
index e24ff8e9..6b998e44 100644
--- a/module/rdd-roll.js
+++ b/module/rdd-roll.js
@@ -40,7 +40,7 @@ export class RdDRoll extends Dialog {
moral: actor.getMoralTotal(),
carac: actor.data.data.carac,
finalLevel: 0,
- diffConditions: rollData.arme ? RdDBonus.bonusAttaque(rollData.surpriseDefenseur) : 0,
+ diffConditions: 0,
diffLibre: rollData.competence?.data.default_diffLibre ?? 0,
editLibre: true,
editConditions: true,
@@ -54,7 +54,7 @@ export class RdDRoll extends Dialog {
useMalusEncTotal: false,
encTotal: actor.getEncTotal(),
ajustementAstrologique: actor.ajustementAstrologique(),
- surprise: actor.getSurprise(),
+ surprise: actor.getSurprise(false),
}
mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false });
RollDataAjustements.calcul(rollData, actor);
@@ -225,7 +225,7 @@ export class RdDRoll extends Dialog {
$("#compdialogTitle").text(this._getTitle(rollData));
$('#coupsNonMortels').prop('checked', rollData.coupsNonMortels);
$("#dmg-arme-actor").text(dmgText);
- $("#defenseur-surprise").text(RdDBonus.description(rollData.surpriseDefenseur));
+// $("#defenseur-surprise").text(RdDBonus.description(rollData.ajustements.attaqueDefenseurSurpris.descr));
$('.table-ajustement').remove();
$(".table-resolution").remove();
$(".table-proba-reussite").remove();
diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js
index ebef73c7..4e827961 100644
--- a/module/rdd-tmr-dialog.js
+++ b/module/rdd-tmr-dialog.js
@@ -51,14 +51,17 @@ export class RdDTMRDialog extends Dialog {
this.rencontreState = 'aucune';
this.pixiApp = new PIXI.Application({ width: 720, height: 860 });
if (!this.viewOnly){
+ this.actor.setStatusDemiReve(true);
this._tellToGM(this.actor.name + " monte dans les terres médianes (" + mode + ")");
}
}
-
+
/* -------------------------------------------- */
close() {
this.actor.santeIncDec("fatigue", this.nbFatigue).then(super.close()); // moving 1 cell costs 1 fatigue
this.actor.tmrApp = undefined; // Cleanup reference
+ this.actor.setStatusDemiReve(false);
+
this._tellToGM(this.actor.name + " a quitté les terres médianes")
}
diff --git a/module/rolldata-ajustements.js b/module/rolldata-ajustements.js
index 5139a5da..f3bf16b2 100644
--- a/module/rolldata-ajustements.js
+++ b/module/rolldata-ajustements.js
@@ -88,8 +88,9 @@ export const referenceAjustements = {
getValue: (rollData, actor) => actor.ajustementAstrologique()
},
facteurSign: {
- isUsed: (rollData, actor) => rollData.diviseur > 1,
- getDescr: (rollData, actor) => rollData.diviseur > 1 ? `Facteur significative ×${Misc.getFractionHtml(rollData.diviseur)}` : ''
+ isUsed: (rollData, actor) => rollData.diviseurSignificative > 1,
+ getLabel: (rollData, actor) => Misc.getFractionHtml(rollData.diviseurSignificative),
+ getDescr: (rollData, actor) => rollData.diviseurSignificative > 1 ? `Facteur significative ×${Misc.getFractionHtml(rollData.diviseurSignificative)}` : ''
},
finesse: {
isUsed: (rollData, actor) => RdDBonus.isDefenseAttaqueFinesse(rollData),
@@ -100,7 +101,7 @@ export const referenceAjustements = {
getDescr: (rollData, actor) => rollData.attackerRoll && rollData.arme? `${RdDItemArme.getNomCategorieParade(rollData.attackerRoll?.arme)} vs ${RdDItemArme.getNomCategorieParade(rollData.arme)}`: ''
},
surprise: {
- isUsed: (rollData, actor) => actor.getSurprise(),
+ isUsed: (rollData, actor) => actor.getSurprise(rollData.passeArme),
getDescr: (rollData, actor) => RdDBonus.find(actor.getSurprise()).descr
},
bonusCase: {
diff --git a/module/status-effects.js b/module/status-effects.js
new file mode 100644
index 00000000..cf420867
--- /dev/null
+++ b/module/status-effects.js
@@ -0,0 +1,128 @@
+
+const rddStatusEffects = [
+ { id: 'sonne', rdd: true, label: 'Sonné', icon: 'icons/svg/stoned.svg' },
+];
+const demiReveStatusEffect = { id: 'demi-reve', rdd: true, label: 'Demi-rêve', icon: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.svg' };
+const rddPrivateStatusEffects = [demiReveStatusEffect,];
+const statusDemiSurpriseCombat = new Set(['sonne', 'demi-reve', 'prone', 'restrain']);
+const statusDemiSurprise = new Set(['sonne', 'prone', 'restrain']);
+const statusSurpriseTotale = new Set(['unconscious', 'blind']);
+
+export class StatusEffects {
+ static init() {
+ StatusEffects.setCoreStatusId(rddPrivateStatusEffects);
+ StatusEffects.setCoreStatusId(rddStatusEffects);
+ const defaultUseStatusEffect = CONFIG.statusEffects.map(it => it.id).join();
+ game.settings.register("foundryvtt-reve-de-dragon", "use-status-effects", {
+ name: "use-status-effects",
+ scope: "world",
+ config: false,
+ default: defaultUseStatusEffect,
+ type: String
+ });
+
+ game.settings.registerMenu("foundryvtt-reve-de-dragon", "select-status-effect", {
+ name: "Choisir les effets disponibles",
+ label: "Choix des effets",
+ hint: "Ouvre la fenêtre de sélection des effets/status appliqués aux acteurs",
+ icon: "fas fa-bars",
+ type: StatusEffectsSettings,
+ restricted: true
+ });
+ CONFIG.RDD.allEffects = rddStatusEffects.concat(CONFIG.statusEffects);
+
+ StatusEffects._setUseStatusEffects(StatusEffects._getUseStatusEffects());
+
+ console.log('statusEffects', CONFIG.statusEffects);
+ }
+
+ static valeurSurprise(effect, isCombat) {
+ const id = StatusEffects.statusId(effect);
+ if (statusSurpriseTotale.has(id)) {
+ return 2;
+ }
+ const status = (isCombat ? statusDemiSurpriseCombat : statusDemiSurprise);
+ return status.has(id) ? 1 : 0;
+ }
+
+ static statusId(effectData) {
+ return effectData.flags?.core?.statusId ?? effectData["flags.core.statusId"];
+ }
+
+ static setCoreStatusId(list) {
+ list.forEach(it => {
+ it.flags = { core: { statusId: it.id } };
+ it["flags.core.statusId"] = it.id;
+ });
+ }
+
+ static _getUseStatusEffects() {
+ const setting = game.settings.get("foundryvtt-reve-de-dragon", "use-status-effects");
+ return setting ? new Set(setting.split(',')) : new Set();
+ }
+
+ static _setUseStatusEffects(useStatusEffects) {
+ game.settings.set("foundryvtt-reve-de-dragon", "use-status-effects", StatusEffects._toSetting(useStatusEffects));
+
+ for (let effect of CONFIG.RDD.allEffects) {
+ effect.active = effect.rdd || useStatusEffects.has(effect.id);
+ }
+ CONFIG.statusEffects = CONFIG.RDD.allEffects.filter(it => it.active);
+ }
+
+ static _toSetting(useStatusEffects) {
+ return Array.from(useStatusEffects).join();
+ }
+
+ static demiReve() {
+ return demiReveStatusEffect;
+ }
+}
+
+class StatusEffectsSettings extends FormApplication {
+ constructor(...args) {
+ super(...args);
+ }
+
+ static get defaultOptions() {
+ const options = super.defaultOptions;
+ mergeObject(options, {
+ id: "status-effects-settings",
+ template: "systems/foundryvtt-reve-de-dragon/templates/status-effects-settings.html",
+ height: "auto",
+ width: 350,
+ minimizable: false,
+ closeOnSubmit: true,
+ title: "Choix des status/effets"
+ });
+ return options;
+ }
+
+ getData() {
+ let data = super.getData();
+ data.effects = CONFIG.RDD.allEffects;
+ return data;
+ }
+
+ activateListeners(html) {
+ html.find(".select-effect").click((event) => {
+ let id = event.currentTarget.attributes.name?.value;
+ if (id) {
+ let selected = StatusEffects._getUseStatusEffects();
+ let isChecked = event.currentTarget.checked;
+ if (isChecked) {
+ selected.add(id);
+ }
+ else {
+ selected.delete(id);
+ }
+ StatusEffects._setUseStatusEffects(selected);
+ }
+ });
+ }
+
+ async _updateObject(event, formData) {
+ this.close();
+ }
+}
+
diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html
index 27eab69d..439a78c8 100644
--- a/templates/actor-sheet.html
+++ b/templates/actor-sheet.html
@@ -1,3 +1,4 @@
+{{log "handlebar actor-sheet" this}}