Merge pull request 'v13.0.11 - Le gambit d'Illysis' (#775) from VincentVk/foundryvtt-reve-de-dragon:v13 into v13
All checks were successful
Release Creation / build (release) Successful in 2m2s

Reviewed-on: #775
This commit is contained in:
2025-10-09 14:14:44 +02:00
51 changed files with 736 additions and 242 deletions

View File

@@ -1,5 +1,11 @@
# 13.0 # 13.0
## 13.0.11 - Le gambit d'Illysis
- Nouvelle fenêtre de jets de dés
- jeux
- cuisine et préparation de nourriture
## 13.0.10 - Les papilles d'Illysis ## 13.0.10 - Les papilles d'Illysis
- Ajout d'un statut "saignement" en cas de blessure grave ou critique sans premiers soins - Ajout d'un statut "saignement" en cas de blessure grave ou critique sans premiers soins

View File

@@ -160,7 +160,7 @@ select,
min-height: 100px; min-height: 100px;
background: var(--rdd-bg-input-alt); background: var(--rdd-bg-input-alt);
padding: 5px; padding: 5px;
border-radius: 3px; border-radius: 0.2rem;
color: var(--rdd-color-text-primary); color: var(--rdd-color-text-primary);
} }
.system-foundryvtt-reve-de-dragon .monnaie-content .window-content { .system-foundryvtt-reve-de-dragon .monnaie-content .window-content {
@@ -177,7 +177,7 @@ select,
background: var(--fieldset-background); background: var(--fieldset-background);
color: var(--rdd-color-text-primary); color: var(--rdd-color-text-primary);
margin-bottom: 4px; margin-bottom: 4px;
border-radius: 6px; border-radius: 0.5rem;
border-color: var(--rdd-color-text-primary); border-color: var(--rdd-color-text-primary);
border-width: 2px; border-width: 2px;
} }
@@ -207,7 +207,7 @@ select,
border: 1px solid var(--rdd-color-border-input); border: 1px solid var(--rdd-color-border-input);
color: var(--rdd-color-text-input); color: var(--rdd-color-text-input);
padding: 2px 2px; padding: 2px 2px;
border-radius: 3px; border-radius: 0.2rem;
} }
.system-foundryvtt-reve-de-dragon .monnaie-content .form-group input[type="checkbox"] { .system-foundryvtt-reve-de-dragon .monnaie-content .form-group input[type="checkbox"] {
flex: 0 0 20px; flex: 0 0 20px;
@@ -251,7 +251,7 @@ select,
min-height: 100px; min-height: 100px;
background: var(--rdd-bg-input-alt); background: var(--rdd-bg-input-alt);
padding: 5px; padding: 5px;
border-radius: 3px; border-radius: 0.2rem;
color: var(--rdd-color-text-primary); color: var(--rdd-color-text-primary);
} }
.system-foundryvtt-reve-de-dragon .munition-content .window-content { .system-foundryvtt-reve-de-dragon .munition-content .window-content {
@@ -268,7 +268,7 @@ select,
background: var(--fieldset-background); background: var(--fieldset-background);
color: var(--rdd-color-text-primary); color: var(--rdd-color-text-primary);
margin-bottom: 4px; margin-bottom: 4px;
border-radius: 6px; border-radius: 0.5rem;
border-color: var(--rdd-color-text-primary); border-color: var(--rdd-color-text-primary);
border-width: 2px; border-width: 2px;
} }
@@ -298,7 +298,7 @@ select,
border: 1px solid var(--rdd-color-border-input); border: 1px solid var(--rdd-color-border-input);
color: var(--rdd-color-text-input); color: var(--rdd-color-text-input);
padding: 2px 2px; padding: 2px 2px;
border-radius: 3px; border-radius: 0.2rem;
} }
.system-foundryvtt-reve-de-dragon .munition-content .form-group input[type="checkbox"] { .system-foundryvtt-reve-de-dragon .munition-content .form-group input[type="checkbox"] {
flex: 0 0 20px; flex: 0 0 20px;
@@ -342,7 +342,7 @@ select,
min-height: 100px; min-height: 100px;
background: var(--rdd-bg-input-alt); background: var(--rdd-bg-input-alt);
padding: 5px; padding: 5px;
border-radius: 3px; border-radius: 0.2rem;
color: var(--rdd-color-text-primary); color: var(--rdd-color-text-primary);
} }
.system-foundryvtt-reve-de-dragon .tarot-content .window-content { .system-foundryvtt-reve-de-dragon .tarot-content .window-content {
@@ -359,7 +359,7 @@ select,
background: var(--fieldset-background); background: var(--fieldset-background);
color: var(--rdd-color-text-primary); color: var(--rdd-color-text-primary);
margin-bottom: 4px; margin-bottom: 4px;
border-radius: 6px; border-radius: 0.5rem;
border-color: var(--rdd-color-text-primary); border-color: var(--rdd-color-text-primary);
border-width: 2px; border-width: 2px;
} }
@@ -389,7 +389,7 @@ select,
border: 1px solid var(--rdd-color-border-input); border: 1px solid var(--rdd-color-border-input);
color: var(--rdd-color-text-input); color: var(--rdd-color-text-input);
padding: 2px 2px; padding: 2px 2px;
border-radius: 3px; border-radius: 0.2rem;
} }
.system-foundryvtt-reve-de-dragon .tarot-content .form-group input[type="checkbox"] { .system-foundryvtt-reve-de-dragon .tarot-content .form-group input[type="checkbox"] {
flex: 0 0 20px; flex: 0 0 20px;
@@ -530,7 +530,7 @@ select,
margin: 0.1rem 0; margin: 0.1rem 0;
} }
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section subline .warning { .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section subline .warning {
border-radius: 6px; border-radius: 0.5rem;
background: var(--gradient-warning); background: var(--gradient-warning);
} }
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-img { .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-img {
@@ -560,6 +560,7 @@ select,
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline div.poesie-extrait { .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline div.poesie-extrait {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: normal;
} }
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline span.status-surprise { .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline span.status-surprise {
display: flex; display: flex;
@@ -576,8 +577,12 @@ select,
display: flow; display: flow;
width: 2.5rem; width: 2.5rem;
text-align: right; text-align: right;
margin: 0 0.2rem 0 0.5rem; margin: 0 0.2rem;
padding: 0 0.2rem; padding: 0 0.2rem;
border: 1px solid ;
border-radius: 0.2rem;
height: 1.5rem;
background: hsla(0, 0%, 0%, 0.2);
} }
.system-foundryvtt-reve-de-dragon .roll-dialog roll-action { .system-foundryvtt-reve-de-dragon .roll-dialog roll-action {
flex-basis: content; flex-basis: content;
@@ -632,12 +637,13 @@ select,
margin: 0 0.1rem; margin: 0 0.1rem;
} }
.system-foundryvtt-reve-de-dragon .roll-dialog roll-carac select[name="select-carac"] { .system-foundryvtt-reve-de-dragon .roll-dialog roll-carac select[name="select-carac"] {
max-width: 6rem; min-width: 6.5rem;
max-width: 8rem;
} }
.system-foundryvtt-reve-de-dragon .roll-dialog roll-comp select[name="select-comp"] { .system-foundryvtt-reve-de-dragon .roll-dialog roll-comp select[name="select-comp"] {
min-width: 8rem; min-width: 8rem;
max-width: 11rem; max-width: 10rem;
margin-left: 1rem; margin-left: 1.5rem;
} }
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="coeur"] select[name="coeur"] { .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="coeur"] select[name="coeur"] {
max-width: 4rem; max-width: 4rem;
@@ -1463,38 +1469,38 @@ select,
} }
.system-foundryvtt-reve-de-dragon .rdd-roll-part { .system-foundryvtt-reve-de-dragon .rdd-roll-part {
align-items: center; align-items: center;
border-radius: 6px; border-radius: 0.5rem;
padding: 3px; padding: 3px;
background: var(--gradient-gold); background: var(--gradient-gold);
} }
.system-foundryvtt-reve-de-dragon .rdd-roll-sign { .system-foundryvtt-reve-de-dragon .rdd-roll-sign {
border-radius: 6px; border-radius: 0.5rem;
padding: 3px; padding: 3px;
background: var(--gradient-silver); background: var(--gradient-silver);
} }
.system-foundryvtt-reve-de-dragon .rdd-roll-norm { .system-foundryvtt-reve-de-dragon .rdd-roll-norm {
border-radius: 6px; border-radius: 0.5rem;
padding: 3px; padding: 3px;
background: var(--gradient-green); background: var(--gradient-green);
} }
.system-foundryvtt-reve-de-dragon .rdd-roll-notSign, .system-foundryvtt-reve-de-dragon .rdd-roll-notSign,
.system-foundryvtt-reve-de-dragon .rdd-roll-echec { .system-foundryvtt-reve-de-dragon .rdd-roll-echec {
border-radius: 6px; border-radius: 0.5rem;
padding: 3px; padding: 3px;
background: var(--gradient-red); background: var(--gradient-red);
} }
.system-foundryvtt-reve-de-dragon .rdd-roll-epart { .system-foundryvtt-reve-de-dragon .rdd-roll-epart {
border-radius: 6px; border-radius: 0.5rem;
padding: 3px; padding: 3px;
background: var(--gradient-violet); background: var(--gradient-violet);
} }
.system-foundryvtt-reve-de-dragon .rdd-roll-etotal { .system-foundryvtt-reve-de-dragon .rdd-roll-etotal {
border-radius: 6px; border-radius: 0.5rem;
padding: 3px; padding: 3px;
background: var(--gradient-purple-black); background: var(--gradient-purple-black);
} }
.system-foundryvtt-reve-de-dragon .rdd-diviseur { .system-foundryvtt-reve-de-dragon .rdd-diviseur {
border-radius: 6px; border-radius: 0.5rem;
padding: 3px; padding: 3px;
background: var(--gradient-red); background: var(--gradient-red);
} }
@@ -1521,12 +1527,8 @@ select,
font-size: 0.8rem; font-size: 0.8rem;
font-style: italic; font-style: italic;
color: rgba(82, 17, 131, 0.9); color: rgba(82, 17, 131, 0.9);
overflow: hidden; overflow-y: scroll;
} width: 100%;
.system-foundryvtt-reve-de-dragon .poesie-extrait:hover {
max-height: unset;
overflow: visible;
opacity: 1;
} }
.system-foundryvtt-reve-de-dragon .poesie-reference { .system-foundryvtt-reve-de-dragon .poesie-reference {
font-size: 0.7rem; font-size: 0.7rem;
@@ -1592,7 +1594,7 @@ select,
height: var(--form-field-height); height: var(--form-field-height);
margin: 0; margin: 0;
color: var(--color-text-dark-primary); color: var(--color-text-dark-primary);
border-radius: 3px; border-radius: 0.2rem;
} }
.system-foundryvtt-reve-de-dragon .app-calendar-astrologie div.theme-astral { .system-foundryvtt-reve-de-dragon .app-calendar-astrologie div.theme-astral {
width: 14rem; width: 14rem;
@@ -1643,7 +1645,7 @@ select,
background: hsla(280, 50%, 50%, 0.1); background: hsla(280, 50%, 50%, 0.1);
padding: 1px 4px; padding: 1px 4px;
border: 1px solid var(--color-border-dark-tertiary); border: 1px solid var(--color-border-dark-tertiary);
border-radius: 2px; border-radius: 0.2rem;
white-space: nowrap; white-space: nowrap;
word-break: break-all; word-break: break-all;
} }
@@ -1653,7 +1655,7 @@ select,
font-weight: 560; font-weight: 560;
padding: 0.1rem 0.3rem; padding: 0.1rem 0.3rem;
border: 1px solid var(--color-border-dark-tertiary); border: 1px solid var(--color-border-dark-tertiary);
border-radius: 0.25rem; border-radius: 0.2rem;
white-space: nowrap; white-space: nowrap;
word-break: break-all; word-break: break-all;
display: ruby; display: ruby;
@@ -1773,7 +1775,7 @@ select,
.system-foundryvtt-reve-de-dragon .xp-level-up { .system-foundryvtt-reve-de-dragon .xp-level-up {
margin: 0.1rem; margin: 0.1rem;
box-shadow: inset 0px 0px 1px #00000096; box-shadow: inset 0px 0px 1px #00000096;
border-radius: 0.25rem; border-radius: 0.2rem;
padding: 0.1rem; padding: 0.1rem;
flex: 1 1 5rem; flex: 1 1 5rem;
background: var(--gradient-gold) !important; background: var(--gradient-gold) !important;
@@ -1804,7 +1806,7 @@ select,
.system-foundryvtt-reve-de-dragon .list-item { .system-foundryvtt-reve-de-dragon .list-item {
margin: 0.1rem; margin: 0.1rem;
box-shadow: inset 0px 0px 1px #00000096; box-shadow: inset 0px 0px 1px #00000096;
border-radius: 0.25rem; border-radius: 0.2rem;
padding: 0.1rem; padding: 0.1rem;
flex: 1 1 1.5rem; flex: 1 1 1.5rem;
display: flex; display: flex;
@@ -2117,6 +2119,9 @@ select,
font-size: 0.7rem; font-size: 0.7rem;
flex-grow: 3; flex-grow: 3;
} }
.system-foundryvtt-reve-de-dragon .chat-message header.message-header .message-metadata {
flex-grow: 3.5;
}
.system-foundryvtt-reve-de-dragon .chat-message hr { .system-foundryvtt-reve-de-dragon .chat-message hr {
margin: 0.2rem 0; margin: 0.2rem 0;
} }
@@ -2337,7 +2342,7 @@ select,
font-size: 0.8rem; font-size: 0.8rem;
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
border-radius: 0.3rem; border-radius: 0.2rem;
} }
.system-foundryvtt-reve-de-dragon div.horloge-roue div img { .system-foundryvtt-reve-de-dragon div.horloge-roue div img {
border: none; border: none;
@@ -2664,7 +2669,7 @@ select,
.system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements { .system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements {
width: 10rem; width: 10rem;
background: var(--background-tooltip); background: var(--background-tooltip);
border-radius: 6px; border-radius: 0.5rem;
font-size: 0.9rem; font-size: 0.9rem;
padding: 3px 0; padding: 3px 0;
} }

1
icons/cuisine/gibier.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.8 KiB

1
icons/cuisine/herbe.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.6 KiB

1
icons/cuisine/plante.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.8 KiB

1
icons/cuisine/ragout.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -777,31 +777,31 @@
} }
.rdd-roll-part { .rdd-roll-part {
align-items: center; align-items: center;
border-radius: 6px; padding: 3px; border-radius: 0.5rem; padding: 3px;
background: var(--gradient-gold); background: var(--gradient-gold);
} }
.rdd-roll-sign{ .rdd-roll-sign{
border-radius: 6px; padding: 3px; border-radius: 0.5rem; padding: 3px;
background: var(--gradient-silver); background: var(--gradient-silver);
} }
.rdd-roll-norm{ .rdd-roll-norm{
border-radius: 6px; padding: 3px; border-radius: 0.5rem; padding: 3px;
background: var(--gradient-green); background: var(--gradient-green);
} }
.rdd-roll-notSign, .rdd-roll-echec{ .rdd-roll-notSign, .rdd-roll-echec{
border-radius: 6px; padding: 3px; border-radius: 0.5rem; padding: 3px;
background: var(--gradient-red); background: var(--gradient-red);
} }
.rdd-roll-epart{ .rdd-roll-epart{
border-radius: 6px; padding: 3px; border-radius: 0.5rem; padding: 3px;
background: var(--gradient-violet); background: var(--gradient-violet);
} }
.rdd-roll-etotal{ .rdd-roll-etotal{
border-radius: 6px; padding: 3px; border-radius: 0.5rem; padding: 3px;
background: var(--gradient-purple-black); background: var(--gradient-purple-black);
} }
.rdd-diviseur{ .rdd-diviseur{
border-radius: 6px; padding: 3px; border-radius: 0.5rem; padding: 3px;
background: var(--gradient-red); background: var(--gradient-red);
} }
@@ -832,15 +832,10 @@
font-size: 0.8rem; font-size: 0.8rem;
font-style: italic; font-style: italic;
color: rgba(82, 17, 131, 0.9); color: rgba(82, 17, 131, 0.9);
overflow: hidden; overflow-y: scroll;
width: 100%;
} }
.poesie-extrait:hover {
max-height: unset;
overflow: visible;
opacity: 1;
}
.poesie-reference { .poesie-reference {
font-size: 0.7rem; font-size: 0.7rem;
text-align: right; text-align: right;
@@ -913,7 +908,7 @@
height: var(--form-field-height); height: var(--form-field-height);
margin: 0; margin: 0;
color: var(--color-text-dark-primary); color: var(--color-text-dark-primary);
border-radius: 3px; border-radius: 0.2rem;
} }
.app-calendar-astrologie{ .app-calendar-astrologie{
div.theme-astral{ div.theme-astral{
@@ -970,7 +965,7 @@
background: hsla(280, 50%, 50%, 0.1); background: hsla(280, 50%, 50%, 0.1);
padding: 1px 4px; padding: 1px 4px;
border: 1px solid var(--color-border-dark-tertiary); border: 1px solid var(--color-border-dark-tertiary);
border-radius: 2px; border-radius: 0.2rem;
white-space: nowrap; white-space: nowrap;
word-break: break-all; word-break: break-all;
} }
@@ -981,7 +976,7 @@
font-weight: 560; font-weight: 560;
padding: 0.1rem 0.3rem; padding: 0.1rem 0.3rem;
border: 1px solid var(--color-border-dark-tertiary); border: 1px solid var(--color-border-dark-tertiary);
border-radius: 0.25rem; border-radius: 0.2rem;
white-space: nowrap; white-space: nowrap;
word-break: break-all; word-break: break-all;
display: ruby; display: ruby;
@@ -1111,7 +1106,7 @@
.xp-level-up { .xp-level-up {
margin: 0.1rem; margin: 0.1rem;
box-shadow: inset 0px 0px 1px #00000096; box-shadow: inset 0px 0px 1px #00000096;
border-radius: 0.25rem; border-radius: 0.2rem;
padding: 0.1rem; padding: 0.1rem;
flex: 1 1 5rem; flex: 1 1 5rem;
background: var(--gradient-gold) !important; background: var(--gradient-gold) !important;
@@ -1142,7 +1137,7 @@
.list-item { .list-item {
margin: 0.1rem; margin: 0.1rem;
box-shadow: inset 0px 0px 1px #00000096; box-shadow: inset 0px 0px 1px #00000096;
border-radius: 0.25rem; border-radius: 0.2rem;
padding: 0.1rem; padding: 0.1rem;
flex: 1 1 1.5rem; flex: 1 1 1.5rem;
display: flex; display: flex;
@@ -1483,10 +1478,15 @@
.message-content { .message-content {
text-align: justify; text-align: justify;
} }
header.message-header .heure-rdd { header.message-header{
font-size: 0.7rem; .heure-rdd {
flex-grow: 3; font-size: 0.7rem;
} flex-grow: 3;
}
.message-metadata {
flex-grow: 3.5;
}
}
hr { hr {
margin: 0.2rem 0; margin: 0.2rem 0;
} }
@@ -1685,7 +1685,7 @@
font-size: 0.8rem; font-size: 0.8rem;
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
border-radius: 0.3rem; border-radius: 0.2rem;
} }
div.horloge-roue div img { div.horloge-roue div img {
@@ -1921,7 +1921,7 @@
.ttt-ajustements { .ttt-ajustements {
width: 10rem; width: 10rem;
background: var(--background-tooltip); background: var(--background-tooltip);
border-radius: 6px; border-radius: 0.5rem;
font-size: 0.9rem; font-size: 0.9rem;
padding: 3px 0; padding: 3px 0;
div:nth-child(odd) { div:nth-child(odd) {

View File

@@ -90,7 +90,7 @@
flex-direction: row; flex-direction: row;
margin: 0.1rem 0; margin: 0.1rem 0;
.warning { .warning {
border-radius: 6px; border-radius: 0.5rem;
background: var(--gradient-warning); background: var(--gradient-warning);
} }
} }
@@ -121,6 +121,7 @@
div.poesie-extrait{ div.poesie-extrait{
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: normal;
} }
span.status-surprise{ span.status-surprise{
display: flex; display: flex;
@@ -141,8 +142,13 @@
display: flow; display: flow;
width: 2.5rem; width: 2.5rem;
text-align: right; text-align: right;
margin: 0 0.2rem 0 0.5rem; margin: 0 0.2rem;
padding: 0 0.2rem; padding: 0 0.2rem;
border: 1px solid ;
border-radius: 0.2rem ;
background: hsla(0, 0%, 0%, 0.2);
height: 1.5rem;
background: hsla(0, 0%, 0%, 0.2);
} }
roll-action { roll-action {
@@ -205,14 +211,14 @@
} }
roll-carac select[name="select-carac"] { roll-carac select[name="select-carac"] {
max-width: 6rem; min-width: 6.5rem;
max-width: 8rem;
} }
roll-comp select[name="select-comp"] { roll-comp select[name="select-comp"] {
min-width: 8rem; min-width: 8rem;
max-width: 11rem; max-width: 10rem;
margin-left: 1rem; margin-left: 1.5rem;
} }
roll-conditions roll-section[name="coeur"] select[name="coeur"] { roll-conditions roll-section[name="coeur"] select[name="coeur"] {
max-width: 4rem; max-width: 4rem;

View File

@@ -8,7 +8,7 @@
min-height: 100px; // Hauteur minimale pour la description min-height: 100px; // Hauteur minimale pour la description
background: var(--rdd-bg-input-alt); // Une couleur de fond alternative background: var(--rdd-bg-input-alt); // Une couleur de fond alternative
padding: 5px; padding: 5px;
border-radius: 3px; border-radius: 0.2rem;
color: var(--rdd-color-text-primary); color: var(--rdd-color-text-primary);
} }
@@ -28,7 +28,7 @@
background: var(--fieldset-background); background: var(--fieldset-background);
color: var(--rdd-color-text-primary); color: var(--rdd-color-text-primary);
margin-bottom: 4px; margin-bottom: 4px;
border-radius: 6px; border-radius: 0.5rem;
border-color: var(--rdd-color-text-primary); border-color: var(--rdd-color-text-primary);
border-width: 2px; border-width: 2px;
} }
@@ -64,7 +64,7 @@
--rdd-color-text-input --rdd-color-text-input
); // Assurez-vous que cette variable existe ); // Assurez-vous que cette variable existe
padding: 2px 2px; // Augmentation du padding vertical padding: 2px 2px; // Augmentation du padding vertical
border-radius: 3px; border-radius: 0.2rem;
} }
input[type="checkbox"] { input[type="checkbox"] {

View File

@@ -47,9 +47,11 @@ import { RdDRollResult } from "./rdd-roll-result.js";
import { RdDInitiative } from "./initiative.mjs"; import { RdDInitiative } from "./initiative.mjs";
import RollDialog from "./roll/roll-dialog.mjs"; import RollDialog from "./roll/roll-dialog.mjs";
import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js"; import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js";
import { ROLL_TYPE_MEDITATION } from "./roll/roll-constants.mjs"; import { ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION } from "./roll/roll-constants.mjs";
import { PART_TACHE } from "./roll/roll-part-tache.mjs"; import { PART_TACHE } from "./roll/roll-part-tache.mjs";
import { PART_COMP } from "./roll/roll-part-comp.mjs"; import { PART_COMP } from "./roll/roll-part-comp.mjs";
import { PART_OEUVRE } from "./roll/roll-part-oeuvre.mjs";
import { PART_CUISINE } from "./roll/roll-part-cuisine.mjs";
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
@@ -163,10 +165,10 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
getDemiReve() { return this.system.reve.tmrpos.coord } getDemiReve() { return this.system.reve.tmrpos.coord }
getDraconicList() { return this.itemTypes[ITEM_TYPES.competence].filter(it => it.system.categorie == 'draconic') } getDraconics() { return this.itemTypes[ITEM_TYPES.competence].filter(it => it.system.categorie == 'draconic') }
getBestDraconic() { return foundry.utils.duplicate([...this.getDraconicList(), PAS_DE_DRACONIC].sort(Misc.descending(it => it.system.niveau)).find(it => true)) } getBestDraconic() { return foundry.utils.duplicate([...this.getDraconics(), PAS_DE_DRACONIC].sort(Misc.descending(it => it.system.niveau)).find(it => true)) }
getDraconicOuPossession() { getDraconicOuPossession() {
return [...this.getDraconicList().filter(it => it.system.niveau >= 0), POSSESSION_SANS_DRACONIC] return [...this.getDraconics().filter(it => it.system.niveau >= 0), POSSESSION_SANS_DRACONIC]
.sort(Misc.descending(it => it.system.niveau)) .sort(Misc.descending(it => it.system.niveau))
.find(it => true) .find(it => true)
} }
@@ -703,11 +705,12 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async combattreReveDeDragon(force) { async combattreReveDeDragon(force) {
const rencontre = await game.system.rdd.rencontresTMR.getReveDeDragon(force);
let rollData = { let rollData = {
actor: this, actor: this,
competence: this.getDraconicOuPossession(), competence: this.getDraconicOuPossession(),
canClose: false, canClose: false,
rencontre: await game.system.rdd.rencontresTMR.getReveDeDragon(force), rencontre: rencontre,
tmr: true, tmr: true,
use: { libre: false, conditions: false }, use: { libre: false, conditions: false },
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } } forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } }
@@ -1688,7 +1691,7 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
computeDraconicAndSortIndex(sortList) { computeDraconicAndSortIndex(sortList) {
let draconicList = this.getDraconicList(); let draconicList = this.getDraconics();
for (let sort of sortList) { for (let sort of sortList) {
let draconicsSort = RdDItemSort.getDraconicsSort(draconicList, sort).map(it => it.name); let draconicsSort = RdDItemSort.getDraconicsSort(draconicList, sort).map(it => it.name);
for (let index = 0; index < draconicList.length && sort.system.listIndex == undefined; index++) { for (let index = 0; index < draconicList.length && sort.system.listIndex == undefined; index++) {
@@ -1933,12 +1936,13 @@ export class RdDActor extends RdDBaseActorSang {
const rollData = { const rollData = {
ids: { actorId: this.id }, ids: { actorId: this.id },
type: { allowed: [PART_COMP], current: PART_COMP }, type: { allowed: [PART_COMP], current: PART_COMP },
selected: { selected: {
carac: {key: caracName }, carac: { key: caracName },
comp: { key: compName, forced: options.forced } comp: { key: compName, forced: options.forced },
diff: { value: diff ?? 0 }
} }
} }
RollDialog.create(rollData, options) RollDialog.create(rollData, foundry.utils.mergeObject(options, { onRollDone: RollDialog.onRollDoneClose }))
return return
} }
@@ -1970,7 +1974,7 @@ export class RdDActor extends RdDBaseActorSang {
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = { const rollData = {
ids: { actorId: this.id }, ids: { actorId: this.id },
selected: { tache: { key: tache.id, forced: options.forced} }, selected: { tache: { key: tache.id, forced: options.forced } },
type: { allowed: [PART_TACHE], current: PART_TACHE } type: { allowed: [PART_TACHE], current: PART_TACHE }
} }
RollDialog.create(rollData, options) RollDialog.create(rollData, options)
@@ -2025,9 +2029,19 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollJeu(id) { async rollJeu(id) {
const oeuvre = this.getJeu(id); const jeu = this.getJeu(id);
const listCarac = oeuvre.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim()); if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
selected: { jeu: { key: jeu.id } },
type: { allowed: [ROLL_TYPE_JEU], current: ROLL_TYPE_JEU }
}
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return
}
const listCarac = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim());
const carac = listCarac.length > 0 ? listCarac[0] : 'chance' const carac = listCarac.length > 0 ? listCarac[0] : 'chance'
const artData = { const artData = {
art: 'jeu', verbe: 'Jeu', art: 'jeu', verbe: 'Jeu',
@@ -2037,8 +2051,8 @@ export class RdDActor extends RdDBaseActorSang {
}; };
listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]); listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]);
artData.competence.system.niveauReel = artData.competence.system.niveau; artData.competence.system.niveauReel = artData.competence.system.niveau;
artData.competence.system.niveau = Math.max(artData.competence.system.niveau, oeuvre.system.base); artData.competence.system.niveau = Math.max(artData.competence.system.niveau, jeu.system.base);
await this._rollArtV1(artData, carac, oeuvre); await this._rollArtV1(artData, carac, jeu);
} }
@@ -2052,7 +2066,7 @@ export class RdDActor extends RdDBaseActorSang {
selected: { meditation: { key: id } }, selected: { meditation: { key: id } },
type: { allowed: [ROLL_TYPE_MEDITATION], current: ROLL_TYPE_MEDITATION } type: { allowed: [ROLL_TYPE_MEDITATION], current: ROLL_TYPE_MEDITATION }
} }
await RollDialog.create(rollData) await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return return
} }
@@ -2114,7 +2128,7 @@ export class RdDActor extends RdDBaseActorSang {
ui.notifications.info(`Aucun signe draconiques en ${coord} !`); ui.notifications.info(`Aucun signe draconiques en ${coord} !`);
return; return;
} }
let draconicList = this.getDraconicList() let draconicList = this.getDraconics()
.map(draconic => { .map(draconic => {
let draconicLecture = foundry.utils.duplicate(draconic); let draconicLecture = foundry.utils.duplicate(draconic);
draconicLecture.system.defaut_carac = "intellect"; draconicLecture.system.defaut_carac = "intellect";
@@ -2395,7 +2409,7 @@ export class RdDActor extends RdDBaseActorSang {
return return
} }
if (mode != 'visu' && this.isDemiReve()) { if (mode != 'visu' && this.isDemiReve()) {
ui.notifications.warn("Les personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation") ui.notifications.warn("Le personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation")
mode = "visu"; // bascule le mode en visu automatiquement mode = "visu"; // bascule le mode en visu automatiquement
} }
if (mode == 'visu') { if (mode == 'visu') {
@@ -2434,7 +2448,7 @@ export class RdDActor extends RdDBaseActorSang {
let tmrFormData = { let tmrFormData = {
mode: mode, mode: mode,
fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance), fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance),
draconic: this.getDraconicList(), draconic: this.getDraconics(),
sort: this.itemTypes['sort'], sort: this.itemTypes['sort'],
signes: this.itemTypes['signedraconique'], signes: this.itemTypes['signedraconique'],
caracReve: parseInt(this.system.carac.reve.value), caracReve: parseInt(this.system.carac.reve.value),
@@ -3098,17 +3112,9 @@ export class RdDActor extends RdDBaseActorSang {
async _rollArtV2(oeuvreId) { async _rollArtV2(oeuvreId) {
const oeuvre = this.items.get(oeuvreId) const oeuvre = this.items.get(oeuvreId)
const rollData = { const rollData = {
title: `Interpretation de ${oeuvre.name} par ${this.name}`, ids: { actorId: this.id },
type: { selected: { oeuvre: { key: oeuvre.id } },
allowed: ["oeuvre"], type: { allowed: [PART_OEUVRE], current: PART_OEUVRE, },
current: "oeuvre",
},
selected: {
oeuvre: { key: oeuvre.id },
},
ids: {
actorId: this.id
}
} }
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose }) await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
} }
@@ -3206,14 +3212,26 @@ export class RdDActor extends RdDBaseActorSang {
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollRecetteCuisine(id) { async rollRecetteCuisine(id) {
const oeuvre = this.getRecetteCuisine(id); const recette = this.getRecetteCuisine(id);
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
type: { allowed: [PART_CUISINE], current: PART_CUISINE },
selected: {
cuisine: { key: recette.id }
}
}
RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return
}
const artData = { const artData = {
verbe: 'Cuisiner', verbe: 'Cuisiner',
compName: 'cuisine', compName: 'cuisine',
proportions: 1, proportions: 1,
ajouterEquipement: false ajouterEquipement: false
}; };
await this._rollArtV1(artData, 'odoratgout', oeuvre, r => this._resultRecetteCuisine(r)); await this._rollArtV1(artData, 'odoratgout', recette, r => this._resultRecetteCuisine(r));
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -3246,6 +3264,18 @@ export class RdDActor extends RdDBaseActorSang {
} }
async preparerNourriture(item) { async preparerNourriture(item) {
if (item.getUtilisationCuisine() == 'brut' && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
const rollData = {
ids: { actorId: this.id },
type: { allowed: [PART_CUISINE], current: PART_CUISINE },
selected: {
cuisine: { key: item.id }
}
}
RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
return
}
if (item.getUtilisationCuisine() == 'brut') { if (item.getUtilisationCuisine() == 'brut') {
const nourriture = { const nourriture = {
name: 'Plat de ' + item.name, name: 'Plat de ' + item.name,
@@ -3256,7 +3286,7 @@ export class RdDActor extends RdDBaseActorSang {
exotisme: item.system.exotisme, exotisme: item.system.exotisme,
ingredients: item.name ingredients: item.name
} }
}; }
const artData = { const artData = {
verbe: 'Préparer', verbe: 'Préparer',
compName: 'cuisine', compName: 'cuisine',

View File

@@ -191,7 +191,7 @@ export class ChatUtility {
const timestamp = new RdDTimestamp(rddTimestamp); const timestamp = new RdDTimestamp(rddTimestamp);
const timestampData = timestamp.toCalendrier(); const timestampData = timestamp.toCalendrier();
const dateHeure = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData); const dateHeure = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData);
$(html).find('header.message-header .message-sender').after(dateHeure) $(html).find('header.message-header .message-timestamp').after(dateHeure)
} }
} }

View File

@@ -6,8 +6,8 @@ const tableEffets = [
{ code: "passeur", resultat: "succes", description: "Déplacer le demi-rêve à (force) cases", method: EffetsRencontre.passeur}, { code: "passeur", resultat: "succes", description: "Déplacer le demi-rêve à (force) cases", method: EffetsRencontre.passeur},
{ code: "reve+f", resultat: "succes", description: "Gain de (force) points de rêve" , method: EffetsRencontre.reve_plus_force}, { code: "reve+f", resultat: "succes", description: "Gain de (force) points de rêve" , method: EffetsRencontre.reve_plus_force},
{ code: "teleport", resultat: "succes", description: "Déplacer le demi-rêve (même type)", method: EffetsRencontre.teleportation_typecase }, { code: "teleport", resultat: "succes", description: "Déplacer le demi-rêve (même type)", method: EffetsRencontre.teleportation_typecase },
{ code: "part+tete", resultat: "succes", description: "Tête de dragon sur réussite particulière", method: EffetsRencontre.rdd_part_tete }, { code: "part+tete", resultat: "succes", description: "Tête de dragon sur particulière", method: EffetsRencontre.rdd_part_tete },
{ code: "part+xp", resultat: "succes", description: "Expérience sur réussite particulière", method: EffetsRencontre.experience_particuliere }, { code: "part+xp", resultat: "succes", description: "Expérience sur particulière", method: EffetsRencontre.experience_particuliere },
{ code: "seuil", resultat: "succes", description: "Récupération de seuil de rêve", method: EffetsRencontre.regain_seuil }, { code: "seuil", resultat: "succes", description: "Récupération de seuil de rêve", method: EffetsRencontre.regain_seuil },
{ code: "reve-1", resultat: "echec", description: "Perte de 1 point de rêve", method: EffetsRencontre.reve_moins_1 }, { code: "reve-1", resultat: "echec", description: "Perte de 1 point de rêve", method: EffetsRencontre.reve_moins_1 },
@@ -19,7 +19,7 @@ const tableEffets = [
{ code: "aleatoire", resultat: "echec", description: "Déplacement aléatoire", method: EffetsRencontre.deplacement_aleatoire }, { code: "aleatoire", resultat: "echec", description: "Déplacement aléatoire", method: EffetsRencontre.deplacement_aleatoire },
{ code: "sort-aleatoire", resultat: "echec", description: "Déclenche un sort en réserve aléatoire", method: EffetsRencontre.sort_aleatoire }, { code: "sort-aleatoire", resultat: "echec", description: "Déclenche un sort en réserve aléatoire", method: EffetsRencontre.sort_aleatoire },
{ code: "rompu", resultat: "echec", description: "Demi-rêve interrompu", method: EffetsRencontre.demireve_rompu }, { code: "rompu", resultat: "echec", description: "Demi-rêve interrompu", method: EffetsRencontre.demireve_rompu },
{ code: "echec-queue", resultat: "echec", description: "Queue(s) de dragon sur échec", method: EffetsRencontre.rdd_echec_queue }, { code: "echec-queue", resultat: "echec", description: "Queue(s) de dragon", method: EffetsRencontre.rdd_echec_queue },
{ code: "reve+1", resultat: "succes", description: "Gain de 1 point de rêve", method: EffetsRencontre.reve_plus_1 }, { code: "reve+1", resultat: "succes", description: "Gain de 1 point de rêve", method: EffetsRencontre.reve_plus_1 },
{ code: "vie-f", resultat: "echec", description: "Perte de (force) points de vie", method: EffetsRencontre.vie_moins_force }, { code: "vie-f", resultat: "echec", description: "Perte de (force) points de vie", method: EffetsRencontre.vie_moins_force },

View File

@@ -6,6 +6,8 @@ import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
import { RdDResolutionTable } from "../rdd-resolution-table.js" import { RdDResolutionTable } from "../rdd-resolution-table.js"
import { RDD_CONFIG, renderTemplate } from "../constants.js" import { RDD_CONFIG, renderTemplate } from "../constants.js"
import { EMPOIGNADE } from "../item/arme.js" import { EMPOIGNADE } from "../item/arme.js"
import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js"
import { RollTypeCuisine } from "./roll-type-cuisine.mjs"
export default class ChatRollResult { export default class ChatRollResult {
static init() { static init() {
@@ -24,7 +26,7 @@ export default class ChatRollResult {
}) })
} }
async display(roll) { async display(roll, impacts) {
this.prepareDisplay(roll) this.prepareDisplay(roll)
const chatMessage = await ChatUtility.createChatWithRollMode( const chatMessage = await ChatUtility.createChatWithRollMode(
@@ -34,7 +36,8 @@ export default class ChatRollResult {
roll.active.actor, roll.active.actor,
roll.current?.rollmode?.key roll.current?.rollmode?.key
) )
const save = RollDialog.saveParts(roll) const save = RollDialog.saveParts(roll, impacts)
ChatUtility.setMessageData(chatMessage, 'rollData', save) ChatUtility.setMessageData(chatMessage, 'rollData', save)
return chatMessage return chatMessage
} }
@@ -98,7 +101,8 @@ export default class ChatRollResult {
async buildRollHtml(roll) { async buildRollHtml(roll) {
const template = `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${roll.type.current}.hbs` const template = `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${roll.type.current}.hbs`
return await renderTemplate(template, roll) const html = await renderTemplate(template, roll)
return await RdDTextEditor.enrichHTML(html, undefined, { showLink: false })
} }
async chatListeners(html) { async chatListeners(html) {
@@ -107,6 +111,7 @@ export default class ChatRollResult {
$(html).on("click", '.encaissement', event => this.onClickEncaissement(event)) $(html).on("click", '.encaissement', event => this.onClickEncaissement(event))
$(html).on("click", '.resister-recul', event => this.onClickRecul(event)) $(html).on("click", '.resister-recul', event => this.onClickRecul(event))
$(html).on("click", '.choix-particuliere', event => this.onClickChoixParticuliere(event)) $(html).on("click", '.choix-particuliere', event => this.onClickChoixParticuliere(event))
$(html).on("click", '.faire-gouter', event => this.onClickFaireGouter(event))
} }
@@ -141,6 +146,7 @@ export default class ChatRollResult {
onAppelChanceSuccess(savedRoll, chatMessage) { onAppelChanceSuccess(savedRoll, chatMessage) {
const reRoll = foundry.utils.duplicate(savedRoll) const reRoll = foundry.utils.duplicate(savedRoll)
console.log('onAppelChanceSuccess savedRoll', savedRoll)
reRoll.type.retry = true reRoll.type.retry = true
const callbacks = [r => ChatUtility.removeChatMessageId(chatMessage.id)] const callbacks = [r => ChatUtility.removeChatMessageId(chatMessage.id)]
// TODO: annuler les effets // TODO: annuler les effets
@@ -209,4 +215,9 @@ export default class ChatRollResult {
await this.updateChatMessage(chatMessage, savedRoll) await this.updateChatMessage(chatMessage, savedRoll)
await this.getCombat(savedRoll)?.onAttaqueV2(savedRoll, callbacks) await this.getCombat(savedRoll)?.onAttaqueV2(savedRoll, callbacks)
} }
async onClickFaireGouter(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
await new RollTypeCuisine().onFaireGouter(savedRoll)
}
} }

View File

@@ -1,4 +1,4 @@
import { ActorToken } from "../actor-token.mjs" import { TokenActor } from "../technical/actor-token.mjs"
import { StatusEffects } from "../settings/status-effects.js" import { StatusEffects } from "../settings/status-effects.js"
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
import { PART_ATTAQUE } from "./roll-part-attaque.mjs" import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
@@ -9,8 +9,8 @@ export class RollBasicParts {
static restore(rollData) { static restore(rollData) {
rollData.ids.sceneId = rollData.ids.sceneId ?? canvas.scene.id rollData.ids.sceneId = rollData.ids.sceneId ?? canvas.scene.id
rollData.active = RollBasicParts.$getActor(rollData) rollData.active = RollBasicParts.getTokenActor(rollData)
rollData.opponent = RollBasicParts.$getOpponent(rollData) rollData.opponent = RollBasicParts.getTokenActorOpponent(rollData)
if (rollData.type.opposed == undefined) { if (rollData.type.opposed == undefined) {
rollData.type.opposed = rollData.opponent != null rollData.type.opposed = rollData.opponent != null
} }
@@ -40,6 +40,7 @@ export class RollBasicParts {
} }
static initFrom(rollData) { static initFrom(rollData) {
const isOpposed = rollData.type.opposed && rollData.opponent
return { return {
selected: {}, selected: {},
type: rollData.type, type: rollData.type,
@@ -47,8 +48,8 @@ export class RollBasicParts {
sceneId: rollData.ids.sceneId, sceneId: rollData.ids.sceneId,
actorId: rollData.active.id, actorId: rollData.active.id,
actorTokenId: rollData.active.tokenId, actorTokenId: rollData.active.tokenId,
opponentId: rollData.type.opposed ? rollData.opponent.id : undefined, opponentId: isOpposed ? rollData.opponent.id : undefined,
opponentTokenId: rollData.type.opposed ? rollData.opponent.tokenId : undefined, opponentTokenId: isOpposed ? rollData.opponent.tokenId : undefined,
} }
} }
} }
@@ -63,30 +64,30 @@ export class RollBasicParts {
} }
} }
static $getActor(rollData) { static getTokenActor(rollData) {
if (rollData.ids.actorTokenId) { if (rollData.ids.actorTokenId) {
return ActorToken.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId) return TokenActor.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId)
} }
else { else {
const actorId = rollData.ids.actorId ?? (canvas.tokens.controlled.length == 1 const actorId = rollData.ids.actorId ?? (canvas.tokens.controlled.length == 1
/** TODO: jets de plusieurs personnages??? */ /** TODO: jets de plusieurs personnages??? */
? canvas.tokens.controlled[0] ? canvas.tokens.controlled[0]
: undefined) : undefined)
return ActorToken.fromActorId(actorId, () => { throw new Error("Pas d'acteur sélectionné") }) return TokenActor.fromActorId(actorId, () => { throw new Error("Pas d'acteur sélectionné") })
} }
} }
static $getOpponent(rollData) { static getTokenActorOpponent(rollData) {
if (rollData.ids.opponentTokenId) { if (rollData.ids.opponentTokenId) {
return ActorToken.fromTokenId(rollData.ids.opponentTokenId, rollData.ids.sceneId) return TokenActor.fromTokenId(rollData.ids.opponentTokenId, rollData.ids.sceneId)
} }
else if (rollData.ids.opponentId) { else if (rollData.ids.opponentId) {
return ActorToken.fromActorId(rollData.ids.opponentId) return TokenActor.fromActorId(rollData.ids.opponentId)
} }
else { else {
const targets = Array.from(game.user.targets) const targets = Array.from(game.user.targets)
if (targets.length == 1) { if (targets.length == 1) {
return ActorToken.fromToken(targets[0]) return TokenActor.fromToken(targets[0])
} }
else { else {
return undefined return undefined

View File

@@ -1,10 +1,10 @@
export const ROLL_TYPE_ATTAQUE = 'attaque' export const ROLL_TYPE_ATTAQUE = 'attaque'
export const ROLL_TYPE_COMP = 'comp' export const ROLL_TYPE_COMP = 'comp'
export const ROLL_TYPE_CUISINE = 'cuisine'
export const ROLL_TYPE_DEFENSE = 'defense' export const ROLL_TYPE_DEFENSE = 'defense'
export const ROLL_TYPE_JEU = 'jeu' export const ROLL_TYPE_JEU = 'jeu'
export const ROLL_TYPE_MEDITATION = 'meditation' export const ROLL_TYPE_MEDITATION = 'meditation'
export const ROLL_TYPE_CUISINE = 'cuisine'
export const ROLL_TYPE_OEUVRE = 'oeuvre' export const ROLL_TYPE_OEUVRE = 'oeuvre'
export const ROLL_TYPE_SORT = 'sort' export const ROLL_TYPE_SORT = 'sort'
export const ROLL_TYPE_TACHE = 'tache' export const ROLL_TYPE_TACHE = 'tache'
@@ -12,11 +12,10 @@ export const ROLL_TYPE_TACHE = 'tache'
export const ATTAQUE_ROLL_TYPES = [ROLL_TYPE_ATTAQUE] export const ATTAQUE_ROLL_TYPES = [ROLL_TYPE_ATTAQUE]
export const COMBAT_ROLL_TYPES = [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE] export const COMBAT_ROLL_TYPES = [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE]
export const DEMIREVE_ROLL_TYPES = [ROLL_TYPE_SORT] 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 DEFAULT_ROLL_TYPES = [ROLL_TYPE_COMP, ROLL_TYPE_TACHE, ROLL_TYPE_MEDITATION, ROLL_TYPE_CUISINE, ROLL_TYPE_OEUVRE, ROLL_TYPE_JEU]
export const ALL_ROLL_TYPES = [...DEFAULT_ROLL_TYPES, ...COMBAT_ROLL_TYPES, ...DEMIREVE_ROLL_TYPES] export const ALL_ROLL_TYPES = [...DEFAULT_ROLL_TYPES, ...COMBAT_ROLL_TYPES, ...DEMIREVE_ROLL_TYPES]
export const DIFF = { export const DIFF = {
LIBRE: 'libre', LIBRE: 'libre',
ATTAQUE: 'attaque', ATTAQUE: 'attaque',

View File

@@ -8,7 +8,7 @@ import { RdDItemArme } from "../item/arme.js";
import { RdDBonus } from "../rdd-bonus.js"; import { RdDBonus } from "../rdd-bonus.js";
import { ITEM_TYPES, RDD_CONFIG } from "../constants.js"; import { ITEM_TYPES, RDD_CONFIG } from "../constants.js";
import { CARACS } from "../rdd-carac.js"; import { CARACS } from "../rdd-carac.js";
import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs"; import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_OEUVRE } from "./roll-constants.mjs";
import { PART_ATTAQUE } from "./roll-part-attaque.mjs"; import { PART_ATTAQUE } from "./roll-part-attaque.mjs";
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -47,6 +47,10 @@ export class RollDialogAdapter {
rolled.finalLevel = rollData.current.totaldiff rolled.finalLevel = rollData.current.totaldiff
rolled.bonus = rollData.current.bonus ?? 0 rolled.bonus = rollData.current.bonus ?? 0
rolled.factorHtml = Misc.getFractionOneN(rollData.current.sign.diviseur) rolled.factorHtml = Misc.getFractionOneN(rollData.current.sign.diviseur)
if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) {
rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rolled.caracValue, rolled.roll)
rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
}
return rolled return rolled
} }
@@ -67,19 +71,20 @@ export class RollDialogAdapter {
if (rollData.ajustements == undefined) { if (rollData.ajustements == undefined) {
rollData.ajustements = {} rollData.ajustements = {}
} }
rollData.selectedCarac = rollData.active.actor.system.carac[rollData.current.carac.key] rollData.selectedCarac = rollData.active.actor.getCaracByName(rollData.current.carac.key)
const compKey = rollData.current.comp?.key const compKey = rollData.current.comp?.key
if (compKey) { if (compKey) {
rollData.competence = rollData.refs[PART_COMP].all.find(it => it.key == compKey)?.comp rollData.competence = rollData.refs[PART_COMP].all.find(it => it.key == compKey)?.comp
rollData.jetResistance = rollData.type.jetResistance rollData.jetResistance = rollData.type.jetResistance
} }
const oeuvreKey = rollData.current.oeuvre?.key if (rollData.type.current == ROLL_TYPE_OEUVRE) {
if (oeuvreKey) { const oeuvreKey = rollData.current.oeuvre?.key
const oeuvreCurrent = rollData.current[PART_OEUVRE]; if (rollData.type.current == ROLL_TYPE_OEUVRE && oeuvreKey) {
rollData.oeuvre = oeuvreCurrent.oeuvre const oeuvreCurrent = rollData.current[PART_OEUVRE];
// rollData.oeuvre = rollData.refs[PART_OEUVRE].oeuvres.find(it => it.key == oeuvreKey)?.oeuvre rollData.oeuvre = oeuvreCurrent.oeuvre
rollData.art = oeuvreCurrent.art.type rollData.art = oeuvreCurrent.art.type
}
} }
// pour appel moral // pour appel moral
rollData.diviseurSignificative = rollData.current.sign rollData.diviseurSignificative = rollData.current.sign
@@ -87,7 +92,7 @@ export class RollDialogAdapter {
rollData.use.moral = true rollData.use.moral = true
} }
if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) { if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) {
rolled.niveauNecessaire = this.findNiveauNecessaire(carac, rolled.roll) rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rollData.selectedCarac.value, rolled.roll)
rolled.ajustementNecessaire = rolled.niveauNecessaire - diff rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
} }
rollData.ajustements = rollData.ajustements.map(aj => { rollData.ajustements = rollData.ajustements.map(aj => {

View File

@@ -43,6 +43,7 @@ import { renderTemplate } from "../constants.js";
import { RollTypeCuisine } from "./roll-type-cuisine.mjs"; import { RollTypeCuisine } from "./roll-type-cuisine.mjs";
import { RollPartCuisine } from "./roll-part-cuisine.mjs"; import { RollPartCuisine } from "./roll-part-cuisine.mjs";
import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js"; import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js";
import { ActorImpacts } from "../technical/actor-impacts.mjs";
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
@@ -292,7 +293,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
return rollData return rollData
} }
static saveParts(rollData) { static saveParts(rollData, impacts) {
const target = RollBasicParts.initFrom(rollData) const target = RollBasicParts.initFrom(rollData)
ROLL_PARTS.filter(p => p.isActive(rollData)) ROLL_PARTS.filter(p => p.isActive(rollData))
.forEach(p => p.storeClean(rollData, target)) .forEach(p => p.storeClean(rollData, target))
@@ -301,6 +302,12 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
target.result = rollData.result target.result = rollData.result
target.done = rollData.done ?? {} target.done = rollData.done ?? {}
target.dmg = rollData.dmg target.dmg = rollData.dmg
if (impacts) {
target.reverse = {
active: impacts.active?.reverseImpacts(),
opponent: impacts.opponent?.reverseImpacts()
}
}
return target return target
} }
@@ -436,24 +443,36 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
async roll() { async roll() {
const roll = RollDialog.saveParts(this.rollData) const roll = RollDialog.saveParts(this.rollData)
this.loadRollData(roll)
const selectedRollType = this.getSelectedType(roll); const selectedRollType = this.getSelectedType(roll);
RollDialog.loadRollData(roll) selectedRollType.onSelect(roll)
roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1 roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1
roll.choix = {} roll.choix = {}
roll.rolled = await RollDialogAdapter.rollDice(roll, this.rollTitle(roll)) roll.rolled = await RollDialogAdapter.rollDice(roll, this.rollTitle(roll))
roll.result = selectedRollType.getResult(roll)
const impacts = {
active: new ActorImpacts(roll.active),
opponent: roll.opponent ? new ActorImpacts(roll.opponent) : undefined
}
roll.result = selectedRollType.getResult(roll, impacts)
console.info('RollDialog.roll:', roll) console.info('RollDialog.roll:', roll)
const callbacks = [ const callbacks = [
...this.rollOptions.callbacks, ...this.rollOptions.callbacks,
...selectedRollType.callbacks(this.rollOptions), ...selectedRollType.callbacks(this.rollOptions),
] ]
await Promise.all(callbacks.map(async callback => await callback(roll))) await Promise.all(callbacks.map(async callback => await callback(roll)))
await this.chatRollResult.display(roll)
await impacts.active?.applyImpacts()
await impacts.opponent?.applyImpacts()
selectedRollType.onApplyImpacts(roll, impacts)
await this.chatRollResult.display(roll, impacts)
this.rollOptions.onRollDone(this) this.rollOptions.onRollDone(this)
} }
static loadRollData(roll) { loadRollData(roll) {
RollDialog.$prepareRollData(roll) RollDialog.$prepareRollData(roll)
RollDialog.calculAjustements(roll) RollDialog.calculAjustements(roll)
roll.v2 = true roll.v2 = true

View File

@@ -21,10 +21,9 @@ export class RollPartComp extends RollPartSelect {
refs.all = this.$getActorComps(rollData) refs.all = this.$getActorComps(rollData)
.filter(comp => !selected.forced || .filter(comp => !selected.forced ||
(selected.key ? (selected.key ?
Grammar.includesLowerCaseNoAccent(comp.name, selected.key) Grammar.includesLowerCaseNoAccent(comp.name, selected.key)
: comp.key == '') : comp.key == '')
) )
refs.comps = refs.all refs.comps = refs.all
this.$selectComp(rollData) this.$selectComp(rollData)
} }
@@ -33,7 +32,7 @@ export class RollPartComp extends RollPartSelect {
$getActorComps(rollData) { $getActorComps(rollData) {
const competences = (rollData.active.actor?.getCompetences() ?? []) const competences = (rollData.active.actor?.getCompetences() ?? [])
.map(RollPartComp.$extractComp) .map(RollPartComp.extractComp)
.sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label))) .sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label)))
/* TODO: filter competences */ /* TODO: filter competences */
const listCompetences = [ const listCompetences = [
@@ -43,7 +42,7 @@ export class RollPartComp extends RollPartSelect {
return listCompetences return listCompetences
} }
static $extractComp(comp) { static extractComp(comp) {
return { return {
key: comp.name, key: comp.name,
label: comp.name, label: comp.name,
@@ -52,12 +51,16 @@ export class RollPartComp extends RollPartSelect {
} }
} }
filterComps(rollData, allowed = []) { filterComps(rollData, allowed = [], sorting = undefined) {
const sans = allowed.includes('')
allowed = allowed.filter(it => it != undefined) allowed = allowed.filter(it => it != undefined)
const refs = this.getRefs(rollData) const refs = this.getRefs(rollData)
refs.comps = allowed.length > 0 refs.comps = allowed.length > 0
? refs.all.filter(it => allowed.includes(it.label)) ? refs.all.filter(it => allowed.includes(it.label) || (sans && it.key == ''))
: refs.all : refs.all
if (sorting && refs.comps.length > 0) {
refs.comps.sort(sorting)
}
this.$selectComp(rollData) this.$selectComp(rollData)
} }
@@ -66,7 +69,7 @@ export class RollPartComp extends RollPartSelect {
} }
setSpecialComp(rollData, comps) { setSpecialComp(rollData, comps) {
this.getRefs(rollData).comps = comps.map(RollPartComp.$extractComp) this.getRefs(rollData).comps = comps.map(RollPartComp.extractComp)
.sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label))) .sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label)))
} }

View File

@@ -19,55 +19,153 @@ export class RollPartCuisine extends RollPartSelect {
isValid(rollData) { return rollData.active.actor.isPersonnage() } isValid(rollData) { return rollData.active.actor.isPersonnage() }
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_CUISINE) } visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_CUISINE) }
restore(rollData) {
super.restore(rollData)
this.$restoreSavedOptions(rollData)
}
store(rollData, targetData) {
const current = this.getCurrent(rollData)
this.setSaved(targetData, {
key: current.key,
fabriquer: current.fabriquer,
proportions: current.proportions,
value: current.value,
})
}
loadRefs(rollData) { loadRefs(rollData) {
const refs = this.getRefs(rollData) const refs = this.getRefs(rollData)
refs.recettes = rollData.active.actor.items const actor = rollData.active.actor
refs.cuisine = actor.getCompetence('Cuisine')
const recettes = actor.items
.filter(it => it.type == ITEM_TYPES.recettecuisine) .filter(it => it.type == ITEM_TYPES.recettecuisine)
.map(it => RollPartCuisine.$extractRecette(it, rollData.active.actor)) .map(RollPartCuisine.$extractPreparationRecette)
if (refs.recettes.length > 0) {
this.$selectRecette(rollData) const ingredientsBruts = actor.items
.filter(it => it.getUtilisationCuisine() == 'brut')
.map(RollPartCuisine.$extractPreparationBrut)
refs.preparations = [RollPartCuisine.$preparationBasique(), ...recettes, ...ingredientsBruts]
refs.preparations.forEach(p => p.comp = refs.cuisine)
if (refs.preparations.length > 0) {
this.$selectPreparation(rollData)
this.$restoreSavedOptions(rollData)
} }
} }
choices(refs) { return refs.recettes } $restoreSavedOptions(rollData) {
const saved = this.getSaved(rollData)
const current = this.getCurrent(rollData)
if (saved.fabriquer != undefined) {
current.fabriquer = saved.fabriquer
}
if (saved.proportions != undefined) {
current.proportions = saved.proportions
}
if (saved.value != undefined) {
current.value = saved.value
}
}
static $extractRecette(recette, actor) { choices(refs) { return refs.preparations }
static $preparationBasique() {
return {
key: '',
label: "Improvisation du moment",
img: RollPartCuisine.$getImgIngredient(),
sust: 1,
exotisme: 0,
ingredients: "Ce qu'il y a sous la main",
proportions: 8,
proportionsMax: 50,
value: 0,
fabriquer: false,
}
}
static $extractPreparationRecette(recette) {
const proportions = recette.system.sust ?? 1
return { return {
key: recette.id, key: recette.id,
label: recette.name, label: recette.name,
caracs: RollPartCuisine.getCaracs(recette), img: 'systems/foundryvtt-reve-de-dragon/icons/cuisine/ragout.svg',
qualite: recette.system.niveau, sust: 1,
exotisme: recette.system.exotisme,
ingredients: recette.system.ingredients,
proportions: proportions,
proportionsMax: proportions * 10,
value: -recette.system.niveau, value: -recette.system.niveau,
recette: recette, recette: recette,
comp: actor.getCompetence('Cuisine') fabriquer: true,
} }
} }
static getCaracs(recette){
// TODO: permettre différentes caractéristiques pour la cuisine? static $extractPreparationBrut(ingredient) {
return [CARACS.ODORATGOUT, CARACS.EMPATHIE, CARACS.DEXTERITE] return {
key: ingredient.id,
label: ingredient.name + ' cuisiné',
img: RollPartCuisine.$getImgIngredient(ingredient.type),
sust: ingredient.system.sust ?? 1,
exotisme: ingredient.system.exotisme,
ingredients: ingredient.name,
proportions: Math.min(10, ingredient.system.quantite),
proportionsMax: Math.min(50, ingredient.system.quantite),
value: 0,
ingredient: ingredient,
fabriquer: true,
}
} }
$selectRecette(rollData, key) { static $getImgIngredient(type = ITEM_TYPES.ingredient) {
switch (type) {
case ITEM_TYPES.herbe:
case ITEM_TYPES.plante:
return `systems/foundryvtt-reve-de-dragon/icons/cuisine/${type}.svg`
case ITEM_TYPES.faune:
return 'systems/foundryvtt-reve-de-dragon/icons/cuisine/gibier.svg'
}
return 'systems/foundryvtt-reve-de-dragon/icons/cuisine/ragout.svg'
}
$selectPreparation(rollData, key) {
this.selectByKey(rollData, key, 0) this.selectByKey(rollData, key, 0)
} }
async _onRender(rollDialog, context, options) { async _onRender(rollDialog, context, options) {
const selectRecette = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-recette"]`) const current = this.getCurrent(rollDialog.rollData)
selectRecette.addEventListener("change", e => { const selectPreparation = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-preparation"]`)
const inputDiff = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="diff-var"]`)
const checkboxFabriquer = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="fabriquer"]`)
const inputProportions = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="proportions"]`)
selectPreparation.addEventListener("change", e => {
const selectOptions = e.currentTarget.options const selectOptions = e.currentTarget.options
const index = selectOptions.selectedIndex const index = selectOptions.selectedIndex
this.$selectRecette(rollDialog.rollData, selectOptions[index]?.value) this.$selectPreparation(rollDialog.rollData, selectOptions[index]?.value)
rollDialog.render() rollDialog.render()
}) })
checkboxFabriquer?.addEventListener("change", e => {
current.fabriquer = e.currentTarget.checked
})
inputDiff?.addEventListener("change", e => {
current.value = parseInt(e.currentTarget.value)
})
inputProportions?.addEventListener("change", e => {
current.proportions = parseInt(e.currentTarget.value)
})
} }
impactOtherPart(part, rollData) { impactOtherPart(part, rollData) {
if (this.visible(rollData)) { if (this.visible(rollData)) {
const current = this.getCurrent(rollData)
switch (part.code) { switch (part.code) {
case PART_CARAC: return part.filterCaracs(rollData, current.caracs) case PART_CARAC: return part.filterCaracs(rollData, [CARACS.ODORATGOUT])
case PART_COMP: return part.filterComps(rollData, [current.comp?.name]) case PART_COMP: return part.filterComps(rollData, [this.getRefs(rollData).cuisine.name])
} }
} }
return undefined return undefined

View File

@@ -1,10 +1,15 @@
import { DIFF, DIFFS, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_SORT, ROLL_TYPE_TACHE } from "./roll-constants.mjs"; import { DIFF, DIFFS, ROLL_TYPE_CUISINE, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_SORT, ROLL_TYPE_TACHE } from "./roll-constants.mjs";
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"; import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs";
import { Misc } from "../misc.js"; import { Misc } from "../misc.js";
export const PART_DIFF = "diff" export const PART_DIFF = "diff"
const EXCLUDED_ROLL_TYPES = [ROLL_TYPE_TACHE, ROLL_TYPE_MEDITATION, ROLL_TYPE_SORT, ROLL_TYPE_OEUVRE] const EXCLUDED_ROLL_TYPES = [
ROLL_TYPE_TACHE,
ROLL_TYPE_MEDITATION,
ROLL_TYPE_SORT,
ROLL_TYPE_CUISINE,
ROLL_TYPE_OEUVRE]
export class RollPartDiff extends RollPart { export class RollPartDiff extends RollPart {
@@ -53,8 +58,8 @@ export class RollPartDiff extends RollPart {
setDiff(rollData, diff) { setDiff(rollData, diff) {
const current = this.getCurrent(rollData) const current = this.getCurrent(rollData)
current.value = diff.diff current.value = diff.diff ?? current.value
current.type = diff.type current.type = diff.type ?? current.type
} }
getAjustements(rollData) { getAjustements(rollData) {

View File

@@ -1,15 +1,16 @@
import { Grammar } from "../grammar.js"
import { ITEM_TYPES } from "../constants.js" import { ITEM_TYPES } from "../constants.js"
import { CARACS } from "../rdd-carac.js" import { CARACS } from "../rdd-carac.js"
import { ROLL_TYPE_JEU } from "./roll-constants.mjs" import { ROLL_TYPE_JEU } from "./roll-constants.mjs"
import { PART_CARAC } from "./roll-part-carac.mjs" import { PART_CARAC } from "./roll-part-carac.mjs"
import { PART_COMP } from "./roll-part-comp.mjs" import { PART_COMP, RollPartComp } from "./roll-part-comp.mjs"
import { RollPartSelect } from "./roll-part-select.mjs" import { RollPartSelect } from "./roll-part-select.mjs"
import { ROLLDIALOG_SECTION } from "./roll-part.mjs" import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
import { RdDItem } from "../item.js"
import { Misc } from "../misc.js"
export const PART_JEU = "jeu" export const PART_JEU = "jeu"
const COMPETENCE_JEU = 'Jeu' export const COMPETENCE_JEU = 'Jeu'
export class RollPartJeu extends RollPartSelect { export class RollPartJeu extends RollPartSelect {
@@ -21,8 +22,12 @@ export class RollPartJeu extends RollPartSelect {
loadRefs(rollData) { loadRefs(rollData) {
const refs = this.getRefs(rollData) const refs = this.getRefs(rollData)
refs.jeux = rollData.active.actor.itemTypes[ITEM_TYPES.jeu] const actor = rollData.active.actor
.map(it => RollPartJeu.$extractJeu(it, rollData.active.actor)) const compJeu = actor.getCompetence(COMPETENCE_JEU)
refs.jeux = actor.itemTypes[ITEM_TYPES.jeu]
.map(it => RollPartJeu.$extractJeu(it, compJeu))
if (refs.jeux.length > 0) { if (refs.jeux.length > 0) {
this.$selectJeu(rollData) this.$selectJeu(rollData)
} }
@@ -30,18 +35,17 @@ export class RollPartJeu extends RollPartSelect {
choices(refs) { return refs.jeux } choices(refs) { return refs.jeux }
static $extractJeu(jeu, actor) { static $extractJeu(jeu, compJeu) {
const comp = actor.getCompetence(COMPETENCE_JEU)
const caracs = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim()) const caracs = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim())
const base = RollPartJeu.$getJeuBase(jeu, comp, caracs) const base = RollPartJeu.$getJeuBase(jeu, compJeu, caracs)
return { return {
key: jeu.id, key: jeu.id,
label: jeu.name, label: jeu.name,
caracs: caracs, caracs: caracs,
jeu: jeu, jeu: jeu,
value: (base ?? comp).system.niveau, value: 0,
base: base, base: base,
comp: comp comp: compJeu
} }
} }
@@ -49,10 +53,10 @@ export class RollPartJeu extends RollPartSelect {
if (jeu.system.base < comp.system.niveau) { if (jeu.system.base < comp.system.niveau) {
return undefined return undefined
} }
return { return new RdDItem({
id: comp.id, id: comp.id,
name: `Jeu ${jeu.name}`, name: `Jeu ${Misc.lowerFirst(jeu.name)}`,
type: comp.type, type: ITEM_TYPES.competence,
img: comp.img, img: comp.img,
system: foundry.utils.mergeObject( system: foundry.utils.mergeObject(
{ {
@@ -61,9 +65,9 @@ export class RollPartJeu extends RollPartSelect {
default_carac: caracs.length > 0 ? caracs[0] : CARACS.CHANCE default_carac: caracs.length > 0 ? caracs[0] : CARACS.CHANCE
}, },
comp.system, comp.system,
{ inplace: true, overwrite: false } { overwrite: false }
) )
} })
} }
prepareContext(rollData) { prepareContext(rollData) {
@@ -77,6 +81,13 @@ export class RollPartJeu extends RollPartSelect {
$selectJeu(rollData, key) { $selectJeu(rollData, key) {
this.selectByKey(rollData, key, 0) this.selectByKey(rollData, key, 0)
RollPartJeu.forceCompJeu(rollData)
}
static forceCompJeu(rollData) {
const jeu = rollData.current[PART_JEU].base ?? rollData.current[PART_JEU].comp
rollData.refs[PART_COMP].comps = [jeu].map(it => RollPartComp.extractComp(it))
rollData.current[PART_COMP] = rollData.refs[PART_COMP].comps[0]
} }
async _onRender(rollDialog, context, options) { async _onRender(rollDialog, context, options) {
@@ -95,7 +106,7 @@ export class RollPartJeu extends RollPartSelect {
const current = this.getCurrent(rollData) const current = this.getCurrent(rollData)
switch (part.code) { switch (part.code) {
case PART_CARAC: return part.filterCaracs(rollData, current.caracs) case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
case PART_COMP: return part.filterComps(rollData,[current.comp?.name]) case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
} }
} }
return undefined return undefined

View File

@@ -27,7 +27,7 @@ export class RollPartSelect extends RollPart {
const current = this.getCurrent(rollData) const current = this.getCurrent(rollData)
const newChoice = (choices.length == 0) const newChoice = (choices.length == 0)
? { key: '', value: defValue } ? { key: '', value: defValue }
: this.$getSelectedChoice(choices, key ?? current?.key ?? refs?.key ?? '') : this.$getSelectedChoice(choices, key ?? current?.key ?? refs?.key ?? choices[0].key)
this.setCurrent(rollData, newChoice) this.setCurrent(rollData, newChoice)
return newChoice return newChoice
} }

View File

@@ -11,9 +11,11 @@ import { CARACS } from "../rdd-carac.js"
export const PART_SORT = "sort" export const PART_SORT = "sort"
export class RollPartSort extends RollPartSelect { export class RollPartSort extends RollPartSelect {
onReady() { onReady() {
// TODO: utiliser un hook pour écouter les déplacements dans les TMRs? // TODO: utiliser un hook pour écouter les déplacements dans les TMRs?
} }
get code() { return PART_SORT } get code() { return PART_SORT }
get section() { return ROLLDIALOG_SECTION.CHOIX } get section() { return ROLLDIALOG_SECTION.CHOIX }
@@ -23,7 +25,7 @@ export class RollPartSort extends RollPartSelect {
loadRefs(rollData) { loadRefs(rollData) {
const refs = this.getRefs(rollData) const refs = this.getRefs(rollData)
const coord = rollData.active.actor.system.reve.tmrpos.coord const coord = rollData.active.actor.system.reve.tmrpos.coord
const draconics = rollData.active.actor.getDraconicList() const draconics = rollData.active.actor.getDraconics()
const sorts = rollData.active.actor.itemTypes[ITEM_TYPES.sort] const sorts = rollData.active.actor.itemTypes[ITEM_TYPES.sort]
.map(s => RollPartSort.$extractSort(s, coord, draconics)) .map(s => RollPartSort.$extractSort(s, coord, draconics))
@@ -120,7 +122,7 @@ export class RollPartSort extends RollPartSelect {
const current = this.getCurrent(rollData) const current = this.getCurrent(rollData)
switch (part.code) { switch (part.code) {
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.REVE]) case PART_CARAC: return part.filterCaracs(rollData, [CARACS.REVE])
case PART_COMP: return part.filterComps(rollData,current.draconics ?? []) case PART_COMP: return part.filterComps(rollData, current.draconics ?? [])
} }
} }
return undefined return undefined

View File

@@ -1,4 +1,4 @@
import { ROLL_TYPE_COMP } from "./roll-constants.mjs" import { DIFF, ROLL_TYPE_COMP } from "./roll-constants.mjs"
import { RollType } from "./roll-type.mjs" import { RollType } from "./roll-type.mjs"
export class RollTypeComp extends RollType { export class RollTypeComp extends RollType {
@@ -7,4 +7,9 @@ export class RollTypeComp extends RollType {
title(rollData) { return `fait un jet ${rollData.type.opposed ? ' contre ' : ''}` } title(rollData) { return `fait un jet ${rollData.type.opposed ? ' contre ' : ''}` }
onSelect(rollData) {
this.setDiffType(rollData, DIFF.LIBRE)
}
} }

View File

@@ -1,3 +1,5 @@
import { ITEM_TYPES } from "../constants.js"
import { RollBasicParts } from "./roll-basic-parts.mjs"
import { DIFF, ROLL_TYPE_CUISINE } from "./roll-constants.mjs" import { DIFF, ROLL_TYPE_CUISINE } from "./roll-constants.mjs"
import { PART_CUISINE } from "./roll-part-cuisine.mjs" import { PART_CUISINE } from "./roll-part-cuisine.mjs"
import { RollType } from "./roll-type.mjs" import { RollType } from "./roll-type.mjs"
@@ -9,19 +11,73 @@ export class RollTypeCuisine extends RollType {
visible(rollData) { return rollData.active.actor.isPersonnage() } visible(rollData) { return rollData.active.actor.isPersonnage() }
title(rollData) { title(rollData) {
const current = rollData.current[PART_CUISINE] const current = rollData.current[PART_CUISINE]
return `prépare une recette: ${current.label}` return current.recette ? `prépare une recette: ${current.label}` : `prépare: ${current.label}`
} }
onSelect(rollData) { onSelect(rollData) {
this.setDiffType(rollData, DIFF.AUCUN) this.setDiffType(rollData, DIFF.AUCUN)
} }
getResult(rollData){ getResult(rollData, impacts) {
const current = rollData.current[PART_CUISINE] const current = rollData.current[PART_CUISINE]
const qualite = rollData.rolled.isSuccess ? current.qualite : Math.min(current.qualite, current.comp.system.niveau) const diff = -current.value
return { const cuisine = rollData.refs[PART_CUISINE].cuisine
qualite: qualite + rollData.rolled.ptQualite const qualite = rollData.rolled.ptQualite + (rollData.rolled.isSuccess ? diff : Math.min(diff, cuisine.system.niveau))
const result = {
qualite: qualite,
exotisme: Math.min(Math.min(qualite, current.exotisme ?? 0), 0),
messages: []
} }
if (current.fabriquer) {
const plat = this.$prepareNourriture(rollData.active.name, current, result)
result.messages.push(`${plat.system.quantite} ${plat.name} ont été préparés dans l'équipement`)
impacts.active.addCreatedItem(plat)
result.plat = { id: plat.id }
}
if (current.ingredient) {
const quantite = Math.min(current.proportions, current.ingredient.system.quantite)
if (quantite == current.ingredient.system.quantite) {
impacts.active.addDeletedItem(current.ingredient)
result.messages.push(`Il n'y a plus de ${ingredient.name}`)
}
else {
impacts.active.addItemDelta(current.ingredient, 'system.quantite', -current.proportions)
result.messages.push(`${current.proportions} ${current.ingredient.name} ont été utilisés`)
}
}
return result
}
onApplyImpacts(roll, impacts) {
if (roll.result.plat) {
// le plat n'est pas créé immédiatement, il faut donc retrouver l'id
roll.result.plat.id = impacts.active.itemCreates.find(it => it.id = roll.result.plat.id)?.createdId
}
}
$prepareNourriture(cuisinier, current, result) {
return {
id: foundry.utils.randomID(16),
name: current.label,
img: current.img,
type: ITEM_TYPES.nourritureboisson,
system: {
sust: current.sust,
cuisinier: cuisinier,
exotisme: result.exotisme,
encombrement: 0.1,
quantite: current.proportions,
qualite: result.qualite,
cout: result.qualite > 0 ? (result.qualite * 0.01) : 0.01,
}
}
}
async onFaireGouter(savedRoll) {
const actor = RollBasicParts.getTokenActor(savedRoll).actor
const platId = savedRoll.result.plat.id
const plat = actor.items.get(platId)
await plat?.proposerVente()
} }
} }

