Roll V2: cuisine
@@ -4,6 +4,8 @@
|
||||
|
||||
- Nouvelle fenêtre de jets de dés
|
||||
- jeux
|
||||
- cuisine et préparation de nourriture
|
||||
|
||||
## 13.0.10 - Les papilles d'Illysis
|
||||
|
||||
- Ajout d'un statut "saignement" en cas de blessure grave ou critique sans premiers soins
|
||||
|
@@ -160,7 +160,7 @@ select,
|
||||
min-height: 100px;
|
||||
background: var(--rdd-bg-input-alt);
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
color: var(--rdd-color-text-primary);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .monnaie-content .window-content {
|
||||
@@ -177,7 +177,7 @@ select,
|
||||
background: var(--fieldset-background);
|
||||
color: var(--rdd-color-text-primary);
|
||||
margin-bottom: 4px;
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
border-color: var(--rdd-color-text-primary);
|
||||
border-width: 2px;
|
||||
}
|
||||
@@ -207,7 +207,7 @@ select,
|
||||
border: 1px solid var(--rdd-color-border-input);
|
||||
color: var(--rdd-color-text-input);
|
||||
padding: 2px 2px;
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .monnaie-content .form-group input[type="checkbox"] {
|
||||
flex: 0 0 20px;
|
||||
@@ -251,7 +251,7 @@ select,
|
||||
min-height: 100px;
|
||||
background: var(--rdd-bg-input-alt);
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
color: var(--rdd-color-text-primary);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .munition-content .window-content {
|
||||
@@ -268,7 +268,7 @@ select,
|
||||
background: var(--fieldset-background);
|
||||
color: var(--rdd-color-text-primary);
|
||||
margin-bottom: 4px;
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
border-color: var(--rdd-color-text-primary);
|
||||
border-width: 2px;
|
||||
}
|
||||
@@ -298,7 +298,7 @@ select,
|
||||
border: 1px solid var(--rdd-color-border-input);
|
||||
color: var(--rdd-color-text-input);
|
||||
padding: 2px 2px;
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .munition-content .form-group input[type="checkbox"] {
|
||||
flex: 0 0 20px;
|
||||
@@ -342,7 +342,7 @@ select,
|
||||
min-height: 100px;
|
||||
background: var(--rdd-bg-input-alt);
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
color: var(--rdd-color-text-primary);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .tarot-content .window-content {
|
||||
@@ -359,7 +359,7 @@ select,
|
||||
background: var(--fieldset-background);
|
||||
color: var(--rdd-color-text-primary);
|
||||
margin-bottom: 4px;
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
border-color: var(--rdd-color-text-primary);
|
||||
border-width: 2px;
|
||||
}
|
||||
@@ -389,7 +389,7 @@ select,
|
||||
border: 1px solid var(--rdd-color-border-input);
|
||||
color: var(--rdd-color-text-input);
|
||||
padding: 2px 2px;
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .tarot-content .form-group input[type="checkbox"] {
|
||||
flex: 0 0 20px;
|
||||
@@ -530,7 +530,7 @@ select,
|
||||
margin: 0.1rem 0;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section subline .warning {
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
background: var(--gradient-warning);
|
||||
}
|
||||
.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 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: normal;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline span.status-surprise {
|
||||
display: flex;
|
||||
@@ -576,8 +577,12 @@ select,
|
||||
display: flow;
|
||||
width: 2.5rem;
|
||||
text-align: right;
|
||||
margin: 0 0.2rem 0 0.5rem;
|
||||
margin: 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 {
|
||||
flex-basis: content;
|
||||
@@ -632,12 +637,13 @@ select,
|
||||
margin: 0 0.1rem;
|
||||
}
|
||||
.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"] {
|
||||
min-width: 8rem;
|
||||
max-width: 11rem;
|
||||
margin-left: 1rem;
|
||||
max-width: 10rem;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="coeur"] select[name="coeur"] {
|
||||
max-width: 4rem;
|
||||
@@ -1463,38 +1469,38 @@ select,
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd-roll-part {
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
padding: 3px;
|
||||
background: var(--gradient-gold);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd-roll-sign {
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
padding: 3px;
|
||||
background: var(--gradient-silver);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd-roll-norm {
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
padding: 3px;
|
||||
background: var(--gradient-green);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd-roll-notSign,
|
||||
.system-foundryvtt-reve-de-dragon .rdd-roll-echec {
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
padding: 3px;
|
||||
background: var(--gradient-red);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd-roll-epart {
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
padding: 3px;
|
||||
background: var(--gradient-violet);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd-roll-etotal {
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
padding: 3px;
|
||||
background: var(--gradient-purple-black);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd-diviseur {
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
padding: 3px;
|
||||
background: var(--gradient-red);
|
||||
}
|
||||
@@ -1522,6 +1528,7 @@ select,
|
||||
font-style: italic;
|
||||
color: rgba(82, 17, 131, 0.9);
|
||||
overflow-y: scroll;
|
||||
width: 100%;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .poesie-reference {
|
||||
font-size: 0.7rem;
|
||||
@@ -1587,7 +1594,7 @@ select,
|
||||
height: var(--form-field-height);
|
||||
margin: 0;
|
||||
color: var(--color-text-dark-primary);
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .app-calendar-astrologie div.theme-astral {
|
||||
width: 14rem;
|
||||
@@ -1638,7 +1645,7 @@ select,
|
||||
background: hsla(280, 50%, 50%, 0.1);
|
||||
padding: 1px 4px;
|
||||
border: 1px solid var(--color-border-dark-tertiary);
|
||||
border-radius: 2px;
|
||||
border-radius: 0.2rem;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
@@ -1648,7 +1655,7 @@ select,
|
||||
font-weight: 560;
|
||||
padding: 0.1rem 0.3rem;
|
||||
border: 1px solid var(--color-border-dark-tertiary);
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.2rem;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
display: ruby;
|
||||
@@ -1768,7 +1775,7 @@ select,
|
||||
.system-foundryvtt-reve-de-dragon .xp-level-up {
|
||||
margin: 0.1rem;
|
||||
box-shadow: inset 0px 0px 1px #00000096;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.2rem;
|
||||
padding: 0.1rem;
|
||||
flex: 1 1 5rem;
|
||||
background: var(--gradient-gold) !important;
|
||||
@@ -1799,7 +1806,7 @@ select,
|
||||
.system-foundryvtt-reve-de-dragon .list-item {
|
||||
margin: 0.1rem;
|
||||
box-shadow: inset 0px 0px 1px #00000096;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.2rem;
|
||||
padding: 0.1rem;
|
||||
flex: 1 1 1.5rem;
|
||||
display: flex;
|
||||
@@ -2112,6 +2119,9 @@ select,
|
||||
font-size: 0.7rem;
|
||||
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 {
|
||||
margin: 0.2rem 0;
|
||||
}
|
||||
@@ -2332,7 +2342,7 @@ select,
|
||||
font-size: 0.8rem;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
border-radius: 0.3rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon div.horloge-roue div img {
|
||||
border: none;
|
||||
@@ -2659,7 +2669,7 @@ select,
|
||||
.system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements {
|
||||
width: 10rem;
|
||||
background: var(--background-tooltip);
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
1
icons/cuisine/gibier.svg
Normal file
After Width: | Height: | Size: 6.8 KiB |
1
icons/cuisine/herbe.svg
Normal file
After Width: | Height: | Size: 5.6 KiB |
1
icons/cuisine/mortadelle.svg
Normal file
After Width: | Height: | Size: 8.6 KiB |
1
icons/cuisine/plante.svg
Normal file
After Width: | Height: | Size: 6.8 KiB |
1
icons/cuisine/ragout.svg
Normal file
After Width: | Height: | Size: 6.3 KiB |
1
icons/cuisine/saucisson.svg
Normal file
After Width: | Height: | Size: 8.2 KiB |
1
icons/cuisine/volaille.svg
Normal file
After Width: | Height: | Size: 10 KiB |
@@ -777,31 +777,31 @@
|
||||
}
|
||||
.rdd-roll-part {
|
||||
align-items: center;
|
||||
border-radius: 6px; padding: 3px;
|
||||
border-radius: 0.5rem; padding: 3px;
|
||||
background: var(--gradient-gold);
|
||||
}
|
||||
.rdd-roll-sign{
|
||||
border-radius: 6px; padding: 3px;
|
||||
border-radius: 0.5rem; padding: 3px;
|
||||
background: var(--gradient-silver);
|
||||
}
|
||||
.rdd-roll-norm{
|
||||
border-radius: 6px; padding: 3px;
|
||||
border-radius: 0.5rem; padding: 3px;
|
||||
background: var(--gradient-green);
|
||||
}
|
||||
.rdd-roll-notSign, .rdd-roll-echec{
|
||||
border-radius: 6px; padding: 3px;
|
||||
border-radius: 0.5rem; padding: 3px;
|
||||
background: var(--gradient-red);
|
||||
}
|
||||
.rdd-roll-epart{
|
||||
border-radius: 6px; padding: 3px;
|
||||
border-radius: 0.5rem; padding: 3px;
|
||||
background: var(--gradient-violet);
|
||||
}
|
||||
.rdd-roll-etotal{
|
||||
border-radius: 6px; padding: 3px;
|
||||
border-radius: 0.5rem; padding: 3px;
|
||||
background: var(--gradient-purple-black);
|
||||
}
|
||||
.rdd-diviseur{
|
||||
border-radius: 6px; padding: 3px;
|
||||
border-radius: 0.5rem; padding: 3px;
|
||||
background: var(--gradient-red);
|
||||
}
|
||||
|
||||
@@ -833,14 +833,9 @@
|
||||
font-style: italic;
|
||||
color: rgba(82, 17, 131, 0.9);
|
||||
overflow-y: scroll;
|
||||
// overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// .poesie-extrait:hover {
|
||||
// overflow-y: scroll;
|
||||
// opacity: 1;
|
||||
// }
|
||||
|
||||
.poesie-reference {
|
||||
font-size: 0.7rem;
|
||||
text-align: right;
|
||||
@@ -913,7 +908,7 @@
|
||||
height: var(--form-field-height);
|
||||
margin: 0;
|
||||
color: var(--color-text-dark-primary);
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
.app-calendar-astrologie{
|
||||
div.theme-astral{
|
||||
@@ -970,7 +965,7 @@
|
||||
background: hsla(280, 50%, 50%, 0.1);
|
||||
padding: 1px 4px;
|
||||
border: 1px solid var(--color-border-dark-tertiary);
|
||||
border-radius: 2px;
|
||||
border-radius: 0.2rem;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
@@ -981,7 +976,7 @@
|
||||
font-weight: 560;
|
||||
padding: 0.1rem 0.3rem;
|
||||
border: 1px solid var(--color-border-dark-tertiary);
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.2rem;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
display: ruby;
|
||||
@@ -1111,7 +1106,7 @@
|
||||
.xp-level-up {
|
||||
margin: 0.1rem;
|
||||
box-shadow: inset 0px 0px 1px #00000096;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.2rem;
|
||||
padding: 0.1rem;
|
||||
flex: 1 1 5rem;
|
||||
background: var(--gradient-gold) !important;
|
||||
@@ -1142,7 +1137,7 @@
|
||||
.list-item {
|
||||
margin: 0.1rem;
|
||||
box-shadow: inset 0px 0px 1px #00000096;
|
||||
border-radius: 0.25rem;
|
||||
border-radius: 0.2rem;
|
||||
padding: 0.1rem;
|
||||
flex: 1 1 1.5rem;
|
||||
display: flex;
|
||||
@@ -1483,9 +1478,14 @@
|
||||
.message-content {
|
||||
text-align: justify;
|
||||
}
|
||||
header.message-header .heure-rdd {
|
||||
font-size: 0.7rem;
|
||||
flex-grow: 3;
|
||||
header.message-header{
|
||||
.heure-rdd {
|
||||
font-size: 0.7rem;
|
||||
flex-grow: 3;
|
||||
}
|
||||
.message-metadata {
|
||||
flex-grow: 3.5;
|
||||
}
|
||||
}
|
||||
hr {
|
||||
margin: 0.2rem 0;
|
||||
@@ -1685,7 +1685,7 @@
|
||||
font-size: 0.8rem;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
border-radius: 0.3rem;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
div.horloge-roue div img {
|
||||
@@ -1921,7 +1921,7 @@
|
||||
.ttt-ajustements {
|
||||
width: 10rem;
|
||||
background: var(--background-tooltip);
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
padding: 3px 0;
|
||||
div:nth-child(odd) {
|
||||
|
@@ -90,7 +90,7 @@
|
||||
flex-direction: row;
|
||||
margin: 0.1rem 0;
|
||||
.warning {
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
background: var(--gradient-warning);
|
||||
}
|
||||
}
|
||||
@@ -121,6 +121,7 @@
|
||||
div.poesie-extrait{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: normal;
|
||||
}
|
||||
span.status-surprise{
|
||||
display: flex;
|
||||
@@ -141,8 +142,13 @@
|
||||
display: flow;
|
||||
width: 2.5rem;
|
||||
text-align: right;
|
||||
margin: 0 0.2rem 0 0.5rem;
|
||||
margin: 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 {
|
||||
@@ -205,13 +211,13 @@
|
||||
}
|
||||
|
||||
roll-carac select[name="select-carac"] {
|
||||
max-width: 6rem;
|
||||
|
||||
min-width: 6.5rem;
|
||||
max-width: 8rem;
|
||||
}
|
||||
roll-comp select[name="select-comp"] {
|
||||
min-width: 8rem;
|
||||
max-width: 11rem;
|
||||
margin-left: 1rem;
|
||||
max-width: 10rem;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
roll-conditions roll-section[name="coeur"] select[name="coeur"] {
|
||||
|
@@ -8,7 +8,7 @@
|
||||
min-height: 100px; // Hauteur minimale pour la description
|
||||
background: var(--rdd-bg-input-alt); // Une couleur de fond alternative
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
color: var(--rdd-color-text-primary);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
background: var(--fieldset-background);
|
||||
color: var(--rdd-color-text-primary);
|
||||
margin-bottom: 4px;
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
border-color: var(--rdd-color-text-primary);
|
||||
border-width: 2px;
|
||||
}
|
||||
@@ -64,7 +64,7 @@
|
||||
--rdd-color-text-input
|
||||
); // Assurez-vous que cette variable existe
|
||||
padding: 2px 2px; // Augmentation du padding vertical
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
|
@@ -51,6 +51,7 @@ import { ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION } from "./roll/roll-constants.mjs";
|
||||
import { PART_TACHE } from "./roll/roll-part-tache.mjs";
|
||||
import { PART_COMP } from "./roll/roll-part-comp.mjs";
|
||||
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']
|
||||
|
||||
@@ -1937,10 +1938,11 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
type: { allowed: [PART_COMP], current: PART_COMP },
|
||||
selected: {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -2064,7 +2066,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
selected: { meditation: { key: id } },
|
||||
type: { allowed: [ROLL_TYPE_MEDITATION], current: ROLL_TYPE_MEDITATION }
|
||||
}
|
||||
await RollDialog.create(rollData)
|
||||
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3210,14 +3212,26 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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 = {
|
||||
verbe: 'Cuisiner',
|
||||
compName: 'cuisine',
|
||||
proportions: 1,
|
||||
ajouterEquipement: false
|
||||
};
|
||||
await this._rollArtV1(artData, 'odoratgout', oeuvre, r => this._resultRecetteCuisine(r));
|
||||
await this._rollArtV1(artData, 'odoratgout', recette, r => this._resultRecetteCuisine(r));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -3250,6 +3264,18 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
|
||||
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') {
|
||||
const nourriture = {
|
||||
name: 'Plat de ' + item.name,
|
||||
@@ -3260,7 +3286,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
exotisme: item.system.exotisme,
|
||||
ingredients: item.name
|
||||
}
|
||||
};
|
||||
}
|
||||
const artData = {
|
||||
verbe: 'Préparer',
|
||||
compName: 'cuisine',
|
||||
|
@@ -191,7 +191,7 @@ export class ChatUtility {
|
||||
const timestamp = new RdDTimestamp(rddTimestamp);
|
||||
const timestampData = timestamp.toCalendrier();
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import { RdDResolutionTable } from "../rdd-resolution-table.js"
|
||||
import { RDD_CONFIG, renderTemplate } from "../constants.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 {
|
||||
static init() {
|
||||
@@ -25,7 +26,7 @@ export default class ChatRollResult {
|
||||
})
|
||||
}
|
||||
|
||||
async display(roll) {
|
||||
async display(roll, impacts) {
|
||||
this.prepareDisplay(roll)
|
||||
|
||||
const chatMessage = await ChatUtility.createChatWithRollMode(
|
||||
@@ -35,7 +36,8 @@ export default class ChatRollResult {
|
||||
roll.active.actor,
|
||||
roll.current?.rollmode?.key
|
||||
)
|
||||
const save = RollDialog.saveParts(roll)
|
||||
const save = RollDialog.saveParts(roll, impacts)
|
||||
|
||||
ChatUtility.setMessageData(chatMessage, 'rollData', save)
|
||||
return chatMessage
|
||||
}
|
||||
@@ -109,6 +111,7 @@ export default class ChatRollResult {
|
||||
$(html).on("click", '.encaissement', event => this.onClickEncaissement(event))
|
||||
$(html).on("click", '.resister-recul', event => this.onClickRecul(event))
|
||||
$(html).on("click", '.choix-particuliere', event => this.onClickChoixParticuliere(event))
|
||||
$(html).on("click", '.faire-gouter', event => this.onClickFaireGouter(event))
|
||||
|
||||
}
|
||||
|
||||
@@ -143,6 +146,7 @@ export default class ChatRollResult {
|
||||
|
||||
onAppelChanceSuccess(savedRoll, chatMessage) {
|
||||
const reRoll = foundry.utils.duplicate(savedRoll)
|
||||
console.log('onAppelChanceSuccess savedRoll', savedRoll)
|
||||
reRoll.type.retry = true
|
||||
const callbacks = [r => ChatUtility.removeChatMessageId(chatMessage.id)]
|
||||
// TODO: annuler les effets
|
||||
@@ -211,4 +215,9 @@ export default class ChatRollResult {
|
||||
await this.updateChatMessage(chatMessage, savedRoll)
|
||||
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)
|
||||
}
|
||||
}
|
@@ -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 { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
|
||||
import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
|
||||
@@ -9,8 +9,8 @@ export class RollBasicParts {
|
||||
|
||||
static restore(rollData) {
|
||||
rollData.ids.sceneId = rollData.ids.sceneId ?? canvas.scene.id
|
||||
rollData.active = RollBasicParts.$getActor(rollData)
|
||||
rollData.opponent = RollBasicParts.$getOpponent(rollData)
|
||||
rollData.active = RollBasicParts.getTokenActor(rollData)
|
||||
rollData.opponent = RollBasicParts.getTokenActorOpponent(rollData)
|
||||
if (rollData.type.opposed == undefined) {
|
||||
rollData.type.opposed = rollData.opponent != null
|
||||
}
|
||||
@@ -64,30 +64,30 @@ export class RollBasicParts {
|
||||
}
|
||||
}
|
||||
|
||||
static $getActor(rollData) {
|
||||
static getTokenActor(rollData) {
|
||||
if (rollData.ids.actorTokenId) {
|
||||
return ActorToken.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId)
|
||||
return TokenActor.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId)
|
||||
}
|
||||
else {
|
||||
const actorId = rollData.ids.actorId ?? (canvas.tokens.controlled.length == 1
|
||||
/** TODO: jets de plusieurs personnages??? */
|
||||
? canvas.tokens.controlled[0]
|
||||
: 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) {
|
||||
return ActorToken.fromTokenId(rollData.ids.opponentTokenId, rollData.ids.sceneId)
|
||||
return TokenActor.fromTokenId(rollData.ids.opponentTokenId, rollData.ids.sceneId)
|
||||
}
|
||||
else if (rollData.ids.opponentId) {
|
||||
return ActorToken.fromActorId(rollData.ids.opponentId)
|
||||
return TokenActor.fromActorId(rollData.ids.opponentId)
|
||||
}
|
||||
else {
|
||||
const targets = Array.from(game.user.targets)
|
||||
if (targets.length == 1) {
|
||||
return ActorToken.fromToken(targets[0])
|
||||
return TokenActor.fromToken(targets[0])
|
||||
}
|
||||
else {
|
||||
return undefined
|
||||
|
@@ -43,6 +43,7 @@ import { renderTemplate } from "../constants.js";
|
||||
import { RollTypeCuisine } from "./roll-type-cuisine.mjs";
|
||||
import { RollPartCuisine } from "./roll-part-cuisine.mjs";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js";
|
||||
import { ActorImpacts } from "../technical/actor-impacts.mjs";
|
||||
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
|
||||
@@ -292,7 +293,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
return rollData
|
||||
}
|
||||
|
||||
static saveParts(rollData) {
|
||||
static saveParts(rollData, impacts) {
|
||||
const target = RollBasicParts.initFrom(rollData)
|
||||
ROLL_PARTS.filter(p => p.isActive(rollData))
|
||||
.forEach(p => p.storeClean(rollData, target))
|
||||
@@ -301,6 +302,12 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
target.result = rollData.result
|
||||
target.done = rollData.done ?? {}
|
||||
target.dmg = rollData.dmg
|
||||
if (impacts) {
|
||||
target.reverse = {
|
||||
active: impacts.active?.reverseImpacts(),
|
||||
opponent: impacts.opponent?.reverseImpacts()
|
||||
}
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
@@ -442,15 +449,26 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1
|
||||
roll.choix = {}
|
||||
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)
|
||||
const callbacks = [
|
||||
...this.rollOptions.callbacks,
|
||||
...selectedRollType.callbacks(this.rollOptions),
|
||||
]
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@@ -19,55 +19,153 @@ export class RollPartCuisine extends RollPartSelect {
|
||||
isValid(rollData) { return rollData.active.actor.isPersonnage() }
|
||||
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) {
|
||||
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)
|
||||
.map(it => RollPartCuisine.$extractRecette(it, rollData.active.actor))
|
||||
if (refs.recettes.length > 0) {
|
||||
this.$selectRecette(rollData)
|
||||
.map(RollPartCuisine.$extractPreparationRecette)
|
||||
|
||||
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 {
|
||||
key: recette.id,
|
||||
label: recette.name,
|
||||
caracs: RollPartCuisine.getCaracs(recette),
|
||||
qualite: recette.system.niveau,
|
||||
img: 'systems/foundryvtt-reve-de-dragon/icons/cuisine/ragout.svg',
|
||||
sust: 1,
|
||||
exotisme: recette.system.exotisme,
|
||||
ingredients: recette.system.ingredients,
|
||||
proportions: proportions,
|
||||
proportionsMax: proportions * 10,
|
||||
value: -recette.system.niveau,
|
||||
recette: recette,
|
||||
comp: actor.getCompetence('Cuisine')
|
||||
fabriquer: true,
|
||||
}
|
||||
}
|
||||
static getCaracs(recette){
|
||||
// TODO: permettre différentes caractéristiques pour la cuisine?
|
||||
return [CARACS.ODORATGOUT, CARACS.EMPATHIE, CARACS.DEXTERITE]
|
||||
|
||||
static $extractPreparationBrut(ingredient) {
|
||||
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)
|
||||
}
|
||||
|
||||
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 index = selectOptions.selectedIndex
|
||||
this.$selectRecette(rollDialog.rollData, selectOptions[index]?.value)
|
||||
this.$selectPreparation(rollDialog.rollData, selectOptions[index]?.value)
|
||||
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) {
|
||||
if (this.visible(rollData)) {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
|
||||
case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.ODORATGOUT])
|
||||
case PART_COMP: return part.filterComps(rollData, [this.getRefs(rollData).cuisine.name])
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@@ -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 { PART_CUISINE } from "./roll-part-cuisine.mjs"
|
||||
import { RollType } from "./roll-type.mjs"
|
||||
@@ -9,19 +11,73 @@ export class RollTypeCuisine extends RollType {
|
||||
visible(rollData) { return rollData.active.actor.isPersonnage() }
|
||||
title(rollData) {
|
||||
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) {
|
||||
this.setDiffType(rollData, DIFF.AUCUN)
|
||||
}
|
||||
|
||||
getResult(rollData){
|
||||
getResult(rollData, impacts) {
|
||||
const current = rollData.current[PART_CUISINE]
|
||||
const qualite = rollData.rolled.isSuccess ? current.qualite : Math.min(current.qualite, current.comp.system.niveau)
|
||||
return {
|
||||
qualite: qualite + rollData.rolled.ptQualite
|
||||
const diff = -current.value
|
||||
const cuisine = rollData.refs[PART_CUISINE].cuisine
|
||||
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()
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -16,11 +16,12 @@ export class RollTypeOeuvre extends RollType {
|
||||
this.setDiffType(rollData, DIFF.AUCUN)
|
||||
}
|
||||
|
||||
getResult(rollData){
|
||||
getResult(rollData, impacts) {
|
||||
const current = rollData.current[PART_OEUVRE]
|
||||
const qualite = rollData.rolled.isSuccess ? current.qualite : Math.min(current.qualite, current.comp.system.niveau)
|
||||
return {
|
||||
qualite: qualite + rollData.rolled.ptQualite
|
||||
qualite: qualite + rollData.rolled.ptQualite,
|
||||
messages: []
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -53,5 +53,14 @@ export class RollType {
|
||||
|
||||
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) { }
|
||||
}
|
||||
|
128
module/technical/actor-impacts.mjs
Normal 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
|
||||
}
|
||||
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
/**
|
||||
* 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){
|
||||
return token ? ActorToken.fromToken(token) : ActorToken.fromActor(actor)
|
||||
return token ? TokenActor.fromToken(token) : TokenActor.fromActor(actor)
|
||||
}
|
||||
|
||||
static fromActorId(actorId, onError = () => undefined) {
|
||||
@@ -19,17 +19,17 @@ export class ActorToken {
|
||||
|
||||
static fromActor(actor) {
|
||||
const token = actor.isToken ? actor.token : actor.prototypeToken
|
||||
return ActorToken.fromToken(token)
|
||||
return TokenActor.fromToken(token)
|
||||
}
|
||||
|
||||
static fromTokenId(tokenId, sceneId = undefined) {
|
||||
const tokensList = sceneId ? game.scenes.get(sceneId).tokens : canvas.tokens.placeables
|
||||
const token = tokensList.get(tokenId)
|
||||
return ActorToken.fromToken(token)
|
||||
return TokenActor.fromToken(token)
|
||||
}
|
||||
|
||||
static fromToken(token) {
|
||||
return new ActorToken(token)
|
||||
return new TokenActor(token)
|
||||
}
|
||||
|
||||
constructor(token) {
|
@@ -1,3 +1,3 @@
|
||||
<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>
|
@@ -1,7 +1,7 @@
|
||||
<div class="roll-chat">
|
||||
<div class="chat-img">
|
||||
<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}}" />
|
||||
</div>
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div class="roll-chat">
|
||||
<div class="chat-img">
|
||||
<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 class="chat-header">
|
||||
{{active.name}} fait un jet de {{current.comp.label}}
|
||||
|
@@ -1,10 +1,15 @@
|
||||
<div class="roll-chat">
|
||||
<div class="chat-img">
|
||||
<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 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 class="chat-resume">
|
||||
@@ -14,16 +19,35 @@
|
||||
|
||||
<div class="chat-details">
|
||||
<p>
|
||||
{{active.name}}
|
||||
{{#if rolled.isSuccess}}réussit la recette avec
|
||||
{{else}}manque d'inspiration, le plat a
|
||||
{{/if}}
|
||||
une qualité de {{result.qualite}}.
|
||||
{{active.name}}
|
||||
{{#if rolled.isSuccess}}
|
||||
réussit la recette, pour un plat de qualité {{result.qualite~}}
|
||||
{{#if (lt result.exotisme 0)}}et d'exotisme {{result.exotisme}}{{/if~}}
|
||||
{{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>
|
||||
{{> 'partial-info-appel-moral'}}
|
||||
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-description.hbs" current.cuisine.recette.system}}
|
||||
</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> faire goûter à ses compagnons
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="chat-buttons">
|
||||
{{> 'partial-appel-chance'}}
|
||||
</div>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div class="roll-chat">
|
||||
<div class="chat-img">
|
||||
<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}}" />
|
||||
</div>
|
||||
|
||||
|
@@ -1,8 +1,7 @@
|
||||
{{log 'jeu' this}}
|
||||
<div class="roll-chat">
|
||||
<div class="chat-img">
|
||||
<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 class="chat-header">
|
||||
{{active.name}} Joue : {{current.jeu.label}} (niveau de base {{current.jeu.jeu.system.base}})
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div class="roll-chat">
|
||||
<div class="chat-img">
|
||||
<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 class="chat-header">
|
||||
{{active.name}} a médité : {{current.meditation.label}}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div class="roll-chat">
|
||||
<div class="chat-img">
|
||||
<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 class="chat-header">
|
||||
{{active.name}} {{current.oeuvre.art.action}}: {{current.oeuvre.label}} (de niveau {{current.oeuvre.oeuvre.system.niveau}})
|
||||
|
@@ -2,4 +2,4 @@
|
||||
{{selectOptions refs.comps selected=current.key valueAttr="key" labelAttr="label"}}
|
||||
</select>
|
||||
<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}}" />
|
||||
|
@@ -1,16 +1,53 @@
|
||||
<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-detail>
|
||||
<subline>
|
||||
<select name="select-recette" {{#if rollData.type.retry}}disabled{{/if}}>
|
||||
{{selectOptions refs.recettes selected=current.key valueAttr="key" labelAttr="label"}}
|
||||
<select name="select-preparation" {{#if rollData.type.retry}}disabled{{/if}}>
|
||||
{{selectOptions refs.preparations selected=current.key valueAttr="key" labelAttr="label"}}
|
||||
</select>
|
||||
{{#if current.recette}}
|
||||
<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}}
|
||||
</subline>
|
||||
{{#if current.recette}}
|
||||
{{> 'roll-oeuvre-recettecuisine'}}
|
||||
<subline>
|
||||
<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>(× {{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> 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 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>
|
@@ -39,10 +39,11 @@
|
||||
{{else}}
|
||||
<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> Mettre en réserve</label>
|
||||
{{!-- TODO: proposer de mettre une HN/Taille de zone --}}
|
||||
{{/if}}
|
||||
</subline>
|
||||
<subline>Case TMR: {{current.caseTMR}}</subline>
|
||||
{{#if current.bonusCase}}
|
||||
<subline>Bonus case: {{plusMoins current.bonusCase}}%</subline>
|
||||
{{/if}}
|
||||
{{#if current.bonusCase}}
|
||||
<subline>Bonus case: {{plusMoins current.bonusCase}}%</subline>
|
||||
{{/if}}
|
||||
</roll-part-detail>
|
||||
|