Merge pull request 'v13.0.14 - Le familier d'Illysis' (#779) from VincentVk/foundryvtt-reve-de-dragon:v13 into v13
Reviewed-on: #779
This commit is contained in:
		
							
								
								
									
										1
									
								
								assets/actions/armes-disparates.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								assets/actions/armes-disparates.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,0)" style=""><path d="m329.5 29.12-8.1 11.4L359 67.16l8.1-11.44zm-88 5.04 24.2 45.36 1.8 1.29 14.8-40.36zm57.6 12.63-16.4 44.8 40.7 28.81 35.3-31.54c-.9-.58-1.9-1.19-2.8-1.84zM59.83 48.56l10.84 45.83 29.63 2.6 2.7-29.63zM470.9 75.41c-5.6 4.71-12.2 8.59-19.5 11.74 5 46.45-14.7 83.45-45.2 109.75-26.5 22.9-60.9 38.4-95 47.9-2.5 4.8-5 9.2-7.4 13.1 41.5 5.4 93.2-21.2 129.2-60 19.8-21.3 34.8-45.9 41.1-69.2 5.2-19.4 4.7-37.42-3.2-53.29zm-351.3 8.71-3 32.48-32.35-2.9 226.55 271 20-16.7 15.3-12.8zM434 93.09c-4.2 1-8.5 2-12.8 2.7-14.9 2.5-30.1 3.1-43.5.3l-41 36.61c4 7 5 15.7 4.5 24.5-.6 12.6-4.3 26.7-9.3 40.9-3 8.3-6.3 16.6-9.9 24.6 26.9-9.2 52.6-22.3 72.5-39.4 26.2-22.8 42.5-51.6 39.5-90.21zM274 107.4l-51.2 72.2 30.6 36.5 58.2-82.1zM173.8 248.8 34.53 445.2l37.53 26.6L204.3 285.3zm233 79.2L273.3 439.5l19.2 23.1L426 351zm-18.3 77.9-35.3 29.4 39.7 47.6 35.3-29.4z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||
| After Width: | Height: | Size: 1.0 KiB | 
							
								
								
									
										1
									
								
								assets/actions/empoignade.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								assets/actions/empoignade.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,0)" style=""><path d="M243.512 23.29c-27.105 18.337-53.533 32.92-82.274 45.337-2.843 17.364-3.948 34.497-4.05 51.584 28.913 15.41 56.096 32.85 83.33 49.634l7.045 4.344-3.432 7.482c-12.12 26.572-24.33 47.087-46.245 70.3l-5.184 5.512-6.46-3.904c-32.974-19.974-74.472-38.724-113.373-53.95l6.826-17.374c36.79 14.4 75.11 32.32 108.153 51.504 15.396-17.198 25.326-33.354 34.713-52.89-43.44-26.91-86.13-53.51-134.69-70.632-23.012 20.357-37.705 45.243-51.942 70.74 8.324 25.495 6.596 53.376-6.596 77.46 48.58-.593 97.994 2.23 150.666 10.26l5.658.837 1.787 5.44c8.85 26.46 11.79 54.41 8.325 83.588l-.987 8.432-8.466-.187c-40.508-.864-80.175-2.138-118.17.234 1.634 15.94-2.31 30.972-7.724 45.025 13.427 28.54 27.38 55.8 48.29 79.39 41.27-19.05 73.564-31.288 115.93-42.85-3.407-13.72-6.918-26.36-11.097-33.62-5.122-8.9-10.207-13.057-17.85-15.256-15.284-4.4-44.533 2.293-92.894 19.454l-6.243-17.594c48.907-17.354 79.702-26.894 104.283-19.82 9.133 2.628 16.884 8.004 23.066 15.46 14.487-7.627 28.415-16.79 42.053-26.996 12.34-45.92 37.29-81.42 66.626-112.107-7.226-13.52-13.208-27.204-20.563-40.613l-3.394-6.168 5-4.965c23.275-23.13 47.34-40.157 71.87-52.487l8.395 16.716c-20.952 10.53-41.503 25.913-61.795 45.152 12.41 23.91 22.263 45.5 39.457 64.826 37.488-27.124 74.943-51.39 116.84-74.938-13.96-30.473-31.345-58.357-56.286-79.462-32.2 13.38-62.527 17.39-92.61 12.29-14.223 13.25-30.094 22.23-48.756 23.337-29.017 1.722-60.74-15.74-99.174-57.672l6.858-6.295.017-.028.006.006 6.88-6.314c36.702 40.043 63.74 52.87 84.32 51.65 18.514-1.1 35.03-14.95 51.684-35.406-28.827-31.81-64.174-59.94-97.822-84.465zM39.324 277.884c-6.06.022-12.104.098-18.142.223 1.673 26.288 5.512 51.288 14.052 73.732 45.88-5.82 93.308-4.96 141.15-3.87 1.518-21.27-.253-41.69-6.058-61.212-45.528-6.565-88.59-9.03-131.002-8.873z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||
| After Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB | 
							
								
								
									
										65
									
								
								assets/actions/surenc.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								assets/actions/surenc.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    viewBox="0 0 448 434" | ||||