View File

@@ -1,6 +1,7 @@
import { PART_JEU } from "./roll-part-jeu.mjs" import { PART_JEU, RollPartJeu } from "./roll-part-jeu.mjs"
import { RollType } from "./roll-type.mjs" import { RollType } from "./roll-type.mjs"
import { ROLL_TYPE_JEU } from "./roll-constants.mjs" import { DIFF, ROLL_TYPE_JEU } from "./roll-constants.mjs"
export class RollTypeJeu extends RollType { export class RollTypeJeu extends RollType {
get code() { return ROLL_TYPE_JEU } get code() { return ROLL_TYPE_JEU }
@@ -14,4 +15,9 @@ export class RollTypeJeu extends RollType {
return `joue: ${rollData.current[PART_JEU].label}` return `joue: ${rollData.current[PART_JEU].label}`
} }
onSelect(rollData) {
this.setDiffType(rollData, DIFF.LIBRE)
RollPartJeu.forceCompJeu(rollData)
}
} }

View File

@@ -17,6 +17,7 @@ export class RollTypeMeditation extends RollType {
onSelect(rollData) { onSelect(rollData) {
this.setDiffType(rollData, DIFF.AUCUN) this.setDiffType(rollData, DIFF.AUCUN)
} }
callbacks(rollOptions) { return [RollTypeMeditation.$onRollMeditation] } callbacks(rollOptions) { return [RollTypeMeditation.$onRollMeditation] }
static async $onRollMeditation(rollData) { static async $onRollMeditation(rollData) {

View File

@@ -16,11 +16,12 @@ export class RollTypeOeuvre extends RollType {
this.setDiffType(rollData, DIFF.AUCUN) this.setDiffType(rollData, DIFF.AUCUN)
} }
getResult(rollData){ getResult(rollData, impacts) {
const current = rollData.current[PART_OEUVRE] const current = rollData.current[PART_OEUVRE]
const qualite = rollData.rolled.isSuccess ? current.qualite : Math.min(current.qualite, current.comp.system.niveau) const qualite = rollData.rolled.isSuccess ? current.qualite : Math.min(current.qualite, current.comp.system.niveau)
return { return {
qualite: qualite + rollData.rolled.ptQualite qualite: qualite + rollData.rolled.ptQualite,
messages: []
} }
} }

View File

@@ -53,5 +53,14 @@ export class RollType {
callbacks(rollOptions) { return [] } callbacks(rollOptions) { return [] }
getResult(rollData) { return undefined } /**
* Préparation des résultats d'un jet pour ce type de jet
*
* @param {*} rollData les données du jet, incluans la partie rolled
* @param {*} impacts une structure composée de deux ActorImpacts {active, opponent}
* pour stocker les effets sur ces deux participants au jey
* @returns undefined ou une structure contenant les informations requise pour afficher
*/
getResult(rollData, impacts) { return { messages: [] } }
onApplyImpacts(roll, impacts) { }
} }

View File

@@ -0,0 +1,128 @@
/**
* class designed to store actor modification instructions, to apply them in a single operation, and have the ability to revert these
*/
export class ActorImpacts {
constructor(actorToken) {
this.actorToken = actorToken
this.updates = []
this.deltas = []
this.itemCreates = []
this.itemUpdates = []
this.itemDeletes = []
}
addActorUpdate(path, value) {
this.updates.push([path, value])
}
addActorDelta(path, value) {
const intValue = Number.parseInt(value)
if (Number.isInteger(intValue) && intValue != 0) {
const delta = [path, intValue]
this.deltas.push(delta)
}
else {
console.error('Cannot use non integer value {} for delta update', value)
}
}
addDeletedItem(item) {
this.itemDeletes.push(item)
}
addCreatedItem(item) {
this.itemCreates.push(item)
}
addItemUpdate(item, path, value) {
const existing = this.itemUpdates.find(it => it.id == item.id)
const update = [path, value]
if (existing) {
existing.updates.push(update)
}
else {
this.itemUpdates.push({ id: item.id, updates: [update], deltas: [] })
}
}
addItemDelta(item, path, value) {
const intValue = Number.parseInt(value)
if (Number.isInteger(intValue) && intValue != 0) {
const delta = [path, intValue]
const existing = this.itemUpdates.find(it => it.id == item.id)
if (existing) {
existing.deltas.push(delta)
}
else {
this.itemUpdates.push({ id: item.id, updates: [], deltas: [delta] })
}
}
else {
console.error('Cannot use non integer value {} for delta update', value)
}
}
reverseImpacts() {
const reverse = ActorImpacts.$computeReverts(new ActorImpacts(this.actorToken), this, __ => this.actorToken.actor)
reverse.itemCreates = this.itemDeletes.map(it => foundry.utils.duplicate(it))
reverse.itemDeletes = this.itemCreates.map(it => { return { id: it.id } })
reverse.itemUpdates = this.itemUpdates.map(it => ActorImpacts.$computeReverts({ id: it.id }, it, id => this.$getActorItem(id)))
return reverse
}
toStorable() {
delete this.actorToken
return this
}
async applyImpacts() {
const actor = this.actorToken.actor
const isItemsDelete = this.itemDeletes.length > 0
const isItemsCreate = this.itemCreates.length > 0
const isItemsUpdate = this.itemUpdates.length > 0
const isActorUpdate = this.updates.length > 0 || this.deltas.length > 0
if (isItemsDelete) {
const deletes = this.itemDeletes.map(it => it.id)
await actor.deleteEmbeddedDocuments('Item', deletes, { render: !(isItemsCreate || isItemsUpdate || isActorUpdate) })
}
if (isItemsCreate) {
const creates = this.itemCreates
const created = await actor.createEmbeddedDocuments('Item', creates, { render: !(isItemsUpdate || isActorUpdate)})
for (let i=0; i<creates.length; i++){
creates[i].createdId = created[i].id
}
}
if (isItemsUpdate) {
const updates = this.itemUpdates.map(u => ActorImpacts.$computeUpdates(u, id => this.$getActorItem(id)))
await actor.updateEmbeddedDocuments('Item', updates, { render: !isActorUpdate })
}
if (isActorUpdate) {
const updates = ActorImpacts.$computeUpdates(this, id => actor)
await actor.update(updates, { render: true })
}
}
$getActorItem(id) {
return this.actorToken.actor.items.get(id)
}
static $computeUpdates(u, getSource) {
const source = getSource(u.id)
const instruction = { _id: u.id }
u.updates.forEach(u => instruction[u[0]] = u[1])
u.deltas.forEach(u => instruction[u[0]] = foundry.utils.getProperty(source, u[0]) + u[1])
return instruction
}
static $computeReverts(target, u, getSource) {
const source = getSource(u.id)
target.updates = u.updates.map(u => [u[0], foundry.utils.getProperty(source, u[0])])
target.deltas = u.deltas.map(d => [d[0], -d[1]])
return target
}
}

View File

@@ -1,9 +1,9 @@
/** /**
* class providing the actor and token, and choosing the name and image from the token if available. * class providing the actor and token, and choosing the name and image from the token if available.
*/ */
export class ActorToken { export class TokenActor {
static fromTokenActor(token, actor){ static fromTokenActor(token, actor){
return token ? ActorToken.fromToken(token) : ActorToken.fromActor(actor) return token ? TokenActor.fromToken(token) : TokenActor.fromActor(actor)
} }
static fromActorId(actorId, onError = () => undefined) { static fromActorId(actorId, onError = () => undefined) {
@@ -19,17 +19,17 @@ export class ActorToken {
static fromActor(actor) { static fromActor(actor) {
const token = actor.isToken ? actor.token : actor.prototypeToken const token = actor.isToken ? actor.token : actor.prototypeToken
return ActorToken.fromToken(token) return TokenActor.fromToken(token)
} }
static fromTokenId(tokenId, sceneId = undefined) { static fromTokenId(tokenId, sceneId = undefined) {
const tokensList = sceneId ? game.scenes.get(sceneId).tokens : canvas.tokens.placeables const tokensList = sceneId ? game.scenes.get(sceneId).tokens : canvas.tokens.placeables
const token = tokensList.get(tokenId) const token = tokensList.get(tokenId)
return ActorToken.fromToken(token) return TokenActor.fromToken(token)
} }
static fromToken(token) { static fromToken(token) {
return new ActorToken(token) return new TokenActor(token)
} }
constructor(token) { constructor(token) {

View File

@@ -2,7 +2,6 @@ import { renderTemplate } from "./constants.js";
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { RdDDice } from "./rdd-dice.js"; import { RdDDice } from "./rdd-dice.js";
import { RdDUtility } from "./rdd-utility.js";
import { SystemCompendiums, CompendiumTable, CompendiumTableHelpers } from "./settings/system-compendiums.js"; import { SystemCompendiums, CompendiumTable, CompendiumTableHelpers } from "./settings/system-compendiums.js";
import { TMRUtility } from "./tmr-utility.js"; import { TMRUtility } from "./tmr-utility.js";

View File

@@ -28,16 +28,7 @@ export class EffetsRencontre {
static reve_plus_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, 1) } static reve_plus_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, 1) }
static reve_moins_force = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -context.rencontre.system.force) } static reve_moins_force = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -context.rencontre.system.force) }
static reve_moins_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -1) } static reve_moins_1 = async (dialog, context) => { await EffetsRencontre.$reve_plus(context.actor, -1) }
static $reve_plus = async (actor, reve) => { static $reve_plus = async (actor, reve) => { await actor.reveActuelIncDec(reve) }
if (!ReglesOptionnelles.isUsing("recuperation-reve") && reve < 0) {
ChatMessage.create({
whisper: ChatUtility.getOwners(actor),
content: `Pas de récupération de rêve (${reve} points ignorés)`
});
return
}
await actor.reveActuelIncDec(reve)
}
static vie_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) } static vie_moins_1 = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -1) }
static vie_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) } static vie_moins_force = async (dialog, context) => { await EffetsRencontre.$vie_plus(context.actor, -context.rencontre.system.force) }

