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 @@
+
+
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 @@
+
+
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 @@
+
+
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 @@
+
+
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 @@