|    version="1.1" | ||||
|    id="svg6" | ||||
|    sodipodi:docname="surenc.svg" | ||||
|    width="448" | ||||
|    height="434" | ||||
|    inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> | ||||
|   <metadata | ||||
|      id="metadata12"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <defs | ||||
|      id="defs10" /> | ||||
|   <sodipodi:namedview | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1" | ||||
|      objecttolerance="10" | ||||
|      gridtolerance="10" | ||||
|      guidetolerance="10" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:window-width="3840" | ||||
|      inkscape:window-height="2054" | ||||
|      id="namedview8" | ||||
|      showgrid="false" | ||||
|      fit-margin-top="0" | ||||
|      fit-margin-left="0" | ||||
|      fit-margin-right="0" | ||||
|      fit-margin-bottom="0" | ||||
|      inkscape:zoom="1.4355469" | ||||
|      inkscape:cx="224" | ||||
|      inkscape:cy="210" | ||||
|      inkscape:window-x="-11" | ||||
|      inkscape:window-y="-11" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:current-layer="svg6" /> | ||||
|   <g | ||||
|      class="" | ||||
|      id="g4" | ||||
|      transform="translate(-32,-46)"> | ||||
|     <path | ||||
|        d="m 256,46 c -45.074,0 -82,36.926 -82,82 0,25.812 12.123,48.936 30.938,64 H 128 L 32,480 H 480 L 384,192 H 307.062 C 325.877,176.936 338,153.812 338,128 338,82.926 301.074,46 256,46 Z m 0,36 c 25.618,0 46,20.382 46,46 0,25.618 -20.382,46 -46,46 -25.618,0 -46,-20.382 -46,-46 0,-25.618 20.382,-46 46,-46 z m -82.215,202.95 h 23.5 v 33.263 l 33.873,-33.264 h 27.283 l -43.883,43.15 48.4,47.974 H 233.54 l -36.255,-35.888 v 35.888 h -23.5 z m 119.934,21.24 c 4.76,0 8.952,0.934 12.573,2.806 3.62,1.872 6.938,4.82 9.95,8.85 v -10.13 h 21.972 v 61.462 c 0,10.986 -3.48,19.368 -10.438,25.146 -6.917,5.82 -16.968,8.727 -30.152,8.727 -4.272,0 -8.4,-0.325 -12.39,-0.976 a 77.367,77.367 0 0 1 -12.024,-2.99 v -17.03 c 3.826,2.198 7.57,3.826 11.23,4.884 3.664,1.098 7.347,1.648 11.05,1.648 7.162,0 12.41,-1.566 15.746,-4.7 3.337,-3.132 5.006,-8.035 5.006,-14.708 v -4.7 c -3.01,3.986 -6.328,6.916 -9.95,8.788 -3.62,1.87 -7.813,2.808 -12.573,2.808 -8.343,0 -15.238,-3.275 -20.69,-9.826 -5.453,-6.592 -8.18,-14.974 -8.18,-25.146 0,-10.214 2.727,-18.576 8.18,-25.086 5.452,-6.55 12.347,-9.827 20.69,-9.827 z m 8.118,15.746 c -4.517,0 -8.038,1.67 -10.56,5.005 -2.523,3.338 -3.784,8.058 -3.784,14.162 0,6.266 1.22,11.026 3.662,14.28 2.442,3.215 6.003,4.823 10.682,4.823 4.557,0 8.096,-1.67 10.62,-5.006 2.522,-3.337 3.784,-8.036 3.784,-14.098 0,-6.104 -1.262,-10.824 -3.785,-14.16 -2.523,-3.337 -6.062,-5.006 -10.62,-5.006 z" | ||||
|        fill="#ffffff" | ||||
|        fill-opacity="1" | ||||
|        id="path2" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.1 KiB | 
							
								
								
									
										25
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,4 +1,29 @@ | ||||
| # 13.0 | ||||
| ## 13.0.14 - Le familier d'Illysis | ||||
|  | ||||
| - Les réussites particulières en demi-surprise sont de simples réussites | ||||
| - Les images des scènes par défaut sont corrigées | ||||
| - Ajout d'une image de status "sur-encombré" | ||||
| - Correction V13 | ||||
|   - couleur lisible dans les sommaires des journaux et des compendiums | ||||
| - Amélioration des entités: | ||||
|   - l'attaquant ne sait plus que c'est une entité de cauchemar (surprise!) | ||||
|   - l'encaissement indique une blessure dans le tchat... même si ce n'est que de l'endurance | ||||
|   - les blurettes suivent les règles des entités de cauchemar (p322) | ||||
| - Nouvelle fenêtre de jets de dés | ||||
|   - attaque/défense des créatures | ||||
|   - les attaques/parades avec une arme trop lourde se font en demi-surprise | ||||
|   - les demandes de défense disparaîssent une fois prises en compte | ||||
|   - empoignade | ||||
|     - l'empoignade est possible avec une initiative d'empoignade, ou en cours d'empoignade | ||||
|     - seule la dague, le pugilat et la dague sont possibles en cours d'empoignade | ||||
|     - jet de Dextérité/Dague pour utiliser la dague en cours d'empoignade (p136) | ||||
|     - attaquer avec une arme un empoigneur donne un +4 si pas d'empoignade (p134) | ||||
|     - la différence de taille donne un bonus/malus en cours d'empoignade (p135) | ||||
|     - les dommages de l'empoignade ajoutent/enlèvent un point d'empoignade | ||||
|     - le statut d'empoignade est affiché sur les tokens | ||||
|     - les défenses contre une empoignade sont corrigées | ||||
|  | ||||
| ## 13.0.13 - L'épanouissement d'Illysis | ||||
|  | ||||
| - Fix d'erreur au chargement de templates RollDialog | ||||
|   | ||||
| @@ -648,15 +648,19 @@ select, | ||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="coeur"] select[name="coeur"] { | ||||
|   max-width: 4rem; | ||||
| } | ||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="tricher"] img { | ||||
|   /* image de d100 */ | ||||
|   max-width: 2.5rem; | ||||
|   max-height: 2.5rem; | ||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section img { | ||||
|   max-width: 1rem; | ||||
|   max-height: 1rem; | ||||
|   gap: 0; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
|   filter: invert(0.8); | ||||
| } | ||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="tricher"] img { | ||||
|   /* image de d100 */ | ||||
|   max-width: 2.5rem; | ||||
|   max-height: 2.5rem; | ||||
| } | ||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-buttons { | ||||
|   display: flex; | ||||
|   flex-direction: row-reverse; | ||||
| @@ -855,7 +859,7 @@ select, | ||||
|   max-width: 1.4rem; | ||||
|   max-height: 1.4rem; | ||||
|   border: 1px; | ||||
|   background: center / contain no-repeat url('../../assets/ui/icone_parchement_vierge.webp'); | ||||
|   background: center / contain no-repeat url('../../icons/templates/icone_parchement_vierge.webp'); | ||||
| } | ||||
| .system-foundryvtt-reve-de-dragon .sheet-header .header-compteurs { | ||||
|   width: calc(60% - 110px - 1rem); | ||||
| @@ -1565,6 +1569,12 @@ select, | ||||
| .system-foundryvtt-reve-de-dragon .type-compendium { | ||||
|   font-size: 0.6rem; | ||||
| } | ||||
| .system-foundryvtt-reve-de-dragon .sheet.journal-entry .journal-sidebar { | ||||
|   color: var(--color-text-dark-primary); | ||||
| } | ||||
| .system-foundryvtt-reve-de-dragon .sheet.journal-entry .journal-sidebar button { | ||||
|   color: var(--color-text-dark-primary); | ||||
| } | ||||
| .system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .sheet-header { | ||||
|   background: #011d33 url(../assets/ui/bg_header.webp) no-repeat left top; | ||||
|   color: #ffffff; | ||||
| @@ -2708,6 +2718,13 @@ select, | ||||
| .system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements div:nth-child(odd) { | ||||
|   background: var(--background-tooltip-alt); | ||||
| } | ||||
| .system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements div img { | ||||
|   display: inline; | ||||
|   margin: 0; | ||||
|   max-width: 1rem; | ||||
|   max-height: 1rem; | ||||
|   filter: invert(0.8); | ||||
| } | ||||
| .system-foundryvtt-reve-de-dragon aside#tooltip { | ||||
|   max-width: 15rem; | ||||
|   background: var(--background-tooltip); | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "TYPES": { | ||||
|     "Actor": {  | ||||
|     "Actor": { | ||||
|       "personnage": "Personnage", | ||||
|       "creature": "Créature", | ||||
|       "entite": "Entité de cauchemar", | ||||
| @@ -67,6 +67,7 @@ | ||||
|     "StatusComma": "Comma", | ||||
|     "StatusDead": "Mort", | ||||
|     "StatusDemiReve": "Demi-rêve", | ||||
|     "StatusSurEnc": "Sur-encombrement", | ||||
|     "StatusForceWeak": "Force insuffisante" | ||||
|   } | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -118,7 +118,7 @@ | ||||
|     max-width: 1.4rem; | ||||
|     max-height: 1.4rem; | ||||
|     border: 1px; | ||||
|     background: center / contain no-repeat url('../../assets/ui/icone_parchement_vierge.webp'); | ||||
|     background: center / contain no-repeat url('../../icons/templates/icone_parchement_vierge.webp'); | ||||
|   } | ||||
|  | ||||
|   .sheet-header .header-compteurs { | ||||
| @@ -865,6 +865,12 @@ | ||||
|   .type-compendium { | ||||
|     font-size: 0.6rem; | ||||
|   } | ||||
|   .sheet.journal-entry .journal-sidebar { | ||||
|     color: var(--color-text-dark-primary); | ||||
|     button { | ||||
|       color: var(--color-text-dark-primary); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* ======================================== */ | ||||
|   /* Sheet  */ | ||||
| @@ -1955,6 +1961,13 @@ | ||||
|       div:nth-child(odd) { | ||||
|         background: var(--background-tooltip-alt); | ||||
|       } | ||||
|       div img { | ||||
|         display: inline; | ||||
|         margin: 0; | ||||
|         max-width: 1rem; | ||||
|         max-height: 1rem; | ||||
|         filter: invert(0.8); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -224,15 +224,19 @@ | ||||
|     max-width: 4rem; | ||||
|   } | ||||
|  | ||||
|   roll-conditions roll-section[name="tricher"] img { | ||||
|     /* image de d100 */ | ||||
|     max-width: 2.5rem; | ||||
|     max-height: 2.5rem; | ||||
|   roll-conditions roll-section img { | ||||
|     max-width: 1rem; | ||||
|     max-height: 1rem; | ||||
|     gap: 0; | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
|     filter: invert(0.8); | ||||
|   } | ||||
|   roll-conditions roll-section[name="tricher"] img { | ||||
|     /* image de d100 */ | ||||
|     max-width: 2.5rem; | ||||
|     max-height: 2.5rem; | ||||
|   } | ||||
|  | ||||
|   roll-buttons {  | ||||
|     display: flex; | ||||
|   | ||||
| @@ -375,14 +375,6 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | ||||
|     return position; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   /** @override */ | ||||
|   _updateObject(event, formData) { | ||||
|     // Update the Actor | ||||
|     return this.actor.update(formData); | ||||
|   } | ||||
|  | ||||
|   async splitItem(item) { | ||||
|     const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split)); | ||||
|     dialog.render(true); | ||||
|   | ||||
| @@ -185,13 +185,13 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     const actions = [] | ||||
|     const uniques = [] | ||||
|  | ||||
|     const addAttaque = (arme, main = undefined, action = 'attaque') => { | ||||
|       const dommagesArme = RdDItemArme.valeurMain(arme.system.dommages, main) | ||||
|     const addAttaque = (arme, main = undefined) => { | ||||
|       const dommages = 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; | ||||
|  | ||||
|       const comp = this.getCompetence(RdDActor.$getCompetenceAction(arme, main)) | ||||
|       const unique = [comp.id, arme.name, dommagesArme, forceRequise, ecaillesEfficacite].join('|'); | ||||
|       const unique = [comp.id, arme.name, dommages, forceRequise, ecaillesEfficacite].join('|'); | ||||
|       if (uniques.includes(unique)) { | ||||
|         return | ||||
|       } | ||||
| @@ -212,12 +212,13 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         main: main, | ||||
|         carac: { key: caracCode, value: caracValue }, | ||||
|         equipe: arme.system.equipe, | ||||
|         dommagesArme: dommagesArme, | ||||
|         dommages: dommages, | ||||
|         forceRequise: forceRequise, | ||||
|         initiative: RdDInitiative.getRollInitiative(caracValue, niveau, ajustement) | ||||
|       }) | ||||
|     } | ||||
|  | ||||
|     addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS) | ||||
|     this.itemTypes[ITEM_TYPES.arme] | ||||
|       .filter(it => it.isAttaque()) | ||||
|       .sort(Misc.ascending(it => it.name)) | ||||
| @@ -227,9 +228,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         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 | ||||
|   } | ||||
| @@ -756,20 +755,18 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     let updates = {}; | ||||
|     if (caracName == LIST_CARAC_PERSONNAGE.reve.code) { | ||||
|       if (to > Misc.toInt(this.system.reve.seuil.value)) { | ||||
|         updates[`system.reve.seuil.value`] = to; // SFA : Direct and packed changes | ||||
|         //this.setPointsDeSeuil(to); | ||||
|         updates[`system.reve.seuil.value`] = to | ||||
|       } | ||||
|     } | ||||
|     if (caracName == LIST_CARAC_PERSONNAGE.chance.code) { | ||||
|       if (to > Misc.toInt(this.system.compteurs.chance.value)) { | ||||
|         updates[`system.compteurs.chance.value`] = to; // SFA : Direct and packed changes | ||||
|         //this.setPointsDeChance(to); | ||||
|         updates[`system.compteurs.chance.value`] = to | ||||
|       } | ||||
|     } | ||||
|     let selectedCarac = this.findCaracByName(caracName); | ||||
|     const from = selectedCarac.value | ||||
|     updates[`system.carac.${caracName}.value`] = to; | ||||
|     await this.update(updates); | ||||
|     await this.update(updates, { noHook: true }); | ||||
|     await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName); | ||||
|   } | ||||
|  | ||||
| @@ -1754,7 +1751,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|           this.tmrApp?.close(); | ||||
|           this.tmrApp = undefined; | ||||
|         } | ||||
|       } ], | ||||
|       }], | ||||
|       onRollDone: RollDialog.onRollDoneClose, | ||||
|       onClose: () => { | ||||
|         this.tmrApp?.restoreTMRAfterAction(); | ||||
| @@ -2608,7 +2605,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     if (item?.isEquipable()) { | ||||
|       const isEquipe = !item.system.equipe; | ||||
|       await item.update({ "system.equipe": isEquipe }); | ||||
|       this.computeEncTotal(); | ||||
|       this.computeEncTotal() | ||||
|       if (isEquipe) | ||||
|         this.verifierForceMin(item); | ||||
|     } | ||||
| @@ -2999,6 +2996,7 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|     if (updatedEndurance && options.diff) { | ||||
|       await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0) | ||||
|     } | ||||
|     await super.onUpdateActor(update, options, actorId) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -3041,9 +3039,12 @@ export class RdDActor extends RdDBaseActorSang { | ||||
|         break | ||||
|       case ITEM_TYPES.empoignade: | ||||
|         await RdDEmpoignade.deleteLinkedEmpoignade(this.id, item) | ||||
|         // TODO: check remaining emp. | ||||
|         await this.setEffect(STATUSES.StatusGrappled, false) | ||||
|         await this.setEffect(STATUSES.StatusGrappling, false) | ||||
|         break | ||||
|     } | ||||
|     super.onDeleteItem(item, options, id) | ||||
|     await super.onDeleteItem(item, options, id) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
| @@ -56,13 +56,15 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet { | ||||
|     if (this.options.vueDetaillee) { | ||||
|       // On carac change | ||||
|       this.html.find('.carac-value').change(async event => { | ||||
|         let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "") | ||||
|         await this.actor.updateCarac(caracName, parseInt(event.target.value)) | ||||
|       }); | ||||
|         if (event.currentTarget.name.includes("carac.")) { | ||||
|           let caracName = event.currentTarget.name.replace("carac.", "") | ||||
|           await this.actor.updateCarac(caracName, parseInt(event.currentTarget.value)) | ||||
|         } | ||||
|       }) | ||||
|       // On competence change | ||||
|       this.html.find('.competence-value').change(async event => { | ||||
|         let compName = event.currentTarget.attributes.compname.value | ||||
|         await this.actor.updateCompetence(compName, parseInt(event.target.value)) | ||||
|         await this.actor.updateCompetence(compName, parseInt(event.currentTarget.value)) | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { ENTITE_INCARNE, renderTemplate, SHOW_DICE, SYSTEM_RDD } from "../constants.js"; | ||||
| import { 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"; | ||||
| @@ -89,7 +89,6 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|   getSConst() { return 0 } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   isSurenc() { return false } | ||||
|   computeMalusSurEncombrement() { return 0 } | ||||
|  | ||||
|   ajustementAstrologique() { return 0 } | ||||
| @@ -126,6 +125,8 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|   async remiseANeuf() { } | ||||
|   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { } | ||||
|  | ||||
|   computeResumeBlessure() { } | ||||
|   countBlessures(filter = it => !it.isContusion()) { return 0 } | ||||
|   async santeIncDec(name, inc, isCritique = false) { } | ||||
|  | ||||
|   async finDeRound(options = { terminer: false }) { | ||||
| @@ -176,10 +177,11 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|   } | ||||
|  | ||||
|   getCompetences(name = undefined, options = { onMessage: message => { } }) { | ||||
|     const all = [...this.itemTypes[ITEM_TYPES.competence], ...this.itemTypes[ITEM_TYPES.competencecreature]] | ||||
|     if (name == undefined) { | ||||
|       return this.itemTypes[ITEM_TYPES.competence] | ||||
|       return all | ||||
|     } | ||||
|     return RdDItemCompetence.findCompetences(this.itemTypes[ITEM_TYPES.competence], name, options) | ||||
|     return RdDItemCompetence.findCompetences(all, name, options) | ||||
|   } | ||||
|  | ||||
|   getCompetenceCorpsACorps(options = { onMessage: message => { } }) { | ||||
| @@ -203,6 +205,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|   getPossession(possessionId) { | ||||
|     return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId); | ||||
|   } | ||||
|  | ||||
|   getEmpoignades() { | ||||
|     return this.itemTypes[ITEM_TYPES.empoignade]; | ||||
|   } | ||||
| @@ -226,53 +229,13 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   isEffectAllowed(effectId) { return false } | ||||
|  | ||||
|   getEffects(filter = e => true, forceRequise = undefined) { | ||||
|     const effects = this.getEmbeddedCollection("ActiveEffect") | ||||
|     const selected = effects.filter(filter) | ||||
|     if (forceRequise && this.isForceInsuffisante(forceRequise)) { | ||||
|       selected.push(StatusEffects.prepareActiveEffect(STATUSES.StatusForceWeak)) | ||||
|     } | ||||
|     return selected | ||||
|   } | ||||
|  | ||||
|   getEffectByStatus(statusId) { | ||||
|     return this.getEffects().find(it => it.statuses.has(statusId)); | ||||
|   } | ||||
|  | ||||
|   async setEffect(statusId, status) { | ||||
|     if (this.isEffectAllowed(statusId)) { | ||||
|       const effect = this.getEffectByStatus(statusId); | ||||
|       if (!status && effect) { | ||||
|         await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id], { render: true}) | ||||
|       } | ||||
|       if (status && !effect) { | ||||
|         await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.prepareActiveEffect(statusId)], { render: true}) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async removeEffect(id) { | ||||
|     this.removeEffects(it => it.id == id) | ||||
|   } | ||||
|  | ||||
|   async removeEffects(filter = e => true) { | ||||
|     if (game.user.isGM) { | ||||
|       const effectsToRemove = this.getEffects(filter); | ||||
|       const ids = effectsToRemove.map(it => it.id); | ||||
|       await this.deleteEmbeddedDocuments('ActiveEffect', ids); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   isDemiReve() { | ||||
|     return this.getEffectByStatus(STATUSES.StatusDemiReve) != undefined | ||||
|     return this.getEffectsByStatus(STATUSES.StatusDemiReve).length > 0 | ||||
|   } | ||||
|  | ||||
|   getSurprise(isCombat = undefined) { | ||||
|     return StatusEffects.getSurprise(this.getEffects(), isCombat) | ||||
|   getSurprise(isCombat = undefined, forceRequise = undefined) { | ||||
|     return StatusEffects.getSurprise(this.getEffects(e => true, isCombat, forceRequise), isCombat) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -309,6 +272,22 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|  | ||||
|   async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) { | ||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||
|  | ||||
|     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||
|       const competence = this.getCompetence(compName); | ||||
|       const rollData = { | ||||
|         ids: { actorId: this.id }, | ||||
|         type: { allowed: DEFAULT_ROLL_TYPES, current: PART_COMP }, | ||||
|         selected: { | ||||
|           carac: { key: caracName }, | ||||
|           comp: { key: competence.name }, | ||||
|           diff: { value: diff } | ||||
|         } | ||||
|       } | ||||
|       RollDialog.create(rollData, options) | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     const competence = this.getCompetence(compName); | ||||
|     await this.openRollDialog({ | ||||
|       name: 'jet-competence', | ||||
| @@ -423,32 +402,22 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-general.hbs'); | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   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)) { | ||||
|     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||
|       const rollData = { | ||||
|         ids: { actorId: this.id }, | ||||
|         type: { allowed: options.arme ? ATTAQUE_ROLL_TYPES : DEFAULT_ROLL_TYPES }, | ||||
|         selected: { | ||||
|           carac: competence.type == ITEM_TYPES.competencecreature ? { key: competence.name } : undefined, | ||||
|           comp: { key: competence.name }, | ||||
|           diff: { type: DIFF.LIBRE, value: competence.system.default_diffLibre ?? 0 } | ||||
|           diff: { type: options.arme ? DIFF.ATTAQUE : DIFF.LIBRE, value: competence.system.default_diffLibre ?? 0 }, | ||||
|           attaque: options.arme ? { arme: { key: options.arme.id } } : undefined | ||||
|         } | ||||
|       } | ||||
|       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 | ||||
|       return await RollDialog.create(rollData) | ||||
|     } | ||||
|  | ||||
|     let rollData = { | ||||
| @@ -512,19 +481,13 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|         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 } | ||||
|             }, | ||||
|           const rollData = { | ||||
|             ids: { actorId: this.id, actorTokenId: token?.id, }, | ||||
|             type: { | ||||
|               allowed: [ROLL_TYPE_COMP, ROLL_TYPE_ATTAQUE, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE, ROLL_TYPE_JEU], | ||||
|               current: ROLL_TYPE_COMP | ||||
|               allowed: [ROLL_TYPE_ATTAQUE], current: ROLL_TYPE_ATTAQUE | ||||
|             } | ||||
|           }) | ||||
|           }; | ||||
|           return await RollDialog.create(rollData) | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
| @@ -669,7 +632,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | ||||
|   async accorder(entite, when = 'avant-encaissement') { | ||||
|     if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar") | ||||
|       || entite == undefined | ||||
|       || !entite.isEntite([ENTITE_INCARNE]) | ||||
|       || !entite.isEntiteIncarnee() | ||||
|       || entite.isEntiteAccordee(this)) { | ||||
|       return true | ||||
|     } | ||||
|   | ||||
| @@ -186,6 +186,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | ||||
|         await this.changeBleedingState() | ||||
|         break | ||||
|     } | ||||
|     await super.onCreateItem(item, options, id) | ||||
|   } | ||||
|  | ||||
|   async onUpdateItem(item, options, id) { | ||||
| @@ -194,6 +195,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | ||||
|         await this.changeBleedingState() | ||||
|         break | ||||
|     } | ||||
|     await super.onUpdateItem(item, options, id) | ||||
|   } | ||||
|  | ||||
|   async changeBleedingState() { | ||||
| @@ -313,7 +315,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | ||||
|   } | ||||
|  | ||||
|   isSonne() { | ||||
|     return this.getEffectByStatus(STATUSES.StatusStunned) | ||||
|     return this.getEffectsByStatus(STATUSES.StatusStunned).length > 0 | ||||
|   } | ||||
|  | ||||
|   isEffectAllowed(effectId) { return true } | ||||
|   | ||||
| @@ -49,15 +49,14 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet { | ||||
|     formData.calc = { | ||||
|       fortune: Monnaie.toSolsDeniers(this.actor.getFortune()), | ||||
|       prixTotalEquipement: this.actor.computePrixTotalEquipement(), | ||||
|       encTotal: await this.actor.computeEncTotal(), | ||||
|       encTotal: this.actor.getEncTotal(), | ||||
|     } | ||||
|  | ||||
|     this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires); | ||||
|     this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires); | ||||
|     formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs); | ||||
|     formData.competences.filter(it => it.type == ITEM_TYPES.competencecreature) | ||||
|       .forEach(it => it.isdommages = it.isDommages() | ||||
|       ) | ||||
|       .forEach(it => it.isdommages = it.isDommages()) | ||||
|  | ||||
|     return formData; | ||||
|   } | ||||
| @@ -230,14 +229,6 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet { | ||||
|     return position; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   /** @override */ | ||||
|   _updateObject(event, formData) { | ||||
|     // Update the Actor | ||||
|     return this.actor.update(formData); | ||||
|   } | ||||
|  | ||||
|   async splitItem(item) { | ||||
|     const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split)); | ||||
|     dialog.render(true); | ||||
|   | ||||
| @@ -10,7 +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"; | ||||
| import { StatusEffects, STATUSES } from "../settings/status-effects.js"; | ||||
|  | ||||
| export class RdDBaseActor extends Actor { | ||||
|  | ||||
| @@ -215,9 +215,11 @@ export class RdDBaseActor extends Actor { | ||||
|     return game.users.players.find(player => player.active && player.character?.id == this.id); | ||||
|   } | ||||
|  | ||||
|   isCreatureEntite() { return this.isCreature() || this.isEntite() } | ||||
|   isCreatureOuEntite() { return this.isCreature() || this.isEntite() } | ||||
|   isCreature() { return false } | ||||
|   isEntite(typeentite = []) { return false } | ||||
|   isEntite() { return false } | ||||
|   isEntiteIncarnee() { return false } | ||||
|   isEntiteNonIncarnee() { return false } | ||||
|   isHautRevant() { return false } | ||||
|   isVehicule() { return false } | ||||
|   isPersonnage() { return false } | ||||
| @@ -241,18 +243,68 @@ export class RdDBaseActor extends Actor { | ||||
|  | ||||
|   getMonnaie(id) { return this.findItemLike(id, 'monnaie'); } | ||||
|   getEncombrementMax() { return 0 } | ||||
|   isSurenc() { return false } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   isEffectAllowed(effectId) { return false } | ||||
|  | ||||
|   getEffects(filter = e => true, forceRequise = undefined) { | ||||
|     const effects = this.getEmbeddedCollection("ActiveEffect") | ||||
|     const selected = effects.filter(filter) | ||||
|     if (forceRequise && this.isForceInsuffisante(forceRequise)) { | ||||
|       selected.push(StatusEffects.prepareActiveEffect(STATUSES.StatusForceWeak)) | ||||
|     } | ||||
|     return selected | ||||
|   } | ||||
|  | ||||
|   getEffectsByStatus(effectId) { | ||||
|     return this.getEffects().filter(it => it.statuses.has(effectId)) | ||||
|   } | ||||
|  | ||||
|   async setEffect(effectId, status) { | ||||
|     if (this.isEffectAllowed(effectId)) { | ||||
|       const effects = this.getEffectsByStatus(effectId) | ||||
|       if (!status && effects.length > 0) { | ||||
|         await this.deleteEmbeddedDocuments('ActiveEffect', effects.map(it => it.id), { render: true }) | ||||
|       } | ||||
|       if (status && effects.length == 0) { | ||||
|         await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.prepareActiveEffect(effectId)], { render: true }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async removeEffect(id) { | ||||
|     this.removeEffects(it => it.id == id) | ||||
|   } | ||||
|  | ||||
|   async removeEffects(filter = e => true) { | ||||
|     if (game.user.isGM) { | ||||
|       const effectsToRemove = this.getEffects(filter); | ||||
|       const ids = effectsToRemove.map(it => it.id); | ||||
|       await this.deleteEmbeddedDocuments('ActiveEffect', ids); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async updateCarac(caracName, to) { | ||||
|   } | ||||
|  | ||||
|   async onUpdateActor(change, options, actorId) { | ||||
|     const updatedCarac = change?.system?.carac | ||||
|     if (updatedCarac && (updatedCarac.force || updatedCarac.reve || updatedCarac.taille)) { | ||||
|       console.log(' onUpdateActor', change, options, actorId) | ||||
|       await this.setEffect(STATUSES.StatusSurEnc, this.isSurenc()) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async onPreUpdateItem(item, change, options, id) { } | ||||
|  | ||||
|   async onCreateItem(item, options, id) { } | ||||
|   async onCreateItem(item, options, id) { | ||||
|   } | ||||
|  | ||||
|   async onUpdateItem(item, options, id) { } | ||||
|  | ||||
|   async onUpdateActor(update, options, actorId) { } | ||||
|   async onUpdateItem(item, options, id) { | ||||
|   } | ||||
|  | ||||
|   async onDeleteItem(item, options, id) { | ||||
|     if (item.isInventaire()) { | ||||
| @@ -260,6 +312,7 @@ export class RdDBaseActor extends Actor { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   async _removeItemFromConteneur(item) { | ||||
|     const updates = this.items.filter(it => it.isConteneur() && it.system.contenu.includes(item.id)) | ||||
|       .map(conteneur => { | ||||
| @@ -508,16 +561,22 @@ export class RdDBaseActor extends Actor { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async computeEncTotal() { | ||||
|     if (!this.pack) { | ||||
|     if (this.pack) { | ||||
|       this.encTotal = 0 | ||||
|     } | ||||
|     else { | ||||
|       const wasSurenc = this.isSurenc() | ||||
|       this.encTotal = this.items.filter(it => RdDItem.getItemTypesInventaire().includes(it.type)) | ||||
|         .map(it => it.getEncTotal()).reduce(Misc.sum(), 0) | ||||
|       return this.encTotal; | ||||
|       const isSurenc = this.isSurenc() | ||||
|       if (isSurenc != wasSurenc) { | ||||
|         await this.setEffect(STATUSES.StatusSurEnc, isSurenc) | ||||
|       } | ||||
|     } | ||||
|     return 0; | ||||
|   } | ||||
|  | ||||
|   getEncTotal() { | ||||
|     return Math.floor(this.encTotal ?? 0); | ||||
|     return Math.floor(this.encTotal ?? 0) | ||||
|   } | ||||
|  | ||||
|   async createItem(type, name = undefined) { | ||||
| @@ -568,7 +627,7 @@ export class RdDBaseActor extends Actor { | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     await this.computeEncTotal(); | ||||
|     await this.computeEncTotal() | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -43,7 +43,7 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet { | ||||
|     this.html.find('.resonance-add').click(async event => | ||||
|       await DialogSelect.select({ | ||||
|         label: "Choisir un acteur à accorder", | ||||
|         list: game.actors.filter(it => it.isPersonnage() && it.prototypeToken.actorLink) | ||||
|         list: game.actors.filter(it => true) | ||||
|       }, | ||||
|         it => this.resonanceAdd(it.id)) | ||||
|     ) | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; | ||||
| import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
| import { RdDItemBlessure } from "../item/blessure.js"; | ||||
| import { Misc } from "../misc.js"; | ||||
| import { RdDCarac } from "../rdd-carac.js"; | ||||
| import { RdDEncaisser } from "../rdd-roll-encaisser.js"; | ||||
| @@ -16,11 +17,10 @@ export class RdDEntite extends RdDBaseActorReve { | ||||
|     return item.type == ITEM_TYPES.competencecreature | ||||
|   } | ||||
|  | ||||
|   isEntite(typeentite = []) { | ||||
|     return (typeentite.length == 0 || typeentite.includes(this.system.definition.typeentite)); | ||||
|   } | ||||
|  | ||||
|   isNonIncarnee() { return this.isEntite([ENTITE_NONINCARNE]) } | ||||
|   isEntite() { return true } | ||||
|   isEntiteNonIncarnee() { return this.system.definition.typeentite == ENTITE_NONINCARNE } | ||||
|   isEntiteIncarnee() { return [ENTITE_INCARNE, ENTITE_BLURETTE].includes(this.system.definition.typeentite) } | ||||
|   isEntiteBlurette() { return this.system.definition.typeentite !== ENTITE_BLURETTE } | ||||
|  | ||||
|   getReveActuel() { | ||||
|     return Misc.toInt(this.system.carac.reve?.value) | ||||
| @@ -49,20 +49,20 @@ export class RdDEntite extends RdDBaseActorReve { | ||||
|   } | ||||
|  | ||||
|   async remiseANeuf() { | ||||
|     await this.removeEffects(e => true); | ||||
|     if (!this.isNonIncarnee()) { | ||||
|     if (!this.isEntiteNonIncarnee()) { | ||||
|       await this.update({ | ||||
|         'system.sante.endurance.value': this.system.sante.endurance.max | ||||
|       }); | ||||
|     } | ||||
|     await this.removeEffects(e => true) | ||||
|   } | ||||
|  | ||||
|   isDead() { | ||||
|     return this.isNonIncarnee() ? false : this.system.sante.endurance.value <= 0 | ||||
|     return this.isEntiteNonIncarnee() ? false : this.system.sante.endurance.value <= 0 | ||||
|   } | ||||
|  | ||||
|   async santeIncDec(name, inc, isCritique = false) { | ||||
|     if (name == 'endurance' && !this.isNonIncarnee()) { | ||||
|     if (name == 'endurance' && !this.isEntiteNonIncarnee()) { | ||||
|       const oldValue = this.system.sante.endurance.value; | ||||
|       const endurance = Math.max(0, | ||||
|         Math.min(oldValue + inc, | ||||
| @@ -78,7 +78,7 @@ export class RdDEntite extends RdDBaseActorReve { | ||||
|   } | ||||
|  | ||||
|   async encaisser() { | ||||
|     if (this.isNonIncarnee()) { | ||||
|     if (this.isEntiteNonIncarnee()) { | ||||
|       return | ||||
|     } | ||||
|     await RdDEncaisser.encaisser(this) | ||||
| @@ -89,15 +89,19 @@ export class RdDEntite extends RdDBaseActorReve { | ||||
|   } | ||||
|  | ||||
|   async onAppliquerJetEncaissement(encaissement, attackerToken) { | ||||
|     if (this.isEntiteNonIncarnee()) { | ||||
|       return | ||||
|     } | ||||
|     const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance); | ||||
|     foundry.utils.mergeObject(encaissement, { | ||||
|       resteEndurance: perteEndurance.newValue, | ||||
|       endurance: perteEndurance.perte | ||||
|     }); | ||||
|       endurance: perteEndurance.perte, | ||||
|       blessure: RdDItemBlessure.prepareBlessure(encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken) | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   isEntiteAccordee(attacker) { | ||||
|     if (this.isEntite([ENTITE_INCARNE])) { | ||||
|     if (this.isEntiteIncarnee()) { | ||||
|       let resonnance = this.system.sante.resonnance | ||||
|       return (resonnance.actors.find(it => it == attacker.id)) | ||||
|     } | ||||
| @@ -106,7 +110,7 @@ export class RdDEntite extends RdDBaseActorReve { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   async setEntiteReveAccordee(actor) { | ||||
|     if (this.isEntite([ENTITE_INCARNE])) { | ||||
|     if (this.isEntiteIncarnee()) { | ||||
|       if (this.system.sante.resonnance.actors.find(it => it == actor.id)) { | ||||
|         // déjà accordé | ||||
|         return | ||||
|   | ||||
| @@ -29,7 +29,7 @@ export class ExperienceLog { | ||||
|     }; | ||||
|     console.log('ExperienceLog.add', newXpLog) | ||||
|     const newExperienceLog = (actor.system.experiencelog ?? []).concat([newXpLog]); | ||||
|     await actor.update({ [`system.experiencelog`]: newExperienceLog }); | ||||
|     await actor.update({ [`system.experiencelog`]: newExperienceLog }, { noHook: true }); | ||||
|   } | ||||
|  | ||||
|   static labelTopic(topic) { | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { Grammar } from "../../grammar.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" | ||||
| import { ITEM_TYPES, RDD_CONFIG } from "../../constants.js" | ||||
| import { Misc } from "../../misc.js" | ||||
| import { RdDTimestamp } from "../../time/rdd-timestamp.js" | ||||
| import { RdDBonus } from "../../rdd-bonus.js" | ||||
| @@ -160,7 +160,7 @@ export class Mapping { | ||||
|       return undefined | ||||
|     } | ||||
|     const categorie = Mapping.complementCategorie(arme, maniement) | ||||
|     const dommages = Mapping.dommagesArme(actor, arme, maniement) | ||||
|     const dommages = Mapping.dommages(actor, arme, maniement) | ||||
|     return { | ||||
|       name: arme.name + categorie, | ||||
|       niveau: Misc.toSignedString(competence.system.niveau), | ||||
| @@ -170,12 +170,13 @@ export class Mapping { | ||||
|       arme: arme | ||||
|     } | ||||
|   } | ||||
|   static dommagesArme(actor, arme, maniement) { | ||||
|  | ||||
|   static dommages(actor, arme, maniement) { | ||||
|     const dmgArme = RdDItemArme.dommagesReels(arme, maniement) | ||||
|     const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)) | ||||
|     switch (arme.system.mortalite) { | ||||
|       case 'non-mortel': return `(${dommages})` | ||||
|       case EMPOIGNADE: return '-' | ||||
|       case RDD_CONFIG.encaissement.nonmortel: return `(${dommages})` | ||||
|       case RDD_CONFIG.encaissement.empoignade: return '-' | ||||
|     } | ||||
|     return dommages | ||||
|   } | ||||
|   | ||||
| @@ -21,7 +21,7 @@ const RANDOM_VALUES = { | ||||
|   'system.sexe': { 'masculin': 1, 'féminin': 1 }, | ||||
|   'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidextre': 6 }, | ||||
|   'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains': 3, 'châtain clair': 5, 'blonds': 4, 'blond platine': 1, 'roux carotte': 1, 'roux cuivré': 3, 'chauve': 1 }, | ||||
|   'system.yeux': { 'noirs': 2, 'noisette': 3, 'brun vert': 4, 'verts': 3, 'bleu clair': 3, 'bleu gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 }, | ||||
|   'system.yeux': { 'noirs': 2, 'noisette': 3, 'brun-vert': 4, 'verts': 3, 'bleu clair': 3, 'bleu gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 }, | ||||
| } | ||||
|  | ||||
| export class AppPersonnageAleatoire extends FormApplication { | ||||
|   | ||||
| @@ -13,53 +13,65 @@ 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)" } | ||||
|     { 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", | ||||
|     "reve": "Rêve" | ||||
|     'cauchemar': 'Cauchemar', | ||||
|     'reve': 'Rêve' | ||||
|   }, | ||||
|   typeEntite: { | ||||
|     "incarne": "Incarnée", | ||||
|     "nonincarne": "Non Incarnée", | ||||
|     "blurette": "Blurette" | ||||
|     [ENTITE_INCARNE]: 'Incarnée', | ||||
|     [ENTITE_NONINCARNE]: 'Non Incarnée', | ||||
|     [ENTITE_BLURETTE]: 'Blurette' | ||||
|   }, | ||||
|   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" } | ||||
|     { 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: 'rapidite', descr: 'en rapidité', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-rapidite.svg'}, | ||||
|     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: 'rapidite', descr: 'en rapidité', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-rapidite.svg' }, | ||||
|   }, | ||||
|   icons: { | ||||
|     armesDisparates: 'systems/foundryvtt-reve-de-dragon/assets/actions/armes-disparates.svg', | ||||
|     demiReve: 'systems/foundryvtt-reve-de-dragon/assets/actions/sort.svg', | ||||
|     empoignade: 'systems/foundryvtt-reve-de-dragon/assets/actions/empoignade.svg', | ||||
|     forceWeak: 'systems/foundryvtt-reve-de-dragon/assets/actions/weak.svg', | ||||
|     surenc: 'systems/foundryvtt-reve-de-dragon/assets/actions/surenc.svg', | ||||
|   }, | ||||
|   encaissement: { | ||||
|     mortel: 'mortel', | ||||
|     nonmortel: 'non-mortel', | ||||
|     entiteincarnee: 'entiteincarnee', | ||||
|     empoignade: 'empoignade' | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| export const ACTOR_TYPES = { | ||||
|   personnage: 'personnage', | ||||
|   creature: 'creature', | ||||
|   | ||||
| @@ -58,6 +58,7 @@ export class RdDInitiative { | ||||
|     return { | ||||
|       roll: roll, | ||||
|       value: value, | ||||
|       rang: formule.phase.rang, | ||||
|       init: formule.phase.rang + value / 100, | ||||
|       label: formule.phase.label | ||||
|     } | ||||
|   | ||||
| @@ -32,6 +32,7 @@ export class RdDItemCompetenceCreature extends RdDItem { | ||||
|             initiative: initative, | ||||
|             mortalite: this.system.mortalite, | ||||
|             dommages: this.system.dommages, | ||||
|             forceRequise: 0, | ||||
|             equipe: true, | ||||
|             resistance: 100, | ||||
|             penetration: 0, | ||||
| @@ -43,7 +44,8 @@ export class RdDItemCompetenceCreature extends RdDItem { | ||||
|         carac: { key: this.name, value: this.system.carac_value }, | ||||
|         equipe: true, | ||||
|         mortalite: this.system.mortalite, | ||||
|         dmg: this.system.dommages, | ||||
|         dommages: this.system.dommages, | ||||
|         //dmg: this.system.dommages, | ||||
|         initiative: initative | ||||
|       }; | ||||
|       return attaque | ||||
|   | ||||
| @@ -260,7 +260,7 @@ export class RdDItemSheetV1 extends foundry.appv1.sheets.ItemSheet { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   /** @override */ | ||||
|   _updateObject(event, formData) { | ||||
|   async _updateObject(event, formData) { | ||||
|     switch (this.item.type) { | ||||
|       case ITEM_TYPES.sort: | ||||
|         formData['system.bonuscase'] = RdDItemSort.bonuscasesToString(RdDItemSheetV1._listCaseTmr( | ||||
| @@ -273,8 +273,7 @@ export class RdDItemSheetV1 extends foundry.appv1.sheets.ItemSheet { | ||||
|         formData['system.niveau'] = formData['system.niveau'] ?? formData['system.base'] | ||||
|         break | ||||
|     } | ||||
|  | ||||
|     return this.item.update(formData) | ||||
|     return await super._updateObject(event, formData) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { ITEM_TYPES, renderTemplate } from "./constants.js"; | ||||
| import { ITEM_TYPES, RDD_CONFIG, 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"; | ||||
|  | ||||
| @@ -629,7 +629,7 @@ export class RdDItem extends Item { | ||||
|   _armeChatData() { | ||||
|     return [ | ||||
|       `<b>Compétence</b>: ${this.system.competence}`, | ||||
|       `<b>Dommages</b>: ${this.system.dommages} ${this.system.mortalite == 'non-mortel' ? '(Non mortel)' : ''}`, | ||||
|       `<b>Dommages</b>: ${this.system.dommages} ${this.system.mortalite == RDD_CONFIG.encaissement.nonmortel ? '(Non mortel)' : ''}`, | ||||
|       `<b>Force minimum</b>: ${this.system.force}`, | ||||
|       `<b>Resistance</b>: ${this.system.resistance}`, | ||||
|       ...this._inventaireTemplateChatData() | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { ITEM_TYPES } from "../constants.js"; | ||||
| import { ITEM_TYPES, RDD_CONFIG } from "../constants.js"; | ||||
| import { RdDItem } from "../item.js"; | ||||
| import { BASE_CORPS_A_CORPS } from "./base-items.js"; | ||||
| import { Grammar } from "../grammar.js"; | ||||
| @@ -27,10 +27,11 @@ export const ATTAQUE_TYPE = { | ||||
|   TIR: '(tir)', | ||||
|   LANCER: '(lancer)' | ||||
| } | ||||
| export const ATTAQUE_TYPE_MELEE = [ATTAQUE_TYPE.UNE_MAIN, ATTAQUE_TYPE.DEUX_MAINS, ATTAQUE_TYPE.CORPS_A_CORPS] | ||||
|  | ||||
| export const CORPS_A_CORPS = 'Corps à corps' | ||||
| export const PUGILAT = 'pugilat' | ||||
| export const EMPOIGNADE = 'empoignade' | ||||
| export const EMPOIGNADE = RDD_CONFIG.encaissement.empoignade | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| export class RdDItemArme extends RdDItem { | ||||
| @@ -254,15 +255,23 @@ export class RdDItemArme extends RdDItem { | ||||
|     return this.system.resistance > 0 || (this.system.tir != '' && this.system.portee_courte > 0) | ||||
|   } | ||||
|  | ||||
|   isEmpoignade() { | ||||
|     return this.system.mortalite == RDD_CONFIG.encaissement.empoignade | ||||
|   } | ||||
|  | ||||
|   isUtilisableEmpoigne() { | ||||
|     return this.system.baseInit == 3 || this.system.baseInit == 4 || this.system.competence == "Dague" | ||||
|   } | ||||
|  | ||||
|   static pugilat(actor) { | ||||
|     return RdDItemArme.$corpsACorps(actor, 'Pugilat', PUGILAT) | ||||
|   } | ||||
|  | ||||
|   static empoignade(actor) { | ||||
|     return RdDItemArme.$corpsACorps(actor, 'Empoignade', EMPOIGNADE) | ||||
|     return RdDItemArme.$corpsACorps(actor, 'Empoignade', RDD_CONFIG.encaissement.empoignade) | ||||
|   } | ||||
|  | ||||
|   static $corpsACorps(actor, name, cac, system) { | ||||
|   static $corpsACorps(actor, name, cac) { | ||||
|     const competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS | ||||
|     const melee = actor ? actor.system.carac['melee'].value : 0 | ||||
|     return new RdDItemArme({ | ||||
| @@ -277,10 +286,10 @@ export class RdDItemArme extends RdDItem { | ||||
|         force: 0, | ||||
|         dommages: "0", | ||||
|         dommagesReels: 0, | ||||
|         mortalite: cac == EMPOIGNADE ? EMPOIGNADE : 'non-mortel', | ||||
|         mortalite: cac == RDD_CONFIG.encaissement.empoignade ? RDD_CONFIG.encaissement.empoignade : RDD_CONFIG.encaissement.nonmortel, | ||||
|         competence: CORPS_A_CORPS, | ||||
|         resistance: 1, | ||||
|         baseInit: cac == EMPOIGNADE ? 3 : 4, | ||||
|         baseInit: cac == RDD_CONFIG.encaissement.empoignade ? 3 : 4, | ||||
|         cac: cac, | ||||
|         deuxmains: true, | ||||
|         categorie_parade: 'sans-armes' | ||||
|   | ||||
| @@ -71,21 +71,25 @@ export class RdDItemBlessure extends RdDItem { | ||||
|     return 0 | ||||
|   } | ||||
|  | ||||
|   static async createBlessure(actor, gravite, localisation = '', attackerToken) { | ||||
|     const definition = RdDItemBlessure.getDefinition(gravite) | ||||
|     const blessure = { | ||||
|   static async createBlessure(actor, gravite, localisation = '', attackerToken = undefined) { | ||||
|     const blessure = RdDItemBlessure.prepareBlessure(gravite, localisation, attackerToken); | ||||
|     const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) | ||||
|     return blessures[0] | ||||
|   } | ||||
|  | ||||
|   static prepareBlessure(gravite, localisation, attackerToken) { | ||||
|     const definition = RdDItemBlessure.getDefinition(gravite); | ||||
|     return { | ||||
|       name: definition.label, | ||||
|       type: 'blessure', | ||||
|       img: definition.icon, | ||||
|       system: { | ||||
|         gravite: gravite, | ||||
|         difficulte: - gravite, | ||||
|         difficulte: -gravite, | ||||
|         localisation: localisation, | ||||
|         origine: attackerToken?.name ?? "" | ||||
|       } | ||||
|     } | ||||
|     const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) | ||||
|     return blessures[0] | ||||
|   } | ||||
|  | ||||
|   static async createTacheSoinBlessure(actor, gravite) { | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| import { RDD_CONFIG } from "./constants.js"; | ||||
| import { RdDItemArme } from "./item/arme.js"; | ||||
| import { RdDPossession } from "./rdd-possession.js"; | ||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||
| @@ -35,7 +36,7 @@ export class RdDBonus { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static dmg(rollData, actor, isEntiteIncarnee = false) { | ||||
|   static dmg(rollData, actor) { | ||||
|     const diff = rollData.diffLibre; | ||||
|     const dmgArme = RdDBonus.dmgArme(rollData.arme, rollData.arme?.system.dommagesReels) | ||||
|     const forceRequise = rollData.arme ? RdDItemArme.valeurMain(rollData.arme.system.force ?? 0, RdDItemArme.getMainAttaque(rollData.competence)) : 0 | ||||
| @@ -48,18 +49,18 @@ export class RdDBonus { | ||||
|       dmgTactique: RdDBonus.dmgBonus(rollData.tactique), | ||||
|       dmgParticuliere: RdDBonus._dmgParticuliere(rollData), | ||||
|       dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris?.used), | ||||
|       mortalite: RdDBonus._calculMortalite(rollData, isEntiteIncarnee), | ||||
|       mortalite: RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite), | ||||
|       dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme), | ||||
|       dmgForceInsuffisante: Math.min(0, actor.getForce() - forceRequise) | ||||
|     } | ||||
|     dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante | ||||
|     return dmg; | ||||
|     return dmg | ||||
|   } | ||||
|  | ||||
|   static dmgRollV2(rollData, attaque) { | ||||
|     const actor = rollData.active.actor | ||||
|     const arme = attaque.arme | ||||
|     const dmgArme = RdDBonus.dmgArme(arme, attaque.dommagesArme) | ||||
|     const dmgArme = RdDBonus.dmgArme(arme, attaque.dommages) | ||||
|     const dmg = { | ||||
|       total: 0, | ||||
|       dmgArme: dmgArme, | ||||
| @@ -68,11 +69,12 @@ export class RdDBonus { | ||||
|       dmgTactique: attaque.tactique?.dmg ?? 0, | ||||
|       dmgParticuliere: RdDBonus._dmgParticuliere(rollData), | ||||
|       dmgSurprise: rollData.opponent?.surprise?.dmg ?? 0, | ||||
|       mortalite: RdDBonus.mortalite(attaque.dmg?.mortalite, arme?.system.mortalite, rollData.opponent?.actor?.isEntite()), | ||||
|       mortalite: RdDBonus.mortalite(attaque.dmg?.mortalite, arme?.system.mortalite), | ||||
|       dmgActor: RdDBonus.bonusDmg(actor, attaque.carac.key, dmgArme, attaque.forceRequise), | ||||
|       dmgForceInsuffisante: Math.min(0, actor.getForce() - attaque.forceRequise), | ||||
|       dmgForceInsuffisante: Math.min(0, actor.getForce() - (attaque.forceRequise ?? 0)), | ||||
|       dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0 | ||||
|     } | ||||
|     dmg.isEmpoignade = dmg.mortalite == RDD_CONFIG.encaissement.empoignade | ||||
|     dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante + dmg.dmgDiffLibre | ||||
|     return dmg | ||||
|   } | ||||
| @@ -93,21 +95,14 @@ export class RdDBonus { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static _calculMortalite(rollData, isEntiteIncarnee) { | ||||
|     return RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite, isEntiteIncarnee) | ||||
|   } | ||||
|  | ||||
|   static mortalite(mortaliteSelect, mortaliteArme, isEntiteIncarnee) { | ||||
|     return isEntiteIncarnee ? "entiteincarnee" | ||||
|       : mortaliteSelect | ||||
|       ?? mortaliteArme | ||||
|       ?? "mortel"; | ||||
|   static mortalite(mortaliteSelect, mortaliteArme) { | ||||
|     return mortaliteSelect ?? mortaliteArme ?? RDD_CONFIG.encaissement.mortel | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static dmgArme(arme, dommagesMain) { | ||||
|   static dmgArme(arme, dommages) { | ||||
|     if (arme) { | ||||
|       let dmgBase = dommagesMain ?? Number(arme.system.dommages ?? 0); | ||||
|       let dmgBase = dommages ?? Number(arme.system.dommages ?? 0); | ||||
|       //Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278) | ||||
|       return dmgBase + Math.min(dmgBase, arme.system.magique ? arme.system.ecaille_efficacite : 0); | ||||
|     } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { ChatUtility } from "./chat-utility.js"; | ||||
| import { ENTITE_BLURETTE, HIDE_DICE, renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | ||||
| import { 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"; | ||||
| @@ -15,7 +15,7 @@ import { RdDItemCompetence } from "./item-competence.js"; | ||||
| import { MAP_PHASE, RdDInitiative } from "./initiative.mjs"; | ||||
| import RollDialog from "./roll/roll-dialog.mjs"; | ||||
| import { PART_DEFENSE } from "./roll/roll-part-defense.mjs"; | ||||
| import { DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs"; | ||||
| import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs"; | ||||
| import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js"; | ||||
| import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs"; | ||||
| import { RollBasicParts } from "./roll/roll-basic-parts.mjs"; | ||||
| @@ -56,6 +56,12 @@ export class RdDCombatManager extends Combat { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   static getCombatant(actorId, tokenId) { | ||||
|     return game.combat.combatants.find(it => it.actor.id == actorId && | ||||
|       it.token.id == tokenId | ||||
|     ); | ||||
|   } | ||||
|   /* -------------------------------------------- */ | ||||
|   async nextRound() { | ||||
|     await this.finDeRound(); | ||||
| @@ -402,7 +408,6 @@ export class RdDCombat { | ||||
|   /* -------------------------------------------- */ | ||||
|   static registerChatCallbacks(html) { | ||||
|     for (let button of [ | ||||
|       '.button-defense', | ||||
|       '.button-parade', | ||||
|       '.button-esquive', | ||||
|       '.button-encaisser', | ||||
| @@ -474,8 +479,6 @@ export class RdDCombat { | ||||
|  | ||||
|     switch (button) { | ||||
|       case '.particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); | ||||
|       case '.button-defense': return this.defenseV2(attackerRoll); | ||||
|  | ||||
|       case '.button-parade': return this.parade(attackerRoll, armeParadeId); | ||||
|       case '.button-esquive': return this.esquive(attackerRoll, compId, competence); | ||||
|       case '.button-encaisser': return this.encaisser(attackerRoll, defenderRoll); | ||||
| @@ -601,7 +604,7 @@ export class RdDCombat { | ||||
|   /* -------------------------------------------- */ | ||||
|   async proposerAjustementTirLancer(rollData) { | ||||
|     if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) { | ||||
|       if (this.defender.isEntite([ENTITE_BLURETTE])) { | ||||
|       if (this.defender.isEntiteBlurette()) { | ||||
|         ChatMessage.create({ | ||||
|           content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`, | ||||
|           whisper: ChatUtility.getGMs() | ||||
| @@ -725,26 +728,24 @@ export class RdDCombat { | ||||
|   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 defenseData = RollBasicParts.prepareDefense(attackerRoll) | ||||
|  | ||||
|     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) | ||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', defenseData) | ||||
|     }); | ||||
|     // flag pour garder les jets d'attaque/defense | ||||
|     ChatUtility.setMessageData(choixDefense, 'rollData', defense) | ||||
|     ChatUtility.setMessageData(choixDefense, 'demande-defense', true) | ||||
|     ChatUtility.setMessageData(choixDefense, 'rollData', { | ||||
|       ids: defenseData.ids, | ||||
|       attackerRoll: RollDialog.saveParts(attackerRoll), | ||||
|       passeArme: defenseData.passeArme | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -799,7 +800,7 @@ export class RdDCombat { | ||||
|       essais: {} | ||||
|     }; | ||||
|  | ||||
|     if (this.attacker.isCreatureEntite()) { | ||||
|     if (this.attacker.isCreatureOuEntite()) { | ||||
|       MappingCreatureArme.setRollDataCreature(rollData); | ||||
|     } | ||||
|     else if (arme) { | ||||
| @@ -868,7 +869,7 @@ export class RdDCombat { | ||||
|   async _onAttaqueNormale(attackerRoll) { | ||||
|     console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll); | ||||
|  | ||||
|     attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); | ||||
|     attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker); | ||||
|     let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } | ||||
|     attackerRoll.show = { | ||||
|       cible: this.defender?.getAlias() ?? 'la cible', | ||||
| @@ -1054,7 +1055,7 @@ export class RdDCombat { | ||||
|     dialog.render(true); | ||||
|   } | ||||
|  | ||||
|   async defenseV2(attackerRoll) { | ||||
|   async defenseV2(attackerRoll, callbacks = []) { | ||||
|     // this._prepareParade(attackerRoll, arme, competence); | ||||
|     RollDialog.loadRollData(attackerRoll) | ||||
|     await this.doRollDefense({ | ||||
| @@ -1067,7 +1068,7 @@ export class RdDCombat { | ||||
|       type: { allowed: [ROLL_TYPE_DEFENSE], current: ROLL_TYPE_DEFENSE }, | ||||
|       attackerRoll: attackerRoll, | ||||
|       passeArme: attackerRoll.passeArme, | ||||
|     }) | ||||
|     }, callbacks) | ||||
|   } | ||||
|  | ||||
|   async doRollDefense(rollData, callbacks = []) { | ||||
| @@ -1106,7 +1107,7 @@ export class RdDCombat { | ||||
|       show: {} | ||||
|     }; | ||||
|  | ||||
|     if (this.defender.isCreatureEntite()) { | ||||
|     if (this.defender.isCreatureOuEntite()) { | ||||
|       MappingCreatureArme.setRollDataCreature(defenderRoll); | ||||
|     } | ||||
|  | ||||
| @@ -1233,7 +1234,7 @@ export class RdDCombat { | ||||
|       show: {} | ||||
|     }; | ||||
|  | ||||
|     if (this.defender.isCreatureEntite()) { | ||||
|     if (this.defender.isCreatureOuEntite()) { | ||||
|       MappingCreatureArme.setRollDataCreature(rollData); | ||||
|     } | ||||
|     return rollData; | ||||
|   | ||||
| @@ -4,6 +4,8 @@ import { ChatUtility } from "./chat-utility.js"; | ||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | ||||
| import { RdDRoll } from "./rdd-roll.js"; | ||||
| import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs"; | ||||
| import { MAP_PHASE } from "./initiative.mjs"; | ||||
| import { RdDCombatManager } from "./rdd-combat.js"; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| export class RdDEmpoignade { | ||||
| @@ -12,6 +14,49 @@ export class RdDEmpoignade { | ||||
|   static init() { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static isCombatantEmpoignade(actorId, tokenId) { | ||||
|     const combatant = RdDCombatManager.getCombatant(actorId, tokenId) | ||||
|     return MAP_PHASE.empoignade.rang == combatant?.system.init.rang | ||||
|   } | ||||
|  | ||||
|   static async ajustementEmpoignade(attacker, defender, adjust = 1) { | ||||
|     const empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||
|     const empId = empoignade?.system.empoignadeid ?? foundry.utils.randomID(16) | ||||
|     if (empoignade) { | ||||
|       if (empoignade.system.empoigneurid == defender.id) { | ||||
|         adjust = - adjust | ||||
|       } | ||||
|       empoignade.system.pointsemp += adjust | ||||
|       await RdDEmpoignade.$updateEtatEmpoignade(empoignade, attacker, defender) | ||||
|     } | ||||
|     else { | ||||
|       await RdDEmpoignade.$createEtatEmpoignade({ | ||||
|         name: `Empoignade de ${attacker.name} sur ${defender.name}`, | ||||
|         type: ITEM_TYPES.empoignade, | ||||
|         system: { | ||||
|           description: "", | ||||
|           empoignadeid: empId, | ||||
|           empoigneurid: attacker.id, | ||||
|           empoigneid: defender.id, | ||||
|           pointsemp: adjust, | ||||
|           empoigneurname: attacker.name, | ||||
|           empoignename: defender.name | ||||
|         } | ||||
|       }, attacker, defender) | ||||
|     } | ||||
|     const result = RdDEmpoignade.getEmpoignadeById(defender, empId); | ||||
|     const defGrappled = result.system.pointsemp == (result.system.empoigneid == defender.id ? 2 : -2) | ||||
|     const attGrappled = result.system.pointsemp == (result.system.empoigneurid == attacker.id ? -2 : 2) | ||||
|     const grappling = Math.abs(result.system.pointsemp) > 0 | ||||
|     await defender.setEffect(STATUSES.StatusGrappling, grappling && !defGrappled) | ||||
|     await attacker.setEffect(STATUSES.StatusGrappling, grappling && !attGrappled) | ||||
|     await defender.setEffect(STATUSES.StatusGrappled, defGrappled) | ||||
|     await attacker.setEffect(STATUSES.StatusGrappled, attGrappled) | ||||
|     return result | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static registerChatCallbacks(html) { | ||||
|     $(html).on("click", '.defense-empoignade-cac', event => { | ||||
| @@ -184,7 +229,7 @@ export class RdDEmpoignade { | ||||
|       selectedCarac: attacker.system.carac.melee, | ||||
|       malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender) | ||||
|     } | ||||
|     if (attacker.isCreatureEntite()) { | ||||
|     if (attacker.isCreatureOuEntite()) { | ||||
|       MappingCreatureArme.setRollDataCreature(rollData) | ||||
|     } | ||||
|     if (empoignade.system.pointsemp >= 2) { | ||||
| @@ -237,10 +282,7 @@ export class RdDEmpoignade { | ||||
|  | ||||
|  | ||||
|     if (rollData.rolled.isSuccess && isNouvelle) { | ||||
|       const objectEmpoignade = rollData.empoignade.toObject(); | ||||
|       // Creer l'empoignade sur attaquant/defenseur | ||||
|       attacker.creerObjetParMJ(objectEmpoignade); | ||||
|       defender.creerObjetParMJ(objectEmpoignade); | ||||
|       RdDEmpoignade.$createEtatEmpoignade(rollData.empoignade) | ||||
|     } | ||||
|  | ||||
|     rollData.empoignade.isSuccess = rollData.rolled.isSuccess; | ||||
| @@ -259,7 +301,7 @@ export class RdDEmpoignade { | ||||
|       return | ||||
|     } | ||||
|  | ||||
|     let empoignade = this.getEmpoignade(attacker, defender) | ||||
|     let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||
|  | ||||
|     if (!empoignade) { | ||||
|       ui.notifications.warn("Une erreur s'est produite : Aucune empoignade trouvée !!") | ||||
| @@ -317,18 +359,33 @@ export class RdDEmpoignade { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async $updateEtatEmpoignade(empoignade) { | ||||
|     console.log("UPDATE Empoignade", empoignade) | ||||
|   static async $createEtatEmpoignade(empoignade) { | ||||
|     console.log("CREATE Empoignade", empoignade) | ||||
|  | ||||
|     let defender = game.actors.get(empoignade.system.empoigneid) | ||||
|     let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid) | ||||
|     let update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol } | ||||
|     await defender.updateEmbeddedDocuments('Item', [update]) | ||||
|  | ||||
|     let attacker = game.actors.get(empoignade.system.empoigneurid) | ||||
|     emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid) | ||||
|     update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol } | ||||
|     await attacker.updateEmbeddedDocuments('Item', [update]) | ||||
|  | ||||
|     // Creer l'empoignade sur attaquant/defenseur | ||||
|     await attacker.creerObjetParMJ(empoignade) | ||||
|     await defender.creerObjetParMJ(empoignade) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async $updateEtatEmpoignade(empoignade, attacker, defender) { | ||||
|     console.log("UPDATE Empoignade", empoignade) | ||||
|     const belligerants = [ | ||||
|       attacker ?? game.actors.get(empoignade.system.empoigneurid), | ||||
|       defender ?? game.actors.get(empoignade.system.empoigneid)] | ||||
|  | ||||
|     await Promise.all( | ||||
|       belligerants.map(async belligerant => { | ||||
|         const emp = RdDEmpoignade.getEmpoignadeById(belligerant, empoignade.system.empoignadeid) | ||||
|         return await belligerant.updateEmbeddedDocuments('Item', [{ | ||||
|           _id: emp._id, | ||||
|           "system.pointsemp": empoignade.system.pointsemp, | ||||
|           "system.ausol": empoignade.system.ausol | ||||
|         }]) | ||||
|       })) | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
| @@ -347,7 +404,7 @@ export class RdDEmpoignade { | ||||
|     if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { | ||||
|       return | ||||
|     } | ||||
|     let empoignade = this.getEmpoignade(attacker, defender) | ||||
|     let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||
|  | ||||
|     empoignade.system.ausol = true | ||||
|     await this.$updateEtatEmpoignade(empoignade) | ||||
| @@ -366,7 +423,7 @@ export class RdDEmpoignade { | ||||
|     if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { | ||||
|       return | ||||
|     } | ||||
|     let empoignade = this.getEmpoignade(attacker, defender) | ||||
|     let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||
|  | ||||
|     await defender.setEffect(STATUSES.StatusProne, true); | ||||
|     await this.$deleteEmpoignade(empoignade) | ||||
| @@ -382,7 +439,7 @@ export class RdDEmpoignade { | ||||
|     if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { | ||||
|       return | ||||
|     } | ||||
|     let empoignade = this.getEmpoignade(attacker, defender) | ||||
|     let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||
|  | ||||
|     //console.log("Perte d'endurance :!!!", perteMode) | ||||
|     let endValue = defender.system.sante.endurance.value | ||||
| @@ -423,9 +480,17 @@ export class RdDEmpoignade { | ||||
|   /* -------------------------------------------- */ | ||||
|   static async createEmpoignade(attacker, defender) { | ||||
|     return await Item.create({ | ||||
|       name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name, | ||||
|       type: 'empoignade', | ||||
|       system: { description: "", empoignadeid: foundry.utils.randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name } | ||||
|       name: "Empoignade de " + attacker.name + ' sur ' + defender.name, | ||||
|       type: ITEM_TYPES.empoignade, | ||||
|       system: { | ||||
|         description: "", | ||||
|         empoignadeid: foundry.utils.randomID(16), | ||||
|         empoigneurid: attacker.id, | ||||
|         empoigneid: defender.id, | ||||
|         pointsemp: 0, | ||||
|         empoigneurname: attacker.name, | ||||
|         empoignename: defender.name | ||||
|       } | ||||
|     }, | ||||
|       { | ||||
|         temporary: true | ||||
|   | ||||
| @@ -95,7 +95,7 @@ export class RdDPossession { | ||||
|  | ||||
|   static selectCompetenceDraconicOuPossession(rollData, rollingActor) { | ||||
|     rollData.competence = rollingActor.getDraconicOuPossession(); | ||||
|     if (rollingActor.isCreatureEntite()) { | ||||
|     if (rollingActor.isCreatureOuEntite()) { | ||||
|       const carac = rollingActor.system.carac | ||||
|       rollData.carac = carac | ||||
|       rollData.competence.system.defaut_carac = 'reve' | ||||
|   | ||||
| @@ -16,17 +16,20 @@ const levelDown = [ | ||||
| ]; | ||||
| const levelImpossible = { score: 0, norm: 0, sign: 0, part: 0, epart: 0, etotal: 1 }; | ||||
|  | ||||
| const reussiteNormale = { code: "norm", isPart: false, isSign: false, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 1, ptQualite: 0, quality: "Réussite normale", condition: (target, roll) => (roll > target.sign && roll <= target.norm) }; | ||||
| const reussiteSignificative = { code: "sign", isPart: false, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 2, ptQualite: 1, quality: "Réussite significative", condition: (target, roll) => (roll > target.part && roll <= target.sign) }; | ||||
| const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false } | ||||
|  | ||||
| const reussites = [ | ||||
|   { code: "etotal", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: -4, ptQualite: -6, quality: "Echec total", condition: (target, roll) => roll >= target.etotal && roll <= 100 }, | ||||
|   { code: "epart", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: false, ptTache: -2, ptQualite: -4, quality: "Echec particulier", condition: (target, roll) => (roll >= target.epart && roll < target.etotal) }, | ||||
|   { code: "echec", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Echec normal", condition: (target, roll) => (roll > target.norm && roll < target.etotal) }, | ||||
|   { code: "norm", isPart: false, isSign: false, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 1, ptQualite: 0, quality: "Réussite normale", condition: (target, roll) => (roll > target.sign && roll <= target.norm) }, | ||||
|   { code: "sign", isPart: false, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 2, ptQualite: 1, quality: "Réussite significative", condition: (target, roll) => (roll > target.part && roll <= target.sign) }, | ||||
|   reussiteNormale, | ||||
|   reussiteSignificative, | ||||
|   { code: "part", isPart: true, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 3, ptQualite: 2, quality: "Réussite Particulière!", condition: (target, roll) => (roll > 0 && roll <= target.part) }, | ||||
|   { code: "error", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: 0, ptQualite: 0, quality: "Jet de dés invalide", condition: (target, roll) => (roll <= 0 || roll > 100) } | ||||
| ]; | ||||
|  | ||||
| const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false } | ||||
| /* -------------------------------------------- */ | ||||
| const CARAC_MAXIMUM_RESOLUTION = 40; | ||||
| /* -------------------------------------------- */ | ||||
| @@ -157,7 +160,7 @@ export class RdDResolutionTable { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static replaceParticuliereDemiSurprise(chances){ | ||||
|   static replaceParticuliereDemiSurprise(chances) { | ||||
|     foundry.utils.mergeObject(chances, reussites.find(x => x.code == 'part'), { overwrite: true }); | ||||
|   } | ||||
|  | ||||
| @@ -165,7 +168,7 @@ export class RdDResolutionTable { | ||||
|   static significativeRequise(chances) { | ||||
|     chances.roll = Math.min(chances.part + 1, chances.sign) | ||||
|     foundry.utils.mergeObject(chances, reussites.find(x => x.code == 'sign'), { overwrite: true }); | ||||
|   }   | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static succesRequis(chances) { | ||||
| @@ -197,6 +200,7 @@ export class RdDResolutionTable { | ||||
|       if (chances.norm < roll * diviseur) { | ||||
|         return reussiteInsuffisante | ||||
|       } | ||||
|       return reussiteSignificative | ||||
|     } | ||||
|     return reussite | ||||
|   } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { ENTITE_BLURETTE, ENTITE_INCARNE, renderTemplate } from "./constants.js"; | ||||
| import { ENTITE_NONINCARNE, RDD_CONFIG, renderTemplate } from "./constants.js"; | ||||
| import { RdDUtility } from "./rdd-utility.js"; | ||||
|  | ||||
| /** | ||||
| @@ -16,34 +16,29 @@ export class RdDEncaisser extends Dialog { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   constructor(html, actor) { | ||||
|     let dialogConf = { | ||||
|     if (actor.isEntiteNonIncarnee([ENTITE_NONINCARNE])) { | ||||
|       throw `${actor.name} est une entité non incarnée et ne peut pas subnir de dommages` | ||||
|     } | ||||
|  | ||||
|     const dialogConf = { | ||||
|       title: "Jet d'Encaissement", | ||||
|       content: html, | ||||
|     } | ||||
|  | ||||
|     if (!actor.isEntite()) { | ||||
|       dialogConf.default = "mortel"; | ||||
|       dialogConf.buttons = { | ||||
|         "mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") }, | ||||
|         "non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") }, | ||||
|         "sonne": { label: "Sonné", callback: html => this.actor.setSonne() }, | ||||
|       }; | ||||
|     } | ||||
|     else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])) { | ||||
|       dialogConf.default = "entiteincarnee" | ||||
|       dialogConf.buttons = { | ||||
|         "entiteincarnee": { label: "Entité incarnée", callback: html => this.performEncaisser("entiteincarnee") } | ||||
|       default: RDD_CONFIG.encaissement.mortel, | ||||
|       buttons: { | ||||
|         [RDD_CONFIG.encaissement.mortel]: { label: "Mortel", callback: html => this.performEncaisser(RDD_CONFIG.encaissement.mortel) }, | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     let dialogOptions = { | ||||
|       classes: ["rdd-roll-dialog"], | ||||
|       width: 320, | ||||
|       height: 'fit-content' | ||||
|     if (!actor.isEntite()) { | ||||
|       dialogConf.buttons[RDD_CONFIG.encaissement.nonmortel] = { label: "Non-mortel", callback: html => this.performEncaisser(RDD_CONFIG.encaissement.nonmortel) } | ||||
|       dialogConf.buttons["sonne"] = { label: "Sonné", callback: html => this.actor.setSonne() } | ||||
|     } | ||||
|  | ||||
|     // Select proper roll dialog template and stuff | ||||
|     super(dialogConf, dialogOptions); | ||||
|     super(dialogConf, { | ||||
|       classes: ["rdd-roll-dialog"], | ||||
|       width: 320, | ||||
|       height: 'fit-content' | ||||
|     }); | ||||
|  | ||||
|     this.actor = actor; | ||||
|     this.modifier = 0; | ||||
|   | ||||
| @@ -8,7 +8,7 @@ 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, renderTemplate } from "./constants.js"; | ||||
| import { ACTOR_TYPES, RDD_CONFIG, renderTemplate } from "./constants.js"; | ||||
| import { EMPOIGNADE } from "./item/arme.js"; | ||||
|  | ||||
| /** | ||||
| @@ -206,7 +206,7 @@ export class RdDRoll extends Dialog { | ||||
|       this.updateRollResult(html); | ||||
|     }); | ||||
|     this.html.find("input.check-mortalite").change((event) => { | ||||
|       this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel"; | ||||
|       this.rollData.dmg.mortalite = event.currentTarget.checked ? RDD_CONFIG.encaissement.nonmortel : RDD_CONFIG.encaissement.mortel; | ||||
|       this.updateRollResult(html); | ||||
|     }); | ||||
|     this.html.find('.cuisine-proportions').change((event) => { | ||||
| @@ -333,8 +333,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("input.check-mortalite").prop('checked', rollData.dmg.mortalite == RDD_CONFIG.encaissement.nonmortel); | ||||
|     this.html.find("label.dmg-arme-actor").text(rollData.dmg.isEmpoignade ? EMPOIGNADE : Misc.toSignedString(rollData.dmg.total)); | ||||
|     this.html.find("label.arme-mortalite").text(rollData.dmg.mortalite); | ||||
|     this.html.find("div.placeholder-ajustements").empty().append(adjustements); | ||||
|     this.html.find("div.placeholder-resolution").empty().append(resolutionTable) | ||||
|   | ||||
| @@ -75,30 +75,27 @@ const fatigueLineMalus = [0, -1, -2, -3, -4, -5, -6, -7]; | ||||
| /* -------------------------------------------- */ | ||||
| const nomEthylisme = ["Emeché", "Gris", "Pinté", "Pas frais", "Ivre", "Bu", "Complètement fait", "Ivre mort"]; | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| const definitionsEncaissement = { | ||||
|   "mortel": [ | ||||
|     { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, | ||||
|     { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, | ||||
|     { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2 }, | ||||
|     { minimum: 16, maximum: 19, endurance: "2d6", vie: "2", gravite: 4 }, | ||||
|     { minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", gravite: 6 }, | ||||
|   ], | ||||
|   "non-mortel": [ | ||||
|     { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, | ||||
|     { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, | ||||
|     { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 }, | ||||
|     { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 2 }, | ||||
|     { minimum: 20, maximum: undefined, endurance: "100", vie: "0", gravite: 2 }, | ||||
|   ], | ||||
|   "entiteincarnee": [ | ||||
|     { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, | ||||
|     { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, | ||||
|     { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 }, | ||||
|     { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 0 }, | ||||
|     { minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", gravite: 0 }, | ||||
|   ] | ||||
| }; | ||||
| const TABLE_ENCAISSEMENT_MORTEL = [ | ||||
|   { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, | ||||
|   { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, | ||||
|   { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2 }, | ||||
|   { minimum: 16, maximum: 19, endurance: "2d6", vie: "2", gravite: 4 }, | ||||
|   { minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", gravite: 6 }, | ||||
| ] | ||||
| const TABLE_ENCAISSEMENT_NONMORTEL = [ | ||||
|   { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, | ||||
|   { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, | ||||
|   { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 }, | ||||
|   { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 2 }, | ||||
|   { minimum: 20, maximum: undefined, endurance: "100", vie: "0", gravite: 2 }, | ||||
| ] | ||||
| const TABLE_ENCAISSEMENT_ENTITE = [ | ||||
|   { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, | ||||
|   { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, | ||||
|   { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2 }, | ||||
|   { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 4 }, | ||||
|   { minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", gravite: 6 }, | ||||
| ] | ||||
|  | ||||
| /* -------------------------------------------- */ | ||||
| export class RdDUtility { | ||||
| @@ -278,7 +275,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 +283,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,7 +296,7 @@ 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))) | ||||
| @@ -613,20 +610,20 @@ export class RdDUtility { | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async getLocalisation(type = 'personnage') { | ||||
|     const loc = { result:  await RdDDice.rollTotal("1d20")}; | ||||
|     const loc = { result: await RdDDice.rollTotal("1d20") }; | ||||
|     if (type == 'personnage') { | ||||
|       if (loc.result <= 3) loc.txt =  "Jambe, genou, pied, jarret"; | ||||
|       else if (loc.result <= 7) loc.txt =  "Hanche, cuisse, fesse"; | ||||
|       else if (loc.result <= 9) loc.txt =  "Ventre, reins"; | ||||
|       else if (loc.result <= 12) loc.txt =  "Poitrine, dos"; | ||||
|       else if (loc.result <= 14) loc.txt =  "Avant-bras, main, coude"; | ||||
|       else if (loc.result <= 18) loc.txt =  "Epaule, bras, omoplate"; | ||||
|       else if (loc.result == 19) loc.txt =  "Tête"; | ||||
|       else if (loc.result == 20) loc.txt =  "Tête (visage)"; | ||||
|       if (loc.result <= 3) loc.txt = "Jambe, genou, pied, jarret"; | ||||
|       else if (loc.result <= 7) loc.txt = "Hanche, cuisse, fesse"; | ||||
|       else if (loc.result <= 9) loc.txt = "Ventre, reins"; | ||||
|       else if (loc.result <= 12) loc.txt = "Poitrine, dos"; | ||||
|       else if (loc.result <= 14) loc.txt = "Avant-bras, main, coude"; | ||||
|       else if (loc.result <= 18) loc.txt = "Epaule, bras, omoplate"; | ||||
|       else if (loc.result == 19) loc.txt = "Tête"; | ||||
|       else if (loc.result == 20) loc.txt = "Tête (visage)"; | ||||
|     } else { | ||||
|       if (loc.result <= 7) loc.txt =  "Jambes/Pattes"; | ||||
|       else if (loc.result <= 18) loc.txt =  "Corps"; | ||||
|       else if (loc.result <= 20) loc.txt =  "Tête"; | ||||
|       if (loc.result <= 7) loc.txt = "Jambes/Pattes"; | ||||
|       else if (loc.result <= 18) loc.txt = "Corps"; | ||||
|       else if (loc.result <= 20) loc.txt = "Tête"; | ||||
|     } | ||||
|     return loc | ||||
|   } | ||||
| @@ -671,13 +668,13 @@ export class RdDUtility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static async prepareEncaissement(actor, dmg, roll, armure) { | ||||
|   static async prepareEncaissement(targetActor, dmg, roll, armure) { | ||||
|     const jetTotal = roll.total + dmg.total - armure | ||||
|     const encaissement = RdDUtility._selectEncaissement(jetTotal, dmg.mortalite); | ||||
|     const over20 = Math.max(jetTotal - 20, 0); | ||||
|     const encaissement = RdDUtility.$selectEncaissement(targetActor, jetTotal, dmg.mortalite) | ||||
|     const over20 = Math.max(jetTotal - 20, 0) | ||||
|     encaissement.dmg = dmg | ||||
|     if (ReglesOptionnelles.isUsing('localisation-aleatoire')) { | ||||
|       encaissement.dmg.loc = dmg.loc ?? await RdDUtility.getLocalisation(actor.type) | ||||
|       encaissement.dmg.loc = dmg.loc ?? await RdDUtility.getLocalisation(targetActor.type) | ||||
|       encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;' | ||||
|     } | ||||
|     else { | ||||
| @@ -693,15 +690,21 @@ export class RdDUtility { | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   static _selectEncaissement(degats, mortalite) { | ||||
|     const table = definitionsEncaissement[mortalite] === undefined ? definitionsEncaissement["mortel"] : definitionsEncaissement[mortalite]; | ||||
|     for (let encaissement of table) { | ||||
|       if ((encaissement.minimum === undefined || encaissement.minimum <= degats) | ||||
|         && (encaissement.maximum === undefined || degats <= encaissement.maximum)) { | ||||
|         return foundry.utils.duplicate(encaissement); | ||||
|       } | ||||
|   static $selectEncaissement(targetActor, degats, mortalite) { | ||||
|     const table = RdDUtility.$getTableEncaissement(targetActor, mortalite) | ||||
|     const encaissement = table.find(it => ((it.minimum ?? degats) <= degats && degats <= (it.maximum ?? degats))) | ||||
|     return foundry.utils.duplicate(encaissement ?? table[0]) | ||||
|   } | ||||
|  | ||||
|   static $getTableEncaissement(targetActor, mortalite) { | ||||
|     if (targetActor.isEntite()) { | ||||
|       return TABLE_ENCAISSEMENT_ENTITE | ||||
|     } | ||||
|     return foundry.utils.duplicate(table[0]); | ||||
|     switch (mortalite) { | ||||
|       case RDD_CONFIG.encaissement.nonmortel: return TABLE_ENCAISSEMENT_NONMORTEL | ||||
|       case RDD_CONFIG.encaissement.entiteincarnee: return TABLE_ENCAISSEMENT_ENTITE | ||||
|     } | ||||
|     return TABLE_ENCAISSEMENT_MORTEL | ||||
|   } | ||||
|  | ||||
|   /* -------------------------------------------- */ | ||||
|   | ||||
| @@ -5,13 +5,13 @@ 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" | ||||
| import { RollTypeMeditation } from "./roll-type-meditation.mjs" | ||||
| import { PART_DEFENSE } from "./roll-part-defense.mjs" | ||||
| import { PART_ATTAQUE } from "./roll-part-attaque.mjs" | ||||
| import { RdDRollTables } from "../rdd-rolltables.js" | ||||
| import { RdDEmpoignade } from "../rdd-empoignade.js" | ||||
|  | ||||
| export default class ChatRollResult { | ||||
|   static init() { | ||||
| @@ -67,7 +67,7 @@ export default class ChatRollResult { | ||||
|   isShowEncaissement(roll) { | ||||
|     switch (roll.type.current) { | ||||
|       case ROLL_TYPE_DEFENSE: | ||||
|         return roll.rolled.isEchec && roll.attackerRoll?.dmg.mortalite != EMPOIGNADE | ||||
|         return roll.rolled.isEchec | ||||
|     } | ||||
|     return false | ||||
|   } | ||||
| @@ -132,6 +132,7 @@ export default class ChatRollResult { | ||||
|   async chatListeners(html) { | ||||
|     $(html).on("click", '.appel-chance', event => this.onClickAppelChance(event)) | ||||
|     $(html).on("click", '.appel-destinee', event => this.onClickAppelDestinee(event)) | ||||
|     $(html).on("click", '.button-defense', event => this.onClickDefense(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)) | ||||
| @@ -219,18 +220,41 @@ export default class ChatRollResult { | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   async onClickEncaissement(event) { | ||||
|   async onClickDefense(event) { | ||||
|     const chatMessage = ChatUtility.getChatMessage(event) | ||||
|     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||
|     const attackerRoll = savedRoll.attackerRoll | ||||
|     this.getCombat(attackerRoll)?.defenseV2(attackerRoll, | ||||
|       [roll => { ChatUtility.removeChatMessageId(chatMessage.id) }] | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   async onClickEncaissement(event) { | ||||
|     const chatMessage = ChatUtility.getChatMessage(event) | ||||
|     const isMessageDemande = ChatUtility.getMessageData(chatMessage, 'demande-defense') | ||||
|     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||
|     const attaque = savedRoll.attackerRoll | ||||
|     const defender = game.actors.get(savedRoll.ids.actorId) | ||||
|     const attacker = game.actors.get(savedRoll.ids.opponentId) | ||||
|     const defenderToken = savedRoll.ids.actorTokenId ? canvas.tokens.get(savedRoll.ids.actorTokenId) : undefined | ||||
|     const attackerToken = savedRoll.ids.opponentTokenId ? canvas.tokens.get(savedRoll.ids.opponentTokenId) : undefined | ||||
|     await defender?.encaisserDommages(attaque.dmg, attacker, undefined, attackerToken, defenderToken) | ||||
|  | ||||
|     savedRoll.done.encaissement = true | ||||
|     await this.updateChatMessage(chatMessage, savedRoll) | ||||
|     switch (attaque.dmg.mortalite) { | ||||
|       case RDD_CONFIG.encaissement.empoignade: | ||||
|         savedRoll.done = savedRoll.done ?? {} | ||||
|         savedRoll.done.empoignade = await RdDEmpoignade.ajustementEmpoignade(attackerToken.actor, defenderToken.actor) | ||||
|         break | ||||
|       case RDD_CONFIG.encaissement.entiteincarnee: | ||||
|       case RDD_CONFIG.encaissement.nonmortel: | ||||
|       case RDD_CONFIG.encaissement.mortel: | ||||
|         const defender = defenderToken?.actor ?? game.actors.get(savedRoll.ids.actorId) | ||||
|         const attacker = attackerToken?.actor ?? game.actors.get(savedRoll.ids.opponentId) | ||||
|         await defender?.encaisserDommages(attaque.dmg, attacker, undefined, attackerToken, defenderToken) | ||||
|         break | ||||
|     } | ||||
|     if (isMessageDemande) { | ||||
|       ChatUtility.removeChatMessageId(chatMessage.id) | ||||
|     } else { | ||||
|       savedRoll.done.encaissement = true | ||||
|       await this.updateChatMessage(chatMessage, savedRoll) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async onClickRecul(event) { | ||||
|   | ||||
| @@ -26,7 +26,7 @@ export class RollBasicParts { | ||||
|   static loadSurprise(who, forceRequise) { | ||||
|     if (who?.actor) { | ||||
|       foundry.utils.mergeObject(who, | ||||
|         StatusEffects.getActorEffetSurprise(who.actor, forceRequise), | ||||
|         StatusEffects.getActorEffetSurprise(who.actor), | ||||
|         { overwrite: true, inPlace: true }) | ||||
|     } | ||||
|   } | ||||
| @@ -54,13 +54,27 @@ export class RollBasicParts { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static prepareDefense(attackerRoll) { | ||||
|     if (!attackerRoll.passeArme) { | ||||
|       attackerRoll.passeArme = foundry.utils.randomID(16); | ||||
|     } | ||||
|     return { | ||||
|       ids: RollBasicParts.reverseIds(attackerRoll), | ||||
|       active: attackerRoll.opponent, | ||||
|       opponent: attackerRoll.active, | ||||
|       attackerRoll: attackerRoll, | ||||
|       passeArme: attackerRoll.passeArme, | ||||
|       show: { encaissement: true } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static reverseIds(rollData) { | ||||
|     return { | ||||
|       sceneId: rollData.ids.sceneId, | ||||
|       actorId: rollData.ids.opponentId, | ||||
|       actorTokenId: rollData.ids.opponentTokenId, | ||||
|       opponentId: rollData.ids.actorId, | ||||
|       opponentTokenId: rollData.actorTokenId | ||||
|       opponentTokenId: rollData.ids.actorTokenId | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,7 @@ 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 DEFAULT_ROLL_TYPES = [ROLL_TYPE_COMP, ROLL_TYPE_ATTAQUE, ROLL_TYPE_TACHE, ROLL_TYPE_MEDITATION, ROLL_TYPE_CUISINE, ROLL_TYPE_OEUVRE, ROLL_TYPE_JEU] | ||||
|  | ||||
|  | ||||
| export const DIFF = { | ||||
|   | ||||
| @@ -96,7 +96,7 @@ export class RollDialogAdapter { | ||||
|       rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rollData.selectedCarac.value, rolled.roll) | ||||
|       rolled.ajustementNecessaire = rolled.niveauNecessaire - diff | ||||
|     } | ||||
|     rollData.ajustements = rollData.ajustements.map(aj => { return { label: aj.label, value: aj.value } }) | ||||
|     rollData.ajustements = rollData.ajustements.map(a => { return { label: a.label, value: a.value } }) | ||||
|   } | ||||
|  | ||||
|   static adjustDemiSurprise(rollData) { | ||||
| @@ -124,7 +124,7 @@ export class RollDialogAdapter { | ||||
|  | ||||
|     const attaque = rollData.current.attaque; | ||||
|     const choix = [] | ||||
|     const isEmpoignade = attaque.dmg.mortalite == 'empoignade'; | ||||
|     const isEmpoignade = attaque.dmg.isEmpoignade | ||||
|     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) | ||||
| @@ -165,8 +165,6 @@ export class RollDialogAdapter { | ||||
|       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), | ||||
|   | ||||
| @@ -44,6 +44,8 @@ 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"; | ||||
| import { RollPartEmpoignade } from "./roll-part-empoignade.mjs"; | ||||
| import { RollPartEmpoignadeTaille } from "./roll-part-empoignade-taille.mjs"; | ||||
|  | ||||
|  | ||||
| const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api | ||||
| @@ -85,6 +87,8 @@ const ROLL_PARTS = [ | ||||
|   new RollPartConditions(), | ||||
|   new RollPartEthylisme(), | ||||
|   new RollPartMalusArmure(), | ||||
|   new RollPartEmpoignadeTaille(), | ||||
|   new RollPartEmpoignade(), | ||||
|   new RollPartEncTotal(), | ||||
|   new RollPartSurEnc(), | ||||
|   new RollPartAppelMoral(), | ||||
|   | ||||
| @@ -1,15 +1,25 @@ | ||||
| import { RDD_CONFIG } from "../constants.js" | ||||
| import { ATTAQUE_TYPE_MELEE } from "../item/arme.js" | ||||
| import { RdDBonus } from "../rdd-bonus.js" | ||||
| import { DIFF, ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs" | ||||
| import { CARACS } from "../rdd-carac.js" | ||||
| import { RdDEmpoignade } from "../rdd-empoignade.js" | ||||
| import { DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP } from "./roll-constants.mjs" | ||||
| import RollDialog from "./roll-dialog.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 { PART_SIGN } from "./roll-part-sign.mjs" | ||||
| import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||
|  | ||||
| export const PART_ATTAQUE = 'attaque' | ||||
|  | ||||
| const TACTIQUES = RdDBonus.tactiques.filter(it => it.isTactique) | ||||
|  | ||||
| const FILTER_ATTAQUE_EMPOIGNADE = attaque => attaque.arme.isEmpoignade() | ||||
| const FILTER_ATTAQUE_NON_EMPOIGNADE = attaque => !attaque.arme.isEmpoignade() | ||||
| const FILTER_ATTAQUE_EMPOIGNE = attaque => attaque.arme.isUtilisableEmpoigne() && ATTAQUE_TYPE_MELEE.includes(attaque.main) | ||||
|  | ||||
| export class RollPartAttaque extends RollPartSelect { | ||||
|  | ||||
|   get code() { return PART_ATTAQUE } | ||||
| @@ -20,7 +30,8 @@ export class RollPartAttaque extends RollPartSelect { | ||||
|   loadRefs(rollData) { | ||||
|     const refs = this.getRefs(rollData) | ||||
|     const attaques = rollData.active.actor.listAttaques() | ||||
|     refs.attaques = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor)) | ||||
|     refs.all = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor)) | ||||
|     this.filterAttaquesEmpoignade(rollData) | ||||
|     refs.tactiques = TACTIQUES | ||||
|     if (refs.attaques.length > 0) { | ||||
|       const attaque = this.findAttaque(refs.attaques, this.getSaved(rollData)) | ||||
| @@ -28,6 +39,10 @@ export class RollPartAttaque extends RollPartSelect { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   isAttaqueEmpoignade(it) { | ||||
|     return it.arme.isEmpoignade() | ||||
|   } | ||||
|  | ||||
|   store(rollData, targetData) { | ||||
|     super.store(rollData, targetData) | ||||
|     this.getSaved(targetData).dmg = this.getCurrent(rollData).dmg | ||||
| @@ -36,7 +51,7 @@ export class RollPartAttaque extends RollPartSelect { | ||||
|   restore(rollData) { | ||||
|     const saved = this.getSaved(rollData) | ||||
|     super.restore(rollData) | ||||
|     if (saved.dmg) { | ||||
|     if (saved.dmg != undefined) { | ||||
|       this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg | ||||
|     } | ||||
|   } | ||||
| @@ -57,10 +72,23 @@ export class RollPartAttaque extends RollPartSelect { | ||||
|   } | ||||
|  | ||||
|   prepareContext(rollData) { | ||||
|     this.filterAttaquesEmpoignade(rollData) | ||||
|     const current = this.getCurrent(rollData) | ||||
|     current.dmg = RdDBonus.dmgRollV2(rollData, current) | ||||
|   } | ||||
|  | ||||
|   filterAttaquesEmpoignade(rollData) { | ||||
|     const refs = this.getRefs(rollData) | ||||
|     const isEmpoignade = RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) | ||||
|     refs.isEmpoignadeEnCours = RdDEmpoignade.isEmpoignadeEnCours(rollData.active.actor) | ||||
|     const filterAttaques = isEmpoignade ? | ||||
|       FILTER_ATTAQUE_EMPOIGNADE | ||||
|       : refs.isEmpoignadeEnCours | ||||
|         ? FILTER_ATTAQUE_EMPOIGNE | ||||
|         : FILTER_ATTAQUE_NON_EMPOIGNADE | ||||
|     refs.attaques = refs.all.filter(filterAttaques) | ||||
|   } | ||||
|  | ||||
|   getAjustements(rollData) { | ||||
|     const current = this.getCurrent(rollData) | ||||
|     const tactique = current.tactique ? [{ label: current.tactique.label, value: current.tactique.attaque }] : [] | ||||
| @@ -77,6 +105,7 @@ export class RollPartAttaque extends RollPartSelect { | ||||
|     const selectAttaque = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-attaque"]`) | ||||
|     const selectTactique = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-tactique"]`) | ||||
|     const checkMortalite = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="check-mortalite"]`) | ||||
|     const utiliserDagueEmpoignade = rollDialog.element.querySelector(`roll-section[name="${this.code}"] a.utiliser-dague-empoignade`) | ||||
|     const current = this.getCurrent(rollDialog.rollData) | ||||
|  | ||||
|     selectAttaque.addEventListener("change", e => { | ||||
| @@ -94,9 +123,26 @@ export class RollPartAttaque extends RollPartSelect { | ||||
|     }) | ||||
|  | ||||
|     checkMortalite?.addEventListener("change", e => { | ||||
|       current.dmg.mortalite = (e.currentTarget.checked ? 'mortel' : 'non-mortel') | ||||
|       current.dmg.mortalite = (e.currentTarget.checked ? RDD_CONFIG.encaissement.mortel : RDD_CONFIG.encaissement.nonmortel) | ||||
|       rollDialog.render() | ||||
|     }) | ||||
|     utiliserDagueEmpoignade?.addEventListener("click", e => { | ||||
|       e.preventDefault() | ||||
|       const rollData = rollDialog.rollData | ||||
|       this.utiliserDagueEmpoignade(rollData) | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   utiliserDagueEmpoignade(rollData) { | ||||
|     RollDialog.create({ | ||||
|       ids: { actorId: rollData.ids.actorId, actorTokenId: rollData.ids.actorTokenId }, | ||||
|       type: { allowed: [ROLL_TYPE_COMP], current: ROLL_TYPE_COMP }, | ||||
|       selected: { | ||||
|         carac: { key: CARACS.DEXTERITE, forced: true }, | ||||
|         comp: { key: 'Dague', forced: true }, | ||||
|         diff: { type: DIFF.IMPOSEE, value: -4 } | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   impactOtherPart(part, rollData) { | ||||
| @@ -110,7 +156,9 @@ export class RollPartAttaque extends RollPartSelect { | ||||
|             part.setDiff(rollData, { type: DIFF.ATTAQUE, value: current.initialDiff }) | ||||
|             current.initialDiff = undefined | ||||
|           } | ||||
|           break | ||||
|         } | ||||
|         case PART_SIGN: return part.setArme(rollData, false, current.forceRequise) | ||||
|       } | ||||
|     } | ||||
|     return undefined | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| import { Grammar } from "../grammar.js" | ||||
| import { RollPartSelect } from "./roll-part-select.mjs" | ||||
| import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||
|  | ||||
| @@ -12,22 +13,36 @@ export class RollPartCarac extends RollPartSelect { | ||||
|  | ||||
|   loadRefs(rollData) { | ||||
|     const refs = this.getRefs(rollData) | ||||
|     refs.all = this.$getActorCaracs(rollData) | ||||
|     const selected = this.getSelected(rollData) | ||||
|     const actor = rollData.active.actor | ||||
|     refs.all = [...this.$getActorCaracs(actor), ...this.$getCaracCompetenceCreature(actor)] | ||||
|       .filter(c => !selected.forced || | ||||
|             (selected.key ? | ||||
|               Grammar.includesLowerCaseNoAccent(c.label, selected.key) | ||||
|               : c.key == '') | ||||
|           ) | ||||
|     refs.caracs = refs.all | ||||
|     this.$selectCarac(rollData) | ||||
|   } | ||||
|  | ||||
|   choices(refs) { return refs.caracs } | ||||
|  | ||||
|   $getActorCaracs(rollData) { | ||||
|     return Object.entries(rollData.active.actor.getCarac()) | ||||
|   $getActorCaracs(actor) { | ||||
|     return Object.entries(actor.getCarac()) | ||||
|       .filter(([key, c]) => key != 'taille') | ||||
|       /* TODO: filter by context */ | ||||
|       .map(([key, carac]) => { | ||||
|         return RollPartCarac.$extractCarac(key, carac) | ||||
|       }) | ||||
|   } | ||||
|  | ||||
|   $getCaracCompetenceCreature(actor) { | ||||
|     if (actor.isPersonnage()) { | ||||
|       return [] | ||||
|     } | ||||
|     return actor.getCompetences() | ||||
|       .map(it => { return { key: it.name, label: it.name, value: parseInt(it.system.carac_value) } }) | ||||
|   } | ||||
|  | ||||
|   static $extractCarac(key, carac) { | ||||
|     return { | ||||
|       key: key, | ||||
| @@ -40,7 +55,6 @@ export class RollPartCarac extends RollPartSelect { | ||||
|     allowed = allowed.filter(it => it != undefined) | ||||
|     const refs = this.getRefs(rollData) | ||||
|     refs.caracs = allowed.length > 0 | ||||
|       // ? refs.all.filter(it => allowed.includes(Grammar.toLowerCaseNoAccent(it.key))) | ||||
|       ? refs.all.filter(it => allowed.includes(it.key)) | ||||
|       : refs.all | ||||
|     this.$selectCarac(rollData) | ||||
|   | ||||
| @@ -18,12 +18,16 @@ 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 == '') | ||||
|       ) | ||||
|     const all = this.$getActorComps(rollData) | ||||
|     if (selected.forced) { | ||||
|       refs.all = all.filter(comp => Grammar.equalsInsensitive(comp.label, selected.key)) | ||||
|       if (refs.all.length == 0) { | ||||
|         refs.all = all.filter(comp => Grammar.includesLowerCaseNoAccent(comp.label, selected.key)) | ||||
|       } | ||||
|     } | ||||
|     else { | ||||
|       refs.all = all | ||||
|     } | ||||
|     refs.comps = refs.all | ||||
|     this.$selectComp(rollData) | ||||
|   } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { ITEM_TYPES } from "../constants.js" | ||||
| import { ITEM_TYPES, RDD_CONFIG } from "../constants.js" | ||||
| import { ATTAQUE_TYPE, RdDItemArme } from "../item/arme.js" | ||||
| import { CARACS } from "../rdd-carac.js" | ||||
| import { DIFF, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" | ||||
| @@ -15,6 +15,8 @@ export class RollPartDefense extends RollPartSelect { | ||||
|  | ||||
|   get code() { return PART_DEFENSE } | ||||
|   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||
|  | ||||
|   isValid(rollData) { return rollData.attackerRoll != undefined } | ||||
|   visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_DEFENSE) } | ||||
|  | ||||
|   static getDiffAttaque(attackerRoll) { | ||||
| @@ -27,13 +29,22 @@ export class RollPartDefense extends RollPartSelect { | ||||
|     const attackerRoll = rollData.attackerRoll | ||||
|     const defenseur = rollData.active.actor | ||||
|     refs.isDistance = [ATTAQUE_TYPE.TIR, ATTAQUE_TYPE.LANCER].find(it => it == attackerRoll?.main) | ||||
|     const esquives = refs.isDistance == ATTAQUE_TYPE.TIR ? [] : defenseur.getCompetencesEsquive() | ||||
|       .map(it => RollPartDefense.$extractEsquive(it, defenseur)) | ||||
|     const isEmpoignade = attackerRoll.dmg.isEmpoignade | ||||
|     const isEmpoignadeEnCours = isEmpoignade && defenseur.itemTypes[ITEM_TYPES.empoignade].find(it => | ||||
|       [it.system.empoigneurid, it.system.empoigneid].includes(rollData.ids.opponentId) && | ||||
|       it.system.pointsemp != 0) | ||||
|  | ||||
|     const parades = defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier())) | ||||
|       .map(it => RollPartDefense.$extractParade(it, attackerRoll?.arme, defenseur)) | ||||
|     const esquives = (refs.isDistance == ATTAQUE_TYPE.TIR || isEmpoignadeEnCours) | ||||
|       ? [] | ||||
|       : defenseur.getCompetencesEsquive() | ||||
|     const parades = isEmpoignade | ||||
|       ? [RdDItemArme.empoignade(defenseur)] | ||||
|       : defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier())) | ||||
|  | ||||
|     refs.defenses = [...esquives, ...parades].filter(it => it != undefined) | ||||
|     refs.defenses = [ | ||||
|       ...esquives.map(it => RollPartDefense.$extractEsquive(it, defenseur)), | ||||
|       ...parades.map(it => RollPartDefense.$extractParade(it, attackerRoll?.arme, defenseur)) | ||||
|     ] | ||||
|     this.$selectDefense(rollData) | ||||
|   } | ||||
|  | ||||
| @@ -101,7 +112,7 @@ export class RollPartDefense extends RollPartSelect { | ||||
|         case PART_CARAC: return part.filterCaracs(rollData, [current.carac]) | ||||
|         case PART_COMP: return part.filterComps(rollData, [current.comp?.name]) | ||||
|         case PART_DIFF: return part.setDiff(rollData, this.getDiffDefense(rollData)) | ||||
|         case PART_SIGN: return part.setArmeDisparate(rollData, this.isArmeDisparate(rollData)) | ||||
|         case PART_SIGN: return part.setArme(rollData, this.isArmeDisparate(rollData), current.forceRequise) | ||||
|       } | ||||
|     } | ||||
|     return undefined | ||||
|   | ||||
							
								
								
									
										40
									
								
								module/roll/roll-part-empoignade-taille.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								module/roll/roll-part-empoignade-taille.mjs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| import { RDD_CONFIG } from "../constants.js" | ||||
| import { ATTAQUE_TYPE_MELEE } from "../item/arme.js" | ||||
| import { RdDEmpoignade } from "../rdd-empoignade.js" | ||||
| import { COMBAT_ROLL_TYPES } from "./roll-constants.mjs" | ||||
| import { PART_ATTAQUE } from "./roll-part-attaque.mjs" | ||||
| import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||
|  | ||||
| const EMPOIGNADE_TAILLE = "empoignade-taille" | ||||
|  | ||||
| export class RollPartEmpoignadeTaille extends RollPartCheckbox { | ||||
|  | ||||
|   get code() { return EMPOIGNADE_TAILLE } | ||||
|  | ||||
|   isValid(rollData) { | ||||
|     return RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) | ||||
|   } | ||||
|  | ||||
|   visible(rollData) { | ||||
|     return COMBAT_ROLL_TYPES.includes(rollData.type.current) && | ||||
|       RdDEmpoignade.isEmpoignadeEnCours(rollData.active.actor) && | ||||
|       this.getTailleDiff(rollData) != 0 | ||||
|   } | ||||
|  | ||||
|   getTailleDiff(rollData) { | ||||
|     const taille = rollData.active.actor.getTaille() | ||||
|     const tailleOpponent = rollData.opponent.actor.getTaille() | ||||
|     const diff = taille - tailleOpponent | ||||
|     const diffTailleAbs = Math.max(0, Math.abs(diff) - 1) | ||||
|     const signDiff = Math.sign(diff) | ||||
|     return signDiff * diffTailleAbs | ||||
|   } | ||||
|  | ||||
|   getCheckboxIcon(rollData) { return `<img src="${RDD_CONFIG.icons.empoignade}">` } | ||||
|   getCheckboxLabel(rollData) { | ||||
|     return `Taille ${rollData.active.actor.getTaille()} vs ${rollData.opponent.actor.getTaille()} ` | ||||
|   } | ||||
|   getCheckboxValue(rollData) { | ||||
|     return this.getTailleDiff(rollData) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										30
									
								
								module/roll/roll-part-empoignade.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								module/roll/roll-part-empoignade.mjs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| import { RDD_CONFIG } from "../constants.js" | ||||
| import { ATTAQUE_TYPE_MELEE } from "../item/arme.js" | ||||
| import { RdDEmpoignade } from "../rdd-empoignade.js" | ||||
| import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs" | ||||
| import { PART_ATTAQUE } from "./roll-part-attaque.mjs" | ||||
| import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||
|  | ||||
| const EMPOIGNADE = "empoignade" | ||||
|  | ||||
| export class RollPartEmpoignade extends RollPartCheckbox { | ||||
|  | ||||
|   get code() { return EMPOIGNADE } | ||||
|  | ||||
|   isValid(rollData) { | ||||
|     return RdDEmpoignade.isCombatantEmpoignade(rollData.ids.opponentId, rollData.ids.opponentTokenId) && | ||||
|       !RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) | ||||
|   } | ||||
|  | ||||
|   visible(rollData) { | ||||
|     return rollData.type.current == ROLL_TYPE_ATTAQUE && | ||||
|       ATTAQUE_TYPE_MELEE.includes(rollData.current[PART_ATTAQUE].main) && | ||||
|       RdDEmpoignade.isCombatantEmpoignade(rollData.ids.opponentId, rollData.ids.opponentTokenId) && | ||||
|       !RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) && | ||||
|       !RdDEmpoignade.isEmpoignadeEnCours(rollData.active.actor) | ||||
|   } | ||||
|  | ||||
|   getCheckboxIcon(rollData) { return `<img src="${RDD_CONFIG.icons.empoignade}">` } | ||||
|   getCheckboxLabel(rollData) { return "vs. empoigneur" } | ||||
|   getCheckboxValue(rollData) { return 4 } | ||||
| } | ||||
| @@ -1,3 +1,4 @@ | ||||
| import { RDD_CONFIG } from "../constants.js" | ||||
| import { RdDItemCompetence } from "../item-competence.js" | ||||
| import { RdDCarac } from "../rdd-carac.js" | ||||
| import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||
| @@ -25,7 +26,7 @@ export class RollPartEncTotal extends RollPartCheckbox { | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   getCheckboxIcon(rollData) { return '<i class="fa-solid fa-weight-hanging"></i>' } | ||||
|   getCheckboxIcon(rollData) { return `<img src="${RDD_CONFIG.icons.surenc}">` } | ||||
|   getCheckboxLabel(rollData) { return "Enc. total" } | ||||
|   getCheckboxValue(rollData) { return - rollData.active.actor.getEncTotal() } | ||||
| } | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| import { ITEM_TYPES } from "../constants.js" | ||||
| import { Grammar } from "../grammar.js" | ||||
| import { CARACS, RdDCarac } from "../rdd-carac.js" | ||||
| import { CARACS } from "../rdd-carac.js" | ||||
| import { RdDTimestamp } from "../time/rdd-timestamp.js" | ||||
| import { TMRUtility } from "../tmr-utility.js" | ||||
| import { ROLL_TYPE_MEDITATION } from "./roll-constants.mjs" | ||||
| import { PART_CARAC } from "./roll-part-carac.mjs" | ||||
| import { PART_CARAC, RollPartCarac } 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" | ||||
| @@ -34,8 +34,9 @@ export class RollPartMeditation extends RollPartSelect { | ||||
|  | ||||
|   loadRefs(rollData) { | ||||
|     const refs = this.getRefs(rollData) | ||||
|     refs.meditations = rollData.active.actor.itemTypes[ITEM_TYPES.meditation] | ||||
|       .map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor)) | ||||
|     const actor = rollData.active.actor | ||||
|     refs.meditations = actor.itemTypes[ITEM_TYPES.meditation] | ||||
|       .map(it => RollPartMeditation.$extractMeditation(it, actor)) | ||||
|  | ||||
|     if (refs.meditations.length > 0) { | ||||
|       this.$selectMeditation(rollData) | ||||
| @@ -73,7 +74,7 @@ export class RollPartMeditation extends RollPartSelect { | ||||
|  | ||||
|   getAjustements(rollData) { | ||||
|     const malus = this.getMalusEchecs(rollData) | ||||
|     const malusEchecs = malusEchecs == 0 ? [] : [{ label: "Méditation", value: malus }] | ||||
|     const malusEchecs = malus == 0 ? [] : [{ label: "Méditation", value: malus }] | ||||
|     const malusConditions = { label: "Conditions", value: this.getMalusConditions(rollData) } | ||||
|     return [malusConditions, ...malusEchecs] | ||||
|   } | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { RDD_CONFIG } from "../constants.js" | ||||
| import { Misc } from "../misc.js" | ||||
| import { ReglesOptionnelles } from "../settings/regles-optionnelles.js" | ||||
| import { StatusEffects } from "../settings/status-effects.js" | ||||
| import { demiReveStatusEffect, StatusEffects } from "../settings/status-effects.js" | ||||
| import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" | ||||
| import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs" | ||||
|  | ||||
| @@ -39,29 +40,30 @@ export class RollPartSign extends RollPart { | ||||
|     const isCombat = this.isCombat(rollData) | ||||
|     const current = this.getCurrent(rollData) | ||||
|     current.armeDisparate = isCombat && current.armeDisparate | ||||
|     current.surprise = actor.getSurprise(isCombat) // TODO: could be from rollData.active.surprise?? | ||||
|     current.reasons = actor.getEffects(it => StatusEffects.niveauSurprise(it) > 0).map(it => it.name) | ||||
|     current.surprise = actor.getSurprise(isCombat, current.forceRequise ?? 0)  | ||||
|     current.reasons = actor.getEffects(it => StatusEffects.niveauSurprise(it, isCombat) > 0, current.forceRequise ?? 0) | ||||
|       .map(it => { return { img: it.img, label: game.i18n.localize(it.name) } }) | ||||
|     current.diviseur = 1 | ||||
|     if (current.surprise == 'demi') { | ||||
|       current.diviseur *= 2 | ||||
|     } | ||||
|     if (isCombat && actor.isDemiReve()) { | ||||
|       current.reasons.push('Demi-rêve en combat') | ||||
|       current.reasons.push({ img: RDD_CONFIG.icons.demiReve, label: 'Demi-rêve en combat' }) | ||||
|     } | ||||
|     if (this.isParadeArmeDisparate(current)) { | ||||
|       current.diviseur *= 2 | ||||
|       current.reasons.push('Armes disparates') | ||||
|       current.reasons.push({ img: RDD_CONFIG.icons.armesDisparates, label: 'Armes disparates' }) | ||||
|     } | ||||
|     if (this.isAttaqueFinesse(rollData)) { | ||||
|       current.diviseur *= 2 | ||||
|       current.reasons.push('Particulière en finesse') | ||||
|       current.reasons.push({ img: RDD_CONFIG.particuliere.finesse.img, label: 'Particulière en finesse' }) | ||||
|     } | ||||
|  | ||||
|     if (!ReglesOptionnelles.isUsing('tripleSignificative')) { | ||||
|       current.diviseur = Math.min(current.diviseur, 4); | ||||
|     } | ||||
|  | ||||
|     current.reason = current.reasons.join(', ') | ||||
|     current.reason = current.reasons.map(it => it.label).join(', ') | ||||
|   } | ||||
|  | ||||
|   isAttaqueFinesse(rollData) { | ||||
| @@ -76,8 +78,16 @@ export class RollPartSign extends RollPart { | ||||
|     const current = this.getCurrent(rollData) | ||||
|     if (current.surprise == 'demi') { | ||||
|       return [ | ||||
|         { label: 'Significative requise ' + Misc.getFractionOneN(current.diviseur) }, | ||||
|         ...current.reasons.map(it => { return { label: '<i class="fa-solid fa-triangle-exclamation"></i> ' + it } }) | ||||
|         { | ||||
|           label: 'Significative requise ' + Misc.getFractionOneN(current.diviseur) | ||||
|         }, | ||||
|         ...current.reasons.map(it => { | ||||
|           return { | ||||
|             label: it.img | ||||
|               ? `<img src="${it.img}"> ${it.label}` | ||||
|               : `<i class="fa-solid fa-triangle-exclamation"></i> ${it.label}` | ||||
|           } | ||||
|         }) | ||||
|       ] | ||||
|     } | ||||
|     return [] | ||||
| @@ -92,7 +102,9 @@ export class RollPartSign extends RollPart { | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   setArmeDisparate(rollData, armeDisparate) { | ||||
|     this.getCurrent(rollData).armeDisparate = armeDisparate | ||||
|   setArme(rollData, armeDisparate, forceRequise) { | ||||
|     const current = this.getCurrent(rollData) | ||||
|     current.armeDisparate = armeDisparate | ||||
|     current.forceRequise = forceRequise | ||||
|   } | ||||
| } | ||||
| @@ -1,3 +1,4 @@ | ||||
| import { RDD_CONFIG } from "../constants.js" | ||||
| import { RdDCarac } from "../rdd-carac.js" | ||||
| import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||
|  | ||||
| @@ -10,7 +11,7 @@ export class RollPartSurEnc extends RollPartCheckbox { | ||||
|   visible(rollData) { | ||||
|     return RdDCarac.isActionPhysique(rollData.current.carac.key) && rollData.active.actor.isSurenc() | ||||
|   } | ||||
|   getCheckboxIcon(rollData) { return '<i class="fa-solid fa-weight-hanging"></i>' } | ||||
|   getCheckboxIcon(rollData) { return `<img src="${RDD_CONFIG.icons.surenc}">` } | ||||
|   getCheckboxLabel(rollData) { return "Sur-enc." } | ||||
|   getCheckboxValue(rollData) { return rollData.active.actor.computeMalusSurEncombrement() } | ||||
| } | ||||
|   | ||||
| @@ -30,7 +30,8 @@ export class RollPart { | ||||
|       rollData.selected[this.code] = {} | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** l'acteur actif du jet */ | ||||
|   getActor(rollData) { return rollData.active.actor } | ||||
|   /** le conteneur de données du RollPart */ | ||||
|   getRefs(rollData) { | ||||
|     return rollData.refs[this.code] | ||||
|   | ||||
| @@ -47,6 +47,7 @@ export class RollType { | ||||
|   } | ||||
|  | ||||
|   setDiffType(rollData, type) { | ||||
|     type = rollData.selected[PART_DIFF].type ?? type | ||||
|     rollData.current[PART_DIFF].type = type | ||||
|     this.setRollDataType(rollData) | ||||
|   } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { SYSTEM_RDD } from "../constants.js"; | ||||
| import { RDD_CONFIG, SYSTEM_RDD } from "../constants.js"; | ||||
| import { Misc } from "../misc.js"; | ||||
| import { RdDBonus } from "../rdd-bonus.js"; | ||||
|  | ||||
| @@ -14,14 +14,17 @@ export const STATUSES = { | ||||
|   StatusBleeding: 'bleeding', | ||||
|   StatusDead: 'dead', | ||||
|   StatusDemiReve: 'demi-reve', | ||||
|   StatusSurEnc: 'sur-encombrement', | ||||
|   StatusForceWeak: 'force insuffisante', | ||||
| } | ||||
|  | ||||
| const forceWeakStatusEffect = { rdd: true, id: STATUSES.StatusForceWeak, name: 'EFFECT.StatusForceWeak', img: 'systems/foundryvtt-reve-de-dragon/assets/actions/weak.svg' }; | ||||
| const demiReveStatusEffect = { rdd: true, id: STATUSES.StatusDemiReve, name: 'EFFECT.StatusDemiReve', img: 'systems/foundryvtt-reve-de-dragon/assets/actions/sort.svg' }; | ||||
| export const forceWeakStatusEffect = { rdd: true, id: STATUSES.StatusForceWeak, name: 'EFFECT.StatusForceWeak', img: RDD_CONFIG.icons.forceWeak }; | ||||
| export const surEncEffect = { rdd: true, id: STATUSES.StatusSurEnc, name: 'EFFECT.StatusSurEnc', img: RDD_CONFIG.icons.surenc }; | ||||
| export const demiReveStatusEffect = { rdd: true, id: STATUSES.StatusDemiReve, name: 'EFFECT.StatusDemiReve', img: RDD_CONFIG.icons.demiReve }; | ||||
|  | ||||
| const rddStatusEffects = [ | ||||
|   { rdd: true, id: STATUSES.StatusGrappling, tint: '#33cc33', name: 'EFFECT.StatusGrappling', img: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' }, | ||||
|   { rdd: true, id: STATUSES.StatusGrappled, tint: '#ff9900', name: 'EFFECT.StatusGrappled', img: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp' }, | ||||
|   { rdd: true, id: STATUSES.StatusGrappling, name: 'EFFECT.StatusGrappling', img: RDD_CONFIG.icons.empoignade }, | ||||
|   { rdd: true, id: STATUSES.StatusGrappled, tint: '#d5633d', name: 'EFFECT.StatusGrappled', img: RDD_CONFIG.icons.empoignade }, | ||||
|  | ||||
|   { rdd: true, id: STATUSES.StatusRestrained, name: 'EFFECT.StatusRestrained', img: 'icons/svg/net.svg' }, | ||||
|   { rdd: true, id: STATUSES.StatusStunned, name: 'EFFECT.StatusStunned', img: 'icons/svg/stoned.svg', "duration.rounds": 1 }, | ||||
| @@ -34,7 +37,8 @@ const rddStatusEffects = [ | ||||
|   { rdd: true, id: STATUSES.StatusBleeding, name: 'EFFECT.StatusBleeding', img: 'icons/svg/blood.svg' }, | ||||
|   { rdd: true, id: STATUSES.StatusDead, name: 'EFFECT.StatusDead', img: 'icons/svg/skull.svg' }, | ||||
|   demiReveStatusEffect, | ||||
|   forceWeakStatusEffect | ||||
|   forceWeakStatusEffect, | ||||
|   surEncEffect, | ||||
| ]; | ||||
|  | ||||
| const statusDemiSurprise = new Set([STATUSES.StatusStunned, STATUSES.StatusProne, STATUSES.StatusRestrained, STATUSES.StatusForceWeak]) | ||||
| @@ -43,8 +47,9 @@ const statusSurpriseTotale = new Set([STATUSES.StatusUnconscious, STATUSES.Statu | ||||
| export class StatusEffects extends FormApplication { | ||||
|  | ||||
|   static onReady() { | ||||
|     const rddEffectIds = rddStatusEffects.map(it => it.id); | ||||
|     const rddEffectIds = rddStatusEffects.map(it => it.id) | ||||
|     rddStatusEffects.forEach(it => { | ||||
|       it.name = game.i18n.localize(it.name) | ||||
|       it.statuses = new Set([it.id]) | ||||
|     }) | ||||
|     const defaultStatusEffectIds = CONFIG.statusEffects.map(it => it.id); | ||||
| @@ -82,8 +87,8 @@ export class StatusEffects extends FormApplication { | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   static getActorEffetSurprise(actor, forceRequise) { | ||||
|     const effets = actor?.getEffects(StatusEffects.isSurprise, forceRequise) ?? [] | ||||
|   static getActorEffetSurprise(actor) { | ||||
|     const effets = actor?.getEffects(StatusEffects.isSurprise) ?? [] | ||||
|     return { | ||||
|       effets: effets, | ||||
|       surprise: effets.length > 0 | ||||
| @@ -133,7 +138,7 @@ export class StatusEffects extends FormApplication { | ||||
|   } | ||||
|  | ||||
|   static prepareActiveEffect(effectId) { | ||||
|     let status = rddStatusEffects.find(it => it.id == effectId) | ||||
|     let status = rddStatusEffects.find(it => it.statuses.has(effectId)) | ||||
|     if (status) { | ||||
|       status = foundry.utils.duplicate(status) | ||||
|       status.statuses = new Set([effectId]) | ||||
|   | ||||
| @@ -1408,7 +1408,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!1Nng9d8r6lrPHCaJ.MxFDPQmm1900bWin' | ||||
|   - _id: bNUVmIoLEROEIOIm | ||||
|     name: Cuir / Métal | ||||
|     name: Cuir / métal | ||||
|     type: armure | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_metal.webp | ||||
|     effects: [] | ||||
| @@ -1447,7 +1447,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!1Nng9d8r6lrPHCaJ.bNUVmIoLEROEIOIm' | ||||
|   - _id: OKZvybZ9jJuX8ZDY | ||||
|     name: Cuir Epais | ||||
|     name: Cuir épais | ||||
|     type: armure | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_epais.webp | ||||
|     effects: [] | ||||
| @@ -1485,7 +1485,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!1Nng9d8r6lrPHCaJ.OKZvybZ9jJuX8ZDY' | ||||
|   - _id: sgvPgIF2ars8IeHv | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|     effects: [] | ||||
| @@ -1553,7 +1553,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!1Nng9d8r6lrPHCaJ.rZxksRn5Ih4Sj4rN' | ||||
|   - _id: oKCl27wSt33w6j7O | ||||
|     name: Drap Matelassé | ||||
|     name: Drap matelassé | ||||
|     type: armure | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/drap_matelasse.webp | ||||
|     effects: [] | ||||
| @@ -1625,7 +1625,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!1Nng9d8r6lrPHCaJ.Kv9Lb28qekqLU1F7' | ||||
|   - _id: sFm86jqLy1K6q4Px | ||||
|     name: Mailles de Fer | ||||
|     name: Mailles de fer | ||||
|     type: armure | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/mailles.webp | ||||
|     effects: [] | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!ryUZTa17LzNv25UY.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!ohmz9Jn4jxD88Kll.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
| @@ -2028,7 +2028,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!ohmz9Jn4jxD88Kll.c5wursWW03ckpyqn' | ||||
|   - _id: i42zzohNKPYS0kMp | ||||
|     name: Drap Matelassé | ||||
|     name: Drap matelassé | ||||
|     type: armure | ||||
|     sort: 6900000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/drap_matelasse.webp | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!JARnWt2MQWDyRwQt.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
| @@ -2390,7 +2390,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!JARnWt2MQWDyRwQt.RYIOLj7To0rr9RuH' | ||||
|   - _id: bycXvPmShoXAnteu | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 8100000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!SJb0c8FDcYdd41rB.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -2060,7 +2060,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!SJb0c8FDcYdd41rB.EqKsIbamIeYP3GHz' | ||||
|   - _id: tei7L0X6H6kNrQaI | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 7100000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!JQCwAOK64Yijwtch.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
| @@ -2297,7 +2297,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!JQCwAOK64Yijwtch.9mOVjXVNdvnf7isr' | ||||
|   - _id: ISONFNOaWkW2TaE8 | ||||
|     name: Cuir / Métal | ||||
|     name: Cuir / métal | ||||
|     type: armure | ||||
|     sort: 8400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_metal.webp | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!CRRP8ucJpljX6tq8.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!51vL4MhEE0asjgF2.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
| @@ -2202,7 +2202,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!51vL4MhEE0asjgF2.EqKsIbamIeYP3GHz' | ||||
|   - _id: tei7L0X6H6kNrQaI | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 7100000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!NX1nAqKKIcQlyGua.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!2bRaEDuwZezKAyEq.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
| @@ -2028,7 +2028,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!2bRaEDuwZezKAyEq.c5wursWW03ckpyqn' | ||||
|   - _id: cMiKr3BxOauOkMIm | ||||
|     name: Mailles de Fer | ||||
|     name: Mailles de fer | ||||
|     type: armure | ||||
|     sort: 6900000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/mailles.webp | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!IeKSXignUpfUTU4m.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
| @@ -2028,7 +2028,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!IeKSXignUpfUTU4m.c5wursWW03ckpyqn' | ||||
|   - _id: cMiKr3BxOauOkMIm | ||||
|     name: Mailles de Fer | ||||
|     name: Mailles de fer | ||||
|     type: armure | ||||
|     sort: 6900000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/mailles.webp | ||||
|   | ||||
| @@ -1552,7 +1552,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!pSM0ku0RJNLvHSvF.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1552,7 +1552,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!5xPFHgrY5AIP9Mnb.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!U9NNcXQBJmsI9Ttk.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!oLDROOdwfctyRusH.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!2KN3nKGZ36Qkn7Mf.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1605,7 +1605,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!V2WOs8deCYdBT2Jo.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
|   | ||||
| @@ -1605,7 +1605,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!UNs4RBLYiGbfxd1c.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
|   | ||||
| @@ -1605,7 +1605,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!jfXs7qaHEWQpIHud.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!awZg7bGbTjEGRMiw.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
|   | ||||
| @@ -1604,7 +1604,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!dMdBctaRRdGJgced.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     flags: {} | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| name: Survie en Désert | ||||
| name: Survie en désert | ||||
| type: competence | ||||
| img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| _id: vDOAyWc2YnuhNnFF | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| _id: fDwsTMuug0Z5BdaA | ||||
| name: Cuir / Métal | ||||
| name: Cuir / métal | ||||
| type: armure | ||||
| img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_metal.webp | ||||
| effects: [] | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| _id: vQ494sD9FgFI08kZ | ||||
| name: Drap Matelassé | ||||
| name: Drap matelassé | ||||
| type: armure | ||||
| img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/drap_matelasse.webp | ||||
| effects: [] | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!qscItDC5z6Hr2Lrh.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -1961,7 +1961,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!qscItDC5z6Hr2Lrh.c5wursWW03ckpyqn' | ||||
|   - _id: 0s8mKVg0m9CzQKoa | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 100000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1550,7 +1550,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!zACge7QxwyJkC6nD.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5500000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!esJWonwDGLFaMRK3.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -2006,7 +2006,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!esJWonwDGLFaMRK3.LkCSQ9Kh4HD0ENBj' | ||||
|   - _id: RCexiBHCy0K6tGlx | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 6900000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!gscYFtwk73WrGvA5.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -2059,7 +2059,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!gscYFtwk73WrGvA5.lzKudaY9nzr7DkEq' | ||||
|   - _id: 1wjf9mDIMSMHF4Jj | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 7000000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!dW4RMKpz2WaXbW3h.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!ncXFs8oaZWG68Tzn.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!OKMXH6YpPXUyvqzN.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -2052,7 +2052,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!OKMXH6YpPXUyvqzN.a6dPg35gmlWfgbbm' | ||||
|   - _id: nYijZF3MgDRAeOwb | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 7000000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!EzV1Zxuwi7jwa6bj.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -1961,7 +1961,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!EzV1Zxuwi7jwa6bj.c5wursWW03ckpyqn' | ||||
|   - _id: Q359FY95mPDxyQEb | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 6800000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!YQ6vavAVyZecPvGQ.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!b7ThiitioBVXxU7D.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -2047,7 +2047,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!b7ThiitioBVXxU7D.KT8qpVHGD0Ku8TV7' | ||||
|   - _id: YFFEw7kpUAgEdo5R | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 900001 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!XnBXyRyE2BUVVT1k.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!kKI9izKrKftYVnvs.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!nzw2q9BHSDN6TIQQ.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1551,7 +1551,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!Pf4cLn0kandYzviD.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -128,7 +128,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!z87rV5CJ3inc6ZPc.VyAJK54OPjiRt8oH' | ||||
|   - _id: KR10Pvv0bzDem5OP | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 7200000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -16,7 +16,7 @@ background: | ||||
|   alphaThreshold: 0 | ||||
| foreground: null | ||||
| foregroundElevation: 4 | ||||
| thumb: systems/foundryvtt-reve-de-dragon/assets/scenes/YSpVuLeMCX9tAmgn-thumb.webp | ||||
| thumb: systems/foundryvtt-reve-de-dragon/pic/YSpVuLeMCX9tAmgn-thumb.webp | ||||
| width: 1920 | ||||
| height: 1080 | ||||
| padding: 0.25 | ||||
|   | ||||
| @@ -7,7 +7,7 @@ initial: | ||||
|   x: null | ||||
|   'y': null | ||||
|   scale: 0.5 | ||||
| thumb: systems/foundryvtt-reve-de-dragon/assets/scenes/9fmf9lcb3L9XO3bJ-thumb.png | ||||
| thumb: systems/foundryvtt-reve-de-dragon/pic/9fmf9lcb3L9XO3bJ-thumb.png | ||||
| width: 3521 | ||||
| height: 2492 | ||||
| padding: 0.25 | ||||
| @@ -38,7 +38,7 @@ regions: [] | ||||
| ownership: | ||||
|   default: 0 | ||||
| background: | ||||
|   src: systems/foundryvtt-reve-de-dragon/assets/ecran_rdd.webp | ||||
|   src: systems/foundryvtt-reve-de-dragon/pic/ecran_rdd.webp | ||||
|   offsetX: 0 | ||||
|   offsetY: 0 | ||||
|   anchorX: 0 | ||||
|   | ||||
| @@ -668,7 +668,7 @@ results: | ||||
|   - _id: ZhPRAyUuEYcG9X5z | ||||
|     flags: {} | ||||
|     type: pack | ||||
|     text: Survie en Désert | ||||
|     text: Survie en désert | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|     weight: 1 | ||||
|     range: | ||||
|   | ||||
| @@ -1552,7 +1552,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!GJWEoGXy5kSd4sT8.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -2180,7 +2180,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!GJWEoGXy5kSd4sT8.v9ZBfOr9DzqsXj99' | ||||
|   - _id: bRqg1kGSwJ6S82lQ | ||||
|     name: Drap Matelassé | ||||
|     name: Drap matelassé | ||||
|     type: armure | ||||
|     sort: 7600000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/drap_matelasse.webp | ||||
|   | ||||
| @@ -1552,7 +1552,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!m63oPEPvCrds4akp.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
|   | ||||
| @@ -1552,7 +1552,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!jtJqqegMrF3fuND3.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -2129,7 +2129,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!jtJqqegMrF3fuND3.R34t4VV4k8eotNl1' | ||||
|   - _id: YIIwnf5q41kYDvYg | ||||
|     name: Cuir Souple | ||||
|     name: Cuir souple | ||||
|     type: armure | ||||
|     sort: 7500000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
| @@ -1552,7 +1552,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!8Jeas59CdpnnYabL.oHnSnCw1RAW5t15S' | ||||
|   - _id: vDOAyWc2YnuhNnFF | ||||
|     name: Survie en Désert | ||||
|     name: Survie en désert | ||||
|     type: competence | ||||
|     sort: 5400000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/competence_survie_desert.webp | ||||
| @@ -2079,7 +2079,7 @@ items: | ||||
|       coreVersion: '12.331' | ||||
|     _key: '!actors.items!8Jeas59CdpnnYabL.8nMoKLsPd73xCozD' | ||||
|   - _id: 9hg8nq9rCNP1Te02 | ||||
|     name: Cuir Souple incomplet | ||||
|     name: Cuir souple incomplet | ||||
|     type: armure | ||||
|     sort: 7300000 | ||||
|     img: systems/foundryvtt-reve-de-dragon/icons/armes_armures/cuir_souple.webp | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user