View File

@@ -10,7 +10,6 @@
"gulp": "gulp", "gulp": "gulp",
"run": "npx vite serve", "run": "npx vite serve",
"packCompendiumsToDist": "node ./tools/packCompendiumsToDist.mjs", "packCompendiumsToDist": "node ./tools/packCompendiumsToDist.mjs",
"packCompendiumsToPublic": "node ./tools/packCompendiumsToPublic.mjs",
"unpackCompendiumsFromPublic": "node ./tools/unpackCompendiumsFromPublic.mjs" "unpackCompendiumsFromPublic": "node ./tools/unpackCompendiumsFromPublic.mjs"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -1,6 +1,6 @@
name: Rêve de Dragon name: Rêve de Dragon
type: rencontre type: rencontre
img: systems/foundryvtt-reve-de-dragon/assets/rdd_pause.webp img: systems/foundryvtt-reve-de-dragon/assets/ui/rdd_pause.webp
system: system:
description: '' description: ''
descriptionmj: '' descriptionmj: ''

View File

@@ -1,3 +1,3 @@
<span class="message-metadata heure-rdd"> <span class="message-metadata heure-rdd">
{{this.jourDuMois}} {{this.mois.label}} - {{timestamp-imgSigne this.heure}} {{this.jourDuMois}} {{this.mois.label}} {{timestamp-imgSigne this.heure}}
</span> </span>

