diff --git a/assets/actions/cuisine.svg b/assets/actions/cuisine.svg
new file mode 100644
index 00000000..2bb4ca88
--- /dev/null
+++ b/assets/actions/cuisine.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/ui/fatigue.svg b/assets/ui/fatigue.svg
new file mode 100644
index 00000000..8397e044
--- /dev/null
+++ b/assets/ui/fatigue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/ui/part-finesse.svg b/assets/ui/part-finesse.svg
new file mode 100644
index 00000000..b9fc0de7
--- /dev/null
+++ b/assets/ui/part-finesse.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/ui/part-force.svg b/assets/ui/part-force.svg
new file mode 100644
index 00000000..15f4c4eb
--- /dev/null
+++ b/assets/ui/part-force.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/ui/part-rapidite.svg b/assets/ui/part-rapidite.svg
new file mode 100644
index 00000000..dbb6d451
--- /dev/null
+++ b/assets/ui/part-rapidite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/changelog.md b/changelog.md
index cefc6aec..33b97cc8 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,28 @@
# 13.0
+## 13.0.10 - Les papilles d'Illysis
+
+- Ajout d'un statut "saignement" en cas de blessure grave ou critique sans premiers soins
+
+- Nouvelle fenêtre de jets de dés
+ - jets de méditation
+ - jets de tâches
+ - jets de caractéristiques
+ - jets de compétences
+ - Boutons d'initiative et d'attaque V2
+ - fenêtre d'attaque
+ - choix des armes
+ - gestion des particulières
+ - message au défenseur
+ - gestion des demi-surprises (attaquant/défenseur)
+ - gestion des tactiques (attaquant/défenseur)
+ - en cours nouvelle fenêtre de jets
+ - jets de compétence avec messages
+ - jets de cuisine séparés avec messages (pour gérer plus tard les spécificités: fabricatioon de plats)
+ - gestion des empoignades
+
+- Technique: suppression de warnings foundry sur renderTemplate
+
## 13.0.9 - Le combat d'Illysis
- Fix
- La montée en TMR fonctionne
diff --git a/css/foundryvtt-reve-de-dragon.css b/css/foundryvtt-reve-de-dragon.css
index 36ac4ced..41de9c72 100644
--- a/css/foundryvtt-reve-de-dragon.css
+++ b/css/foundryvtt-reve-de-dragon.css
@@ -96,6 +96,7 @@ select,
--gradient-red: linear-gradient(150deg, rgba(255, 0, 0, 0.3), rgba(255, 200, 128, 0.05), rgba(255, 200, 128, 0.1), rgba(255, 10, 0, 0.3));
--gradient-violet: linear-gradient(150deg, rgba(100, 45, 124, 0.6), rgba(216, 157, 192, 0.3), rgba(177, 157, 216, 0.5), rgba(107, 62, 121, 0.3), rgba(100, 45, 124, 0.6));
--gradient-purple-black: linear-gradient(150deg, rgba(0, 0, 0, 0.7), rgba(100, 45, 124, 0.4), rgba(82, 17, 131, 0.3), rgba(100, 45, 124, 0.4), rgba(0, 0, 0, 0.7));
+ --gradient-warning: linear-gradient(150deg, hsla(32, 100%, 50%, 0.3), hsla(52, 60%, 50%, 0.1), hsla(32, 60%, 50%, 0.1), hsla(32, 100%, 50%, 0.3));
--gradient-silver-light: linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2));
--gradient-daylight: conic-gradient(from 0deg, hsla(50, 100%, 80%, 0.7), hsla(30, 30%, 40%, 0.1) 25%, hsla(250, 50%, 40%, 0.1) 25%, hsla(250, 30%, 30%, 0.7) 50%, hsla(250, 50%, 40%, 0.1) 75%, hsla(30, 30%, 40%, 0.1) 75%, hsla(50, 100%, 80%, 0.7));
--background-custom-button: linear-gradient(to bottom, hsla(208, 38%, 21%, 0.988) 5%, hsla(202, 42%, 14%, 0.671) 100%);
@@ -528,6 +529,10 @@ select,
flex-direction: row;
margin: 0.1rem 0;
}
+.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section subline .warning {
+ border-radius: 6px;
+ background: var(--gradient-warning);
+}
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-img {
display: flex;
flex-direction: column;
@@ -655,7 +660,8 @@ select,
width: 1.5rem;
text-align: center;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat {
font-family: CaslonAntique;
display: grid;
grid-template-areas: "img header buttons" "img resume buttons" "details details details" "actions actions actions";
@@ -663,51 +669,61 @@ select,
grid-template-rows: max-content max-content max-content max-content;
gap: 0 0.5rem;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-img {
grid-area: img;
display: flex;
flex-direction: column;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img img {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img img,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-img img {
border: 0;
max-height: 3rem;
max-width: 3rem;
object-fit: contain;
height: 100%;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-header {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-header,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-header {
grid-area: header;
font-weight: bold;
font-size: 0.9rem;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-resume {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-resume,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-resume {
grid-area: resume;
text-align: justify;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-details {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-details,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-details {
grid-area: details;
text-align: justify;
display: flex;
flex-direction: column;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions {
grid-area: actions;
display: flex;
flex-direction: column;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions a {
display: flex;
flex-direction: row;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a img {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a img,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions a img {
margin-right: 0.5rem;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons {
grid-area: buttons;
display: flex;
flex-direction: column;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a {
border-radius: 0.2rem;
cursor: pointer;
padding: 0.2rem;
@@ -718,14 +734,17 @@ select,
display: inline-block;
align-items: center;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a img {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a img,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a img {
max-width: 1rem;
max-height: 1rem;
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:hover {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:hover,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a:hover {
background: var(--background-custom-button-hover);
}
-.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:active {
+.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:active,
+.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a:active {
position: relative;
top: 1px;
}
@@ -1954,13 +1973,13 @@ select,
justify-content: flex-start;
flex-direction: column;
position: absolute;
- top: 4.6rem;
- left: -19rem;
+ top: 10rem;
+ left: -9rem;
}
.system-foundryvtt-reve-de-dragon .token-hud-ext.soins {
flex-direction: column;
position: absolute;
- top: 14.7rem;
+ top: 15.5rem;
left: -6rem;
max-width: 8rem;
line-height: 1rem;
@@ -1975,14 +1994,18 @@ select,
width: 9rem;
height: fit-content;
border-radius: 0.3rem;
- min-width: 6rem;
+ min-width: 8rem;
flex-basis: auto;
padding: 0;
- line-height: 0.95rem;
+ line-height: 1.6rem;
margin: 0.2rem;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
}
-.system-foundryvtt-reve-de-dragon .rdd-hud-menu label {
- font-size: 0.8rem;
+.system-foundryvtt-reve-de-dragon div.control-icon.token-hud-icon select,
+.system-foundryvtt-reve-de-dragon div.control-icon.token-hud-icon label {
+ font-size: 1rem;
}
.system-foundryvtt-reve-de-dragon .item-checkbox {
height: 25px;
diff --git a/less/colors.less b/less/colors.less
index 6320490a..bf889464 100644
--- a/less/colors.less
+++ b/less/colors.less
@@ -27,6 +27,11 @@
--gradient-red: linear-gradient(150deg, rgba(255, 0, 0, 0.3), rgba(255, 200, 128, 0.05),rgba(255, 200, 128, 0.1), rgba(255,10,0,0.3));
--gradient-violet: linear-gradient(150deg, rgba(100, 45, 124, 0.6), rgba(216, 157, 192, 0.3), rgba(177, 157, 216, 0.5), rgba(107, 62, 121, 0.3), rgba(100, 45, 124, 0.6));
--gradient-purple-black: linear-gradient(150deg, rgba(0, 0, 0, 0.7), rgba(100, 45, 124, 0.4), rgba(82, 17, 131, 0.3),rgba(100, 45, 124, 0.4), rgba(0, 0, 0, 0.7));
+ --gradient-warning: linear-gradient(150deg,
+ hsla(32, 100%, 50%, 0.3),
+ hsla(52, 60%, 50%, 0.1),
+ hsla(32, 60%, 50%, 0.1),
+ hsla(32, 100%, 50%, 0.3));
--gradient-silver-light: linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2));
--gradient-daylight: conic-gradient(
from 0deg,
diff --git a/less/foundryvtt-reve-de-dragon.less b/less/foundryvtt-reve-de-dragon.less
index f204ceab..975e0224 100644
--- a/less/foundryvtt-reve-de-dragon.less
+++ b/less/foundryvtt-reve-de-dragon.less
@@ -1319,13 +1319,13 @@
justify-content: flex-start;
flex-direction: column;
position: absolute;
- top: 4.6rem;
- left: -19rem;
+ top: 10rem;
+ left: -9rem;
}
.token-hud-ext.soins {
flex-direction: column;
position: absolute;
- top: 14.7rem;
+ top: 15.5rem;
left: -6rem;
max-width: 8rem;
line-height: 1rem;
@@ -1341,14 +1341,18 @@
width: 9rem;
height: fit-content;
border-radius: 0.3rem;
- min-width: 6rem;
+ min-width: 8rem;
flex-basis: auto;
padding: 0;
- line-height: 0.95rem;
+ line-height: 1.6rem;
margin: 0.2rem;
- }
- .rdd-hud-menu label {
- font-size: 0.8rem;
+
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ select, label {
+ font-size: 1rem;
+ }
}
/* ======================================== */
.item-checkbox {
diff --git a/less/roll-chat.less b/less/roll-chat.less
index c5da339c..69eb436e 100644
--- a/less/roll-chat.less
+++ b/less/roll-chat.less
@@ -1,87 +1,86 @@
-.chat-message {
- div.roll-chat {
- font-family: CaslonAntique;
- display: grid;
- grid-template-areas:
- "img header buttons"
- "img resume buttons"
- "details details details"
- "actions actions actions";
- grid-template-columns: 3rem 1fr 1.4rem;
- grid-template-rows: max-content max-content max-content max-content;
- gap: 0 0.5rem;
+.chat-message div.roll-chat,
+.dialog-content div.roll-chat {
+ font-family: CaslonAntique;
+ display: grid;
+ grid-template-areas:
+ "img header buttons"
+ "img resume buttons"
+ "details details details"
+ "actions actions actions";
+ grid-template-columns: 3rem 1fr 1.4rem;
+ grid-template-rows: max-content max-content max-content max-content;
+ gap: 0 0.5rem;
- div.chat-img {
- grid-area: img;
+ div.chat-img {
+ grid-area: img;
+ display: flex;
+ flex-direction: column;
+ img {
+ border: 0;
+ max-height: 3rem;
+ max-width: 3rem;
+ object-fit: contain;
+ height: 100%;
+ }
+ }
+ div.chat-header {
+ grid-area: header;
+ font-weight: bold;
+ font-size: 0.9rem;
+ }
+ div.chat-resume {
+ grid-area: resume;
+ text-align: justify;
+ }
+ div.chat-details {
+ grid-area: details;
+ text-align: justify;
+ display: flex;
+ flex-direction: column;
+ }
+ div.chat-actions {
+ grid-area: actions;
+ display: flex;
+ flex-direction: column;
+ a {
display: flex;
- flex-direction: column;
+ flex-direction: row;
img {
- border: 0;
- max-height: 3rem;
- max-width: 3rem;
- object-fit: contain;
- height: 100%;
+ margin-right: 0.5rem;
}
}
- div.chat-header {
- grid-area: header;
- font-weight: bold;
- font-size: 0.9rem;
- }
- div.chat-resume {
- grid-area: resume;
- text-align: justify;
- }
- div.chat-details {
- grid-area: details;
- text-align: justify;
- display: flex;
- flex-direction: column;
- }
- div.chat-actions {
- grid-area: actions;
- display: flex;
- flex-direction: column;
- a {
- display: flex;
- flex-direction: row;
- img {
- margin-right: 0.5rem;
- }
+ }
+
+ div.chat-buttons {
+ grid-area: buttons;
+ display: flex;
+ flex-direction: column;
+
+ a {
+ border-radius: 0.2rem;
+ cursor: pointer;
+ padding: 0.2rem;
+ position: relative;
+ box-shadow: inset 1x 1px #a6827e;
+ color: var(--color-controls);
+ border: 1px ridge #846109;
+ display: inline-block;
+ align-items: center;
+
+ img {
+ max-width: 1rem;
+ max-height: 1rem;
}
}
- div.chat-buttons {
- grid-area: buttons;
- display: flex;
- flex-direction: column;
-
- a {
- border-radius: 0.2rem;
- cursor: pointer;
- padding: 0.2rem;
- position: relative;
- box-shadow: inset 1x 1px #a6827e;
- color: var(--color-controls);
- border: 1px ridge #846109;
- display: inline-block;
- align-items: center;
-
- img {
- max-width: 1rem;
- max-height: 1rem;
- }
- }
-
- a:hover {
- background: var(--background-custom-button-hover);
- }
-
- a:active{
- position:relative;
- top:1px;
- }
-
+ a:hover {
+ background: var(--background-custom-button-hover);
}
+
+ a:active{
+ position:relative;
+ top:1px;
+ }
+
}
-}
\ No newline at end of file
+}
diff --git a/less/roll-dialog.less b/less/roll-dialog.less
index c5628f3a..ba05a596 100644
--- a/less/roll-dialog.less
+++ b/less/roll-dialog.less
@@ -89,8 +89,12 @@
display: flex;
flex-direction: row;
margin: 0.1rem 0;
+ .warning {
+ border-radius: 6px;
+ background: var(--gradient-warning);
+ }
}
-
+
roll-part-img {
display: flex;
flex-direction: column;
diff --git a/module/achat-vente/chat-vente.js b/module/achat-vente/chat-vente.js
index a921a356..66a0f2a9 100644
--- a/module/achat-vente/chat-vente.js
+++ b/module/achat-vente/chat-vente.js
@@ -1,4 +1,4 @@
-import { SYSTEM_RDD } from "../constants.js";
+import { renderTemplate, SYSTEM_RDD } from "../constants.js";
import { RdDUtility } from "../rdd-utility.js";
const DETAIL_VENTE = 'detailVente';
diff --git a/module/achat-vente/dialog-item-achat.js b/module/achat-vente/dialog-item-achat.js
index 58992d7e..09b686ff 100644
--- a/module/achat-vente/dialog-item-achat.js
+++ b/module/achat-vente/dialog-item-achat.js
@@ -1,3 +1,4 @@
+import { renderTemplate } from "../constants.js";
import { Misc } from "../misc.js";
import { RdDUtility } from "../rdd-utility.js";
import { ChatVente } from "./chat-vente.js";
diff --git a/module/achat-vente/dialog-item-vente.js b/module/achat-vente/dialog-item-vente.js
index 64a2166e..13c3f448 100644
--- a/module/achat-vente/dialog-item-vente.js
+++ b/module/achat-vente/dialog-item-vente.js
@@ -1,3 +1,4 @@
+import { renderTemplate } from "../constants.js";
import { HtmlUtility } from "../html-utility.js";
import { RdDUtility } from "../rdd-utility.js";
import { ChatVente } from "./chat-vente.js";
diff --git a/module/actor-sheet.js b/module/actor-sheet.js
index 1dacbf44..27f658b8 100644
--- a/module/actor-sheet.js
+++ b/module/actor-sheet.js
@@ -3,7 +3,7 @@ import { HtmlUtility } from "./html-utility.js";
import { RdDBonus } from "./rdd-bonus.js";
import { Misc } from "./misc.js";
import { RdDCombatManager } from "./rdd-combat.js";
-import { RdDCarac } from "./rdd-carac.js";
+import { CARACS, RdDCarac } from "./rdd-carac.js";
import { DialogSplitItem } from "./dialog-split-item.js";
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
@@ -174,7 +174,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
await this.getBlessure(event)?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } })
});
- this.html.find('.roll-chance-actuelle').click(async event => await this.actor.rollCarac('chance-actuelle'))
+ this.html.find('.roll-chance-actuelle').click(async event => await this.actor.rollCarac(CARACS.CHANCE_ACTUELLE))
this.html.find('.button-appel-chance').click(async event => await this.actor.rollAppelChance())
this.html.find('[name="jet-astrologie"]').click(async event => await this.actor.astrologieNombresAstraux())
@@ -208,7 +208,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
}
// Points de reve actuel
- this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac('reve-actuel', { resistance: true }))
+ this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac(CARACS.REVE_ACTUEL, { resistance: true }))
this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor)))
this.html.find('.roll-arme').click(async event => {
diff --git a/module/actor-token.mjs b/module/actor-token.mjs
index 465e98e8..8a05ee30 100644
--- a/module/actor-token.mjs
+++ b/module/actor-token.mjs
@@ -2,6 +2,9 @@
* class providing the actor and token, and choosing the name and image from the token if available.
*/
export class ActorToken {
+ static fromTokenActor(token, actor){
+ return token ? ActorToken.fromToken(token) : ActorToken.fromActor(actor)
+ }
static fromActorId(actorId, onError = () => undefined) {
actorId = actorId ?? (canvas.tokens.controlled.length > 0
diff --git a/module/actor.js b/module/actor.js
index e683cdf5..6b0c44e4 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -17,9 +17,9 @@ import { Draconique } from "./tmr/draconique.js";
import { CARACS, LIST_CARAC_PERSONNAGE, RdDCarac } from "./rdd-carac.js";
import { DialogConsommer } from "./dialog-item-consommer.js";
import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js";
-import { RollDataAjustements } from "./rolldata-ajustements.js";
+import { RollDataAjustements } from "./rolldata-ajustements-v1.js";
import { RdDPossession } from "./rdd-possession.js";
-import { ACTOR_TYPES, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
+import { ACTOR_TYPES, renderTemplate, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { RdDConfirm } from "./rdd-confirm.js";
import { DialogRepos } from "./sommeil/dialog-repos.js";
import { RdDBaseActor } from "./actor/base-actor.js";
@@ -47,6 +47,9 @@ import { RdDRollResult } from "./rdd-roll-result.js";
import { RdDInitiative } from "./initiative.mjs";
import RollDialog from "./roll/roll-dialog.mjs";
import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js";
+import { ROLL_TYPE_MEDITATION } from "./roll/roll-constants.mjs";
+import { PART_TACHE } from "./roll/roll-part-tache.mjs";
+import { PART_COMP } from "./roll/roll-part-comp.mjs";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@@ -98,6 +101,8 @@ export class RdDActor extends RdDBaseActorSang {
}
isPersonnage() { return true }
+ isFeminin() { return this.system.sexe.length > 0 && this.system.sexe.charAt(0).toLowerCase() == 'f' }
+
isHautRevant() { return this.system.attributs.hautrevant.value != "" }
/* -------------------------------------------- */
@@ -136,12 +141,12 @@ export class RdDActor extends RdDBaseActorSang {
}
listActions({ isAttaque = false, isEquipe = false }) {
- // Recupération des armes
+ // Recupération des attaques
const actions = this.listActionsAttaque()
.filter(it => !isEquipe || it.arme.system.equipe)
if (!isAttaque && this.system.attributs.hautrevant.value) {
- actions.push({ name: "Draconic", action: 'haut-reve', initOnly: true })
+ actions.push({ label: "Draconic", action: 'haut-reve', initOnly: true })
}
return actions
}
@@ -177,7 +182,7 @@ export class RdDActor extends RdDBaseActorSang {
const actions = []
const uniques = []
- const addAttaque = (arme, main) => {
+ const addAttaque = (arme, main = undefined, action = 'attaque') => {
const dommagesArme = RdDItemArme.valeurMain(arme.system.dommages, main)
const forceRequise = RdDItemArme.valeurMain(arme.system.force ?? 0, main)
const ecaillesEfficacite = arme.system.magique ? arme.system.ecaille_efficacite : 0;
@@ -196,7 +201,7 @@ export class RdDActor extends RdDBaseActorSang {
const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + ecaillesEfficacite
actions.push({
- name: arme.name + (main ? ' ' + main : ''),
+ label: arme.name + (main ? ' ' + main : ''),
action: 'attaque',
initOnly: false,
arme: arme,
@@ -206,22 +211,23 @@ export class RdDActor extends RdDBaseActorSang {
equipe: arme.system.equipe,
dommagesArme: dommagesArme,
forceRequise: forceRequise,
- initiative: RdDInitiative.calculInitiative(niveau, caracValue, ajustement)
+ initiative: RdDInitiative.getRollInitiative(caracValue, niveau, ajustement)
})
}
- addAttaque(RdDItemArme.empoignade(this))
- addAttaque(RdDItemArme.corpsACorps(this))
-
this.itemTypes[ITEM_TYPES.arme]
.filter(it => it.isAttaque())
.sort(Misc.ascending(it => it.name))
.forEach(arme => {
- if (arme.system.unemain && arme.system.competence) { addAttaque(arme, ATTAQUE_TYPE.UNE_MAIN) }
- if (arme.system.deuxmains && arme.system.competence) { addAttaque(arme, ATTAQUE_TYPE.DEUX_MAINS) }
- if (arme.system.lancer) { addAttaque(arme, ATTAQUE_TYPE.LANCER) }
+ if (arme.system.unemain && arme.system.competence && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.UNE_MAIN) }
+ if (arme.system.deuxmains && arme.system.competence && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.DEUX_MAINS) }
+ if (arme.system.lancer && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.LANCER) }
if (arme.system.tir) { addAttaque(arme, ATTAQUE_TYPE.TIR) }
})
+
+ addAttaque(RdDItemArme.pugilat(this), ATTAQUE_TYPE.CORPS_A_CORPS)
+ addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS, 'empoignade')
+
return actions
}
@@ -1342,7 +1348,7 @@ export class RdDActor extends RdDBaseActorSang {
async _apprecierCuisine(item, seForcer) {
const surmonteExotisme = await this._surmonterExotisme(item, seForcer);
if (surmonteExotisme) {
- await this.apprecier('gout', 'cuisine', item.system.qualite, item.system.boisson ? "apprécie la boisson" : "apprécie le plat");
+ await this.apprecier(CARACS.ODORATGOUT, 'cuisine', item.system.qualite, item.system.boisson ? "apprécie la boisson" : "apprécie le plat");
}
else if (seForcer) {
await this.jetDeMoral('malheureux');
@@ -1360,7 +1366,7 @@ export class RdDActor extends RdDBaseActorSang {
if (exotisme < 0 || qualite < 0) {
const competence = qualite > 0 ? 'cuisine' : undefined
const difficulte = Math.min(exotisme, qualite)
- const rolled = await this.doRollCaracCompetence('volonte', competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
+ const rolled = await this.doRollCaracCompetence(CARACS.VOLONTE, competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
return rolled.isSuccess
}
return true;
@@ -1922,6 +1928,20 @@ export class RdDActor extends RdDBaseActorSang {
}
async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
+
+ if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
+ const rollData = {
+ ids: { actorId: this.id },
+ type: { allowed: [PART_COMP], current: PART_COMP },
+ selected: {
+ carac: {key: caracName },
+ comp: { key: compName, forced: options.forced }
+ }
+ }
+ RollDialog.create(rollData, options)
+ return
+ }
+
RdDEmpoignade.checkEmpoignadeEnCours(this)
const competence = this.getCompetence(compName);
await this.openRollDialog({
@@ -1944,23 +1964,34 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async rollTache(id, options = {}) {
+
RdDEmpoignade.checkEmpoignadeEnCours(this)
- const tacheData = this.getTache(id)
- const compData = this.getCompetence(tacheData.system.competence)
- compData.system.defaut_carac = tacheData.system.carac; // Patch !
+ const tache = this.getTache(id)
+ if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
+ const rollData = {
+ ids: { actorId: this.id },
+ selected: { tache: { key: tache.id, forced: options.forced} },
+ type: { allowed: [PART_TACHE], current: PART_TACHE }
+ }
+ RollDialog.create(rollData, options)
+ return
+ }
+
+ const compData = this.getCompetence(tache.system.competence)
+ compData.system.defaut_carac = tache.system.carac; // Patch !
await this.openRollDialog({
name: 'jet-competence',
- label: 'Jet de Tâche ' + tacheData.name,
+ label: 'Jet de Tâche ' + tache.name,
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs',
rollData: {
competence: compData,
- tache: tacheData,
- diffLibre: tacheData.system.difficulte,
+ tache: tache,
+ diffLibre: tache.system.difficulte,
diffConditions: 0,
use: { libre: false, conditions: true },
carac: {
- [tacheData.system.carac]: foundry.utils.duplicate(this.system.carac[tacheData.system.carac])
+ [tache.system.carac]: foundry.utils.duplicate(this.system.carac[tache.system.carac])
}
},
callbacks: [{ action: r => this._tacheResult(r, options) }]
@@ -2014,6 +2045,17 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */
async rollMeditation(id) {
const meditation = foundry.utils.duplicate(this.getMeditation(id));
+
+ if (meditation && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
+ const rollData = {
+ ids: { actorId: this.id },
+ selected: { meditation: { key: id } },
+ type: { allowed: [ROLL_TYPE_MEDITATION], current: ROLL_TYPE_MEDITATION }
+ }
+ await RollDialog.create(rollData)
+ return
+ }
+
const competence = foundry.utils.duplicate(this.getCompetence(meditation.system.competence));
competence.system.defaut_carac = "intellect"; // Meditation = toujours avec intellect
let meditationData = {
@@ -2414,14 +2456,17 @@ export class RdDActor extends RdDBaseActorSang {
if (!blessure.system.premierssoins.done) {
const tache = await this.getTacheBlessure(blesse, blessure);
return await this.rollTache(tache.id, {
- onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r)
+ onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r),
+ title: 'Premiers soins',
+ forced: true
});
}
- if (!blessure.system.soinscomplets.done) {
+ else if (!blessure.system.soinscomplets.done) {
const diff = blessure.system.difficulte + (blessure.system.premierssoins.bonus ?? 0);
- return await this.rollCaracCompetence("dexterite", "Chirurgie", diff, {
+ return await this.rollCaracCompetence(CARACS.DEXTERITE, "Chirurgie", diff, {
title: "Soins complets",
- onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r)
+ onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r),
+ forced: true
})
}
}
@@ -2436,6 +2481,7 @@ export class RdDActor extends RdDBaseActorSang {
})
}
const blessure = this.getItem(blessureId, 'blessure')
+
if (blessure && !blessure.system.premierssoins.done) {
const tache = rollData.tache;
if (rollData.rolled.isETotal) {
@@ -2916,7 +2962,9 @@ export class RdDActor extends RdDBaseActorSang {
break
case ITEM_TYPES.race:
await this.onCreateOwnedRace(item, options, id)
+ break
}
+ await super.onCreateItem(item, options, id)
await item.onCreateItemTemporel(this);
await item.onCreateDecoupeComestible(this);
}
@@ -3062,12 +3110,7 @@ export class RdDActor extends RdDBaseActorSang {
actorId: this.id
}
}
- await RollDialog.create(rollData, {
- onRollDone: (dialog) => {
- if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
- dialog.close()
- }
- })
+ await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
}
/* -------------------------------------------- */
diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js
index 9207ade4..5e548843 100644
--- a/module/actor/base-actor-reve.js
+++ b/module/actor/base-actor-reve.js
@@ -1,4 +1,4 @@
-import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
+import { ENTITE_INCARNE, renderTemplate, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
import { Grammar } from "../grammar.js";
import { Misc } from "../misc.js";
import { RdDResolutionTable } from "../rdd-resolution-table.js";
@@ -11,7 +11,7 @@ import { ITEM_TYPES } from "../constants.js";
import { StatusEffects, STATUSES } from "../settings/status-effects.js";
import { Targets } from "../targets.js";
import { RdDConfirm } from "../rdd-confirm.js";
-import { RdDCarac } from "../rdd-carac.js";
+import { CARACS, RdDCarac } from "../rdd-carac.js";
import { RdDRollResult } from "../rdd-roll-result.js";
import { RdDItemArme } from "../item/arme.js";
@@ -23,8 +23,12 @@ import { RdDCombat } from "../rdd-combat.js";
import { RdDEmpoignade } from "../rdd-empoignade.js";
import { RdDPossession } from "../rdd-possession.js";
import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, POSSESSION_SANS_DRACONIC } from "../item/base-items.js";
-import { RollDataAjustements } from "../rolldata-ajustements.js";
+import { RollDataAjustements } from "../rolldata-ajustements-v1.js";
import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs";
+import RollDialog from "../roll/roll-dialog.mjs";
+import { ATTAQUE_ROLL_TYPES, DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP, ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE } from "../roll/roll-constants.mjs";
+import { OptionsAvancees, ROLL_DIALOG_V2 } from "../settings/options-avancees.js";
+import { PART_COMP } from "../roll/roll-part-comp.mjs";
/**
* Classe de base pour les acteurs disposant de rêve (donc, pas des objets)
@@ -377,9 +381,22 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
/* -------------------------------------------- */
async rollCarac(caracName, options = {}) {
- if (Grammar.equalsInsensitive(caracName, 'taille')) {
+ if (Grammar.equalsInsensitive(caracName, CARACS.TAILLE)) {
return
}
+ if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
+ const rollData = {
+ ids: { actorId: this.id },
+ type: { allowed: [PART_COMP], current: PART_COMP },
+ selected: {
+ carac: { key: caracName },
+ comp: options.resistance ? { key: undefined, forced: true } : undefined
+ }
+ }
+ RollDialog.create(rollData, options)
+ return
+ }
+
foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false })
RdDEmpoignade.checkEmpoignadeEnCours(this)
let selectedCarac = this.getCaracByName(caracName)
@@ -407,9 +424,33 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
/* -------------------------------------------- */
+ async rollCompetenceV2(rollData) {
+ rollData.ids = rollData?.ids ?? {}
+ rollData.type = rollData.type ?? { allowed: DEFAULT_ROLL_TYPES }
+ rollData.ids.actorId = this.id
+ await RollDialog.create(rollData)
+ }
+
async rollCompetence(idOrName, options = { tryTarget: true, arme: undefined }) {
RdDEmpoignade.checkEmpoignadeEnCours(this)
+
const competence = this.getCompetence(idOrName);
+ if (competence.type != ITEM_TYPES.competencecreature && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
+ const rollData = {
+ selected: {
+ comp: { key: competence.name },
+ diff: { type: DIFF.LIBRE, value: competence.system.default_diffLibre ?? 0 }
+ }
+ }
+ if (options.arme) {
+ rollData.selected.attaque = { arme: { id: options.arme.id }, comp: { id: competence.id } }
+ rollData.type = { allowed: ATTAQUE_ROLL_TYPES }
+ }
+
+ await this.rollCompetenceV2(rollData)
+ return
+ }
+
let rollData = {
carac: this.system.carac,
competence: competence,
@@ -427,7 +468,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme)
}
});
- return;
+ return
}
// Transformer la competence de créature
MappingCreatureArme.setRollDataCreature(rollData)
@@ -449,6 +490,46 @@ export class RdDBaseActorReve extends RdDBaseActor {
}
}
+ rollAttaque(token) {
+ token = token ?? RdDUtility.getSelectedToken(this)
+
+ if (Targets.hasTargets()) {
+ Targets.selectOneTargetToken(target => {
+ if (Targets.isTargetEntite(target)) {
+ ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée!!!!`)
+ return
+ }
+
+ RdDCombat.rddCombatTarget(target, this, token).attaqueV2();
+ })
+ }
+ else {
+ return RdDConfirm.confirmer({
+ settingConfirmer: "confirmer-combat-sans-cible",
+ content: `
`)
- game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined)
+ game.messages.filter(m => ChatUtility.getMessageData(m, 'rollData') != undefined && ChatUtility.getMessageData(m, 'rollData') != undefined)
.forEach(it => it.delete())
RdDEmpoignade.deleteAllEmpoignades()
}
@@ -106,14 +107,18 @@ export class RdDCombatManager extends Combat {
return combatant.actor
}
- static calculAjustementInit(actor, arme) {
- const efficacite = (arme?.system.magique) ? arme.system.ecaille_efficacite : 0
- const etatGeneral = actor.getEtatGeneral() ?? 0
- return efficacite + etatGeneral
-
+ static bonusArme(arme) {
+ return (arme?.system.magique) ? arme.system.ecaille_efficacite : 0
}
- /************************************************************************************/
+ static etatGeneral(actor) {
+ return actor.getEtatGeneral() ?? 0;
+ }
+
+
+ /** ***********************************************************************************
+ * @override lance l'initiative de plusieurs combattants (tous/ous les PNJs) en une fois
+ */
async rollInitiative(ids, messageOptions = {}) {
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, messageOptions)
ids = typeof ids === "string" ? [ids] : ids
@@ -121,18 +126,17 @@ export class RdDCombatManager extends Combat {
return this
}
- async rollInitRdD(id, formula, messageOptions = {}) {
+ async rollInitRdD(id, formule, messageOptions = {}) {
const combatant = this.combatants.get(id);
const actor = RdDCombatManager.getActorCombatant(combatant)
if (actor) {
- const rollFormula = formula ?? RdDCombatManager.getFirstInitRollFormula(actor)
- const roll = combatant.getInitiativeRoll(rollFormula);
- if (!roll.total) {
- await roll.evaluate();
- }
- const total = Math.max(roll.total, 0.00);
- console.log("Compute init for", rollFormula, roll, total, combatant);
- await this.updateEmbeddedDocuments("Combatant", [{ _id: combatant._id || combatant.id, initiative: total }]);
+ formule = formule ?? RdDCombatManager.getFirstInitRollFormula(actor)
+ const init = await RdDInitiative.roll(formule)
+
+ await this.updateEmbeddedDocuments("Combatant", [{
+ _id: combatant._id || combatant.id,
+ initiative: init.init, 'system.init': init
+ }])
// Send a chat message
let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode");
@@ -144,10 +148,10 @@ export class RdDCombatManager extends Combat {
alias: combatant.token?.name,
sound: CONFIG.sounds.dice,
},
- flavor: `${combatant.token?.name} a fait son jet d'Initiative (${messageOptions.info})
`
+ flavor: `${combatant.token?.name} a une initiatyive de ${init.value} : ${messageOptions.info}
`
},
messageOptions);
- roll.toMessage(messageData, { rollMode, create: true });
+ init.roll.toMessage(messageData, { rollMode, create: true });
RdDCombatManager.processPremierRoundInit();
}
@@ -159,16 +163,11 @@ export class RdDCombatManager extends Combat {
if (actions.length > 0) {
const action = actions[0]
const init = RdDCombatManager.getInitData(actor, action)
- const ajustement = RdDCombatManager.calculAjustementInit(actor, action)
- return RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
+ const ajustement = RdDCombatManager.bonusArme(action.arme) + RdDCombatManager.etatGeneral(actor)
+ return RdDInitiative.formule(init.phase, init.carac, init.niveau, ajustement);
}
- let ajustement = RdDCombatManager.calculAjustementInit(actor, undefined);
- return RdDCombatManager.formuleInitiative(2, 10, 0, ajustement);
- }
-
- static formuleInitiative(rang, carac, niveau, bonusMalus) {
- return `${rang} +( (${RdDInitiative.calculInitiative(niveau, carac, bonusMalus)} )/100)`;
+ return RdDInitiative.formule(MAP_PHASE['autre'], 10, 0, actor.getEtatGeneral() ?? 0);
}
/* -------------------------------------------- */
@@ -180,7 +179,6 @@ export class RdDCombatManager extends Combat {
for (let combatant of game.combat.combatants) {
if (combatant.initiativeData?.arme?.type == "arme") {
// TODO: get init data premier round
- const initiativeData = combatant.initiativeData;
const action = combatant.initiativeData.arme;
const fromArme = Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround)
const initData = premierRoundInit.find(it => fromArme.includes(initData.pattern))
@@ -200,10 +198,27 @@ export class RdDCombatManager extends Combat {
}
/* -------------------------------------------- */
- static incDecInit(combatantId, incDecValue) {
- const combatant = game.combat.combatants.get(combatantId);
- let initValue = combatant.initiative + incDecValue;
- game.combat.setInitiative(combatantId, initValue);
+
+ static applyInitiativeCommand(combatantId, command, commandValue) {
+ switch (command) {
+ case 'delta': return RdDCombatManager.incDecInit(combatantId, commandValue);
+ case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
+ { name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
+ }
+ }
+
+ static async incDecInit(combatantId, incDecValue) {
+ const combatant = game.combat.combatants.get(combatantId)
+ if (combatant?.initiative && incDecValue != 0) {
+ const value = combatant.system.init.value + incDecValue
+ const newInit = combatant.initiative + incDecValue / 100;
+ await game.combat.updateEmbeddedDocuments("Combatant", [{
+ _id: combatantId,
+ initiative: newInit,
+ 'system.init.value': value,
+ 'system.init.init': newInit,
+ }])
+ }
}
/* -------------------------------------------- */
@@ -220,56 +235,42 @@ export class RdDCombatManager extends Combat {
}
}
options = [
- { name: "Incrémenter initiative", condition: true, icon: '
', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +0.01); } },
- { name: "Décrémenter initiative", condition: true, icon: '
', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -0.01); } }
+ { name: "Incrémenter initiative", condition: true, icon: '
', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +1); } },
+ { name: "Décrémenter initiative", condition: true, icon: '
', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -1); } }
].concat(options);
}
+
/* -------------------------------------------- */
static async rollInitiativeAction(combatantId, action) {
const combatant = game.combat.combatants.get(combatantId)
const actor = RdDCombatManager.getActorCombatant(combatant)
- if (actor == undefined) { return [] }
- combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0
+ if (actor == undefined) { return }
const init = RdDCombatManager.getInitData(actor, action)
- const ajustement = RdDCombatManager.calculAjustementInit(actor, action.arme)
- const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
+ const ajustement = RdDCombatManager.bonusArme(actor, action.arme) + RdDCombatManager.etatGeneral(actor)
+ const formule = RdDInitiative.formule(init.phase, init.carac, init.niveau, ajustement);
- await game.combat.rollInitRdD(combatantId, rollFormula, init);
- combatant.initiativeData
+ await game.combat.rollInitRdD(combatantId, formule, init);
+ combatant.initiativeData = { action, formule } // pour reclasser l'init au round 0
}
static getInitData(actor, action) {
- if (actor.getSurprise() == "totale") { return { offset: -1, info: "Surprise Totale", carac: 0, niveau: 0 } }
- if (actor.getSurprise() == "demi") { return { offset: 0, info: "Demi Surprise", carac: 0, niveau: 0 } }
- if (action.action == 'autre') { return { offset: 2, info: "Autre Action", carac: 0, niveau: 0 } }
- if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } }
- if (action.action == 'haut-reve') { return { offset: 9, info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } }
+ if (actor.getSurprise() == "totale") { return { phase: MAP_PHASE['totale'], info: "Surprise Totale", carac: 0, niveau: 0 } }
+ if (actor.getSurprise() == "demi") { return { phase: MAP_PHASE['demi'], info: "Demi Surprise", carac: 0, niveau: 0 } }
+ if (action.action == 'autre') { return { phase: MAP_PHASE['autre'], info: "Autre Action", carac: 0, niveau: 0 } }
+ if (action.action == 'possession') { return { phase: MAP_PHASE['possession'], info: "Possession", carac: actor.getReveActuel(), niveau: 0 } }
+ if (action.action == 'haut-reve') { return { phase: MAP_PHASE['draconic'], info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } }
const comp = action.comp
return {
- offset: RdDCombatManager.initOffset(comp?.system.categorie, action.arme),
- info: action.name + " / " + comp.name,
+ phase: RdDInitiative.phaseArme(comp?.system.categorie, action.arme),
+ info: action.label,
carac: actor.getCaracInit(comp),
niveau: comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(action.main) ? -8 : -6)
}
}
- static initOffset(categorie, arme) {
- switch (categorie) {
- case "tir": return 8
- case "lancer": return 7
- default:
- switch (arme.system.cac) {
- case "empoignade": return 3
- case "pugilat": return 4
- case "naturelle": return 4
- default: return 5
- }
- }
- }
-
/* -------------------------------------------- */
static displayInitiativeMenu(html, combatantId) {
const combatant = game.combat.combatants.get(combatantId)
@@ -297,13 +298,8 @@ export class RdDCombatManager extends Combat {
? possessions
: actor.listActions({ isEquipe: true })
- for (let index = 0; index < actions.length; index++) {
- actions[index].index = index
- }
- return actions
+ return Misc.indexed(actions)
}
-
-
}
/* -------------------------------------------- */
@@ -383,8 +379,13 @@ export class RdDCombat {
let defenderToken = canvas.tokens.get(msg.defenderToken.id)
if (defenderToken && Misc.isFirstConnectedGM()) {
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id)
- rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme)
- rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll)
+ rddCombat?.removeChatMessageActionsPasseArme(msg.paramChatDefense.attackerRoll.passeArme)
+ if (msg.defenderRoll.ids) {/* TODO: delete roll V1 */
+ RollDialog.loadRollData(msg.paramChatDefense)
+ rddCombat?._chatMessageDefenseV2(msg.paramChatDefense)
+ } else {
+ rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll)
+ }
}
}
@@ -464,8 +465,8 @@ export class RdDCombat {
/* -------------------------------------------- */
async onEvent(button, event) {
const chatMessage = ChatUtility.getChatMessage(event);
- const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll');
- const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll');
+ const defenderRoll = ChatUtility.getMessageData(chatMessage, 'rollData');
+ const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'rollData');
console.log('RdDCombat', attackerRoll, defenderRoll);
const armeParadeId = event.currentTarget.attributes['data-armeid']?.value;
@@ -665,12 +666,101 @@ export class RdDCombat {
return { msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3 };
}
+
+ async attaqueV2() {
+ if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
+ return
+ }
+ await this.doRollAttaque({
+ ids: {
+ actorId: this.attackerId,
+ actorTokenId: this.attackerTokenId,
+ opponentId: this.defender.id,
+ opponentTokenId: this.defenderTokenId,
+ },
+ type: { allowed: ['attaque'], current: 'attaque' },
+ passeArme: foundry.utils.randomID(16),
+ })
+ }
+
+ async doRollAttaque(rollData, callbacks = []) {
+ // TODO V2 await this.proposerAjustementTirLancer(rollData)
+ await RollDialog.create(rollData, {
+ onRollDone: (dialog) => {
+ if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
+ dialog.close()
+ },
+ customChatMessage: true,
+ callbacks: [
+ async (roll) => await this.onAttaqueV2(roll),
+ ...callbacks
+ ]
+ })
+ }
+
+ async onAttaqueV2(attackerRoll) {
+ if (!this.defender || !attackerRoll.rolled.isSuccess || attackerRoll.particulieres?.length > 1) {
+ return
+ }
+ if (!await this.attacker.accorder(this.defender, 'avant-defense')) {
+ return;
+ }
+
+ RollDialog.loadRollData(attackerRoll)
+
+ const surpriseDefender = this.defender.getSurprise(true);
+ const paramChatDefense = {
+ attackerRoll: attackerRoll,
+ isPossession: this.isPossession(attackerRoll),
+ defender: this.defender,
+ attacker: this.attacker,
+ attackerId: this.attackerId,
+ attackerToken: this.attackerToken,
+ defenderToken: this.defenderToken,
+ surprise: surpriseDefender,
+ }
+
+ if (Misc.isFirstConnectedGM()) {
+ await this._chatMessageDefenseV2(paramChatDefense);
+ }
+ else {
+ this._socketSendMessageDefense(paramChatDefense, {});
+ }
+ }
+ async _chatMessageDefenseV2(paramDemandeDefense) {
+ const attackerRoll = paramDemandeDefense.attackerRoll;
+ RollBasicParts.loadSurprises(attackerRoll)
+ attackerRoll.passeArme = attackerRoll.passeArme ?? foundry.utils.randomID(16)
+ attackerRoll.dmg = RdDBonus.dmgRollV2(attackerRoll, attackerRoll.current.attaque)
+ // attackerRoll.current.attaque.dmg = attackerRoll.dmg
+ // attaque.dmg = attackerRoll.current.attaque.dmg
+ const attaque = RollDialog.saveParts(attackerRoll)
+ const defense = {
+ attackerRoll: attaque,
+ ids: RollBasicParts.reverseIds(attaque),
+ passeArme: attaque.passeArme ?? foundry.utils.randomID(16)
+ }
+
+ const choixDefense = await ChatMessage.create({
+ // message privé: du défenseur à lui même (et aux GMs)
+ speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
+ alias: this.attacker?.getAlias(),
+ whisper: ChatUtility.getOwners(this.defender),
+ content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', attackerRoll)
+ });
+ // flag pour garder les jets d'attaque/defense
+ ChatUtility.setMessageData(choixDefense, 'rollData', defense)
+ }
+
/* -------------------------------------------- */
async attaque(competence, arme) {
if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
return
}
- if (arme.system.cac == 'empoignade') {
+ if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
+ return this.attacker.rollCompetence(competence.name, { arme: arme })
+ }
+ if (arme.system.cac == EMPOIGNADE) {
RdDEmpoignade.onAttaqueEmpoignade(this.attacker, this.defender)
return
}
@@ -723,9 +813,9 @@ export class RdDCombat {
}
else {
// sans armes: à mains nues
- rollData.arme = RdDItemArme.corpsACorps(this.attacker)
+ rollData.arme = RdDItemArme.pugilat(this.attacker)
rollData.arme.system.niveau = competence.system.niveau
- rollData.arme.system.initiative = RdDInitiative.calculInitiative(competence.system.niveau, this.attacker.system.carac['melee'].value);
+ rollData.arme.system.initiative = RdDInitiative.getRollInitiative(this.attacker.system.carac['melee'].value, competence.system.niveau);
}
return rollData;
}
@@ -776,7 +866,7 @@ export class RdDCombat {
passeArme: rollData.passeArme
})
});
- ChatUtility.setMessageData(choixParticuliere, 'attacker-roll', rollData);
+ ChatUtility.setMessageData(choixParticuliere, 'rollData', rollData);
}
/* -------------------------------------------- */
@@ -852,10 +942,10 @@ export class RdDCombat {
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
alias: this.attacker?.getAlias(),
whisper: ChatUtility.getOwners(this.defender),
- content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', paramDemandeDefense),
+ content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense-v1.hbs', paramDemandeDefense),
});
// flag pour garder les jets d'attaque/defense
- ChatUtility.setMessageData(choixDefense, 'defender-roll', defenderRoll);
+ ChatUtility.setMessageData(choixDefense, 'rollData', defenderRoll);
}
/* -------------------------------------------- */
@@ -869,7 +959,7 @@ export class RdDCombat {
defenderToken: this.defenderToken,
defenderRoll: defenderRoll,
paramChatDefense: paramChatDefense,
- rollMode: true
+ rollMode: true,
}
});
}
@@ -906,7 +996,7 @@ export class RdDCombat {
essais: attackerRoll.essais
})
});
- ChatUtility.setMessageData(choixEchecTotal, 'attacker-roll', attackerRoll);
+ ChatUtility.setMessageData(choixEchecTotal, 'rollData', attackerRoll);
}
/* -------------------------------------------- */
@@ -968,6 +1058,7 @@ export class RdDCombat {
async defenseV2(attackerRoll) {
// this._prepareParade(attackerRoll, arme, competence);
+ RollDialog.loadRollData(attackerRoll)
await this.doRollDefense({
ids: {
actorId: this.defender.id,
@@ -975,7 +1066,7 @@ export class RdDCombat {
opponentTokenId: this.attackerTokenId,
opponentId: this.attackerId,
},
- type: { allowed: ['defense'], current: 'defense' },
+ type: { allowed: [ROLL_TYPE_DEFENSE], current: ROLL_TYPE_DEFENSE },
attackerRoll: RollDialogAdapter.mapActionAttaque(attackerRoll),
passeArme: attackerRoll.passeArme,
})
@@ -983,10 +1074,7 @@ export class RdDCombat {
async doRollDefense(rollData, callbacks = []) {
await RollDialog.create(rollData, {
- onRollDone: (dialog) => {
- if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
- dialog.close()
- },
+ onRollDone: RollDialog.onRollDoneClose,
customChatMessage: true,
callbacks: [
async (roll) => {
@@ -1034,22 +1122,17 @@ export class RdDCombat {
if (RdDCombat.isReussite(rollData)) {
if (isParade) {
await this.computeDeteriorationArme(rollData)
+ if (RdDCombat.isParticuliere(rollData)) {
+ await this.infoAttaquantDesarme(rollData)
+ }
}
- if (RdDCombat.isParticuliere(rollData)) {
- await this._onDefenseParticuliere(rollData, isEsquive)
- }
}
this.removeChatMessageActionsPasseArme(rollData.passeArme)
}
- async _onDefenseParticuliere(rollData, isEsquive) {
- if (isEsquive) {
- ChatUtility.createChatWithRollMode(
- { content: "
Vous pouvez esquiver une deuxième fois! " },
- this.defender)
- }
- else if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) {
+ async infoAttaquantDesarme(rollData) {
+ if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) {
// TODO: attaquant doit jouer résistance et peut être désarmé p132
ChatUtility.createChatWithRollMode(
{ content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` },
diff --git a/module/rdd-commands.js b/module/rdd-commands.js
index 158bc946..762f8d23 100644
--- a/module/rdd-commands.js
+++ b/module/rdd-commands.js
@@ -19,6 +19,7 @@ import { TMRUtility } from "./tmr-utility.js";
import { DialogFatigueVoyage } from "./voyage/dialog-fatigue-voyage.js";
import { ChatUtility } from "./chat-utility.js";
import { RdDRollResult } from "./rdd-roll-result.js";
+import { renderTemplate } from "./constants.js";
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
diff --git a/module/rdd-empoignade.js b/module/rdd-empoignade.js
index f7fce4a0..475c6147 100644
--- a/module/rdd-empoignade.js
+++ b/module/rdd-empoignade.js
@@ -1,5 +1,5 @@
import { STATUSES } from "./settings/status-effects.js";
-import { ITEM_TYPES } from "./constants.js";
+import { ITEM_TYPES, renderTemplate } from "./constants.js";
import { ChatUtility } from "./chat-utility.js";
import { RdDRollResult } from "./rdd-roll-result.js";
import { RdDRoll } from "./rdd-roll.js";
diff --git a/module/rdd-hotbar-drop.js b/module/rdd-hotbar-drop.js
index 84e004c6..5ee0087f 100644
--- a/module/rdd-hotbar-drop.js
+++ b/module/rdd-hotbar-drop.js
@@ -1,4 +1,4 @@
-import { ATTAQUE_TYPE, RdDItemArme } from "./item/arme.js";
+import { ATTAQUE_TYPE, EMPOIGNADE, PUGILAT, RdDItemArme } from "./item/arme.js";
import { ITEM_TYPES } from "./constants.js";
export class RdDHotbar {
@@ -28,8 +28,8 @@ export class RdDHotbar {
return ' ' + maniement
case 'tir': return ' (tir)';
case 'lancer': return ' (lancer)';
- case 'pugilat': return ' (pugilat)';
- case 'empoignade': return ' (empoignade)';
+ case PUGILAT: return ' (pugilat)';
+ case EMPOIGNADE: return ' (empoignade)';
}
return ''
}
@@ -63,8 +63,8 @@ export class RdDHotbar {
case ITEM_TYPES.competence:
await this.createItemMacro(item, slot++, 'competence')
if (item.isCorpsACorps()) {
- await this.createItemMacro(item, slot++, 'pugilat')
- await this.createItemMacro(item, slot++, 'empoignade')
+ await this.createItemMacro(item, slot++, PUGILAT)
+ await this.createItemMacro(item, slot++, EMPOIGNADE)
}
else if (item.isCompetenceArme()) {
ui.notifications.info(`${item.name} est une compétence d'arme, la macro n'est pas liée à un arme.
@@ -121,9 +121,9 @@ export class RdDHotbar {
case ITEM_TYPES.competence:
if (item.isCorpsACorps()) {
switch (categorieArme) {
- case 'pugilat':
- return actor.rollArme(RdDItemArme.corpsACorps(actor));
- case 'empoignade':
+ case PUGILAT:
+ return actor.rollArme(RdDItemArme.pugilat(actor));
+ case EMPOIGNADE:
return actor.rollArme(RdDItemArme.empoignade(actor));
}
}
diff --git a/module/rdd-meteo.js b/module/rdd-meteo.js
index e3512f22..d1cfb738 100644
--- a/module/rdd-meteo.js
+++ b/module/rdd-meteo.js
@@ -1,4 +1,5 @@
import { ChatUtility } from "./chat-utility.js"
+import { renderTemplate } from "./constants.js"
const vents = [
{ min: 0, max: 0, valeur: 'Calme' },
diff --git a/module/rdd-namegen.js b/module/rdd-namegen.js
index f0768cf7..9429e6fe 100644
--- a/module/rdd-namegen.js
+++ b/module/rdd-namegen.js
@@ -1,5 +1,6 @@
import { RdDBaseActor } from "./actor/base-actor.js";
import { ChatUtility } from "./chat-utility.js";
+import { renderTemplate } from "./constants.js";
import { Misc } from "./misc.js";
import { RdDDice } from "./rdd-dice.js";
diff --git a/module/rdd-resolution-table.js b/module/rdd-resolution-table.js
index 99d51688..18c7545f 100644
--- a/module/rdd-resolution-table.js
+++ b/module/rdd-resolution-table.js
@@ -1,3 +1,4 @@
+import { renderTemplate } from "./constants.js";
import { Misc } from "./misc.js";
import { RdDDice } from "./rdd-dice.js";
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
@@ -66,9 +67,9 @@ export class RdDResolutionTable {
}
/* -------------------------------------------- */
- static _computeCell(niveau, percentage) {
+ static _computeCell(level, percentage) {
return {
- niveau: niveau,
+ level: level,
score: percentage,
norm: Math.min(99, percentage),
sign: this._reussiteSignificative(percentage),
@@ -188,7 +189,7 @@ export class RdDResolutionTable {
static computeReussite(chances, roll, diviseur) {
const reussite = reussites.find(x => x.condition(chances, roll))
if (diviseur > 1 && reussite.isSuccess) {
- if (chances > roll * diviseur) {
+ if (chances.norm < roll * diviseur) {
return reussiteInsuffisante
}
}
@@ -236,7 +237,7 @@ export class RdDResolutionTable {
maxCarac = Math.min(maxCarac, minCarac + 20);
minLevel = Math.max(minLevel, -10);
maxLevel = Math.max(Math.min(maxLevel, 30), minLevel + colonnes);
- return await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', {
+ return await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', {
carac: carac,
difficulte: level,
min: minLevel,
diff --git a/module/rdd-roll-encaisser.js b/module/rdd-roll-encaisser.js
index e11b3a23..058c93ff 100644
--- a/module/rdd-roll-encaisser.js
+++ b/module/rdd-roll-encaisser.js
@@ -1,4 +1,4 @@
-import { ENTITE_BLURETTE, ENTITE_INCARNE } from "./constants.js";
+import { ENTITE_BLURETTE, ENTITE_INCARNE, renderTemplate } from "./constants.js";
import { RdDUtility } from "./rdd-utility.js";
/**
diff --git a/module/rdd-roll-resolution-table.js b/module/rdd-roll-resolution-table.js
index 6901c523..337a9568 100644
--- a/module/rdd-roll-resolution-table.js
+++ b/module/rdd-roll-resolution-table.js
@@ -1,5 +1,7 @@
+import { renderTemplate } from "./constants.js";
import { Misc } from "./misc.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
+import { RdDRollResult } from "./rdd-roll-result.js";
const titleTableDeResolution = 'Table de résolution';
/**
@@ -98,14 +100,14 @@ export class RdDRollResolutionTable extends Dialog {
async onLancer() {
await RdDResolutionTable.rollData(this.rollData);
console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled);
- await RdDResolutionTable.displayRollData(this.rollData);
+ await RdDRollResult.displayRollData(this.rollData);
}
/* -------------------------------------------- */
async onLancerFermer() {
await RdDResolutionTable.rollData(this.rollData);
console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled);
- await RdDResolutionTable.displayRollData(this.rollData);
+ await RdDRollResult.displayRollData(this.rollData);
}
/* -------------------------------------------- */
diff --git a/module/rdd-roll-result.js b/module/rdd-roll-result.js
index 3087ff2f..2495e366 100644
--- a/module/rdd-roll-result.js
+++ b/module/rdd-roll-result.js
@@ -1,4 +1,5 @@
import { ChatUtility } from "./chat-utility.js";
+import { renderTemplate } from "./constants.js";
export class RdDRollResult {
@@ -13,6 +14,6 @@ export class RdDRollResult {
static async buildRollDataHtml(rollData, template = 'chat-resultat-general.hbs') {
rollData.show = rollData.show || {};
- return await foundry.applications.handlebars.renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
+ return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
}
}
diff --git a/module/rdd-roll.js b/module/rdd-roll.js
index 7ae8900d..65c08de6 100644
--- a/module/rdd-roll.js
+++ b/module/rdd-roll.js
@@ -1,4 +1,4 @@
-import { RollDataAjustements } from "./rolldata-ajustements.js";
+import { RollDataAjustements } from "./rolldata-ajustements-v1.js";
import { HtmlUtility } from "./html-utility.js";
import { RdDItemCompetence } from "./item-competence.js";
import { RdDItemSort } from "./item-sort.js";
@@ -8,8 +8,8 @@ import { RdDCarac } from "./rdd-carac.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
import { Grammar } from "./grammar.js";
-import { ACTOR_TYPES } from "./constants.js";
-import { RdDUtility } from "./rdd-utility.js";
+import { ACTOR_TYPES, renderTemplate } from "./constants.js";
+import { EMPOIGNADE } from "./item/arme.js";
/**
* Extend the base Dialog entity to select roll parameters
@@ -23,7 +23,7 @@ export class RdDRoll extends Dialog {
RdDRoll._ensureCorrectAction(action);
RdDRoll._setDefaultOptions(actor, rollData);
- const html = await foundry.applications.handlebars.renderTemplate(dialogConfig.html, rollData);
+ const html = await renderTemplate(dialogConfig.html, rollData);
let options = { classes: ["rdd-roll-dialog"], width: 650, height: 'fit-content', 'z-index': 99999, close: html => { } };
if (dialogConfig.close) {
@@ -334,10 +334,8 @@ export class RdDRoll extends Dialog {
// Mise à jour valeurs
this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
this.html.find("input.check-mortalite").prop('checked', rollData.dmg.mortalite == 'non-mortel');
- this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == 'empoignade' ? 'empoignade' : Misc.toSignedString(rollData.dmg.total));
+ this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == EMPOIGNADE ? EMPOIGNADE : Misc.toSignedString(rollData.dmg.total));
this.html.find("label.arme-mortalite").text(rollData.dmg.mortalite);
- // this.html.find("[name='dmg-arme-actor']").text(rollData.dmg.mortalite == 'empoignade'? 'empoignade': Misc.toSignedString(rollData.dmg.total) );
- // this.html.find("[name='arme-mortalite']").text(rollData.dmg.mortalite);
this.html.find("div.placeholder-ajustements").empty().append(adjustements);
this.html.find("div.placeholder-resolution").empty().append(resolutionTable)
}
@@ -345,7 +343,7 @@ export class RdDRoll extends Dialog {
/* -------------------------------------------- */
async buildAjustements(rollData) {
- return await foundry.applications.handlebars.renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs`, rollData);
+ return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs`, rollData);
}
/* -------------------------------------------- */
diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js
index dbf635f5..fbc88b7f 100644
--- a/module/rdd-tmr-dialog.js
+++ b/module/rdd-tmr-dialog.js
@@ -1,5 +1,5 @@
-import { SHOW_DICE, SYSTEM_RDD } from "./constants.js";
-import { RollDataAjustements } from "./rolldata-ajustements.js";
+import { renderTemplate, SHOW_DICE, SYSTEM_RDD } from "./constants.js";
+import { RollDataAjustements } from "./rolldata-ajustements-v1.js";
import { RdDUtility } from "./rdd-utility.js";
import { COORD_TMR_INCONNU, TMRUtility } from "./tmr-utility.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
@@ -47,7 +47,7 @@ export class RdDTMRDialog extends Dialog {
static async create(actor, tmrData) {
await PixiTMR.init()
- let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.hbs', tmrData);
+ let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.hbs', tmrData);
if (tmrData.mode != 'visu' && !game.user.isGM) {
ChatMessage.create({ content: actor.name + " est monté dans les TMR en mode : " + tmrData.mode, whisper: ChatUtility.getGMs() });
}
@@ -508,7 +508,7 @@ export class RdDTMRDialog extends Dialog {
ChatMessage.create({
whisper: ChatUtility.getOwners(this.actor),
- content: await foundry.applications.handlebars.renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.hbs`, rencData)
+ content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.hbs`, rencData)
});
this.$updateValuesDisplay();
diff --git a/module/rdd-token-hud.js b/module/rdd-token-hud.js
index 83553c8f..f9612726 100644
--- a/module/rdd-token-hud.js
+++ b/module/rdd-token-hud.js
@@ -1,6 +1,9 @@
/* -------------------------------------------- */
+import { renderTemplate } from "./constants.js";
import { HtmlUtility } from "./html-utility.js";
+import { Misc } from "./misc.js";
import { RdDCombatManager } from "./rdd-combat.js";
+import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js";
import { Targets } from "./targets.js";
/* -------------------------------------------- */
@@ -30,47 +33,92 @@ export class RdDTokenHud {
const combatant = game.combat.combatants.find(c => c.tokenId == tokenId)
const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false })
if (actor) {
- const actions = RdDCombatManager.listActionsActorCombatant(actor)
- // initiative
- await RdDTokenHud.addExtensionHudInit(html, combatant, actions)
- // combat
- await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions.filter(it => !it.initOnly))
+ if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
+ await RdDTokenHud.addExtensionHudCombat(html, combatant, actor, token)
+ }
+ else {
+ const actions = RdDCombatManager.listActionsActorCombatant(actor)
+ // initiative
+ await RdDTokenHud.addExtensionHudInit(html, combatant, actions)
+ // combat
+ await RdDTokenHud.addExtensionHudAttaques(html, combatant, token, actions.filter(it => !it.initOnly))
+ }
}
}
+ }
+ static async addExtensionHudCombat(html, combatant, actor, token) {
+ const actionsActor = actor.listActionsCombat();
+ const ajustements = combatant?.initiative ?
+ [
+ { label: 'Initiative +1', action: 'delta', value: 1 },
+ { label: 'Initiative -1', action: 'delta', value: -1 }
+ ] : []
+ const autres = [{ label: "Autre action", action: 'autre' }]
+ const actions = Misc.indexed(actionsActor.concat(ajustements).concat(autres))
+ const hudData = { combatant, token, actions };
+ const hud = $(await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/hud-actor-combat.hbs', hudData))
+ $(html).find('div.col.left').append(hud)
+
+ const list = hud.find('div.rdd-hud-list')
+ RdDTokenHud.setupHudToggle(hud, list)
+
+ const selectInitiative = list.find('select[name="initiative"]');
+ selectInitiative.change(event => {
+ const action = actions.find(it => it.index == event.currentTarget.value)
+ console.log('select initiative', combatant.id, action)
+ if (action) {
+ switch (action.action) {
+ case 'delta':
+ RdDCombatManager.incDecInit(combatant.id, action.value);
+ break
+ case 'autre':
+ RdDCombatManager.rollInitiativeAction(combatant.id,
+ { label: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
+ break
+ default:
+ RdDCombatManager.rollInitiativeAction(combatant.id, action)
+ }
+ selectInitiative.select("")
+ }
+ })
+ list.find('.rdd-attaque-v2').click(event => combatant.actor.rollAttaque(token))
}
static async addExtensionHudInit(html, combatant, actions) {
const hudData = {
combatant, actions,
commandes: [
- { name: "Autre action", command: 'autre' },
- { name: 'Initiative +1', command: 'inc', value: 0.01 },
- { name: 'Initiative -1', command: 'dec', value: -0.01 }]
+ { label: "Autre action", command: 'autre' },
+ { label: 'Initiative +1', command: 'delta', value: 1 },
+ { label: 'Initiative -1', command: 'deltac', value: -1 }]
};
const controlIconCombat = $(html).find('.control-icon[data-action=combat]');
- await RdDTokenHud._configureSubMenu(controlIconCombat,
+ await RdDTokenHud._configureSubMenu(it => controlIconCombat.after(it),
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.hbs',
hudData,
(event) => {
- let initCommand = event.currentTarget.attributes['data-command']?.value;
- let combatantId = event.currentTarget.attributes['data-combatant-id']?.value;
+ let initCommand = event.currentTarget.attributes['data-command']?.value
+ let initCommandValue = Number(event.currentTarget.attributes['data-command-value']?.value ?? 0)
+ let combatantId = event.currentTarget.attributes['data-combatant-id']?.value
if (initCommand) {
- RdDTokenHud._initiativeCommand(initCommand, combatantId);
+ RdDCombatManager.applyInitiativeCommand(combatantId, initCommand, initCommandValue)
} else {
- let index = event.currentTarget.attributes['data-action-index'].value;
- let action = hudData.actions[index];
- RdDCombatManager.rollInitiativeAction(combatantId, action);
+ let index = event.currentTarget.attributes['data-action-index'].value
+ let action = hudData.actions[index]
+ RdDCombatManager.rollInitiativeAction(combatantId, action)
}
- });
+ })
}
- static async addExtensionHudCombat(html, combatant, token, actions) {
+ static async addExtensionHudAttaques(html, combatant, token, actions) {
const hudData = { combatant, token, actions, commandes: [] };
- const controlIconTarget = $(html).find('.control-icon[data-action=target]');
- await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs', hudData,
+ const divColLeft = $(html).find('div.col.left');
+ await RdDTokenHud._configureSubMenu(it => divColLeft.append(it),
+ 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs',
+ hudData,
(event) => {
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
const action = hudData.actions[actionIndex];
@@ -90,7 +138,7 @@ export class RdDTokenHud {
const hudSoins = { blessures: target.actor.blessuresASoigner() ?? [] };
if (hudSoins.blessures.length > 0) {
const controlIconTarget = $(html).find('.control-icon[data-action=combat]');
- await RdDTokenHud._configureSubMenu(controlIconTarget,
+ await RdDTokenHud._configureSubMenu(it => controlIconTarget.after(it),
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-soins.hbs',
hudSoins,
(event) => {
@@ -101,15 +149,6 @@ export class RdDTokenHud {
}
}
- static _initiativeCommand(initCommand, combatantId) {
- switch (initCommand) {
- case 'inc': return RdDCombatManager.incDecInit(combatantId, 0.01);
- case 'dec': return RdDCombatManager.incDecInit(combatantId, -0.01);
- case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
- { name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
- }
- }
-
/* -------------------------------------------- */
static async addTokenHudExtensions(app, html, tokenId) {
console.log(`Adding token HUD extensions for token ${tokenId}`);
@@ -129,20 +168,24 @@ export class RdDTokenHud {
}
/* -------------------------------------------- */
- static async _configureSubMenu(insertionPoint, template, hudData, onMenuItem) {
- const hud = $(await foundry.applications.handlebars.renderTemplate(template, hudData));
+ static async _configureSubMenu(callInsertion, template, hudData, onMenuItem) {
+ const hud = $(await renderTemplate(template, hudData));
const list = hud.find('div.rdd-hud-list');
- RdDTokenHud._toggleHudListActive(hud, list);
+ RdDTokenHud.setupHudToggle(hud, list)
- hud.find('img.rdd-hud-togglebutton').click(event => RdDTokenHud._toggleHudListActive(hud, list));
list.find('.rdd-hud-menu').click(onMenuItem);
- insertionPoint.after(hud);
+ callInsertion(hud);
}
- static _toggleHudListActive(hud, list) {
- hud.toggleClass('active');
- HtmlUtility.showControlWhen(list, hud.hasClass('active'));
+ static setupHudToggle(hud, list) {
+ function toggleHudList(hud, list) {
+ hud.toggleClass('active')
+ HtmlUtility.showControlWhen(list, hud.hasClass('active'))
+ }
+ toggleHudList(hud, list)
+ $(hud).find('img.rdd-hud-togglebutton').click(event => toggleHudList(hud, list))
}
+
}
\ No newline at end of file
diff --git a/module/rdd-utility.js b/module/rdd-utility.js
index 7a49e6c1..b37b79c5 100644
--- a/module/rdd-utility.js
+++ b/module/rdd-utility.js
@@ -278,7 +278,7 @@ export class RdDUtility {
Handlebars.registerHelper('plusMoins', diff => parseInt(diff) ? (diff > 0 ? '+' : '') + Math.round(diff) : diff)
Handlebars.registerHelper('fractionOneN', n => new Handlebars.SafeString(Misc.getFractionOneN(n)))
-
+
// Handle v12 removal of this helper
Handlebars.registerHelper('select', function (selected, options) {
const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected));
@@ -286,7 +286,7 @@ export class RdDUtility {
const html = options.fn(this);
return html.replace(rgx, "$& selected");
})
-
+
// logic
Handlebars.registerHelper('either', (a, b) => a ?? b);
// string manipulation
@@ -299,8 +299,10 @@ export class RdDUtility {
Handlebars.registerHelper('grammar-un', str => Grammar.articleIndetermine(str));
Handlebars.registerHelper('grammar-accord', (genre, ...args) => Grammar.accord(genre, args));
Handlebars.registerHelper('json-stringify', object => JSON.stringify(object))
-
+
// math
+ Handlebars.registerHelper('math-sum', (...values) => values.slice(0, -1).reduce(Misc.sum(), 0))
+ Handlebars.registerHelper('math-abs', diff => Math.abs(parseInt(diff)))
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
Handlebars.registerHelper('repeat', function (n, block) {
let accum = '';
diff --git a/module/roll/chat-roll-result.mjs b/module/roll/chat-roll-result.mjs
index 7c22ad21..69bfbbbf 100644
--- a/module/roll/chat-roll-result.mjs
+++ b/module/roll/chat-roll-result.mjs
@@ -4,6 +4,8 @@ import { RdDCarac } from "../rdd-carac.js"
import { RdDCombat } from "../rdd-combat.js"
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
import { RdDResolutionTable } from "../rdd-resolution-table.js"
+import { RDD_CONFIG, renderTemplate } from "../constants.js"
+import { EMPOIGNADE } from "../item/arme.js"
export default class ChatRollResult {
static init() {
@@ -15,6 +17,7 @@ export default class ChatRollResult {
static onReady() {
foundry.applications.handlebars.loadTemplates({
'partial-appel-chance': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-appel-chance.hbs',
+ 'partial-attaque-particuliere': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-attaque-particuliere.hbs',
'partial-encaissement': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-encaissement.hbs',
'partial-recul-choc': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-recul-choc.hbs',
'partial-info-appel-moral': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-info-appel-moral.hbs',
@@ -37,12 +40,12 @@ export default class ChatRollResult {
}
prepareDisplay(roll) {
- roll.done = roll.done || {}
- roll.show = roll.show || {}
+ roll.done = roll.done ?? {}
+ roll.show = roll.show ?? {}
roll.show.chance = this.isAppelChancePossible(roll)
roll.show.encaissement = this.isShowEncaissement(roll)
- roll.show.recul = this.getReculChoc(roll)
-
+ roll.show.recul = this.getRecul(roll)
+ //roll.show.particuliere = roll.show.particuliere ?? []
}
isAppelChancePossible(roll) {
@@ -52,31 +55,50 @@ export default class ChatRollResult {
}
isShowEncaissement(roll) {
- return roll.rolled.isEchec &&
- roll.attackerRoll?.dmg.mortalite != 'empoignade'
+ switch (roll.type.current) {
+ case ROLL_TYPE_DEFENSE:
+ return roll.rolled.isEchec && roll.attackerRoll?.dmg.mortalite != EMPOIGNADE
+ }
+ return false
}
- getReculChoc(roll, defender = roll.active.actor, attacker = roll.opponent.actor) {
- const attaque = roll.attackerRoll
- if (attaque &&
- (roll.rolled.isEchec || !roll.current.defense.isEsquive) &&
- (attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)) {
- const taille = defender.system.carac.taille.value
- const impact = attacker.system.carac.force.value + roll.attackerRoll?.dmg.dmgArme
- return {
- raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force',
- taille: taille,
- impact: impact,
- chances: RdDResolutionTable.computeChances(10, taille-impact).norm,
- diff: taille - impact
- }
+
+ getRecul(roll, defender = roll.active.actor, attacker = roll.opponent?.actor) {
+ switch (roll.type.current) {
+ case ROLL_TYPE_DEFENSE:
+ {
+ const attaque = roll.attackerRoll
+ if (attaque &&
+ (roll.rolled.isEchec || !roll.current.defense.isEsquive) &&
+ (attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)) {
+ const taille = defender.system.carac.taille.value
+ const impact = attacker.system.carac.force.value + roll.attackerRoll?.dmg.dmgArme
+ return {
+ raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force',
+ taille: taille,
+ impact: impact,
+ chances: RdDResolutionTable.computeChances(10, taille - impact).norm,
+ diff: taille - impact
+ }
+ }
+ break
+ }
+ case ROLL_TYPE_ATTAQUE:
+ {
+ const attaque = roll
+ if (attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key) {
+ return {
+ raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force',
+ }
+ }
+ }
}
return undefined
}
async buildRollHtml(roll) {
const template = `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${roll.type.current}.hbs`
- return await foundry.applications.handlebars.renderTemplate(template, roll)
+ return await renderTemplate(template, roll)
}
async chatListeners(html) {
@@ -84,6 +106,7 @@ export default class ChatRollResult {
$(html).on("click", '.appel-destinee', event => this.onClickAppelDestinee(event))
$(html).on("click", '.encaissement', event => this.onClickEncaissement(event))
$(html).on("click", '.resister-recul', event => this.onClickRecul(event))
+ $(html).on("click", '.choix-particuliere', event => this.onClickChoixParticuliere(event))
}
@@ -177,4 +200,13 @@ export default class ChatRollResult {
await this.updateChatMessage(chatMessage, savedRoll)
}
+ async onClickChoixParticuliere(event) {
+ const choix = event.currentTarget.attributes['data-particuliere'].value
+ const chatMessage = ChatUtility.getChatMessage(event)
+ const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
+ savedRoll.particuliere = choix
+ savedRoll.particulieres = [RDD_CONFIG.particuliere[choix]]
+ await this.updateChatMessage(chatMessage, savedRoll)
+ await this.getCombat(savedRoll)?.onAttaqueV2(savedRoll, callbacks)
+ }
}
\ No newline at end of file
diff --git a/module/roll/roll-basic-parts.mjs b/module/roll/roll-basic-parts.mjs
index 3a1c5746..8a6fc14d 100644
--- a/module/roll/roll-basic-parts.mjs
+++ b/module/roll/roll-basic-parts.mjs
@@ -4,9 +4,10 @@ import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
import { PART_DEFENSE } from "./roll-part-defense.mjs"
+
export class RollBasicParts {
- restore(rollData) {
+ static restore(rollData) {
rollData.ids.sceneId = rollData.ids.sceneId ?? canvas.scene.id
rollData.active = RollBasicParts.$getActor(rollData)
rollData.opponent = RollBasicParts.$getOpponent(rollData)
@@ -15,14 +16,14 @@ export class RollBasicParts {
}
}
- loadSurprises(rollData, type) {
+ static loadSurprises(rollData, type = rollData.type.current) {
if (!rollData.type.passif) {
- this.loadSurprise(rollData.active, this.getForceRequiseActiveActor(rollData, type))
- this.loadSurprise(rollData.opponent, 0)
+ RollBasicParts.loadSurprise(rollData.active, RollBasicParts.getForceRequiseActiveActor(rollData, type))
+ RollBasicParts.loadSurprise(rollData.opponent, 0)
}
}
- loadSurprise(who, forceRequise) {
+ static loadSurprise(who, forceRequise) {
if (who?.actor) {
foundry.utils.mergeObject(who,
StatusEffects.getActorEffetSurprise(who.actor, forceRequise),
@@ -30,15 +31,15 @@ export class RollBasicParts {
}
}
- getForceRequiseActiveActor(rollData, type) {
+ static getForceRequiseActiveActor(rollData, type) {
switch (type) {
- case ROLL_TYPE_ATTAQUE: return rollData.current[PART_ATTAQUE].attaque.forceRequise
+ case ROLL_TYPE_ATTAQUE: return rollData.current[PART_ATTAQUE].forceRequise
case ROLL_TYPE_DEFENSE: return rollData.current[PART_DEFENSE].forceRequise
default: return 0
}
}
- initFrom(rollData) {
+ static initFrom(rollData) {
return {
selected: {},
type: rollData.type,
@@ -52,6 +53,16 @@ export class RollBasicParts {
}
}
+ static reverseIds(rollData) {
+ return {
+ sceneId: rollData.ids.sceneId,
+ actorId: rollData.ids.opponentId,
+ actorTokenId: rollData.ids.opponentTokenId,
+ opponentId: rollData.ids.actorId,
+ opponentTokenId: rollData.actorTokenId
+ }
+ }
+
static $getActor(rollData) {
if (rollData.ids.actorTokenId) {
return ActorToken.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId)
diff --git a/module/roll/roll-constants.mjs b/module/roll/roll-constants.mjs
index f44f9bd5..7b5f54f9 100644
--- a/module/roll/roll-constants.mjs
+++ b/module/roll/roll-constants.mjs
@@ -4,10 +4,19 @@ export const ROLL_TYPE_COMP = 'comp'
export const ROLL_TYPE_DEFENSE = 'defense'
export const ROLL_TYPE_JEU = 'jeu'
export const ROLL_TYPE_MEDITATION = 'meditation'
+export const ROLL_TYPE_CUISINE = 'cuisine'
export const ROLL_TYPE_OEUVRE = 'oeuvre'
export const ROLL_TYPE_SORT = 'sort'
export const ROLL_TYPE_TACHE = 'tache'
+export const ATTAQUE_ROLL_TYPES = [ROLL_TYPE_ATTAQUE]
+export const COMBAT_ROLL_TYPES = [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE]
+export const DEMIREVE_ROLL_TYPES = [ROLL_TYPE_SORT]
+export const DEFAULT_ROLL_TYPES = [ROLL_TYPE_COMP, ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_CUISINE, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE]
+export const ALL_ROLL_TYPES = [...DEFAULT_ROLL_TYPES, ...COMBAT_ROLL_TYPES, ...DEMIREVE_ROLL_TYPES]
+
+
+
export const DIFF = {
LIBRE: 'libre',
ATTAQUE: 'attaque',
diff --git a/module/roll/roll-dialog-adapter.mjs b/module/roll/roll-dialog-adapter.mjs
index 55beea84..ba3e432f 100644
--- a/module/roll/roll-dialog-adapter.mjs
+++ b/module/roll/roll-dialog-adapter.mjs
@@ -6,6 +6,10 @@ import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
import { PART_OEUVRE } from "./roll-part-oeuvre.mjs";
import { RdDItemArme } from "../item/arme.js";
import { RdDBonus } from "../rdd-bonus.js";
+import { ITEM_TYPES, RDD_CONFIG } from "../constants.js";
+import { CARACS } from "../rdd-carac.js";
+import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs";
+import { PART_ATTAQUE } from "./roll-part-attaque.mjs";
/* -------------------------------------------- */
export class RollDialogAdapter {
@@ -15,21 +19,21 @@ export class RollDialogAdapter {
carac: rollData.current.carac.value,
diff: rollData.current.totaldiff,
bonus: rollData.current.bonus,
- sign: rollData.current.sign,
showDice: rollData.options.showDice,
rollMode: rollData.current.rollmode.key
})
const rolled = await RollDialogAdapter.rollChances(rollData, chances)
- RollDialogAdapter.adjustRollDataForV1(rollData, rolled, rollTitle)
+ RollDialogAdapter.setRollDataRolled(rollData, rolled, rollTitle)
+ RollDialogAdapter.adjustRollDataForV1(rollData)
+ RollDialogAdapter.adjustAttaqueParticuliere(rollData)
return rolled
}
- static computeChances({ carac, diff, bonus, sign, showDice, rollMode }) {
+ static computeChances({ carac, diff, bonus, showDice, rollMode }) {
const chances = foundry.utils.duplicate(RdDResolutionTable.computeChances(carac, diff))
RdDResolutionTable._updateChancesWithBonus(chances, bonus, diff)
- RdDResolutionTable._updateChancesFactor(chances, sign)
chances.showDice = showDice
chances.rollMode = rollMode
return chances
@@ -37,7 +41,7 @@ export class RollDialogAdapter {
static async rollChances(rollData, chances) {
const rolled = await RdDResolutionTable.rollChances(chances,
- rollData.current.sign,
+ rollData.current.sign.diviseur,
rollData.current.resultat)
rolled.caracValue = rollData.current.carac.value
rolled.finalLevel = rollData.current.totaldiff
@@ -46,13 +50,20 @@ export class RollDialogAdapter {
return rolled
}
- static adjustRollDataForV1(rollData, rolled, rollTitle) {
+ static setRollDataRolled(rollData, rolled, rollTitle) {
+ rollData.rolled = rolled
+ rollData.choix = rollData.choix ?? {}
+ rollData.show = rollData.show ?? {}
+ rollData.show.title = rollTitle
+ }
+
+ static adjustRollDataForV1(rollData) {
+ const rolled = rollData.rolled
// temporaire pour être homogène roll v1
rollData.alias = rollData.active.actor.getAlias()
// pour experience
rollData.finalLevel = rollData.current.totaldiff
if (rollData.use == undefined) { rollData.use = {} }
- if (rollData.show == undefined) { rollData.show = {} }
if (rollData.ajustements == undefined) {
rollData.ajustements = {}
}
@@ -75,7 +86,6 @@ export class RollDialogAdapter {
if (rollData.current[PART_APPELMORAL]?.checked) {
rollData.use.moral = true
}
- rollData.rolled = rolled
if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) {
rolled.niveauNecessaire = this.findNiveauNecessaire(carac, rolled.roll)
rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
@@ -88,7 +98,39 @@ export class RollDialogAdapter {
descr: aj.diff == undefined ? aj.label : undefined
}
})
- rollData.show.title = rollTitle
+ }
+
+ static adjustAttaqueParticuliere(rollData) {
+ if (rollData.type.current != ROLL_TYPE_ATTAQUE || !rollData.rolled.isPart) {
+ return
+ }
+
+ const attaque = rollData.current.attaque;
+ const choix = []
+ const isEmpoignade = attaque.dmg.mortalite == 'empoignade';
+ const isCharge = attaque.tactique == 'charge'
+ /* TODO: cas de créatures faisant des lancers, Glou, Glipzouk */
+ const isMeleeDiffNegative = (attaque.comp.type == ITEM_TYPES.competencecreature || rollData.current.carac.key == CARACS.MELEE)
+ && rollData.current.diff.value < 0
+
+ // force toujours, sauf empoignade
+ if (!isEmpoignade) {
+ choix.push(RDD_CONFIG.particuliere.force)
+ }
+
+ // finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
+ if (!isCharge && (isEmpoignade || isMeleeDiffNegative)) {
+ choix.push(RDD_CONFIG.particuliere.finesse)
+ }
+
+ // rapidité seulement en mêlée, si l'arme le permet, et si la difficulté libre est de -1 minimum
+ if (!isCharge && !isEmpoignade && isMeleeDiffNegative && attaque.arme.system.rapide) {
+ choix.push(RDD_CONFIG.particuliere.rapidite)
+ }
+ if (choix.length == 1) {
+ rollData.particuliere = choix[0].key
+ }
+ rollData.particulieres = choix
}
static mapActionAttaque(attackerRoll) {
@@ -99,17 +141,15 @@ export class RollDialogAdapter {
return {
// correspond à l'attaque de RollPartAttaque (dans rollDta.current.attaque)
label: label,
- attaque: {
- // correspond aux actions d'attaques dans RdDActor.listActionsAttaque
- name: label,
- // action: 'attaque',
- arme: attackerRoll.arme,
- comp: attackerRoll.competence,
- main: RdDItemArme.getMainAttaque(attackerRoll.competence),
- equipe: attackerRoll.arme.system.equipe,
- // carac: { key: caracCode, value: caracValue },
- // dommagesArme: dommagesArme,
- },
+ // correspond aux actions d'attaques dans RdDActor.listActionsAttaque
+ name: label,
+ // action: 'attaque',
+ arme: attackerRoll.arme,
+ comp: attackerRoll.competence,
+ main: RdDItemArme.getMainAttaque(attackerRoll.competence),
+ equipe: attackerRoll.arme.system.equipe,
+ // carac: { key: caracCode, value: caracValue },
+ // dommagesArme: dommagesArme,
diff: attackerRoll.diffLibre,
particuliere: attackerRoll.particuliere,
tactique: RdDBonus.find(attackerRoll.tactique),
diff --git a/module/roll/roll-dialog.mjs b/module/roll/roll-dialog.mjs
index 2ecc326e..a49c510c 100644
--- a/module/roll/roll-dialog.mjs
+++ b/module/roll/roll-dialog.mjs
@@ -39,10 +39,13 @@ import { RollDialogAdapter } from "./roll-dialog-adapter.mjs";
import { ROLLDIALOG_SECTION } from "./roll-part.mjs";
import { ROLL_TYPE_COMP } from "./roll-constants.mjs";
import ChatRollResult from "./chat-roll-result.mjs";
+import { renderTemplate } from "../constants.js";
+import { RollTypeCuisine } from "./roll-type-cuisine.mjs";
+import { RollPartCuisine } from "./roll-part-cuisine.mjs";
+import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js";
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
-const doNothing = (dialog) => { }
const ALL_ROLL_TYPES = [
new RollTypeComp(),
@@ -51,14 +54,13 @@ const ALL_ROLL_TYPES = [
new RollTypeDefense(),
new RollTypeSort(),
new RollTypeMeditation(),
+ new RollTypeCuisine(),
new RollTypeOeuvre(),
new RollTypeJeu(),
// new RollTypeResistance ??
// new RollTypeFixedCarac ??
]
-const BASIC_PARTS = new RollBasicParts()
-
const ROLL_PARTS = [
new RollPartActor(),
new RollPartAction(),
@@ -72,6 +74,7 @@ const ROLL_PARTS = [
new RollPartMeditation(),
new RollPartSort(),
new RollPartTache(),
+ new RollPartCuisine(),
new RollPartOeuvre(),
new RollPartJeu(),
@@ -169,6 +172,14 @@ const ROLL_PARTS = [
/* -------------------------------------------- */
export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2)
{
+ static onRollDoneDoNothing(dialog) {
+ dialog.render()
+ }
+ static onRollDoneClose(dialog) {
+ if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
+ dialog.close()
+ }
+
static init() {
}
@@ -256,13 +267,13 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
rollData.selected = rollData.selected ?? {}
rollData.type = rollData.type ?? {}
rollData.type.retry = rollData.type.retry ?? false
- BASIC_PARTS.restore(rollData)
+ RollBasicParts.restore(rollData)
const potential = ALL_ROLL_TYPES.find(m => m.code == rollData.type.current)?.code
const allowed = rollData.type.retry && potential
? [potential]
- : (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code))
- const rollType = allowed.find(c => c == rollData.type.current) ?? (allowed.length > 0 ? allowed[0].code : ROLL_TYPE_COMP);
+ : (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code) ?? [ROLL_TYPE_COMP])
+ const rollType = allowed.find(c => c == rollData.type.current) ?? allowed[0]
rollData.type.allowed = allowed
rollData.type.current = rollType
@@ -272,9 +283,9 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
rollData.options = rollData.options ?? { rollMode: game.settings.get("core", "rollMode") }
ROLL_PARTS.forEach(p => p.initialize(rollData))
- ROLL_PARTS.forEach(p => p.restore(rollData))
ROLL_PARTS.filter(p => p.isValid(rollData))
.forEach(p => {
+ p.restore(rollData)
p.loadRefs(rollData)
p.prepareContext(rollData)
})
@@ -282,13 +293,14 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
}
static saveParts(rollData) {
- const target = BASIC_PARTS.initFrom(rollData)
+ const target = RollBasicParts.initFrom(rollData)
ROLL_PARTS.filter(p => p.isActive(rollData))
.forEach(p => p.storeClean(rollData, target))
target.attackerRoll = rollData.attackerRoll
target.rolled = rollData.rolled
target.result = rollData.result
- target.done = target.done ?? {}
+ target.done = rollData.done ?? {}
+ target.dmg = rollData.dmg
return target
}
@@ -303,7 +315,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
...(rollOptions.callbacks ?? [])
],
customChatMessage: rollOptions.customChatMessage,
- onRollDone: rollOptions.onRollDone ?? doNothing
+ onRollDone: rollOptions.onRollDone ?? RollDialog.onRollDoneDoNothing
}
this.chatRollResult = new ChatRollResult();
this.selectType()
@@ -324,16 +336,16 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
return ROLL_PARTS.filter(p => p.isActive(rollData))
}
- // get title() {
- // return this.rollData.title ?? `Jet de dés de ${this.rollData.active.actor.name}`
- // }
-
rollTitle(rollData) {
- return rollData.label ?? ROLL_PARTS
+ const title = rollData.label ?? ROLL_PARTS
.filter(it => it.section == ROLLDIALOG_SECTION.ACTION)
.filter(it => it.isActive(rollData))
.map(it => it.title(rollData))
- .reduce(Misc.joining(' '))
+ .reduce(Misc.joining(' '));
+ if (this.rollOptions.title) {
+ return `${this.rollOptions.title} ${title}`
+ }
+ return title
}
async _onRender(context, options) {
@@ -368,7 +380,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
}
async buildHTMLTable(carac, diff) {
- return await foundry.applications.handlebars.renderTemplate('roll-table', { carac, diff })
+ return await renderTemplate('roll-table', { carac, diff })
}
async _prepareContext() {
@@ -376,7 +388,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
const types = ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData))
.map(m => m.toTypeData(rollData))
- BASIC_PARTS.loadSurprises(rollData, this.getSelectedType().code)
+ RollBasicParts.loadSurprises(rollData, this.getSelectedType().code)
rollData.type.label = this.getSelectedType()?.title(rollData)
//TOCHECK: set type.label ?
const visibleRollParts = RollDialog.getActiveParts(rollData)
@@ -422,18 +434,22 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
}
async roll() {
- // ROLL_PARTS.filter(p => p.isActive(this.rollData))
- // .forEach(p => p.validate(this.rollData))
const roll = RollDialog.saveParts(this.rollData)
+ const selectedRollType = this.getSelectedType(roll);
RollDialog.loadRollData(roll)
roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1
- roll.rolled = await this.$rollDice(roll)
- roll.result = this.getSelectedType(roll).getResult(roll)
- console.info('RollDialog.roll:', roll)
- await Promise.all(this.rollOptions.callbacks.map(async callback => await callback(roll)))
- await this.chatRollResult.display(roll)
+ roll.choix = {}
+ roll.rolled = await RollDialogAdapter.rollDice(roll, this.rollTitle(roll))
+ roll.result = selectedRollType.getResult(roll)
+ console.info('RollDialog.roll:', roll)
+ const callbacks = [
+ ...this.rollOptions.callbacks,
+ ...selectedRollType.callbacks(this.rollOptions),
+ ]
+ await Promise.all(callbacks.map(async callback => await callback(roll)))
+ await this.chatRollResult.display(roll)
this.rollOptions.onRollDone(this)
}
@@ -443,12 +459,9 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
roll.v2 = true
}
- async defaultCallback(rollData, rolled) {
- await rollData.active.actor.appliquerAjoutExperience(rollData)
- await rollData.active.actor.appliquerAppelMoral(rollData)
+ async defaultCallback(roll, rolled) {
+ await roll.active.actor.appliquerAjoutExperience(roll)
+ await roll.active.actor.appliquerAppelMoral(roll)
}
- async $rollDice(rollData) {
- return await RollDialogAdapter.rollDice(rollData, this.rollTitle(rollData))
- }
}
diff --git a/module/roll/roll-part-attaque.mjs b/module/roll/roll-part-attaque.mjs
index ca2f41e5..a9f69731 100644
--- a/module/roll/roll-part-attaque.mjs
+++ b/module/roll/roll-part-attaque.mjs
@@ -1,8 +1,8 @@
import { RdDBonus } from "../rdd-bonus.js"
-import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"
-import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs"
+import { DIFF, ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs"
import { PART_CARAC } from "./roll-part-carac.mjs"
import { PART_COMP } from "./roll-part-comp.mjs"
+import { PART_DIFF } from "./roll-part-diff.mjs"
import { RollPartSelect } from "./roll-part-select.mjs"
import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
@@ -23,7 +23,8 @@ export class RollPartAttaque extends RollPartSelect {
refs.attaques = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor))
refs.tactiques = TACTIQUES
if (refs.attaques.length > 0) {
- this.$selectAttaque(rollData)
+ const attaque = this.findAttaque(refs.attaques, this.getSaved(rollData))
+ this.$selectAttaque(rollData, attaque?.key)
}
}
@@ -33,19 +34,34 @@ export class RollPartAttaque extends RollPartSelect {
}
restore(rollData) {
+ const saved = this.getSaved(rollData)
super.restore(rollData)
- this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg
+ if (saved.dmg) {
+ this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg
+ }
+ }
+
+ findAttaque(attaques, saved) {
+ return attaques.find(at => at.arme.id == saved?.arme?.id &&
+ at.comp.id == saved?.comp?.id
+ )
}
choices(refs) { return refs.attaques }
static $extractAttaque(attaque, actor) {
- return {
- key: `${attaque.action}::${attaque.name}`,
- label: attaque.name,
- attaque: attaque,
- tactique: TACTIQUES[0],
- }
+ // const extracted = foundry.utils.mergeObject({
+ // key: `${attaque.action}::${attaque.label}`,
+ // tactique: TACTIQUES[0]
+ // },
+ // attaque
+ // )
+ // return extracted
+ // extracted.initialDiff = attaque.comp?.system.default_diffLibre ?? 0
+ attaque.key = `${attaque.action}::${attaque.label}`
+ attaque.tactique = TACTIQUES[0]
+ attaque.initialDiff = attaque.comp?.system.default_diffLibre ?? 0
+ return attaque
}
prepareContext(rollData) {
@@ -100,8 +116,14 @@ export class RollPartAttaque extends RollPartSelect {
if (this.visible(rollData)) {
const current = this.getCurrent(rollData)
switch (part.code) {
- case PART_CARAC: return part.filterCaracs(rollData, [current.attaque.carac.key])
- case PART_COMP: return part.filterComps(rollData, [current.attaque.comp?.name])
+ case PART_CARAC: return part.filterCaracs(rollData, [current.carac.key])
+ case PART_COMP: return part.filterComps(rollData, [current.comp.name])
+ case PART_DIFF: {
+ if (current.initialDiff) {
+ part.setDiff(rollData, { type: DIFF.ATTAQUE, value: current.initialDiff })
+ current.initialDiff = undefined
+ }
+ }
}
}
return undefined
diff --git a/module/roll/roll-part-checkbox.mjs b/module/roll/roll-part-checkbox.mjs
index 1d128941..c5476ab0 100644
--- a/module/roll/roll-part-checkbox.mjs
+++ b/module/roll/roll-part-checkbox.mjs
@@ -28,9 +28,7 @@ export class RollPartCheckbox extends RollPart {
/* TODO: user setting? */
current.checked = true
}
- if (current.value == undefined) {
- current.value = this.getCheckboxValue(rollData)
- }
+ current.value = this.getCheckboxValue(rollData)
current.icon = this.getCheckboxIcon(rollData)
}
diff --git a/module/roll/roll-part-comp.mjs b/module/roll/roll-part-comp.mjs
index 0463307f..2057c889 100644
--- a/module/roll/roll-part-comp.mjs
+++ b/module/roll/roll-part-comp.mjs
@@ -17,7 +17,14 @@ export class RollPartComp extends RollPartSelect {
loadRefs(rollData) {
const refs = this.getRefs(rollData)
+ const selected = this.getSelected(rollData)
refs.all = this.$getActorComps(rollData)
+ .filter(comp => !selected.forced ||
+ (selected.key ?
+ Grammar.includesLowerCaseNoAccent(comp.name, selected.key)
+ : comp.key == '')
+ )
+
refs.comps = refs.all
this.$selectComp(rollData)
}
@@ -49,7 +56,6 @@ export class RollPartComp extends RollPartSelect {
allowed = allowed.filter(it => it != undefined)
const refs = this.getRefs(rollData)
refs.comps = allowed.length > 0
- // ? refs.all.filter(it => allowed.includes(Grammar.toLowerCaseNoAccent(it.label)))
? refs.all.filter(it => allowed.includes(it.label))
: refs.all
this.$selectComp(rollData)
diff --git a/module/roll/roll-part-cuisine.mjs b/module/roll/roll-part-cuisine.mjs
new file mode 100644
index 00000000..fa60128d
--- /dev/null
+++ b/module/roll/roll-part-cuisine.mjs
@@ -0,0 +1,76 @@
+import { ITEM_TYPES } from "../constants.js"
+import { CARACS } from "../rdd-carac.js"
+import { ROLL_TYPE_CUISINE } from "./roll-constants.mjs"
+import { PART_CARAC } from "./roll-part-carac.mjs"
+import { PART_COMP } from "./roll-part-comp.mjs"
+import { RollPartSelect } from "./roll-part-select.mjs"
+import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
+
+export const PART_CUISINE = "cuisine"
+
+export class RollPartCuisine extends RollPartSelect {
+ onReady() {
+ foundry.applications.handlebars.loadTemplates({ 'roll-oeuvre-recettecuisine': `systems/foundryvtt-reve-de-dragon/templates/roll/roll-oeuvre-recettecuisine.hbs` })
+ }
+
+ get code() { return PART_CUISINE }
+ get section() { return ROLLDIALOG_SECTION.CHOIX }
+
+ isValid(rollData) { return rollData.active.actor.isPersonnage() }
+ visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_CUISINE) }
+
+ loadRefs(rollData) {
+ const refs = this.getRefs(rollData)
+ refs.recettes = rollData.active.actor.items
+ .filter(it => it.type == ITEM_TYPES.recettecuisine)
+ .map(it => RollPartCuisine.$extractRecette(it, rollData.active.actor))
+ if (refs.recettes.length > 0) {
+ this.$selectRecette(rollData)
+ }
+ }
+
+ choices(refs) { return refs.recettes }
+
+ static $extractRecette(recette, actor) {
+ return {
+ key: recette.id,
+ label: recette.name,
+ caracs: RollPartCuisine.getCaracs(recette),
+ qualite: recette.system.niveau,
+ value: -recette.system.niveau,
+ recette: recette,
+ comp: actor.getCompetence('Cuisine')
+ }
+ }
+ static getCaracs(recette){
+ // TODO: permettre différentes caractéristiques pour la cuisine?
+ return [CARACS.ODORATGOUT, CARACS.EMPATHIE, CARACS.DEXTERITE]
+ }
+
+ $selectRecette(rollData, key) {
+ this.selectByKey(rollData, key, 0)
+ }
+
+ async _onRender(rollDialog, context, options) {
+ const selectRecette = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-recette"]`)
+
+ selectRecette.addEventListener("change", e => {
+ const selectOptions = e.currentTarget.options
+ const index = selectOptions.selectedIndex
+ this.$selectRecette(rollDialog.rollData, selectOptions[index]?.value)
+ rollDialog.render()
+ })
+ }
+
+ impactOtherPart(part, rollData) {
+ if (this.visible(rollData)) {
+ const current = this.getCurrent(rollData)
+ switch (part.code) {
+ case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
+ case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
+ }
+ }
+ return undefined
+ }
+
+}
diff --git a/module/roll/roll-part-defense.mjs b/module/roll/roll-part-defense.mjs
index 82d33c51..e03dcfb0 100644
--- a/module/roll/roll-part-defense.mjs
+++ b/module/roll/roll-part-defense.mjs
@@ -34,7 +34,7 @@ export class RollPartDefense extends RollPartSelect {
.map(it => RollPartDefense.$extractEsquive(it, defenseur))
const parades = defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier()))
- .map(it => RollPartDefense.$extractParade(it, attackerRoll?.attaque.arme, defenseur))
+ .map(it => RollPartDefense.$extractParade(it, attackerRoll?.arme, defenseur))
refs.defenses = [...esquives, ...parades].filter(it => it != undefined)
this.$selectDefense(rollData)
@@ -113,17 +113,16 @@ export class RollPartDefense extends RollPartSelect {
isArmeDisparate(rollData) {
const armeDefense = this.getCurrent(rollData).arme
if (armeDefense) {
- const armeAttaque = rollData.attackerRoll?.attaque.arme
+ const armeAttaque = rollData.attackerRoll?.arme
return RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) == 'sign'
}
return false
}
getDiffDefense(rollData) {
- const current = this.getCurrent(rollData)
const refs = this.getRefs(rollData)
if (refs.isDistance || !rollData.attackerRoll) {
- // Déterminer la difficulté de parade
+ // TODO: Déterminer la difficulté de parade
return { diff: 0, type: DIFF.LIBRE }
}
else {
diff --git a/module/roll/roll-part-diff.mjs b/module/roll/roll-part-diff.mjs
index 8ec99049..680dd9e8 100644
--- a/module/roll/roll-part-diff.mjs
+++ b/module/roll/roll-part-diff.mjs
@@ -51,10 +51,10 @@ export class RollPartDiff extends RollPart {
)
}
- setDiff(rollData, diffDefense) {
+ setDiff(rollData, diff) {
const current = this.getCurrent(rollData)
- current.value = diffDefense.diff
- current.type = diffDefense.type
+ current.value = diff.diff
+ current.type = diff.type
}
getAjustements(rollData) {
diff --git a/module/roll/roll-part-meditation.mjs b/module/roll/roll-part-meditation.mjs
index 1d929dbc..0e55646e 100644
--- a/module/roll/roll-part-meditation.mjs
+++ b/module/roll/roll-part-meditation.mjs
@@ -11,26 +11,41 @@ import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
export const PART_MEDITATION = "meditation"
+const COMPORTEMENTS = ['isComportement', 'isHeure', 'isPurification', 'isVeture']
+
export class RollPartMeditation extends RollPartSelect {
get code() { return PART_MEDITATION }
get section() { return ROLLDIALOG_SECTION.CHOIX }
+ store(rollData, targetData) {
+ const current = this.getCurrent(rollData)
+ this.setSaved(targetData, {
+ key: current.key,
+ isComportement: current.isComportement,
+ isHeure: current.isHeure,
+ isPurification: current.isPurification,
+ isVeture: current.isVeture
+ })
+ }
+
isValid(rollData) { return rollData.active.actor.isPersonnage() && rollData.active.actor.isHautRevant() }
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_MEDITATION) }
loadRefs(rollData) {
const refs = this.getRefs(rollData)
- foundry.utils.mergeObject(refs,
- {
- meditations: rollData.active.actor.itemTypes[ITEM_TYPES.meditation]
- .map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor))
- }
- )
+ refs.meditations = rollData.active.actor.itemTypes[ITEM_TYPES.meditation]
+ .map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor))
+
if (refs.meditations.length > 0) {
this.$selectMeditation(rollData)
+ this.$selectConditionMeditation(rollData)
+ const selected = this.getSelected(rollData)
+ const current = this.getCurrent(rollData)
+ COMPORTEMENTS.filter(it => selected[it]).forEach(it => current[it] = selected[it])
}
}
+
choices(refs) { return refs.meditations }
static $extractMeditation(meditation, actor) {
@@ -48,12 +63,7 @@ export class RollPartMeditation extends RollPartSelect {
getMalusConditions(rollData) {
const current = this.getCurrent(rollData)
- const conditionsManquantes = [
- current.isComportement,
- current.isHeure,
- current.isPurification,
- current.isVeture
- ].filter(it => !it).length
+ const conditionsManquantes = COMPORTEMENTS.filter(it => !current[it]).length
return -2 * conditionsManquantes
}
@@ -71,13 +81,18 @@ export class RollPartMeditation extends RollPartSelect {
const previous = this.getCurrent(rollData)
const current = this.selectByKey(rollData, key, 0)
if (current.key != previous.key) {
- const heureMonde = RdDTimestamp.getWorldTime().heure
- const heureMeditation = RdDTimestamp.findHeure(current.meditation.system.heure)?.heure
- current.isHeure = heureMeditation == heureMonde
- current.isTMR = Grammar.equalsInsensitive(current.meditation.system.tmr, TMRUtility.getTMRType(rollData.active.actor.system.reve.tmrpos.coord))
+ this.$selectConditionMeditation(rollData)
}
}
+ $selectConditionMeditation(rollData) {
+ const current = this.getCurrent(rollData)
+ current.heureMonde = RdDTimestamp.getWorldTime().heure
+ current.heureMeditation = RdDTimestamp.findHeure(current.meditation.system.heure)?.heure
+ current.isHeure = current.heureMeditation == current.heureMonde
+ current.isTMR = Grammar.equalsInsensitive(current.meditation.system.tmr, TMRUtility.getTMRType(rollData.active.actor.system.reve.tmrpos.coord))
+ }
+
async _onRender(rollDialog, context, options) {
const selectMeditation = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-meditation"]`)
@@ -88,10 +103,7 @@ export class RollPartMeditation extends RollPartSelect {
rollDialog.render()
})
- this.setupListenerCondition(rollDialog, 'isComportement')
- this.setupListenerCondition(rollDialog, 'isHeure')
- this.setupListenerCondition(rollDialog, 'isPurification')
- this.setupListenerCondition(rollDialog, 'isVeture')
+ COMPORTEMENTS.forEach(it => this.setupListenerCondition(rollDialog, it))
}
setupListenerCondition(rollDialog, inputName) {
@@ -108,7 +120,7 @@ export class RollPartMeditation extends RollPartSelect {
const current = this.getCurrent(rollData)
switch (part.code) {
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.INTELLECT])
- case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
+ case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
}
}
return undefined
diff --git a/module/roll/roll-part-oeuvre.mjs b/module/roll/roll-part-oeuvre.mjs
index d59dd63a..a8dd637a 100644
--- a/module/roll/roll-part-oeuvre.mjs
+++ b/module/roll/roll-part-oeuvre.mjs
@@ -11,6 +11,7 @@ export const PART_OEUVRE = "oeuvre"
const ARTS = [
{ type: ITEM_TYPES.oeuvre, action: "interpréte l'oeuvre", competence: it => it.system.competence, caracs: it => [it.system.default_carac] },
+ { type: ITEM_TYPES.musique, action: "joue le morceau:", competence: it => 'Musique', caracs: it => [CARACS.OUIE] },
{ type: ITEM_TYPES.chant, action: "chante", competence: it => 'Chant', caracs: it => [CARACS.OUIE] },
{
type: ITEM_TYPES.danse, action: "danse:", competence: it => 'Danse', caracs: it => {
@@ -20,8 +21,6 @@ const ARTS = [
return caracs
}
},
- { type: ITEM_TYPES.musique, action: "joue le morceau:", competence: it => 'Musique', caracs: it => [CARACS.OUIE] },
- { type: ITEM_TYPES.recettecuisine, action: "cuisine le plat:", competence: it => 'Cuisine', caracs: it => [CARACS.ODORATGOUT] },
]
export class RollPartOeuvre extends RollPartSelect {
diff --git a/module/roll/roll-part-tache.mjs b/module/roll/roll-part-tache.mjs
index 9a914783..1abb670e 100644
--- a/module/roll/roll-part-tache.mjs
+++ b/module/roll/roll-part-tache.mjs
@@ -1,5 +1,4 @@
import { ITEM_TYPES } from "../constants.js"
-import { Grammar } from "../grammar.js"
import { ROLL_TYPE_TACHE } from "./roll-constants.mjs"
import { PART_CARAC } from "./roll-part-carac.mjs"
import { PART_COMP } from "./roll-part-comp.mjs"
@@ -18,13 +17,17 @@ export class RollPartTache extends RollPartSelect {
loadRefs(rollData) {
const refs = this.getRefs(rollData)
- refs.taches = rollData.active.actor.itemTypes[ITEM_TYPES.tache]
+ const selected = this.getSelected(rollData)
+ refs.all = rollData.active.actor.itemTypes[ITEM_TYPES.tache]
+ .filter(tache => !selected.forced || tache.id == selected.key)
.filter(tache => tache.system.points_de_tache_courant < tache.system.points_de_tache)
.map(tache => RollPartTache.$extractTache(tache, rollData.active.actor))
+ refs.taches = refs.all
if (refs.taches.length > 0) {
this.$selectTache(rollData)
}
}
+
choices(refs) { return refs.taches }
static $extractTache(tache, actor) {
diff --git a/module/roll/roll-part.mjs b/module/roll/roll-part.mjs
index 3543dd72..dc7dfb9d 100644
--- a/module/roll/roll-part.mjs
+++ b/module/roll/roll-part.mjs
@@ -43,6 +43,7 @@ export class RollPart {
}
/** les informations minimales représentant la sélection dans le rollData permettant de restaurer la fenêtre */
+ getSelected(rollData) { return this.getSaved(rollData) }
getSaved(rollData) {
return rollData.selected[this.code] ?? {}
}
@@ -84,9 +85,9 @@ export class RollPart {
loadRefs(rollData) { }
prepareContext(rollData) { }
-
+
/** permet de sauvegarder dans rollData les informations (cas des champs edit) */
- validate(rollData) {}
+ validate(rollData) { }
/** ---- cross roll-part filtering ---- */
applyImpact(rollData, filter) { }
diff --git a/module/roll/roll-type-attaque.mjs b/module/roll/roll-type-attaque.mjs
index 0bf07924..f761e9be 100644
--- a/module/roll/roll-type-attaque.mjs
+++ b/module/roll/roll-type-attaque.mjs
@@ -1,4 +1,5 @@
import { DIFF, ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs"
+import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
import { RollType } from "./roll-type.mjs"
export class RollTypeAttaque extends RollType {
@@ -10,4 +11,5 @@ export class RollTypeAttaque extends RollType {
onSelect(rollData) {
this.setDiffType(rollData, DIFF.ATTAQUE)
}
+
}
\ No newline at end of file
diff --git a/module/roll/roll-type-cuisine.mjs b/module/roll/roll-type-cuisine.mjs
new file mode 100644
index 00000000..7ab82f6b
--- /dev/null
+++ b/module/roll/roll-type-cuisine.mjs
@@ -0,0 +1,28 @@
+import { DIFF, ROLL_TYPE_CUISINE } from "./roll-constants.mjs"
+import { PART_CUISINE } from "./roll-part-cuisine.mjs"
+import { RollType } from "./roll-type.mjs"
+
+export class RollTypeCuisine extends RollType {
+ get code() { return ROLL_TYPE_CUISINE }
+ get name() { return `Interpréter une oeuvre` }
+
+ visible(rollData) { return rollData.active.actor.isPersonnage() }
+ title(rollData) {
+ const current = rollData.current[PART_CUISINE]
+ return `prépare une recette: ${current.label}`
+ }
+
+ onSelect(rollData) {
+ this.setDiffType(rollData, DIFF.AUCUN)
+ }
+
+ getResult(rollData){
+ const current = rollData.current[PART_CUISINE]
+ const qualite = rollData.rolled.isSuccess ? current.qualite : Math.min(current.qualite, current.comp.system.niveau)
+ return {
+ qualite: qualite + rollData.rolled.ptQualite
+ }
+ }
+
+}
+
diff --git a/module/roll/roll-type-meditation.mjs b/module/roll/roll-type-meditation.mjs
index 9fd9c4c9..3248f428 100644
--- a/module/roll/roll-type-meditation.mjs
+++ b/module/roll/roll-type-meditation.mjs
@@ -1,3 +1,4 @@
+import { RdDItemSigneDraconique } from "../item/signedraconique.js"
import { DIFF, ROLL_TYPE_MEDITATION } from "./roll-constants.mjs"
import { PART_MEDITATION } from "./roll-part-meditation.mjs"
import { RollType } from "./roll-type.mjs"
@@ -16,4 +17,20 @@ export class RollTypeMeditation extends RollType {
onSelect(rollData) {
this.setDiffType(rollData, DIFF.AUCUN)
}
+ callbacks(rollOptions) { return [RollTypeMeditation.$onRollMeditation] }
+
+ static async $onRollMeditation(rollData) {
+ const actor = rollData.active.actor
+ const meditation = rollData.current.meditation.meditation
+ const rolled = rollData.rolled
+ if (meditation && rolled) {
+ if (rolled.isSuccess) {
+ await actor.createEmbeddedDocuments("Item", [RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditation, rolled)])
+ }
+ if (rolled.isEPart) {
+ await actor.updateEmbeddedDocuments('Item', [{ _id: meditation._id, 'system.malus': meditation.system.malus - 1 }])
+ }
+ await actor.santeIncDec("fatigue", 2)
+ }
+ }
}
\ No newline at end of file
diff --git a/module/roll/roll-type-tache.mjs b/module/roll/roll-type-tache.mjs
index 267763d3..3e2e19a0 100644
--- a/module/roll/roll-type-tache.mjs
+++ b/module/roll/roll-type-tache.mjs
@@ -1,3 +1,5 @@
+import { ITEM_TYPES } from "../constants.js"
+import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"
import { DIFF, ROLL_TYPE_TACHE } from "./roll-constants.mjs"
import { PART_TACHE } from "./roll-part-tache.mjs"
import { RollType } from "./roll-type.mjs"
@@ -16,4 +18,26 @@ export class RollTypeTache extends RollType {
onSelect(rollData) {
this.setDiffType(rollData, DIFF.AUCUN)
}
+
+ callbacks(rollOptions) { return [ async r => await RollTypeTache.$onRollTache(r, rollOptions)] }
+
+ static async $onRollTache(rollData, rollOptions) {
+ const actor = rollData.active.actor
+ const tache = rollData.current[PART_TACHE].tache
+ if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
+ await actor.santeIncDec("fatigue", tache.system.fatigue)
+ }
+
+ rollData.current[PART_TACHE].tache = await tache.update({
+ 'system.points_de_tache_courant': tache.system.points_de_tache_courant + rollData.rolled.ptTache,
+ 'system.nb_jet_succes': tache.system.nb_jet_succes + (rollData.rolled.isSuccess ? 1 : 0),
+ 'system.nb_jet_echec': tache.system.nb_jet_echec + (rollData.rolled.isSuccess ? 0 : 1),
+ 'system.difficulte': tache.system.difficulte - (rollData.rolled.isETotal ? 1 : 0),
+ }, {render:true})
+
+
+ if (rollOptions?.onRollAutomate) {
+ await rollOptions.onRollAutomate(rollData)
+ }
+ }
}
\ No newline at end of file
diff --git a/module/roll/roll-type.mjs b/module/roll/roll-type.mjs
index ef7547bc..124f503d 100644
--- a/module/roll/roll-type.mjs
+++ b/module/roll/roll-type.mjs
@@ -11,14 +11,13 @@ export class RollType {
get name() { return this.code }
get icon() { return `systems/foundryvtt-reve-de-dragon/assets/actions/${this.code}.svg` }
get chatResultTemplate() { return `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${this.code}.hbs` }
-
+
toTypeData(rollData) {
return { code: this.code, name: this.name, icon: this.icon, section: 'type', template: this.template, selected: this.isSelected(rollData) }
}
isAllowed(rollData) { return rollData.type.allowed == undefined || rollData.type.allowed.includes(this.code) }
visible(rollData) { return true }
-
title(rollData) { return this.code }
isSelected(rollData) { return rollData.type.current == this.code }
@@ -33,11 +32,10 @@ export class RollType {
this.typeFromOpponents(rollData),
rollData.selected[PART_DIFF].type
]
- const type = possibleTypes.find(m => DEFAULT_DIFF_TYPES.includes(m)) ??DIFF.DEFAUT
+ const type = possibleTypes.find(m => DEFAULT_DIFF_TYPES.includes(m)) ?? DIFF.DEFAUT
this.setDiffType(rollData, type)
}
-
typeFromOpponents(rollData) {
if (rollData.type.opposed) {
if (rollData.type.resistance) {
@@ -53,7 +51,7 @@ export class RollType {
this.setRollDataType(rollData)
}
- getResult(rollData){
- return undefined
- }
+ callbacks(rollOptions) { return [] }
+
+ getResult(rollData) { return undefined }
}
diff --git a/module/rolldata-ajustements.js b/module/rolldata-ajustements-v1.js
similarity index 100%
rename from module/rolldata-ajustements.js
rename to module/rolldata-ajustements-v1.js
diff --git a/module/settings/options-avancees.js b/module/settings/options-avancees.js
index 720a3923..f5828268 100644
--- a/module/settings/options-avancees.js
+++ b/module/settings/options-avancees.js
@@ -50,7 +50,7 @@ export class OptionsAvancees extends FormApplication {
.map(it => {
it = foundry.utils.duplicate(it)
it.id = OptionsAvancees._getId(it.name)
- it.active = OptionsAvancees.isSet(it.name)
+ it.active = OptionsAvancees.isUsing(it.name)
return it
})
formData.regles = regles
@@ -63,10 +63,6 @@ export class OptionsAvancees extends FormApplication {
}
static isUsing(name) {
- return OptionsAvancees.isSet(name)
- }
-
- static isSet(name) {
return game.settings.get(SYSTEM_RDD, OptionsAvancees._getId(name))
}
diff --git a/module/settings/system-compendiums.js b/module/settings/system-compendiums.js
index fe782aaf..f602b80a 100644
--- a/module/settings/system-compendiums.js
+++ b/module/settings/system-compendiums.js
@@ -1,5 +1,5 @@
import { ChatUtility } from "../chat-utility.js";
-import { HIDE_DICE, SYSTEM_RDD } from "../constants.js";
+import { HIDE_DICE, renderTemplate, SYSTEM_RDD } from "../constants.js";
import { Grammar } from "../grammar.js";
import { RdDItem } from "../item.js";
import { Misc } from "../misc.js";
diff --git a/module/sommeil/dialog-chateau-dormant.js b/module/sommeil/dialog-chateau-dormant.js
index c01075dc..64218b62 100644
--- a/module/sommeil/dialog-chateau-dormant.js
+++ b/module/sommeil/dialog-chateau-dormant.js
@@ -1,3 +1,4 @@
+import { renderTemplate } from "../constants.js";
export class DialogChateauDormant extends Dialog {
@@ -9,7 +10,7 @@ export class DialogChateauDormant extends Dialog {
motifStress: `Nuit du ${date}`,
finChateauDormant: game.system.rdd.calendrier.getTimestampFinChateauDormant()
};
- const html = await foundry.applications.handlebars.renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-chateau-dormant.hbs",
+ const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-chateau-dormant.hbs",
dialogData);
new DialogChateauDormant(dialogData, html)
diff --git a/module/sommeil/dialog-repos.js b/module/sommeil/dialog-repos.js
index 7374a520..a7267e51 100644
--- a/module/sommeil/dialog-repos.js
+++ b/module/sommeil/dialog-repos.js
@@ -1,3 +1,4 @@
+import { renderTemplate } from "../constants.js";
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
import { EffetsDraconiques } from "../tmr/effets-draconiques.js";
diff --git a/module/sommeil/dialog-stress.js b/module/sommeil/dialog-stress.js
index 0b30c323..cdf7928e 100644
--- a/module/sommeil/dialog-stress.js
+++ b/module/sommeil/dialog-stress.js
@@ -1,3 +1,4 @@
+import { renderTemplate } from "../constants.js";
export class DialogStress extends Dialog {
diff --git a/module/time/rdd-calendrier.js b/module/time/rdd-calendrier.js
index 1c1671c5..83eeee3a 100644
--- a/module/time/rdd-calendrier.js
+++ b/module/time/rdd-calendrier.js
@@ -4,7 +4,7 @@ import { RdDResolutionTable } from "../rdd-resolution-table.js";
import { RdDDice } from "../rdd-dice.js";
import { Misc } from "../misc.js";
import { DialogChronologie } from "../dialog-chronologie.js";
-import { HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
+import { HIDE_DICE, renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
import { DialogChateauDormant } from "../sommeil/dialog-chateau-dormant.js";
import { APP_ASTROLOGIE_REFRESH, AppAstrologie } from "../sommeil/app-astrologie.js";
diff --git a/module/tirage/fenetre-recherche-tirage.js b/module/tirage/fenetre-recherche-tirage.js
index 932778d0..c72ee938 100644
--- a/module/tirage/fenetre-recherche-tirage.js
+++ b/module/tirage/fenetre-recherche-tirage.js
@@ -4,6 +4,7 @@ import { Misc } from "../misc.js";
import { CompendiumTableHelpers } from '../settings/system-compendiums.js';
import { RdDRaretes } from '../item/raretes.js';
import { Grammar } from '../grammar.js';
+import { renderTemplate } from '../constants.js';
const FILTER_GROUPS = [
{ group: 'type', label: "Type d'objet" },
diff --git a/module/tmr-rencontres.js b/module/tmr-rencontres.js
index 684fdf85..2281517e 100644
--- a/module/tmr-rencontres.js
+++ b/module/tmr-rencontres.js
@@ -1,3 +1,4 @@
+import { renderTemplate } from "./constants.js";
import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
import { RdDDice } from "./rdd-dice.js";
@@ -102,7 +103,7 @@ export class TMRRencontres {
/* -------------------------------------------- */
async $chatRolledRencontre(row, rencontre, tmr) {
- const flavorContent = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll-rencontre.hbs',
+ const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll-rencontre.hbs',
{
roll: row.roll,
rencontre,
diff --git a/module/tmr/effets-rencontres.js b/module/tmr/effets-rencontres.js
index 183c876c..675218a4 100644
--- a/module/tmr/effets-rencontres.js
+++ b/module/tmr/effets-rencontres.js
@@ -1,5 +1,6 @@
import { ExperienceLog, XP_TOPIC } from "../actor/experience-log.js";
import { ChatUtility } from "../chat-utility.js";
+import { renderTemplate } from "../constants.js";
import { Poetique } from "../poetique.js";
import { RdDDice } from "../rdd-dice.js";
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
diff --git a/module/voyage/dialog-fatigue-voyage.js b/module/voyage/dialog-fatigue-voyage.js
index 18c96e41..d1adce19 100644
--- a/module/voyage/dialog-fatigue-voyage.js
+++ b/module/voyage/dialog-fatigue-voyage.js
@@ -1,4 +1,4 @@
-import { ITEM_TYPES } from "../constants.js"
+import { ITEM_TYPES, renderTemplate } from "../constants.js"
import { RdDItemCompetence } from "../item-competence.js"
import { ChatUtility } from "../chat-utility.js"
import { Misc } from "../misc.js"
diff --git a/templates/actor/combat.hbs b/templates/actor/combat.hbs
index 235327dc..68f686e4 100644
--- a/templates/actor/combat.hbs
+++ b/templates/actor/combat.hbs
@@ -9,15 +9,14 @@
{{#each combat as |action key|}}
+ data-tooltip="{{action.label}}: niveau {{plusMoins action.comp.system.niveau}}">
{{#if action.arme.img}}
{{/if}}
- {{action.name}}
+ {{action.label}}
- ({{action.comp.name}})
{{>"systems/foundryvtt-reve-de-dragon/templates/item/icon-arme-broken.hbs" action.arme}}
{{plusMoins action.comp.system.niveau}}
diff --git a/templates/actor/export-scriptarium/arme.hbs b/templates/actor/export-scriptarium/arme.hbs
index 572c9367..6a784d64 100644
--- a/templates/actor/export-scriptarium/arme.hbs
+++ b/templates/actor/export-scriptarium/arme.hbs
@@ -2,8 +2,8 @@
data-item-id="{{attaque.arme._id}}"
data-arme-name="{{attaque.arme.name}}"
data-competence-name="{{attaque.comp.name}}">
- {{#if attaque.name}}
- {{upperFirst attaque.name}}
+ {{#if attaque.label}}
+ {{upperFirst attaque.label}}
{{else}}
{{/if}}
diff --git a/templates/chat-demande-defense-v1.hbs b/templates/chat-demande-defense-v1.hbs
new file mode 100644
index 00000000..718e86dc
--- /dev/null
+++ b/templates/chat-demande-defense-v1.hbs
@@ -0,0 +1,103 @@
+
\ No newline at end of file
diff --git a/templates/chat-demande-defense.hbs b/templates/chat-demande-defense.hbs
index 718e86dc..75d544be 100644
--- a/templates/chat-demande-defense.hbs
+++ b/templates/chat-demande-defense.hbs
@@ -1,103 +1,59 @@
-
\ No newline at end of file
diff --git a/templates/chat-infojet.hbs b/templates/chat-infojet.hbs
index 696c607d..bc94b4c1 100644
--- a/templates/chat-infojet.hbs
+++ b/templates/chat-infojet.hbs
@@ -1,13 +1,11 @@
+{{log rolled}}
{{rolled.caracValue}} à {{plusMoins rolled.finalLevel}}
- {{#if (and rolled.factorHtml (gt rolled.factorHtml 1))}}
- ×{{{rolled.factorHtml}}}
- = {{rolled.score}}%
- ×{{{rolled.factorHtml}}}
- {{else}}
= {{rolled.score}}%
+ {{#if (and rolled.factorHtml (ne rolled.factorHtml 1))}}
+ ×{{{rolled.factorHtml}}}
{{/if}}
diff --git a/templates/hud-actor-attaque.hbs b/templates/hud-actor-attaque.hbs
index 4f841f16..8d650963 100644
--- a/templates/hud-actor-attaque.hbs
+++ b/templates/hud-actor-attaque.hbs
@@ -6,8 +6,8 @@
{{/unless}}
{{/each}}
diff --git a/templates/hud-actor-combat.hbs b/templates/hud-actor-combat.hbs
new file mode 100644
index 00000000..e3e921d4
--- /dev/null
+++ b/templates/hud-actor-combat.hbs
@@ -0,0 +1,34 @@
+{{log this}}
+
+
+
+
+
+
+ {{log combatant}}
+ {{#if combatant.system.init}}
+ {{combatant.system.init.value}} {{combatant.system.init.label}}
+ {{else}}Initiative...{{/if}}
+
+ {{selectOptions actions selected='' valueAttr='index' labelAttr='label'}}
+
+
+
+ {{!--
+ Initiative
+
--}}
+
+
+ Attaquer
+
+
+
+
diff --git a/templates/hud-actor-init.hbs b/templates/hud-actor-init.hbs
index a642e265..e4836c77 100644
--- a/templates/hud-actor-init.hbs
+++ b/templates/hud-actor-init.hbs
@@ -5,17 +5,17 @@
{{/each}}
{{#each commandes as |commande key|}}
{{/each}}
diff --git a/templates/roll/result/chat-attaque.hbs b/templates/roll/result/chat-attaque.hbs
index e69de29b..ba173d6c 100644
--- a/templates/roll/result/chat-attaque.hbs
+++ b/templates/roll/result/chat-attaque.hbs
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+ {{current.carac.label}} / {{current.comp.label}} à {{current.diff.value}}
+ {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.hbs"}}
+
+
+
+
+ {{#if rolled.isSuccess}}
+
+ {{opponent.name}} doit se défendre à {{current.diff.value}} ,
+ {{#if (eq current.dmg.mortalite 'empoignade')}}
+ ou {{active.name}} marquera un point d'empoignade
+ {{else if (eq current.dmg.mortalite 'non-mortel')}}
+ ou encaisser à {{plusMoins current.dmg.total}} (non-mortel)
+ {{else}}
+ {{!-- {{~#if (eq current.dmg.mortalite 'mortel')}} --}}
+ ou encaisser à {{plusMoins current.dmg.total}}
+ {{!-- {{~#if (eq current.dmg.mortalite 'cauchemar')}} --}}
+ {{!-- {{else}}
+ {{plusMoins dmg.total}} (entités de cauchemar) --}}
+ {{/if}}
+
+
+ {{#if show.recul}}
+
+
+ Si votre adversaire n'esquive pas cette {{show.recul.raison}}, il devra résister à l'impact ou reculer sous le choc!
+
+ {{/if}}
+ {{#if (eq particuliere 'rapidite')}}
+
+ Votre attaque rapide vous permet une deuxième attaque, ou une défense supplémentaire!
+
+ {{/if}}
+ {{else}}
+
Votre attaque a échoué!
+ {{/if}}
+ {{#if (eq current.tactique 'charge')}}
+
+
+ C'est une charge, vos parades auront un -4 et vous ne pourrez pas esquiver!
+
+ {{/if}}
+ {{#if (and (eq current.tactique 'feinte') rolled.isSuccess)}}
+
+
+ Votre feinte peut faire mouche!
+
+ {{/if}}
+
+ {{> "systems/foundryvtt-reve-de-dragon/templates/chat-info-appel-au-moral.hbs"}}
+
+
+
+
+ {{> 'partial-attaque-particuliere'}}
+ {{!-- TODO: maladresses --}}
+
+
+
+ {{> 'partial-appel-chance'}}
+
+
+
\ No newline at end of file
diff --git a/templates/roll/result/chat-comp.hbs b/templates/roll/result/chat-comp.hbs
new file mode 100644
index 00000000..91d7323a
--- /dev/null
+++ b/templates/roll/result/chat-comp.hbs
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+ {{current.carac.label}} / {{current.comp.label}} à {{current.diff.value}}
+ {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.hbs"}}
+
+
+
+
Qualité {{rolled.ptQualite}}, points de tâche {{rolled.ptQualite}}
+
+ {{> 'partial-info-appel-moral'}}
+
+
+ {{> 'partial-appel-chance'}}
+
+
diff --git a/templates/roll/result/chat-competence.hbs b/templates/roll/result/chat-competence.hbs
deleted file mode 100644
index e69de29b..00000000
diff --git a/templates/roll/result/chat-cuisine.hbs b/templates/roll/result/chat-cuisine.hbs
new file mode 100644
index 00000000..3b17db80
--- /dev/null
+++ b/templates/roll/result/chat-cuisine.hbs
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+ {{current.carac.label}} / {{current.comp.label}} à {{current.diff.value}}
+ {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.hbs"}}
+
+
+
+
+ {{active.name}}
+ {{#if rolled.isSuccess}}réussit la recette avec
+ {{else}}manque d'inspiration, le plat a
+ {{/if}}
+ une qualité de {{result.qualite}}.
+
+ {{> 'partial-info-appel-moral'}}
+ {{> "systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs" current.cuisine.recette.system}}
+
+
+ {{> 'partial-appel-chance'}}
+
+
diff --git a/templates/roll/result/chat-defense.hbs b/templates/roll/result/chat-defense.hbs
index b9c078a1..975134a9 100644
--- a/templates/roll/result/chat-defense.hbs
+++ b/templates/roll/result/chat-defense.hbs
@@ -1,9 +1,8 @@
-
-{{log this}}
+ {{!-- TODO: maladresses --}}
{{> 'partial-recul-choc'}}
{{> 'partial-encaissement'}}
diff --git a/templates/roll/result/chat-meditation.hbs b/templates/roll/result/chat-meditation.hbs
index e69de29b..362bc806 100644
--- a/templates/roll/result/chat-meditation.hbs
+++ b/templates/roll/result/chat-meditation.hbs
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+ {{current.carac.label}} / {{current.comp.label}} à {{current.diff.value}}
+ {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.hbs"}}
+
+
+
+
+
+ {{#if rolled.isSuccess}}
+
+ {{active.name}} aperçoit un signe draconique éphémère, qu'il faut aller lire en {{typeTmr-name current.meditation.meditation.system.tmr}} .
+
+ {{else}}
+ {{active.name}} ne distingue aucun signe Draconique, la meditation n'a pas porté de fruits.
+ {{/if}}
+
+
+ {{#if rolled.isEPart}}
+
+ L'échec {{#if rolled.isETotal}}total{{else}}particulier{{/if}} augmente la difficulté de la méditation
+ {{current.meditation.meditation.name}} de 1 !
+
+ {{/if}}
+
+ {{#if (regle-optionnelle 'appliquer-fatigue')}}
+
+
+ {{active.name}} s'est fatigué{{~#if (actor-isFeminin active.actor)}}e{{/if}} de 2 cases.
+
+ {{/if}}
+
+
+
+
+
diff --git a/templates/roll/result/chat-oeuvre.hbs b/templates/roll/result/chat-oeuvre.hbs
index f1b0b31e..f0300a72 100644
--- a/templates/roll/result/chat-oeuvre.hbs
+++ b/templates/roll/result/chat-oeuvre.hbs
@@ -1,8 +1,7 @@
-{{log this}}