diff --git a/module/actor-sheet.js b/module/actor-sheet.js
index f8836363..ae6a0d3b 100644
--- a/module/actor-sheet.js
+++ b/module/actor-sheet.js
@@ -459,7 +459,7 @@ export class RdDActorSheet extends ActorSheet {
this.actor.setEthylisme(parseInt(event.target.value));
});
html.find('#stress-test').click((event) => {
- this.actor.stressTest();
+ this.actor.transformerStress();
this.render(true);
});
html.find('#moral-malheureux').click((event) => {
diff --git a/module/actor.js b/module/actor.js
index 5ae26497..1e3aaa73 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -207,6 +207,10 @@ export class RdDActor extends Actor {
}
return 10;
}
+ /* -------------------------------------------- */
+ getChance() {
+ return Misc.toInt(this.data.data.carac.chance?.value ?? 10);
+ }
getMoralTotal() {
return Misc.toInt(this.data.data.compteurs.moral?.value);
}
@@ -315,7 +319,9 @@ export class RdDActor extends Actor {
await this._recupererBlessures(message, "critique", blessures.critiques.liste.filter(b => b.active), blessures.graves.liste);
await this.update({ "data.blessures": blessures });
await this._recupererVie(message);
- await this.transformerStress(message);
+ await this.jetDeMoral('neutre');
+ await this.chanceActuelleIncDec(1);
+ this.transformerStress();
await this.retourSeuilDeReve(message);
message.content = `A la fin Chateau Dormant, ${message.content}
Un nouveau jour se lève`;
ChatMessage.create(message);
@@ -1411,69 +1417,72 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
- async stressTest() {
- const message = {
- content: "",
- whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name)
- };
- await this.transformerStress(message);
- ChatMessage.create(message);
- }
-
- /* -------------------------------------------- */
- async transformerStress(message) {
- let compteurs = duplicate(this.data.data.compteurs);
- const stress = Misc.toInt(compteurs.stress.value);
-
+ async transformerStress() {
+ const stress = Misc.toInt(this.data.data.compteurs.stress.value);
if (stress <= 0) {
- return false;
+ return;
}
-
- let stressRoll = await this._stressRoll();
- let convertis = Math.floor(stress * stressRoll.factor);
- compteurs.stress.value = Math.max(stress - convertis - 1, 0);
-
- let dissolution = Math.max(0, Misc.toInt(compteurs.dissolution.value));
- let exaltation = Math.max(0, Misc.toInt(compteurs.exaltation.value));
+
+ const stressRoll = await this._stressRoll(this.getReveActuel());
+
+ const conversion = Math.floor(stress * stressRoll.factor / 100);
+ let dissolution = Math.max(0, Misc.toInt(this.data.data.compteurs.dissolution.value));
+ let exaltation = Math.max(0, Misc.toInt(this.data.data.compteurs.exaltation.value));
const annule = Math.min(dissolution, exaltation);
dissolution -= annule;
exaltation -= annule;
- if (dissolution > 0) {
- const perdus = Math.min(dissolution, convertis);
- convertis -= perdus;
- dissolution -= perdus;
- }
- compteurs.experience.value += convertis + exaltation;
- compteurs.dissolution.value = dissolution;
+ const perteDissolution = Math.max(0, Math.min(dissolution, conversion));
+
+ let stressRollData = {
+ alias: this.name,
+ selectedCarac: this.data.data.carac.reve,
+ rolled: stressRoll,
+ stress: stress,
+ perte: Math.min(conversion, stress),
+ convertis: conversion - perteDissolution,
+ xp: conversion - perteDissolution + exaltation,
+ dissolution: dissolution,
+ exaltation: exaltation
+ };
+
+ ChatMessage.create({
+ whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
+ content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-resultat-transformer-stress.html`, stressRollData)
+ });
+
+ let compteurs = duplicate(this.data.data.compteurs);
+ compteurs.stress.value = Math.max(stress - stressRollData.perte - 1, 0);
+ compteurs.experience.value += stressRollData.xp;
+ compteurs.dissolution.value = dissolution - perteDissolution;
compteurs.exaltation.value = 0;
- message.content += "
Vous transformez " + convertis + " points de Stress en Expérience" + stressRoll.comment;
await this.update({ "data.compteurs": compteurs });
- return true;
}
/* -------------------------------------------- */
- async _stressRoll() {
- let reveActuel = this.getReveActuel();
+ async _stressRoll(reveActuel) {
let result = await RdDResolutionTable.roll(reveActuel, 0);
- console.log("_stressRoll", result);
- switch (result.code) {
- case "sign": return { factor: 0.75, comment: " (75%): " + result.quality + " - " + result.roll + " sur " + result.score + "%" }
- case "norm": return { factor: 0.5, comment: " (50%): " + result.quality + " - " + result.roll + " sur " + result.score + "%" }
- case "echec": return { factor: 0.2, comment: " (20%): " + result.quality + " - " + result.roll + " sur " + result.score + "%" }
- case "epart": return { factor: 0.1, comment: " (10%): " + result.quality + " - " + result.roll + " sur " + result.score + "%" }
- case "etotal": return { factor: 0, comment: " (0%): " + result.quality + " - " + result.roll + " sur " + result.score + "%" }
- case "part":
- {
- let second = await RdDResolutionTable.roll(reveActuel, 0);
- console.log("_stressRoll", second);
- switch (second.code) {
- case "part": case "sign":
- return { factor: 1.5, comment: " (150%): Double Particulière - " + result.roll + " puis " + second.roll + " sur " + result.score + "%" }
- default:
- return { factor: 1, comment: " (100%): " + result.quality + " - " + result.roll + " puis " + second.roll + " sur " + result.score + "%" }
- }
- }
+ if (result.isPart) {
+ result.second = await RdDResolutionTable.roll(reveActuel, 0);
}
+ result.factor = this._getFacteurStress(result);
+ return result;
+ }
+
+ _getFacteurStress(stressRoll) {
+ switch (stressRoll.code) {
+ case "sign": return 75;
+ case "norm": return 50;
+ case "echec": return 20;
+ case "epart": return 10;
+ case "etotal": return 0;
+ case "part":
+ if (stressRoll.second.isSign) {
+ stressRoll.quality = "Double Particulière";
+ return 150;
+ }
+ return 100;
+ }
+ return 0;
}
/* -------------------------------------------- */
@@ -2156,7 +2165,7 @@ export class RdDActor extends Actor {
async _appelChanceResult(rollData, onSuccess = () => { }, onEchec = () => { }) {
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-appelchance.html')
if (rollData.rolled.isSuccess) {
- await this.chanceActuelleIncDec(-1)
+ await this.chanceActuelleIncDec(-1);
onSuccess();
}
else {
@@ -2165,9 +2174,12 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
- async chanceActuelleIncDec(value) {
+ async chanceActuelleIncDec(value, limit=true) {
let chance = duplicate(this.data.data.compteurs.chance);
chance.value = Math.max(chance.value + value, 0);
+ if (limit) {
+ chance.value = Math.min(chance.value, this.getChance())
+ }
await this.update({ "data.compteurs.chance": chance });
}
diff --git a/module/item-arme.js b/module/item-arme.js
index 4e9fbd76..048543f0 100644
--- a/module/item-arme.js
+++ b/module/item-arme.js
@@ -144,6 +144,9 @@ export class RdDItemArme extends Item {
return arme;
}
+ static isArmeUtilisable(item) {
+ return item.type == 'arme' && item.data.resistance > 0;
+ }
static mainsNues(actorData={}) {
const mainsNues = {
diff --git a/module/item-competencecreature.js b/module/item-competencecreature.js
index 5d3235a4..524d5829 100644
--- a/module/item-competencecreature.js
+++ b/module/item-competencecreature.js
@@ -1,7 +1,6 @@
/* -------------------------------------------- */
export class RdDItemCompetenceCreature extends Item {
-
/* -------------------------------------------- */
static setRollDataCreature(rollData) {
rollData.carac = { "carac_creature": { label: rollData.competence.name, value: rollData.competence.data.carac_value } };
@@ -17,7 +16,7 @@ export class RdDItemCompetenceCreature extends Item {
/* -------------------------------------------- */
static toArme(item) {
- if (item.type == 'competencecreature' && item.data.iscombat) {
+ if (RdDItemCompetenceCreature.isCompetenceAttaque(item)) {
let arme = { name: item.name, data: duplicate(item.data) };
mergeObject(arme.data,
{
@@ -34,4 +33,11 @@ export class RdDItemCompetenceCreature extends Item {
return undefined;
}
+ static isCompetenceAttaque(item) {
+ return item.type == 'competencecreature' && item.data.iscombat;
+ }
+
+ static isCompetenceParade(item) {
+ return item.type == 'competencecreature' && item.data.isparade;
+ }
}
diff --git a/module/rdd-combat.js b/module/rdd-combat.js
index 35af36ed..98556587 100644
--- a/module/rdd-combat.js
+++ b/module/rdd-combat.js
@@ -510,7 +510,7 @@ export class RdDCombat {
/* -------------------------------------------- */
_filterArmesParade(items, competence) {
- items = items.filter(item => (item.type == 'arme' && item.data.equipe) || (item.type == 'competencecreature' && item.data.isparade));
+ items = items.filter(item => RdDItemArme.isArmeUtilisable(item) || RdDItemCompetenceCreature.isCompetenceParade(item));
switch (competence.data.categorie) {
case 'tir':
case 'lancer':
@@ -743,20 +743,20 @@ export class RdDCombat {
}
/* -------------------------------------------- */
- async computeDeteriorationArme(rollData) {
+ async computeDeteriorationArme(defenderRoll) {
if (!ReglesOptionelles.isUsing('resistanceArmeParade')) {
return;
}
- const attackerRoll = rollData.attackerRoll;
+ const attackerRoll = defenderRoll.attackerRoll;
// Est-ce une parade normale?
- if (rollData.arme && attackerRoll && !rollData.rolled.isPart) {
+ if (defenderRoll.arme && attackerRoll && !defenderRoll.rolled.isPart) {
// Est-ce que l'attaque est une particulière en force ou une charge
- if (rollData.needResist || attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge') {
+ if (defenderRoll.needResist || this._isForceOuCharge(attackerRoll)) {
- rollData.show = rollData.show || {}
+ defenderRoll.show = defenderRoll.show || {}
const dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor;
- let resistance = Misc.toInt(rollData.arme.data.resistance);
+ let resistance = Misc.toInt(defenderRoll.arme.data.resistance);
let msg = "";
// Jet de résistance de l'arme de parade (p.132)
let resistRoll = await RdDResolutionTable.rollData({
@@ -765,26 +765,21 @@ export class RdDCombat {
showDice: false
});
if (resistRoll.rolled.isSuccess) { // Perte de résistance
- rollData.show.deteriorationArme = 'resiste';
+ defenderRoll.show.deteriorationArme = 'resiste';
} else {
resistance -= dmg;
- if (resistance <= 0) {
- this.defender.deleteEmbeddedEntity("OwnedItem", rollData.arme._id);
- rollData.show.deteriorationArme = 'brise';
- } else {
- this.defender.updateEmbeddedEntity("OwnedItem", { _id: rollData.arme._id, 'data.resistance': resistance });
- rollData.show.deteriorationArme = 'perte';
- rollData.show.perteResistance = dmg;
- }
+ defenderRoll.show.deteriorationArme = resistance <= 0 ? 'brise': 'perte';
+ defenderRoll.show.perteResistance = dmg;
+ this.defender.updateEmbeddedEntity("OwnedItem", { _id: defenderRoll.arme._id, 'data.resistance': resistance });
}
// Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132)
- if (ReglesOptionelles.isUsing('defenseurDesarme') && resistance > 0 && RdDItemArme.getCategorieParade(rollData.arme) != 'boucliers') {
+ if (ReglesOptionelles.isUsing('defenseurDesarme') && resistance > 0 && RdDItemArme.getCategorieParade(defenderRoll.arme) != 'boucliers') {
let desarme = await RdDResolutionTable.rollData({
caracValue: this.defender.getForce(),
- finalLevel: Misc.toInt(rollData.competence.data.niveau) - dmg,
+ finalLevel: Misc.toInt(defenderRoll.competence.data.niveau) - dmg,
showDice: false
});
- rollData.show.desarme = desarme.rolled.isEchec;
+ defenderRoll.show.desarme = desarme.rolled.isEchec;
}
}
}
@@ -793,7 +788,7 @@ export class RdDCombat {
/* -------------------------------------------- */
async computeRecul(defenderRoll) { // Calcul du recul (p. 132)
const attackerRoll = defenderRoll.attackerRoll;
- if (ReglesOptionelles.isUsing('recul') && this._isAttaqueCauseRecul(attackerRoll)) {
+ if (ReglesOptionelles.isUsing('recul') && this._isForceOuCharge(attackerRoll)) {
const impact = this._computeImpactRecul(attackerRoll);
const rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impact });
if (rollRecul.rolled.isSuccess) {
@@ -816,7 +811,7 @@ export class RdDCombat {
}
/* -------------------------------------------- */
- _isAttaqueCauseRecul(attaque) {
+ _isForceOuCharge(attaque) {
return attaque.particuliere == 'force' || attaque.tactique == 'charge';
}
diff --git a/module/rdd-commands.js b/module/rdd-commands.js
index 1523cb26..8190042c 100644
--- a/module/rdd-commands.js
+++ b/module/rdd-commands.js
@@ -249,7 +249,7 @@ export class RdDCommands {
getCoutXpCarac(msg, params) {
if (params && params.length == 1) {
let to = Number(params[0]);
- RdDCommands._chatAnswer(msg, `Coût pour passer une caractéristique de ${to - 1} à ${to}: ${RdDUtility.getCaractXp(to)}`);
+ RdDCommands._chatAnswer(msg, `Coût pour passer une caractéristique de ${to - 1} à ${to}: ${RdDUtility.getCaracXp(to)}`);
}
else {
return false;
diff --git a/module/rdd-utility.js b/module/rdd-utility.js
index 20c16708..98dd7db5 100644
--- a/module/rdd-utility.js
+++ b/module/rdd-utility.js
@@ -412,11 +412,11 @@ export class RdDUtility {
static getCaracNextXp(value) {
const nextValue = Number(value) + 1;
// xp est le coût pour atteindre cette valeur, on regarde donc le coût de la valeur+1
- return RdDUtility.getCaractXp(nextValue);
+ return RdDUtility.getCaracXp(nextValue);
}
- static getCaractXp(targetValue) {
- return tableCaracDerivee[targetValue].xp;
+ static getCaracXp(targetValue) {
+ return tableCaracDerivee[targetValue]?.xp ?? 200 ;
}
/* -------------------------------------------- */
@@ -715,11 +715,11 @@ export class RdDUtility {
let items = actor.data.items;
let actions = []
if (actor.isCreature()) {
- actions = actions.concat(items.filter(it => it.type == 'competencecreature' && it.data.iscombat)
+ actions = actions.concat(items.filter(it => RdDItemCompetenceCreature.isCompetenceAttaque(it))
.map(competence => RdDItemCompetenceCreature.toArme(competence)));
} else {
// Recupération des items 'arme'
- let armes = items.filter(it => it.type == 'arme')
+ let armes = items.filter(it => RdDItemArme.isArmeUtilisable(it))
.map(arme => duplicate(arme)) /* pas de changements aux armes d'origine */
.concat(RdDItemArme.mainsNues());
diff --git a/template.json b/template.json
index cf971e9c..b7e9b81f 100644
--- a/template.json
+++ b/template.json
@@ -434,12 +434,12 @@
"reve": {
"reve": {
"max": 0,
- "value": 0,
+ "value": 10,
"label": "Points de Rêve actuels"
},
"seuil": {
"max": 0,
- "value": 0,
+ "value": 10,
"label": "Seuil de Rêve"
},
"tmrpos": {
diff --git a/templates/chat-resultat-transformer-stress.html b/templates/chat-resultat-transformer-stress.html
new file mode 100644
index 00000000..0bef2112
--- /dev/null
+++ b/templates/chat-resultat-transformer-stress.html
@@ -0,0 +1,18 @@
+