View File

@@ -1,7 +1,7 @@
<div class="roll-chat"> <div class="roll-chat">
<div class="chat-img"> <div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" /> <img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.img}}" data-tooltip="{{current.comp.name}}" /> <img src="{{current.comp.comp.img}}" data-tooltip="{{current.comp.label}}" />
<img src="{{opponent.img}}" data-tooltip="{{opponent.name}}" /> <img src="{{opponent.img}}" data-tooltip="{{opponent.name}}" />
</div> </div>

View File

@@ -1,7 +1,7 @@
<div class="roll-chat"> <div class="roll-chat">
<div class="chat-img"> <div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" /> <img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.img}}" data-tooltip="{{current.comp.name}}" /> <img src="{{current.comp.comp.img}}" data-tooltip="{{current.comp.label}}" />
</div> </div>
<div class="chat-header"> <div class="chat-header">
{{active.name}} fait un jet de {{current.comp.label}} {{active.name}} fait un jet de {{current.comp.label}}

View File

@@ -1,10 +1,15 @@
<div class="roll-chat"> <div class="roll-chat">
<div class="chat-img"> <div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" /> <img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.img}}" data-tooltip="{{current.comp.name}}" /> <img src="{{current.cuisine.img}}" data-tooltip="{{current.comp.label}}" />
</div> </div>
<div class="chat-header"> <div class="chat-header">
{{active.name}} prépare une recette de niveau {{current.cuisine.recette.system.niveau}}: : {{current.cuisine.label}} ( {{active.name}}
{{#if current.recette}}
prépare une recette de niveau {{current.cuisine.recette.system.niveau}}: {{current.cuisine.label}}
{{else}}
prépare {{current.label}}: {{current.cuisine.label}}
{{/if}}
</div> </div>
<div class="chat-resume"> <div class="chat-resume">
@@ -14,15 +19,35 @@
<div class="chat-details"> <div class="chat-details">
<p> <p>
{{active.name}} {{active.name}}
{{#if rolled.isSuccess}}réussit la recette avec {{#if rolled.isSuccess}}
{{else}}manque d'inspiration, le plat a réussit la recette, pour un plat de qualité {{result.qualite~}}
{{/if}} {{#if (lt result.exotisme 0)}}et d'exotisme {{result.exotisme}}{{/if~}}
une qualité de {{result.qualite}}. {{else}}
fait un piètre cuisinier, et obtient un plat de qualité {{result.qualite~}}
{{#if (lt result.exotisme 0)}}à l'exotisme certain ({{result.exotisme}}){{/if~}}
{{/if~}}.
{{#if (lt result.exotisme 0)}}
<br>Au vu de l'exotisme du plat, les convives devront réussir un jet de @roll[Volonté/Cuisine/{{result.exotisme}}].
En cas d'échec, ils peuvent se forcer à faire plaisir à {{active.name}}, mais devront faire un jet de moral Malheureux.
{{/if}}
{{#each result.messages as |message|}}
<br>{{message}}
{{/each}}
</p> </p>
{{> 'partial-info-appel-moral'}} {{> 'partial-info-appel-moral'}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs" current.cuisine.recette.system}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs" current.cuisine.recette.system}}
</div> </div>
<div class="chat-actions">
{{#if current.cuisine.fabriquer}}
<a class='chat-card-button faire-gouter'
data-tooltip="Faire goûter à ses compagnons">
<i class="fa-solid fa-utensils"></i>&nbsp; faire goûter à ses compagnons
</a>
{{/if}}
</div>
<div class="chat-buttons"> <div class="chat-buttons">
{{> 'partial-appel-chance'}} {{> 'partial-appel-chance'}}
</div> </div>

View File

@@ -1,7 +1,7 @@
<div class="roll-chat"> <div class="roll-chat">
<div class="chat-img"> <div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" /> <img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.img}}" data-tooltip="{{current.comp.name}}" /> <img src="{{current.comp.comp.img}}" data-tooltip="{{current.comp.label}}" />
<img src="{{opponent.img}}" data-tooltip="{{opponent.name}}" /> <img src="{{opponent.img}}" data-tooltip="{{opponent.name}}" />
</div> </div>

View File

@@ -0,0 +1,28 @@
<div class="roll-chat">
<div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.comp.img}}" data-tooltip="{{current.comp.label}}" />
</div>
<div class="chat-header">
{{active.name}} Joue : {{current.jeu.label}} (niveau de base {{current.jeu.jeu.system.base}})
</div>
<div class="chat-resume">
{{current.carac.label}} / {{current.comp.label}} à {{current.diff.value}}
<br>{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.hbs"}}
</div>
<div class="chat-details">
<p>
{{active.name}}
{{#if rolled.isSuccess}}marque{{else}}perd{{/if}}
des points dans la partie, obtenant {{rolled.ptTache}} points de tâche (si applicable pour le jeu en cours).
</p>
{{> 'partial-info-appel-moral'}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs" current.jeu.jeu.system}}
</div>
<div class="chat-buttons">
{{> 'partial-appel-chance'}}
</div>
</div>

View File

@@ -1,7 +1,7 @@
<div class="roll-chat"> <div class="roll-chat">
<div class="chat-img"> <div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" /> <img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.img}}" data-tooltip="{{current.comp.name}}" /> <img src="{{current.comp.comp.img}}" data-tooltip="{{current.comp.label}}" />
</div> </div>
<div class="chat-header"> <div class="chat-header">
{{active.name}} a médité : {{current.meditation.label}} {{active.name}} a médité : {{current.meditation.label}}

View File

@@ -1,7 +1,7 @@
<div class="roll-chat"> <div class="roll-chat">
<div class="chat-img"> <div class="chat-img">
<img src="{{active.img}}" data-tooltip="{{active.name}}" /> <img src="{{active.img}}" data-tooltip="{{active.name}}" />
<img src="{{current.comp.img}}" data-tooltip="{{current.comp.name}}" /> <img src="{{current.comp.comp.img}}" data-tooltip="{{current.comp.label}}" />
</div> </div>
<div class="chat-header"> <div class="chat-header">
{{active.name}} {{current.oeuvre.art.action}}: {{current.oeuvre.label}} (de niveau {{current.oeuvre.oeuvre.system.niveau}}) {{active.name}} {{current.oeuvre.art.action}}: {{current.oeuvre.label}} (de niveau {{current.oeuvre.oeuvre.system.niveau}})
@@ -23,6 +23,7 @@
{{> 'partial-info-appel-moral'}} {{> 'partial-info-appel-moral'}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs" current.oeuvre.oeuvre.system}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs" current.oeuvre.oeuvre.system}}
</div> </div>
<div class="chat-buttons"> <div class="chat-buttons">
{{> 'partial-appel-chance'}} {{> 'partial-appel-chance'}}
</div> </div>

View File

@@ -15,7 +15,6 @@
<div class="chat-details"> <div class="chat-details">
<hr> <hr>
<p> <p>
{{log 'tache' this }}
{{#if rolled.isSuccess}} {{#if rolled.isSuccess}}
{{active.name}} a obtenu {{rolled.ptTache}} point{{~#unless (eq rolled.ptTache 1)}}s{{/unless}} de tâche, {{active.name}} a obtenu {{rolled.ptTache}} point{{~#unless (eq rolled.ptTache 1)}}s{{/unless}} de tâche,
{{else if (or rolled.isETotal rolled.isEPart)}} {{else if (or rolled.isETotal rolled.isEPart)}}
@@ -53,5 +52,6 @@
</div> </div>
<div class="chat-buttons"> <div class="chat-buttons">
{{> 'partial-appel-chance'}}
</div> </div>
</div> </div>

View File

@@ -2,4 +2,4 @@
{{selectOptions refs.comps selected=current.key valueAttr="key" labelAttr="label"}} {{selectOptions refs.comps selected=current.key valueAttr="key" labelAttr="label"}}
</select> </select>
<selected-numeric-value>{{plusMoins current.value}}</selected-numeric-value> <selected-numeric-value>{{plusMoins current.value}}</selected-numeric-value>
<img src="{{current.comp.img}}" data-tooltip="{{current.comp.name}}" /> <img src="{{current.comp.comp.img}}" data-tooltip="{{current.comp.label}}" />

View File

@@ -1,16 +1,53 @@
<roll-part-img> <roll-part-img>
<img src="{{current.recette.img}}" data-tooltip="{{current.recette.name}}" /> <img src="{{current.img}}" data-tooltip="{{current.label}}" />
</roll-part-img> </roll-part-img>
<roll-part-detail> <roll-part-detail>
<subline> <subline>
<select name="select-recette" {{#if rollData.type.retry}}disabled{{/if}}> <select name="select-preparation" {{#if rollData.type.retry}}disabled{{/if}}>
{{selectOptions refs.recettes selected=current.key valueAttr="key" labelAttr="label"}} {{selectOptions refs.preparations selected=current.key valueAttr="key" labelAttr="label"}}
</select> </select>
{{#if current.recette}} {{#if current.recette}}
<selected-numeric-value>{{plusMoins current.value}}</selected-numeric-value> <selected-numeric-value>{{plusMoins current.value}}</selected-numeric-value>
{{else if current.ingredient}}
{{numberInput current.value
name='diff-var'
step=1
min=-10
max=0
disabled=rollData.type.retry
}}
{{/if}} {{/if}}
</subline> </subline>
{{#if current.recette}} <subline>
{{> 'roll-oeuvre-recettecuisine'}} <label for="proportions">Proportions</label>
{{numberInput current.proportions
name='proportions'
step=1
min=1
max=(either current.proportionsMax 10)
disabled=rollData.type.retry
}}
{{#if (and current.sust (ne current.sust 1))}}<span>(&times; {{current.sust}})</span>{{/if}}
</subline>
<subline>
<input type="checkbox" name="fabriquer" {{#if current.fabriquer}}checked{{/if}} {{#if rollData.type.retry}}disabled{{/if}}/>
<label for="fabriquer"><i class="fa-solid fa-utensils"></i>&nbsp; Ajouter à l'équipement</label>
</subline>
{{#if current.ingredients}}
<subline><span><strong>Ingrédients:</strong></span></subline>
<subline>
<div class="poesie-extrait">
{{{current.ingredients}}}
</div>
</subline>
{{/if}} {{/if}}
{{#if current.recette}}
{{#if current.ingredients}}
<hr>
<subline>
{{/if}}
{{> "systems/foundryvtt-reve-de-dragon/templates/partial-description.hbs" current.recette.system}}
</subline>
{{/if}}
</roll-part-detail> </roll-part-detail>

View File

@@ -6,7 +6,6 @@
<select name="select-jeu" {{#if rollData.type.retry}}disabled{{/if}}> <select name="select-jeu" {{#if rollData.type.retry}}disabled{{/if}}>
{{selectOptions refs.jeux selected=current.key valueAttr="key" labelAttr="label"}} {{selectOptions refs.jeux selected=current.key valueAttr="key" labelAttr="label"}}
</select> </select>
<selected-numeric-value>{{plusMoins current.value}}</selected-numeric-value>
</subline> </subline>
<subline> <subline>
{{> "systems/foundryvtt-reve-de-dragon/templates/partial-description.hbs" current.jeu.system}} {{> "systems/foundryvtt-reve-de-dragon/templates/partial-description.hbs" current.jeu.system}}

View File

@@ -39,10 +39,11 @@
{{else}} {{else}}
<input type="checkbox" name="reserve" {{#if current.isReserve}}checked{{/if}} {{#if rollData.type.retry}}disabled{{/if}}/> <input type="checkbox" name="reserve" {{#if current.isReserve}}checked{{/if}} {{#if rollData.type.retry}}disabled{{/if}}/>
<label for="reserve"><i class="fa-solid fa-sparkles"></i>&nbsp; Mettre en réserve</label> <label for="reserve"><i class="fa-solid fa-sparkles"></i>&nbsp; Mettre en réserve</label>
{{!-- TODO: proposer de mettre une HN/Taille de zone --}}
{{/if}} {{/if}}
</subline> </subline>
<subline>Case TMR:&nbsp;{{current.caseTMR}}</subline> <subline>Case TMR:&nbsp;{{current.caseTMR}}</subline>
{{#if current.bonusCase}} {{#if current.bonusCase}}
<subline>Bonus case: {{plusMoins current.bonusCase}}%</subline> <subline>Bonus case: {{plusMoins current.bonusCase}}%</subline>
{{/if}} {{/if}}
</roll-part-detail> </roll-part-detail>