Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
edf920b340 | |||
293af5ab83 | |||
1bf9e330f4 | |||
33dc58138c | |||
fa6769fcd7 | |||
47c4478303 | |||
52065fd6f6 | |||
6886f19921 | |||
10a89cc268 | |||
6a987086f8 | |||
54f470d531 | |||
37af0dd4f1 | |||
d46b039a63 | |||
7370b633db | |||
d0ba1ebf99 | |||
053bc23d12 |
1
assets/actions/cuisine.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M259.063 25.094c-56.045 0-106.836 9.775-144.438 26.125-18.8 8.174-34.34 17.96-45.594 29.53-11.254 11.57-18.28 25.338-18.28 40.188 0 9.936 3.17 19.388 8.625 28.03-10.218 21.883-15.844 45.794-15.844 70.782 0 103.158 95.757 187.844 215.532 187.844 119.776 0 215.563-84.686 215.563-187.844 0-24.99-5.653-48.897-15.875-70.78 5.454-8.644 8.625-18.096 8.625-28.032 0-14.85-7.026-28.617-18.28-40.188-11.256-11.57-26.825-21.356-45.626-29.53-37.603-16.35-88.363-26.126-144.408-26.126zm0 18.687c53.848 0 102.554 9.6 136.968 24.564 17.208 7.482 30.775 16.306 39.658 25.437 8.882 9.133 13 18.115 13 27.157 0 9.043-4.118 18.057-13 27.188-8.883 9.13-22.45 17.956-39.657 25.438-34.413 14.963-83.12 24.562-136.967 24.562-53.85 0-102.555-9.6-136.97-24.563-17.206-7.48-30.804-16.306-39.687-25.437-8.882-9.13-12.97-18.145-12.97-27.188 0-9.042 4.088-18.024 12.97-27.156 8.883-9.13 22.48-17.954 39.688-25.436 34.414-14.964 83.12-24.563 136.97-24.563zm-7.782 17.282c-80.57 0-146 26.008-146 57.844 0 31.836 65.43 57.81 146 57.813 40.04 0 76.404-6.613 102.782-16.94-21.316 3.34-45.064 5.845-70.656 5.845-86.066 0-155.937-21.656-155.937-47.906s69.868-47.282 155.936-47.282c20.43 0 39.926.725 57.813 2.906-24.816-7.704-55.957-12.28-89.94-12.28zM87.657 360.5c-9.916 19.897-14.758 36.638-15.78 49.03-1.23 14.906 2.752 22.238 6.655 24.626 3.905 2.388 11.497 2.48 23.376-5.75 9.25-6.41 20.16-17.73 31.375-34.406-16.778-9.432-32.1-20.71-45.624-33.5zm342.75.063c-13.532 12.782-28.872 24.043-45.656 33.468 11.21 16.666 22.13 27.97 31.375 34.376 11.88 8.23 19.472 8.138 23.375 5.75 3.903-2.388 7.886-9.72 6.656-24.625-1.022-12.38-5.855-29.098-15.75-48.967zm-199.25 64.25c1.36 21.275 5.296 37.554 10.344 48.468 6.272 13.56 13.26 17.82 17.72 17.908 4.457.088 11.14-3.683 17.374-16.907 5.133-10.89 9.165-27.52 10.437-49.467a267.366 267.366 0 0 1-27.967 1.468c-9.437 0-18.75-.506-27.907-1.467z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
After Width: | Height: | Size: 2.1 KiB |
1
assets/ui/fatigue.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M249.094 18.25c-42.675 0-81.852 25.486-110.938 68.438C109.07 129.637 90.72 189.74 90.72 256.28c0 66.543 18.35 126.643 47.436 169.595s68.263 68.47 110.938 68.47 81.883-25.518 110.97-68.47c29.084-42.952 47.436-103.052 47.436-169.594 0-66.54-18.352-126.64-47.438-169.592C330.978 43.736 291.77 18.25 249.094 18.25zm-128.97 241.313c18.356 18.096 37.528 26.765 55.72 27.562 18.19.797 35.927-6.096 52.125-21.5l12.874 13.53c-19.214 18.274-42.25 27.658-65.813 26.626-23.56-1.03-47.1-12.3-68-32.905l13.095-13.313zm264.782 0 13.125 13.312C377.135 293.48 353.564 304.75 330 305.78c-23.563 1.033-46.598-8.35-65.813-26.624l12.875-13.53c16.2 15.403 33.934 22.296 52.125 21.5 18.192-.798 37.365-9.467 55.72-27.563zM251.562 371.656c36.423-.156 72.996 19.144 77.438 58.406-51.33 13.296-102.67 12.767-154 0 3.858-38.638 40.14-58.25 76.563-58.406z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
assets/ui/part-finesse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M45.95 14.553c-19.38.81-30.594 11.357-30.282 30.283l19.768 30.78c4.43-1.213 9.36-3.838 14.248-7.335l42.474 59.935c-17.018 20.83-31.258 44.44-42.71 70.836l26.55 26.552c11.275-23.6 24.634-44.826 39.918-63.864l210.82 297.475 166.807 33.213L460.33 325.62 162.78 114.745c19.907-16.108 41.842-29.91 65.652-41.578l-26.553-26.55c-27.206 11.803-51.442 26.576-72.735 44.292L69.39 48.56c3.443-4.823 6.062-9.735 7.342-14.242l-30.78-19.765zm400.84 86.933v.008l.003-.008h-.002zm0 .008-28.028 124.97-25.116-80.593-18.105 70.667-26.862-49.64-.584 57.818 128.484 91.69 15.184 87.017-1.168-186.885-34.457 39.713-9.346-154.756zm-300.95 27.98 222.224 196.368 25.645 66.75-66.75-25.645L130.6 144.734a308.453 308.453 0 0 1 15.238-15.26zm32.305 196.274v.004h.005l-.005-.004zm.005.004 28.028 22.775-36.21 4.088 57.82 19.272-105.706 4.09 115.05 27.45L136.1 422.114l127.316 25.696-67.164 43.803 208.494 1.752-87.017-15.185-104.54-150.676-35.037-1.752z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
1
assets/ui/part-force.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M227.227 21.777c-1.845 0-3.704.05-5.567.157-15.314.875-30.76 5.305-39.494 10.863l-.008 73.15c2.884-.094 5.777-.147 8.676-.142 23.382.036 47.104 3.286 68.47 9.513l.01-87.507c-7.034-3.518-19.178-6.03-32.087-6.033zm80.74 9.16c-11.925.15-23.077 2.364-29.967 5.596l-.008 77.602v7.658c38.486 15.67 64.814 42.48 58.735 78.764l-.96 5.73-5.562 1.674c-17.45 5.253-34.872 9.703-52.225 13.335v25.234c25.562-.704 51.327-2.687 77.145-6.098l.02-197.928c-8.284-5.563-23.508-10.243-38.842-11.328a100.065 100.065 0 0 0-8.336-.238zM143.223 46.294a99.206 99.206 0 0 0-16.491 1.172c-15.67 2.454-31.477 8.565-40.406 15.402l-.01 72.955c18.808-15.81 46.704-25.143 77.15-28.54l.007-57.966c-4.82-1.752-12.018-2.916-20.25-3.023zm258.394 3.46c-10.804.117-20.722 1.93-27.043 4.655l-.02 183.182c25.074-4.02 50.16-9.412 75.122-16.358l1.99-158.447c-8.352-5.9-23.648-11.025-39.05-12.553a100.98 100.98 0 0 0-11-.478zm-222.775 74.202c-53.72.702-101.407 20.365-97.887 66.6 15.836-3.918 30.84-5.893 44.94-6.1 34.84-.51 64.213 9.704 87.318 27.613 34.608-3.11 69.852-10 105.412-20.314.14-41.287-74.098-68.657-139.783-67.8zm-48.877 78.65c-1.296-.003-2.603.012-3.92.045-17.256.436-36.45 4.03-57.566 11.037 5.79 53.808 26.325 106.41 58.5 143.346 6.226 7.15 12.856 13.712 19.875 19.615 29.303 9.282 69.26 12.917 110.534 12.14 3.777-55.805-8.717-108.357-36.193-142.74-21.265-26.61-51.064-43.39-91.232-43.444zm129.326 22.282a545.177 545.177 0 0 1-27.995 4.15 138.77 138.77 0 0 1 4.502 5.346c3.146 3.937 6.094 8.062 8.873 12.334 9.916.144 19.868.125 29.857-.106H259.29v-21.723zm191.817 15.343c-65.406 17.826-131.462 25.41-195.85 25.315 16.998 35.144 23.828 78.093 21.013 122.6 42.482-2.08 85.03-8.23 118.187-15.983 26.693-32.78 47.37-77.118 56.65-131.932zM400.51 389.9c-38.334 9.145-87.95 16.056-136.873 17.454-47.67 1.36-94.336-2.228-129.448-15.262l-.01 78.93c27.187 12.568 76.414 20.205 127.318 20.298 51.224.094 104.214-7.173 139-20.773l.012-80.647z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
After Width: | Height: | Size: 2.1 KiB |
1
assets/ui/part-rapidite.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M275.03 20c35.223 49.563 53.59 113.64 55.69 173.47C315.154 143 289.092 88.423 250.81 48.75c40.294 79.527 51.15 172.312 37.938 256.094-12.287-75.777-40.564-159.524-92.375-227.156 29.6 70.937 36.64 149.785 24.813 221.843-8.745-51.804-25.41-107.4-52.594-158.81 13.023 54.315 12.854 107.64 3.437 159.28l21.657 6.813 15 4.718-11.28 10.908c-10.68 10.332-19.868 21.905-27.345 34.343 93.614 35.486 232.952 64.53 298.032 41.376-41.02 56.466-210.332 13.822-309.313-18.687-1.514 3.775-2.918 7.594-4.124 11.467a152.536 152.536 0 0 0-6.062 29.657l176.47 66.375c98.5 31.095 150.5-24.62 158.655-81.72C505.253 254.472 485.016 105.66 426.06 20h-22.187c40.092 65.52 66.67 154.216 60.47 255.344-8.154-79.833-42.8-157.214-98.44-219.5 38.676 85.094 56.566 185.746 34.376 288.625.057-118.816-33.1-225.865-105.092-324.47H275.03zm-110.186 1.594c41.255 29.176 74.328 74.093 97.5 120.656-7.702-46.15-21.3-86.79-44-120.656h-53.5zm176.375 0c28.882 15.143 52.096 36.614 71.28 66.78-7.14-27.79-17.217-49.85-31.438-66.78H341.22zM123.686 304.406a179.344 179.344 0 0 1-4.062 64L18.812 336.344V366l91.938 29.094a178.602 178.602 0 0 1-30.313 48.28l50.094 15.75c-3.038-24.898-1.136-49.885 6.282-73.718 7.446-23.92 20.223-46.108 37.032-65.22l-50.156-15.78z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
After Width: | Height: | Size: 1.5 KiB |
29
changelog.md
@@ -1,5 +1,34 @@
|
||||
# 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
|
||||
|
||||
- Ajout d'un statut "saignement" en cas de blessure grave ou critique sans premiers soins
|
||||
|
||||
- Nouvelle fenêtre de jets de dés
|
||||
- jets de méditation
|
||||
- jets de tâches
|
||||
- jets de caractéristiques
|
||||
- jets de compétences
|
||||
- Boutons d'initiative et d'attaque V2
|
||||
- fenêtre d'attaque
|
||||
- choix des armes
|
||||
- gestion des particulières
|
||||
- message au défenseur
|
||||
- gestion des demi-surprises (attaquant/défenseur)
|
||||
- gestion des tactiques (attaquant/défenseur)
|
||||
- en cours nouvelle fenêtre de jets
|
||||
- jets de compétence avec messages
|
||||
- jets de cuisine séparés avec messages (pour gérer plus tard les spécificités: fabricatioon de plats)
|
||||
- gestion des empoignades
|
||||
|
||||
- Technique: suppression de warnings foundry sur renderTemplate
|
||||
|
||||
## 13.0.9 - Le combat d'Illysis
|
||||
- Fix
|
||||
- La montée en TMR fonctionne
|
||||
|
@@ -96,6 +96,7 @@ select,
|
||||
--gradient-red: linear-gradient(150deg, rgba(255, 0, 0, 0.3), rgba(255, 200, 128, 0.05), rgba(255, 200, 128, 0.1), rgba(255, 10, 0, 0.3));
|
||||
--gradient-violet: linear-gradient(150deg, rgba(100, 45, 124, 0.6), rgba(216, 157, 192, 0.3), rgba(177, 157, 216, 0.5), rgba(107, 62, 121, 0.3), rgba(100, 45, 124, 0.6));
|
||||
--gradient-purple-black: linear-gradient(150deg, rgba(0, 0, 0, 0.7), rgba(100, 45, 124, 0.4), rgba(82, 17, 131, 0.3), rgba(100, 45, 124, 0.4), rgba(0, 0, 0, 0.7));
|
||||
--gradient-warning: linear-gradient(150deg, hsla(32, 100%, 50%, 0.3), hsla(52, 60%, 50%, 0.1), hsla(32, 60%, 50%, 0.1), hsla(32, 100%, 50%, 0.3));
|
||||
--gradient-silver-light: linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2));
|
||||
--gradient-daylight: conic-gradient(from 0deg, hsla(50, 100%, 80%, 0.7), hsla(30, 30%, 40%, 0.1) 25%, hsla(250, 50%, 40%, 0.1) 25%, hsla(250, 30%, 30%, 0.7) 50%, hsla(250, 50%, 40%, 0.1) 75%, hsla(30, 30%, 40%, 0.1) 75%, hsla(50, 100%, 80%, 0.7));
|
||||
--background-custom-button: linear-gradient(to bottom, hsla(208, 38%, 21%, 0.988) 5%, hsla(202, 42%, 14%, 0.671) 100%);
|
||||
@@ -159,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 {
|
||||
@@ -176,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;
|
||||
}
|
||||
@@ -206,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;
|
||||
@@ -250,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 {
|
||||
@@ -267,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;
|
||||
}
|
||||
@@ -297,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;
|
||||
@@ -341,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 {
|
||||
@@ -358,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;
|
||||
}
|
||||
@@ -388,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;
|
||||
@@ -528,6 +529,10 @@ select,
|
||||
flex-direction: row;
|
||||
margin: 0.1rem 0;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section subline .warning {
|
||||
border-radius: 0.5rem;
|
||||
background: var(--gradient-warning);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-img {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -555,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;
|
||||
@@ -571,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;
|
||||
@@ -627,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;
|
||||
@@ -655,7 +666,8 @@ select,
|
||||
width: 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat {
|
||||
font-family: CaslonAntique;
|
||||
display: grid;
|
||||
grid-template-areas: "img header buttons" "img resume buttons" "details details details" "actions actions actions";
|
||||
@@ -663,51 +675,61 @@ select,
|
||||
grid-template-rows: max-content max-content max-content max-content;
|
||||
gap: 0 0.5rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-img {
|
||||
grid-area: img;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img img {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img img,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-img img {
|
||||
border: 0;
|
||||
max-height: 3rem;
|
||||
max-width: 3rem;
|
||||
object-fit: contain;
|
||||
height: 100%;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-header {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-header,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-header {
|
||||
grid-area: header;
|
||||
font-weight: bold;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-resume {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-resume,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-resume {
|
||||
grid-area: resume;
|
||||
text-align: justify;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-details {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-details,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-details {
|
||||
grid-area: details;
|
||||
text-align: justify;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions {
|
||||
grid-area: actions;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions a {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a img {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a img,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions a img {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons {
|
||||
grid-area: buttons;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a {
|
||||
border-radius: 0.2rem;
|
||||
cursor: pointer;
|
||||
padding: 0.2rem;
|
||||
@@ -718,14 +740,17 @@ select,
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a img {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a img,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a img {
|
||||
max-width: 1rem;
|
||||
max-height: 1rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:hover {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:hover,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a:hover {
|
||||
background: var(--background-custom-button-hover);
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:active {
|
||||
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:active,
|
||||
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
@@ -1444,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);
|
||||
}
|
||||
@@ -1502,12 +1527,8 @@ select,
|
||||
font-size: 0.8rem;
|
||||
font-style: italic;
|
||||
color: rgba(82, 17, 131, 0.9);
|
||||
overflow: hidden;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .poesie-extrait:hover {
|
||||
max-height: unset;
|
||||
overflow: visible;
|
||||
opacity: 1;
|
||||
overflow-y: scroll;
|
||||
width: 100%;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .poesie-reference {
|
||||
font-size: 0.7rem;
|
||||
@@ -1573,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;
|
||||
@@ -1624,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;
|
||||
}
|
||||
@@ -1634,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;
|
||||
@@ -1754,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;
|
||||
@@ -1785,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;
|
||||
@@ -1954,13 +1975,13 @@ select,
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 4.6rem;
|
||||
left: -19rem;
|
||||
top: 10rem;
|
||||
left: -9rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .token-hud-ext.soins {
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 14.7rem;
|
||||
top: 15.5rem;
|
||||
left: -6rem;
|
||||
max-width: 8rem;
|
||||
line-height: 1rem;
|
||||
@@ -1975,14 +1996,18 @@ select,
|
||||
width: 9rem;
|
||||
height: fit-content;
|
||||
border-radius: 0.3rem;
|
||||
min-width: 6rem;
|
||||
min-width: 8rem;
|
||||
flex-basis: auto;
|
||||
padding: 0;
|
||||
line-height: 0.95rem;
|
||||
line-height: 1.6rem;
|
||||
margin: 0.2rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .rdd-hud-menu label {
|
||||
font-size: 0.8rem;
|
||||
.system-foundryvtt-reve-de-dragon div.control-icon.token-hud-icon select,
|
||||
.system-foundryvtt-reve-de-dragon div.control-icon.token-hud-icon label {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.system-foundryvtt-reve-de-dragon .item-checkbox {
|
||||
height: 25px;
|
||||
@@ -2094,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;
|
||||
}
|
||||
@@ -2314,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;
|
||||
@@ -2641,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 |
@@ -27,6 +27,11 @@
|
||||
--gradient-red: linear-gradient(150deg, rgba(255, 0, 0, 0.3), rgba(255, 200, 128, 0.05),rgba(255, 200, 128, 0.1), rgba(255,10,0,0.3));
|
||||
--gradient-violet: linear-gradient(150deg, rgba(100, 45, 124, 0.6), rgba(216, 157, 192, 0.3), rgba(177, 157, 216, 0.5), rgba(107, 62, 121, 0.3), rgba(100, 45, 124, 0.6));
|
||||
--gradient-purple-black: linear-gradient(150deg, rgba(0, 0, 0, 0.7), rgba(100, 45, 124, 0.4), rgba(82, 17, 131, 0.3),rgba(100, 45, 124, 0.4), rgba(0, 0, 0, 0.7));
|
||||
--gradient-warning: linear-gradient(150deg,
|
||||
hsla(32, 100%, 50%, 0.3),
|
||||
hsla(52, 60%, 50%, 0.1),
|
||||
hsla(32, 60%, 50%, 0.1),
|
||||
hsla(32, 100%, 50%, 0.3));
|
||||
--gradient-silver-light: linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2));
|
||||
--gradient-daylight: conic-gradient(
|
||||
from 0deg,
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
@@ -832,15 +832,10 @@
|
||||
font-size: 0.8rem;
|
||||
font-style: italic;
|
||||
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 {
|
||||
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;
|
||||
@@ -1319,13 +1314,13 @@
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 4.6rem;
|
||||
left: -19rem;
|
||||
top: 10rem;
|
||||
left: -9rem;
|
||||
}
|
||||
.token-hud-ext.soins {
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 14.7rem;
|
||||
top: 15.5rem;
|
||||
left: -6rem;
|
||||
max-width: 8rem;
|
||||
line-height: 1rem;
|
||||
@@ -1341,14 +1336,18 @@
|
||||
width: 9rem;
|
||||
height: fit-content;
|
||||
border-radius: 0.3rem;
|
||||
min-width: 6rem;
|
||||
min-width: 8rem;
|
||||
flex-basis: auto;
|
||||
padding: 0;
|
||||
line-height: 0.95rem;
|
||||
line-height: 1.6rem;
|
||||
margin: 0.2rem;
|
||||
}
|
||||
.rdd-hud-menu label {
|
||||
font-size: 0.8rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
select, label {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
/* ======================================== */
|
||||
.item-checkbox {
|
||||
@@ -1479,10 +1478,15 @@
|
||||
.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;
|
||||
}
|
||||
@@ -1681,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 {
|
||||
@@ -1917,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) {
|
||||
|
@@ -1,87 +1,86 @@
|
||||
.chat-message {
|
||||
div.roll-chat {
|
||||
font-family: CaslonAntique;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"img header buttons"
|
||||
"img resume buttons"
|
||||
"details details details"
|
||||
"actions actions actions";
|
||||
grid-template-columns: 3rem 1fr 1.4rem;
|
||||
grid-template-rows: max-content max-content max-content max-content;
|
||||
gap: 0 0.5rem;
|
||||
.chat-message div.roll-chat,
|
||||
.dialog-content div.roll-chat {
|
||||
font-family: CaslonAntique;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"img header buttons"
|
||||
"img resume buttons"
|
||||
"details details details"
|
||||
"actions actions actions";
|
||||
grid-template-columns: 3rem 1fr 1.4rem;
|
||||
grid-template-rows: max-content max-content max-content max-content;
|
||||
gap: 0 0.5rem;
|
||||
|
||||
div.chat-img {
|
||||
grid-area: img;
|
||||
div.chat-img {
|
||||
grid-area: img;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
img {
|
||||
border: 0;
|
||||
max-height: 3rem;
|
||||
max-width: 3rem;
|
||||
object-fit: contain;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
div.chat-header {
|
||||
grid-area: header;
|
||||
font-weight: bold;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
div.chat-resume {
|
||||
grid-area: resume;
|
||||
text-align: justify;
|
||||
}
|
||||
div.chat-details {
|
||||
grid-area: details;
|
||||
text-align: justify;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
div.chat-actions {
|
||||
grid-area: actions;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
img {
|
||||
border: 0;
|
||||
max-height: 3rem;
|
||||
max-width: 3rem;
|
||||
object-fit: contain;
|
||||
height: 100%;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
div.chat-header {
|
||||
grid-area: header;
|
||||
font-weight: bold;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
div.chat-resume {
|
||||
grid-area: resume;
|
||||
text-align: justify;
|
||||
}
|
||||
div.chat-details {
|
||||
grid-area: details;
|
||||
text-align: justify;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
div.chat-actions {
|
||||
grid-area: actions;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
a {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
img {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
div.chat-buttons {
|
||||
grid-area: buttons;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
a {
|
||||
border-radius: 0.2rem;
|
||||
cursor: pointer;
|
||||
padding: 0.2rem;
|
||||
position: relative;
|
||||
box-shadow: inset 1x 1px #a6827e;
|
||||
color: var(--color-controls);
|
||||
border: 1px ridge #846109;
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
max-width: 1rem;
|
||||
max-height: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
div.chat-buttons {
|
||||
grid-area: buttons;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
a {
|
||||
border-radius: 0.2rem;
|
||||
cursor: pointer;
|
||||
padding: 0.2rem;
|
||||
position: relative;
|
||||
box-shadow: inset 1x 1px #a6827e;
|
||||
color: var(--color-controls);
|
||||
border: 1px ridge #846109;
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
max-width: 1rem;
|
||||
max-height: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background: var(--background-custom-button-hover);
|
||||
}
|
||||
|
||||
a:active{
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background: var(--background-custom-button-hover);
|
||||
}
|
||||
|
||||
a:active{
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -89,8 +89,12 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 0.1rem 0;
|
||||
.warning {
|
||||
border-radius: 0.5rem;
|
||||
background: var(--gradient-warning);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
roll-part-img {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -117,6 +121,7 @@
|
||||
div.poesie-extrait{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: normal;
|
||||
}
|
||||
span.status-surprise{
|
||||
display: flex;
|
||||
@@ -137,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 {
|
||||
@@ -201,14 +211,14 @@
|
||||
}
|
||||
|
||||
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"] {
|
||||
max-width: 4rem;
|
||||
|
@@ -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"] {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { SYSTEM_RDD } from "../constants.js";
|
||||
import { renderTemplate, SYSTEM_RDD } from "../constants.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
|
||||
const DETAIL_VENTE = 'detailVente';
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "../constants.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
import { ChatVente } from "./chat-vente.js";
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "../constants.js";
|
||||
import { HtmlUtility } from "../html-utility.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
import { ChatVente } from "./chat-vente.js";
|
||||
|
@@ -3,7 +3,7 @@ import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDBonus } from "./rdd-bonus.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDCombatManager } from "./rdd-combat.js";
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
import { CARACS, RdDCarac } from "./rdd-carac.js";
|
||||
import { DialogSplitItem } from "./dialog-split-item.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||
@@ -174,7 +174,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
|
||||
await this.getBlessure(event)?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } })
|
||||
});
|
||||
|
||||
this.html.find('.roll-chance-actuelle').click(async event => await this.actor.rollCarac('chance-actuelle'))
|
||||
this.html.find('.roll-chance-actuelle').click(async event => await this.actor.rollCarac(CARACS.CHANCE_ACTUELLE))
|
||||
this.html.find('.button-appel-chance').click(async event => await this.actor.rollAppelChance())
|
||||
|
||||
this.html.find('[name="jet-astrologie"]').click(async event => await this.actor.astrologieNombresAstraux())
|
||||
@@ -208,7 +208,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
|
||||
}
|
||||
|
||||
// Points de reve actuel
|
||||
this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac('reve-actuel', { resistance: true }))
|
||||
this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac(CARACS.REVE_ACTUEL, { resistance: true }))
|
||||
this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor)))
|
||||
|
||||
this.html.find('.roll-arme').click(async event => {
|
||||
|
189
module/actor.js
@@ -17,9 +17,9 @@ import { Draconique } from "./tmr/draconique.js";
|
||||
import { CARACS, LIST_CARAC_PERSONNAGE, RdDCarac } from "./rdd-carac.js";
|
||||
import { DialogConsommer } from "./dialog-item-consommer.js";
|
||||
import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js";
|
||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||
import { RollDataAjustements } from "./rolldata-ajustements-v1.js";
|
||||
import { RdDPossession } from "./rdd-possession.js";
|
||||
import { ACTOR_TYPES, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { ACTOR_TYPES, renderTemplate, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { RdDConfirm } from "./rdd-confirm.js";
|
||||
import { DialogRepos } from "./sommeil/dialog-repos.js";
|
||||
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||
@@ -47,6 +47,11 @@ import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
import { RdDInitiative } from "./initiative.mjs";
|
||||
import RollDialog from "./roll/roll-dialog.mjs";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js";
|
||||
import { ROLL_TYPE_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']
|
||||
|
||||
@@ -98,6 +103,8 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
|
||||
isPersonnage() { return true }
|
||||
isFeminin() { return this.system.sexe.length > 0 && this.system.sexe.charAt(0).toLowerCase() == 'f' }
|
||||
|
||||
isHautRevant() { return this.system.attributs.hautrevant.value != "" }
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -136,12 +143,12 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
|
||||
listActions({ isAttaque = false, isEquipe = false }) {
|
||||
// Recupération des armes
|
||||
// Recupération des attaques
|
||||
const actions = this.listActionsAttaque()
|
||||
.filter(it => !isEquipe || it.arme.system.equipe)
|
||||
|
||||
if (!isAttaque && this.system.attributs.hautrevant.value) {
|
||||
actions.push({ name: "Draconic", action: 'haut-reve', initOnly: true })
|
||||
actions.push({ label: "Draconic", action: 'haut-reve', initOnly: true })
|
||||
}
|
||||
return actions
|
||||
}
|
||||
@@ -158,10 +165,10 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getDemiReve() { return this.system.reve.tmrpos.coord }
|
||||
getDraconicList() { 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)) }
|
||||
getDraconics() { return this.itemTypes[ITEM_TYPES.competence].filter(it => it.system.categorie == 'draconic') }
|
||||
getBestDraconic() { return foundry.utils.duplicate([...this.getDraconics(), PAS_DE_DRACONIC].sort(Misc.descending(it => it.system.niveau)).find(it => true)) }
|
||||
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))
|
||||
.find(it => true)
|
||||
}
|
||||
@@ -177,7 +184,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
const actions = []
|
||||
const uniques = []
|
||||
|
||||
const addAttaque = (arme, main) => {
|
||||
const addAttaque = (arme, main = undefined, action = 'attaque') => {
|
||||
const dommagesArme = RdDItemArme.valeurMain(arme.system.dommages, main)
|
||||
const forceRequise = RdDItemArme.valeurMain(arme.system.force ?? 0, main)
|
||||
const ecaillesEfficacite = arme.system.magique ? arme.system.ecaille_efficacite : 0;
|
||||
@@ -196,7 +203,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + ecaillesEfficacite
|
||||
|
||||
actions.push({
|
||||
name: arme.name + (main ? ' ' + main : ''),
|
||||
label: arme.name + (main ? ' ' + main : ''),
|
||||
action: 'attaque',
|
||||
initOnly: false,
|
||||
arme: arme,
|
||||
@@ -206,22 +213,23 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
equipe: arme.system.equipe,
|
||||
dommagesArme: dommagesArme,
|
||||
forceRequise: forceRequise,
|
||||
initiative: RdDInitiative.calculInitiative(niveau, caracValue, ajustement)
|
||||
initiative: RdDInitiative.getRollInitiative(caracValue, niveau, ajustement)
|
||||
})
|
||||
}
|
||||
|
||||
addAttaque(RdDItemArme.empoignade(this))
|
||||
addAttaque(RdDItemArme.corpsACorps(this))
|
||||
|
||||
this.itemTypes[ITEM_TYPES.arme]
|
||||
.filter(it => it.isAttaque())
|
||||
.sort(Misc.ascending(it => it.name))
|
||||
.forEach(arme => {
|
||||
if (arme.system.unemain && arme.system.competence) { addAttaque(arme, ATTAQUE_TYPE.UNE_MAIN) }
|
||||
if (arme.system.deuxmains && arme.system.competence) { addAttaque(arme, ATTAQUE_TYPE.DEUX_MAINS) }
|
||||
if (arme.system.lancer) { addAttaque(arme, ATTAQUE_TYPE.LANCER) }
|
||||
if (arme.system.unemain && arme.system.competence && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.UNE_MAIN) }
|
||||
if (arme.system.deuxmains && arme.system.competence && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.DEUX_MAINS) }
|
||||
if (arme.system.lancer && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.LANCER) }
|
||||
if (arme.system.tir) { addAttaque(arme, ATTAQUE_TYPE.TIR) }
|
||||
})
|
||||
|
||||
addAttaque(RdDItemArme.pugilat(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
||||
addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS, 'empoignade')
|
||||
|
||||
return actions
|
||||
}
|
||||
|
||||
@@ -697,11 +705,12 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async combattreReveDeDragon(force) {
|
||||
const rencontre = await game.system.rdd.rencontresTMR.getReveDeDragon(force);
|
||||
let rollData = {
|
||||
actor: this,
|
||||
competence: this.getDraconicOuPossession(),
|
||||
canClose: false,
|
||||
rencontre: await game.system.rdd.rencontresTMR.getReveDeDragon(force),
|
||||
rencontre: rencontre,
|
||||
tmr: true,
|
||||
use: { libre: false, conditions: false },
|
||||
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } }
|
||||
@@ -1342,7 +1351,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
async _apprecierCuisine(item, seForcer) {
|
||||
const surmonteExotisme = await this._surmonterExotisme(item, seForcer);
|
||||
if (surmonteExotisme) {
|
||||
await this.apprecier('gout', 'cuisine', item.system.qualite, item.system.boisson ? "apprécie la boisson" : "apprécie le plat");
|
||||
await this.apprecier(CARACS.ODORATGOUT, 'cuisine', item.system.qualite, item.system.boisson ? "apprécie la boisson" : "apprécie le plat");
|
||||
}
|
||||
else if (seForcer) {
|
||||
await this.jetDeMoral('malheureux');
|
||||
@@ -1360,7 +1369,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
if (exotisme < 0 || qualite < 0) {
|
||||
const competence = qualite > 0 ? 'cuisine' : undefined
|
||||
const difficulte = Math.min(exotisme, qualite)
|
||||
const rolled = await this.doRollCaracCompetence('volonte', competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
|
||||
const rolled = await this.doRollCaracCompetence(CARACS.VOLONTE, competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
|
||||
return rolled.isSuccess
|
||||
}
|
||||
return true;
|
||||
@@ -1682,7 +1691,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
computeDraconicAndSortIndex(sortList) {
|
||||
let draconicList = this.getDraconicList();
|
||||
let draconicList = this.getDraconics();
|
||||
for (let sort of sortList) {
|
||||
let draconicsSort = RdDItemSort.getDraconicsSort(draconicList, sort).map(it => it.name);
|
||||
for (let index = 0; index < draconicList.length && sort.system.listIndex == undefined; index++) {
|
||||
@@ -1922,6 +1931,21 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
|
||||
async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
|
||||
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: { allowed: [PART_COMP], current: PART_COMP },
|
||||
selected: {
|
||||
carac: { key: caracName },
|
||||
comp: { key: compName, forced: options.forced },
|
||||
diff: { value: diff ?? 0 }
|
||||
}
|
||||
}
|
||||
RollDialog.create(rollData, foundry.utils.mergeObject(options, { onRollDone: RollDialog.onRollDoneClose }))
|
||||
return
|
||||
}
|
||||
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
const competence = this.getCompetence(compName);
|
||||
await this.openRollDialog({
|
||||
@@ -1944,23 +1968,34 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollTache(id, options = {}) {
|
||||
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
const tacheData = this.getTache(id)
|
||||
const compData = this.getCompetence(tacheData.system.competence)
|
||||
compData.system.defaut_carac = tacheData.system.carac; // Patch !
|
||||
const tache = this.getTache(id)
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
selected: { tache: { key: tache.id, forced: options.forced } },
|
||||
type: { allowed: [PART_TACHE], current: PART_TACHE }
|
||||
}
|
||||
RollDialog.create(rollData, options)
|
||||
return
|
||||
}
|
||||
|
||||
const compData = this.getCompetence(tache.system.competence)
|
||||
compData.system.defaut_carac = tache.system.carac; // Patch !
|
||||
|
||||
await this.openRollDialog({
|
||||
name: 'jet-competence',
|
||||
label: 'Jet de Tâche ' + tacheData.name,
|
||||
label: 'Jet de Tâche ' + tache.name,
|
||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs',
|
||||
rollData: {
|
||||
competence: compData,
|
||||
tache: tacheData,
|
||||
diffLibre: tacheData.system.difficulte,
|
||||
tache: tache,
|
||||
diffLibre: tache.system.difficulte,
|
||||
diffConditions: 0,
|
||||
use: { libre: false, conditions: true },
|
||||
carac: {
|
||||
[tacheData.system.carac]: foundry.utils.duplicate(this.system.carac[tacheData.system.carac])
|
||||
[tache.system.carac]: foundry.utils.duplicate(this.system.carac[tache.system.carac])
|
||||
}
|
||||
},
|
||||
callbacks: [{ action: r => this._tacheResult(r, options) }]
|
||||
@@ -1994,9 +2029,19 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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 artData = {
|
||||
art: 'jeu', verbe: 'Jeu',
|
||||
@@ -2006,14 +2051,25 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
};
|
||||
listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]);
|
||||
artData.competence.system.niveauReel = artData.competence.system.niveau;
|
||||
artData.competence.system.niveau = Math.max(artData.competence.system.niveau, oeuvre.system.base);
|
||||
await this._rollArtV1(artData, carac, oeuvre);
|
||||
artData.competence.system.niveau = Math.max(artData.competence.system.niveau, jeu.system.base);
|
||||
await this._rollArtV1(artData, carac, jeu);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollMeditation(id) {
|
||||
const meditation = foundry.utils.duplicate(this.getMeditation(id));
|
||||
|
||||
if (meditation && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
selected: { meditation: { key: id } },
|
||||
type: { allowed: [ROLL_TYPE_MEDITATION], current: ROLL_TYPE_MEDITATION }
|
||||
}
|
||||
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
|
||||
return
|
||||
}
|
||||
|
||||
const competence = foundry.utils.duplicate(this.getCompetence(meditation.system.competence));
|
||||
competence.system.defaut_carac = "intellect"; // Meditation = toujours avec intellect
|
||||
let meditationData = {
|
||||
@@ -2072,7 +2128,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
ui.notifications.info(`Aucun signe draconiques en ${coord} !`);
|
||||
return;
|
||||
}
|
||||
let draconicList = this.getDraconicList()
|
||||
let draconicList = this.getDraconics()
|
||||
.map(draconic => {
|
||||
let draconicLecture = foundry.utils.duplicate(draconic);
|
||||
draconicLecture.system.defaut_carac = "intellect";
|
||||
@@ -2353,7 +2409,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
return
|
||||
}
|
||||
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
|
||||
}
|
||||
if (mode == 'visu') {
|
||||
@@ -2392,7 +2448,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
let tmrFormData = {
|
||||
mode: mode,
|
||||
fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance),
|
||||
draconic: this.getDraconicList(),
|
||||
draconic: this.getDraconics(),
|
||||
sort: this.itemTypes['sort'],
|
||||
signes: this.itemTypes['signedraconique'],
|
||||
caracReve: parseInt(this.system.carac.reve.value),
|
||||
@@ -2414,14 +2470,17 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
if (!blessure.system.premierssoins.done) {
|
||||
const tache = await this.getTacheBlessure(blesse, blessure);
|
||||
return await this.rollTache(tache.id, {
|
||||
onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r)
|
||||
onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r),
|
||||
title: 'Premiers soins',
|
||||
forced: true
|
||||
});
|
||||
}
|
||||
if (!blessure.system.soinscomplets.done) {
|
||||
else if (!blessure.system.soinscomplets.done) {
|
||||
const diff = blessure.system.difficulte + (blessure.system.premierssoins.bonus ?? 0);
|
||||
return await this.rollCaracCompetence("dexterite", "Chirurgie", diff, {
|
||||
return await this.rollCaracCompetence(CARACS.DEXTERITE, "Chirurgie", diff, {
|
||||
title: "Soins complets",
|
||||
onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r)
|
||||
onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r),
|
||||
forced: true
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2436,6 +2495,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
})
|
||||
}
|
||||
const blessure = this.getItem(blessureId, 'blessure')
|
||||
|
||||
if (blessure && !blessure.system.premierssoins.done) {
|
||||
const tache = rollData.tache;
|
||||
if (rollData.rolled.isETotal) {
|
||||
@@ -2916,7 +2976,9 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
break
|
||||
case ITEM_TYPES.race:
|
||||
await this.onCreateOwnedRace(item, options, id)
|
||||
break
|
||||
}
|
||||
await super.onCreateItem(item, options, id)
|
||||
await item.onCreateItemTemporel(this);
|
||||
await item.onCreateDecoupeComestible(this);
|
||||
}
|
||||
@@ -3050,24 +3112,11 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
async _rollArtV2(oeuvreId) {
|
||||
const oeuvre = this.items.get(oeuvreId)
|
||||
const rollData = {
|
||||
title: `Interpretation de ${oeuvre.name} par ${this.name}`,
|
||||
type: {
|
||||
allowed: ["oeuvre"],
|
||||
current: "oeuvre",
|
||||
},
|
||||
selected: {
|
||||
oeuvre: { key: oeuvre.id },
|
||||
},
|
||||
ids: {
|
||||
actorId: this.id
|
||||
}
|
||||
ids: { actorId: this.id },
|
||||
selected: { oeuvre: { key: oeuvre.id } },
|
||||
type: { allowed: [PART_OEUVRE], current: PART_OEUVRE, },
|
||||
}
|
||||
await RollDialog.create(rollData, {
|
||||
onRollDone: (dialog) => {
|
||||
if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
|
||||
dialog.close()
|
||||
}
|
||||
})
|
||||
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -3163,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));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -3203,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,
|
||||
@@ -3213,7 +3286,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
exotisme: item.system.exotisme,
|
||||
ingredients: item.name
|
||||
}
|
||||
};
|
||||
}
|
||||
const artData = {
|
||||
verbe: 'Préparer',
|
||||
compName: 'cuisine',
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
|
||||
import { ENTITE_INCARNE, renderTemplate, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDResolutionTable } from "../rdd-resolution-table.js";
|
||||
@@ -11,7 +11,7 @@ import { ITEM_TYPES } from "../constants.js";
|
||||
import { StatusEffects, STATUSES } from "../settings/status-effects.js";
|
||||
import { Targets } from "../targets.js";
|
||||
import { RdDConfirm } from "../rdd-confirm.js";
|
||||
import { RdDCarac } from "../rdd-carac.js";
|
||||
import { CARACS, RdDCarac } from "../rdd-carac.js";
|
||||
import { RdDRollResult } from "../rdd-roll-result.js";
|
||||
|
||||
import { RdDItemArme } from "../item/arme.js";
|
||||
@@ -23,8 +23,12 @@ import { RdDCombat } from "../rdd-combat.js";
|
||||
import { RdDEmpoignade } from "../rdd-empoignade.js";
|
||||
import { RdDPossession } from "../rdd-possession.js";
|
||||
import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, POSSESSION_SANS_DRACONIC } from "../item/base-items.js";
|
||||
import { RollDataAjustements } from "../rolldata-ajustements.js";
|
||||
import { RollDataAjustements } from "../rolldata-ajustements-v1.js";
|
||||
import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs";
|
||||
import RollDialog from "../roll/roll-dialog.mjs";
|
||||
import { ATTAQUE_ROLL_TYPES, DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP, ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE } from "../roll/roll-constants.mjs";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2 } from "../settings/options-avancees.js";
|
||||
import { PART_COMP } from "../roll/roll-part-comp.mjs";
|
||||
|
||||
/**
|
||||
* Classe de base pour les acteurs disposant de rêve (donc, pas des objets)
|
||||
@@ -377,9 +381,22 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async rollCarac(caracName, options = {}) {
|
||||
if (Grammar.equalsInsensitive(caracName, 'taille')) {
|
||||
if (Grammar.equalsInsensitive(caracName, CARACS.TAILLE)) {
|
||||
return
|
||||
}
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: { allowed: [PART_COMP], current: PART_COMP },
|
||||
selected: {
|
||||
carac: { key: caracName },
|
||||
comp: options.resistance ? { key: undefined, forced: true } : undefined
|
||||
}
|
||||
}
|
||||
RollDialog.create(rollData, options)
|
||||
return
|
||||
}
|
||||
|
||||
foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false })
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
let selectedCarac = this.getCaracByName(caracName)
|
||||
@@ -407,9 +424,33 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollCompetenceV2(rollData) {
|
||||
rollData.ids = rollData?.ids ?? {}
|
||||
rollData.type = rollData.type ?? { allowed: DEFAULT_ROLL_TYPES }
|
||||
rollData.ids.actorId = this.id
|
||||
await RollDialog.create(rollData)
|
||||
}
|
||||
|
||||
async rollCompetence(idOrName, options = { tryTarget: true, arme: undefined }) {
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
|
||||
const competence = this.getCompetence(idOrName);
|
||||
if (competence.type != ITEM_TYPES.competencecreature && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
selected: {
|
||||
comp: { key: competence.name },
|
||||
diff: { type: DIFF.LIBRE, value: competence.system.default_diffLibre ?? 0 }
|
||||
}
|
||||
}
|
||||
if (options.arme) {
|
||||
rollData.selected.attaque = { arme: { id: options.arme.id }, comp: { id: competence.id } }
|
||||
rollData.type = { allowed: ATTAQUE_ROLL_TYPES }
|
||||
}
|
||||
|
||||
await this.rollCompetenceV2(rollData)
|
||||
return
|
||||
}
|
||||
|
||||
let rollData = {
|
||||
carac: this.system.carac,
|
||||
competence: competence,
|
||||
@@ -427,7 +468,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme)
|
||||
}
|
||||
});
|
||||
return;
|
||||
return
|
||||
}
|
||||
// Transformer la competence de créature
|
||||
MappingCreatureArme.setRollDataCreature(rollData)
|
||||
@@ -449,6 +490,46 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
}
|
||||
}
|
||||
|
||||
rollAttaque(token) {
|
||||
token = token ?? RdDUtility.getSelectedToken(this)
|
||||
|
||||
if (Targets.hasTargets()) {
|
||||
Targets.selectOneTargetToken(target => {
|
||||
if (Targets.isTargetEntite(target)) {
|
||||
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée!!!!`)
|
||||
return
|
||||
}
|
||||
|
||||
RdDCombat.rddCombatTarget(target, this, token).attaqueV2();
|
||||
})
|
||||
}
|
||||
else {
|
||||
return RdDConfirm.confirmer({
|
||||
settingConfirmer: "confirmer-combat-sans-cible",
|
||||
content: `<p>Voulez vous faire une attaque sans choisir de cible valide?
|
||||
<br>Tous les jets de combats devront être gérés à la main
|
||||
</p>`,
|
||||
title: 'Ne pas utiliser les automatisation de combat',
|
||||
buttonLabel: "Pas d'automatisation",
|
||||
onAction: async () => {
|
||||
this.rollCompetenceV2({
|
||||
ids: {
|
||||
actorId: this.id,
|
||||
actorTokenId: token?.id,
|
||||
},
|
||||
selected: {
|
||||
conditions: { value: 0 }
|
||||
},
|
||||
type: {
|
||||
allowed: [ROLL_TYPE_COMP, ROLL_TYPE_ATTAQUE, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE, ROLL_TYPE_JEU],
|
||||
current: ROLL_TYPE_COMP
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/** --------------------------------------------
|
||||
* @param {*} arme item d'arme/compétence de créature
|
||||
* @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession
|
||||
|
@@ -34,17 +34,17 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||
|
||||
getFatigueActuelle() {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
return Math.max(0, Math.min(this.getFatigueMax(), Misc.toInt(this.system.sante.fatigue?.value)))
|
||||
return Math.max(0, Math.min(this.getFatigueMax(), Misc.toInt(this.system.sante.fatigue?.value)))
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
isCumulFatigueCauseSommeil(cumulFatigue){
|
||||
isCumulFatigueCauseSommeil(cumulFatigue) {
|
||||
return ReglesOptionnelles.isUsing("appliquer-fatigue")
|
||||
? (this.getFatigueRestante() <= cumulFatigue)
|
||||
: (this.getEnduranceActuelle() <= cumulFatigue)
|
||||
? (this.getFatigueRestante() <= cumulFatigue)
|
||||
: (this.getEnduranceActuelle() <= cumulFatigue)
|
||||
}
|
||||
getFatigueRestante() {return this.getFatigueMax() - this.getFatigueActuelle() }
|
||||
getFatigueRestante() { return this.getFatigueMax() - this.getFatigueActuelle() }
|
||||
getFatigueMin() { return this.system.sante.endurance.max - this.system.sante.endurance.value }
|
||||
|
||||
malusFatigue() {
|
||||
@@ -161,7 +161,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) {
|
||||
sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this.getFatigueMin());
|
||||
}
|
||||
await this.update({ "system.sante": sante })
|
||||
await this.update({ "system.sante": sante }, { render: true })
|
||||
if (this.isDead()) {
|
||||
await this.setEffect(STATUSES.StatusComma, true);
|
||||
}
|
||||
@@ -195,7 +195,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||
const endActuelle = this.getEnduranceActuelle();
|
||||
const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken);
|
||||
if (blessure.isCritique()) {
|
||||
encaissement.endurance = endActuelle;
|
||||
encaissement.endurance = endActuelle
|
||||
}
|
||||
|
||||
if (blessure.isMort()) {
|
||||
|
@@ -56,10 +56,8 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires);
|
||||
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
|
||||
formData.competences.filter(it => it.type == ITEM_TYPES.competencecreature)
|
||||
.forEach(it => {
|
||||
const competenceCreature = new RdDItemCompetenceCreature(it.toObject(), { parent: it.parent });
|
||||
it.isdommages = competenceCreature.isDommages();
|
||||
})
|
||||
.forEach(it => it.isdommages = it.isDommages()
|
||||
)
|
||||
|
||||
return formData;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { ChatVente } from "../achat-vente/chat-vente.js";
|
||||
import { ChatUtility } from "../chat-utility.js";
|
||||
import { SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { renderTemplate, SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { Monnaie } from "../item-monnaie.js";
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
@@ -10,6 +10,7 @@ import { RdDConfirm } from "../rdd-confirm.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
||||
import { RdDItem } from "../item.js";
|
||||
import { STATUSES } from "../settings/status-effects.js";
|
||||
|
||||
export class RdDBaseActor extends Actor {
|
||||
|
||||
@@ -45,8 +46,10 @@ export class RdDBaseActor extends Actor {
|
||||
}
|
||||
|
||||
static init() {
|
||||
Handlebars.registerHelper('actor-isFeminin', actor => actor.isFeminin())
|
||||
Hooks.on("preUpdateItem", (item, change, options, id) => Misc.documentIfResponsible(item.parent)?.onPreUpdateItem(item, change, options, id))
|
||||
Hooks.on("createItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onCreateItem(item, options, id))
|
||||
Hooks.on("updateItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onUpdateItem(item, options, id))
|
||||
Hooks.on("deleteItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onDeleteItem(item, options, id))
|
||||
Hooks.on("updateActor", (actor, change, options, actorId) => Misc.documentIfResponsible(actor)?.onUpdateActor(change, options, actorId))
|
||||
}
|
||||
@@ -218,6 +221,7 @@ export class RdDBaseActor extends Actor {
|
||||
isHautRevant() { return false }
|
||||
isVehicule() { return false }
|
||||
isPersonnage() { return false }
|
||||
isFeminin() { return false }
|
||||
getItem(id, type = undefined) {
|
||||
const item = this.items.get(id);
|
||||
if (type == undefined || (item?.type == type)) {
|
||||
@@ -243,7 +247,28 @@ export class RdDBaseActor extends Actor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async onPreUpdateItem(item, change, options, id) { }
|
||||
async onCreateItem(item, options, id) { }
|
||||
|
||||
async onCreateItem(item, options, id) {
|
||||
switch (item.type) {
|
||||
case ITEM_TYPES.blessure:
|
||||
await this.changeBleedingState()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
async onUpdateItem(item, options, id) {
|
||||
switch (item.type) {
|
||||
case ITEM_TYPES.blessure:
|
||||
await this.changeBleedingState()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
async changeBleedingState() {
|
||||
const bleeding = this.itemTypes[ITEM_TYPES.blessure].find(it => it.isBleeding())
|
||||
await this.setEffect(STATUSES.StatusBleeding, bleeding ? true : false)
|
||||
}
|
||||
|
||||
async onUpdateActor(update, options, actorId) { }
|
||||
async onDeleteItem(item, options, id) {
|
||||
if (item.isInventaire()) {
|
||||
@@ -738,7 +763,7 @@ export class RdDBaseActor extends Actor {
|
||||
name: this.getAlias(),
|
||||
system: { description: this.system.description }
|
||||
}
|
||||
foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.hbs', chatData)
|
||||
renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.hbs', chatData)
|
||||
.then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride)));
|
||||
}
|
||||
|
||||
@@ -769,11 +794,15 @@ export class RdDBaseActor extends Actor {
|
||||
return this.itemTypes[ITEM_TYPES.possession]
|
||||
.map(p => {
|
||||
return {
|
||||
name: p.name,
|
||||
label: p.name,
|
||||
action: 'possession',
|
||||
possessionid: p.system.possessionid,
|
||||
}
|
||||
})
|
||||
}
|
||||
listActionsCombat() {
|
||||
const possessions = this.listActionsPossessions()
|
||||
return possessions.length > 0 ? possessions : this.listActions({})
|
||||
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
import { Grammar } from "../../grammar.js"
|
||||
import { RdDItemArme } from "../../item/arme.js"
|
||||
import { EMPOIGNADE, RdDItemArme } from "../../item/arme.js"
|
||||
import { RdDItemCompetence } from "../../item-competence.js"
|
||||
import { RdDItemSort } from "../../item-sort.js"
|
||||
import { ITEM_TYPES } from "../../constants.js"
|
||||
@@ -141,7 +141,7 @@ export class Mapping {
|
||||
|
||||
static prepareArmes(actor) {
|
||||
const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme)
|
||||
armes.push(RdDItemArme.corpsACorps(actor));
|
||||
armes.push(RdDItemArme.pugilat(actor));
|
||||
armes.push(RdDItemArme.empoignade(actor));
|
||||
return armes.map(arme => [
|
||||
arme.system.unemain ? Mapping.prepareArme(actor, arme, '(1 main)') : undefined,
|
||||
@@ -175,7 +175,7 @@ export class Mapping {
|
||||
const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme))
|
||||
switch (arme.system.mortalite) {
|
||||
case 'non-mortel': return `(${dommages})`
|
||||
case 'empoignade': return '-'
|
||||
case EMPOIGNADE: return '-'
|
||||
}
|
||||
return dommages
|
||||
}
|
||||
@@ -274,11 +274,10 @@ export class Mapping {
|
||||
}
|
||||
|
||||
static getDescription(actor) {
|
||||
const sexe = actor.system.sexe
|
||||
const sexeFeminin = sexe.length > 0 && sexe.charAt(0).toLowerCase() == 'f' ? 'Née' : 'Né'
|
||||
const naissance = actor.isFeminin() ? 'née' : 'né'
|
||||
const race = ['', 'humain'].includes(Grammar.toLowerCaseNoAccent(actor.system.race)) ? '' : (actor.system.race + ' ')
|
||||
const heure = actor.system.heure
|
||||
const hn = `${sexeFeminin} à l'heure ${RdDTimestamp.definition(heure).avecArticle}`
|
||||
const hn = `${naissance} à l'heure ${RdDTimestamp.definition(heure).avecArticle}`
|
||||
const age = (actor.system.age && actor.system.age >0) ? `${actor.system.age} ans` : undefined
|
||||
const taille = actor.system.taille
|
||||
const poids = actor.system.poids
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "../../constants.js";
|
||||
|
||||
export class TextRollManager {
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { Misc } from "./misc.js";
|
||||
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js";
|
||||
|
||||
@@ -190,8 +190,8 @@ export class ChatUtility {
|
||||
if (rddTimestamp) {
|
||||
const timestamp = new RdDTimestamp(rddTimestamp);
|
||||
const timestampData = timestamp.toCalendrier();
|
||||
const dateHeure = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData);
|
||||
$(html).find('header.message-header .message-sender').after(dateHeure)
|
||||
const dateHeure = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData);
|
||||
$(html).find('header.message-header .message-timestamp').after(dateHeure)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { RdDBaseActor } from "../actor/base-actor.js";
|
||||
import { ChatUtility } from "../chat-utility.js";
|
||||
import { renderTemplate } from "../constants.js";
|
||||
|
||||
const INFO_COEUR = 'info-coeur';
|
||||
|
||||
|
@@ -9,17 +9,19 @@ export const ENTITE_INCARNE = 'incarne'
|
||||
export const ENTITE_NONINCARNE = 'nonincarne'
|
||||
export const ENTITE_BLURETTE = 'blurette'
|
||||
|
||||
export const renderTemplate = foundry.applications.handlebars.renderTemplate
|
||||
|
||||
export const RDD_CONFIG = {
|
||||
niveauEthylisme : [
|
||||
{value: "1", label: "Aucun"},
|
||||
{value: "0", label: "Eméché (0)"},
|
||||
{value: "-1", label: "Gris (-1)"},
|
||||
{value: "-2", label: "Pinté (-2)"},
|
||||
{value: "-3", label: "Pas Frais (-3)"},
|
||||
{value: "-4", label: "Ivre (-4)"},
|
||||
{value: "-5", label: "Bu (-5)"},
|
||||
{value: "-6", label: "Complètement fait (-6)"},
|
||||
{value: "-7", label: "Ivre mort (-7)"}
|
||||
niveauEthylisme: [
|
||||
{ value: "1", label: "Aucun" },
|
||||
{ value: "0", label: "Eméché (0)" },
|
||||
{ value: "-1", label: "Gris (-1)" },
|
||||
{ value: "-2", label: "Pinté (-2)" },
|
||||
{ value: "-3", label: "Pas Frais (-3)" },
|
||||
{ value: "-4", label: "Ivre (-4)" },
|
||||
{ value: "-5", label: "Bu (-5)" },
|
||||
{ value: "-6", label: "Complètement fait (-6)" },
|
||||
{ value: "-7", label: "Ivre mort (-7)" }
|
||||
],
|
||||
categorieEntite: {
|
||||
"cauchemar": "Cauchemar",
|
||||
@@ -30,28 +32,34 @@ export const RDD_CONFIG = {
|
||||
"nonincarne": "Non Incarnée",
|
||||
"blurette": "Blurette"
|
||||
},
|
||||
heuresRdD : [
|
||||
{value : "vaisseau", label: "Vaisseau", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd01.webp"},
|
||||
{value : "sirene", label: "Sirène", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd02.webp"},
|
||||
{value : "faucon", label: "Faucon", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd03.webp"},
|
||||
{value : "couronne", label: "Couronne", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd04.webp"},
|
||||
{value : "dragon", label: "Dragon", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd05.webp"},
|
||||
{value : "epees", label: "Epées", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd06.webp"},
|
||||
{value : "lyre", label: "Lyre", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd07.webp"},
|
||||
{value : "serpent", label: "Serpent", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd08.webp"},
|
||||
{value : "poissonacrobate", label: "Poisson Acrobate", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd09.webp"},
|
||||
{value : "araignee", label: "Araignée", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd10.webp"},
|
||||
{value : "roseau", label: "Roseau", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd11.webp"},
|
||||
{value : "chateaudormant", label: "Chateau Dormant", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd12.webp"}
|
||||
heuresRdD: [
|
||||
{ value: "vaisseau", label: "Vaisseau", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd01.webp" },
|
||||
{ value: "sirene", label: "Sirène", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd02.webp" },
|
||||
{ value: "faucon", label: "Faucon", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd03.webp" },
|
||||
{ value: "couronne", label: "Couronne", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd04.webp" },
|
||||
{ value: "dragon", label: "Dragon", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd05.webp" },
|
||||
{ value: "epees", label: "Epées", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd06.webp" },
|
||||
{ value: "lyre", label: "Lyre", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd07.webp" },
|
||||
{ value: "serpent", label: "Serpent", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd08.webp" },
|
||||
{ value: "poissonacrobate", label: "Poisson Acrobate", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd09.webp" },
|
||||
{ value: "araignee", label: "Araignée", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd10.webp" },
|
||||
{ value: "roseau", label: "Roseau", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd11.webp" },
|
||||
{ value: "chateaudormant", label: "Chateau Dormant", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd12.webp" }
|
||||
],
|
||||
raretes: [
|
||||
{value: "Commune", label: "Commune"},
|
||||
{value: "Frequente", label: "Fréquente"},
|
||||
{value: "Rare", label: "Rare"},
|
||||
{value: "Rarissime", label: "Rarissime"}
|
||||
]
|
||||
{ value: "Commune", label: "Commune" },
|
||||
{ value: "Frequente", label: "Fréquente" },
|
||||
{ value: "Rare", label: "Rare" },
|
||||
{ value: "Rarissime", label: "Rarissime" }
|
||||
],
|
||||
particuliere: {
|
||||
force: { key: 'force', descr: 'en force', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-force.svg'},
|
||||
finesse: { key: 'finesse', descr: 'en finesse', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-finesse.svg'},
|
||||
rapidite: { key: 'finesse', descr: 'en rapidité', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-rapidite.svg'},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const ACTOR_TYPES = {
|
||||
personnage: 'personnage',
|
||||
creature: 'creature',
|
||||
@@ -107,13 +115,3 @@ export const ITEM_TYPES = {
|
||||
extraitpoetique: 'extraitpoetique',
|
||||
}
|
||||
|
||||
export const CATEGORIES_COMPETENCES = {
|
||||
"generale": { base: -4, label: "Générales" },
|
||||
"particuliere": { base: -8, label: "Particulières" },
|
||||
"specialisee": { base: -11, label: "Spécialisées" },
|
||||
"connaissance": { base: -11, label: "Connaissances" },
|
||||
"draconic": { base: -11, label: "Draconic" },
|
||||
"melee": { base: -6, label: "Mêlée" },
|
||||
"tir": { base: -8, label: "Tir" },
|
||||
"lancer": { base: -8, label: "Lancer" }
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js"
|
||||
|
||||
export class DialogChoixXpCarac extends Dialog {
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { SYSTEM_RDD } from "./constants.js";
|
||||
import { renderTemplate, SYSTEM_RDD } from "./constants.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDItemSigneDraconique } from "./item/signedraconique.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
export class DialogConsommer extends Dialog {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js"
|
||||
|
||||
export class DialogSelect extends Dialog {
|
||||
static extractIdNameImg(it) { return { id: it.id, name: it.name, img: it.img } }
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Misc } from "./misc.js";
|
||||
import { renderTemplate } from "./constants.js";
|
||||
|
||||
export class DialogSplitItem extends Dialog {
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { HIDE_DICE, SHOW_DICE } from "./constants.js";
|
||||
import { HIDE_DICE, renderTemplate, SHOW_DICE } from "./constants.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
|
||||
/**
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { ITEM_TYPES } from "../constants.js"
|
||||
import { ITEM_TYPES, renderTemplate } from "../constants.js"
|
||||
import { RdDItemSort } from "../item-sort.js"
|
||||
import { Misc } from "../misc.js"
|
||||
|
||||
|
@@ -1,7 +1,65 @@
|
||||
export const MAP_PHASE = {
|
||||
possession: { label: "possession", rang: 10 },
|
||||
draconic: { label: "draconic", rang: 9 },
|
||||
tir: { label: "tir", rang: 8 },
|
||||
lancer: { label: "lancer", rang: 7 },
|
||||
arme: { label: "mêlée", rang: 5 },
|
||||
pugilat: { label: "pugilat", rang: 4 },
|
||||
naturelle: { label: "créature", rang: 4 },
|
||||
empoignade: { label: "empoignade", rang: 3 },
|
||||
autre: { label: "autre action", rang: 2 },
|
||||
demi: { label: "demi-surprise", rang: 0 },
|
||||
totale: { label: "surprise totale", rang: -1 },
|
||||
}
|
||||
export const PHASE = Object.values(MAP_PHASE)
|
||||
|
||||
export class RdDInitiative {
|
||||
|
||||
static calculInitiative(niveau, caracValue, bonus = 0) {
|
||||
let base = niveau + Math.floor(caracValue / 2) + bonus;
|
||||
return "1d6" + (base >= 0 ? "+" : "") + base;
|
||||
static getRollInitiative(caracValue, niveau, bonus = 0) {
|
||||
const base = RdDInitiative.ajustementInitiative(caracValue, niveau, bonus)
|
||||
return "1d6" + (base >= 0 ? "+" : "") + base
|
||||
}
|
||||
|
||||
static ajustementInitiative(caracValue, niveau, bonus) {
|
||||
return niveau + Math.floor(caracValue / 2) + bonus
|
||||
}
|
||||
|
||||
static formule(phase, carac, niveau, bonusMalus) {
|
||||
const ajustement = RdDInitiative.ajustementInitiative(carac, niveau, bonusMalus)
|
||||
return { phase, ajustement }
|
||||
}
|
||||
|
||||
static phaseArme(categorie, arme) {
|
||||
switch (categorie) {
|
||||
case "tir":
|
||||
case "lancer":
|
||||
return MAP_PHASE[categorie]
|
||||
default:
|
||||
switch (arme.system.cac) {
|
||||
case "empoignade":
|
||||
case "pugilat":
|
||||
case "naturelle":
|
||||
return MAP_PHASE[arme.system.cac]
|
||||
default:
|
||||
return MAP_PHASE['arme']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static phase(keyOrRang) {
|
||||
return MAP_PHASE[keyOrRang] ?? PHASE.find(it => it.rang == keyOrRang) ?? MAP_PHASE.autre
|
||||
}
|
||||
|
||||
static async roll(formule) {
|
||||
const sign = formule.ajustement >= 0 ? "+" : ""
|
||||
const roll = new Roll(`1d6 + ${sign} + ${formule.ajustement}`)
|
||||
await roll.evaluate()
|
||||
const value = Math.max(roll.total, 0)
|
||||
return {
|
||||
roll: roll,
|
||||
value: value,
|
||||
init: formule.phase.rang + value / 100,
|
||||
label: formule.phase.label
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,15 +10,15 @@ export class RdDItemCompetenceCreature extends RdDItem {
|
||||
|
||||
static get defaultIcon() { return "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp" }
|
||||
|
||||
isAttaque() { return this.getCategorieAttaque() != undefined }
|
||||
isParade() { return this.system.iscombat && (this.system.categorie_parade ?? '') != '' }
|
||||
isBouclier() { return this.system.categorie_parade.includes('bouclier') }
|
||||
|
||||
attaqueCreature() {
|
||||
const categorieAttaque = this.getCategorieAttaque()
|
||||
if (categorieAttaque != undefined) {
|
||||
const initative = RdDInitiative.calculInitiative(this.system.niveau, this.system.carac_value);
|
||||
const initative = RdDInitiative.getRollInitiative(this.system.carac_value, this.system.niveau);
|
||||
const attaque = {
|
||||
name: this.name,
|
||||
label: this.name,
|
||||
action: this.isCompetencePossession() ? 'possession' : 'attaque',
|
||||
initOnly: false,
|
||||
arme: new RdDItemArme({
|
||||
@@ -51,10 +51,6 @@ export class RdDItemCompetenceCreature extends RdDItem {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
isAttaque() {
|
||||
return this.getCategorieAttaque() != undefined
|
||||
}
|
||||
|
||||
getCategorieAttaque() {
|
||||
switch (this.system.categorie) {
|
||||
case "melee":
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { ITEM_TYPES } from "./constants.js";
|
||||
import { ITEM_TYPES, renderTemplate } from "./constants.js";
|
||||
import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES, CATEGORIES_COMPETENCES_CREATURES } from "./item/base-items.js";
|
||||
import { ITEM_ACTIONS, DEFAULT_ACTIONS, COMMON_ACTIONS } from "./item/item-actions.js";
|
||||
|
||||
|
@@ -4,6 +4,7 @@ import { BASE_CORPS_A_CORPS } from "./base-items.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { RdDInitiative } from "../initiative.mjs";
|
||||
import { MappingCreatureArme } from "./mapping-creature-arme.mjs";
|
||||
import { Misc } from "../misc.js";
|
||||
|
||||
const nomCategorieParade = {
|
||||
"sans-armes": "Sans arme",
|
||||
@@ -21,11 +22,16 @@ const nomCategorieParade = {
|
||||
export const ATTAQUE_TYPE = {
|
||||
UNE_MAIN: '(1 main)',
|
||||
DEUX_MAINS: '(2 mains)',
|
||||
CORPS_A_CORPS: '(corps à corps)',
|
||||
COMPETENCE: 'competence',
|
||||
TIR: '(tir)',
|
||||
LANCER: '(lancer)'
|
||||
}
|
||||
|
||||
export const CORPS_A_CORPS = 'Corps à corps'
|
||||
export const PUGILAT = 'pugilat'
|
||||
export const EMPOIGNADE = 'empoignade'
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDItemArme extends RdDItem {
|
||||
|
||||
@@ -62,7 +68,7 @@ export class RdDItemArme extends RdDItem {
|
||||
case ITEM_TYPES.competencecreature:
|
||||
return MappingCreatureArme.armeCreature(arme);
|
||||
}
|
||||
return RdDItemArme.corpsACorps();
|
||||
return RdDItemArme.pugilat();
|
||||
}
|
||||
|
||||
static getCompetenceArme(arme, maniement) {
|
||||
@@ -76,6 +82,7 @@ export class RdDItemArme extends RdDItem {
|
||||
case ATTAQUE_TYPE.DEUX_MAINS: return arme.competence2Mains()
|
||||
case ATTAQUE_TYPE.TIR: case 'tir': return arme.system.tir
|
||||
case ATTAQUE_TYPE.LANCER: case 'lancer': return arme.system.lancer;
|
||||
case ATTAQUE_TYPE.CORPS_A_CORPS: return CORPS_A_CORPS
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
@@ -244,47 +251,41 @@ export class RdDItemArme extends RdDItem {
|
||||
}
|
||||
|
||||
isAttaque() {
|
||||
return this.system.resistance > 0 || this.system.portee_courte > 0
|
||||
return this.system.resistance > 0 || (this.system.tir != '' && this.system.portee_courte > 0)
|
||||
}
|
||||
|
||||
static corpsACorps(actor) {
|
||||
let competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS
|
||||
let melee = actor ? actor.system.carac['melee'].value : 0
|
||||
static pugilat(actor) {
|
||||
return RdDItemArme.$corpsACorps(actor, 'Pugilat', PUGILAT)
|
||||
}
|
||||
|
||||
static empoignade(actor) {
|
||||
return RdDItemArme.$corpsACorps(actor, 'Empoignade', EMPOIGNADE)
|
||||
}
|
||||
|
||||
static $corpsACorps(actor, name, cac, system) {
|
||||
const competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS
|
||||
const melee = actor ? actor.system.carac['melee'].value : 0
|
||||
return new RdDItemArme({
|
||||
_id: competence.id,
|
||||
name: 'Corps à corps',
|
||||
_id: Misc.fakeId(cac),
|
||||
name: name,
|
||||
type: ITEM_TYPES.arme,
|
||||
img: competence.img,
|
||||
system: {
|
||||
initiative: RdDInitiative.calculInitiative(competence.system.niveau, melee),
|
||||
initiative: RdDInitiative.getRollInitiative(melee, competence.system.niveau),
|
||||
equipe: true,
|
||||
rapide: true,
|
||||
force: 0,
|
||||
dommages: "0",
|
||||
dommagesReels: 0,
|
||||
mortalite: 'non-mortel',
|
||||
competence: 'Corps à corps',
|
||||
mortalite: cac == EMPOIGNADE ? EMPOIGNADE : 'non-mortel',
|
||||
competence: CORPS_A_CORPS,
|
||||
resistance: 1,
|
||||
baseInit: 4,
|
||||
cac: 'pugilat',
|
||||
baseInit: cac == EMPOIGNADE ? 3 : 4,
|
||||
cac: cac,
|
||||
deuxmains: true,
|
||||
categorie_parade: 'sans-armes'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static mainsNues(actor) {
|
||||
const mainsNues = RdDItemArme.corpsACorps(actor)
|
||||
mainsNues.name = 'Mains nues'
|
||||
return mainsNues;
|
||||
}
|
||||
|
||||
static empoignade(actor) {
|
||||
const empoignade = RdDItemArme.corpsACorps(actor)
|
||||
empoignade.name = 'Empoignade'
|
||||
empoignade.system.cac = 'empoignade'
|
||||
empoignade.system.baseInit = 3
|
||||
empoignade.system.mortalite = 'empoignade'
|
||||
return empoignade
|
||||
}
|
||||
}
|
||||
|
@@ -209,6 +209,9 @@ export class RdDItemBlessure extends RdDItem {
|
||||
isCritique() {
|
||||
return this.system.gravite > 4 && this.system.gravite <= 6
|
||||
}
|
||||
isBleeding() {
|
||||
return this.system.gravite > 2 && !this.system.premierssoins.done
|
||||
}
|
||||
isMort() {
|
||||
return this.system.gravite > 6
|
||||
}
|
||||
|
@@ -3,7 +3,6 @@ import { RdDInitiative } from "../initiative.mjs";
|
||||
|
||||
export class MappingCreatureArme {
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static setRollDataCreature(rollData) {
|
||||
const code = Grammar.toLowerCaseNoAccentNoSpace(rollData.competence.name);
|
||||
@@ -26,7 +25,7 @@ export class MappingCreatureArme {
|
||||
competence: item.name,
|
||||
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
|
||||
niveau: item.system.niveau,
|
||||
initiative: RdDInitiative.calculInitiative(item.system.niveau, item.system.carac_value),
|
||||
initiative: RdDInitiative.getRollInitiative(item.system.carac_value, item.system.niveau),
|
||||
equipe: true,
|
||||
resistance: 100,
|
||||
dommagesReels: item.system.dommages,
|
||||
|
@@ -6,8 +6,8 @@ const tableEffets = [
|
||||
{ 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: "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+xp", resultat: "succes", description: "Expérience sur réussite particulière", method: EffetsRencontre.experience_particuliere },
|
||||
{ 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 particulière", method: EffetsRencontre.experience_particuliere },
|
||||
{ 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 },
|
||||
@@ -19,7 +19,7 @@ const tableEffets = [
|
||||
{ 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: "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: "vie-f", resultat: "echec", description: "Perte de (force) points de vie", method: EffetsRencontre.vie_moins_force },
|
||||
|
@@ -34,9 +34,13 @@ export class Misc {
|
||||
return ((n % m) + m) % m;
|
||||
}
|
||||
|
||||
static inRange(value, min,max){
|
||||
static inRange(value, min, max) {
|
||||
if (min > max) {
|
||||
return Misc.inRange(value, max, min)
|
||||
}
|
||||
return Math.max(min, Math.min(value, max))
|
||||
}
|
||||
|
||||
static sum() {
|
||||
return (a, b) => Number(a) + Number(b);
|
||||
}
|
||||
@@ -61,6 +65,10 @@ export class Misc {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static fakeId(base) {
|
||||
return (base + foundry.utils.randomID(16)).substring(0, 16)
|
||||
}
|
||||
|
||||
static typeName(type, subType) {
|
||||
return subType ? game.i18n.localize(`TYPES.${type}.${subType}`)
|
||||
: '';
|
||||
@@ -111,6 +119,10 @@ export class Misc {
|
||||
list.forEach(it => addToObj(obj, it))
|
||||
return obj;
|
||||
}
|
||||
static indexed(list, index = 'index') {
|
||||
let i = 0;
|
||||
return list.map(it => { it[index] = i++; return it })
|
||||
}
|
||||
|
||||
static concat(lists) {
|
||||
return lists.reduce((a, b) => a.concat(b), []);
|
||||
|
@@ -55,21 +55,20 @@ export class RdDBonus {
|
||||
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante
|
||||
return dmg;
|
||||
}
|
||||
|
||||
static dmgRollV2(rollData, current) {
|
||||
|
||||
static dmgRollV2(rollData, attaque) {
|
||||
const actor = rollData.active.actor
|
||||
const attaque = current.attaque
|
||||
const arme = attaque.arme
|
||||
const dmgArme = RdDBonus.dmgArme(arme, attaque.dommagesArme)
|
||||
const dmg = {
|
||||
total: 0,
|
||||
dmgArme: dmgArme,
|
||||
penetration: arme.penetration(),
|
||||
penetration: arme?.penetration() ?? 0,
|
||||
diff: attaque.diff,
|
||||
dmgTactique: current.tactique?.dmg ?? 0,
|
||||
dmgParticuliere: 0, // TODO RdDBonus._dmgParticuliere(rollData),
|
||||
dmgTactique: attaque.tactique?.dmg ?? 0,
|
||||
dmgParticuliere: RdDBonus._dmgParticuliere(rollData),
|
||||
dmgSurprise: rollData.opponent?.surprise?.dmg ?? 0,
|
||||
mortalite: RdDBonus.mortalite(current.dmg?.mortalite, arme.system.mortalite, rollData.opponent?.actor?.isEntite()),
|
||||
mortalite: RdDBonus.mortalite(attaque.dmg?.mortalite, arme?.system.mortalite, rollData.opponent?.actor?.isEntite()),
|
||||
dmgActor: RdDBonus.bonusDmg(actor, attaque.carac.key, dmgArme, attaque.forceRequise),
|
||||
dmgForceInsuffisante: Math.min(0, actor.getForce() - attaque.forceRequise),
|
||||
dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { ENTITE_BLURETTE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { ENTITE_BLURETTE, HIDE_DICE, renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDBonus } from "./rdd-bonus.js";
|
||||
@@ -10,15 +10,16 @@ import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
import { Targets } from "./targets.js";
|
||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
import { RdDItemArme } from "./item/arme.js";
|
||||
import { EMPOIGNADE, RdDItemArme } from "./item/arme.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { RdDInitiative } from "./initiative.mjs";
|
||||
import { MAP_PHASE, RdDInitiative } from "./initiative.mjs";
|
||||
import RollDialog from "./roll/roll-dialog.mjs";
|
||||
import { PART_DEFENSE } from "./roll/roll-part-defense.mjs";
|
||||
import { RollDialogAdapter } from "./roll/roll-dialog-adapter.mjs";
|
||||
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js";
|
||||
import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs";
|
||||
import { RollBasicParts } from "./roll/roll-basic-parts.mjs";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const premierRoundInit = [
|
||||
@@ -67,7 +68,7 @@ export class RdDCombatManager extends Combat {
|
||||
if (Misc.isFirstConnectedGM()) {
|
||||
await this.finDeRound({ terminer: true })
|
||||
ChatUtility.removeChatMessageContaining(`<div data-combatid="${this.id}" data-combatmessage="actor-turn-summary">`)
|
||||
game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined)
|
||||
game.messages.filter(m => ChatUtility.getMessageData(m, 'rollData') != undefined && ChatUtility.getMessageData(m, 'rollData') != undefined)
|
||||
.forEach(it => it.delete())
|
||||
RdDEmpoignade.deleteAllEmpoignades()
|
||||
}
|
||||
@@ -106,14 +107,18 @@ export class RdDCombatManager extends Combat {
|
||||
return combatant.actor
|
||||
}
|
||||
|
||||
static calculAjustementInit(actor, arme) {
|
||||
const efficacite = (arme?.system.magique) ? arme.system.ecaille_efficacite : 0
|
||||
const etatGeneral = actor.getEtatGeneral() ?? 0
|
||||
return efficacite + etatGeneral
|
||||
|
||||
static bonusArme(arme) {
|
||||
return (arme?.system.magique) ? arme.system.ecaille_efficacite : 0
|
||||
}
|
||||
|
||||
/************************************************************************************/
|
||||
static etatGeneral(actor) {
|
||||
return actor.getEtatGeneral() ?? 0;
|
||||
}
|
||||
|
||||
|
||||
/** ***********************************************************************************
|
||||
* @override lance l'initiative de plusieurs combattants (tous/ous les PNJs) en une fois
|
||||
*/
|
||||
async rollInitiative(ids, messageOptions = {}) {
|
||||
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, messageOptions)
|
||||
ids = typeof ids === "string" ? [ids] : ids
|
||||
@@ -121,18 +126,17 @@ export class RdDCombatManager extends Combat {
|
||||
return this
|
||||
}
|
||||
|
||||
async rollInitRdD(id, formula, messageOptions = {}) {
|
||||
async rollInitRdD(id, formule, messageOptions = {}) {
|
||||
const combatant = this.combatants.get(id);
|
||||
const actor = RdDCombatManager.getActorCombatant(combatant)
|
||||
if (actor) {
|
||||
const rollFormula = formula ?? RdDCombatManager.getFirstInitRollFormula(actor)
|
||||
const roll = combatant.getInitiativeRoll(rollFormula);
|
||||
if (!roll.total) {
|
||||
await roll.evaluate();
|
||||
}
|
||||
const total = Math.max(roll.total, 0.00);
|
||||
console.log("Compute init for", rollFormula, roll, total, combatant);
|
||||
await this.updateEmbeddedDocuments("Combatant", [{ _id: combatant._id || combatant.id, initiative: total }]);
|
||||
formule = formule ?? RdDCombatManager.getFirstInitRollFormula(actor)
|
||||
const init = await RdDInitiative.roll(formule)
|
||||
|
||||
await this.updateEmbeddedDocuments("Combatant", [{
|
||||
_id: combatant._id || combatant.id,
|
||||
initiative: init.init, 'system.init': init
|
||||
}])
|
||||
|
||||
// Send a chat message
|
||||
let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode");
|
||||
@@ -144,10 +148,10 @@ export class RdDCombatManager extends Combat {
|
||||
alias: combatant.token?.name,
|
||||
sound: CONFIG.sounds.dice,
|
||||
},
|
||||
flavor: `${combatant.token?.name} a fait son jet d'Initiative (${messageOptions.info})<br>`
|
||||
flavor: `${combatant.token?.name} a une initiatyive de ${init.value} : ${messageOptions.info}<br>`
|
||||
},
|
||||
messageOptions);
|
||||
roll.toMessage(messageData, { rollMode, create: true });
|
||||
init.roll.toMessage(messageData, { rollMode, create: true });
|
||||
|
||||
RdDCombatManager.processPremierRoundInit();
|
||||
}
|
||||
@@ -159,16 +163,11 @@ export class RdDCombatManager extends Combat {
|
||||
if (actions.length > 0) {
|
||||
const action = actions[0]
|
||||
const init = RdDCombatManager.getInitData(actor, action)
|
||||
const ajustement = RdDCombatManager.calculAjustementInit(actor, action)
|
||||
return RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
|
||||
const ajustement = RdDCombatManager.bonusArme(action.arme) + RdDCombatManager.etatGeneral(actor)
|
||||
return RdDInitiative.formule(init.phase, init.carac, init.niveau, ajustement);
|
||||
}
|
||||
|
||||
let ajustement = RdDCombatManager.calculAjustementInit(actor, undefined);
|
||||
return RdDCombatManager.formuleInitiative(2, 10, 0, ajustement);
|
||||
}
|
||||
|
||||
static formuleInitiative(rang, carac, niveau, bonusMalus) {
|
||||
return `${rang} +( (${RdDInitiative.calculInitiative(niveau, carac, bonusMalus)} )/100)`;
|
||||
return RdDInitiative.formule(MAP_PHASE['autre'], 10, 0, actor.getEtatGeneral() ?? 0);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -180,7 +179,6 @@ export class RdDCombatManager extends Combat {
|
||||
for (let combatant of game.combat.combatants) {
|
||||
if (combatant.initiativeData?.arme?.type == "arme") {
|
||||
// TODO: get init data premier round
|
||||
const initiativeData = combatant.initiativeData;
|
||||
const action = combatant.initiativeData.arme;
|
||||
const fromArme = Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround)
|
||||
const initData = premierRoundInit.find(it => fromArme.includes(initData.pattern))
|
||||
@@ -200,10 +198,27 @@ export class RdDCombatManager extends Combat {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static incDecInit(combatantId, incDecValue) {
|
||||
const combatant = game.combat.combatants.get(combatantId);
|
||||
let initValue = combatant.initiative + incDecValue;
|
||||
game.combat.setInitiative(combatantId, initValue);
|
||||
|
||||
static applyInitiativeCommand(combatantId, command, commandValue) {
|
||||
switch (command) {
|
||||
case 'delta': return RdDCombatManager.incDecInit(combatantId, commandValue);
|
||||
case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
|
||||
{ name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
|
||||
}
|
||||
}
|
||||
|
||||
static async incDecInit(combatantId, incDecValue) {
|
||||
const combatant = game.combat.combatants.get(combatantId)
|
||||
if (combatant?.initiative && incDecValue != 0) {
|
||||
const value = combatant.system.init.value + incDecValue
|
||||
const newInit = combatant.initiative + incDecValue / 100;
|
||||
await game.combat.updateEmbeddedDocuments("Combatant", [{
|
||||
_id: combatantId,
|
||||
initiative: newInit,
|
||||
'system.init.value': value,
|
||||
'system.init.init': newInit,
|
||||
}])
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -220,56 +235,42 @@ export class RdDCombatManager extends Combat {
|
||||
}
|
||||
}
|
||||
options = [
|
||||
{ name: "Incrémenter initiative", condition: true, icon: '<i class="fa-solid fa-plus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +0.01); } },
|
||||
{ name: "Décrémenter initiative", condition: true, icon: '<i class="fa-solid fa-minus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -0.01); } }
|
||||
{ name: "Incrémenter initiative", condition: true, icon: '<i class="fa-solid fa-plus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +1); } },
|
||||
{ name: "Décrémenter initiative", condition: true, icon: '<i class="fa-solid fa-minus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -1); } }
|
||||
].concat(options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async rollInitiativeAction(combatantId, action) {
|
||||
const combatant = game.combat.combatants.get(combatantId)
|
||||
const actor = RdDCombatManager.getActorCombatant(combatant)
|
||||
if (actor == undefined) { return [] }
|
||||
|
||||
combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0
|
||||
if (actor == undefined) { return }
|
||||
|
||||
const init = RdDCombatManager.getInitData(actor, action)
|
||||
const ajustement = RdDCombatManager.calculAjustementInit(actor, action.arme)
|
||||
const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
|
||||
const ajustement = RdDCombatManager.bonusArme(actor, action.arme) + RdDCombatManager.etatGeneral(actor)
|
||||
const formule = RdDInitiative.formule(init.phase, init.carac, init.niveau, ajustement);
|
||||
|
||||
await game.combat.rollInitRdD(combatantId, rollFormula, init);
|
||||
combatant.initiativeData
|
||||
await game.combat.rollInitRdD(combatantId, formule, init);
|
||||
combatant.initiativeData = { action, formule } // pour reclasser l'init au round 0
|
||||
}
|
||||
|
||||
static getInitData(actor, action) {
|
||||
if (actor.getSurprise() == "totale") { return { offset: -1, info: "Surprise Totale", carac: 0, niveau: 0 } }
|
||||
if (actor.getSurprise() == "demi") { return { offset: 0, info: "Demi Surprise", carac: 0, niveau: 0 } }
|
||||
if (action.action == 'autre') { return { offset: 2, info: "Autre Action", carac: 0, niveau: 0 } }
|
||||
if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } }
|
||||
if (action.action == 'haut-reve') { return { offset: 9, info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } }
|
||||
if (actor.getSurprise() == "totale") { return { phase: MAP_PHASE['totale'], info: "Surprise Totale", carac: 0, niveau: 0 } }
|
||||
if (actor.getSurprise() == "demi") { return { phase: MAP_PHASE['demi'], info: "Demi Surprise", carac: 0, niveau: 0 } }
|
||||
if (action.action == 'autre') { return { phase: MAP_PHASE['autre'], info: "Autre Action", carac: 0, niveau: 0 } }
|
||||
if (action.action == 'possession') { return { phase: MAP_PHASE['possession'], info: "Possession", carac: actor.getReveActuel(), niveau: 0 } }
|
||||
if (action.action == 'haut-reve') { return { phase: MAP_PHASE['draconic'], info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } }
|
||||
|
||||
const comp = action.comp
|
||||
return {
|
||||
offset: RdDCombatManager.initOffset(comp?.system.categorie, action.arme),
|
||||
info: action.name + " / " + comp.name,
|
||||
phase: RdDInitiative.phaseArme(comp?.system.categorie, action.arme),
|
||||
info: action.label,
|
||||
carac: actor.getCaracInit(comp),
|
||||
niveau: comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(action.main) ? -8 : -6)
|
||||
}
|
||||
}
|
||||
|
||||
static initOffset(categorie, arme) {
|
||||
switch (categorie) {
|
||||
case "tir": return 8
|
||||
case "lancer": return 7
|
||||
default:
|
||||
switch (arme.system.cac) {
|
||||
case "empoignade": return 3
|
||||
case "pugilat": return 4
|
||||
case "naturelle": return 4
|
||||
default: return 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static displayInitiativeMenu(html, combatantId) {
|
||||
const combatant = game.combat.combatants.get(combatantId)
|
||||
@@ -297,13 +298,8 @@ export class RdDCombatManager extends Combat {
|
||||
? possessions
|
||||
: actor.listActions({ isEquipe: true })
|
||||
|
||||
for (let index = 0; index < actions.length; index++) {
|
||||
actions[index].index = index
|
||||
}
|
||||
return actions
|
||||
return Misc.indexed(actions)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -383,8 +379,13 @@ export class RdDCombat {
|
||||
let defenderToken = canvas.tokens.get(msg.defenderToken.id)
|
||||
if (defenderToken && Misc.isFirstConnectedGM()) {
|
||||
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id)
|
||||
rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme)
|
||||
rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll)
|
||||
rddCombat?.removeChatMessageActionsPasseArme(msg.paramChatDefense.attackerRoll.passeArme)
|
||||
if (msg.defenderRoll.ids) {/* TODO: delete roll V1 */
|
||||
RollDialog.loadRollData(msg.paramChatDefense)
|
||||
rddCombat?._chatMessageDefenseV2(msg.paramChatDefense)
|
||||
} else {
|
||||
rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,8 +465,8 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
async onEvent(button, event) {
|
||||
const chatMessage = ChatUtility.getChatMessage(event);
|
||||
const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll');
|
||||
const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll');
|
||||
const defenderRoll = ChatUtility.getMessageData(chatMessage, 'rollData');
|
||||
const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'rollData');
|
||||
console.log('RdDCombat', attackerRoll, defenderRoll);
|
||||
|
||||
const armeParadeId = event.currentTarget.attributes['data-armeid']?.value;
|
||||
@@ -665,12 +666,101 @@ export class RdDCombat {
|
||||
return { msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3 };
|
||||
}
|
||||
|
||||
|
||||
async attaqueV2() {
|
||||
if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
|
||||
return
|
||||
}
|
||||
await this.doRollAttaque({
|
||||
ids: {
|
||||
actorId: this.attackerId,
|
||||
actorTokenId: this.attackerTokenId,
|
||||
opponentId: this.defender.id,
|
||||
opponentTokenId: this.defenderTokenId,
|
||||
},
|
||||
type: { allowed: ['attaque'], current: 'attaque' },
|
||||
passeArme: foundry.utils.randomID(16),
|
||||
})
|
||||
}
|
||||
|
||||
async doRollAttaque(rollData, callbacks = []) {
|
||||
// TODO V2 await this.proposerAjustementTirLancer(rollData)
|
||||
await RollDialog.create(rollData, {
|
||||
onRollDone: (dialog) => {
|
||||
if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
|
||||
dialog.close()
|
||||
},
|
||||
customChatMessage: true,
|
||||
callbacks: [
|
||||
async (roll) => await this.onAttaqueV2(roll),
|
||||
...callbacks
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
async onAttaqueV2(attackerRoll) {
|
||||
if (!this.defender || !attackerRoll.rolled.isSuccess || attackerRoll.particulieres?.length > 1) {
|
||||
return
|
||||
}
|
||||
if (!await this.attacker.accorder(this.defender, 'avant-defense')) {
|
||||
return;
|
||||
}
|
||||
|
||||
RollDialog.loadRollData(attackerRoll)
|
||||
|
||||
const surpriseDefender = this.defender.getSurprise(true);
|
||||
const paramChatDefense = {
|
||||
attackerRoll: attackerRoll,
|
||||
isPossession: this.isPossession(attackerRoll),
|
||||
defender: this.defender,
|
||||
attacker: this.attacker,
|
||||
attackerId: this.attackerId,
|
||||
attackerToken: this.attackerToken,
|
||||
defenderToken: this.defenderToken,
|
||||
surprise: surpriseDefender,
|
||||
}
|
||||
|
||||
if (Misc.isFirstConnectedGM()) {
|
||||
await this._chatMessageDefenseV2(paramChatDefense);
|
||||
}
|
||||
else {
|
||||
this._socketSendMessageDefense(paramChatDefense, {});
|
||||
}
|
||||
}
|
||||
async _chatMessageDefenseV2(paramDemandeDefense) {
|
||||
const attackerRoll = paramDemandeDefense.attackerRoll;
|
||||
RollBasicParts.loadSurprises(attackerRoll)
|
||||
attackerRoll.passeArme = attackerRoll.passeArme ?? foundry.utils.randomID(16)
|
||||
attackerRoll.dmg = RdDBonus.dmgRollV2(attackerRoll, attackerRoll.current.attaque)
|
||||
// attackerRoll.current.attaque.dmg = attackerRoll.dmg
|
||||
// attaque.dmg = attackerRoll.current.attaque.dmg
|
||||
const attaque = RollDialog.saveParts(attackerRoll)
|
||||
const defense = {
|
||||
attackerRoll: attaque,
|
||||
ids: RollBasicParts.reverseIds(attaque),
|
||||
passeArme: attaque.passeArme ?? foundry.utils.randomID(16)
|
||||
}
|
||||
|
||||
const choixDefense = await ChatMessage.create({
|
||||
// message privé: du défenseur à lui même (et aux GMs)
|
||||
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
|
||||
alias: this.attacker?.getAlias(),
|
||||
whisper: ChatUtility.getOwners(this.defender),
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', attackerRoll)
|
||||
});
|
||||
// flag pour garder les jets d'attaque/defense
|
||||
ChatUtility.setMessageData(choixDefense, 'rollData', defense)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async attaque(competence, arme) {
|
||||
if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
|
||||
return
|
||||
}
|
||||
if (arme.system.cac == 'empoignade') {
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
return this.attacker.rollCompetence(competence.name, { arme: arme })
|
||||
}
|
||||
if (arme.system.cac == EMPOIGNADE) {
|
||||
RdDEmpoignade.onAttaqueEmpoignade(this.attacker, this.defender)
|
||||
return
|
||||
}
|
||||
@@ -723,9 +813,9 @@ export class RdDCombat {
|
||||
}
|
||||
else {
|
||||
// sans armes: à mains nues
|
||||
rollData.arme = RdDItemArme.corpsACorps(this.attacker)
|
||||
rollData.arme = RdDItemArme.pugilat(this.attacker)
|
||||
rollData.arme.system.niveau = competence.system.niveau
|
||||
rollData.arme.system.initiative = RdDInitiative.calculInitiative(competence.system.niveau, this.attacker.system.carac['melee'].value);
|
||||
rollData.arme.system.initiative = RdDInitiative.getRollInitiative(this.attacker.system.carac['melee'].value, competence.system.niveau);
|
||||
}
|
||||
return rollData;
|
||||
}
|
||||
@@ -776,7 +866,7 @@ export class RdDCombat {
|
||||
passeArme: rollData.passeArme
|
||||
})
|
||||
});
|
||||
ChatUtility.setMessageData(choixParticuliere, 'attacker-roll', rollData);
|
||||
ChatUtility.setMessageData(choixParticuliere, 'rollData', rollData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -852,10 +942,10 @@ export class RdDCombat {
|
||||
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
|
||||
alias: this.attacker?.getAlias(),
|
||||
whisper: ChatUtility.getOwners(this.defender),
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', paramDemandeDefense),
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense-v1.hbs', paramDemandeDefense),
|
||||
});
|
||||
// flag pour garder les jets d'attaque/defense
|
||||
ChatUtility.setMessageData(choixDefense, 'defender-roll', defenderRoll);
|
||||
ChatUtility.setMessageData(choixDefense, 'rollData', defenderRoll);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -869,7 +959,7 @@ export class RdDCombat {
|
||||
defenderToken: this.defenderToken,
|
||||
defenderRoll: defenderRoll,
|
||||
paramChatDefense: paramChatDefense,
|
||||
rollMode: true
|
||||
rollMode: true,
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -906,7 +996,7 @@ export class RdDCombat {
|
||||
essais: attackerRoll.essais
|
||||
})
|
||||
});
|
||||
ChatUtility.setMessageData(choixEchecTotal, 'attacker-roll', attackerRoll);
|
||||
ChatUtility.setMessageData(choixEchecTotal, 'rollData', attackerRoll);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -968,6 +1058,7 @@ export class RdDCombat {
|
||||
|
||||
async defenseV2(attackerRoll) {
|
||||
// this._prepareParade(attackerRoll, arme, competence);
|
||||
RollDialog.loadRollData(attackerRoll)
|
||||
await this.doRollDefense({
|
||||
ids: {
|
||||
actorId: this.defender.id,
|
||||
@@ -975,7 +1066,7 @@ export class RdDCombat {
|
||||
opponentTokenId: this.attackerTokenId,
|
||||
opponentId: this.attackerId,
|
||||
},
|
||||
type: { allowed: ['defense'], current: 'defense' },
|
||||
type: { allowed: [ROLL_TYPE_DEFENSE], current: ROLL_TYPE_DEFENSE },
|
||||
attackerRoll: RollDialogAdapter.mapActionAttaque(attackerRoll),
|
||||
passeArme: attackerRoll.passeArme,
|
||||
})
|
||||
@@ -983,10 +1074,7 @@ export class RdDCombat {
|
||||
|
||||
async doRollDefense(rollData, callbacks = []) {
|
||||
await RollDialog.create(rollData, {
|
||||
onRollDone: (dialog) => {
|
||||
if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
|
||||
dialog.close()
|
||||
},
|
||||
onRollDone: RollDialog.onRollDoneClose,
|
||||
customChatMessage: true,
|
||||
callbacks: [
|
||||
async (roll) => {
|
||||
@@ -1034,22 +1122,17 @@ export class RdDCombat {
|
||||
if (RdDCombat.isReussite(rollData)) {
|
||||
if (isParade) {
|
||||
await this.computeDeteriorationArme(rollData)
|
||||
if (RdDCombat.isParticuliere(rollData)) {
|
||||
await this.infoAttaquantDesarme(rollData)
|
||||
}
|
||||
}
|
||||
|
||||
if (RdDCombat.isParticuliere(rollData)) {
|
||||
await this._onDefenseParticuliere(rollData, isEsquive)
|
||||
}
|
||||
}
|
||||
this.removeChatMessageActionsPasseArme(rollData.passeArme)
|
||||
}
|
||||
|
||||
async _onDefenseParticuliere(rollData, isEsquive) {
|
||||
if (isEsquive) {
|
||||
ChatUtility.createChatWithRollMode(
|
||||
{ content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" },
|
||||
this.defender)
|
||||
}
|
||||
else if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) {
|
||||
async infoAttaquantDesarme(rollData) {
|
||||
if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) {
|
||||
// TODO: attaquant doit jouer résistance et peut être désarmé p132
|
||||
ChatUtility.createChatWithRollMode(
|
||||
{ content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` },
|
||||
|
@@ -19,6 +19,7 @@ import { TMRUtility } from "./tmr-utility.js";
|
||||
import { DialogFatigueVoyage } from "./voyage/dialog-fatigue-voyage.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
import { renderTemplate } from "./constants.js";
|
||||
|
||||
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { STATUSES } from "./settings/status-effects.js";
|
||||
import { ITEM_TYPES } from "./constants.js";
|
||||
import { ITEM_TYPES, renderTemplate } from "./constants.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
import { RdDRoll } from "./rdd-roll.js";
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { ATTAQUE_TYPE, RdDItemArme } from "./item/arme.js";
|
||||
import { ATTAQUE_TYPE, EMPOIGNADE, PUGILAT, RdDItemArme } from "./item/arme.js";
|
||||
import { ITEM_TYPES } from "./constants.js";
|
||||
|
||||
export class RdDHotbar {
|
||||
@@ -28,8 +28,8 @@ export class RdDHotbar {
|
||||
return ' ' + maniement
|
||||
case 'tir': return ' (tir)';
|
||||
case 'lancer': return ' (lancer)';
|
||||
case 'pugilat': return ' (pugilat)';
|
||||
case 'empoignade': return ' (empoignade)';
|
||||
case PUGILAT: return ' (pugilat)';
|
||||
case EMPOIGNADE: return ' (empoignade)';
|
||||
}
|
||||
return ''
|
||||
}
|
||||
@@ -63,8 +63,8 @@ export class RdDHotbar {
|
||||
case ITEM_TYPES.competence:
|
||||
await this.createItemMacro(item, slot++, 'competence')
|
||||
if (item.isCorpsACorps()) {
|
||||
await this.createItemMacro(item, slot++, 'pugilat')
|
||||
await this.createItemMacro(item, slot++, 'empoignade')
|
||||
await this.createItemMacro(item, slot++, PUGILAT)
|
||||
await this.createItemMacro(item, slot++, EMPOIGNADE)
|
||||
}
|
||||
else if (item.isCompetenceArme()) {
|
||||
ui.notifications.info(`${item.name} est une compétence d'arme, la macro n'est pas liée à un arme.<br>
|
||||
@@ -121,9 +121,9 @@ export class RdDHotbar {
|
||||
case ITEM_TYPES.competence:
|
||||
if (item.isCorpsACorps()) {
|
||||
switch (categorieArme) {
|
||||
case 'pugilat':
|
||||
return actor.rollArme(RdDItemArme.corpsACorps(actor));
|
||||
case 'empoignade':
|
||||
case PUGILAT:
|
||||
return actor.rollArme(RdDItemArme.pugilat(actor));
|
||||
case EMPOIGNADE:
|
||||
return actor.rollArme(RdDItemArme.empoignade(actor));
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { ChatUtility } from "./chat-utility.js"
|
||||
import { renderTemplate } from "./constants.js"
|
||||
|
||||
const vents = [
|
||||
{ min: 0, max: 0, valeur: 'Calme' },
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
@@ -66,9 +67,9 @@ export class RdDResolutionTable {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _computeCell(niveau, percentage) {
|
||||
static _computeCell(level, percentage) {
|
||||
return {
|
||||
niveau: niveau,
|
||||
level: level,
|
||||
score: percentage,
|
||||
norm: Math.min(99, percentage),
|
||||
sign: this._reussiteSignificative(percentage),
|
||||
@@ -188,7 +189,7 @@ export class RdDResolutionTable {
|
||||
static computeReussite(chances, roll, diviseur) {
|
||||
const reussite = reussites.find(x => x.condition(chances, roll))
|
||||
if (diviseur > 1 && reussite.isSuccess) {
|
||||
if (chances > roll * diviseur) {
|
||||
if (chances.norm < roll * diviseur) {
|
||||
return reussiteInsuffisante
|
||||
}
|
||||
}
|
||||
@@ -236,7 +237,7 @@ export class RdDResolutionTable {
|
||||
maxCarac = Math.min(maxCarac, minCarac + 20);
|
||||
minLevel = Math.max(minLevel, -10);
|
||||
maxLevel = Math.max(Math.min(maxLevel, 30), minLevel + colonnes);
|
||||
return await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', {
|
||||
return await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', {
|
||||
carac: carac,
|
||||
difficulte: level,
|
||||
min: minLevel,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { ENTITE_BLURETTE, ENTITE_INCARNE } from "./constants.js";
|
||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, renderTemplate } from "./constants.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
|
||||
/**
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
|
||||
const titleTableDeResolution = 'Table de résolution';
|
||||
/**
|
||||
@@ -98,14 +100,14 @@ export class RdDRollResolutionTable extends Dialog {
|
||||
async onLancer() {
|
||||
await RdDResolutionTable.rollData(this.rollData);
|
||||
console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled);
|
||||
await RdDResolutionTable.displayRollData(this.rollData);
|
||||
await RdDRollResult.displayRollData(this.rollData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onLancerFermer() {
|
||||
await RdDResolutionTable.rollData(this.rollData);
|
||||
console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled);
|
||||
await RdDResolutionTable.displayRollData(this.rollData);
|
||||
await RdDRollResult.displayRollData(this.rollData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { renderTemplate } from "./constants.js";
|
||||
|
||||
export class RdDRollResult {
|
||||
|
||||
@@ -13,6 +14,6 @@ export class RdDRollResult {
|
||||
|
||||
static async buildRollDataHtml(rollData, template = 'chat-resultat-general.hbs') {
|
||||
rollData.show = rollData.show || {};
|
||||
return await foundry.applications.handlebars.renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
|
||||
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||
import { RollDataAjustements } from "./rolldata-ajustements-v1.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { RdDItemSort } from "./item-sort.js";
|
||||
@@ -8,8 +8,8 @@ import { RdDCarac } from "./rdd-carac.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { ACTOR_TYPES } from "./constants.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { ACTOR_TYPES, renderTemplate } from "./constants.js";
|
||||
import { EMPOIGNADE } from "./item/arme.js";
|
||||
|
||||
/**
|
||||
* Extend the base Dialog entity to select roll parameters
|
||||
@@ -23,7 +23,7 @@ export class RdDRoll extends Dialog {
|
||||
RdDRoll._ensureCorrectAction(action);
|
||||
RdDRoll._setDefaultOptions(actor, rollData);
|
||||
|
||||
const html = await foundry.applications.handlebars.renderTemplate(dialogConfig.html, rollData);
|
||||
const html = await renderTemplate(dialogConfig.html, rollData);
|
||||
|
||||
let options = { classes: ["rdd-roll-dialog"], width: 650, height: 'fit-content', 'z-index': 99999, close: html => { } };
|
||||
if (dialogConfig.close) {
|
||||
@@ -334,10 +334,8 @@ export class RdDRoll extends Dialog {
|
||||
// Mise à jour valeurs
|
||||
this.html.find(".dialog-roll-title").text(this._getTitle(rollData));
|
||||
this.html.find("input.check-mortalite").prop('checked', rollData.dmg.mortalite == 'non-mortel');
|
||||
this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == 'empoignade' ? 'empoignade' : Misc.toSignedString(rollData.dmg.total));
|
||||
this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == EMPOIGNADE ? EMPOIGNADE : Misc.toSignedString(rollData.dmg.total));
|
||||
this.html.find("label.arme-mortalite").text(rollData.dmg.mortalite);
|
||||
// this.html.find("[name='dmg-arme-actor']").text(rollData.dmg.mortalite == 'empoignade'? 'empoignade': Misc.toSignedString(rollData.dmg.total) );
|
||||
// this.html.find("[name='arme-mortalite']").text(rollData.dmg.mortalite);
|
||||
this.html.find("div.placeholder-ajustements").empty().append(adjustements);
|
||||
this.html.find("div.placeholder-resolution").empty().append(resolutionTable)
|
||||
}
|
||||
@@ -345,7 +343,7 @@ export class RdDRoll extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async buildAjustements(rollData) {
|
||||
return await foundry.applications.handlebars.renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs`, rollData);
|
||||
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs`, rollData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { SHOW_DICE, SYSTEM_RDD } from "./constants.js";
|
||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||
import { renderTemplate, SHOW_DICE, SYSTEM_RDD } from "./constants.js";
|
||||
import { RollDataAjustements } from "./rolldata-ajustements-v1.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { COORD_TMR_INCONNU, TMRUtility } from "./tmr-utility.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
@@ -47,7 +47,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
static async create(actor, tmrData) {
|
||||
await PixiTMR.init()
|
||||
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.hbs', tmrData);
|
||||
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.hbs', tmrData);
|
||||
if (tmrData.mode != 'visu' && !game.user.isGM) {
|
||||
ChatMessage.create({ content: actor.name + " est monté dans les TMR en mode : " + tmrData.mode, whisper: ChatUtility.getGMs() });
|
||||
}
|
||||
@@ -508,7 +508,7 @@ export class RdDTMRDialog extends Dialog {
|
||||
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getOwners(this.actor),
|
||||
content: await foundry.applications.handlebars.renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.hbs`, rencData)
|
||||
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.hbs`, rencData)
|
||||
});
|
||||
|
||||
this.$updateValuesDisplay();
|
||||
|
@@ -1,6 +1,9 @@
|
||||
/* -------------------------------------------- */
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDCombatManager } from "./rdd-combat.js";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js";
|
||||
import { Targets } from "./targets.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -30,47 +33,92 @@ export class RdDTokenHud {
|
||||
const combatant = game.combat.combatants.find(c => c.tokenId == tokenId)
|
||||
const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false })
|
||||
if (actor) {
|
||||
const actions = RdDCombatManager.listActionsActorCombatant(actor)
|
||||
// initiative
|
||||
await RdDTokenHud.addExtensionHudInit(html, combatant, actions)
|
||||
// combat
|
||||
await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions.filter(it => !it.initOnly))
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
await RdDTokenHud.addExtensionHudCombat(html, combatant, actor, token)
|
||||
}
|
||||
else {
|
||||
const actions = RdDCombatManager.listActionsActorCombatant(actor)
|
||||
// initiative
|
||||
await RdDTokenHud.addExtensionHudInit(html, combatant, actions)
|
||||
// combat
|
||||
await RdDTokenHud.addExtensionHudAttaques(html, combatant, token, actions.filter(it => !it.initOnly))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async addExtensionHudCombat(html, combatant, actor, token) {
|
||||
const actionsActor = actor.listActionsCombat();
|
||||
const ajustements = combatant?.initiative ?
|
||||
[
|
||||
{ label: 'Initiative +1', action: 'delta', value: 1 },
|
||||
{ label: 'Initiative -1', action: 'delta', value: -1 }
|
||||
] : []
|
||||
const autres = [{ label: "Autre action", action: 'autre' }]
|
||||
const actions = Misc.indexed(actionsActor.concat(ajustements).concat(autres))
|
||||
|
||||
const hudData = { combatant, token, actions };
|
||||
const hud = $(await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/hud-actor-combat.hbs', hudData))
|
||||
$(html).find('div.col.left').append(hud)
|
||||
|
||||
const list = hud.find('div.rdd-hud-list')
|
||||
RdDTokenHud.setupHudToggle(hud, list)
|
||||
|
||||
const selectInitiative = list.find('select[name="initiative"]');
|
||||
selectInitiative.change(event => {
|
||||
const action = actions.find(it => it.index == event.currentTarget.value)
|
||||
console.log('select initiative', combatant.id, action)
|
||||
if (action) {
|
||||
switch (action.action) {
|
||||
case 'delta':
|
||||
RdDCombatManager.incDecInit(combatant.id, action.value);
|
||||
break
|
||||
case 'autre':
|
||||
RdDCombatManager.rollInitiativeAction(combatant.id,
|
||||
{ label: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
|
||||
break
|
||||
default:
|
||||
RdDCombatManager.rollInitiativeAction(combatant.id, action)
|
||||
}
|
||||
selectInitiative.select("")
|
||||
}
|
||||
})
|
||||
list.find('.rdd-attaque-v2').click(event => combatant.actor.rollAttaque(token))
|
||||
}
|
||||
|
||||
static async addExtensionHudInit(html, combatant, actions) {
|
||||
const hudData = {
|
||||
combatant, actions,
|
||||
commandes: [
|
||||
{ name: "Autre action", command: 'autre' },
|
||||
{ name: 'Initiative +1', command: 'inc', value: 0.01 },
|
||||
{ name: 'Initiative -1', command: 'dec', value: -0.01 }]
|
||||
{ label: "Autre action", command: 'autre' },
|
||||
{ label: 'Initiative +1', command: 'delta', value: 1 },
|
||||
{ label: 'Initiative -1', command: 'deltac', value: -1 }]
|
||||
};
|
||||
const controlIconCombat = $(html).find('.control-icon[data-action=combat]');
|
||||
await RdDTokenHud._configureSubMenu(controlIconCombat,
|
||||
await RdDTokenHud._configureSubMenu(it => controlIconCombat.after(it),
|
||||
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.hbs',
|
||||
hudData,
|
||||
(event) => {
|
||||
let initCommand = event.currentTarget.attributes['data-command']?.value;
|
||||
let combatantId = event.currentTarget.attributes['data-combatant-id']?.value;
|
||||
let initCommand = event.currentTarget.attributes['data-command']?.value
|
||||
let initCommandValue = Number(event.currentTarget.attributes['data-command-value']?.value ?? 0)
|
||||
let combatantId = event.currentTarget.attributes['data-combatant-id']?.value
|
||||
if (initCommand) {
|
||||
RdDTokenHud._initiativeCommand(initCommand, combatantId);
|
||||
RdDCombatManager.applyInitiativeCommand(combatantId, initCommand, initCommandValue)
|
||||
} else {
|
||||
let index = event.currentTarget.attributes['data-action-index'].value;
|
||||
let action = hudData.actions[index];
|
||||
RdDCombatManager.rollInitiativeAction(combatantId, action);
|
||||
let index = event.currentTarget.attributes['data-action-index'].value
|
||||
let action = hudData.actions[index]
|
||||
RdDCombatManager.rollInitiativeAction(combatantId, action)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
static async addExtensionHudCombat(html, combatant, token, actions) {
|
||||
static async addExtensionHudAttaques(html, combatant, token, actions) {
|
||||
|
||||
const hudData = { combatant, token, actions, commandes: [] };
|
||||
const controlIconTarget = $(html).find('.control-icon[data-action=target]');
|
||||
await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs', hudData,
|
||||
const divColLeft = $(html).find('div.col.left');
|
||||
await RdDTokenHud._configureSubMenu(it => divColLeft.append(it),
|
||||
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs',
|
||||
hudData,
|
||||
(event) => {
|
||||
const actionIndex = event.currentTarget.attributes['data-action-index']?.value;
|
||||
const action = hudData.actions[actionIndex];
|
||||
@@ -90,7 +138,7 @@ export class RdDTokenHud {
|
||||
const hudSoins = { blessures: target.actor.blessuresASoigner() ?? [] };
|
||||
if (hudSoins.blessures.length > 0) {
|
||||
const controlIconTarget = $(html).find('.control-icon[data-action=combat]');
|
||||
await RdDTokenHud._configureSubMenu(controlIconTarget,
|
||||
await RdDTokenHud._configureSubMenu(it => controlIconTarget.after(it),
|
||||
'systems/foundryvtt-reve-de-dragon/templates/hud-actor-soins.hbs',
|
||||
hudSoins,
|
||||
(event) => {
|
||||
@@ -101,15 +149,6 @@ export class RdDTokenHud {
|
||||
}
|
||||
}
|
||||
|
||||
static _initiativeCommand(initCommand, combatantId) {
|
||||
switch (initCommand) {
|
||||
case 'inc': return RdDCombatManager.incDecInit(combatantId, 0.01);
|
||||
case 'dec': return RdDCombatManager.incDecInit(combatantId, -0.01);
|
||||
case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
|
||||
{ name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async addTokenHudExtensions(app, html, tokenId) {
|
||||
console.log(`Adding token HUD extensions for token ${tokenId}`);
|
||||
@@ -129,20 +168,24 @@ export class RdDTokenHud {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async _configureSubMenu(insertionPoint, template, hudData, onMenuItem) {
|
||||
const hud = $(await foundry.applications.handlebars.renderTemplate(template, hudData));
|
||||
static async _configureSubMenu(callInsertion, template, hudData, onMenuItem) {
|
||||
const hud = $(await renderTemplate(template, hudData));
|
||||
const list = hud.find('div.rdd-hud-list');
|
||||
|
||||
RdDTokenHud._toggleHudListActive(hud, list);
|
||||
RdDTokenHud.setupHudToggle(hud, list)
|
||||
|
||||
hud.find('img.rdd-hud-togglebutton').click(event => RdDTokenHud._toggleHudListActive(hud, list));
|
||||
list.find('.rdd-hud-menu').click(onMenuItem);
|
||||
|
||||
insertionPoint.after(hud);
|
||||
callInsertion(hud);
|
||||
}
|
||||
|
||||
static _toggleHudListActive(hud, list) {
|
||||
hud.toggleClass('active');
|
||||
HtmlUtility.showControlWhen(list, hud.hasClass('active'));
|
||||
static setupHudToggle(hud, list) {
|
||||
function toggleHudList(hud, list) {
|
||||
hud.toggleClass('active')
|
||||
HtmlUtility.showControlWhen(list, hud.hasClass('active'))
|
||||
}
|
||||
toggleHudList(hud, list)
|
||||
$(hud).find('img.rdd-hud-togglebutton').click(event => toggleHudList(hud, list))
|
||||
}
|
||||
|
||||
}
|
@@ -278,7 +278,7 @@ export class RdDUtility {
|
||||
|
||||
Handlebars.registerHelper('plusMoins', diff => parseInt(diff) ? (diff > 0 ? '+' : '') + Math.round(diff) : diff)
|
||||
Handlebars.registerHelper('fractionOneN', n => new Handlebars.SafeString(Misc.getFractionOneN(n)))
|
||||
|
||||
|
||||
// Handle v12 removal of this helper
|
||||
Handlebars.registerHelper('select', function (selected, options) {
|
||||
const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected));
|
||||
@@ -286,7 +286,7 @@ export class RdDUtility {
|
||||
const html = options.fn(this);
|
||||
return html.replace(rgx, "$& selected");
|
||||
})
|
||||
|
||||
|
||||
// logic
|
||||
Handlebars.registerHelper('either', (a, b) => a ?? b);
|
||||
// string manipulation
|
||||
@@ -299,8 +299,10 @@ export class RdDUtility {
|
||||
Handlebars.registerHelper('grammar-un', str => Grammar.articleIndetermine(str));
|
||||
Handlebars.registerHelper('grammar-accord', (genre, ...args) => Grammar.accord(genre, args));
|
||||
Handlebars.registerHelper('json-stringify', object => JSON.stringify(object))
|
||||
|
||||
|
||||
// math
|
||||
Handlebars.registerHelper('math-sum', (...values) => values.slice(0, -1).reduce(Misc.sum(), 0))
|
||||
Handlebars.registerHelper('math-abs', diff => Math.abs(parseInt(diff)))
|
||||
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
|
||||
Handlebars.registerHelper('repeat', function (n, block) {
|
||||
let accum = '';
|
||||
|
@@ -4,6 +4,10 @@ import { RdDCarac } from "../rdd-carac.js"
|
||||
import { RdDCombat } from "../rdd-combat.js"
|
||||
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
|
||||
import { RdDResolutionTable } from "../rdd-resolution-table.js"
|
||||
import { RDD_CONFIG, renderTemplate } from "../constants.js"
|
||||
import { EMPOIGNADE } from "../item/arme.js"
|
||||
import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js"
|
||||
import { RollTypeCuisine } from "./roll-type-cuisine.mjs"
|
||||
|
||||
export default class ChatRollResult {
|
||||
static init() {
|
||||
@@ -15,13 +19,14 @@ export default class ChatRollResult {
|
||||
static onReady() {
|
||||
foundry.applications.handlebars.loadTemplates({
|
||||
'partial-appel-chance': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-appel-chance.hbs',
|
||||
'partial-attaque-particuliere': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-attaque-particuliere.hbs',
|
||||
'partial-encaissement': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-encaissement.hbs',
|
||||
'partial-recul-choc': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-recul-choc.hbs',
|
||||
'partial-info-appel-moral': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-info-appel-moral.hbs',
|
||||
})
|
||||
}
|
||||
|
||||
async display(roll) {
|
||||
async display(roll, impacts) {
|
||||
this.prepareDisplay(roll)
|
||||
|
||||
const chatMessage = await ChatUtility.createChatWithRollMode(
|
||||
@@ -31,18 +36,19 @@ 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
|
||||
}
|
||||
|
||||
prepareDisplay(roll) {
|
||||
roll.done = roll.done || {}
|
||||
roll.show = roll.show || {}
|
||||
roll.done = roll.done ?? {}
|
||||
roll.show = roll.show ?? {}
|
||||
roll.show.chance = this.isAppelChancePossible(roll)
|
||||
roll.show.encaissement = this.isShowEncaissement(roll)
|
||||
roll.show.recul = this.getReculChoc(roll)
|
||||
|
||||
roll.show.recul = this.getRecul(roll)
|
||||
//roll.show.particuliere = roll.show.particuliere ?? []
|
||||
}
|
||||
|
||||
isAppelChancePossible(roll) {
|
||||
@@ -52,31 +58,51 @@ export default class ChatRollResult {
|
||||
}
|
||||
|
||||
isShowEncaissement(roll) {
|
||||
return roll.rolled.isEchec &&
|
||||
roll.attackerRoll?.dmg.mortalite != 'empoignade'
|
||||
switch (roll.type.current) {
|
||||
case ROLL_TYPE_DEFENSE:
|
||||
return roll.rolled.isEchec && roll.attackerRoll?.dmg.mortalite != EMPOIGNADE
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
getReculChoc(roll, defender = roll.active.actor, attacker = roll.opponent.actor) {
|
||||
const attaque = roll.attackerRoll
|
||||
if (attaque &&
|
||||
(roll.rolled.isEchec || !roll.current.defense.isEsquive) &&
|
||||
(attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)) {
|
||||
const taille = defender.system.carac.taille.value
|
||||
const impact = attacker.system.carac.force.value + roll.attackerRoll?.dmg.dmgArme
|
||||
return {
|
||||
raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force',
|
||||
taille: taille,
|
||||
impact: impact,
|
||||
chances: RdDResolutionTable.computeChances(10, taille-impact).norm,
|
||||
diff: taille - impact
|
||||
}
|
||||
|
||||
getRecul(roll, defender = roll.active.actor, attacker = roll.opponent?.actor) {
|
||||
switch (roll.type.current) {
|
||||
case ROLL_TYPE_DEFENSE:
|
||||
{
|
||||
const attaque = roll.attackerRoll
|
||||
if (attaque &&
|
||||
(roll.rolled.isEchec || !roll.current.defense.isEsquive) &&
|
||||
(attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)) {
|
||||
const taille = defender.system.carac.taille.value
|
||||
const impact = attacker.system.carac.force.value + roll.attackerRoll?.dmg.dmgArme
|
||||
return {
|
||||
raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force',
|
||||
taille: taille,
|
||||
impact: impact,
|
||||
chances: RdDResolutionTable.computeChances(10, taille - impact).norm,
|
||||
diff: taille - impact
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
case ROLL_TYPE_ATTAQUE:
|
||||
{
|
||||
const attaque = roll
|
||||
if (attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key) {
|
||||
return {
|
||||
raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
async buildRollHtml(roll) {
|
||||
const template = `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${roll.type.current}.hbs`
|
||||
return await foundry.applications.handlebars.renderTemplate(template, roll)
|
||||
const html = await renderTemplate(template, roll)
|
||||
return await RdDTextEditor.enrichHTML(html, undefined, { showLink: false })
|
||||
}
|
||||
|
||||
async chatListeners(html) {
|
||||
@@ -84,6 +110,8 @@ export default class ChatRollResult {
|
||||
$(html).on("click", '.appel-destinee', event => this.onClickAppelDestinee(event))
|
||||
$(html).on("click", '.encaissement', event => this.onClickEncaissement(event))
|
||||
$(html).on("click", '.resister-recul', event => this.onClickRecul(event))
|
||||
$(html).on("click", '.choix-particuliere', event => this.onClickChoixParticuliere(event))
|
||||
$(html).on("click", '.faire-gouter', event => this.onClickFaireGouter(event))
|
||||
|
||||
}
|
||||
|
||||
@@ -118,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
|
||||
@@ -177,4 +206,18 @@ export default class ChatRollResult {
|
||||
await this.updateChatMessage(chatMessage, savedRoll)
|
||||
}
|
||||
|
||||
async onClickChoixParticuliere(event) {
|
||||
const choix = event.currentTarget.attributes['data-particuliere'].value
|
||||
const chatMessage = ChatUtility.getChatMessage(event)
|
||||
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
|
||||
savedRoll.particuliere = choix
|
||||
savedRoll.particulieres = [RDD_CONFIG.particuliere[choix]]
|
||||
await this.updateChatMessage(chatMessage, savedRoll)
|
||||
await this.getCombat(savedRoll)?.onAttaqueV2(savedRoll, callbacks)
|
||||
}
|
||||
async onClickFaireGouter(event) {
|
||||
const chatMessage = ChatUtility.getChatMessage(event)
|
||||
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
|
||||
await new RollTypeCuisine().onFaireGouter(savedRoll)
|
||||
}
|
||||
}
|
@@ -1,28 +1,29 @@
|
||||
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"
|
||||
import { PART_DEFENSE } from "./roll-part-defense.mjs"
|
||||
|
||||
|
||||
export class RollBasicParts {
|
||||
|
||||
restore(rollData) {
|
||||
static restore(rollData) {
|
||||
rollData.ids.sceneId = rollData.ids.sceneId ?? canvas.scene.id
|
||||
rollData.active = RollBasicParts.$getActor(rollData)
|
||||
rollData.opponent = RollBasicParts.$getOpponent(rollData)
|
||||
rollData.active = RollBasicParts.getTokenActor(rollData)
|
||||
rollData.opponent = RollBasicParts.getTokenActorOpponent(rollData)
|
||||
if (rollData.type.opposed == undefined) {
|
||||
rollData.type.opposed = rollData.opponent != null
|
||||
}
|
||||
}
|
||||
|
||||
loadSurprises(rollData, type) {
|
||||
static loadSurprises(rollData, type = rollData.type.current) {
|
||||
if (!rollData.type.passif) {
|
||||
this.loadSurprise(rollData.active, this.getForceRequiseActiveActor(rollData, type))
|
||||
this.loadSurprise(rollData.opponent, 0)
|
||||
RollBasicParts.loadSurprise(rollData.active, RollBasicParts.getForceRequiseActiveActor(rollData, type))
|
||||
RollBasicParts.loadSurprise(rollData.opponent, 0)
|
||||
}
|
||||
}
|
||||
|
||||
loadSurprise(who, forceRequise) {
|
||||
static loadSurprise(who, forceRequise) {
|
||||
if (who?.actor) {
|
||||
foundry.utils.mergeObject(who,
|
||||
StatusEffects.getActorEffetSurprise(who.actor, forceRequise),
|
||||
@@ -30,15 +31,16 @@ export class RollBasicParts {
|
||||
}
|
||||
}
|
||||
|
||||
getForceRequiseActiveActor(rollData, type) {
|
||||
static getForceRequiseActiveActor(rollData, type) {
|
||||
switch (type) {
|
||||
case ROLL_TYPE_ATTAQUE: return rollData.current[PART_ATTAQUE].attaque.forceRequise
|
||||
case ROLL_TYPE_ATTAQUE: return rollData.current[PART_ATTAQUE].forceRequise
|
||||
case ROLL_TYPE_DEFENSE: return rollData.current[PART_DEFENSE].forceRequise
|
||||
default: return 0
|
||||
}
|
||||
}
|
||||
|
||||
initFrom(rollData) {
|
||||
static initFrom(rollData) {
|
||||
const isOpposed = rollData.type.opposed && rollData.opponent
|
||||
return {
|
||||
selected: {},
|
||||
type: rollData.type,
|
||||
@@ -46,36 +48,46 @@ export class RollBasicParts {
|
||||
sceneId: rollData.ids.sceneId,
|
||||
actorId: rollData.active.id,
|
||||
actorTokenId: rollData.active.tokenId,
|
||||
opponentId: rollData.type.opposed ? rollData.opponent.id : undefined,
|
||||
opponentTokenId: rollData.type.opposed ? rollData.opponent.tokenId : undefined,
|
||||
opponentId: isOpposed ? rollData.opponent.id : undefined,
|
||||
opponentTokenId: isOpposed ? rollData.opponent.tokenId : undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static $getActor(rollData) {
|
||||
static reverseIds(rollData) {
|
||||
return {
|
||||
sceneId: rollData.ids.sceneId,
|
||||
actorId: rollData.ids.opponentId,
|
||||
actorTokenId: rollData.ids.opponentTokenId,
|
||||
opponentId: rollData.ids.actorId,
|
||||
opponentTokenId: rollData.actorTokenId
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@@ -1,6 +1,7 @@
|
||||
|
||||
export const ROLL_TYPE_ATTAQUE = 'attaque'
|
||||
export const ROLL_TYPE_COMP = 'comp'
|
||||
export const ROLL_TYPE_CUISINE = 'cuisine'
|
||||
export const ROLL_TYPE_DEFENSE = 'defense'
|
||||
export const ROLL_TYPE_JEU = 'jeu'
|
||||
export const ROLL_TYPE_MEDITATION = 'meditation'
|
||||
@@ -8,6 +9,13 @@ export const ROLL_TYPE_OEUVRE = 'oeuvre'
|
||||
export const ROLL_TYPE_SORT = 'sort'
|
||||
export const ROLL_TYPE_TACHE = 'tache'
|
||||
|
||||
export const ATTAQUE_ROLL_TYPES = [ROLL_TYPE_ATTAQUE]
|
||||
export const COMBAT_ROLL_TYPES = [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE]
|
||||
export const DEMIREVE_ROLL_TYPES = [ROLL_TYPE_SORT]
|
||||
export const DEFAULT_ROLL_TYPES = [ROLL_TYPE_COMP, ROLL_TYPE_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 DIFF = {
|
||||
LIBRE: 'libre',
|
||||
ATTAQUE: 'attaque',
|
||||
|
@@ -6,6 +6,10 @@ import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||
import { PART_OEUVRE } from "./roll-part-oeuvre.mjs";
|
||||
import { RdDItemArme } from "../item/arme.js";
|
||||
import { RdDBonus } from "../rdd-bonus.js";
|
||||
import { ITEM_TYPES, RDD_CONFIG } from "../constants.js";
|
||||
import { CARACS } from "../rdd-carac.js";
|
||||
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_OEUVRE } from "./roll-constants.mjs";
|
||||
import { PART_ATTAQUE } from "./roll-part-attaque.mjs";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RollDialogAdapter {
|
||||
@@ -15,21 +19,21 @@ export class RollDialogAdapter {
|
||||
carac: rollData.current.carac.value,
|
||||
diff: rollData.current.totaldiff,
|
||||
bonus: rollData.current.bonus,
|
||||
sign: rollData.current.sign,
|
||||
showDice: rollData.options.showDice,
|
||||
rollMode: rollData.current.rollmode.key
|
||||
})
|
||||
|
||||
const rolled = await RollDialogAdapter.rollChances(rollData, chances)
|
||||
RollDialogAdapter.adjustRollDataForV1(rollData, rolled, rollTitle)
|
||||
RollDialogAdapter.setRollDataRolled(rollData, rolled, rollTitle)
|
||||
RollDialogAdapter.adjustRollDataForV1(rollData)
|
||||
RollDialogAdapter.adjustAttaqueParticuliere(rollData)
|
||||
|
||||
return rolled
|
||||
}
|
||||
|
||||
static computeChances({ carac, diff, bonus, sign, showDice, rollMode }) {
|
||||
static computeChances({ carac, diff, bonus, showDice, rollMode }) {
|
||||
const chances = foundry.utils.duplicate(RdDResolutionTable.computeChances(carac, diff))
|
||||
RdDResolutionTable._updateChancesWithBonus(chances, bonus, diff)
|
||||
RdDResolutionTable._updateChancesFactor(chances, sign)
|
||||
chances.showDice = showDice
|
||||
chances.rollMode = rollMode
|
||||
return chances
|
||||
@@ -37,47 +41,58 @@ export class RollDialogAdapter {
|
||||
|
||||
static async rollChances(rollData, chances) {
|
||||
const rolled = await RdDResolutionTable.rollChances(chances,
|
||||
rollData.current.sign,
|
||||
rollData.current.sign.diviseur,
|
||||
rollData.current.resultat)
|
||||
rolled.caracValue = rollData.current.carac.value
|
||||
rolled.finalLevel = rollData.current.totaldiff
|
||||
rolled.bonus = rollData.current.bonus ?? 0
|
||||
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
|
||||
}
|
||||
|
||||
static adjustRollDataForV1(rollData, rolled, rollTitle) {
|
||||
static setRollDataRolled(rollData, rolled, rollTitle) {
|
||||
rollData.rolled = rolled
|
||||
rollData.choix = rollData.choix ?? {}
|
||||
rollData.show = rollData.show ?? {}
|
||||
rollData.show.title = rollTitle
|
||||
}
|
||||
|
||||
static adjustRollDataForV1(rollData) {
|
||||
const rolled = rollData.rolled
|
||||
// temporaire pour être homogène roll v1
|
||||
rollData.alias = rollData.active.actor.getAlias()
|
||||
// pour experience
|
||||
rollData.finalLevel = rollData.current.totaldiff
|
||||
if (rollData.use == undefined) { rollData.use = {} }
|
||||
if (rollData.show == undefined) { rollData.show = {} }
|
||||
if (rollData.ajustements == undefined) {
|
||||
rollData.ajustements = {}
|
||||
}
|
||||
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
|
||||
if (compKey) {
|
||||
rollData.competence = rollData.refs[PART_COMP].all.find(it => it.key == compKey)?.comp
|
||||
rollData.jetResistance = rollData.type.jetResistance
|
||||
}
|
||||
const oeuvreKey = rollData.current.oeuvre?.key
|
||||
if (oeuvreKey) {
|
||||
const oeuvreCurrent = rollData.current[PART_OEUVRE];
|
||||
rollData.oeuvre = oeuvreCurrent.oeuvre
|
||||
// rollData.oeuvre = rollData.refs[PART_OEUVRE].oeuvres.find(it => it.key == oeuvreKey)?.oeuvre
|
||||
rollData.art = oeuvreCurrent.art.type
|
||||
if (rollData.type.current == ROLL_TYPE_OEUVRE) {
|
||||
const oeuvreKey = rollData.current.oeuvre?.key
|
||||
if (rollData.type.current == ROLL_TYPE_OEUVRE && oeuvreKey) {
|
||||
const oeuvreCurrent = rollData.current[PART_OEUVRE];
|
||||
rollData.oeuvre = oeuvreCurrent.oeuvre
|
||||
rollData.art = oeuvreCurrent.art.type
|
||||
}
|
||||
}
|
||||
// pour appel moral
|
||||
rollData.diviseurSignificative = rollData.current.sign
|
||||
if (rollData.current[PART_APPELMORAL]?.checked) {
|
||||
rollData.use.moral = true
|
||||
}
|
||||
rollData.rolled = rolled
|
||||
if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) {
|
||||
rolled.niveauNecessaire = this.findNiveauNecessaire(carac, rolled.roll)
|
||||
rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rollData.selectedCarac.value, rolled.roll)
|
||||
rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
|
||||
}
|
||||
rollData.ajustements = rollData.ajustements.map(aj => {
|
||||
@@ -88,7 +103,39 @@ export class RollDialogAdapter {
|
||||
descr: aj.diff == undefined ? aj.label : undefined
|
||||
}
|
||||
})
|
||||
rollData.show.title = rollTitle
|
||||
}
|
||||
|
||||
static adjustAttaqueParticuliere(rollData) {
|
||||
if (rollData.type.current != ROLL_TYPE_ATTAQUE || !rollData.rolled.isPart) {
|
||||
return
|
||||
}
|
||||
|
||||
const attaque = rollData.current.attaque;
|
||||
const choix = []
|
||||
const isEmpoignade = attaque.dmg.mortalite == 'empoignade';
|
||||
const isCharge = attaque.tactique == 'charge'
|
||||
/* TODO: cas de créatures faisant des lancers, Glou, Glipzouk */
|
||||
const isMeleeDiffNegative = (attaque.comp.type == ITEM_TYPES.competencecreature || rollData.current.carac.key == CARACS.MELEE)
|
||||
&& rollData.current.diff.value < 0
|
||||
|
||||
// force toujours, sauf empoignade
|
||||
if (!isEmpoignade) {
|
||||
choix.push(RDD_CONFIG.particuliere.force)
|
||||
}
|
||||
|
||||
// finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
|
||||
if (!isCharge && (isEmpoignade || isMeleeDiffNegative)) {
|
||||
choix.push(RDD_CONFIG.particuliere.finesse)
|
||||
}
|
||||
|
||||
// rapidité seulement en mêlée, si l'arme le permet, et si la difficulté libre est de -1 minimum
|
||||
if (!isCharge && !isEmpoignade && isMeleeDiffNegative && attaque.arme.system.rapide) {
|
||||
choix.push(RDD_CONFIG.particuliere.rapidite)
|
||||
}
|
||||
if (choix.length == 1) {
|
||||
rollData.particuliere = choix[0].key
|
||||
}
|
||||
rollData.particulieres = choix
|
||||
}
|
||||
|
||||
static mapActionAttaque(attackerRoll) {
|
||||
@@ -99,17 +146,15 @@ export class RollDialogAdapter {
|
||||
return {
|
||||
// correspond à l'attaque de RollPartAttaque (dans rollDta.current.attaque)
|
||||
label: label,
|
||||
attaque: {
|
||||
// correspond aux actions d'attaques dans RdDActor.listActionsAttaque
|
||||
name: label,
|
||||
// action: 'attaque',
|
||||
arme: attackerRoll.arme,
|
||||
comp: attackerRoll.competence,
|
||||
main: RdDItemArme.getMainAttaque(attackerRoll.competence),
|
||||
equipe: attackerRoll.arme.system.equipe,
|
||||
// carac: { key: caracCode, value: caracValue },
|
||||
// dommagesArme: dommagesArme,
|
||||
},
|
||||
// correspond aux actions d'attaques dans RdDActor.listActionsAttaque
|
||||
name: label,
|
||||
// action: 'attaque',
|
||||
arme: attackerRoll.arme,
|
||||
comp: attackerRoll.competence,
|
||||
main: RdDItemArme.getMainAttaque(attackerRoll.competence),
|
||||
equipe: attackerRoll.arme.system.equipe,
|
||||
// carac: { key: caracCode, value: caracValue },
|
||||
// dommagesArme: dommagesArme,
|
||||
diff: attackerRoll.diffLibre,
|
||||
particuliere: attackerRoll.particuliere,
|
||||
tactique: RdDBonus.find(attackerRoll.tactique),
|
||||
|
@@ -39,10 +39,14 @@ import { RollDialogAdapter } from "./roll-dialog-adapter.mjs";
|
||||
import { ROLLDIALOG_SECTION } from "./roll-part.mjs";
|
||||
import { ROLL_TYPE_COMP } from "./roll-constants.mjs";
|
||||
import ChatRollResult from "./chat-roll-result.mjs";
|
||||
import { renderTemplate } from "../constants.js";
|
||||
import { RollTypeCuisine } from "./roll-type-cuisine.mjs";
|
||||
import { RollPartCuisine } from "./roll-part-cuisine.mjs";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js";
|
||||
import { ActorImpacts } from "../technical/actor-impacts.mjs";
|
||||
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
|
||||
const doNothing = (dialog) => { }
|
||||
|
||||
const ALL_ROLL_TYPES = [
|
||||
new RollTypeComp(),
|
||||
@@ -51,14 +55,13 @@ const ALL_ROLL_TYPES = [
|
||||
new RollTypeDefense(),
|
||||
new RollTypeSort(),
|
||||
new RollTypeMeditation(),
|
||||
new RollTypeCuisine(),
|
||||
new RollTypeOeuvre(),
|
||||
new RollTypeJeu(),
|
||||
// new RollTypeResistance ??
|
||||
// new RollTypeFixedCarac ??
|
||||
]
|
||||
|
||||
const BASIC_PARTS = new RollBasicParts()
|
||||
|
||||
const ROLL_PARTS = [
|
||||
new RollPartActor(),
|
||||
new RollPartAction(),
|
||||
@@ -72,6 +75,7 @@ const ROLL_PARTS = [
|
||||
new RollPartMeditation(),
|
||||
new RollPartSort(),
|
||||
new RollPartTache(),
|
||||
new RollPartCuisine(),
|
||||
new RollPartOeuvre(),
|
||||
new RollPartJeu(),
|
||||
|
||||
@@ -169,6 +173,14 @@ const ROLL_PARTS = [
|
||||
/* -------------------------------------------- */
|
||||
export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2)
|
||||
{
|
||||
static onRollDoneDoNothing(dialog) {
|
||||
dialog.render()
|
||||
}
|
||||
static onRollDoneClose(dialog) {
|
||||
if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
|
||||
dialog.close()
|
||||
}
|
||||
|
||||
|
||||
static init() {
|
||||
}
|
||||
@@ -256,13 +268,13 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
rollData.selected = rollData.selected ?? {}
|
||||
rollData.type = rollData.type ?? {}
|
||||
rollData.type.retry = rollData.type.retry ?? false
|
||||
BASIC_PARTS.restore(rollData)
|
||||
RollBasicParts.restore(rollData)
|
||||
|
||||
const potential = ALL_ROLL_TYPES.find(m => m.code == rollData.type.current)?.code
|
||||
const allowed = rollData.type.retry && potential
|
||||
? [potential]
|
||||
: (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code))
|
||||
const rollType = allowed.find(c => c == rollData.type.current) ?? (allowed.length > 0 ? allowed[0].code : ROLL_TYPE_COMP);
|
||||
: (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code) ?? [ROLL_TYPE_COMP])
|
||||
const rollType = allowed.find(c => c == rollData.type.current) ?? allowed[0]
|
||||
|
||||
rollData.type.allowed = allowed
|
||||
rollData.type.current = rollType
|
||||
@@ -272,23 +284,30 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
rollData.options = rollData.options ?? { rollMode: game.settings.get("core", "rollMode") }
|
||||
|
||||
ROLL_PARTS.forEach(p => p.initialize(rollData))
|
||||
ROLL_PARTS.forEach(p => p.restore(rollData))
|
||||
ROLL_PARTS.filter(p => p.isValid(rollData))
|
||||
.forEach(p => {
|
||||
p.restore(rollData)
|
||||
p.loadRefs(rollData)
|
||||
p.prepareContext(rollData)
|
||||
})
|
||||
return rollData
|
||||
}
|
||||
|
||||
static saveParts(rollData) {
|
||||
const target = BASIC_PARTS.initFrom(rollData)
|
||||
static saveParts(rollData, impacts) {
|
||||
const target = RollBasicParts.initFrom(rollData)
|
||||
ROLL_PARTS.filter(p => p.isActive(rollData))
|
||||
.forEach(p => p.storeClean(rollData, target))
|
||||
target.attackerRoll = rollData.attackerRoll
|
||||
target.rolled = rollData.rolled
|
||||
target.result = rollData.result
|
||||
target.done = target.done ?? {}
|
||||
target.done = rollData.done ?? {}
|
||||
target.dmg = rollData.dmg
|
||||
if (impacts) {
|
||||
target.reverse = {
|
||||
active: impacts.active?.reverseImpacts(),
|
||||
opponent: impacts.opponent?.reverseImpacts()
|
||||
}
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
@@ -303,7 +322,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
...(rollOptions.callbacks ?? [])
|
||||
],
|
||||
customChatMessage: rollOptions.customChatMessage,
|
||||
onRollDone: rollOptions.onRollDone ?? doNothing
|
||||
onRollDone: rollOptions.onRollDone ?? RollDialog.onRollDoneDoNothing
|
||||
}
|
||||
this.chatRollResult = new ChatRollResult();
|
||||
this.selectType()
|
||||
@@ -324,16 +343,16 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
return ROLL_PARTS.filter(p => p.isActive(rollData))
|
||||
}
|
||||
|
||||
// get title() {
|
||||
// return this.rollData.title ?? `Jet de dés de ${this.rollData.active.actor.name}`
|
||||
// }
|
||||
|
||||
rollTitle(rollData) {
|
||||
return rollData.label ?? ROLL_PARTS
|
||||
const title = rollData.label ?? ROLL_PARTS
|
||||
.filter(it => it.section == ROLLDIALOG_SECTION.ACTION)
|
||||
.filter(it => it.isActive(rollData))
|
||||
.map(it => it.title(rollData))
|
||||
.reduce(Misc.joining(' '))
|
||||
.reduce(Misc.joining(' '));
|
||||
if (this.rollOptions.title) {
|
||||
return `${this.rollOptions.title} ${title}`
|
||||
}
|
||||
return title
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
@@ -368,7 +387,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
}
|
||||
|
||||
async buildHTMLTable(carac, diff) {
|
||||
return await foundry.applications.handlebars.renderTemplate('roll-table', { carac, diff })
|
||||
return await renderTemplate('roll-table', { carac, diff })
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
@@ -376,7 +395,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
|
||||
const types = ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData))
|
||||
.map(m => m.toTypeData(rollData))
|
||||
BASIC_PARTS.loadSurprises(rollData, this.getSelectedType().code)
|
||||
RollBasicParts.loadSurprises(rollData, this.getSelectedType().code)
|
||||
rollData.type.label = this.getSelectedType()?.title(rollData)
|
||||
//TOCHECK: set type.label ?
|
||||
const visibleRollParts = RollDialog.getActiveParts(rollData)
|
||||
@@ -422,33 +441,46 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
}
|
||||
|
||||
async roll() {
|
||||
// ROLL_PARTS.filter(p => p.isActive(this.rollData))
|
||||
// .forEach(p => p.validate(this.rollData))
|
||||
|
||||
const roll = RollDialog.saveParts(this.rollData)
|
||||
RollDialog.loadRollData(roll)
|
||||
this.loadRollData(roll)
|
||||
const selectedRollType = this.getSelectedType(roll);
|
||||
selectedRollType.onSelect(roll)
|
||||
roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1
|
||||
roll.rolled = await this.$rollDice(roll)
|
||||
roll.result = this.getSelectedType(roll).getResult(roll)
|
||||
console.info('RollDialog.roll:', roll)
|
||||
await Promise.all(this.rollOptions.callbacks.map(async callback => await callback(roll)))
|
||||
await this.chatRollResult.display(roll)
|
||||
roll.choix = {}
|
||||
roll.rolled = await RollDialogAdapter.rollDice(roll, this.rollTitle(roll))
|
||||
|
||||
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 impacts.active?.applyImpacts()
|
||||
await impacts.opponent?.applyImpacts()
|
||||
selectedRollType.onApplyImpacts(roll, impacts)
|
||||
await this.chatRollResult.display(roll, impacts)
|
||||
this.rollOptions.onRollDone(this)
|
||||
}
|
||||
|
||||
static loadRollData(roll) {
|
||||
loadRollData(roll) {
|
||||
RollDialog.$prepareRollData(roll)
|
||||
RollDialog.calculAjustements(roll)
|
||||
roll.v2 = true
|
||||
}
|
||||
|
||||
async defaultCallback(rollData, rolled) {
|
||||
await rollData.active.actor.appliquerAjoutExperience(rollData)
|
||||
await rollData.active.actor.appliquerAppelMoral(rollData)
|
||||
async defaultCallback(roll, rolled) {
|
||||
await roll.active.actor.appliquerAjoutExperience(roll)
|
||||
await roll.active.actor.appliquerAppelMoral(roll)
|
||||
}
|
||||
|
||||
async $rollDice(rollData) {
|
||||
return await RollDialogAdapter.rollDice(rollData, this.rollTitle(rollData))
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import { RdDBonus } from "../rdd-bonus.js"
|
||||
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"
|
||||
import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs"
|
||||
import { DIFF, ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs"
|
||||
import { PART_CARAC } from "./roll-part-carac.mjs"
|
||||
import { PART_COMP } from "./roll-part-comp.mjs"
|
||||
import { PART_DIFF } from "./roll-part-diff.mjs"
|
||||
import { RollPartSelect } from "./roll-part-select.mjs"
|
||||
import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
|
||||
|
||||
@@ -23,7 +23,8 @@ export class RollPartAttaque extends RollPartSelect {
|
||||
refs.attaques = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor))
|
||||
refs.tactiques = TACTIQUES
|
||||
if (refs.attaques.length > 0) {
|
||||
this.$selectAttaque(rollData)
|
||||
const attaque = this.findAttaque(refs.attaques, this.getSaved(rollData))
|
||||
this.$selectAttaque(rollData, attaque?.key)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,19 +34,34 @@ export class RollPartAttaque extends RollPartSelect {
|
||||
}
|
||||
|
||||
restore(rollData) {
|
||||
const saved = this.getSaved(rollData)
|
||||
super.restore(rollData)
|
||||
this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg
|
||||
if (saved.dmg) {
|
||||
this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg
|
||||
}
|
||||
}
|
||||
|
||||
findAttaque(attaques, saved) {
|
||||
return attaques.find(at => at.arme.id == saved?.arme?.id &&
|
||||
at.comp.id == saved?.comp?.id
|
||||
)
|
||||
}
|
||||
|
||||
choices(refs) { return refs.attaques }
|
||||
|
||||
static $extractAttaque(attaque, actor) {
|
||||
return {
|
||||
key: `${attaque.action}::${attaque.name}`,
|
||||
label: attaque.name,
|
||||
attaque: attaque,
|
||||
tactique: TACTIQUES[0],
|
||||
}
|
||||
// const extracted = foundry.utils.mergeObject({
|
||||
// key: `${attaque.action}::${attaque.label}`,
|
||||
// tactique: TACTIQUES[0]
|
||||
// },
|
||||
// attaque
|
||||
// )
|
||||
// return extracted
|
||||
// extracted.initialDiff = attaque.comp?.system.default_diffLibre ?? 0
|
||||
attaque.key = `${attaque.action}::${attaque.label}`
|
||||
attaque.tactique = TACTIQUES[0]
|
||||
attaque.initialDiff = attaque.comp?.system.default_diffLibre ?? 0
|
||||
return attaque
|
||||
}
|
||||
|
||||
prepareContext(rollData) {
|
||||
@@ -100,8 +116,14 @@ export class RollPartAttaque extends RollPartSelect {
|
||||
if (this.visible(rollData)) {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [current.attaque.carac.key])
|
||||
case PART_COMP: return part.filterComps(rollData, [current.attaque.comp?.name])
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [current.carac.key])
|
||||
case PART_COMP: return part.filterComps(rollData, [current.comp.name])
|
||||
case PART_DIFF: {
|
||||
if (current.initialDiff) {
|
||||
part.setDiff(rollData, { type: DIFF.ATTAQUE, value: current.initialDiff })
|
||||
current.initialDiff = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@@ -28,9 +28,7 @@ export class RollPartCheckbox extends RollPart {
|
||||
/* TODO: user setting? */
|
||||
current.checked = true
|
||||
}
|
||||
if (current.value == undefined) {
|
||||
current.value = this.getCheckboxValue(rollData)
|
||||
}
|
||||
current.value = this.getCheckboxValue(rollData)
|
||||
current.icon = this.getCheckboxIcon(rollData)
|
||||
}
|
||||
|
||||
|
@@ -17,7 +17,13 @@ export class RollPartComp extends RollPartSelect {
|
||||
|
||||
loadRefs(rollData) {
|
||||
const refs = this.getRefs(rollData)
|
||||
const selected = this.getSelected(rollData)
|
||||
refs.all = this.$getActorComps(rollData)
|
||||
.filter(comp => !selected.forced ||
|
||||
(selected.key ?
|
||||
Grammar.includesLowerCaseNoAccent(comp.name, selected.key)
|
||||
: comp.key == '')
|
||||
)
|
||||
refs.comps = refs.all
|
||||
this.$selectComp(rollData)
|
||||
}
|
||||
@@ -26,7 +32,7 @@ export class RollPartComp extends RollPartSelect {
|
||||
|
||||
$getActorComps(rollData) {
|
||||
const competences = (rollData.active.actor?.getCompetences() ?? [])
|
||||
.map(RollPartComp.$extractComp)
|
||||
.map(RollPartComp.extractComp)
|
||||
.sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label)))
|
||||
/* TODO: filter competences */
|
||||
const listCompetences = [
|
||||
@@ -36,7 +42,7 @@ export class RollPartComp extends RollPartSelect {
|
||||
return listCompetences
|
||||
}
|
||||
|
||||
static $extractComp(comp) {
|
||||
static extractComp(comp) {
|
||||
return {
|
||||
key: comp.name,
|
||||
label: comp.name,
|
||||
@@ -45,13 +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)
|
||||
const refs = this.getRefs(rollData)
|
||||
refs.comps = allowed.length > 0
|
||||
// ? refs.all.filter(it => allowed.includes(Grammar.toLowerCaseNoAccent(it.label)))
|
||||
? refs.all.filter(it => allowed.includes(it.label))
|
||||
? refs.all.filter(it => allowed.includes(it.label) || (sans && it.key == ''))
|
||||
: refs.all
|
||||
if (sorting && refs.comps.length > 0) {
|
||||
refs.comps.sort(sorting)
|
||||
}
|
||||
this.$selectComp(rollData)
|
||||
}
|
||||
|
||||
@@ -60,7 +69,7 @@ export class RollPartComp extends RollPartSelect {
|
||||
}
|
||||
|
||||
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)))
|
||||
}
|
||||
|
||||
|
174
module/roll/roll-part-cuisine.mjs
Normal file
@@ -0,0 +1,174 @@
|
||||
import { ITEM_TYPES } from "../constants.js"
|
||||
import { CARACS } from "../rdd-carac.js"
|
||||
import { ROLL_TYPE_CUISINE } from "./roll-constants.mjs"
|
||||
import { PART_CARAC } from "./roll-part-carac.mjs"
|
||||
import { PART_COMP } from "./roll-part-comp.mjs"
|
||||
import { RollPartSelect } from "./roll-part-select.mjs"
|
||||
import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
|
||||
|
||||
export const PART_CUISINE = "cuisine"
|
||||
|
||||
export class RollPartCuisine extends RollPartSelect {
|
||||
onReady() {
|
||||
foundry.applications.handlebars.loadTemplates({ 'roll-oeuvre-recettecuisine': `systems/foundryvtt-reve-de-dragon/templates/roll/roll-oeuvre-recettecuisine.hbs` })
|
||||
}
|
||||
|
||||
get code() { return PART_CUISINE }
|
||||
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
||||
|
||||
isValid(rollData) { return rollData.active.actor.isPersonnage() }
|
||||
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_CUISINE) }
|
||||
|
||||
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)
|
||||
const actor = rollData.active.actor
|
||||
refs.cuisine = actor.getCompetence('Cuisine')
|
||||
|
||||
const recettes = actor.items
|
||||
.filter(it => it.type == ITEM_TYPES.recettecuisine)
|
||||
.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)
|
||||
}
|
||||
}
|
||||
|
||||
$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
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
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,
|
||||
fabriquer: true,
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
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 current = this.getCurrent(rollDialog.rollData)
|
||||
|
||||
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.$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)) {
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.ODORATGOUT])
|
||||
case PART_COMP: return part.filterComps(rollData, [this.getRefs(rollData).cuisine.name])
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
}
|
@@ -34,7 +34,7 @@ export class RollPartDefense extends RollPartSelect {
|
||||
.map(it => RollPartDefense.$extractEsquive(it, defenseur))
|
||||
|
||||
const parades = defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier()))
|
||||
.map(it => RollPartDefense.$extractParade(it, attackerRoll?.attaque.arme, defenseur))
|
||||
.map(it => RollPartDefense.$extractParade(it, attackerRoll?.arme, defenseur))
|
||||
|
||||
refs.defenses = [...esquives, ...parades].filter(it => it != undefined)
|
||||
this.$selectDefense(rollData)
|
||||
@@ -113,17 +113,16 @@ export class RollPartDefense extends RollPartSelect {
|
||||
isArmeDisparate(rollData) {
|
||||
const armeDefense = this.getCurrent(rollData).arme
|
||||
if (armeDefense) {
|
||||
const armeAttaque = rollData.attackerRoll?.attaque.arme
|
||||
const armeAttaque = rollData.attackerRoll?.arme
|
||||
return RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) == 'sign'
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
getDiffDefense(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
const refs = this.getRefs(rollData)
|
||||
if (refs.isDistance || !rollData.attackerRoll) {
|
||||
// Déterminer la difficulté de parade
|
||||
// TODO: Déterminer la difficulté de parade
|
||||
return { diff: 0, type: DIFF.LIBRE }
|
||||
}
|
||||
else {
|
||||
|
@@ -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 { Misc } from "../misc.js";
|
||||
|
||||
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 {
|
||||
|
||||
@@ -51,10 +56,10 @@ export class RollPartDiff extends RollPart {
|
||||
)
|
||||
}
|
||||
|
||||
setDiff(rollData, diffDefense) {
|
||||
setDiff(rollData, diff) {
|
||||
const current = this.getCurrent(rollData)
|
||||
current.value = diffDefense.diff
|
||||
current.type = diffDefense.type
|
||||
current.value = diff.diff ?? current.value
|
||||
current.type = diff.type ?? current.type
|
||||
}
|
||||
|
||||
getAjustements(rollData) {
|
||||
|
@@ -1,15 +1,16 @@
|
||||
import { Grammar } from "../grammar.js"
|
||||
import { ITEM_TYPES } from "../constants.js"
|
||||
import { CARACS } from "../rdd-carac.js"
|
||||
import { ROLL_TYPE_JEU } from "./roll-constants.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 { ROLLDIALOG_SECTION } from "./roll-part.mjs"
|
||||
import { RdDItem } from "../item.js"
|
||||
import { Misc } from "../misc.js"
|
||||
|
||||
export const PART_JEU = "jeu"
|
||||
|
||||
const COMPETENCE_JEU = 'Jeu'
|
||||
export const COMPETENCE_JEU = 'Jeu'
|
||||
|
||||
export class RollPartJeu extends RollPartSelect {
|
||||
|
||||
@@ -21,8 +22,12 @@ export class RollPartJeu extends RollPartSelect {
|
||||
|
||||
loadRefs(rollData) {
|
||||
const refs = this.getRefs(rollData)
|
||||
refs.jeux = rollData.active.actor.itemTypes[ITEM_TYPES.jeu]
|
||||
.map(it => RollPartJeu.$extractJeu(it, rollData.active.actor))
|
||||
const actor = 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) {
|
||||
this.$selectJeu(rollData)
|
||||
}
|
||||
@@ -30,18 +35,17 @@ export class RollPartJeu extends RollPartSelect {
|
||||
|
||||
choices(refs) { return refs.jeux }
|
||||
|
||||
static $extractJeu(jeu, actor) {
|
||||
const comp = actor.getCompetence(COMPETENCE_JEU)
|
||||
static $extractJeu(jeu, compJeu) {
|
||||
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 {
|
||||
key: jeu.id,
|
||||
label: jeu.name,
|
||||
caracs: caracs,
|
||||
jeu: jeu,
|
||||
value: (base ?? comp).system.niveau,
|
||||
value: 0,
|
||||
base: base,
|
||||
comp: comp
|
||||
comp: compJeu
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,10 +53,10 @@ export class RollPartJeu extends RollPartSelect {
|
||||
if (jeu.system.base < comp.system.niveau) {
|
||||
return undefined
|
||||
}
|
||||
return {
|
||||
return new RdDItem({
|
||||
id: comp.id,
|
||||
name: `Jeu ${jeu.name}`,
|
||||
type: comp.type,
|
||||
name: `Jeu ${Misc.lowerFirst(jeu.name)}`,
|
||||
type: ITEM_TYPES.competence,
|
||||
img: comp.img,
|
||||
system: foundry.utils.mergeObject(
|
||||
{
|
||||
@@ -61,9 +65,9 @@ export class RollPartJeu extends RollPartSelect {
|
||||
default_carac: caracs.length > 0 ? caracs[0] : CARACS.CHANCE
|
||||
},
|
||||
comp.system,
|
||||
{ inplace: true, overwrite: false }
|
||||
{ overwrite: false }
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
prepareContext(rollData) {
|
||||
@@ -77,6 +81,13 @@ export class RollPartJeu extends RollPartSelect {
|
||||
|
||||
$selectJeu(rollData, key) {
|
||||
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) {
|
||||
@@ -95,7 +106,7 @@ export class RollPartJeu extends RollPartSelect {
|
||||
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_COMP: return part.filterComps(rollData, [current.comp?.name])
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@@ -11,26 +11,41 @@ import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
|
||||
|
||||
export const PART_MEDITATION = "meditation"
|
||||
|
||||
const COMPORTEMENTS = ['isComportement', 'isHeure', 'isPurification', 'isVeture']
|
||||
|
||||
export class RollPartMeditation extends RollPartSelect {
|
||||
|
||||
get code() { return PART_MEDITATION }
|
||||
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
||||
|
||||
store(rollData, targetData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
this.setSaved(targetData, {
|
||||
key: current.key,
|
||||
isComportement: current.isComportement,
|
||||
isHeure: current.isHeure,
|
||||
isPurification: current.isPurification,
|
||||
isVeture: current.isVeture
|
||||
})
|
||||
}
|
||||
|
||||
isValid(rollData) { return rollData.active.actor.isPersonnage() && rollData.active.actor.isHautRevant() }
|
||||
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_MEDITATION) }
|
||||
|
||||
loadRefs(rollData) {
|
||||
const refs = this.getRefs(rollData)
|
||||
foundry.utils.mergeObject(refs,
|
||||
{
|
||||
meditations: rollData.active.actor.itemTypes[ITEM_TYPES.meditation]
|
||||
.map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor))
|
||||
}
|
||||
)
|
||||
refs.meditations = rollData.active.actor.itemTypes[ITEM_TYPES.meditation]
|
||||
.map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor))
|
||||
|
||||
if (refs.meditations.length > 0) {
|
||||
this.$selectMeditation(rollData)
|
||||
this.$selectConditionMeditation(rollData)
|
||||
const selected = this.getSelected(rollData)
|
||||
const current = this.getCurrent(rollData)
|
||||
COMPORTEMENTS.filter(it => selected[it]).forEach(it => current[it] = selected[it])
|
||||
}
|
||||
}
|
||||
|
||||
choices(refs) { return refs.meditations }
|
||||
|
||||
static $extractMeditation(meditation, actor) {
|
||||
@@ -48,12 +63,7 @@ export class RollPartMeditation extends RollPartSelect {
|
||||
|
||||
getMalusConditions(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
const conditionsManquantes = [
|
||||
current.isComportement,
|
||||
current.isHeure,
|
||||
current.isPurification,
|
||||
current.isVeture
|
||||
].filter(it => !it).length
|
||||
const conditionsManquantes = COMPORTEMENTS.filter(it => !current[it]).length
|
||||
return -2 * conditionsManquantes
|
||||
}
|
||||
|
||||
@@ -71,13 +81,18 @@ export class RollPartMeditation extends RollPartSelect {
|
||||
const previous = this.getCurrent(rollData)
|
||||
const current = this.selectByKey(rollData, key, 0)
|
||||
if (current.key != previous.key) {
|
||||
const heureMonde = RdDTimestamp.getWorldTime().heure
|
||||
const heureMeditation = RdDTimestamp.findHeure(current.meditation.system.heure)?.heure
|
||||
current.isHeure = heureMeditation == heureMonde
|
||||
current.isTMR = Grammar.equalsInsensitive(current.meditation.system.tmr, TMRUtility.getTMRType(rollData.active.actor.system.reve.tmrpos.coord))
|
||||
this.$selectConditionMeditation(rollData)
|
||||
}
|
||||
}
|
||||
|
||||
$selectConditionMeditation(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
current.heureMonde = RdDTimestamp.getWorldTime().heure
|
||||
current.heureMeditation = RdDTimestamp.findHeure(current.meditation.system.heure)?.heure
|
||||
current.isHeure = current.heureMeditation == current.heureMonde
|
||||
current.isTMR = Grammar.equalsInsensitive(current.meditation.system.tmr, TMRUtility.getTMRType(rollData.active.actor.system.reve.tmrpos.coord))
|
||||
}
|
||||
|
||||
async _onRender(rollDialog, context, options) {
|
||||
|
||||
const selectMeditation = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-meditation"]`)
|
||||
@@ -88,10 +103,7 @@ export class RollPartMeditation extends RollPartSelect {
|
||||
rollDialog.render()
|
||||
})
|
||||
|
||||
this.setupListenerCondition(rollDialog, 'isComportement')
|
||||
this.setupListenerCondition(rollDialog, 'isHeure')
|
||||
this.setupListenerCondition(rollDialog, 'isPurification')
|
||||
this.setupListenerCondition(rollDialog, 'isVeture')
|
||||
COMPORTEMENTS.forEach(it => this.setupListenerCondition(rollDialog, it))
|
||||
}
|
||||
|
||||
setupListenerCondition(rollDialog, inputName) {
|
||||
@@ -108,7 +120,7 @@ export class RollPartMeditation extends RollPartSelect {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.INTELLECT])
|
||||
case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
|
||||
case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@@ -11,6 +11,7 @@ export const PART_OEUVRE = "oeuvre"
|
||||
|
||||
const ARTS = [
|
||||
{ type: ITEM_TYPES.oeuvre, action: "interpréte l'oeuvre", competence: it => it.system.competence, caracs: it => [it.system.default_carac] },
|
||||
{ type: ITEM_TYPES.musique, action: "joue le morceau:", competence: it => 'Musique', caracs: it => [CARACS.OUIE] },
|
||||
{ type: ITEM_TYPES.chant, action: "chante", competence: it => 'Chant', caracs: it => [CARACS.OUIE] },
|
||||
{
|
||||
type: ITEM_TYPES.danse, action: "danse:", competence: it => 'Danse', caracs: it => {
|
||||
@@ -20,8 +21,6 @@ const ARTS = [
|
||||
return caracs
|
||||
}
|
||||
},
|
||||
{ type: ITEM_TYPES.musique, action: "joue le morceau:", competence: it => 'Musique', caracs: it => [CARACS.OUIE] },
|
||||
{ type: ITEM_TYPES.recettecuisine, action: "cuisine le plat:", competence: it => 'Cuisine', caracs: it => [CARACS.ODORATGOUT] },
|
||||
]
|
||||
|
||||
export class RollPartOeuvre extends RollPartSelect {
|
||||
|
@@ -27,7 +27,7 @@ export class RollPartSelect extends RollPart {
|
||||
const current = this.getCurrent(rollData)
|
||||
const newChoice = (choices.length == 0)
|
||||
? { 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)
|
||||
return newChoice
|
||||
}
|
||||
|
@@ -11,9 +11,11 @@ import { CARACS } from "../rdd-carac.js"
|
||||
export const PART_SORT = "sort"
|
||||
|
||||
export class RollPartSort extends RollPartSelect {
|
||||
|
||||
onReady() {
|
||||
// TODO: utiliser un hook pour écouter les déplacements dans les TMRs?
|
||||
}
|
||||
|
||||
get code() { return PART_SORT }
|
||||
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
||||
|
||||
@@ -23,7 +25,7 @@ export class RollPartSort extends RollPartSelect {
|
||||
loadRefs(rollData) {
|
||||
const refs = this.getRefs(rollData)
|
||||
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]
|
||||
.map(s => RollPartSort.$extractSort(s, coord, draconics))
|
||||
|
||||
@@ -120,7 +122,7 @@ export class RollPartSort extends RollPartSelect {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (part.code) {
|
||||
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
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { ITEM_TYPES } from "../constants.js"
|
||||
import { Grammar } from "../grammar.js"
|
||||
import { ROLL_TYPE_TACHE } from "./roll-constants.mjs"
|
||||
import { PART_CARAC } from "./roll-part-carac.mjs"
|
||||
import { PART_COMP } from "./roll-part-comp.mjs"
|
||||
@@ -18,13 +17,17 @@ export class RollPartTache extends RollPartSelect {
|
||||
|
||||
loadRefs(rollData) {
|
||||
const refs = this.getRefs(rollData)
|
||||
refs.taches = rollData.active.actor.itemTypes[ITEM_TYPES.tache]
|
||||
const selected = this.getSelected(rollData)
|
||||
refs.all = rollData.active.actor.itemTypes[ITEM_TYPES.tache]
|
||||
.filter(tache => !selected.forced || tache.id == selected.key)
|
||||
.filter(tache => tache.system.points_de_tache_courant < tache.system.points_de_tache)
|
||||
.map(tache => RollPartTache.$extractTache(tache, rollData.active.actor))
|
||||
refs.taches = refs.all
|
||||
if (refs.taches.length > 0) {
|
||||
this.$selectTache(rollData)
|
||||
}
|
||||
}
|
||||
|
||||
choices(refs) { return refs.taches }
|
||||
|
||||
static $extractTache(tache, actor) {
|
||||
|
@@ -43,6 +43,7 @@ export class RollPart {
|
||||
}
|
||||
|
||||
/** les informations minimales représentant la sélection dans le rollData permettant de restaurer la fenêtre */
|
||||
getSelected(rollData) { return this.getSaved(rollData) }
|
||||
getSaved(rollData) {
|
||||
return rollData.selected[this.code] ?? {}
|
||||
}
|
||||
@@ -84,9 +85,9 @@ export class RollPart {
|
||||
loadRefs(rollData) { }
|
||||
|
||||
prepareContext(rollData) { }
|
||||
|
||||
|
||||
/** permet de sauvegarder dans rollData les informations (cas des champs edit) */
|
||||
validate(rollData) {}
|
||||
validate(rollData) { }
|
||||
|
||||
/** ---- cross roll-part filtering ---- */
|
||||
applyImpact(rollData, filter) { }
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { DIFF, ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs"
|
||||
import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
|
||||
import { RollType } from "./roll-type.mjs"
|
||||
|
||||
export class RollTypeAttaque extends RollType {
|
||||
@@ -10,4 +11,5 @@ export class RollTypeAttaque extends RollType {
|
||||
onSelect(rollData) {
|
||||
this.setDiffType(rollData, DIFF.ATTAQUE)
|
||||
}
|
||||
|
||||
}
|
@@ -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"
|
||||
|
||||
export class RollTypeComp extends RollType {
|
||||
@@ -7,4 +7,9 @@ export class RollTypeComp extends RollType {
|
||||
|
||||
title(rollData) { return `fait un jet ${rollData.type.opposed ? ' contre ' : ''}` }
|
||||
|
||||
|
||||
onSelect(rollData) {
|
||||
this.setDiffType(rollData, DIFF.LIBRE)
|
||||
}
|
||||
|
||||
}
|
84
module/roll/roll-type-cuisine.mjs
Normal file
@@ -0,0 +1,84 @@
|
||||
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"
|
||||
|
||||
export class RollTypeCuisine extends RollType {
|
||||
get code() { return ROLL_TYPE_CUISINE }
|
||||
get name() { return `Interpréter une oeuvre` }
|
||||
|
||||
visible(rollData) { return rollData.active.actor.isPersonnage() }
|
||||
title(rollData) {
|
||||
const current = rollData.current[PART_CUISINE]
|
||||
return current.recette ? `prépare une recette: ${current.label}` : `prépare: ${current.label}`
|
||||
}
|
||||
|
||||
onSelect(rollData) {
|
||||
this.setDiffType(rollData, DIFF.AUCUN)
|
||||
}
|
||||
|
||||
getResult(rollData, impacts) {
|
||||
const current = rollData.current[PART_CUISINE]
|
||||
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()
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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 { ROLL_TYPE_JEU } from "./roll-constants.mjs"
|
||||
import { DIFF, ROLL_TYPE_JEU } from "./roll-constants.mjs"
|
||||
|
||||
|
||||
export class RollTypeJeu extends RollType {
|
||||
get code() { return ROLL_TYPE_JEU }
|
||||
@@ -14,4 +15,9 @@ export class RollTypeJeu extends RollType {
|
||||
return `joue: ${rollData.current[PART_JEU].label}`
|
||||
}
|
||||
|
||||
onSelect(rollData) {
|
||||
this.setDiffType(rollData, DIFF.LIBRE)
|
||||
RollPartJeu.forceCompJeu(rollData)
|
||||
}
|
||||
|
||||
}
|
@@ -1,3 +1,4 @@
|
||||
import { RdDItemSigneDraconique } from "../item/signedraconique.js"
|
||||
import { DIFF, ROLL_TYPE_MEDITATION } from "./roll-constants.mjs"
|
||||
import { PART_MEDITATION } from "./roll-part-meditation.mjs"
|
||||
import { RollType } from "./roll-type.mjs"
|
||||
@@ -16,4 +17,21 @@ export class RollTypeMeditation extends RollType {
|
||||
onSelect(rollData) {
|
||||
this.setDiffType(rollData, DIFF.AUCUN)
|
||||
}
|
||||
|
||||
callbacks(rollOptions) { return [RollTypeMeditation.$onRollMeditation] }
|
||||
|
||||
static async $onRollMeditation(rollData) {
|
||||
const actor = rollData.active.actor
|
||||
const meditation = rollData.current.meditation.meditation
|
||||
const rolled = rollData.rolled
|
||||
if (meditation && rolled) {
|
||||
if (rolled.isSuccess) {
|
||||
await actor.createEmbeddedDocuments("Item", [RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditation, rolled)])
|
||||
}
|
||||
if (rolled.isEPart) {
|
||||
await actor.updateEmbeddedDocuments('Item', [{ _id: meditation._id, 'system.malus': meditation.system.malus - 1 }])
|
||||
}
|
||||
await actor.santeIncDec("fatigue", 2)
|
||||
}
|
||||
}
|
||||
}
|
@@ -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: []
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
import { ITEM_TYPES } from "../constants.js"
|
||||
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"
|
||||
import { DIFF, ROLL_TYPE_TACHE } from "./roll-constants.mjs"
|
||||
import { PART_TACHE } from "./roll-part-tache.mjs"
|
||||
import { RollType } from "./roll-type.mjs"
|
||||
@@ -16,4 +18,26 @@ export class RollTypeTache extends RollType {
|
||||
onSelect(rollData) {
|
||||
this.setDiffType(rollData, DIFF.AUCUN)
|
||||
}
|
||||
|
||||
callbacks(rollOptions) { return [ async r => await RollTypeTache.$onRollTache(r, rollOptions)] }
|
||||
|
||||
static async $onRollTache(rollData, rollOptions) {
|
||||
const actor = rollData.active.actor
|
||||
const tache = rollData.current[PART_TACHE].tache
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
await actor.santeIncDec("fatigue", tache.system.fatigue)
|
||||
}
|
||||
|
||||
rollData.current[PART_TACHE].tache = await tache.update({
|
||||
'system.points_de_tache_courant': tache.system.points_de_tache_courant + rollData.rolled.ptTache,
|
||||
'system.nb_jet_succes': tache.system.nb_jet_succes + (rollData.rolled.isSuccess ? 1 : 0),
|
||||
'system.nb_jet_echec': tache.system.nb_jet_echec + (rollData.rolled.isSuccess ? 0 : 1),
|
||||
'system.difficulte': tache.system.difficulte - (rollData.rolled.isETotal ? 1 : 0),
|
||||
}, {render:true})
|
||||
|
||||
|
||||
if (rollOptions?.onRollAutomate) {
|
||||
await rollOptions.onRollAutomate(rollData)
|
||||
}
|
||||
}
|
||||
}
|
@@ -11,14 +11,13 @@ export class RollType {
|
||||
get name() { return this.code }
|
||||
get icon() { return `systems/foundryvtt-reve-de-dragon/assets/actions/${this.code}.svg` }
|
||||
get chatResultTemplate() { return `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${this.code}.hbs` }
|
||||
|
||||
|
||||
toTypeData(rollData) {
|
||||
return { code: this.code, name: this.name, icon: this.icon, section: 'type', template: this.template, selected: this.isSelected(rollData) }
|
||||
}
|
||||
|
||||
isAllowed(rollData) { return rollData.type.allowed == undefined || rollData.type.allowed.includes(this.code) }
|
||||
visible(rollData) { return true }
|
||||
|
||||
title(rollData) { return this.code }
|
||||
isSelected(rollData) { return rollData.type.current == this.code }
|
||||
|
||||
@@ -33,11 +32,10 @@ export class RollType {
|
||||
this.typeFromOpponents(rollData),
|
||||
rollData.selected[PART_DIFF].type
|
||||
]
|
||||
const type = possibleTypes.find(m => DEFAULT_DIFF_TYPES.includes(m)) ??DIFF.DEFAUT
|
||||
const type = possibleTypes.find(m => DEFAULT_DIFF_TYPES.includes(m)) ?? DIFF.DEFAUT
|
||||
this.setDiffType(rollData, type)
|
||||
}
|
||||
|
||||
|
||||
typeFromOpponents(rollData) {
|
||||
if (rollData.type.opposed) {
|
||||
if (rollData.type.resistance) {
|
||||
@@ -53,7 +51,16 @@ export class RollType {
|
||||
this.setRollDataType(rollData)
|
||||
}
|
||||
|
||||
getResult(rollData){
|
||||
return undefined
|
||||
}
|
||||
callbacks(rollOptions) { return [] }
|
||||
|
||||
/**
|
||||
* 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) { }
|
||||
}
|
||||
|
@@ -50,7 +50,7 @@ export class OptionsAvancees extends FormApplication {
|
||||
.map(it => {
|
||||
it = foundry.utils.duplicate(it)
|
||||
it.id = OptionsAvancees._getId(it.name)
|
||||
it.active = OptionsAvancees.isSet(it.name)
|
||||
it.active = OptionsAvancees.isUsing(it.name)
|
||||
return it
|
||||
})
|
||||
formData.regles = regles
|
||||
@@ -63,10 +63,6 @@ export class OptionsAvancees extends FormApplication {
|
||||
}
|
||||
|
||||
static isUsing(name) {
|
||||
return OptionsAvancees.isSet(name)
|
||||
}
|
||||
|
||||
static isSet(name) {
|
||||
return game.settings.get(SYSTEM_RDD, OptionsAvancees._getId(name))
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { ChatUtility } from "../chat-utility.js";
|
||||
import { HIDE_DICE, SYSTEM_RDD } from "../constants.js";
|
||||
import { HIDE_DICE, renderTemplate, SYSTEM_RDD } from "../constants.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { RdDItem } from "../item.js";
|
||||
import { Misc } from "../misc.js";
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "../constants.js";
|
||||
|
||||
export class DialogChateauDormant extends Dialog {
|
||||
|
||||
@@ -9,7 +10,7 @@ export class DialogChateauDormant extends Dialog {
|
||||
motifStress: `Nuit du ${date}`,
|
||||
finChateauDormant: game.system.rdd.calendrier.getTimestampFinChateauDormant()
|
||||
};
|
||||
const html = await foundry.applications.handlebars.renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-chateau-dormant.hbs",
|
||||
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-chateau-dormant.hbs",
|
||||
dialogData);
|
||||
|
||||
new DialogChateauDormant(dialogData, html)
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "../constants.js";
|
||||
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||
import { EffetsDraconiques } from "../tmr/effets-draconiques.js";
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "../constants.js";
|
||||
|
||||
export class DialogStress extends Dialog {
|
||||
|
||||
|
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,7 +1,10 @@
|
||||
/**
|
||||
* 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 ? TokenActor.fromToken(token) : TokenActor.fromActor(actor)
|
||||
}
|
||||
|
||||
static fromActorId(actorId, onError = () => undefined) {
|
||||
actorId = actorId ?? (canvas.tokens.controlled.length > 0
|
||||
@@ -16,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) {
|
@@ -4,7 +4,7 @@ import { RdDResolutionTable } from "../rdd-resolution-table.js";
|
||||
import { RdDDice } from "../rdd-dice.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { DialogChronologie } from "../dialog-chronologie.js";
|
||||
import { HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { HIDE_DICE, renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js";
|
||||
import { DialogChateauDormant } from "../sommeil/dialog-chateau-dormant.js";
|
||||
import { APP_ASTROLOGIE_REFRESH, AppAstrologie } from "../sommeil/app-astrologie.js";
|
||||
|