diff --git a/icons/filter.svg b/icons/filter.svg new file mode 100644 index 00000000..cc87a0f6 --- /dev/null +++ b/icons/filter.svg @@ -0,0 +1,59 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/locked.svg b/icons/locked.svg new file mode 100644 index 00000000..6033b6ce --- /dev/null +++ b/icons/locked.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/no-filter.svg b/icons/no-filter.svg new file mode 100644 index 00000000..1d09e88c --- /dev/null +++ b/icons/no-filter.svg @@ -0,0 +1,63 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/icons/unlocked.svg b/icons/unlocked.svg new file mode 100644 index 00000000..f86c359c --- /dev/null +++ b/icons/unlocked.svg @@ -0,0 +1,64 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 9efb56ac..a8833fd9 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -32,9 +32,11 @@ export class RdDActorSheet extends ActorSheet { // Gestion du lock/unlock des zones éditables (carac+compétences) data.data.editCaracComp = this.options.editCaracComp; data.data.lockUnlockText = (this.options.editCaracComp) ? "Bloquer" : "Débloquer"; + data.data.lockUnlockIcon = (this.options.editCaracComp) ? "unlocked.svg" : "locked.svg"; // Gestion de l'affichage total/partiel des compétences data.data.cacherCompetencesNiveauBase = this.options.cacherCompetencesNiveauBase; data.data.showHideCompetenceText = (this.options.cacherCompetencesNiveauBase) ? "Montrer tout" : "Filtrer" ; + data.data.showHideCompetenceIcon = (this.options.cacherCompetencesNiveauBase) ? "no-filter.svg" : "filter.svg"; let compCategorieNiveau = RdDUtility.getLevelCategory(); // recup catégorie data.itemsByType = RdDUtility.buildItemsClassification(data.items); diff --git a/module/actor.js b/module/actor.js index d91608ca..45489778 100644 --- a/module/actor.js +++ b/module/actor.js @@ -126,9 +126,11 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ getBonusDegat() { - return parseInt(this.data.data.attributs.plusdom.value); + return Misc.toInt(this.data.data.attributs.plusdom.value); + } + getProtectionNaturelle() { + return Misc.toInt(this.data.data.attributs.protection.value); } - /* -------------------------------------------- */ getCompetence(compName) { return RdDUtility.findCompetence(this.data.items, compName); @@ -202,32 +204,34 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - computeDeteriorationArme( rollData ) { - if ( rollData.arme && rollData.attackerRoll) { // C'est une parade + async computeDeteriorationArme( rollData ) { + const attackerRoll = rollData.attackerRoll; + if (rollData.arme && attackerRoll) { // C'est une parade // Est-ce que l'attaque est une particulière, en force ou charge et que l'attaque n'en est pas une ? - if ( rollData.attackerRoll.rolled.isPart - && ( (rollData.attackerRoll.particuliereAttaque && rollData.attackerRoll.particuliereAttaque == 'force') || rollData.attackerRoll.isCharge) - && !rollData.rolled.isPart ) { - // Jet de résistance de l'arme de parade (p.132) - let resist = RdDResolutionTable.roll( rollData.arme.data.resistance, rollData.attackerRoll.domArmePlusDom ); + if ( (rollData.needResist || attackerRoll.particuliereAttaque == 'force' || attackerRoll.isCharge) + && !rollData.rolled.isPart ) { + const dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor; + let resistance = Misc.toInt(rollData.arme.data.resistance); let msg = ""; - if (resist.isSuccess) { // Perte de résistance - msg = "Jet de résistance de votre arme réussit !" + // Jet de résistance de l'arme de parade (p.132) + let resistRoll = await RdDResolutionTable.roll( resistance, - dmg ); + if (resistRoll.isSuccess) { // Perte de résistance + msg = "Votre " + rollData.arme.name + " tient le choc de la parade. " } else { - rollData.arme.data.resistance -= rollData.attackerRoll.domArmePlusDom; - if ( rollData.arme.data.resistance <= 0 ) { + resistance -= dmg; + if ( resistance <= 0 ) { this.deleteEmbeddedEntity("OwnedItem", rollData.arme._id); - msg = "Votre arme s'est brisée sous le coup de la parade : " + rollData.arme.name; + msg = "Sous la violence de la parade, votre " + rollData.arme.name + " s'est brisée sous le coup!"; } else { - this.updateEmbeddedEntity("OwnedItem", {_id: rollData.arme._id, 'data.resistance': rollData.arme.data.resistance }); - msg = "Votre arme a perdu de la résistance : " + rollData.arme.name + " - " + rollData.arme.data.resistance; + this.updateEmbeddedEntity("OwnedItem", {_id: rollData.arme._id, 'data.resistance': resistance }); + msg = "En parant, vous endommagez votre " + rollData.arme.name + ", qui perd " + dmg + " de résistance. "; } } // Jet de désarmement - if ( !rollData.arme.includes('Bouclier') ) { // Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132) - let desarme = RdDResolutionTable.roll( this.data.data.carac.force.value, Number(rollData.competence.data.niveau) + Number(rollData.attackerRoll.domArmePlusDom) ); - if ( !desarme.isSucess) { - msg += "
De plus, vous êtes désarmé ! Votre arme " + rollData.arme.name + "tombe au sol à vos pieds"; + if (resistance > 0 && !rollData.arme.name.toLowerCase().includes('bouclier') ) { // Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132) + let desarme = await RdDResolutionTable.roll( this.data.data.carac.force.value, Misc.toInt(rollData.competence.data.niveau) -dmg ); + if ( desarme.isEchec) { + msg += "Vous ne parvenez pas à garder votre arme en main, elle tombe au sol à vos pieds"; } } ChatMessage.create( { content: msg, @@ -245,13 +249,13 @@ export class RdDActor extends Actor { let recul = await RdDResolutionTable.roll( 10, reculNiveau ); let msg = ""; if (recul.isSuccess) { - msg = this.data.name + " - Jet de Recul réussi, aucun effet !"; + msg = " Vous ne reculez pas malgré la force du coup."; } else { let chute = await RdDResolutionTable.roll( this.data.data.carac.agilite.value, reculNiveau ); if ( !chute.isSuccess || recul.isETotal ) { - msg = this.data.name + " - Jet de Recul : Vous subissez le recul du coup, et vous chutez au sol ! Vous ne pouvez plus attaquer ce round."; + msg = "Sous la violence du coup, vous reculez et chutez au sol ! Vous ne pouvez plus attaquer ce round."; } else { - msg = this.data.name + " - Jet de Recul : Vous subissez le recul du coup, et vous reculez de quelques mètres ! Vous ne pouvez plus attaquer ce round."; + msg = "La violence du choc vous fait reculer de quelques mètres ! Vous ne pouvez plus attaquer ce round."; } } ChatMessage.create( {content: msg, @@ -280,7 +284,7 @@ export class RdDActor extends Actor { // In case of fight, replace the message per dommages + localization. it indicates if result is OK or not if (rollData.attackerRoll) { // Defense case ! if (rolled.isSign || (!rollData.needSignificative && rolled.isSuccess)) { - this.computeDeteriorationArme( rollData ); + await this.computeDeteriorationArme( rollData ); explications += "
Attaque parée/esquivée !"; } else { explications += "
Esquive/Parade échouée, encaissement !"; @@ -1883,15 +1887,18 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - computeArmure( locData, domArmePlusDom, arme = undefined ) { + computeArmure( attackerRoll ) { + let locData = attackerRoll.loc; + let dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor; + let arme = attackerRoll.arme; // TODO: arc ignore armure let protection = 0; for (const item of this.data.items) { if (item.type == "armure" && item.data.equipe) { let update = duplicate(item); protection += new Roll(update.data.protection.toString()).roll().total; - update.data.deterioration += domArmePlusDom; - domArmePlusDom = 0; // Reset it + update.data.deterioration = Misc.toInt(update.data.deterioration) + dmg; + dmg = 0; // Reset it if ( update.data.deterioration >= 10) { update.data.deterioration = 0; if ( update.data.protection.toString().length == 1 ) @@ -1906,6 +1913,7 @@ export class RdDActor extends Actor { this.updateEmbeddedEntity("OwnedItem", update); } } + protection += this.getProtectionNaturelle(); console.log("Final protect", protection); return protection; } @@ -1917,7 +1925,7 @@ export class RdDActor extends Actor { } console.log("encaisserDommages", attackerRoll ) - const armure = this.computeArmure( attackerRoll.loc, attackerRoll.domArmePlusDom, attackerRoll.arme); + const armure = this.computeArmure( attackerRoll ); const rollEncaissement = new Roll("2d10 + @dmg - @armure",{ dmg: attackerRoll.dmg.total, diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 970bf137..d6fafbb2 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -74,6 +74,10 @@ export class RdDCombat { return; } let rollData = game.system.rdd.rollDataHandler[this.attackerId]; + if (!rollData) { + ui.notifications.warn("Action automatisée impossible, le jet de l'attaquant a été perdu (suite à un raffraichissement?)") + return; + } // TODO: enlever le ChatMessage? switch (button) { case '#particuliere-attaque': return await this.choixParticuliere(rollData, event.currentTarget.attributes['data-mode'].value); @@ -364,10 +368,7 @@ export class RdDCombat { /* -------------------------------------------- */ async _onParadeNormale(rollData) { console.log("RdDCombat._onParadeNormale >>>", rollData); - if (rollData.needResist && !rollData.rolled.isPart) { - // TODO: déplacer la logique détérioration armure dans RdDCombat - this.defender.computeDeteriorationArme(rollData); - } + await this.defender.computeDeteriorationArme(rollData); await this.defender.computeRecul(rollData, false); let chatOptions = { diff --git a/styles/simple.css b/styles/simple.css index 40a0efbd..670212f2 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -238,6 +238,19 @@ table {border: 1px solid #7a7971;} height: 8%; border-width: 0; } +.small-button-container { + height: 16px; + border: 0; +} + +.small-button-container img { + max-height: 100%; + max-width: 100%; +} +.small-button-img { + max-height: 24; + border-width: 0; +} .foundryvtt-reve-de-dragon .sheet-header .header-fields { -webkit-box-flex: 1; diff --git a/system.json b/system.json index 84799848..82c818fa 100644 --- a/system.json +++ b/system.json @@ -5,7 +5,7 @@ "version": "1.1.10", "minimumCoreVersion": "0.7.5", "compatibleCoreVersion": "0.7.8", - "templateVersion": 69, + "templateVersion": 70, "author": "LeRatierBretonnien", "esmodules": [ "module/rdd-main.js", "module/hook-renderChatLog.js" ], "styles": ["styles/simple.css"], diff --git a/template.json b/template.json index f3ed1b3a..35fdbc9e 100644 --- a/template.json +++ b/template.json @@ -49,7 +49,7 @@ "max": 10, "value": 10, "label": "Endurance", - "derivee": false + "derivee": false }, "resonnance": { "actors" : [] @@ -77,6 +77,12 @@ "value": 0, "label": "Vitesse", "derivee": true + }, + "protection": { + "type": "number", + "value": 0, + "label": "Protection", + "derivee": false } } }, @@ -138,7 +144,7 @@ "max": 10, "value": 10, "label": "Endurance", - "derivee": false + "derivee": false }, "sonne": { "value": false, @@ -178,13 +184,13 @@ "type": "number", "value": 0, "label": "Encombrement", - "derivee": false + "derivee": false }, "protection": { "type": "number", "value": 0, "label": "Protection", - "derivee": false + "derivee": false } }, "compteurs": { @@ -240,7 +246,7 @@ "value": 10, "label": "Dexterité", "xp": 0, - "derivee": false + "derivee": false }, "vue": { "type": "number", @@ -261,7 +267,7 @@ "value": 10, "label": "Odorat-Goût", "xp": 0, - "derivee": false + "derivee": false }, "volonte": { "type": "number", @@ -275,14 +281,14 @@ "value": 10, "label": "Intellect", "xp": 0, - "derivee": false + "derivee": false }, "empathie": { "type": "number", "value": 10, "label": "Empathie", "xp": 0, - "derivee": false + "derivee": false }, "reve": { "type": "number", @@ -400,6 +406,12 @@ "value": 0, "label": "Malus Armure", "derivee": true + }, + "protection": { + "type": "number", + "value": 0, + "label": "Protection naturelle", + "derivee": false } }, "reve": { diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index 7770e99d..177a2ce0 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -98,7 +98,7 @@
- {{data.lockUnlockText}} + blocker/débloquer{{data.lockUnlockText}}