Fixes recul/desarmement

This commit is contained in:
Vincent Vandemeulebrouck 2021-01-23 18:36:30 +01:00
parent 667845d77d
commit 26722d26fd
7 changed files with 95 additions and 85 deletions

View File

@ -179,18 +179,34 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getReveActuel() { getReveActuel() {
return this.data.data.reve?.reve?.value ?? this.data.data.carac.reve.value; return Misc.toInt(this.data.data.reve?.reve?.value ?? this.data.data.carac.reve.value);
}
getChanceActuel() {
return this.data.data.compteurs.chance?.value ?? 10;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getForceValue() { getChanceActuel() {
return this.data.data.carac.force?.force ?? this.data.data.carac.reve.value; return Misc.toInt(this.data.data.compteurs.chance?.value ?? 10);
}
/* -------------------------------------------- */
getTaille() {
return Misc.toInt(this.data.data.carac.taille?.value);
}
/* -------------------------------------------- */
getForce() {
if (this.isEntiteCauchemar()) {
return Misc.toInt(this.data.data.carac.reve?.value);
}
return Misc.toInt(this.data.data.carac.force?.value);
}
/* -------------------------------------------- */
getAgilite() {
switch(this.data.type) {
case 'personnage': return Misc.toInt(this.data.data.carac.agilite?.value);
case 'creature': return Misc.toInt(this.data.data.carac.force?.value);
case 'entite': return Misc.toInt(this.data.data.carac.reve?.value);
}
return 10;
} }
getMoralTotal() { getMoralTotal() {
return this.data.data.compteurs.moral?.value ?? 0; return Misc.toInt(this.data.data.compteurs.moral?.value);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getBonusDegat() { getBonusDegat() {
@ -203,16 +219,16 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getEtatGeneral() { getEtatGeneral() {
return this.data.data.compteurs.etat?.value ?? 0; return Misc.toInt(this.data.data.compteurs.etat?.value);
} }
getMalusArmure() { getMalusArmure() {
return this.data.data.attributs?.malusarmure?.value ?? 0; return Misc.toInt(this.data.data.attributs?.malusarmure?.value);
} }
getEncTotal() { getEncTotal() {
return Math.floor(this.encTotal ?? 0); return Math.floor(this.encTotal ?? 0);
} }
getSurenc() { getSurenc() {
return this.data.data.compteurs.surenc?.value ?? 0; return Misc.toInt(this.data.data.compteurs.surenc?.value);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
loadCompendiumNames() { loadCompendiumNames() {
@ -229,7 +245,6 @@ export class RdDActor extends Actor {
getMeditation(id) { getMeditation(id) {
return this.data.items.find(item => item.type == 'meditation' && item._id == id); return this.data.items.find(item => item.type == 'meditation' && item._id == id);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getBestDraconic() { getBestDraconic() {
const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau); const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau);
@ -559,8 +574,7 @@ export class RdDActor extends Actor {
async updateCarac(caracName, caracValue) { async updateCarac(caracName, caracValue) {
let caracpath = "data.carac." + caracName + ".value" let caracpath = "data.carac." + caracName + ".value"
if (caracName == "force") { if (caracName == "force") {
let caracTaille = this.data.data.carac.taille; if ( Number(caracValue) > this.getTaille() + 4) {
if ( Number(caracValue) > Number(caracTaille.value)+4) {
ui.notifications.warn("Votre FORCE doit être au maximum de TAILLE+4"); ui.notifications.warn("Votre FORCE doit être au maximum de TAILLE+4");
return; return;
} }
@ -580,6 +594,9 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async updateCaracXP(caracName, caracXP) { async updateCaracXP(caracName, caracXP) {
if (caracName == 'Taille') {
return;
}
let caracpath = "data.carac." + caracName + ".xp"; let caracpath = "data.carac." + caracName + ".xp";
await this.update({ [caracpath]: caracXP }); await this.update({ [caracpath]: caracXP });
this.checkCaracXP(caracName); this.checkCaracXP(caracName);
@ -1971,7 +1988,9 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async appliquerExperience(rolled, caracName, competence = undefined) { async appliquerExperience(rolled, caracName, competence = undefined) {
if (this.isCreature()) {
return;
}
if (rolled.isPart && rolled.finalLevel < 0) { if (rolled.isPart && rolled.finalLevel < 0) {
// Cas de désir lancinant, pas d'expérience sur particulière // Cas de désir lancinant, pas d'expérience sur particulière
if (this.checkDesirLancinant()) { if (this.checkDesirLancinant()) {
@ -2222,7 +2241,7 @@ export class RdDActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async encaisserDommages(rollData, attacker = undefined) { async encaisserDommages(rollData, attacker = undefined, defenderRoll = undefined) {
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) { if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
return; return;
} }
@ -2241,15 +2260,16 @@ export class RdDActor extends Actor {
this.computeEtatGeneral(); this.computeEtatGeneral();
this.sheet.render(false); this.sheet.render(false);
let santeActuelle = duplicate(this.data.data.sante); mergeObject(encaissement, {
alias: this.data.name,
encaissement.alias = this.data.name; hasPlayerOwner: this.hasPlayerOwner,
encaissement.hasPlayerOwner = this.hasPlayerOwner; resteEndurance: this.data.data.sante.endurance.value,
encaissement.resteEndurance = santeActuelle.endurance.value sonne: perteEndurance.sonne,
encaissement.sonne = perteEndurance.sonne; jetEndurance: perteEndurance.jetEndurance,
encaissement.jetEndurance = perteEndurance.jetEndurance; endurance: santeOrig.endurance.value - perteEndurance.newValue,
encaissement.endurance = santeOrig.endurance.value - perteEndurance.newValue; vie: this.isEntiteCauchemar() ? 0 : (santeOrig.vie.value - perteVie.newValue),
encaissement.vie = this.isEntiteCauchemar() ? 0 : (santeOrig.vie.value - perteVie.newValue); show: defenderRoll?.show ?? {}
});
ChatUtility.createChatWithRollMode(this.name, { ChatUtility.createChatWithRollMode(this.name, {
roll: encaissement.roll, roll: encaissement.roll,

View File

@ -270,7 +270,7 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
attaqueDestinee(attackerRoll) { attaqueDestinee(attackerRoll) {
ui.notifications.info('Attaque significative grâce à la destinée') ui.notifications.info('Attaque significative grâce à la destinée')
RdDResolutionTable.forceSignificative(attackerRoll.rolled); RdDResolutionTable.significativeRequise(attackerRoll.rolled);
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme); this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
this._onAttaqueNormale(attackerRoll); this._onAttaqueNormale(attackerRoll);
} }
@ -289,7 +289,7 @@ export class RdDCombat {
let defenderRoll = RdDCombat._getDefense(attackerRoll.passeArme); let defenderRoll = RdDCombat._getDefense(attackerRoll.passeArme);
if (defenderRoll) { if (defenderRoll) {
ui.notifications.info('Défense significative grâce à la destinée') ui.notifications.info('Défense significative grâce à la destinée')
RdDResolutionTable.forceSignificative(defenderRoll.rolled); RdDResolutionTable.significativeRequise(defenderRoll.rolled);
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme); this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
if (defenderRoll.arme) { if (defenderRoll.arme) {
this._onParadeNormale(defenderRoll); this._onParadeNormale(defenderRoll);
@ -601,7 +601,6 @@ export class RdDCombat {
let rollData = { let rollData = {
passeArme: attackerRoll.passeArme, passeArme: attackerRoll.passeArme,
forceValue: this.defender.getForceValue(),
diffLibre: attackerRoll.diffLibre, diffLibre: attackerRoll.diffLibre,
attackerRoll: attackerRoll, attackerRoll: attackerRoll,
competence: this.defender.getCompetence(compName), competence: this.defender.getCompetence(compName),
@ -698,7 +697,6 @@ export class RdDCombat {
_prepareEsquive(attackerRoll, competence) { _prepareEsquive(attackerRoll, competence) {
let rollData = { let rollData = {
passeArme: attackerRoll.passeArme, passeArme: attackerRoll.passeArme,
forceValue: this.defender.getForceValue(),
diffLibre: attackerRoll.diffLibre, diffLibre: attackerRoll.diffLibre,
attackerRoll: attackerRoll, attackerRoll: attackerRoll,
competence: competence, competence: competence,
@ -774,16 +772,13 @@ export class RdDCombat {
} }
} }
// Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132) // Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132)
if (resistance > 0 && !RdDItemArme.getCategorieParade(rollData.arme) == 'boucliers') { if (resistance > 0 && RdDItemArme.getCategorieParade(rollData.arme) != 'boucliers') {
let desarme = await RdDResolutionTable.rollData({ let desarme = await RdDResolutionTable.rollData({
caracValue: this.defender.data.data.carac.force.value, caracValue: this.defender.getForce(),
finalLevel: Misc.toInt(rollData.competence.data.niveau) - dmg, finalLevel: Misc.toInt(rollData.competence.data.niveau) - dmg,
showDice: false showDice: false
}); });
rollData.show.desarme = desarme.rolled.isEchec; rollData.show.desarme = desarme.rolled.isEchec;
if (desarme.rolled.isEchec) {
rollData.show.desarme = true;
}
} }
} }
} }
@ -793,23 +788,18 @@ export class RdDCombat {
const attackerRoll = defenderRoll.attackerRoll; const attackerRoll = defenderRoll.attackerRoll;
if (this._isAttaqueCauseRecul(attackerRoll)) { if (this._isAttaqueCauseRecul(attackerRoll)) {
let impactRecul = this._computeImpactRecul(attackerRoll); const impact = this._computeImpactRecul(attackerRoll);
const agilite = this.defender.isEntiteCauchemar() const rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impact });
? this.defender.data.data.carac.reve.value
: this.defender.data.data.carac.agilite.value;
let rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impactRecul, showDice: false }); if (rollRecul.rolled.isSuccess) {
if (rollRecul.isSuccess) {
defenderRoll.show.recul = 'encaisse'; defenderRoll.show.recul = 'encaisse';
} else if (rollRecul.isETotal) { } else if (rollRecul.rolled.isETotal) {
defenderRoll.show.recul = 'chute'; defenderRoll.show.recul = 'chute';
} }
else { else {
let chute = await RdDResolutionTable.rollData({ caracValue: agilite, finalLevel: impactRecul, showDice: false }); const agilite = this.defender.getAgilite();
defenderRoll.show.recul = (chute.isSuccess) const chute = await RdDResolutionTable.rollData({ caracValue: agilite, finalLevel: impact });
? 'recul' defenderRoll.show.recul = (chute.rolled.isSuccess) ? 'recul' : 'chute';
: 'chute';
} }
} }
} }
@ -819,7 +809,10 @@ export class RdDCombat {
} }
_computeImpactRecul(attaque) { _computeImpactRecul(attaque) {
return Misc.toInt(this.defender.data.data.carac.taille.value) - (attaque.forceValue + attaque.arme.data.dommagesReels); const taille = this.defender.getTaille();
const force = this.attacker.getForce();
const dommages = attaque.arme.data.dommagesReels;
return taille - (force + dommages);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -841,7 +834,7 @@ export class RdDCombat {
attackerRoll.defenderTokenId = defenderTokenId; attackerRoll.defenderTokenId = defenderTokenId;
await this.computeRecul(defenderRoll); await this.computeRecul(defenderRoll);
this.defender.encaisserDommages(attackerRoll, this.attacker); this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll);
} else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas } else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas
game.socket.emit("system.foundryvtt-reve-de-dragon", { game.socket.emit("system.foundryvtt-reve-de-dragon", {
msg: "msg_encaisser", msg: "msg_encaisser",

View File

@ -138,7 +138,7 @@ export class RdDResolutionTable {
mergeObject(chances, this._computeCell(null, newScore), { overwrite: true }); mergeObject(chances, this._computeCell(null, newScore), { overwrite: true });
} }
} }
static forceSignificative(chances) { static significativeRequise(chances) {
chances.roll = Math.floor(chances.score / 2); chances.roll = Math.floor(chances.score / 2);
mergeObject(chances, reussites.find(x => x.code == 'sign'), { overwrite: true }); mergeObject(chances, reussites.find(x => x.code == 'sign'), { overwrite: true });
} }

View File

@ -44,7 +44,6 @@ export class RdDRoll extends Dialog {
diffLibre: rollData.competence?.data.default_diffLibre ?? 0, diffLibre: rollData.competence?.data.default_diffLibre ?? 0,
editLibre: true, editLibre: true,
editConditions: true, editConditions: true,
forceValue: actor.getForceValue(),
malusArmureValue: actor.getMalusArmure(), malusArmureValue: actor.getMalusArmure(),
surencMalusFlag: actor.isPersonnage() ? (actor.data.data.compteurs.surenc.value < 0) : false, surencMalusFlag: actor.isPersonnage() ? (actor.data.data.compteurs.surenc.value < 0) : false,
surencMalusValue: actor.getSurenc(), surencMalusValue: actor.getSurenc(),

View File

@ -30,15 +30,19 @@
{{/if}} {{/if}}
({{dmg.loc.label}}) ({{dmg.loc.label}})
{{#if (gt endurance 0)}} {{#if (gt endurance 0)}}
{{#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance {{#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance
{{#if (ne vie 0)}}, <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if}} {{#if (ne vie 0)}}, <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if}}
{{/if}} {{/if}}
{{#if (ne dmg.mortalite 'cauchemar')}} {{#if (ne dmg.mortalite 'cauchemar')}}
{{#if (gt endurance 1)}}et {{#if (gt endurance 1)}}et
{{#if sonne}}est <strong>sonné</strong><img class="chat-icon" src="icons/svg/stoned.svg" alt="charge" height="16" width="16" /> jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}} {{#if sonne}}est <strong>sonné</strong><img class="chat-icon" src="icons/svg/stoned.svg" alt="charge" height="16" width="16" /> jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}
({{jetEndurance}} / {{resteEndurance}})! ({{jetEndurance}} / {{resteEndurance}})!
{{/if}} {{/if}}
{{/if}} {{/if}}
{{/if}}
{{#if (eq show.recul 'encaisse')}}<div>{{alias}} ne recule pas malgré la violence du coup.</div>
{{else if (eq show.recul 'chute')}}<div>Sous la violence du coup, {{alias}} recule et chute au sol ! Il/elle ne pourra plus attaquer ce round.</div>
{{else if (eq show.recul 'recul')}}<div>La violence du coup fait reculer {{alias}} de quelques mètres ! Il/elle ne pourra plus attaquer ce round.</div>
{{/if}} {{/if}}
</div> </div>
{{/if}} {{/if}}

View File

@ -15,11 +15,6 @@
{{/if}} {{/if}}
</div> </div>
{{#if (eq show.recul 'encaisse')}}<div>Vous ne reculez pas malgré la violence du coup.</div>
{{else if (eq show.recul 'chute')}}<div>Sous la violence du coup, vous reculez et chutez au sol ! Vous ne pouvez plus attaquer ce round.</div>
{{else if (eq show.recul 'recul')}}<div>La violence du choup vous fait reculer de quelques mètres ! Vous ne pouvez plus attaquer ce round.</div>
{{/if}}
{{#if attackerRoll.tactique}} {{#if attackerRoll.tactique}}
<div> <div>
{{#if (eq attackerRoll.tactique 'charge')}} {{#if (eq attackerRoll.tactique 'charge')}}

View File

@ -4,42 +4,41 @@
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
<hr> <hr>
<div> <div>
{{#if rolled.isSuccess}} <span>
<span>Attaque parée!</span> {{#if rolled.isSuccess}}
{{#if rolled.isPart}} Attaque parée!
<!-- TODO: cas de parade à mains nues, texte à modifier --> {{#if rolled.isPart}}<strong>{{alias}} pourra tenter une deuxième parade!</strong>{{/if}}
<span><strong>Vous pouvez utiliser votre arme pour une deuxième parade!</strong></span> {{else}}
La parade a échoué!
{{/if}} {{/if}}
{{else}} </span>
<span>Votre parade a échoué!</span>
{{/if}}
</div> </div>
{{#if (eq show.recul 'encaisse')}}<div>Vous ne reculez pas malgré la violence du coup.</div> {{#if (eq show.recul 'encaisse')}}<div>{{alias}} ne recule pas malgré la violence du coup.</div>
{{else if (eq show.recul 'brise')}}<div>Sous la violence du coup, vous reculez et chutez au sol ! Vous ne pouvez plus attaquer ce round.</div> {{else if (eq show.recul 'chute')}}<div>Sous la violence du coup, {{alias}} recule et chute au sol ! Il/elle ne pourra plus attaquer ce round.</div>
{{else if (eq show.recul 'perte')}}<div>La violence du choup vous fait reculer de quelques mètres ! Vous ne pouvez plus attaquer ce round.</div> {{else if (eq show.recul 'recul')}}<div>La violence du coup fait reculer {{alias}} de quelques mètres ! Il/elle ne pourra plus attaquer ce round.</div>
{{/if}} {{/if}}
{{#if (eq show.deteriorationArme 'resiste')}} {{#if (eq show.deteriorationArme 'resiste')}}
<div>Votre {{arme.name}} résiste au choc de la parade.</div> <div>L'arme résiste au choc de la parade.</div>
{{else if (eq show.deteriorationArme 'resiste')}} {{else if (eq show.deteriorationArme 'brise')}}
<div>Sous la violence de la parade, votre {{arme.name}} s'est brisée!</div> <div>Sous la violence de la parade, {{arme.name}} s'est brisée!</div>
{{else if (eq show.deteriorationArme 'resiste')}} {{else if (eq show.deteriorationArme 'perte')}}
<div>En parant, vous endommagez votre {{arme.name}} qui perd {{show.perteResistance}} de résistance.</div> <div>En parant, l'arme perd {{show.perteResistance}} de résistance.</div>
{{/if}} {{/if}}
{{#if show.desarme}} {{#if show.desarme}}
<div>Vous ne parvenez pas à garder votre arme en main, elle tombe à vos pieds.</div> <div>Le défenseur {{alias}} lâche son arme qui tombe à ses pieds.</div>
{{/if}} {{/if}}
{{#if attackerRoll.tactique}} {{#if attackerRoll.tactique}}
<div> <div>
{{#if (eq attackerRoll.tactique 'charge')}} {{#if (eq attackerRoll.tactique 'charge')}}
<img class="chat-icon" src="icons/svg/thrust.svg" alt="charge" height="32" width="32" /> <img class="chat-icon" src="icons/svg/thrust.svg" alt="charge" height="32" width="32" />
C'était une charge, les parades de votre adversaire auront un -4 et il ne pourra pas esquiver! C'était une charge, les parades de l'adversaire auront un -4 et il ne pourra pas esquiver!
{{ else if (eq attackerRoll.tactique 'feinte')}} {{ else if (eq attackerRoll.tactique 'feinte')}}
<img class="chat-icon" src="systems/foundryvtt-reve-de-dragon/icons/heures/hd06.svg" alt="feinte" height="32" <img class="chat-icon" src="systems/foundryvtt-reve-de-dragon/icons/heures/hd06.svg" alt="feinte" height="32"
width="32" /> width="32" />
C'était une feinte! C'était une feinte!
{{/if}} {{/if}}
</div> </div>