Fixes recul/desarmement

# Conflicts:
#	module/rdd-combat.js
This commit is contained in:
Vincent Vandemeulebrouck 2021-01-23 18:36:30 +01:00
parent 7fc6ccb106
commit ad2a68aedd
7 changed files with 95 additions and 93 deletions

View File

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

View File

@ -270,7 +270,7 @@ export class RdDCombat {
/* -------------------------------------------- */
attaqueDestinee(attackerRoll) {
ui.notifications.info('Attaque significative grâce à la destinée')
RdDResolutionTable.forceSignificative(attackerRoll.rolled);
RdDResolutionTable.significativeRequise(attackerRoll.rolled);
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
this._onAttaqueNormale(attackerRoll);
}
@ -289,7 +289,7 @@ export class RdDCombat {
let defenderRoll = RdDCombat._getDefense(attackerRoll.passeArme);
if (defenderRoll) {
ui.notifications.info('Défense significative grâce à la destinée')
RdDResolutionTable.forceSignificative(defenderRoll.rolled);
RdDResolutionTable.significativeRequise(defenderRoll.rolled);
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
if (defenderRoll.arme) {
this._onParadeNormale(defenderRoll);
@ -601,7 +601,6 @@ export class RdDCombat {
let rollData = {
passeArme: attackerRoll.passeArme,
forceValue: this.defender.getForceValue(),
diffLibre: attackerRoll.diffLibre,
attackerRoll: attackerRoll,
competence: this.defender.getCompetence(compName),
@ -698,7 +697,6 @@ export class RdDCombat {
_prepareEsquive(attackerRoll, competence) {
let rollData = {
passeArme: attackerRoll.passeArme,
forceValue: this.defender.getForceValue(),
diffLibre: attackerRoll.diffLibre,
attackerRoll: attackerRoll,
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)
if (resistance > 0 && !RdDItemArme.getCategorieParade(rollData.arme) == 'boucliers') {
if (resistance > 0 && RdDItemArme.getCategorieParade(rollData.arme) != 'boucliers') {
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,
showDice: false
});
rollData.show.desarme = desarme.rolled.isEchec;
if (desarme.rolled.isEchec) {
rollData.show.desarme = true;
}
}
}
}
@ -793,31 +788,18 @@ export class RdDCombat {
const attackerRoll = defenderRoll.attackerRoll;
if (this._isAttaqueCauseRecul(attackerRoll)) {
let impactRecul = this._computeImpactRecul(attackerRoll);
const agilite = 10;
if ( this.defender.data.data.carac.agilite ) {
agilite = this.defender.data.data.carac.agilite.value;
} else if ( this.defender.data.data.carac.force) {
agilite = this.defender.data.data.carac.force.value;
} else if ( this.defender.isEntiteCauchemar()) {
agilite = this.defender.data.data.carac.reve.value;
} else
ui.notifications.warn("Recul impossible pour cette créature/entité");
return;
}
const impact = this._computeImpactRecul(attackerRoll);
const rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impact });
let rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impactRecul, showDice: false });
if (rollRecul.isSuccess) {
if (rollRecul.rolled.isSuccess) {
defenderRoll.show.recul = 'encaisse';
} else if (rollRecul.isETotal) {
} else if (rollRecul.rolled.isETotal) {
defenderRoll.show.recul = 'chute';
}
else {
let chute = await RdDResolutionTable.rollData({ caracValue: agilite, finalLevel: impactRecul, showDice: false });
defenderRoll.show.recul = (chute.isSuccess)
? 'recul'
: 'chute';
const agilite = this.defender.getAgilite();
const chute = await RdDResolutionTable.rollData({ caracValue: agilite, finalLevel: impact });
defenderRoll.show.recul = (chute.rolled.isSuccess) ? 'recul' : 'chute';
}
}
}
@ -827,7 +809,10 @@ export class RdDCombat {
}
_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);
}
/* -------------------------------------------- */
@ -849,7 +834,7 @@ export class RdDCombat {
attackerRoll.defenderTokenId = defenderTokenId;
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
game.socket.emit("system.foundryvtt-reve-de-dragon", {
msg: "msg_encaisser",

View File

@ -138,7 +138,7 @@ export class RdDResolutionTable {
mergeObject(chances, this._computeCell(null, newScore), { overwrite: true });
}
}
static forceSignificative(chances) {
static significativeRequise(chances) {
chances.roll = Math.floor(chances.score / 2);
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,
editLibre: true,
editConditions: true,
forceValue: actor.getForceValue(),
malusArmureValue: actor.getMalusArmure(),
surencMalusFlag: actor.isPersonnage() ? (actor.data.data.compteurs.surenc.value < 0) : false,
surencMalusValue: actor.getSurenc(),

View File

@ -30,15 +30,19 @@
{{/if}}
({{dmg.loc.label}})
{{#if (gt endurance 0)}}
{{#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance
{{#if (ne vie 0)}}, <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if}}
{{/if}}
{{#if (ne dmg.mortalite 'cauchemar')}}
{{#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}}
({{jetEndurance}} / {{resteEndurance}})!
{{/if}}
{{/if}}
{{#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance
{{#if (ne vie 0)}}, <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if}}
{{/if}}
{{#if (ne dmg.mortalite 'cauchemar')}}
{{#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}}
({{jetEndurance}} / {{resteEndurance}})!
{{/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}}
</div>
{{/if}}

View File

@ -15,11 +15,6 @@
{{/if}}
</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}}
<div>
{{#if (eq attackerRoll.tactique 'charge')}}

View File

@ -4,42 +4,41 @@
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
<hr>
<div>
{{#if rolled.isSuccess}}
<span>Attaque parée!</span>
{{#if rolled.isPart}}
<!-- TODO: cas de parade à mains nues, texte à modifier -->
<span><strong>Vous pouvez utiliser votre arme pour une deuxième parade!</strong></span>
<span>
{{#if rolled.isSuccess}}
Attaque parée!
{{#if rolled.isPart}}<strong>{{alias}} pourra tenter une deuxième parade!</strong>{{/if}}
{{else}}
La parade a échoué!
{{/if}}
{{else}}
<span>Votre parade a échoué!</span>
{{/if}}
</span>
</div>
{{#if (eq show.recul 'encaisse')}}<div>Vous ne reculez 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 'perte')}}<div>La violence du choup vous fait reculer de quelques mètres ! Vous ne pouvez plus attaquer ce round.</div>
{{#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 (eq show.deteriorationArme 'resiste')}}
<div>Votre {{arme.name}} résiste au choc de la parade.</div>
{{else if (eq show.deteriorationArme 'resiste')}}
<div>Sous la violence de la parade, votre {{arme.name}} s'est brisée!</div>
{{else if (eq show.deteriorationArme 'resiste')}}
<div>En parant, vous endommagez votre {{arme.name}} qui perd {{show.perteResistance}} de résistance.</div>
<div>L'arme résiste au choc de la parade.</div>
{{else if (eq show.deteriorationArme 'brise')}}
<div>Sous la violence de la parade, {{arme.name}} s'est brisée!</div>
{{else if (eq show.deteriorationArme 'perte')}}
<div>En parant, l'arme perd {{show.perteResistance}} de résistance.</div>
{{/if}}
{{#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 attackerRoll.tactique}}
<div>
{{#if (eq attackerRoll.tactique 'charge')}}
<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')}}
<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!
{{/if}}
</div>