Merge branch 'moral' into 'dev_1.1'

Fin des modifications de combat et du moral

See merge request LeRatierBretonnien/foundryvtt-reve-de-dragon!82
This commit is contained in:
Leratier Bretonnien 2020-12-19 07:21:07 +00:00
commit add5f6c8a0
10 changed files with 209 additions and 143 deletions

View File

@ -46,6 +46,7 @@ export class RdDActorHumanoideSheet extends ActorSheet {
data.data.competencecreature = data.itemsByType["competencecreature"]; data.data.competencecreature = data.itemsByType["competencecreature"];
data.data.isGM = game.user.isGM; data.data.isGM = game.user.isGM;
data.data.compteurs.ethylisme.nom = RdDUtility.getNomEthylisme(data.data.compteurs.ethylisme.value);
RdDUtility.filterItemsPerTypeForSheet(data ); RdDUtility.filterItemsPerTypeForSheet(data );
RdDUtility.buildArbreDeConteneur( this, data ); RdDUtility.buildArbreDeConteneur( this, data );

View File

@ -109,6 +109,11 @@ export class RdDActor extends Actor {
return this.data.type == 'creature' || this.data.type == 'entite'; return this.data.type == 'creature' || this.data.type == 'entite';
} }
/* -------------------------------------------- */
isPersonnage() {
return this.data.type == 'personnage';
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getReveActuel() { getReveActuel() {
return this.data.data.reve.reve.value; return this.data.data.reve.reve.value;
@ -197,8 +202,8 @@ export class RdDActor extends Actor {
let message = { let message = {
whisper: ChatUtility.getWhisperRecipientsAndGMs( this.name ), whisper: ChatUtility.getWhisperRecipientsAndGMs( this.name ),
content : "" content : ""
}; };
const blessures = duplicate(this.data.data.blessures); const blessures = duplicate(this.data.data.blessures);
console.log("dormirChateauDormant", blessures) console.log("dormirChateauDormant", blessures)
await this._recupererBlessures(message, "legere", blessures.legeres.liste.filter(b => b.active), []); await this._recupererBlessures(message, "legere", blessures.legeres.liste.filter(b => b.active), []);
@ -311,6 +316,8 @@ export class RdDActor extends Actor {
} }
await this.update( {"data.blessures": blessures } ); await this.update( {"data.blessures": blessures } );
} }
await this.update({ "data.compteurs.ethylisme.value": 0 });
await this.update({ "data.compteurs.ethylisme.nb_doses": 0 });
await this.santeIncDec("vie", this.data.data.sante.vie.max - this.data.data.sante.vie.value); await this.santeIncDec("vie", this.data.data.sante.vie.max - this.data.data.sante.vie.value);
await this.santeIncDec("endurance", this.data.data.sante.endurance.max - this.data.data.sante.endurance.value); await this.santeIncDec("endurance", this.data.data.sante.endurance.max - this.data.data.sante.endurance.value);
if (this.data.data.sante.fatigue){ if (this.data.data.sante.fatigue){
@ -330,12 +337,26 @@ export class RdDActor extends Actor {
}; };
await this.recupereEndurance(message); await this.recupereEndurance(message);
for (let i=0; i<heures; i++) { for (let i=0; i<heures; i++) {
await this._recupererEthylisme(message);
await this.recupererFatigue(message); await this.recupererFatigue(message);
await this.recuperationReve(message); await this.recuperationReve(message);
} }
ChatMessage.create( message ); ChatMessage.create( message );
} }
async _recupererEthylisme(message) {
let ethylisme = duplicate(this.data.data.compteurs.ethylisme);
if (ethylisme.value < 1)
{
ethylisme.value = Math.min(ethylisme.value + 1, 1);
ethylisme.nb_doses = 0;
await this.update({ "data.compteurs.ethylisme": ethylisme });
if (ethylisme.value <= 0) {
message.content += `<br>Vous dégrisez un peu (${RdDUtility.getNomEthylisme(ethylisme.value)})`;
}
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async recupereEndurance(message) { async recupereEndurance(message) {
const manquant = this._computeEnduranceMax() - this.data.data.sante.endurance.value; const manquant = this._computeEnduranceMax() - this.data.data.sante.endurance.value;
@ -675,18 +696,15 @@ export class RdDActor extends Actor {
return; return;
} }
// Pour les autres // Pour les autres
let state = 0, surenc = 0; let state = - (data.sante.vie.max - data.sante.vie.value);
state = state - (data.sante.vie.max - data.sante.vie.value);
if (data.sante.fatigue) // Creatures n'ont pas de fatigue if (data.sante.fatigue) // Creatures n'ont pas de fatigue
state = state + RdDUtility.currentFatigueMalus(data.sante.fatigue.value, data.sante.endurance.max); state += RdDUtility.currentFatigueMalus(data.sante.fatigue.value, data.sante.endurance.max);
if (data.compteurs && data.compteurs.ethylisme && data.compteurs.ethylisme.value < 0 ) { // Ajout de l'éthylisme if (data.compteurs && data.compteurs.ethylisme && data.compteurs.ethylisme.value < 0 ) { // Ajout de l'éthylisme
state = state + data.compteurs.ethylisme.value; state += data.compteurs.ethylisme.value;
} }
state = state;
data.compteurs.etat.value = state; data.compteurs.etat.value = state;
if ( data.compteurs && data.compteurs.surenc) { if ( data.compteurs && data.compteurs.surenc) {
surenc = -this.detectSurEncombrement(); data.compteurs.surenc.value = - this.detectSurEncombrement();
data.compteurs.surenc.value = surenc;
} }
} }
@ -1058,21 +1076,21 @@ export class RdDActor extends Actor {
let msgText = RdDResolutionTable.explain(rollEthylisme) + "<br>"; let msgText = RdDResolutionTable.explain(rollEthylisme) + "<br>";
if (rollEthylisme.isSuccess ) { if (rollEthylisme.isSuccess ) {
ethylisme.nb_doses = ethylisme.nb_doses + 1; ethylisme.nb_doses = ethylisme.nb_doses + 1;
msgText += "Vous avez réussi votre jet d'éthylisme, votre vous avez désormais " + ethylisme.nb_doses + " doses sans effet."; msgText += `Vous avez réussi votre jet d'éthylisme, vous avez consommé ${ethylisme.nb_doses} doses sans effet.`;
} else { } else {
ethylisme.value = ethylisme.value - 1; ethylisme.value = Math.max(ethylisme.value -1, -7);
if ( ethylisme.value > 7) ethylisme.value = 7; // Niveau max
let enduranceLost = new Roll("1d6").roll().total; let enduranceLost = new Roll("1d6").roll().total;
await this.santeIncDec("endurance", -enduranceLost); await this.santeIncDec("endurance", -enduranceLost);
msgText += "Vous avez échoué à votre jet d'éthylisme, votre niveau d'éthylisme est de " + ethylisme.value const ajustementEthylique = ethylisme.value;
+ "(" + RdDUtility.getNomEthylisme(ethylisme.value) + ").";
// Qui a bu boira (p 164) // Qui a bu boira (p 164)
let rollVolonte = await RdDResolutionTable.roll( this.data.data.carac.volonte.value, -ethylisme.value); let rollVolonte = await RdDResolutionTable.roll( this.data.data.carac.volonte.value, Math.min(ajustementEthylique, 0) + this.data.data.compteurs.moral.value);
msgText += `Vous avez échoué à votre jet d'éthylisme, vous êtes maintenant ${RdDUtility.getNomEthylisme(ajustementEthylique)} (${ajustementEthylique}).`
msgText += "<br>" + RdDResolutionTable.explain(rollVolonte) + "<br>"; msgText += "<br>" + RdDResolutionTable.explain(rollVolonte) + "<br>";
if ( rollVolonte.isSuccess) msgText += "Qui a bu boira : " +(rollVolonte.isSuccess
msgText += "Qui a bu boira : vous êtes libre de continuer à boire ou pas."; ? "vous êtes libre de continuer à boire ou pas."
else : "vous avez une envie irrépréssible de reprendre un verre.");
msgText += "Qui a bu boira : vous avez une envie irrépréssible de reprendre un verre.";
} }
await this.update( { 'data.compteurs.ethylisme': ethylisme} ); await this.update( { 'data.compteurs.ethylisme': ethylisme} );
const message = { const message = {
@ -1080,6 +1098,10 @@ export class RdDActor extends Actor {
whisper: ChatMessage.getWhisperRecipients(game.user.name) whisper: ChatMessage.getWhisperRecipients(game.user.name)
}; };
ChatMessage.create(message); ChatMessage.create(message);
if (rollEthylisme.isEchec && ethylisme.value == 0) {
await this.jetDeMoral('heureuse'); // note: en, théorie, un deuxième jet de moral peut avoir lieu le même jour si lme premier est manqué, qui fait perdre du moral si raté...
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -1095,16 +1117,31 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async transformerStress(message) { async transformerStress(message) {
const stress = Misc.toInt(this.data.data.compteurs.stress.value); let compteurs = duplicate(this.data.data.compteurs);
const stress = Misc.toInt(compteurs.stress.value);
if (stress<=0) { if (stress<=0) {
return; return;
} }
let stressRoll = await this._stressRoll(); let stressRoll = await this._stressRoll();
let convertis = Math.floor(stress * stressRoll.factor); let convertis = Math.floor(stress * stressRoll.factor);
let compteurs = duplicate(this.data.data.compteurs);
compteurs.experience.value += convertis;
compteurs.stress.value = Math.max(stress - convertis - 1, 0); 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 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;
compteurs.exaltation.value = 0;
message.content += "<br>Vous transformez " + convertis + " points de Stress en Expérience" + stressRoll.comment; message.content += "<br>Vous transformez " + convertis + " points de Stress en Expérience" + stressRoll.comment;
await this.update({ "data.compteurs": compteurs }); await this.update({ "data.compteurs": compteurs });
} }
@ -1271,8 +1308,7 @@ export class RdDActor extends Actor {
// Final chat message // Final chat message
let chatOptions = { let chatOptions = {
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.selectedDraconic.name + " / " + rollData.selectedSort.name + "</strong>" content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.selectedDraconic.name + " / " + rollData.selectedSort.name + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) +" / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ RdDResolutionTable.explain(rolled)
+ explications + explications
} }
@ -1310,8 +1346,7 @@ export class RdDActor extends Actor {
// Final chat message // Final chat message
let chatOptions = { let chatOptions = {
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + resumeCompetence + "</strong>" content: "<strong>Test : " + rollData.selectedCarac.label + " / " + resumeCompetence + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) +" / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ RdDResolutionTable.explain(rolled)
+ explications + explications
} }
@ -1410,8 +1445,7 @@ export class RdDActor extends Actor {
// Message de résultat // Message de résultat
ChatUtility.chatWithRollMode({ ChatUtility.chatWithRollMode({
content: "<strong>Test de Tache : " + rollData.tache.name + " - " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" content: "<strong>Test de Tache : " + rollData.tache.name + " - " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) +" / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ "<br>" + RdDResolutionTable.explain(rollData.rolled)
+ "<br>Points de taches : " + rollData.rolled.ptTache + ", ajustement qualité: " + rollData.rolled.ptQualite + "<br>Points de taches : " + rollData.rolled.ptTache + ", ajustement qualité: " + rollData.rolled.ptQualite
}, this.name); }, this.name);
// Message spécifique de la tâche // Message spécifique de la tâche
@ -1432,8 +1466,7 @@ export class RdDActor extends Actor {
_competenceResult(rollData) { _competenceResult(rollData) {
ChatUtility.chatWithRollMode({ ChatUtility.chatWithRollMode({
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) +" / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ RdDResolutionTable.explain(rollData.rolled)
+ "<br>Points de taches : " + rollData.rolled.ptTache + ", ajustement qualité: " + rollData.rolled.ptQualite + "<br>Points de taches : " + rollData.rolled.ptTache + ", ajustement qualité: " + rollData.rolled.ptQualite
}, this.name); }, this.name);
} }
@ -1686,12 +1719,18 @@ export class RdDActor extends Actor {
dmg = 0; // Reset it dmg = 0; // Reset it
if ( update.data.deterioration >= 10) { if ( update.data.deterioration >= 10) {
update.data.deterioration = 0; update.data.deterioration = 0;
if ( update.data.protection.toString().length == 1 ) let res = /\d+^/.exec(update.data.protection);
update.data.protection = "1d"+update.data.protection+"-0"; if ( res )
else { update.data.protection = "1d"+update.data.protection;
let regex = /d\(d+)\-(\d+)/g; // if ( update.data.protection.toString().length == 1 )
let res = regex.exec( update.data.protection ); // update.data.protection = "1d"+update.data.protection;
update.data.protection = "1d"+res[1]+"-"+(parseInt(res[2])+1); else if (res = /(\d+d\d+)(\-\d+)?/.exec( update.data.protection ))
{
let malus = Misc.toInt(res[2]) - 1;
update.data.protection = res[1] + malus;
}
else{
ui.notifications.warn(`La valeur d'armure de votre ${item.name} est incorrecte`)
} }
ChatMessage.create( {content: "Détérioration d'armure: " + update.data.protection } ); ChatMessage.create( {content: "Détérioration d'armure: " + update.data.protection } );
} }

View File

@ -20,7 +20,9 @@ export class RdDCombat {
if (target == undefined) { if (target == undefined) {
ui.notifications.warn("Vous devez choisir une seule cible à attaquer!"); ui.notifications.warn("Vous devez choisir une seule cible à attaquer!");
} }
return this.create(attacker, target ? target.actor : undefined, target) const defender = target ? target.actor : undefined;
const defenderTokenId = target ? target.data._id : undefined;
return this.create(attacker, defender, defenderTokenId, target)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -34,8 +36,8 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static create(attacker, defender, target = undefined) { static create(attacker, defender, defenderTokenId, target = undefined) {
return new RdDCombat(attacker, defender, target) return new RdDCombat(attacker, defender, defenderTokenId, target)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -45,22 +47,40 @@ export class RdDCombat {
const dataDefenderTokenId = event.currentTarget.attributes['data-defenderTokenId']; const dataDefenderTokenId = event.currentTarget.attributes['data-defenderTokenId'];
if (dataDefenderTokenId) { if (dataDefenderTokenId) {
let defenderToken = canvas.tokens.get(dataDefenderTokenId.value); const defenderTokenId = dataDefenderTokenId.value;
let defenderToken = canvas.tokens.get(defenderTokenId);
let defender = defenderToken.actor; let defender = defenderToken.actor;
return this.create(attacker, defender); return RdDCombat.create(attacker, defender, defenderTokenId);
} }
return this.createUsingTarget(attacker) return RdDCombat.createUsingTarget(attacker)
} }
/* -------------------------------------------- */
constructor(attacker, defender, target) { static _sendRollMessage(sender, recipient, defenderTokenId, topic, message, rollData) {
this.attacker = attacker; let chatMessage = {
this.defender = defender; content: message,
this.target = target; whisper: ChatUtility.getWhisperRecipients("blindroll", recipient.name),
this.attackerId = this.attacker.data._id; };
this.defenderId = this.defender.data._id;
this.defenderTokenId = target ? target.data._id : undefined; // envoyer le message au destinataire
if (!game.user.isGM || recipient.hasPlayerOwner) {
let data = {
attackerId: sender ? sender.data._id : undefined,
defenderId: recipient ? recipient.data._id : undefined,
defenderTokenId: defenderTokenId,
rollData: duplicate(rollData),
rollMode: true
};
mergeObject(data, chatMessage);
game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: topic, data: data});
} else {
chatMessage.whisper = [game.user];
}
if (game.user.isGM) { // Always push the message to the MJ
ChatMessage.create(chatMessage);
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -73,6 +93,16 @@ export class RdDCombat {
} }
} }
/* -------------------------------------------- */
constructor(attacker, defender, defenderTokenId, target) {
this.attacker = attacker;
this.defender = defender;
this.target = target;
this.attackerId = this.attacker.data._id;
this.defenderId = this.defender.data._id;
this.defenderTokenId = defenderTokenId;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async onEvent(button, event) { async onEvent(button, event) {
let rollData = game.system.rdd.rollDataHandler[this.attackerId]; let rollData = game.system.rdd.rollDataHandler[this.attackerId];
@ -91,7 +121,6 @@ export class RdDCombat {
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static isEchec(rollData) { static isEchec(rollData) {
switch (rollData.surprise) { switch (rollData.surprise) {
@ -233,62 +262,49 @@ export class RdDCombat {
// Final chat message // Final chat message
let chatOptions = { let chatOptions = {
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ RdDResolutionTable.explain(rollData.rolled)
+ explications + explications
} }
ChatUtility.chatWithRollMode(chatOptions, this.attacker.name) ChatUtility.chatWithRollMode(chatOptions, this.attacker.name)
if (this.target) { if (this.target) {
this._messageDefenseur(rollData); this._sendMessageDefense(rollData);
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
_messageDefenseur(rollData) { _sendMessageDefense(rollData) {
console.log("RdDCombat._messageDefenseur", rollData, " / ", this.attacker, this.target, this.target.actor.isToken, this.attacker.data._id, rollData.competence.data.categorie); console.log("RdDCombat._sendMessageDefense", rollData, " / ", this.attacker, this.target, this.attackerId, rollData.competence.data.categorie);
let content = "<strong>" + this.defender.name + "</strong> doit se défendre :<span class='chat-card-button-area'>"; let message = this._buildMessageDefense(rollData);
// encaisser
message += this._buildMessageEncaisser(rollData) + "</span>";
RdDCombat._sendRollMessage(this.attacker, this.defender, this.defenderTokenId, "msg_defense", message, rollData);
}
_buildMessageDefense(rollData) {
let message = "<strong>" + this.defender.name + "</strong> doit se défendre :<span class='chat-card-button-area'>";
if (this.defender.getSurprise() != 'totale') { if (this.defender.getSurprise() != 'totale') {
// parades // parades
for (const arme of this._filterArmesParade(this.defender.data.items, rollData.competence.data.categorie)) { for (const arme of this._filterArmesParade(this.defender.data.items, rollData.competence.data.categorie)) {
content += "<br><a class='chat-card-button' id='parer-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "' data-armeid='" + arme._id + "'>Parer avec " + arme.name + "</a>"; message += "<br><a class='chat-card-button' id='parer-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "' data-armeid='" + arme._id + "'>Parer avec " + arme.name + "</a>";
} }
// corps à corps // corps à corps
if (rollData.dmg.mortalite != 'mortel') { if (rollData.dmg.mortalite != 'mortel') {
content += "<br><a class='chat-card-button' id='parer-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "'>Parer à mains nues</a>"; message += "<br><a class='chat-card-button' id='parer-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "'>Parer à mains nues</a>";
} }
// esquive // esquive
if (rollData.competence.data.categorie == 'melee' || rollData.competence.data.categorie == "lancer" || rollData.competence.data.categorie == 'competencecreature') { if (rollData.competence.data.categorie == 'melee' || rollData.competence.data.categorie == "lancer" || rollData.competence.data.categorie == 'competencecreature') {
content += "<br><a class='chat-card-button' id='esquiver-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "'>Esquiver</a>"; message += "<br><a class='chat-card-button' id='esquiver-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "'>Esquiver</a>";
} }
} }
return message;
// encaisser
content += "<br><a class='chat-card-button' id='encaisser-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "'>Encaisser à " + Misc.toSignedString(rollData.dmg.total) + " !</a>";
content += "</span>"
let defense = {
title: "Défense en combat",
content: content,
whisper: ChatUtility.getWhisperRecipients("blindroll", this.defender.name),
attackerId: this.attackerId,
defenderTokenId: this.defenderTokenId,
rollMode: true,
rollData: duplicate(rollData)
};
// envoyer le message de defense
if (!game.user.isGM || this.defender.hasPlayerOwner) {
game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: "msg_defense", data: defense });
} else {
defense.whisper = [game.user];
} }
if (game.user.isGM) { // Always push the message to the MJ _buildMessageEncaisser(rollData) {
ChatMessage.create(defense); return "<br><a class='chat-card-button' id='encaisser-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "'>Encaisser à " + Misc.toSignedString(rollData.dmg.total) + " !</a>";
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -328,8 +344,7 @@ export class RdDCombat {
console.log("RdDCombat.onAttaqueEchec >>>", rollData); console.log("RdDCombat.onAttaqueEchec >>>", rollData);
let chatOptions = { let chatOptions = {
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ RdDResolutionTable.explain(rollData.rolled)
+ (this.target ? "<br><strong>Cible</strong> : " + this.defender.data.name : "") + (this.target ? "<br><strong>Cible</strong> : " + this.defender.data.name : "")
} }
ChatUtility.chatWithRollMode(chatOptions, this.attacker.name) ChatUtility.chatWithRollMode(chatOptions, this.attacker.name)
@ -439,8 +454,7 @@ export class RdDCombat {
let chatOptions = { let chatOptions = {
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ RdDResolutionTable.explain(rollData.rolled)
+ "<br><strong>Attaque parée!</strong>" + "<br><strong>Attaque parée!</strong>"
} }
ChatUtility.chatWithRollMode(chatOptions, this.defender.name) ChatUtility.chatWithRollMode(chatOptions, this.defender.name)
@ -470,8 +484,7 @@ export class RdDCombat {
let chatOptions = { let chatOptions = {
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ RdDResolutionTable.explain(rollData.rolled)
+ explications + explications
} }
@ -479,7 +492,8 @@ export class RdDCombat {
await this.computeRecul(rollData, true); await this.computeRecul(rollData, true);
// TODO: gestion message pour chance/encaissement // TODO: gestion message pour chance/encaissement
this.encaisser(rollData.attackerRoll); this._sendMessageEncaisser(rollData.attackerRoll);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -539,8 +553,7 @@ export class RdDCombat {
console.log("RdDCombat._onEsquiveNormal >>>", rollData); console.log("RdDCombat._onEsquiveNormal >>>", rollData);
let chatOptions = { let chatOptions = {
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ RdDResolutionTable.explain(rollData.rolled)
+ "<br><strong>Attaque esquivée!</strong>" + "<br><strong>Attaque esquivée!</strong>"
} }
ChatUtility.chatWithRollMode(chatOptions, this.defender.name) ChatUtility.chatWithRollMode(chatOptions, this.defender.name)
@ -567,15 +580,14 @@ export class RdDCombat {
let chatOptions = { let chatOptions = {
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>"
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat + RdDResolutionTable.explainRollData(rollData)
+ RdDResolutionTable.explain(rollData.rolled)
+ explications + explications
} }
ChatUtility.chatWithRollMode(chatOptions, this.defender.name) ChatUtility.chatWithRollMode(chatOptions, this.defender.name)
await this.computeRecul(rollData, true); await this.computeRecul(rollData, true);
this.encaisser(rollData.attackerRoll); this._sendMessageEncaisser(rollData.attackerRoll);
} }
@ -661,11 +673,10 @@ export class RdDCombat {
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
encaisser(attackerRoll) { _sendMessageEncaisser(rollData){
// TODO: gestion message pour chance/encaissement let message = "<strong>" + this.defender.name + "</strong> doit:" + this._buildMessageEncaisser(rollData);
this.encaisser(attackerRoll, this.defenderTokenId); RdDCombat._sendRollMessage(this.attacker, this.defender, this.defenderTokenId, "msg_encaisser", message, rollData);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@ -86,7 +86,16 @@ export class RdDResolutionTable {
} }
message += '<strong>' + rolled.quality + '</strong>' message += '<strong>' + rolled.quality + '</strong>'
return message; return message;
}
static explainRollData(rollData) {
let message = "<br>Difficultés <strong>libre: " + rollData.diffLibre + "</strong> / conditions: " + Misc.toSignedString(rollData.diffConditions)
+ " / état: " + rollData.etat;
message += RdDResolutionTable.explain(rollData.rolled)
if (rollData.selectedCarac == rollData.carac.volonte) {
message += " / moral: " + rollData.moral;
}
return message;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -240,11 +249,11 @@ export class RdDResolutionTable {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static buildHTMLResults( caracValue, levelValue) { static buildHTMLResults(caracValue, levelValue) {
let cell = this.computeChances( caracValue, levelValue); let cell = this.computeChances(caracValue, levelValue);
let descr = $('<span class="span-valeur competence-label">'); let descr = $('<span class="span-valeur competence-label">');
descr.append("Particulière : " + cell.part+ " - Significative : " + cell.sign + " - Réussite : "+cell.score); descr.append("Particulière : " + cell.part + " - Significative : " + cell.sign + " - Réussite : " + cell.score);
descr.append("<br>Echec Particulier : " + cell.epart + " - Echec Total : " + cell.etotal ); descr.append("<br>Echec Particulier : " + cell.epart + " - Echec Total : " + cell.etotal);
descr.append("</span>"); descr.append("</span>");
return descr; return descr;
} }

View File

@ -33,6 +33,7 @@ export class RdDRoll extends Dialog {
ajustementsConditions: CONFIG.RDD.ajustementsConditions, ajustementsConditions: CONFIG.RDD.ajustementsConditions,
difficultesLibres: CONFIG.RDD.difficultesLibres, difficultesLibres: CONFIG.RDD.difficultesLibres,
etat: actor.data.data.compteurs.etat.value, etat: actor.data.data.compteurs.etat.value,
moral: actor.isPersonnage() ? actor.data.data.compteurs.moral.value : 0,
carac: actor.data.data.carac, carac: actor.data.data.carac,
finalLevel: 0, finalLevel: 0,
diffConditions: rollData.arme ? RdDBonus.bonusAttaque(rollData.surpriseDefenseur) :0, diffConditions: rollData.arme ? RdDBonus.bonusAttaque(rollData.surpriseDefenseur) :0,
@ -40,9 +41,9 @@ export class RdDRoll extends Dialog {
editLibre: true, editLibre: true,
editConditions: true, editConditions: true,
forceValue: actor.getForceValue(), forceValue: actor.getForceValue(),
malusArmureValue: (actor.type == 'personnage ' && actor.data.data.attributs && actor.data.data.attributs.malusarmure) ? actor.data.data.attributs.malusarmure.value : 0, malusArmureValue: (actor.isPersonnage() && actor.data.data.attributs && actor.data.data.attributs.malusarmure) ? actor.data.data.attributs.malusarmure.value : 0,
surencMalusFlag: actor.type == 'personnage ' ? (actor.data.data.compteurs.surenc.value < 0) : false, surencMalusFlag: actor.isPersonnage() ? (actor.data.data.compteurs.surenc.value < 0) : false,
surencMalusValue: actor.type == 'personnage ' ? actor.data.data.compteurs.surenc.value : 0, surencMalusValue: actor.isPersonnage() ? actor.data.data.compteurs.surenc.value : 0,
surencMalusApply: false, surencMalusApply: false,
isNatation: rollData.competence ? rollData.competence.name.toLowerCase().includes("natation") : false, isNatation: rollData.competence ? rollData.competence.name.toLowerCase().includes("natation") : false,
useEncForNatation: false, useEncForNatation: false,
@ -103,10 +104,11 @@ export class RdDRoll extends Dialog {
var rollData = this.rollData; var rollData = this.rollData;
var actor = this.actor; var actor = this.actor;
var dialog = this;
function updateRollResult(rollData) { function updateRollResult(rollData) {
let caracValue = parseInt(rollData.selectedCarac.value) let caracValue = parseInt(rollData.selectedCarac.value)
let rollLevel = RdDRoll._computeFinalLevel(rollData); let rollLevel = dialog._computeFinalLevel(rollData);
rollData.dmg = rollData.attackerRoll ? rollData.attackerRoll.dmg : RdDBonus.dmg(rollData, actor.getBonusDegat()); rollData.dmg = rollData.attackerRoll ? rollData.attackerRoll.dmg : RdDBonus.dmg(rollData, actor.getBonusDegat());
rollData.finalLevel = rollLevel; rollData.finalLevel = rollLevel;
rollData.caracValue = caracValue; rollData.caracValue = caracValue;
@ -116,7 +118,8 @@ export class RdDRoll extends Dialog {
dmgText = '(' + dmgText + ')'; dmgText = '(' + dmgText + ')';
} }
HtmlUtility._showControlWhen(".etat-general", !RdDRoll._isIgnoreEtatGeneral(rollData)); HtmlUtility._showControlWhen(".diffMoral", rollData.selectedCarac == actor.data.data.carac.volonte);
HtmlUtility._showControlWhen(".etat-general", !dialog._isIgnoreEtatGeneral(rollData));
// Sort management // Sort management
if (rollData.selectedSort) { if (rollData.selectedSort) {
@ -128,7 +131,7 @@ export class RdDRoll extends Dialog {
// Mise à jour valeurs // Mise à jour valeurs
$("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel)); $("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
$("#compdialogTitle").text(RdDRoll._getTitle(rollData)); $("#compdialogTitle").text(dialog._getTitle(rollData));
$('#coupsNonMortels').prop('checked', rollData.coupsNonMortels); $('#coupsNonMortels').prop('checked', rollData.coupsNonMortels);
$("#dmg-arme-actor").text(dmgText); $("#dmg-arme-actor").text(dmgText);
$("#defenseur-surprise").text(RdDBonus.description(rollData.surpriseDefenseur)); $("#defenseur-surprise").text(RdDBonus.description(rollData.surpriseDefenseur));
@ -213,28 +216,29 @@ export class RdDRoll extends Dialog {
}); });
} }
static _isIgnoreEtatGeneral(rollData) { _isIgnoreEtatGeneral(rollData) {
return rollData.selectedCarac.ignoreEtatGeneral; return rollData.selectedCarac.ignoreEtatGeneral;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static _computeFinalLevel(rollData) { _computeFinalLevel(rollData) {
const etat = RdDRoll._isIgnoreEtatGeneral(rollData) ? 0 : Misc.toInt(rollData.etat); const etat = this._isIgnoreEtatGeneral(rollData) ? 0 : Misc.toInt(rollData.etat);
const diffConditions = Misc.toInt(rollData.diffConditions); const diffConditions = Misc.toInt(rollData.diffConditions);
const malusEnc = (rollData.surencMalusApply) ? rollData.surencMalusValue : 0; const malusEnc = (rollData.surencMalusApply) ? rollData.surencMalusValue : 0;
const bonusTactique = RdDBonus.bonusAttaque(rollData.tactique); const bonusTactique = RdDBonus.bonusAttaque(rollData.tactique);
const malusEncNatation = (rollData.useEncForNatation) ? -rollData.encValueForNatation : 0; const malusEncNatation = (rollData.useEncForNatation) ? -rollData.encValueForNatation : 0;
const ajustementChance = rollData.selectedCarac.label.toLowerCase().includes('chance') ? rollData.ajustementAstrologique : 0; const ajustementChance = rollData.selectedCarac.label.toLowerCase().includes('chance') ? rollData.ajustementAstrologique : 0;
// Gestion malus armure // Gestion malus armure
const malusArmureValue = RdDRoll._computeMalusArmure(rollData); const malusArmureValue = this._computeMalusArmure(rollData);
const diffLibre = RdDRoll._computeDiffLibre(rollData); const diffLibre = this._computeDiffLibre(rollData);
const diffCompetence = RdDRoll._computeDiffCompetence(rollData); const diffCompetence = this._computeDiffCompetence(rollData);
const diffMoral = rollData.selectedCarac == this.actor.data.data.carac.volonte ? rollData.moral : 0;
return etat + diffCompetence + diffLibre + diffConditions + malusEnc + malusEncNatation + malusArmureValue + ajustementChance + bonusTactique; return etat + diffCompetence + diffLibre + diffMoral + diffConditions + malusEnc + malusEncNatation + malusArmureValue + ajustementChance + bonusTactique;
} }
static _computeDiffCompetence(rollData) { _computeDiffCompetence(rollData) {
if (rollData.competence) { if (rollData.competence) {
return Misc.toInt(rollData.competence.data.niveau); return Misc.toInt(rollData.competence.data.niveau);
} }
@ -244,7 +248,7 @@ export class RdDRoll extends Dialog {
return 0; return 0;
} }
static _computeDiffLibre(rollData) { _computeDiffLibre(rollData) {
let diffLibre = Misc.toInt(rollData.diffLibre); let diffLibre = Misc.toInt(rollData.diffLibre);
if (rollData.draconicList && rollData.selectedSort) { if (rollData.draconicList && rollData.selectedSort) {
return RdDItemSort.getDifficulte(rollData.selectedSort, diffLibre); return RdDItemSort.getDifficulte(rollData.selectedSort, diffLibre);
@ -252,7 +256,7 @@ export class RdDRoll extends Dialog {
return diffLibre; return diffLibre;
} }
static _computeMalusArmure(rollData) { _computeMalusArmure(rollData) {
let malusArmureValue = 0; let malusArmureValue = 0;
if (rollData.malusArmureValue != 0 && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) { if (rollData.malusArmureValue != 0 && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) {
$("#addon-message").text("Malus armure appliqué : " + rollData.malusArmureValue); $("#addon-message").text("Malus armure appliqué : " + rollData.malusArmureValue);
@ -264,7 +268,7 @@ export class RdDRoll extends Dialog {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static _getTitle(rollData) { _getTitle(rollData) {
if (rollData.competence) { if (rollData.competence) {
// If a weapon is there, add it in the title // If a weapon is there, add it in the title
let armeTitle = (rollData.arme) ? " (" + rollData.arme.name + ") " : ""; let armeTitle = (rollData.arme) ? " (" + rollData.arme.name + ") " : "";

View File

@ -203,8 +203,8 @@ export class RdDUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static getNomEthylisme( niveauEthylisme ) { static getNomEthylisme( niveauEthylisme ) {
let index = Math.abs(niveauEthylisme); let index = -niveauEthylisme;
return nomEthylisme[index]; return index <0 ? 'Aucun' : nomEthylisme[index];
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@ -33,6 +33,7 @@
{{/each}} {{/each}}
{{/select}} {{/select}}
</select> </select>
<label class="diffMoral" for="categorie">Moral: {{#if (gt moral 0)}}+{{/if}}{{moral}}</label>
</div> </div>
{{#if arme}} {{#if arme}}
<div class="form-group"> <div class="form-group">

View File

@ -17,6 +17,7 @@
{{/each}} {{/each}}
{{/select}} {{/select}}
</select> </select>
<label class="diffMoral" for="categorie">Moral: {{#if (gt moral 0)}}+{{/if}}{{moral}}</label>
</div> </div>
{{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-surenc.html"}} {{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-surenc.html"}}
<div class="form-group etat-general"> <div class="form-group etat-general">

View File

@ -10,7 +10,7 @@
<section class="sheet-body"> <section class="sheet-body">
<div class="form-group"> <div class="form-group">
<label for="xp">Protection</label> <label for="xp">Protection</label>
<input class="attribute-value" type="text" name="data.protection" value="{{data.protection}}" data-dtype="Number"/> <input class="attribute-value" type="text" name="data.protection" value="{{data.protection}}" data-dtype="String"/>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="xp">Encombrement </label> <label for="xp">Encombrement </label>

View File

@ -1,9 +1,9 @@
<option value="1">Aucun</option> <option value="1">Aucun</option>
<option value="0">Eméché</option> <option value="0">Eméché (0)</option>
<option value="-1">Gris</option> <option value="-1">Gris (-1)</option>
<option value="-2">Pinté</option> <option value="-2">Pinté (-2)</option>
<option value="-3">Pas Frais</option> <option value="-3">Pas Frais (-3)</option>
<option value="-4">Ivre</option> <option value="-4">Ivre (-4)</option>
<option value="-5">Bu</option> <option value="-5">Bu (-5)</option>
<option value="-6">Complètement fait</option> <option value="-6">Complètement fait (-6)</option>
<option value="-7">Ivre mort</option> <option value="-7">Ivre mort (-7)</option>