Compare commits
	
		
			37 Commits
		
	
	
		
			13.0.2
			...
			5d8da860c4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5d8da860c4 | |||
| 607eedc6d2 | |||
| de2c636064 | |||
| 1ff32697f4 | |||
| 652c435833 | |||
| 74c1f33427 | |||
| 0c6caffde3 | |||
| dc63041682 | |||
| f572b1c4e1 | |||
| 1d63cd54fe | |||
| 15e6127e02 | |||
| afd8c2ac80 | |||
| 18de904849 | |||
| cb48c960c2 | |||
| bd082248d9 | |||
| df9df90ccb | |||
| 0456221cf7 | |||
| 583b4ff003 | |||
| b4ac906802 | |||
| 395c7a4cc3 | |||
| 27bc07f64a | |||
| 2f3ec7bab0 | |||
| 8d39a0526f | |||
| f83548b91e | |||
| 90d17a3477 | |||
| fb15f3eb38 | |||
| 4df0eab574 | |||
| c8d589f0d2 | |||
| d7470836a5 | |||
| 817fa8e62a | |||
| 0fe4f64343 | |||
| d6b5b0a550 | |||
| c9d87851bd | |||
| 5b48fda3d0 | |||
| abae85157b | |||
| da2dca1769 | |||
| 6e405ea753 | 
| @@ -12,8 +12,8 @@ Pseudo : LeRatierBretonnien | |||||||
|  |  | ||||||
| Mainteneur/Développeur : LeRatierBretonnien | Mainteneur/Développeur : LeRatierBretonnien | ||||||
| Développeur : VincentVk | Développeur : VincentVk | ||||||
| Tests, Compendiums, Données: Fred, Fab, Grendel | Tests, Compendiums, Données: Fred, Fab, Grendel, LeRatierBretonnien, VincentVk | ||||||
| Styles/CSS : Mandar | Styles/CSS : Mandar, VincentVk | ||||||
|  |  | ||||||
| # Mentions Légales | # Mentions Légales | ||||||
|  |  | ||||||
| @@ -23,6 +23,6 @@ La carte des Terres Médianes du Rêve est une illustration de **Jidus**, utilis | |||||||
| Les silhouettes des créatures, humanoïdes et entités sont des illustrations de **Roland Barthélémy**, et sont utilisés dans le cadre de ce projet avec son aimable autorisation. | Les silhouettes des créatures, humanoïdes et entités sont des illustrations de **Roland Barthélémy**, et sont utilisés dans le cadre de ce projet avec son aimable autorisation. | ||||||
| Merci à eux !! | Merci à eux !! | ||||||
|  |  | ||||||
| Toute la propriété intellectuelle leur appartient, ce système est une adpatation destinée à fonctionner sous FoundryVTT. | Toute la propriété intellectuelle leur appartient, ce système est une adaptation destinée à fonctionner sous FoundryVTT. | ||||||
|  |  | ||||||
| L'ensemble du code est sous licence Creative Commons. | L'ensemble du code est sous licence Creative Commons. | ||||||
							
								
								
									
										1
									
								
								assets/actions/attaque.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="m214.02 19.115-.02.06a433.415 433.415 0 0 1 106.393 58.446L368.02 158.4C292.254 72.063 181.72 20.678 64.66 20.604c-14.96-.01-30.027.834-45.14 2.535v18.8c108.174-12.774 213.91 21.292 293.527 88.554l42.314 97.416C290.887 132.486 182.425 73.885 66.395 73.21a349.119 349.119 0 0 0-46.879 2.906v18.85c98.998-13.552 196.12 18.532 267.11 82.264l30.708 87.82c-53.922-85.58-148.482-138.656-249.986-139.69a297.451 297.451 0 0 0-47.83 3.398v18.914c93.33-15.18 185.38 18.05 247.677 83.27l20.694 83.917C246.555 230.42 160.67 176.716 67.7 175.423a248.202 248.202 0 0 0-48.182 4.06v19.036c89.513-17.794 178.655 19.16 230.357 89.468l4.62 73.348c-28.973-83.013-107.888-136.692-193.257-135.87a201.938 201.938 0 0 0-41.72 4.78v19.188c77.22-18.904 155.333 13.983 197.095 77.14l5.873 57.49c23.33-6.283 47.534-13.218 68.727-20.873 19.194-6.93 35.884-14.525 46.596-22.038 5.354-3.756 9.142-7.478 11.174-10.574 2.033-3.096 2.47-5.184 2.098-7.59l-1.252-8.123 137.074-39.556C446.897 159.92 363.67 69.964 260.654 19.114H214.02zm278.86 273.922-40.196 11.6c1.63 18.66-4.666 36.567-16.397 52.043-14.18 18.707-35.934 34.627-62.363 48.257-45.23 23.33-104.45 39.877-164.397 47.97l4.38 16.35c68.63-7.66 143.34-22.038 198.17-48.538 30.517-14.75 54.633-33.123 68.722-55.33 12.74-20.084 17.775-43.384 12.08-72.353zm-58.513 16.885-65.027 18.765c-.736 4.345-2.345 8.51-4.733 12.147-3.925 5.98-9.462 10.986-16.068 15.62-13.213 9.266-30.996 17.098-50.978 24.316-31.927 11.53-68.41 20.998-99.558 29.134l6.644 24.79c59.027-7.79 117.64-24.153 160.71-46.366 24.828-12.805 44.388-27.573 56.037-42.94 8.804-11.614 13.283-23.135 12.972-35.466zm-261.754 77.43-33.033 8.85 8.197 30.59c10.812 3.95 18.623 14.38 18.623 26.485 0 6.87-2.52 13.2-6.673 18.114l4.716 17.6 33.034-8.85-24.864-92.788zM138.22 443.79c-1.49 0-2.88.33-4.12.91l-75.6 20.255a30.49 30.49 0 0 1 4.625 16.14c0 .67-.03 1.33-.072 1.987l75.96-20.352c4.96-.386 8.698-4.37 8.698-9.453 0-5.35-4.138-9.488-9.49-9.488zM32.327 468.985c-6.798 0-12.11 5.312-12.11 12.11 0 6.798 5.312 12.11 12.11 12.11 6.798 0 12.111-5.312 12.111-12.11 0-6.798-5.313-12.11-12.11-12.11z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||||
| After Width: | Height: | Size: 2.2 KiB | 
							
								
								
									
										1
									
								
								assets/actions/comp.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="M119.1 25v.1c-25 3.2-47.1 32-47.1 68.8 0 20.4 7.1 38.4 17.5 50.9L99.7 157 84 159.9c-13.7 2.6-23.8 9.9-32.2 21.5-8.5 11.5-14.9 27.5-19.4 45.8-8.2 33.6-9.9 74.7-10.1 110.5h44l11.9 158.4h96.3L185 337.7h41.9c0-36.2-.3-77.8-7.8-111.7-4-18.5-10.2-34.4-18.7-45.9-8.6-11.4-19.2-18.7-34.5-21l-16-2.5L160 144c10-12.5 16.7-30.2 16.7-50.1 0-39.2-24.8-68.8-52.4-68.8-2.9 0-4.7-.1-5.2-.1zM440 33c-17.2 0-31 13.77-31 31s13.8 31 31 31 31-13.77 31-31-13.8-31-31-31zM311 55v48H208v18h103v158h-55v18h55v110H208v18h103v32h80.8c-.5-2.9-.8-5.9-.8-9 0-3.1.3-6.1.8-9H329V297h62.8c-.5-2.9-.8-5.9-.8-9 0-3.1.3-6.1.8-9H329V73h62.8c-.5-2.92-.8-5.93-.8-9 0-3.07.3-6.08.8-9H311zm129 202c-17.2 0-31 13.8-31 31s13.8 31 31 31 31-13.8 31-31-13.8-31-31-31zm0 160c-17.2 0-31 13.8-31 31s13.8 31 31 31 31-13.8 31-31-13.8-31-31-31z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||||
| After Width: | Height: | Size: 996 B | 
							
								
								
									
										1
									
								
								assets/actions/defense.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="M80 32c-64 256 48 416 176 464 128-48 240-208 176-464-112 32-240 32-352 0zm99.3 52.9c14.7 27.9 40.1 26.4 65 26.4l53.9 1.5 7.8 25 77.1 10.3 3.5 49.9c-27.9 7.4-83.7 5.9-83.8 17.7-.2 20.6 36.3 16.2 78.1 5.9L356.7 276l-61.4 4.4c3.8 46.4-1.2 77.6-35.6 110.7l-21.9-55.3c-12.6 22.6-30 38.8-57.3 41.4 10.6-26 19.1-46.7 9.7-76.3-13.5 13.3-35.1 18.7-64.8 16.7 31.6-49 48.3-101.9 62.1-151.9l-23.2-20.6c-6.6-23.5-1.3-44.1 15-60.2z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||||
| After Width: | Height: | Size: 621 B | 
							
								
								
									
										1
									
								
								assets/actions/defense1.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="M261.563 64.28A191.758 191.758 0 0 0 64.25 256a191.758 191.758 0 1 0 383.5 0A191.758 191.758 0 0 0 261.562 64.28zm-4.625 9.126 8.937 5.156v10.313l-8.938 5.156-8.906-5.155V78.562l8.907-5.156zm3.53 29.25A153.407 153.407 0 0 1 409.407 256a153.407 153.407 0 0 1-306.812 0A153.407 153.407 0 0 1 260.47 102.656zm-11.53 20.03a133.607 133.607 0 0 0-65.157 20.908V368.22a133.607 133.607 0 0 0 65.157 21.092V122.688zm17.687.314v266.125a133.607 133.607 0 0 0 63.438-22.03V145a133.607 133.607 0 0 0-63.438-22zm-100.5 34.344A133.607 133.607 0 0 0 122.405 256a133.607 133.607 0 0 0 43.72 98.78V157.345zm-60.72 1.625 8.907 5.155v10.28l-8.906 5.157-8.937-5.156v-10.28l8.936-5.157zm300.5 0 8.94 5.155v10.28l-8.94 5.157-8.905-5.156v-10.28l8.906-5.157zm-58.155.093V353.03A133.607 133.607 0 0 0 389.594 256a133.607 133.607 0 0 0-41.844-96.938zm57.813 173.125 8.937 5.156v10.312l-8.938 5.156-8.906-5.156v-10.312l8.906-5.156zm-299.813.718 8.938 5.156v10.313l-8.938 5.156-8.938-5.155v-10.313l8.938-5.156zm149.906 85.188 8.938 5.156v10.313l-8.938 5.156-8.906-5.158v-10.31l8.906-5.156z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										66
									
								
								assets/actions/jeu.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,66 @@ | |||||||
|  | <?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 310.12469 310.12469" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg6" | ||||||
|  |    sodipodi:docname="jeu.svg" | ||||||
|  |    width="310.12469" | ||||||
|  |    height="310.12469" | ||||||
|  |    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="2532" | ||||||
|  |      inkscape:window-height="1492" | ||||||
|  |      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="155.06205" | ||||||
|  |      inkscape:cy="142.25079" | ||||||
|  |      inkscape:window-x="0" | ||||||
|  |      inkscape:window-y="0" | ||||||
|  |      inkscape:window-maximized="0" | ||||||
|  |      inkscape:current-layer="svg6" /> | ||||||
|  |   <g | ||||||
|  |      class="" | ||||||
|  |      transform="translate(-100.93795,-121.74921)" | ||||||
|  |      id="g4"> | ||||||
|  |     <path | ||||||
|  |        d="m 477.518,181.966 a 25,25 0 0 1 -34.91,23 l -62.29,150.26 h -248.92 l -62.24,-150.19 a 25,25 0 1 1 9.73,-7.29 l 87,71.2 20.92,-126.4 a 25,25 0 1 1 14.7,-1.85 l 54.31,117 54.42,-117.3 a 25,25 0 1 1 14.58,2.08 l 20.93,126.42 87.26,-71.3 a 25,25 0 1 1 44.51,-15.63 z m -71.66,241.25 h -300 v 60 h 300 z m -27.75,-52 h -244.22 v 36 h 244.22 z" | ||||||
|  |        fill="#ffffff" | ||||||
|  |        fill-opacity="1" | ||||||
|  |        transform="matrix(0.7,0,0,0.7,76.8,76.8)" | ||||||
|  |        id="path2" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 2.1 KiB | 
							
								
								
									
										63
									
								
								assets/actions/meditation.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,63 @@ | |||||||
|  | <?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 512 512" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg8" | ||||||
|  |    sodipodi:docname="meditation1.svg" | ||||||
|  |    width="512" | ||||||
|  |    height="512" | ||||||
|  |    inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata14"> | ||||||
|  |     <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="defs12" /> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1" | ||||||
|  |      objecttolerance="10" | ||||||
|  |      gridtolerance="10" | ||||||
|  |      guidetolerance="10" | ||||||
|  |      inkscape:pageopacity="1" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:window-width="3840" | ||||||
|  |      inkscape:window-height="2054" | ||||||
|  |      id="namedview10" | ||||||
|  |      showgrid="true" | ||||||
|  |      fit-margin-top="0" | ||||||
|  |      fit-margin-left="0" | ||||||
|  |      fit-margin-right="0" | ||||||
|  |      fit-margin-bottom="0" | ||||||
|  |      inkscape:zoom="1.4355469" | ||||||
|  |      inkscape:cx="254.56378" | ||||||
|  |      inkscape:cy="255.99978" | ||||||
|  |      inkscape:window-x="-11" | ||||||
|  |      inkscape:window-y="-11" | ||||||
|  |      inkscape:window-maximized="1" | ||||||
|  |      inkscape:current-layer="svg8"> | ||||||
|  |     <inkscape:grid | ||||||
|  |        type="xygrid" | ||||||
|  |        id="grid856" /> | ||||||
|  |   </sodipodi:namedview> | ||||||
|  |   <path | ||||||
|  |      id="polygon2" | ||||||
|  |      style="fill:#ffffff;fill-opacity:1;stroke:none" | ||||||
|  |      d="M 256,0 0,256 256,512 512,256 Z m 5.11719,62.361328 c 8.239,0 15.89463,4.297288 21.83203,12.054688 5.2108,6.811 8.83798,16.231192 9.64648,26.841794 -8.4868,-3.970403 -17.26742,-6.37191 -26.14062,-7.13281 v 12.81836 c 8.5484,0.9429 17.03537,3.85822 25.48437,8.64062 -1.442,8.41469 -4.67333,15.84043 -8.99023,21.48243 -5.9367,7.7574 -13.59443,12.05468 -21.83203,12.05468 -8.2376,0 -15.8726,-4.29728 -21.8086,-12.05468 -4.452,-5.8184 -7.76497,-13.52864 -9.14257,-22.26953 7.8043,-4.21541 15.53348,-6.75681 23.20898,-7.72071 V 94.191406 c -7.938,0.763 -15.87192,2.852576 -23.66992,6.300784 0.9261,-10.297007 4.51857,-19.430374 9.60547,-26.076174 5.936,-7.7581 13.57099,-12.052735 21.80859,-12.052735 z M 228.50391,144.4375 c 0.14,0.1883 0.27391,0.38286 0.41601,0.56836 7.8876,10.3082 19.34232,17.19336 32.19922,17.19336 12.8569,0 24.31162,-6.88586 32.19922,-17.19336 0.1421,-0.1862 0.27797,-0.37936 0.41797,-0.56836 7.2765,3.3453 12.81763,7.79108 15.76953,12.86328 h 0.0449 l 29.11524,45.10547 35.48046,-15.37891 c 20.5632,-11.2833 43.10446,16.80074 21.43946,29.18164 l -66.12891,30.84571 -25.74609,-33.90821 c -11.6662,23.2505 -11.80448,46.48779 6.66992,69.73829 37.3275,-3.0275 65.31156,3.90026 69.47656,19.44726 3.4104,12.7316 -9.91357,28.42679 -33.35937,42.45899 l -66.10743,-21.9629 33.66602,-11.17773 -4.11328,-12.4043 -50.29102,16.69141 -50.26757,-16.69141 -4.11133,12.4043 126.1289,41.89063 15.53321,37.60351 -64.44532,-20.10351 0.0234,-0.22071 c -0.2989,-0.0168 -0.5782,-0.0463 -0.875,-0.0645 l -0.30664,-0.0879 h -1.09375 c -43.1116,-2.7132 -70.90445,-9.13273 -109.87695,-29.64063 -19.6938,-13.027 -30.49667,-27.09126 -27.38867,-38.69726 h -0.0215 c 3.4755,-12.9682 23.51598,-19.95189 51.73438,-20.14649 5.3179,-0.0364 10.93654,0.18537 16.77734,0.63477 19.418,-23.6082 20.76969,-47.21649 7.67969,-70.80859 l -26.6211,35.04296 -66.1289,-30.84375 c -21.665,-12.3816 0.87304,-40.46424 21.43554,-29.18164 l 35.46094,15.37891 29.13672,-45.10547 0.26172,0.0664 c 2.9421,-5.1016 8.50701,-9.56969 15.81641,-12.92969 z m -44.58008,217.70117 c 12.7582,5.6602 24.87218,9.90172 37.20898,13.10352 l -48.91406,15.24609 z" /> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 3.8 KiB | 
							
								
								
									
										1
									
								
								assets/actions/oeuvre.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(2,-1)" style=""><path d="m375.2 23.61-12.7 12.7 24.5 24.5c.5-1.2 1-2.3 1.5-3.5 2.4-6.6 4.1-12.4 4.9-15.5zm33.3 30.5c-.9 3-1.9 5.9-3.3 9.6-4 10.8-9.1 23.4-20.2 30.4-4 2.4-8.1 2.6-11.2 2.3-3.1-.3-5.6-1.1-7.5-1.6-1.7-.4-2.6-.6-3.2-.7-.6.9-1.2 2.2-1.6 4.5-.8 3.19-1 7.49-.8 11.59.1 6 .7 10.5 1.2 13.1l26.8 26.8c2.6.4 7.1 1 13 1.2 7.5.1 14.3-1.8 16-2.7-.1-.8-.2-1.4-.6-2.9-.5-2-1.3-4.5-1.7-7.6-.3-3.1 0-7.3 2.3-11.2 7-11.1 19.6-16.2 30.5-20.3 3.6-1.4 6.6-2.2 9.6-3.1l-16.4-32.89zm-67.2 3.4-12.7 12.7 17.4 17.5c1.3-2.9 3-5.6 5.6-7.9 2.5-2.2 5.6-3.3 8.3-3.7zm128.9 60.99c-3.2.8-9.1 2.4-15.7 5-1.1.4-2.2.8-3.4 1.3l24.6 24.6 12.7-12.7zm-120.7 17.9L217.4 262.3l9.8 9.8 129-129zm86.3 15.5c-.4 2.8-1.5 6-3.8 8.5s-4.8 4.3-7.5 5.6l17.3 17.3 12.7-12.7zm-66.9 3.9L240 284.9l9.7 9.6 125.9-132zm-226.3 94.5c-30.4 0-60.87 11.6-84.13 34.9-46.53 46.5-46.53 121.7 0 168.3C105 500 180.2 500 226.8 453.5c35.8-35.9 43.9-88.5 24.7-132.2L156.8 416l14.9 14.9-12.8 12.7-90.46-90.5 12.73-12.7 14.75 14.7 94.78-94.7c-15.3-6.8-31.7-10.1-48.1-10.1zm60.6 23.2-94.5 94.4 11.3 11.3 94.5-94.4zm24 24L132.7 392l11.2 11.2 94.6-94.4z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										65
									
								
								assets/actions/sort.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" | ||||||
|  |    width="66.69709mm" | ||||||
|  |    height="66.69709mm" | ||||||
|  |    viewBox="0 0 378.10574 378.10571" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg3" | ||||||
|  |    sodipodi:docname="sort.svg" | ||||||
|  |    inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata9"> | ||||||
|  |     <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="defs7" /> | ||||||
|  |   <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="namedview5" | ||||||
|  |      showgrid="false" | ||||||
|  |      inkscape:zoom="3.887601" | ||||||
|  |      inkscape:cx="72.254869" | ||||||
|  |      inkscape:cy="97.300114" | ||||||
|  |      inkscape:window-x="-11" | ||||||
|  |      inkscape:window-y="-11" | ||||||
|  |      inkscape:window-maximized="1" | ||||||
|  |      inkscape:current-layer="svg3" | ||||||
|  |      inkscape:document-rotation="0" | ||||||
|  |      inkscape:snap-text-baseline="true" | ||||||
|  |      fit-margin-top="0" | ||||||
|  |      fit-margin-left="0" | ||||||
|  |      fit-margin-right="0" | ||||||
|  |      fit-margin-bottom="0" /> | ||||||
|  |   <path | ||||||
|  |      id="Sélection #2" | ||||||
|  |      fill="none" | ||||||
|  |      stroke="black" | ||||||
|  |      stroke-width="1" | ||||||
|  |      d="M 189.05286,0 378.10571,189.05286 189.05285,378.10571 0,189.05286 Z m 98.94184,241.93328 c -0.88,-10.41 -2.89,-10.17 -9.87,-16.75 l -5.39,-5.72 c -2.61,-2.12 -6.9,-3.02 -8.72,-5.91 -1.19,-1.9 -0.91,-4.46 -1.28,-6.62 -3.40308,-4.90559 -2.01923,-20.20245 -2.01923,-26.63889 3.88586,-9.60746 4.36923,-1.69111 7.45923,-14.36111 0.62,-2.55 2.32,-6.14 1.21,-8.69 -1.07,-2.43 -3.44,-2.03 -6.71,-5.17 -5.66937,-7.30653 -11.39498,-14.88252 -18.68,-20.92 -23.49144,-15.67176 -34.12005,-20.68725 -60,-20.32 -8.54383,0.23148 -13.2432,0.66798 -20,2.68 -19.05,6.09 -27.58,11.85 -41.76999,25.79 -8.08,7.96 -7.17,10.3 -10.91,14.41 -3.1,3.4 -6.12,3.44 -6.73,7.27 -0.64,1.83 -0.09,3.98 0,5.78 1.91418,8.65633 2.50026,3.00305 7.73101,9.8295 1.38405,9.6854 0.3222,25.26042 -0.70608,33.05113 -2.53556,2.89228 -2.29493,5.91937 -3.63493,7.97937 -1.62,2.49 -4.35,2.16 -7.77,5.03 -5.170004,4.32 -4.470004,8.06 -13.210004,13.28 1.78,5.5 4.63,5.91 10,6 z M 195.6316,118.20709 c 11.22808,5.82176 1.31866,21.02928 -11.27386,31.1911 13.0336,5.31132 -0.79998,6.64062 23.09132,6.48796 l 32.86359,-0.54563 13.5005,1.22254 7.27084,3.68304 c -4.13,5.49 -2.71929,1.23718 -2.08929,8.68718 h -4 c -0.28,-1.68 -0.54282,-4.85331 -1.87282,-6.17331 -3.32127,-0.17387 -9.61514,-0.5831 -13.55025,0.47743 -0.17052,3.22972 -0.29693,4.01588 -0.57693,5.69588 l -3.40923,-0.34102 c -0.28,-1.68 0.27564,-3.83025 -1.05436,-5.15025 -3.7305,-0.17387 -10.29718,-0.7195 -13.48204,0.40923 -1.33,1.32 -0.77437,3.40204 -1.05437,5.08204 h -3 c -0.28,-1.68 0.071,-3.08 -0.91796,-5.08204 -2.83922,-1.53335 -14.39204,-0.93796 -18.08204,-0.91796 -1.96,0.01 -5.02,-0.11 -6.68,1.02 -0.19823,6.27508 -0.4088,8.38327 1.52129,9.86916 l 20.15871,0.0399 v 37.07089 h -19.09 c 0.0887,-5.45486 2.17,-22.09 0,-25.77 -2.24,-3.53 -10.37,-4.58 -13.31,-1.63 -0.59765,14.41964 -0.37159,20.85123 -0.92619,27.34486 -16.5374,0 -13.4074,0.42 -16.5374,0 l -0.13641,-21.94486 c -0.0284,-4.56991 -0.5617,-9.93269 1.12488,-14.46674 3.57532,-2.18241 14.40143,0.2341 20.38143,-0.7259 1.06669,-3.31458 1.12908,-6.5781 0.80651,-10.05451 -2.74793,-0.83105 -4.76282,-0.70285 -7.31282,-0.75285 h -11 c -7.39,0.05 -9.43418,2.79797 -7.61418,10.68797 l -6.48228,0.24114 c 0.72,-2.06 1.97646,-7.02474 0.81646,-9.16474 -1.7,-3.14 -11.93127,-2.75719 -14.21127,-0.43719 -2.03,2.07 -1.8049,7.64421 -1.24493,10.08421 l -7.37013,0.12387 c -0.24405,12.94493 0.23633,18.13752 0.10633,29.28752 -0.09,7.42 0.28,6.88722 -7.99999,7.17722 v -28 c 0,-2.48 0.22,-6.59 -1.17,-8.69 -1.62,-2.42 -4.26,-2.22 -6.83,-2.31 2.73,-7.8 6.25917,-8.9 -1.27083,-9 10.53404,-8.39725 16.12632,-16.70355 22.85717,-22.49183 5.05278,-4.9362 12.06169,-10.2231 15.11169,-11.61765 14.97984,-6.56268 20.63207,-10.69702 43.93886,-10.61671 z m -73.26379,44.49619 c -0.79548,4.04536 -1.9331,12.40663 2.6469,12.48663 10.50353,0.43469 11.50999,-8.2279 8.90999,-11.7879 -1.43,-1.96 -9.22689,-0.64873 -11.55689,-0.69873 z m 19.62689,11.59316 9.01278,-0.14468 0.91722,5.78152 c 0.10638,11.6222 0,0 0.0146,31.52202 -8.59422,-0.32911 -7.4946,-0.52202 -9.9446,-0.52202 z m 80.95177,-0.77164 8.14469,0.22835 -0.0965,36.18013 h -8 z m 19.38582,0.5305 7.6014,-0.33759 0.061,36.21557 h -8 z m -129.12528,49.01235 11.33333,-0.31493 45.72718,-0.54563 59.09028,-0.81845 33.54662,-0.27282 c 7.10809,1.39089 4.61048,5.28283 13.46463,11.36941 -49.05198,-0.38776 -122.72138,-0.48241 -173.42548,-0.8649 z" | ||||||
|  |      style="fill:#d6d2d0;fill-opacity:1;stroke:none" | ||||||
|  |      sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccscccccccccccccsccccccccccccccccccccccccccccccccccc" /> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 5.2 KiB | 
							
								
								
									
										1
									
								
								assets/actions/surprise-demi.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M355.102 21.097c-33.682.164-64.173 18.585-74.615 50.5 21.357-.79 23.203 53.922 23.203 53.922l41.619 6.262c-13.41 12.963-50.025 5.967-50.025 5.967-17.14 19.182-33.124 40.966-47.758 57.578-15.952 18.127-35.2 38.103-57.018 60.086-6.79 6.823 41.594-9.821 34.342-2.604-24.567 12.751-42.297 16.097-61.764 32.069-31.312 25.674-62.853 60.71-81.146 79.431-7.711 7.91-44.362 37.674 20.469 34.74 2.404 7.52-1.621 9.456-7.493 15.293-4.327 4.303-18.082.283-22.263 2.828-22.172 35.055-17.246 37.975-27.43 58.047-4.252 11.635 41.68-14.404 64.305-34.18 13.974-7.58 25.147-21.652 35.002-17.202 43.11 18.984 129.826 35.53 141.328 27.619 18.368-12.646-10.321-46.343 3.832-97.912 23.47 5.817 43.825 13.657 66.767 11.459-1.581 49.307 3.56 55.306-3.888 104.777l59.129 21.127 1.91-13.809-33.815-22.478c14.568-50.659 16.809-72.578 15.227-121.719-.16-5.372-45.168-24.325-74.492-33.133l18.593-30.412c30.393-44.788 124.141-62.055 127.932-88.258-13.02-19.676 3.022-27.384-25.092-21.912-6.295 1.318-13.771 24.346-18.023 27.213-7.843 5.276-40.655 24.477-51.951 18.377-1.9-1.026 7.246-33.441 6.85-44.78-.116-3.205-1.19-6.625-2.866-10.001.185-.64 15.24-52.482 54.809-94.016-43.978 25.134-65.332 79.925-65.354 79.98-2.207-2.134-4.476-3.983-6.639-5.423-1.916-14.7-4.819-73.02 68.598-78.776-21.427-21.177-47.704-30.78-72.283-30.66z" fill="#fff" fill-opacity="1" transform="translate(76.8, 76.8) scale(0.7, 0.7) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.6 KiB | 
							
								
								
									
										1
									
								
								assets/actions/surprise-totale.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M332.031 66.13c-28.807-.01-55.439 14.149-67.88 40.65 20.79 1.744 16 55.07 16 55.07-11.814 16.687-24.73 33.186-36.589 50.146 0 0-99.046 132.283-178.378 168.025-28.049 22.593-33.305 36.532-44.137 52.649-4.877 9.54 9.257 14.324 11.701 13.2 22.726-10.461 25.176-20.866 47.07-35.675 12.805-5.026 23.839-15.9 31.854-11.049 34.962 20.86 107.556 44.28 118.271 38.706 17.857-9.263-5.78-43.585 16.174-89.057 31.97-3.352 58.916-.885 88.332-12.094 3.483 50.279 10.106 54.59 6.766 107.092l71.2 1.045.698-14.61-41.814-11.105c11.528-56.054 11.816-78.996 4.672-127.996-.956-6.622-53.746-8.275-81.012-3.79 24.449-24.202 40.274-45.24 47.506-68.44l.027.189c7.637 15.923 30.083 33.958 35.336 37.125 27.704 11.048 38.214 7.982 62.955 3.887 4.907-.784 27.47 24.537 44.807 9.597 2.642-20.238 16.522-20.369-4.938-32.71-4.847-2.73-27.063 7.462-31.418 6.898-20.21-2.481-30.954-5.211-58.45-12.703-10.23-13.187-32.676-56.136-55.43-59.744 6.535-14.15 28.226-53.108 73.664-66.237-20.943-26.54-49.925-39.057-76.987-39.068zm82.405 46.722c-46.658 19.516-58.266 50.4-58.266 50.4l9.916 7.644s9.646-4.765 48.35-58.044zm23.04 160.005-4.658 11.418c5.233-.083 10.425.47 15.328 1.608-12.774 30.856-23.938 59.635-28.181 93.094l-.908 7.558 4.863-5.889c20.805-25.671 32.303-55.25 44.95-85.78 4.203 2.656 8.24 5.885 12.071 9.35l4.78-11.374-20.518-8.526-31.767 66.579 24.062-69.713-20.021-8.325z" fill="#fff" fill-opacity="1" transform="translate(76.8, 76.8) scale(0.7, 0.7) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.6 KiB | 
							
								
								
									
										1
									
								
								assets/actions/tache.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="M56.813 18.438c-.47-.005-.938.014-1.407.03-.625.023-1.252.066-1.875.126-7.468.72-14.682 4.148-22.31 11.125-9.985 9.128-12.863 17.66-11.407 27.718 1.455 10.056 8.353 22.236 21.125 34.906 2.895 2.872 6.126 5.737 9.593 8.625 1.27 1.055 2.565 2.13 3.907 3.186a200.62 200.62 0 0 0 3.438 2.656c.232.175.454.358.688.532C74.71 119.38 95.558 131.28 120.25 142.22c159.723 161.31 288.815 297.553 374.594 352.124-51.11-85.624-187.432-214.62-350-375.531-10.23-23.802-21.115-43.71-32.094-59.282 35.46-10.19 82.517-2.294 125.75 40.94 40.243 40.242 52.642 90.776 41.375 128.343 4.89 4.914 9.883 9.913 14.688 14.75 19.07-46.1 4.573-108.895-42.844-156.313-35.694-35.693-75.48-50.324-111.032-50.22-1.147.005-2.3.03-3.438.064-21.844.65-41.957 6.898-58.344 17.187a102.302 102.302 0 0 0-8.312 5.814c1.33 3.094 2.758 5.884 4.406 8.218 1.92 2.72 4.004 4.936 6.906 6.688 2.202-1.717 4.498-3.375 6.938-4.906a88.727 88.727 0 0 1 3.25-1.97c8.196 10.088 15.465 24.624 25.47 47.25-23.907-10.568-38.822-18.04-49.033-27 .024-.03.04-.063.064-.093-.433-.33-.867-.655-1.28-1-.013-.008-.022-.02-.033-.03-11.215-10.375-16.532-22.934-22.31-44.5 5.988 1.605 11.256 3.19 16 4.844a137.13 137.13 0 0 1 26.81-15.875c-9.5-7.738-18.552-11.93-26.686-12.97-1.443-.185-2.87-.3-4.282-.313zM493.28 64.374c-77.985 0-125.587 28.886-146.124 69.406-20.536 40.52-13.994 90.39 9.688 131.407 11.385 19.72 17.807 40.687 19.187 61.22a4329.64 4329.64 0 0 1 18.47 19.187c2.31-29.955-5.072-61.35-21.47-89.75-21.13-36.602-26.155-80.112-9.186-113.594 16.97-33.481 55.94-59.188 129.437-59.188V64.376zM37.907 114.938c-2.894 23.925 6.18 50.21 29.532 73.562l13.218-13.188c-15.97-15.97-23.188-31.833-24.437-46.593-6.646-4.51-12.754-9.102-18.314-13.782zM124.062 277c-24.466-.028-45.04 4.92-61.343 13.656-24.842 13.31-39.363 35.865-40.75 60.47-2.78 49.207 44.38 102.65 140.405 118.28 101.63 16.544 170.303-9.184 205.406-54.062 1.01-1.29 1.988-2.59 2.94-3.906-4.552-4.232-9.148-8.52-13.783-12.875-1.233 1.79-2.52 3.55-3.875 5.28-29.97 38.315-90.355 62.97-187.687 47.126-90.394-14.715-126.796-62.527-124.75-98.783 1.023-18.127 10.982-34.37 30.938-45.062 19.955-10.692 50.267-15.364 90.5-7.47 34.077 6.69 62.938 3.47 85.437-6.936-4.72-4.65-9.49-9.33-14.28-14.064-17.545 6.452-39.89 8.088-67.564 2.656-14.895-2.923-28.778-4.297-41.594-4.312z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||||
| After Width: | Height: | Size: 2.4 KiB | 
							
								
								
									
										1
									
								
								assets/ui/d100.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><defs><filter id="shadow-1" height="300%" width="300%" x="-100%" y="-100%"><feFlood flood-color="rgba(201, 201, 201, 1)" result="flood"></feFlood><feComposite in="flood" in2="SourceGraphic" operator="atop" result="composite"></feComposite>0<feOffset dx="230" dy="300" result="offset"></feOffset><feComposite in="SourceGraphic" in2="offset" operator="over"></feComposite></filter></defs><g class="" transform="translate(-100,0)" style=""><path d="m375.483 251.243-109.98 51.138.213 183.381L477.01 266.346l-86.993-21.81zm-12.736 108.626-5.947 14.699-48.604-8.955 5.007-12.832a141.306 141.306 0 0 0 13.51-11.358 167.184 167.184 0 0 0 16.566-17.517 170.478 170.478 0 0 0 12.606-17.958 115.607 115.607 0 0 0 9.514-17.97l14.068 2.51q-9.37 22.334-30.361 44.43-13.296 13.64-20.645 18.636zM121.603 244.334l-84.71 21.763L246.474 486V302.38l-109.946-51.137zm19.147 50.852a28.72 28.72 0 0 1 24.273 6.802 53.052 53.052 0 0 1 11.226 14.188l-13.081 2.676a28.542 28.542 0 0 0-5.388-7.374q-5.185-4.876-11.262-3.853l-.487.095a6.458 6.458 0 0 0-5.162 4.448c-.856 2.378-.238 5.554 1.796 9.371q4.08 7.6 10.81 9.027a23.785 23.785 0 0 0 8.563-.203l1.867-.344 5.791 10.822q-6.398 1.427-8.23 3.282-3.21 3.14.429 9.93a17.042 17.042 0 0 0 6.089 6.696 10.406 10.406 0 0 0 7.385 1.534l.416-.083q4.757-.964 5.079-4.757c.261-2.57-.655-5.744-2.748-9.514l12.38-2.545a49.247 49.247 0 0 1 4.103 11.226 19.956 19.956 0 0 1-.642 9.383 11.702 11.702 0 0 1-3.96 5.411 19.575 19.575 0 0 1-8.027 3.235l-1.19.214a27.971 27.971 0 0 1-17.494-2.7 32.193 32.193 0 0 1-14.128-14.092q-3.627-6.79-2.604-12.19a8.396 8.396 0 0 1 2.521-4.947h-.071q-1.844.31-7.04-2.497a32.11 32.11 0 0 1-12.916-13.593q-5.245-9.764-3.282-18.398 1.962-8.634 13.676-11zM27.19 248.865l108.78-116.309a7.135 7.135 0 0 1 1.427 0h.154q3.14.345 2.842 3.71a19.36 19.36 0 0 1-3.294 8.1 39.376 39.376 0 0 1-9.728 10.405q-3.912 2.938-15.044 9.514-12.796 7.505-19.55 14.77a92.535 92.535 0 0 0-11.513 14.486l32.907 3.758 8.182-12.963-20.967-2.378a36.415 36.415 0 0 1 4.757-3.83q2.379-1.605 8.444-5.125l6.422-3.747a92.975 92.975 0 0 0 12.903-8.776 61.472 61.472 0 0 0 12.51-14.414q6.84-10.846 6.494-17.957c-.19-3.949-2.105-6.434-5.684-7.505l79.798-85.161-102.097 179.576-5.708 10.06zm367.238-71.974q-3.817-5.458-3.758-8.515c0-2.033 1.19-3.199 3.568-3.448h.57a11.892 11.892 0 0 1 6.91 2.247 29.85 29.85 0 0 1 7.837 8.051q3.687 5.28 3.71 8.397c0 2.093-1.188 3.258-3.496 3.567h-.594a11.75 11.75 0 0 1-6.957-2.378 29.79 29.79 0 0 1-7.79-7.885zm-109.41-141.52 83.948 89.634h-1.189c-.38 0-.975 0-1.463.107q-7.825.892-8.324 6.862-.5 5.97 5.03 13.747a53.778 53.778 0 0 0 6.375 7.374 37.901 37.901 0 0 0 10.144 6.897q-2.117 2.89-.702 7.98a37.283 37.283 0 0 0 5.613 11.096 55.122 55.122 0 0 0 15.223 14.806q8.098 5.268 16.066 4.935.81 0 1.618-.13 8.776-.988 9.228-7.873a16.114 16.114 0 0 0-.463-4.853l58.689 62.686-91.572-22.941-6.1-10.703zm98.22 104.927 2.45 2.617c.451.57.903 1.189 1.355 1.784 1.808 2.592 2.723 4.757 2.723 6.529 0 1.771-1.034 2.782-3.127 3.02h-.512a10.346 10.346 0 0 1-6.077-1.95 22.596 22.596 0 0 1-6.184-6.137c-1.974-2.83-2.937-5.102-2.878-6.814.06-1.713 1.118-2.7 3.187-2.937h.524a10.263 10.263 0 0 1 6.005 1.879 19.147 19.147 0 0 1 2.533 2.01zM255.987 26 137.456 231.026l118.532 55.05 118.604-55.05zm-1.19 208.463q-17.529 0-24.58-12.273-7.053-12.273-7.053-34.988 0-22.714 7.052-35.047 7.052-12.332 24.582-12.344 17.53 0 24.582 12.332 7.052 12.333 7.052 35.047 0 22.715-7.052 34.988-7.053 12.273-24.582 12.285zm10.538-71.807q2.497 7.968 2.497 24.546 0 15.817-2.497 24.201-2.498 8.384-10.537 8.325-8.04 0-10.632-8.325-2.593-8.324-2.593-24.2 0-16.579 2.593-24.547t10.632-7.968q8.015-.012 10.513 7.956z" fill="#fff" fill-opacity="1" filter="url(#shadow-1)" transform="translate(128, 128) scale(0.5, 0.5) rotate(-30, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| After Width: | Height: | Size: 3.8 KiB | 
							
								
								
									
										1
									
								
								assets/ui/icon_sidebar_cards.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M119.436 36c-16.126 0-29.2 17.237-29.2 38.5v363c0 21.263 13.074 38.5 29.2 38.5h275.298c16.126 0 29.198-17.237 29.198-38.5v-363c0-21.263-13.072-38.5-29.198-38.5zm26.369 10.951 11.002 32.856 34.648.312-27.848 20.617 10.41 33.05-28.212-20.114-28.215 20.113L128 100.736 100.152 80.12l34.649-.312zM363.979 161.84c7.127 9.459 12.739 20.689 16.832 32.04 3.8 10.544 6.197 21.211 6.668 31.02-.163 19.015-3.915 23.274-14.557 36.934l-6.703-11.48c-10.85-13.106-30.779-48.4-47.383-43.672-6.521 6.11-8.996 13.37-10.313 20.802 2.898 8.8 4.477 18.43 4.477 28.516 0 15.293-3.615 29.54-9.996 41.416 22.643 4.537 57.927 19.332 57.973 39.223-.27 3.783-1.835 7.68-4.362 10.42-10.743 12.528-36.958 4.125-45.2 10.072.796 6.947 4.112 14.118 4.355 20.174.136 4.36-1.768 10.58-6.508 13.996-5.67 4.087-12.968 4.551-18.52 3.045C279.94 392.226 272 379.649 256 377c-13.544 3.491-22.412 13.87-34.742 17.346-5.552 1.506-12.85 1.042-18.52-3.045-4.74-3.417-6.644-9.636-6.508-13.996-.058-7.142 4.107-13.794 4.356-20.174-15.741-7.788-33.816 1.97-45.201-10.072-2.527-2.74-4.093-6.637-4.362-10.42 6.146-27.341 35.374-34.684 57.973-39.223C202.615 285.54 199 271.293 199 256c0-11.489 2.047-22.385 5.764-32.135-2.357-7.923-3.441-15.988-9.438-22.441-8.758-.925-14.079 6.897-17.842 12.63-11.683 19.5-18.718 30.606-32.88 46.192-16.604-23.4-19.314-49.29-13.157-70.988 6.065-20.331 19.17-38.798 37.926-47.924 21.216-9.766 39.872-10.03 58.885.203 5.163-13.053 10.4-25.65 18.035-36.209 9.625-13.31 23.8-25.631 43.707-25.295 38.8.656 73.993 51.156 73.979 81.807zm-72.22-63.893c-35.759 2.409-44.771 44.746-55.189 71.29l-9.447-7.087c-18.428-12.31-31.076-13.732-49.875-4.63-12.924 6.288-23.701 20.62-28.553 36.882-3.38 11.329-3.765 23.225-.949 33.645 9.45-13.549 15.806-30.08 28.317-39.178 7.486-7.975 26.27-8.498 35.45 3.897 4.838 7.02 7.437 14.54 9.5 22.234h72.165c.592-1.944 1.067-3.762 2.017-6.033 2.956-7.064 7.765-16.266 18.395-19.504 18.09-3.862 32.494 7.106 43.498 18.514 4.517 4.717 8.492 9.696 12.098 14.517-.69-6.798-2.477-14.651-5.31-22.508-13.127-36.707-37.889-51.031-70.386-32.011 2.556-16.423 16.87-35.72 46.25-26.962-9.094-17.135-30.355-42.471-47.98-43.066zM220.644 233c-2.31 6.965-3.643 14.753-3.643 23 0 15.85 4.892 30.032 12.26 39.855C236.628 305.68 245.988 311 256 311s19.372-5.32 26.74-15.145C290.108 286.032 295 271.85 295 256c0-8.247-1.334-16.035-3.643-23zM232 280h48s-8 14-24 14-24-14-24-14zm-11.14 33.566c-13.86 3.34-50.369 8.9-51.842 21.42 9.621 1.947 20.446.838 28.998 2.235 5.993 1.018 12.82 3.323 17.285 9.517 3.375 4.683 3.577 10.103 3.037 14.21-.543 5.89-3.317 10.557-3.975 16.32 15.955-2.59 28.264-17.532 41.637-18.268 16-.702 29.313 17.402 41.637 18.268-.893-5.59-3.262-11.158-3.975-16.32-.54-4.107-.338-9.527 3.037-14.21 4.465-6.194 11.292-8.5 17.285-9.517 9.742-2.229 19.975.396 28.998-2.235-5.77-13.125-39.813-19.454-51.841-21.42C281.665 323.01 269.45 329 256 329c-13.452 0-25.665-5.991-35.14-15.434zm117.122 64.649 28.213 20.113 28.215-20.113L384 411.264l27.848 20.617-34.649.312-11.004 32.856-11.002-32.856-34.648-.312 27.848-20.617z" fill="#fff" fill-opacity="1" transform="translate(76.8, 76.8) scale(0.7, 0.7) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| After Width: | Height: | Size: 3.2 KiB | 
| @@ -1,449 +1 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M211.313 21.094c-51.776 0-98.754 12.252-133.5 32.718C43.066 74.28 19.874 103.78 19.874 137.69c0 33.54 22.692 62.81 56.813 83.25L48.156 327.094l96.97-79.844c20.65 4.58 42.924 7.063 66.186 7.063 51.776 0 98.786-12.252 133.532-32.72 34.746-20.466 57.937-49.997 57.937-83.905s-23.19-63.41-57.936-83.875c-34.746-20.467-81.756-32.72-133.53-32.72zm0 18.687c48.8 0 92.866 11.77 124.03 30.126 31.165 18.357 48.75 42.447 48.75 67.78 0 25.338-17.585 49.457-48.75 67.814-31.164 18.357-75.23 30.125-124.03 30.125S118.445 223.857 87.28 205.5c-31.163-18.357-48.718-42.476-48.718-67.813 0-25.336 17.555-49.424 48.72-67.78C118.445 51.55 162.51 39.78 211.31 39.78zM96.53 89.938v18.688h93.126V89.937H96.53zm111.814 0v18.688h28.094V89.937h-28.094zm46.78 0v18.688h71.97V89.937h-71.97zM96.532 129.844v18.72h29.657v-18.72H96.53zm48.345 0v18.72h65.938v-18.72h-65.938zm84.656 0v18.72h38.095v-18.72H229.53zm56.782 0v18.72h40.782v-18.72h-40.78zM96.532 166.78v18.69h70.874v-18.69H96.53zm89.562 0v18.69h57.03v-18.69h-57.03zm75.72 0-.002 18.69h65.282v-18.69h-65.28zm92.342 90.25c-74.88 0-135.594 41.762-135.594 93.283 0 51.52 60.716 93.28 135.594 93.28 18.23 0 35.623-2.48 51.5-6.968l68.53 51.156-24.873-71.03c24.947-16.918 40.437-40.432 40.437-66.438 0-51.518-60.714-93.28-135.594-93.28zm-70.344 42.345h32.907v18.688H283.81v-18.688zm51.594 0h90.344v18.688h-90.344v-18.688zm-78.97 41.75h78.314v18.688h-78.313v-18.688zm97.002 0h20.968v18.688h-20.97l.002-18.688zm39.656 0h51v18.688h-51v-18.688zm-109.28 39h79.06v18.688h-79.062v-18.688zm97.748 0h44.188v18.688h-44.188v-18.688z" fill="#fff" fill-opacity="1" transform="translate(76.8, 76.8) scale(0.7, 0.7) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| <!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> |  | ||||||
| <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" |  | ||||||
| 	 viewBox="0 0 512.07 512" style="enable-background:new 0 0 512.07 512;" xml:space="preserve"> |  | ||||||
| <style type="text/css"> |  | ||||||
| 	.st0{fill:#DCDCDC;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;} |  | ||||||
| 	.st1{display:none;} |  | ||||||
| 	.st2{display:inline;} |  | ||||||
| </style> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_chat"> |  | ||||||
| 	<g> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M180,480.93c14-15.25,27.95-29.3,40.56-44.47c14.18-17.05,23.54-36.69,26.34-59.05 |  | ||||||
| 					c1.66-13.29-0.67-25.98-5.04-38.48c-1.8-5.15-5.7-5.52-10.23-5.78c-18.92-1.08-37.99-1.21-56.71-3.83 |  | ||||||
| 					c-40-5.59-76.63-19.99-107.18-47.16c-36.18-32.19-46.99-77.73-26.93-122.29c15.37-34.14,40.96-59.17,71.93-78.94 |  | ||||||
| 					c47.68-30.44,100.22-45.65,156.55-49.23c41.61-2.64,81.81,2.91,120.81,17.42c26.15,9.73,48.71,24.87,66.74,46.2 |  | ||||||
| 					c29.1,34.42,32.23,80.62,8.86,120.58c-23.61,40.37-58.93,67.06-100.58,86.28c-10.17,4.7-20.81,8.38-31.3,12.36 |  | ||||||
| 					c-4.3,1.63-6.47,4.24-6.8,9.02c-2.04,29.43-14.23,54.78-32.77,77.05c-29.18,35.06-66,59.86-107.6,77.9 |  | ||||||
| 					C184.67,479.39,182.56,480.01,180,480.93z"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_rolltable" class="st1"> |  | ||||||
| 	<g class="st2"> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M255.1,55.46c6.7,2.37,12.64,3.53,17.63,6.38c47.83,27.36,95.49,55,143.19,82.58 |  | ||||||
| 					c1.76,1.02,3.5,2.14,5.06,3.43c4.67,3.85,4.73,8.08-0.19,11.57c-4.48,3.18-9.3,5.9-14.07,8.66 |  | ||||||
| 					c-43.81,25.34-87.68,50.58-131.43,76.01c-12.79,7.43-25.19,8.02-38.18,0.44c-47.26-27.53-94.66-54.81-141.95-82.29 |  | ||||||
| 					c-11.67-6.78-11.5-10.86,0.17-17.61c45.93-26.57,91.78-53.27,137.82-79.64C240.07,61.03,247.84,58.57,255.1,55.46z |  | ||||||
| 					 M256.6,177.07c8.18-2.74,15.83-4.76,23.02-7.85c6.75-2.9,11.12-8.42,11.32-16.12c0.2-7.86-4.55-13.18-10.98-16.36 |  | ||||||
| 					c-16.34-8.07-32.92-8.99-48.94,0.93c-13.18,8.17-13.33,23.46,0.28,30.9C238.94,172.75,248.01,174.3,256.6,177.07z |  | ||||||
| 					 M139.44,174.49c10.51,0.36,20.31-1.78,28.43-8.85c7.92-6.9,8.07-17.96,0.6-25.36c-13.09-12.97-44.39-13.07-57.62-0.19 |  | ||||||
| 					c-8.94,8.7-8.15,19.73,2.02,27.08C120.8,172.91,129.82,174.83,139.44,174.49z M371.05,174.5c13.13,0.01,20.45-1.93,27.72-7.04 |  | ||||||
| 					c11.22-7.88,11.04-21.8-0.38-29.44c-14.58-9.76-37.05-9.78-51.54-0.06c-11.6,7.78-11.75,21.98-0.23,29.88 |  | ||||||
| 					C354.29,173.1,362.88,175.12,371.05,174.5z M257.2,200.1c-10.74-0.21-20.43,1.8-28.51,8.53c-9.63,8.02-9.2,19.91,0.7,27.6 |  | ||||||
| 					c13.81,10.71,40.59,10.4,54.05-0.63c9.82-8.05,9.29-21.21-1.19-28.54C274.59,201.7,265.94,199.86,257.2,200.1z M255.77,105.95 |  | ||||||
| 					c10.86-0.08,20.49-2.25,28.35-9.28c8.51-7.61,8.52-17.75,0.3-25.54c-13.52-12.81-43.78-12.59-57.1,0.4 |  | ||||||
| 					c-7.45,7.27-7.44,17.61,0.19,24.78C235.62,103.93,245.78,105.61,255.77,105.95z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M73.56,270.29c-0.01-23.47-0.01-46.95,0-70.42c0-2.24-0.04-4.5,0.09-6.73c0.55-9.08,4.45-11.43,12.3-7.03 |  | ||||||
| 					c14.77,8.29,29.43,16.78,44.1,25.25c31.29,18.06,62.49,36.27,93.87,54.16c13.59,7.75,19.9,19.03,19.84,34.61 |  | ||||||
| 					c-0.18,47.56-0.07,95.12-0.07,142.68c0,1.02,0,2.04-0.03,3.06c-0.37,10.88-4.46,13.26-13.91,7.81 |  | ||||||
| 					c-46.51-26.8-93.02-53.6-139.43-80.56c-11.08-6.44-16.76-16.38-16.77-29.35C73.56,319.28,73.57,294.79,73.56,270.29z |  | ||||||
| 					 M238.89,301.12c-1.04-15.22-9.94-29.1-25.87-37.67c-12.78-6.88-25.53,0.97-25.17,15.07c0.45,18,8.76,32.2,24.15,41.47 |  | ||||||
| 					C226.27,328.58,238.87,320.93,238.89,301.12z M238.88,424.25c-0.03-14.84-11.77-33.85-24.91-40.35 |  | ||||||
| 					c-13.82-6.83-27.24,1.36-26.24,16.4c1.14,17.22,9.44,30.68,24.03,39.63C226.22,448.8,238.92,441.17,238.88,424.25z |  | ||||||
| 					 M78.36,336.56c-0.07,16.35,12.18,35.46,26.64,41.57c13.6,5.74,24.53-1.52,24.14-16.28c-0.47-17.75-9.44-30.82-23.63-40.54 |  | ||||||
| 					c-5.85-4.01-12.62-5.05-19.12-1.43C80,323.43,78.2,329.62,78.36,336.56z M78.16,216.83c1.81,17.43,9.33,31.66,25.03,40.21 |  | ||||||
| 					c13.84,7.55,26.4-0.25,25.96-15.46c-0.51-17.56-9.43-30.51-23.26-40.31c-5.78-4.1-12.64-5.27-19.16-1.76 |  | ||||||
| 					C80.09,203.09,78.12,209.49,78.16,216.83z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M438.48,269.36c0,23.88-0.09,47.77,0.04,71.65c0.08,14.95-5.66,26.05-19.04,33.69 |  | ||||||
| 					c-45.56,26.01-90.87,52.43-136.3,78.66c-1.93,1.11-4.02,2.03-6.14,2.72c-4.13,1.36-6.9-0.45-7.9-4.42 |  | ||||||
| 					c-0.69-2.73-0.78-5.65-0.78-8.49c-0.04-48.18,0.04-96.35-0.07-144.53c-0.03-14.73,6.49-25.32,19.04-32.56 |  | ||||||
| 					c44.18-25.53,88.36-51.07,132.54-76.6c1.24-0.71,2.5-1.39,3.75-2.08c11.32-6.2,14.8-4.14,14.84,9.08 |  | ||||||
| 					C438.53,220.78,438.48,245.07,438.48,269.36z M273.14,421.22c0.05,19.9,12.39,27.34,26.79,18.9 |  | ||||||
| 					c14.92-8.75,23.03-22.32,24.24-39.46c1.09-15.44-12.22-24.3-25.6-16.81C282.99,392.57,274.73,406.59,273.14,421.22z |  | ||||||
| 					 M273.19,300.58c-0.25,19.57,10.43,26.62,25.43,19.95c14.02-6.23,26.59-26.94,25.75-42.41c-0.77-14.26-13.04-21.55-25.73-14.51 |  | ||||||
| 					C283.1,272.22,275.12,286.19,273.19,300.58z M378.55,373.28c0.05-21.14-11.77-28.95-25.77-20.61 |  | ||||||
| 					c-15.26,9.09-24.61,22.51-24.5,41.07c0.1,15.52,11.79,22.77,25.39,15.25C369.25,400.38,377.63,386.78,378.55,373.28z |  | ||||||
| 					 M433.65,340.47c0.1-20.18-12.26-27.99-26.62-19.24c-14.51,8.85-23.33,22.09-24,39.66c-0.62,16.14,11.34,23.92,25.59,16.37 |  | ||||||
| 					C424.57,368.82,431.83,354.54,433.65,340.47z M378.56,249.19c0.11-16.72-10.87-24.46-24.88-17.53 |  | ||||||
| 					c-15.12,7.48-26.59,27.54-25.35,44.37c0.88,11.94,10.06,18.07,21.51,14.37C365.3,285.38,378.44,266.54,378.56,249.19z |  | ||||||
| 					 M433.67,217.08c0.11-15.23-9.9-22.9-23.27-17.86c-16.2,6.12-29.92,29.74-27.12,46.71c1.73,10.53,10.4,15.95,20.67,12.93 |  | ||||||
| 					C419.6,254.24,433.54,234.65,433.67,217.08z"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_actor" class="st1"> |  | ||||||
| 	<g class="st2"> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M194.72,240.85c-18.71-10.84-37.43-21.65-56.1-32.56c-4.38-2.56-3.72-6.78-3.09-10.93 |  | ||||||
| 					c4.53-29.87,16.49-56.68,33.54-81.37c22.53-32.64,51.22-59.09,83.04-82.38c1.94-1.42,4.08-2.55,6.44-4.01 |  | ||||||
| 					c2.95,1.91,5.76,3.52,8.35,5.44c34.2,25.36,64.61,54.39,87.21,90.87c13.92,22.47,23.34,46.63,27.11,72.93 |  | ||||||
| 					c0.74,5.19-0.6,8.42-5.19,11.05c-17.12,9.83-34.08,19.93-51.1,29.92c-0.35-0.42-0.7-0.84-1.06-1.26 |  | ||||||
| 					c7.2-7.59,13.9-15.74,21.74-22.61c6.97-6.11,8.08-12.73,6.54-21.27c-5.03-27.96-18.41-51.68-36.13-73.32 |  | ||||||
| 					c-14.99-18.3-32.86-33.43-51.91-47.27c-3.26-2.37-6.29-3.56-10-0.89c-28.94,20.8-54.74,44.63-72.73,75.88 |  | ||||||
| 					c-9.25,16.07-15.58,33.21-17.65,51.81c-0.5,4.49,0.65,7.78,3.76,10.99c9.23,9.52,18.23,19.25,27.32,28.9L194.72,240.85z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M168.55,345.65c-12.76,3.01-23.81-2.22-35.94-5.83c-3.63,12.02-1.15,22.71,4.28,33.16 |  | ||||||
| 					c-0.52,0.49-1.04,0.98-1.56,1.47c-7.28-3.95-14.57-7.89-22.66-12.28c-0.94,40.71,5.85,79.96,12.76,120.22 |  | ||||||
| 					c-9.73,0-18.21,0-28.31,0c0-4.71-0.17-8.65,0.03-12.57c2.77-54.5,0.73-108.5-16.69-160.88c-1.7-5.12-1.02-8.86,2.98-12.56 |  | ||||||
| 					c15.25-14.13,30.3-28.49,45.51-42.67c1.86-1.73,4.21-2.92,7.2-4.95c12.66,31.79,36.38,51.55,65.92,65.71 |  | ||||||
| 					c-23.56,4.18-43.99-5.23-64.98-14.12C142.45,319.03,153.45,333.5,168.55,345.65z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M378.56,342.15c-11.2,1.29-21.2,6.91-34.38,4.02c17.38-13.12,29.62-28.02,35.34-49.86 |  | ||||||
| 					c-22.86,11.18-44.29,22.27-69.86,17.87c29.22-14.58,53.47-34,65.19-66.51c3.09,2.11,5.44,3.31,7.29,5.04 |  | ||||||
| 					c15.49,14.48,30.83,29.13,46.36,43.57c3.94,3.66,4.92,7.36,3.13,12.52c-12.8,37.05-17.33,75.43-17.57,114.4 |  | ||||||
| 					c-0.11,17.53,0.54,35.07,0.78,52.6c0.02,1.77-0.35,3.55-0.66,6.4c-8.97,0-17.6,0-27.36,0c6.32-39.97,13.54-79.18,12.38-120.61 |  | ||||||
| 					c-8.84,4.81-16.27,8.85-23.71,12.89c-0.49-0.48-0.97-0.96-1.46-1.44C378.33,363.41,381.6,353.68,378.56,342.15z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M207.81,179.57c3.71-5.83,8.78-8.93,15.2-8.75c5.91,0.17,10.65,3.14,13.82,8.68 |  | ||||||
| 					c-3.37,5.93-8.7,7.74-14.45,7.81C216.53,187.39,211.48,185.04,207.81,179.57z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M277.66,179.72c3.23-6.12,7.85-9.04,14-9c6.15,0.04,10.67,3.08,13.58,8.58c-2.43,6.15-7.58,7.55-12.87,7.82 |  | ||||||
| 					C286.5,187.42,281.29,185.46,277.66,179.72z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M194.81,240.77c0,0-0.08,0.08-0.08,0.08C194.72,240.85,194.81,240.77,194.81,240.77z"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_scene" class="st1"> |  | ||||||
| 	<g class="st2"> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M141.31,362.45c10.55-10.81,21.11-21.61,32.39-33.17c-4.23-4.4-7.78-8.52-11.78-12.13 |  | ||||||
| 					c-4.39-3.96-5.23-7.87-1.64-12.78c2.36-3.24,4.31-6.78,7.52-11.92c29.68,29.65,58.51,58.45,88.28,88.2 |  | ||||||
| 					c29.63-29.58,58.38-58.28,88.43-88.27c3.76,6.48,7.17,11.44,9.48,16.88c0.68,1.6-1.26,4.92-2.82,6.75 |  | ||||||
| 					c-3.78,4.43-8.04,8.45-12.61,13.15c3.87,4.06,7.01,7.46,10.26,10.75c6.02,6.1,12.2,12.04,18.09,18.27 |  | ||||||
| 					c1.5,1.58,2.14,3.98,2.19,6.78c-11.12-2.35-15.32-13.36-25.7-18.87c-4.53,5.37-9.27,11-14.4,17.08 |  | ||||||
| 					c4.03,8.46,15.77,12.55,18.84,22.89c-0.64,0.7-1.28,1.4-1.92,2.1c-2.18-1.32-4.7-2.29-6.49-4.01 |  | ||||||
| 					c-7.5-7.21-14.75-14.68-22.17-21.99c-1.69-1.67-3.67-3.05-6.41-5.3c-5.41,5.88-10.51,11.42-16,17.4 |  | ||||||
| 					c1.57,1.94,2.93,3.92,4.6,5.61c7.3,7.42,14.75,14.69,22,22.16c1.66,1.71,2.69,4.01,3.13,6.87 |  | ||||||
| 					c-10.84-2.35-15.01-13.32-25.2-18.68c-4.93,5.38-10.02,10.94-15.43,16.85c4.67,9.02,15.38,13.49,19.26,23.07 |  | ||||||
| 					c-0.54,0.67-1.09,1.34-1.63,2.01c-2.14-1.31-4.59-2.29-6.35-3.98c-7.49-7.22-14.75-14.69-22.17-21.99 |  | ||||||
| 					c-1.69-1.66-3.68-3.01-5.89-4.79c-3.8,3-7.23,5.71-11.03,8.71c-3.77-2.97-7.19-5.68-11.01-8.69c-2.19,1.75-4.19,3.08-5.87,4.74 |  | ||||||
| 					c-7.42,7.3-14.69,14.75-22.16,22c-1.73,1.67-4.02,2.76-6.91,3.23c2.31-10.77,13.12-15.02,18.63-25.24 |  | ||||||
| 					c-5.42-4.76-11.09-9.74-17.21-15.11c-8.81,4.1-12.9,15.32-22.79,18.83c-0.62-0.47-1.25-0.95-1.87-1.42 |  | ||||||
| 					c1.25-2.13,2.15-4.6,3.81-6.33c7.21-7.5,14.68-14.75,21.99-22.17c1.67-1.7,3.05-3.67,5.27-6.37 |  | ||||||
| 					c-5.69-5.59-11.06-10.87-16.79-16.51c-2.48,2-4.47,3.36-6.16,5.02c-7.42,7.3-14.69,14.75-22.16,22c-1.71,1.66-4,2.72-6.87,3.19 |  | ||||||
| 					c2.16-10.9,13.44-14.89,18.41-25.47c-5.23-4.81-10.76-9.89-16.39-15.06c-9.69,4.24-13.75,16.43-24.15,19.15 |  | ||||||
| 					C143.03,364.74,142.17,363.6,141.31,362.45z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M441,403.48c-16.69-27.59-33.44-55.13-50.04-82.77c-42.46-70.68-84.85-141.39-127.26-212.1 |  | ||||||
| 					c-1.34-2.23-2.47-4.58-4.3-8.02c13.34-3.15,24.63-8.77,32.97-20.46c1.71,2.53,2.89,3.85,3.6,5.4 |  | ||||||
| 					c28.28,61.55,56.51,123.12,84.77,184.68c19.15,41.72,38.37,83.41,57.51,125.14c1.18,2.58,1.92,5.36,2.86,8.04L441,403.48z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M217.61,82.38c2.39,3.13,3.85,4.73,4.95,6.53c4.59,7.48,8.69,15.3,13.71,22.47 |  | ||||||
| 					c4.35,6.21,4.12,11.18,0.16,17.73c-47.28,78.28-94.26,156.74-141.31,235.16c-6.51,10.85-13.01,21.71-19.54,32.55 |  | ||||||
| 					c-1.13,1.88-2.39,3.68-4.72,4.92C119.57,295.76,168.27,189.77,217.61,82.38z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M477.25,255.92c-10.87-10.64-21.54-21.09-32.91-32.23c-5.58,5.75-10.68,11.01-16.24,16.75 |  | ||||||
| 					c1.84,2.26,3.31,4.39,5.1,6.21c7.43,7.56,15,15,22.43,22.56c2.12,2.16,4.52,4.52-0.17,8.58c-7.22-6.76-14.48-13.55-21.88-20.47 |  | ||||||
| 					c-6.08,5.51-11.66,10.57-17.97,16.3c7.88,8.42,14.65,15.65,21.42,22.88c-0.62,0.85-1.25,1.7-1.87,2.56 |  | ||||||
| 					c-2.14-1.03-4.53-1.72-6.36-3.13c-13.8-10.59-21.18-25.52-27.46-41.16c-5.78-14.38-8.33-11.03,4.45-23.75 |  | ||||||
| 					c7.23-7.19,14.4-14.44,21.65-21.61c1.71-1.69,3.62-3.17,5.84-5.08c1.73,1.12,3.41,1.86,4.63,3.06 |  | ||||||
| 					c13.32,13.21,26.59,26.48,39.81,39.79C479.85,249.34,482.22,251.73,477.25,255.92z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M68.55,223.56c-12.92,10.59-22.16,23.11-34.32,32.22c-0.78-0.53-1.57-1.06-2.35-1.59 |  | ||||||
| 					c0.43-1.85,0.25-4.3,1.39-5.46c14.33-14.51,28.84-28.83,43.34-43.18c0.39-0.38,1.12-0.42,1.97-0.71 |  | ||||||
| 					c0.75,0.34,1.86,0.54,2.53,1.2c10.88,10.75,21.84,21.43,32.39,32.51c1.47,1.54,1.83,5.55,0.94,7.69 |  | ||||||
| 					c-4.29,10.36-8.17,21.11-14.15,30.47c-5.16,8.08-12.9,14.53-19.62,21.58c-0.65,0.69-2.18,0.54-5.2,1.2 |  | ||||||
| 					c3.65-11.71,15.03-15.79,20.22-26.77c-5.23-4.62-10.83-9.57-16.64-14.7c-9.41,4.67-13.78,15.49-23.35,19.4 |  | ||||||
| 					c-0.67-0.54-1.35-1.07-2.02-1.61c1.11-1.99,1.87-4.32,3.4-5.91c7.07-7.35,14.38-14.47,21.55-21.72c1.84-1.86,3.48-3.92,6.4-7.23 |  | ||||||
| 					C79.61,235.25,74.35,229.69,68.55,223.56z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M256.05,428.1c7.93,7.53,16.37,15.55,24.7,23.47c-8.21,8.27-16.4,16.51-24.37,24.54 |  | ||||||
| 					c-8.23-7.98-16.67-16.16-25.11-24.34C239.8,443.62,248.21,435.58,256.05,428.1z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M254.88,73.27c6.48-5.93,12.68-11.6,18.52-16.94C275.4,65.47,265.2,75.93,254.88,73.27z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M238.87,49.47c0.54-7.99,6.12-13.62,15.88-13.57c-4.81,4.98-9.61,9.96-14.42,14.93 |  | ||||||
| 					C239.84,50.38,239.35,49.92,238.87,49.47z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<polygon class="st0" points="441.11,403.38 441.22,403.67 441,403.48 				"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_item" class="st1"> |  | ||||||
| 	<g class="st2"> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M86.57,379.95c0-48.58,0-96.33,0-143.79c5.64-2.82,112.01-3.19,119.52-0.33c0.25,2.68,0.79,5.83,0.8,8.98 |  | ||||||
| 					c0.07,26.94,0.01,53.88,0.08,80.83c0.01,3.17,0.51,6.33,0.85,10.3c32.36,0,63.92,0,97.01,0c0-33.87,0-66.95,0-99.19 |  | ||||||
| 					c6.41-3.36,112.58-3.86,119.48-1.35c2.55,5.28,2.8,137.43-0.09,144.56C312.19,379.95,199.8,379.95,86.57,379.95z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M351.95,96.52c0,37.52,0,74.24,0,111.87c-15.41,0-30.07,0-45.61,0c-0.81-5.04-1.56-9.72-2.59-16.15 |  | ||||||
| 					c-31.78-0.12-63.35-0.24-95.41,0.16c-1.01,5.85-1.81,10.52-2.76,16c-15.49,0-30.54,0-46.27,0c-0.48-3.17-1.18-5.7-1.19-8.24 |  | ||||||
| 					c-0.08-31.43-0.09-62.85-0.03-94.28c0.02-8.73,1.64-10.33,10.48-10.33c58.36-0.05,116.72-0.03,175.09,0.01 |  | ||||||
| 					C346.04,95.56,348.42,96.09,351.95,96.52z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M132.51,208.42c-9.52,0-18.03,0-27.47,0c0-37.52,0-74.16,0-111.86c9.22,0,17.87,0,27.47,0 |  | ||||||
| 					C132.51,133.9,132.51,170.54,132.51,208.42z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M378.57,96.39c10.31,0,18.82,0,29.12,0c0.27,37.43,0.14,74.07,0.08,111.82c-10.01,0-18.66,0-29.13,0 |  | ||||||
| 					C378.39,170.99,378.51,134.35,378.57,96.39z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M107.03,407.31c99.7,0,198.42,0,297.14,0c0.31,0.74,0.62,1.47,0.93,2.21c-3.8,2.18-7.48,4.61-11.44,6.42 |  | ||||||
| 					c-1.72,0.78-4.02,0.36-6.06,0.36c-87.72,0.01-175.44-0.01-263.17,0.06C117.35,416.37,111.13,415.25,107.03,407.31z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M280.03,311.38c-16.62,0-31.68,0-47.61,0c0-31.35,0-61.94,0-93.7c15.6-1.68,30.82-0.85,47.53-0.45 |  | ||||||
| 					C280.76,248.97,280.56,279.53,280.03,311.38z M267.36,293.14c0.39-3.77,0.85-6.35,0.89-8.94c0.12-7.13-0.2-14.28,0.21-21.39 |  | ||||||
| 					c0.17-2.85,1.14-6.13,2.88-8.31c8.15-10.27,8.56-19.5,0.67-27.25c-8.45-8.3-21.51-8.87-30.61-1.33 |  | ||||||
| 					c-8.41,6.98-10.24,17.21-3.09,25.35c4.73,5.38,5.6,10.91,5.4,17.36c-0.17,5.7-0.14,11.42,0.05,17.12 |  | ||||||
| 					c0.08,2.32,0.82,4.63,1.34,7.39C252.64,293.14,259.56,293.14,267.36,293.14z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M459.64,208.46c-9.05,0-17.17,0-26.05,0c-0.44-3.46-1.09-6.2-1.09-8.93c-0.07-31.16-0.05-62.33-0.04-93.49 |  | ||||||
| 					c0-1.22,0.07-2.44,0.15-3.66c0.3-4.41,2.7-6.57,7.1-6.7c4.5-0.13,6.66,2.09,7.24,6.46c4.34,32.91,8.76,65.81,13.07,98.73 |  | ||||||
| 					C460.3,202.98,459.83,205.2,459.64,208.46z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M77.56,97.23c0,36.74,0,73.41,0,111.08c-8.48,0-16.35,0-25.02,0c-0.25-2.71-0.9-5.08-0.6-7.34 |  | ||||||
| 					c4.21-32.52,8.49-65.04,12.9-97.53C65.84,96.02,68.83,94.5,77.56,97.23z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M451.71,362.72c0-42.84,0-84.74,0-127.72c3.45-0.21,6.42-0.39,10.08-0.61c0.46,3.5,1.09,6.04,1.1,8.58 |  | ||||||
| 					c0.06,34.46-0.08,68.92,0.12,103.38C463.06,354.24,458.99,358.62,451.71,362.72z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M50.26,234.87c2.86,0,5.32,0,7.56,0c2.47,5.02,3.24,118.46,0.9,126.79c-5.37-3.13-9.67-6.58-9.66-13.41 |  | ||||||
| 					c0.02-35.65-0.01-71.31,0.05-106.96C49.12,239.34,49.79,237.4,50.26,234.87z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M51.56,390.71c7.99,7.72,15.99,15.44,25.01,24.15c-9.12,2.16-16.82,2.02-24.49,0.42 |  | ||||||
| 					c-1.03-0.21-2.41-2.03-2.45-3.14c-0.23-6.78-0.11-13.57-0.11-20.36C50.2,391.43,50.88,391.07,51.56,390.71z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M436.46,413.79c8.05-7.65,16.1-15.3,24.15-22.95c0.61,0.34,1.23,0.69,1.84,1.03 |  | ||||||
| 					c0,6.76,0.19,13.52-0.17,20.26c-0.07,1.29-2.24,3.46-3.53,3.53c-7.16,0.35-14.35,0.17-21.53,0.17 |  | ||||||
| 					C436.96,415.15,436.71,414.47,436.46,413.79z"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_fight" class="st1"> |  | ||||||
| 	<g class="st2"> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M98.54,121.71c7.19,0.33,14.38,0.67,22.81,1.06c1.18-7.93,2.28-15.34,3.38-22.75 |  | ||||||
| 					c0.65-0.23,1.3-0.46,1.95-0.69c70.17,84.04,140.34,168.07,211.57,253.38c-9.84,8.24-18.85,15.78-28.82,24.13 |  | ||||||
| 					C238.18,291.6,167.84,207.47,97.5,123.34C97.85,122.8,98.2,122.26,98.54,121.71z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M74.25,462.04c-10.75-7.58-20.15-14.21-30.69-21.64C87.39,378.65,130.68,317.64,175,255.19 |  | ||||||
| 					c8.95,10.7,16.69,19.95,24.95,29.82C158.02,344.06,116.54,402.48,74.25,462.04z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M425.22,103.01c0.37,2.17,1.08,4.12,0.96,6.02c-1.52,23.89-10.41,44.55-26.71,62.21 |  | ||||||
| 					c-17.85,19.34-40.04,31.93-63.81,42.21c-1.98,0.86-4.11,1.36-7.64,2.49c1.24-4.12,1.91-6.97,2.94-9.69 |  | ||||||
| 					c6.52-17.26,11.93-34.75,11.33-53.5c-0.09-2.84-0.01-5.86-0.93-8.47c-2.37-6.7,0.06-11.13,5.24-15.36 |  | ||||||
| 					c8.52-6.96,16.52-14.54,24.94-21.63c1.91-1.61,4.59-3.05,6.99-3.2c14.23-0.85,28.48-1.32,42.72-1.86 |  | ||||||
| 					C422.24,102.2,423.23,102.61,425.22,103.01z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M291.85,453.14c-4.87-5.91-8.93-10.84-14.08-17.09c41.71-34.89,82.71-69.18,124.58-104.2 |  | ||||||
| 					c4.79,5.78,8.96,10.8,14.01,16.89C374.53,383.82,333.55,418.17,291.85,453.14z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M273.79,115.61c10.76,7.57,20.25,14.24,30.73,21.61c-17.52,24.77-34.23,48.41-51.86,73.34 |  | ||||||
| 					c-8.76-10.27-16.69-19.55-25.21-29.54C242.84,159.29,257.83,138.14,273.79,115.61z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M310.02,250.99c3.13-1.7,6.08-3.97,9.41-5.02c21.89-6.92,42.92-15.68,62.36-28.02 |  | ||||||
| 					c29.04-18.43,51.93-42.06,63.17-75.38c4.67-13.85,6.52-28.16,6.18-42.77c-0.05-2.01-0.01-4.02-0.01-6.78 |  | ||||||
| 					c3.9-2.17,7.86-4.37,12.69-7.05c1.31,3.33,2.56,5.61,3.12,8.05c3.1,13.52,1.31,26.78-2.57,39.85 |  | ||||||
| 					c-16.18,54.48-81.45,113.08-140.32,120.1c-4.27,0.51-8.65,0.07-12.98,0.07C310.71,253.03,310.37,252.01,310.02,250.99z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M389.79,472.78c-11.28-13.51-21.9-26.23-33.01-39.54c8.13-9.93,17.68-16.81,28.3-24.44 |  | ||||||
| 					c11.08,13.21,21.71,25.89,33.02,39.37C409.83,457.64,400.05,464.37,389.79,472.78z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M321.15,118.13c-11.98-8.39-23.18-16.22-35.16-24.61c4.46-12.23,8.63-23.66,13.37-36.67 |  | ||||||
| 					c17.45,12.36,33.25,23.54,50.46,35.73C339.82,101.49,330.87,109.47,321.15,118.13z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M98.58,95.77c-7.12-0.81-13.28-1.35-19.35-2.36c-1.23-0.2-2.8-2.02-3.15-3.37 |  | ||||||
| 					c-2.23-8.67-4.18-17.41-6.14-26.14c-0.15-0.68,0.35-1.51,0.74-2.98c1.89,0.47,3.64,0.68,5.2,1.33 |  | ||||||
| 					c6.2,2.59,12.29,5.47,18.53,7.94c4.9,1.94,7.04,5.25,6.33,10.43C100.13,85.01,99.49,89.39,98.58,95.77z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M263.6,72.75c-4.58-8.72-9.17-17.44-14.34-27.29c9.64-1.5,17.2,0.6,26.32,3.04 |  | ||||||
| 					c-3.26,8.72-6.26,16.73-9.26,24.75C265.41,73.08,264.5,72.92,263.6,72.75z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M328.1,39.22c10.42,7.7,21.69,12.69,29.96,23.17C349.73,64.21,326.41,46.59,328.1,39.22z"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_compendium" class="st1"> |  | ||||||
| 	<g class="st2"> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M172.73,49.37c21.98,0,43.98,0,66.87,0c0,137.52,0,274.28,0,412.73c-22.56,0.64-44.71,0.55-66.23,0.05 |  | ||||||
| 					C170.22,455.66,169.78,57.56,172.73,49.37z M200.52,429.88c3.18-7.29,2.79-312.57-0.29-318.12c-6.66,0-13.58,0-20.13,0 |  | ||||||
| 					c-3.18,7.31-2.79,312.56,0.29,318.12C187.06,429.88,193.98,429.88,200.52,429.88z M210.72,299.22 |  | ||||||
| 					c-3.15,7.38-2.74,125.16,0.33,130.65c6.67,0,13.59,0,21.35,0c0-43.84,0-86.81,0-130.65 |  | ||||||
| 					C224.64,299.22,217.72,299.22,210.72,299.22z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M145.38,142.76c0,85.62,0,170.31,0,256.67c-17.42,1.03-34.25,0.66-51.8,0.12 |  | ||||||
| 					c-0.49-3.88-1.14-6.62-1.14-9.36c-0.05-79.17-0.06-158.34-0.03-237.52c0-9.54,1.47-10.94,11.07-11 |  | ||||||
| 					c11.02-0.07,22.04-0.07,33.06,0.03C139.11,141.74,141.67,142.3,145.38,142.76z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M363.52,456.03c-12.7,2.35-23.74,4.39-35.68,6.6c-1.26-4.11-2.57-7.24-3.16-10.5 |  | ||||||
| 					c-10.85-60.07-21.6-120.15-32.38-180.23c-7.75-43.2-15.53-86.4-23.26-129.6c-0.49-2.72-0.59-5.51-1-9.55 |  | ||||||
| 					c12.13-2.2,23.57-4.27,36.31-6.58C324.11,236.33,343.65,345.24,363.52,456.03z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M30.77,95.93c12.29,0,23.52,0,35.63,0c0.49,3.12,1.29,5.83,1.29,8.53c0.07,53.47,0.07,106.95,0.02,160.42 |  | ||||||
| 					c0,2.37-0.57,4.75-0.98,8c-11.97,0-23.53,0-35.96,0C30.77,213.88,30.77,155.54,30.77,95.93z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M367.58,238.23c7-3.03,12.81-5.54,20.08-8.69c31.66,74.22,62.88,147.39,94.52,221.55 |  | ||||||
| 					c-7.17,3.14-12.98,5.68-20.06,8.77C430.48,385.69,399.26,312.48,367.58,238.23z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M65.98,461.62c-11.43,0-22.81,0-35.96,0c-0.23-38.48-0.1-76.1-0.08-114.56c13.02,0,24.42,0,35.56,0 |  | ||||||
| 					C68.27,352.44,68.8,453.4,65.98,461.62z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M145.31,461.62c-17.64,0-34.34,0-51.98,0c0-12.22,0-23.59,0-34.65c5.83-2.99,44.82-3.3,51.98-0.36 |  | ||||||
| 					C145.31,437.66,145.31,449.07,145.31,461.62z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M66.94,299.04c0,7.68,0,14,0,20c-5.68,3.23-28.48,3.6-36.48,0.32c0-5.15-0.23-10.92,0.17-16.64 |  | ||||||
| 					c0.09-1.3,2.32-3.48,3.61-3.52C44.72,298.91,55.21,299.04,66.94,299.04z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M344.77,183.51c1.37-6.24,13.25-11.41,18.86-8.56C361.93,179.91,351.56,184.78,344.77,183.51z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M376.69,203.79c-1.47,1.58-2.66,3.99-4.46,4.57c-4.85,1.58-9.26,6.71-16.33,2.77 |  | ||||||
| 					c5.69-6.11,12.27-7.7,18.8-9.41C375.37,202.41,376.03,203.1,376.69,203.79z"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_settings" class="st1"> |  | ||||||
| 	<g class="st2"> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M167.35,468.66c-13.39-1.77-50.61-24-55.69-33.14c1.08-1.73,2.27-3.8,3.62-5.75 |  | ||||||
| 					c9.08-13.11,15.46-27.19,17.17-43.32c2.08-19.66-8.6-38.21-26.93-45.65c-18.45-7.49-36.8-5.28-55.13,0.52 |  | ||||||
| 					c-2.27,0.72-4.61,1.24-7.95,2.13c-8.74-20.07-13.97-40.42-16.04-62.21c3.72-1,6.27-1.51,8.71-2.36 |  | ||||||
| 					c10.15-3.55,20.93-5.98,30.28-11.03c32.02-17.29,37.2-51.45,11.57-77.58c-7.69-7.84-18.02-13.11-27.21-19.46 |  | ||||||
| 					c-1.8-1.24-3.88-2.08-6.88-3.65c7.46-20.81,19.04-38.63,32.65-56.07c2.6,1.58,4.49,2.63,6.28,3.83 |  | ||||||
| 					c12.84,8.66,26.44,15.16,42.16,16.87c27.62,3.01,49.81-16.05,50.75-43.89c0.44-12.98-0.7-25.69-5.26-37.95 |  | ||||||
| 					c-0.57-1.52-0.94-3.13-1.27-4.72c-0.16-0.77-0.03-1.6-0.03-3.56c19.48-9.06,40.19-13.46,62.14-15.74 |  | ||||||
| 					c1.02,3.75,1.82,6.21,2.34,8.72c3.47,16.64,9.06,32.26,21.51,44.52c15.73,15.49,38.24,17.59,56.71,5.52 |  | ||||||
| 					c12.09-7.9,21.07-18.51,27.72-31.22c1.77-3.4,3.56-6.79,5.82-11.11c21.09,7.8,39.67,18.42,56.8,32.93 |  | ||||||
| 					c-1.64,2.8-2.68,4.95-4.05,6.86C388.21,94.64,382,108.15,380,123.56c-3.04,23.55,11.24,44.26,34.61,49.71 |  | ||||||
| 					c15.81,3.69,31.2,1.62,46.42-3.22c2.48-0.79,5-1.42,8.46-2.39c8.98,19.98,13.9,40.42,16.18,62.37c-3.8,0.94-6.46,1.76-9.18,2.25 |  | ||||||
| 					c-16.65,3.01-31.7,9.36-43.86,21.42c-17.55,17.41-17.87,44.76-1.08,62.94c9.09,9.85,19.19,18.29,31.47,23.91 |  | ||||||
| 					c1.97,0.9,3.73,2.29,6.35,3.94c-7.98,20.35-18.77,38.4-32.84,55.12c-3.06-1.75-5.24-2.79-7.18-4.15 |  | ||||||
| 					c-11.9-8.34-24.87-13.72-39.36-15.81c-25.9-3.73-48.07,12.39-52.41,38.17c-2.51,14.96-0.26,29.24,4.49,43.36 |  | ||||||
| 					c0.89,2.64,1.57,5.34,2.63,8.96c-20.39,9.22-41.13,13.92-63.52,15.93c-1.27-5.66-2.36-10.56-3.47-15.47 |  | ||||||
| 					c-2.68-11.93-7.48-22.97-15.18-32.45c-19.22-23.66-48.23-25.35-70.63-3.31c-8,7.87-13.67,18.12-20.35,27.33 |  | ||||||
| 					C170.02,464.25,168.74,466.5,167.35,468.66z M255.86,400.9c76.17,1.14,145.09-60.6,145.17-144.58 |  | ||||||
| 					c0.07-81.43-64.18-146.3-147.02-145.43c-80.82,0.84-143.17,67.24-143.11,145.2C110.95,336.29,175.57,400.89,255.86,400.9z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M255.9,375.07c-66.32-0.01-119.05-52.79-119.18-119.01c-0.12-60.41,46.51-119.03,119.17-119.37 |  | ||||||
| 					c66.88-0.31,119,51.98,119.5,119.66C375.87,322.28,322.28,375.08,255.9,375.07z M256.32,367.82 |  | ||||||
| 					c61.81,0.01,112.28-50.05,111.82-111.65c-0.45-60.76-47.78-111.81-111.76-112.13c-63.11-0.31-112.37,51.07-112.41,112.06 |  | ||||||
| 					C143.95,318.19,193.87,367.82,256.32,367.82z"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_journal" class="st1"> |  | ||||||
| 	<g class="st2"> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M448.42,92.12c-17.01,7.17-36.38,3.32-52.81,13.34c13.35,7.59,25.04,14.25,36.73,20.9 |  | ||||||
| 					c-0.07,0.7-0.15,1.39-0.22,2.09c-10.32,2.08-20.63,4.16-30.95,6.23c-0.13,0.63-0.27,1.25-0.4,1.88 |  | ||||||
| 					c14.07,8.7,28.14,17.4,42.66,26.38c-0.79,3.42-1.29,6.39-2.17,9.24c-9.51,30.75-25.84,57.54-47.17,81.49 |  | ||||||
| 					c-28.41,31.88-43.98,69.29-47.66,111.76c-0.21,2.39-0.8,4.75-1.37,8.08c-3.69,0.38-7.21,1.06-10.74,1.07 |  | ||||||
| 					c-52.87,0.07-105.74-0.15-158.6,0.15c-23.87,0.13-41.44,11.18-51.15,33.28c-13.04,29.65,8.96,66.89,45.53,62.06 |  | ||||||
| 					c6.73-0.89,13.59-0.76,20.39-1.1c0.18,0.69,0.36,1.39,0.54,2.08c-1.95,1.11-3.78,2.8-5.87,3.23 |  | ||||||
| 					c-13.93,2.87-27.83,6.21-41.92,7.89c-9.63,1.15-19.71,0.93-29.3-0.54c-25.73-3.96-39.5-20.96-46.09-44.94 |  | ||||||
| 					c-7.68-27.98-4.86-55.9,1.11-83.65c2.48-11.54,6.41-22.77,9.52-34.19c1.48-5.44,4.92-7.99,10.38-8.84 |  | ||||||
| 					c14.32-2.22,28.6-4.7,42.88-7.15c2.31-0.4,4.55-1.17,8.35-2.18c-12.43-12.92-23.92-24.85-35.68-37.07 |  | ||||||
| 					c10.82-18.72,21.31-36.6,31.53-54.63c10.13-17.88,18.72-36.44,25.46-57.28c-4.1-0.52-6.79-1.1-9.48-1.17 |  | ||||||
| 					c-19.98-0.48-39.99-0.43-59.95-1.38c-24.37-1.15-41.44-13.86-51.3-35.78c-9.41-20.93-7.08-40.88,7.01-59.34 |  | ||||||
| 					c19.06-24.97,49.5-32.54,79.33-22.79c21.47,7.01,43.03,8.54,65.03,9.07c24.68,0.59,49.38,1.73,74.03,1.02 |  | ||||||
| 					c37.08-1.07,74.08-3.17,111.05-7.28c35.35-3.93,63.98,16.8,71.28,52.84C448.69,88.4,448.42,90.05,448.42,92.12z M159.2,70.78 |  | ||||||
| 					c0-1.99,0.18-2.66-0.04-3.16c-0.48-1.12-1.19-2.13-1.74-3.22c-6.25-12.36-16.75-18.76-29.81-22.21 |  | ||||||
| 					c-18.28-4.83-36.2-6.22-53.53,3.12c-21.82,11.76-31.94,33.41-26.21,55.84c5.97,23.41,24.48,37.29,49.57,37.18 |  | ||||||
| 					c17.77-0.08,24.02-8.04,17.19-24.49c-5.04-12.13-12.63-23.2-19.09-34.74c-1.22-2.18-2.46-4.34-4.73-8.33 |  | ||||||
| 					C114.8,70.78,137.01,70.78,159.2,70.78z M125.86,137.58c1.23,0.84,1.72,1.47,2.22,1.47c10.98,0.11,21.98,0.38,32.94-0.05 |  | ||||||
| 					c1.75-0.07,4.42-3.12,4.9-5.2c3.31-14.42,3.93-28.99,1.39-43.67c-1-5.82-3.9-8.4-9.91-8.3c-12.83,0.22-25.67,0.01-38.51,0.11 |  | ||||||
| 					c-2.02,0.02-4.04,0.76-6.94,1.34C121.1,101.11,132.77,117.32,125.86,137.58z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M437.3,403.69c-12.05,6.13-24.1,12.27-36.16,18.4c0.06,0.71,0.11,1.41,0.17,2.12 |  | ||||||
| 					c24.23,2.92,48.45,5.83,72.88,8.77c0.85,2.39,1.74,4.21,2.15,6.14c4.1,19.37-9.24,40.07-28.6,44.05 |  | ||||||
| 					c-5.16,1.06-10.51,1.63-15.78,1.64c-68.14,0.11-136.27,0.08-204.41,0.06c-2.4,0-4.79-0.23-9.27-0.46 |  | ||||||
| 					c10.87-12.42,17.06-25.54,17.43-40.56c0.37-14.77-2.14-29.17-10.26-43.31c3.8-0.56,6.28-1.23,8.77-1.24 |  | ||||||
| 					c60.59-0.06,121.18-0.1,181.76,0.05c7,0.02,13.99,1.22,20.99,1.88C437.07,402.06,437.18,402.88,437.3,403.69z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M208.78,442.37c-2.84,0.3-5.59,0.73-8.35,0.86c-11.77,0.56-23.55,0.9-35.32,1.59 |  | ||||||
| 					c-11.74,0.69-20.7-11.09-17.7-23.56c2.84-11.78,14.12-20.41,27.04-20.71C193.39,400.09,213.19,416.86,208.78,442.37z"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g id="icon_x5F_sidebar_x5F_music" class="st1"> |  | ||||||
| 	<g class="st2"> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M261.65,225.6c0.7,2.64,1.55,5.26,2.07,7.94c1.62,8.25,2.65,8.79,11.01,8.46c15-0.58,29.14,2.2,41.74,11.16 |  | ||||||
| 					c14.6,10.37,19.64,25.5,21.71,42.14c2.78,22.32-10.19,36.76-25.52,49.9c-0.44,0.37-1.09,0.54-1.67,0.69 |  | ||||||
| 					c-0.37,0.09-0.8-0.03-1.59-0.08c-3.15-4.92-2.8-9.59,0.96-14.33c6.14-7.74,11.54-15.89,12.05-26.24 |  | ||||||
| 					c1.24-25.02-14.28-44.09-39.26-47.94c-4.59-0.71-9.31-0.53-15-0.81c0.44,4.72,0.51,7.73,1.03,10.66 |  | ||||||
| 					c8.8,49.42,17.66,98.83,26.47,148.26c1.07,6.03,2.01,12.08,2.81,18.15c1.93,14.59-2.85,26.51-14.6,35.46 |  | ||||||
| 					c-18.51,14.1-39.18,15.5-60.44,8.72c-16.02-5.1-25.76-22.74-22.74-38.34c3.49-18.02,17.24-29.36,35.42-29.2 |  | ||||||
| 					c17.96,0.16,31.41,11.98,34.49,30.27c0.42,2.52,1.01,5.02,1.49,7.33c10.2,0.4,17.08-7.88,15.5-18.5 |  | ||||||
| 					c-3.27-22-6.51-44.01-10.45-65.89c-5.72-31.73-12.04-63.35-18.15-95.01c-0.4-2.07-1.27-4.05-2.29-7.23 |  | ||||||
| 					c-7.24,4.84-12.49,9.93-15.47,17.08c-5.54,13.32-3.63,26.35,1.74,39.25c1.25,3.01,1.98,6.23,2.95,9.35 |  | ||||||
| 					c-0.69,0.48-1.39,0.96-2.08,1.44c-1.98-1.63-4.28-2.98-5.89-4.92c-14.99-18.11-14.14-48.78,1.75-66.18 |  | ||||||
| 					c2.06-2.26,4.06-4.69,6.52-6.45c5.79-4.17,9.56-8.69,8.28-16.73c-0.43-2.71,3.11-6.04,4.83-9.09 |  | ||||||
| 					C260.1,225.14,260.88,225.37,261.65,225.6z"/> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<path class="st0" d="M242.98,129.77c-0.54-2.18-1.24-3.66-1.24-5.15c0.06-27.65,5.24-53.97,20.63-77.55 |  | ||||||
| 					c0.78-1.19,1.62-2.36,2.52-3.47c15.38-18.96,34.82-17.62,45.72,4.2c15.14,30.31,13.51,60.55-6.91,87.73 |  | ||||||
| 					c-13.67,18.2-29.81,34.59-45.42,51.26c-18.14,19.38-36.83,38.27-50.39,61.34c-4.74,8.07-9.5,16.33-12.73,25.07 |  | ||||||
| 					c-8.46,22.81-4.26,43.77,11.57,62.22c9.81,11.44,22.06,19.31,36.6,23.44c5.39,1.53,7.9,4.61,6.35,11.29 |  | ||||||
| 					c-2.86,0-5.84,0.44-8.66-0.07c-31-5.57-50.06-25.12-60.87-53.46c-11.63-30.51-8.06-59.85,11.23-86 |  | ||||||
| 					c15.34-20.81,32.18-40.57,49.3-59.97c15.92-18.03,33.27-34.79,49.64-52.44c11.16-12.03,12.87-27,10.85-42.48 |  | ||||||
| 					c-1.06-8.1-5.98-13.73-14.13-16.01c-7.39-2.07-12.75,1.54-17.1,6.79c-2.57,3.1-5.27,6.57-6.35,10.32 |  | ||||||
| 					c-3.64,12.7-7.02,25.51-9.61,38.46C252.62,122.04,249,126,242.98,129.77z"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| </svg> |  | ||||||
| Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 1.8 KiB | 
							
								
								
									
										54
									
								
								assets/ui/icon_sidebar_macros.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,54 @@ | |||||||
|  | <?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 640 640" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg4" | ||||||
|  |    sodipodi:docname="icon_sidebar_macros.svg" | ||||||
|  |    inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata10"> | ||||||
|  |     <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="defs8" /> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1" | ||||||
|  |      objecttolerance="10" | ||||||
|  |      gridtolerance="10" | ||||||
|  |      guidetolerance="10" | ||||||
|  |      inkscape:pageopacity="0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:window-width="2666" | ||||||
|  |      inkscape:window-height="1514" | ||||||
|  |      id="namedview6" | ||||||
|  |      showgrid="false" | ||||||
|  |      inkscape:zoom="1.6241359" | ||||||
|  |      inkscape:cx="170.14667" | ||||||
|  |      inkscape:cy="292.89075" | ||||||
|  |      inkscape:window-x="0" | ||||||
|  |      inkscape:window-y="0" | ||||||
|  |      inkscape:window-maximized="0" | ||||||
|  |      inkscape:current-layer="svg4" | ||||||
|  |      units="in" /> | ||||||
|  |   <path | ||||||
|  |      d="m 378.25,116.16 c -13.6,-3.92 -27.76,4 -31.68,17.6 l -102.4,358.4 c -3.92,13.6 4,27.76 17.6,31.68 13.6,3.92 27.76,-4 31.68,-17.6 l 102.4,-358.4 c 3.92,-13.6 -4,-27.76 -17.6,-31.68 z m 51.68,108.88 c -10,10 -10,26.24 0,36.24 l 58.72,58.72 -58.72,58.72 c -10,10 -10,26.24 0,36.24 10,10 26.24,10 36.24,0 l 76.8,-76.8 c 10,-10 10,-26.24 0,-36.24 l -76.8,-76.8 c -10,-10 -26.24,-10 -36.24,0 z m -219.76,0 c -10,-10 -26.24,-10 -36.24,0 l -76.8,76.8 c -10,10 -10,26.24 0,36.24 l 76.8,76.8 c 10,10 26.24,10 36.24,0 10,-10 10,-26.24 0,-36.24 L 151.45,320 210.09,261.28 c 10,-10 10,-26.24 0,-36.24 z" | ||||||
|  |      id="path2" | ||||||
|  |      style="fill:#ffffff;stroke-width:0.8" /> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 2.1 KiB | 
| Before Width: | Height: | Size: 4.9 KiB | 
							
								
								
									
										149
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						| @@ -1,21 +1,86 @@ | |||||||
| # 13.0 | # 13.0 | ||||||
|  |  | ||||||
|  | ## 13.0.9 - Le combat d'Illysis | ||||||
|  | - Fix | ||||||
|  |   - La montée en TMR fonctionne | ||||||
|  | - Nouvelle fenêtre de jets de dés | ||||||
|  |   - avancement du mode attaque | ||||||
|  |     - choix de tactique | ||||||
|  |     - choix des dommages, affichage | ||||||
|  |     - affichage de la surprise du défenseur | ||||||
|  |  | ||||||
|  | ## 13.0.8 - Le renouveau d'Illysis | ||||||
|  |  | ||||||
|  | - Fix Foundry V13 | ||||||
|  |   - Les états sont de nouveau affichés en ligne dans la feuille de personnage | ||||||
|  |   - les icones spécifiques Rêve de Dragon de la barre de droite sont de nouveau utilisées | ||||||
|  |  | ||||||
|  | - Nouvelle fenêtre de jets de dés | ||||||
|  |   - uniquement pour les oeuvres (chant, danse, musique, cuisine,...) | ||||||
|  |   - à activer dans les options avancées | ||||||
|  |  | ||||||
|  | ## 13.0.7 - Sous le signe d'Illysis | ||||||
|  |  | ||||||
|  | - Fix Foundry V13 | ||||||
|  |   - les tooltips des ajustements sont correctement visible | ||||||
|  |   - correction des affichages des signes d'heures dans la fenêtre d'astrologie | ||||||
|  |  | ||||||
|  | - en cas d'appel au moral lorsqu'une double significative est requise, | ||||||
|  |   le moral est perdu si la réussite est insuffisante | ||||||
|  | - transformation du niveau des musiques/danses/chants/recettes de cuisine en valeur numérique | ||||||
|  | - les effets draconiques sur une case inconnue (A0) ne causent plus de problèmes dans les TMRs | ||||||
|  |  | ||||||
|  | ## 13.0.6 - Le bandage d'Illysis | ||||||
|  |  | ||||||
|  | - Les soins sont de nouveau disponibles depuis les tokens | ||||||
|  | - Correction des boutons de la feuille simplifiée | ||||||
|  | - On peut de nouveau acheter dans les commerces | ||||||
|  |  | ||||||
|  | ## 13.0.5 | ||||||
|  |  | ||||||
|  | - Export CSV/Scriptarium à nouveau disponible dans les menus d'acteurs | ||||||
|  |  | ||||||
|  | ## 13.0.4 - Le long discours d'Illysis | ||||||
|  |  | ||||||
|  | - On peut de nouveau modifier les descriptions | ||||||
|  | - ne pas proposer l'export csv par défaut | ||||||
|  | - Correction de la macro "Jet quelconque" | ||||||
|  | - Correction de la ligne 'rêve actuel' ajoutée dans les caracs | ||||||
|  | - Corrections d'affichage | ||||||
|  |   - boutons de l'horloge | ||||||
|  |   - boutons de déplacement des TMR | ||||||
|  |   - modification des messages de tchat | ||||||
|  |  | ||||||
|  | ## 13.0.3 - La dernière auberge d'Illysis | ||||||
|  |  | ||||||
|  | - On peut de nouveau acheter aux commerces | ||||||
|  | - La description des Grizzal a des espaces | ||||||
|  | - Corrections v13 | ||||||
|  |   - Affichage des images et noms d'objets en ligne | ||||||
|  |   - affichage des compétences de créature sur une ligne | ||||||
|  |   - Affichage des informations d'acteur sur une ligne dans l'astrologie | ||||||
|  |   - Affichage des résultat de recherche | ||||||
|  |  | ||||||
| ## 13.0.0 - Le début de l'errance d'Illysis | ## 13.0.0 - Le début de l'errance d'Illysis | ||||||
|  |  | ||||||
| - Migration vers la version 13 de Foundry | - Migration vers la version 13 de Foundry | ||||||
|  |  | ||||||
| # 12.0 | # 12.0 | ||||||
|  |  | ||||||
| ## 12.0.50 - Le sommeil d'Astrobazzarh | ## 12.0.50 - Le sommeil d'Astrobazzarh | ||||||
|  |  | ||||||
| - Le don de double rêve n'interrompt plus le sommeil toutes les heures | - Le don de double rêve n'interrompt plus le sommeil toutes les heures | ||||||
| - la perte de fatigue à la descente des TMR est visible immédiatement | - la perte de fatigue à la descente des TMR est visible immédiatement | ||||||
|  |  | ||||||
| ## 12.0.49 - La deuxième lame d'Astrobazzarh | ## 12.0.49 - La deuxième lame d'Astrobazzarh | ||||||
|  |  | ||||||
| - Corrections | - Corrections | ||||||
|   - les défenses particulières sont correctement affichées |   - les défenses particulières sont correctement affichées | ||||||
|   - les vieux boucliers (sans catégorie de parade car créés il y a longtemps) peuvent parer... |   - les vieux boucliers (sans catégorie de parade car créés il y a longtemps) peuvent parer... | ||||||
|   - Les attaques à distance n'ont pas de difficulté libre |   - Les attaques à distance n'ont pas de difficulté libre | ||||||
|  |  | ||||||
| ## 12.0.48 - La chèvre d'Astrobazzarh | ## 12.0.48 - La chèvre d'Astrobazzarh | ||||||
|  |  | ||||||
| - le Bandersnatch a une protection de 10 | - le Bandersnatch a une protection de 10 | ||||||
| - la consistance chèvre est maintenant possible dans les recettes | - la consistance chèvre est maintenant possible dans les recettes | ||||||
|   alchimiques (et toutes les consistances avec accents) |   alchimiques (et toutes les consistances avec accents) | ||||||
| @@ -24,10 +89,12 @@ | |||||||
| - Correction: les réussites particulières fonctionnent avec les caractéristiques dérivées | - Correction: les réussites particulières fonctionnent avec les caractéristiques dérivées | ||||||
|  |  | ||||||
| ## 12.0.47 | ## 12.0.47 | ||||||
|  |  | ||||||
| - Correction sur les mise à jour en cascade - | - Correction sur les mise à jour en cascade - | ||||||
| - Correction sur le force rendering après un changement de competence | - Correction sur le force rendering après un changement de competence | ||||||
|  |  | ||||||
| ## 12.0.46 - Le double demi d'Astrobazzarh | ## 12.0.46 - Le double demi d'Astrobazzarh | ||||||
|  |  | ||||||
| - correction des raffraîchissement lors du sommeil qui empêchait de dormir | - correction des raffraîchissement lors du sommeil qui empêchait de dormir | ||||||
|   plusieurs heures |   plusieurs heures | ||||||
| - Si la fatigue n'est pas utilisée, les rounds dans les TMR font perdre de l'endurance (au lieu d'en gagner) | - Si la fatigue n'est pas utilisée, les rounds dans les TMR font perdre de l'endurance (au lieu d'en gagner) | ||||||
| @@ -54,18 +121,22 @@ | |||||||
| - Correction des jets `@roll[vue/-2]` qui tentaient de chercher une compétence -2 (à cause des armes à 1/2 mains) | - Correction des jets `@roll[vue/-2]` qui tentaient de chercher une compétence -2 (à cause des armes à 1/2 mains) | ||||||
|  |  | ||||||
| ## 12.0.41 - La loupe d'Astrobazzarh | ## 12.0.41 - La loupe d'Astrobazzarh | ||||||
|  |  | ||||||
| - On peut de nouveau effectuer des tirages cachés | - On peut de nouveau effectuer des tirages cachés | ||||||
| - Le stress transformé est bien diminué lorsqu'on met le stress dans une compétence | - Le stress transformé est bien diminué lorsqu'on met le stress dans une compétence | ||||||
|  |  | ||||||
| ## 12.0.40 - Les mains d'Astrobazzarh | ## 12.0.40 - Les mains d'Astrobazzarh | ||||||
|  |  | ||||||
| - correction des attaques particulières en combat | - correction des attaques particulières en combat | ||||||
| - correction de message sur les min/max liés aux modificateurs de races (s'applique uniquement sur la taille) | - correction de message sur les min/max liés aux modificateurs de races (s'applique uniquement sur la taille) | ||||||
|  |  | ||||||
| ## 12.0.39 - Les mains d'Astrobazzarh | ## 12.0.39 - Les mains d'Astrobazzarh | ||||||
|  |  | ||||||
| - les armes à 1 ou 2 mains fonctionnent dans les liens de jets de dés | - les armes à 1 ou 2 mains fonctionnent dans les liens de jets de dés | ||||||
| - commande `/jet` pour poster une demande de jet de dés | - commande `/jet` pour poster une demande de jet de dés | ||||||
|  |  | ||||||
| ## 12.0.38 - Les prévisions d'Astrobazzarh | ## 12.0.38 - Les prévisions d'Astrobazzarh | ||||||
|  |  | ||||||
| - Correction de modifications de personnages qui ne s'affichaient pas: | - Correction de modifications de personnages qui ne s'affichaient pas: | ||||||
|   - changements d'endurance/vie/fatigue, transformé, ... |   - changements d'endurance/vie/fatigue, transformé, ... | ||||||
| - Migration des compétences "Ecriture" en "Écriture" dans les tâches, livres, oeuvres et méditations | - Migration des compétences "Ecriture" en "Écriture" dans les tâches, livres, oeuvres et méditations | ||||||
| @@ -75,12 +146,14 @@ | |||||||
|   - utilisation de l'extension hbs pour tous les fichiers handlebars |   - utilisation de l'extension hbs pour tous les fichiers handlebars | ||||||
|  |  | ||||||
| ## 12.0.37 - Les enchantements d'Astrobazzarh | ## 12.0.37 - Les enchantements d'Astrobazzarh | ||||||
|  |  | ||||||
| - les potions ont un état, seules les potions liquides sont enchantables | - les potions ont un état, seules les potions liquides sont enchantables | ||||||
| - les lancements de sorts du jour sont conservés jusqu'à chateau dormant | - les lancements de sorts du jour sont conservés jusqu'à chateau dormant | ||||||
| - lorsqu'un joueur souhaite enchanter une potion, les sorts d'enchantements/purification/permanence doivent avoir été lancés auparavant | - lorsqu'un joueur souhaite enchanter une potion, les sorts d'enchantements/purification/permanence doivent avoir été lancés auparavant | ||||||
| - on peut enchanter des gemmes exactement comme des potions | - on peut enchanter des gemmes exactement comme des potions | ||||||
|  |  | ||||||
| ## 12.0.36 - L'alchimie d'Astrobazzarh | ## 12.0.36 - L'alchimie d'Astrobazzarh | ||||||
|  |  | ||||||
| - Nouveautés | - Nouveautés | ||||||
|   - ajout d'un bouton pour enchanter les potions |   - ajout d'un bouton pour enchanter les potions | ||||||
|   - standardisation des boutons d'actions sur les items |   - standardisation des boutons d'actions sur les items | ||||||
| @@ -95,9 +168,11 @@ | |||||||
|   - Corrections de descriptions pour proposer les jet de dés |   - Corrections de descriptions pour proposer les jet de dés | ||||||
|  |  | ||||||
| ## 12.0.35 - La Solution d'Astrobazzarh | ## 12.0.35 - La Solution d'Astrobazzarh | ||||||
|  |  | ||||||
| - Fix problème d'initialisation des feuilles d'items | - Fix problème d'initialisation des feuilles d'items | ||||||
|  |  | ||||||
| ## 12.0.34 - la tête d'Astrobazzarh | ## 12.0.34 - la tête d'Astrobazzarh | ||||||
|  |  | ||||||
| - support de liens "jets de dés" | - support de liens "jets de dés" | ||||||
|   - on peut ajouter des liens "jet de dés" dans les journaux, descriptions, notes, maladresses, ... |   - on peut ajouter des liens "jet de dés" dans les journaux, descriptions, notes, maladresses, ... | ||||||
|   - avec la syntaxe `@roll[...]` on peut ajouter le lien vers: |   - avec la syntaxe `@roll[...]` on peut ajouter le lien vers: | ||||||
| @@ -112,28 +187,35 @@ | |||||||
| - gestion des blocs secrets dans les descriptions | - gestion des blocs secrets dans les descriptions | ||||||
|  |  | ||||||
| ## 12.0.33 - la vieillesse d'Astrobazzarh | ## 12.0.33 - la vieillesse d'Astrobazzarh | ||||||
|  |  | ||||||
| - retour de l'expérience pour les joueurs | - retour de l'expérience pour les joueurs | ||||||
| - suppression du message "Pas de caractéristique" sur les jets d'odorat-goût | - suppression du message "Pas de caractéristique" sur les jets d'odorat-goût | ||||||
|  |  | ||||||
| ## 12.0.32 - les rêveries d'Astrobazzarh | ## 12.0.32 - les rêveries d'Astrobazzarh | ||||||
|  |  | ||||||
| - Ajout des Items Race pour gérer les ajustements liés aux races | - Ajout des Items Race pour gérer les ajustements liés aux races | ||||||
|  |  | ||||||
| ## 12.0.31 - le mausolée d'Astrobazzarh | ## 12.0.31 - le mausolée d'Astrobazzarh | ||||||
|  |  | ||||||
| - Correction: les automatisation de combat jouer-MJ fonctionnentde nouveau | - Correction: les automatisation de combat jouer-MJ fonctionnentde nouveau | ||||||
|  |  | ||||||
| ## 12.0.30 - le cauchemar d'Astrobazzarh | ## 12.0.30 - le cauchemar d'Astrobazzarh | ||||||
|  |  | ||||||
| - calcul automatique du niveau des entités selon leur rêve | - calcul automatique du niveau des entités selon leur rêve | ||||||
| - la description des créatures venimeuses contient un lien vers leur venin | - la description des créatures venimeuses contient un lien vers leur venin | ||||||
| - Correction: les messages de combats ne marchaient plus (Changement combiné Foundry + rêve de Dragon) | - Correction: les messages de combats ne marchaient plus (Changement combiné Foundry + rêve de Dragon) | ||||||
|  |  | ||||||
| ## 12.0.29 - L'indexation d'Astrobazzarh | ## 12.0.29 - L'indexation d'Astrobazzarh | ||||||
|  |  | ||||||
| - les liens dans la descriptions des sorts pointent vers les sorts du compendium | - les liens dans la descriptions des sorts pointent vers les sorts du compendium | ||||||
| - la description du chrasme contient le lien vers son venin plutôt qu'un tableau | - la description du chrasme contient le lien vers son venin plutôt qu'un tableau | ||||||
|  |  | ||||||
| ## 12.0.28 - Les réserves d'Astrobazzarh | ## 12.0.28 - Les réserves d'Astrobazzarh | ||||||
|  |  | ||||||
| - possibilité de mettre en réserve depuis un sort connu | - possibilité de mettre en réserve depuis un sort connu | ||||||
|  |  | ||||||
| ## 12.0.27 - Les vêtements d'Astrobazzarh | ## 12.0.27 - Les vêtements d'Astrobazzarh | ||||||
|  |  | ||||||
| - Ajout de la liste des armures dans l'onglet caractéristiques | - Ajout de la liste des armures dans l'onglet caractéristiques | ||||||
| - Ajout d'une option pour choisir une carte des TMR alternatives | - Ajout d'une option pour choisir une carte des TMR alternatives | ||||||
| - Le Gardien peut créer des sorts en réserve parmi les sorts d'un personnage | - Le Gardien peut créer des sorts en réserve parmi les sorts d'un personnage | ||||||
| @@ -154,12 +236,14 @@ | |||||||
|   - les modèles de personnages non joueurs sont non-liés par défaut |   - les modèles de personnages non joueurs sont non-liés par défaut | ||||||
|  |  | ||||||
| ## 12.0.26 - Astrobazzarh le Haut-rêvant | ## 12.0.26 - Astrobazzarh le Haut-rêvant | ||||||
|  |  | ||||||
| - bouton pour le don de haut-rêve en un clic | - bouton pour le don de haut-rêve en un clic | ||||||
| - les compétences de draconic ne sont plus précédées de "Voie de" | - les compétences de draconic ne sont plus précédées de "Voie de" | ||||||
|   - migration des compétences & compendiums |   - migration des compétences & compendiums | ||||||
| - Correction feuille simplifiée qui ne s'affichait pas en cas de sort variable | - Correction feuille simplifiée qui ne s'affichait pas en cas de sort variable | ||||||
|  |  | ||||||
| ## 12.0.24 - Les ajustements d'Astrobazzarh | ## 12.0.24 - Les ajustements d'Astrobazzarh | ||||||
|  |  | ||||||
| - amélioration | - amélioration | ||||||
|   - meilleure gestion des noms des voies de draconic |   - meilleure gestion des noms des voies de draconic | ||||||
|   - affichage du détail des sorts avec le nom de voie, 'court', la difficulté, le coût |   - affichage du détail des sorts avec le nom de voie, 'court', la difficulté, le coût | ||||||
| @@ -169,6 +253,7 @@ | |||||||
|   - on peut maintenant saisir et supprimer les bonus de cases de manière intuitive |   - on peut maintenant saisir et supprimer les bonus de cases de manière intuitive | ||||||
|  |  | ||||||
| ## 12.0.23 - La bibliothèque d'Astrobazzarh | ## 12.0.23 - La bibliothèque d'Astrobazzarh | ||||||
|  |  | ||||||
| - corrections mineures | - corrections mineures | ||||||
|   - meilleure gestion de la parade des armes naturelles |   - meilleure gestion de la parade des armes naturelles | ||||||
|   - cas de "User lacks permission to update" pour les blessures et les StatusEffects |   - cas de "User lacks permission to update" pour les blessures et les StatusEffects | ||||||
| @@ -184,19 +269,23 @@ | |||||||
|   - dans les compendiums, les compétences Écriture et Épée ont une majuscule accentuée. Les Épée dans le compendium d'équipements référence le nom de compétence accentué. |   - dans les compendiums, les compétences Écriture et Épée ont une majuscule accentuée. Les Épée dans le compendium d'équipements référence le nom de compétence accentué. | ||||||
|  |  | ||||||
| ## 12.0.21 - La nomination d'Astrobazzarh | ## 12.0.21 - La nomination d'Astrobazzarh | ||||||
|  |  | ||||||
| - Les noms pour les messages dans le tchat sont maintenant ceux des tokens plutôt que ceux des acteurs | - Les noms pour les messages dans le tchat sont maintenant ceux des tokens plutôt que ceux des acteurs | ||||||
| - Fix: le choix des effets dans les options s'affiche correctement | - Fix: le choix des effets dans les options s'affiche correctement | ||||||
|  |  | ||||||
| ## 12.0.20 - Le tableau d'Astrobazzarh | ## 12.0.20 - Le tableau d'Astrobazzarh | ||||||
|  |  | ||||||
| - Ecran d'accueil officiel Scriptarium | - Ecran d'accueil officiel Scriptarium | ||||||
|  |  | ||||||
| ## 12.0.19 - La témérité d'Astrobazzarh | ## 12.0.19 - La témérité d'Astrobazzarh | ||||||
|  |  | ||||||
| - Fix | - Fix | ||||||
|   - les défenses des créatures sont correctement filtrées |   - les défenses des créatures sont correctement filtrées | ||||||
|   - le lancer d'initiative pour tous les personnages/PNJs fonctionne correctement |   - le lancer d'initiative pour tous les personnages/PNJs fonctionne correctement | ||||||
|   - les lieux et commerces n'ont pas d'initiative |   - les lieux et commerces n'ont pas d'initiative | ||||||
|  |  | ||||||
| ## 12.0.18 - A la barbe d'Astrobazzarh | ## 12.0.18 - A la barbe d'Astrobazzarh | ||||||
|  |  | ||||||
| - Améliorations sur la feuille de PNJ simplifiée | - Améliorations sur la feuille de PNJ simplifiée | ||||||
|   - Ajout du portrait |   - Ajout du portrait | ||||||
|   - Ajout du corps à corps |   - Ajout du corps à corps | ||||||
| @@ -213,11 +302,13 @@ | |||||||
| - Ajout d'un indicateur pour les armes de parade nécessitant une significative | - Ajout d'un indicateur pour les armes de parade nécessitant une significative | ||||||
|  |  | ||||||
| ## 12.0.16 - Le secret d'Astrobazzarh | ## 12.0.16 - Le secret d'Astrobazzarh | ||||||
|  |  | ||||||
| - Fix: les jets envoyés messages uniquement au MJ ne sont plus envoyés à tous les autres joueurs (et dupliqués) | - Fix: les jets envoyés messages uniquement au MJ ne sont plus envoyés à tous les autres joueurs (et dupliqués) | ||||||
| - Les noms affichés dans les automatisations de combat sont maintenant ceux des tokens plutôt que ceux des acteurs | - Les noms affichés dans les automatisations de combat sont maintenant ceux des tokens plutôt que ceux des acteurs | ||||||
| - Ajout d'une option pour la localisation des blessures | - Ajout d'une option pour la localisation des blessures | ||||||
|  |  | ||||||
| ## 12.0.15 - Le messager d'Astrobazzarh | ## 12.0.15 - Le messager d'Astrobazzarh | ||||||
|  |  | ||||||
| - Correction des faces de dés personalisés dice-so-nice | - Correction des faces de dés personalisés dice-so-nice | ||||||
| - Les messages de maladies ne sont plus publics | - Les messages de maladies ne sont plus publics | ||||||
| - Les messages privés dans les TMR sont aussi envoyés au GM | - Les messages privés dans les TMR sont aussi envoyés au GM | ||||||
| @@ -225,6 +316,7 @@ | |||||||
| - Amélioration du rendu des tables de compendiums (commande /table) | - Amélioration du rendu des tables de compendiums (commande /table) | ||||||
|  |  | ||||||
| ## 12.0.14 - Les légions d'Astrobazzarh | ## 12.0.14 - Les légions d'Astrobazzarh | ||||||
|  |  | ||||||
| - Feuille de PNJ: | - Feuille de PNJ: | ||||||
|   - boutons standard (encaissement, ...) |   - boutons standard (encaissement, ...) | ||||||
|   - boutons pour ajuster les compteurs |   - boutons pour ajuster les compteurs | ||||||
| @@ -233,15 +325,18 @@ | |||||||
|   - gestion des armes |   - gestion des armes | ||||||
|  |  | ||||||
| ## 12.0.13 - La Chance d'Astrobazzarh | ## 12.0.13 - La Chance d'Astrobazzarh | ||||||
|  |  | ||||||
| - Fix: jets de caractéristiques | - Fix: jets de caractéristiques | ||||||
|  |  | ||||||
| ## 12.0.12 - L'étalage d'Astrobazzarh | ## 12.0.12 - L'étalage d'Astrobazzarh | ||||||
|  |  | ||||||
| - Fix: On peut de nouveau vendre des items sans propriétaire, depuis les compendiums ou depuis l'onglet des Objets | - Fix: On peut de nouveau vendre des items sans propriétaire, depuis les compendiums ou depuis l'onglet des Objets | ||||||
| - Début de Feuille PNJ au format des encarts Scriptarium | - Début de Feuille PNJ au format des encarts Scriptarium | ||||||
|   - support des jets de caractéristiques |   - support des jets de caractéristiques | ||||||
|   - support des jets de compétences |   - support des jets de compétences | ||||||
|  |  | ||||||
| ## 12.0.11 - Le scriptorium d'Astrobazzarh | ## 12.0.11 - Le scriptorium d'Astrobazzarh | ||||||
|  |  | ||||||
| - ajout d'un bouton pour générer les éléments de description d'un personnage | - ajout d'un bouton pour générer les éléments de description d'un personnage | ||||||
| - ajout du logo en background dans la liste des systèmes Foundry | - ajout du logo en background dans la liste des systèmes Foundry | ||||||
| - ajout d'un champ pour le métier | - ajout d'un champ pour le métier | ||||||
| @@ -250,10 +345,12 @@ | |||||||
|   - export de l'esquive avec armure et sans armure |   - export de l'esquive avec armure et sans armure | ||||||
|  |  | ||||||
| ## 12.0.9 - 12.0.10 - Le scriptorium d'Astrobazzarh | ## 12.0.9 - 12.0.10 - Le scriptorium d'Astrobazzarh | ||||||
|  |  | ||||||
| - corrections de l'export scriptarium | - corrections de l'export scriptarium | ||||||
| - ajout d'une fonction avancée pour un exporter "scriptarium" des personnages | - ajout d'une fonction avancée pour un exporter "scriptarium" des personnages | ||||||
|  |  | ||||||
| ## 12.0.8 - La quincaillerie d'Astrobazzarh | ## 12.0.8 - La quincaillerie d'Astrobazzarh | ||||||
|  |  | ||||||
| - le propriétaire est indiqué dans les feuilles d'équipements/compétences/... | - le propriétaire est indiqué dans les feuilles d'équipements/compétences/... | ||||||
| - Ecaille d'efficacité | - Ecaille d'efficacité | ||||||
|   - l'écaille d'efficacité est prise en compte même si on n'utilise pas le ciblage en combat |   - l'écaille d'efficacité est prise en compte même si on n'utilise pas le ciblage en combat | ||||||
| @@ -263,6 +360,7 @@ | |||||||
|   - le tooltip de l'initiative affiche correctement l'initiative |   - le tooltip de l'initiative affiche correctement l'initiative | ||||||
|  |  | ||||||
| ## 12.0.7 - La propriété d'Astrobazzarh | ## 12.0.7 - La propriété d'Astrobazzarh | ||||||
|  |  | ||||||
| - correction des opérations faites à la création d'un Item: | - correction des opérations faites à la création d'un Item: | ||||||
|   - la durée des queues/rencontres/souffles |   - la durée des queues/rencontres/souffles | ||||||
|   - les effets draconiques d'un souffle/queue |   - les effets draconiques d'un souffle/queue | ||||||
| @@ -277,6 +375,7 @@ | |||||||
| - la commande /voyage affiche maintenant les compétences liées au terrain | - la commande /voyage affiche maintenant les compétences liées au terrain | ||||||
|  |  | ||||||
| ## 12.0.6 - Le bazar d'Astrobazzarh | ## 12.0.6 - Le bazar d'Astrobazzarh | ||||||
|  |  | ||||||
| - Corrections de l'inventaire en bazar: | - Corrections de l'inventaire en bazar: | ||||||
|   - un problème pouvait survenir en déplaçant les objets |   - un problème pouvait survenir en déplaçant les objets | ||||||
|     l'inventaire, qui fait qu'un conteneur se retrouve récursivement dans son |     l'inventaire, qui fait qu'un conteneur se retrouve récursivement dans son | ||||||
| @@ -291,22 +390,26 @@ | |||||||
| - Fix: restaurer la compatibilité Foundry 11 | - Fix: restaurer la compatibilité Foundry 11 | ||||||
|  |  | ||||||
| ## 12.0.5 - Les mauvais jours d'Astrobazzarh | ## 12.0.5 - Les mauvais jours d'Astrobazzarh | ||||||
|  |  | ||||||
| - Fix: on peut de nouveau ouvrir l'édition de calendrier | - Fix: on peut de nouveau ouvrir l'édition de calendrier | ||||||
| - Fix: on ne peut plus ouvrir plusieurs fenêtres de lancer de sort | - Fix: on ne peut plus ouvrir plusieurs fenêtres de lancer de sort | ||||||
| - Fix: Failed to execute 'getComputedStyle' on 'Window' | - Fix: Failed to execute 'getComputedStyle' on 'Window' | ||||||
|  |  | ||||||
| ## 12.0.4 - La plaie d'Astrobazzarh | ## 12.0.4 - La plaie d'Astrobazzarh | ||||||
|  |  | ||||||
| - **Support V12** | - **Support V12** | ||||||
|   - Fix: les boutons d'encaissement dans le tchat fonctionnent de nouveau |   - Fix: les boutons d'encaissement dans le tchat fonctionnent de nouveau | ||||||
|   - Fix warnings sur "Die" et AudioHelper |   - Fix warnings sur "Die" et AudioHelper | ||||||
|  |  | ||||||
| ## 12.0.3 - L'hémorragie d'Astrobazzarh | ## 12.0.3 - L'hémorragie d'Astrobazzarh | ||||||
|  |  | ||||||
| - **Support V12** | - **Support V12** | ||||||
|   - On peut de nouveau ouvrir un acteur blessé après redémarrage du monde |   - On peut de nouveau ouvrir un acteur blessé après redémarrage du monde | ||||||
|   - On peut de nouveau ouvrir les Items avec une rareté par environnement |   - On peut de nouveau ouvrir les Items avec une rareté par environnement | ||||||
|   - Le choix de ne plus afficher les demandes de suppression est bien pris en compte |   - Le choix de ne plus afficher les demandes de suppression est bien pris en compte | ||||||
|  |  | ||||||
| ## 12.0.2 - Les pluies d'Astrobazzarh | ## 12.0.2 - Les pluies d'Astrobazzarh | ||||||
|  |  | ||||||
| - **Support V12** | - **Support V12** | ||||||
|   - correction des actions techniques déleguées au MJ qui bloquaient les fenêtre de lancer de dés des joueurs (et plein d'autres) |   - correction des actions techniques déleguées au MJ qui bloquaient les fenêtre de lancer de dés des joueurs (et plein d'autres) | ||||||
|   - la fenêtre de calendrier s'ouvre correctement |   - la fenêtre de calendrier s'ouvre correctement | ||||||
| @@ -321,13 +424,16 @@ | |||||||
|   - correction d'erreurs intempestives 'User ... lacks permission to update ...' |   - correction d'erreurs intempestives 'User ... lacks permission to update ...' | ||||||
|  |  | ||||||
| # 11.2 | # 11.2 | ||||||
|  |  | ||||||
| ## 11.2.21 - Le questionnement d'Akarlikarlikar | ## 11.2.21 - Le questionnement d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Une confirmation spécifique est demandée pour monter dans les terres médianes en cas de rencontre en attente | - Une confirmation spécifique est demandée pour monter dans les terres médianes en cas de rencontre en attente | ||||||
| - L'expérience en caractéristique sur les jets de chance et rêve actuels est mise dans la caractéristique correspondante | - L'expérience en caractéristique sur les jets de chance et rêve actuels est mise dans la caractéristique correspondante | ||||||
| - Les effets s'appliquent correctement sur les créatures | - Les effets s'appliquent correctement sur les créatures | ||||||
| - La date et l'heure (draconiques) sont affichées dans les messages du tchat | - La date et l'heure (draconiques) sont affichées dans les messages du tchat | ||||||
|  |  | ||||||
| ## 11.2.20 - Le soulagement d'Akarlikarlikar | ## 11.2.20 - Le soulagement d'Akarlikarlikar | ||||||
|  |  | ||||||
| - L'option "ajout de la difficulté d'attaque à l'encaissement" est affichée comme un modificateur d'encaissement | - L'option "ajout de la difficulté d'attaque à l'encaissement" est affichée comme un modificateur d'encaissement | ||||||
| - Les options d'encaissement alternatives fonctionnent avec la validation de l'encaissement par le gardien | - Les options d'encaissement alternatives fonctionnent avec la validation de l'encaissement par le gardien | ||||||
| - La fenêtre d'astrologie du gardien affiche toutes les heures lues par un personnage | - La fenêtre d'astrologie du gardien affiche toutes les heures lues par un personnage | ||||||
| @@ -337,12 +443,15 @@ | |||||||
| - Les messages de récupération de rêve en cas de Rêve de Dragon sont clarifiés | - Les messages de récupération de rêve en cas de Rêve de Dragon sont clarifiés | ||||||
|  |  | ||||||
| ## 11.2.19 - Les hémorroïdes d'Akarlikarlikar | ## 11.2.19 - Les hémorroïdes d'Akarlikarlikar | ||||||
|  |  | ||||||
| - La validation des jets d'encaissement par le Gardien fonctionne de nouveau | - La validation des jets d'encaissement par le Gardien fonctionne de nouveau | ||||||
|  |  | ||||||
| ## 11.2.18 - Le bourrichon d'Akarlikarlikar | ## 11.2.18 - Le bourrichon d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Les différentes listes de la feuille de personnage ont maintenant le bouton pour envoyer dans le tchat | - Les différentes listes de la feuille de personnage ont maintenant le bouton pour envoyer dans le tchat | ||||||
|  |  | ||||||
| ## 11.2.17 - Le cache-oeil d'Akarlikarlikar | ## 11.2.17 - Le cache-oeil d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Le titre des fenêtre d'objet affiche de nouveau le type traduit | - Le titre des fenêtre d'objet affiche de nouveau le type traduit | ||||||
| - Les tooltips des boutons edit/delete sont maintenant en Français | - Les tooltips des boutons edit/delete sont maintenant en Français | ||||||
| - La case à cocher "Cacher les points de tâches" fonctionne de nouveau | - La case à cocher "Cacher les points de tâches" fonctionne de nouveau | ||||||
| @@ -351,35 +460,43 @@ | |||||||
| - La fenêtre des TMRs ne devrait plus afficher une zone noire au lieu de la carte. | - La fenêtre des TMRs ne devrait plus afficher une zone noire au lieu de la carte. | ||||||
|  |  | ||||||
| ## 11.2.16 - Le Tri d'Akarlikarlikar | ## 11.2.16 - Le Tri d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Tri alphabétique des items dans la fenêtre de création | - Tri alphabétique des items dans la fenêtre de création | ||||||
| - Mise à jour comptage de monde | - Mise à jour comptage de monde | ||||||
|  |  | ||||||
| ## 11.2.15 - La Table d'Akarlikarlikar | ## 11.2.15 - La Table d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Tirage automatique de la foce d'une rencontre (via la commande /tmrr) | - Tirage automatique de la foce d'une rencontre (via la commande /tmrr) | ||||||
| - Ajout de boutons pour ajouter des blessures "complètes" (ie avec perte d'endurance/vie) | - Ajout de boutons pour ajouter des blessures "complètes" (ie avec perte d'endurance/vie) | ||||||
|  |  | ||||||
| ## 11.2.14 - Les petits pas d'Akarlikarlikar | ## 11.2.14 - Les petits pas d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Correction sur la gestion de la surprise | - Correction sur la gestion de la surprise | ||||||
| - Ordre des messages sur les cases humides | - Ordre des messages sur les cases humides | ||||||
|  |  | ||||||
| ## 11.2.13 - Les cent pas d'Akarlikarlikar | ## 11.2.13 - Les cent pas d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Ajout de la commande /voyage pour gérer la fatigue de marche des voyageurs | - Ajout de la commande /voyage pour gérer la fatigue de marche des voyageurs | ||||||
|  |  | ||||||
| ## 11.2.12 - Le somnifère  d'Akarlikarlikar | ## 11.2.12 - Le somnifère  d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Fix: les potions enchantées n'empêchent plus de finir correctement Château Dormant | - Fix: les potions enchantées n'empêchent plus de finir correctement Château Dormant | ||||||
|  |  | ||||||
| ## 11.2.11 - Le miroir d'Akarlikarlikar | ## 11.2.11 - Le miroir d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Changement des images de compétence de créatures morsure/pinces pour être dans le thème | - Changement des images de compétence de créatures morsure/pinces pour être dans le thème | ||||||
| - Suppression de la bordure autour des portraits d'acteurs, remplacés par un légèr éclaircissement du fond | - Suppression de la bordure autour des portraits d'acteurs, remplacés par un légèr éclaircissement du fond | ||||||
| - Fix: le refoulement ajoute correctement un souffle et revient à 0 en cas d'échec | - Fix: le refoulement ajoute correctement un souffle et revient à 0 en cas d'échec | ||||||
|  |  | ||||||
| ## 11.2.10 - Les expériences d'Akarlikarlikar | ## 11.2.10 - Les expériences d'Akarlikarlikar | ||||||
|  |  | ||||||
| - En cas d'expérience des caractéristiques dérivées, | - En cas d'expérience des caractéristiques dérivées, | ||||||
|   - si plusieurs caractéristiques pourraient recevoir l'expérience, une fenêtre demande au joueur |   - si plusieurs caractéristiques pourraient recevoir l'expérience, une fenêtre demande au joueur | ||||||
|   - si une seule caractéristique peut recevoir de l'expérience, c'est attribué automatiquement |   - si une seule caractéristique peut recevoir de l'expérience, c'est attribué automatiquement | ||||||
| - Si la force est au maximum pour la taille personnage, on ne peut plus gagner d'expérience | - Si la force est au maximum pour la taille personnage, on ne peut plus gagner d'expérience | ||||||
|  |  | ||||||
| ## 11.2.9 - La barbe d'Akarlikarlikar | ## 11.2.9 - La barbe d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Amélioration des textes de tooltips | - Amélioration des textes de tooltips | ||||||
| - Les tooltips sont plus dans le thème de couleur du système Rêve de Dragon | - Les tooltips sont plus dans le thème de couleur du système Rêve de Dragon | ||||||
| - Ajouts d'icones pour les attaque/initiative/soins dans les raccourcis sur les tokens (HUD) | - Ajouts d'icones pour les attaque/initiative/soins dans les raccourcis sur les tokens (HUD) | ||||||
| @@ -391,19 +508,23 @@ | |||||||
| - Changement de l'icône d'état d'empoignade pour suivre les couleurs des autres icônes d'état | - Changement de l'icône d'état d'empoignade pour suivre les couleurs des autres icônes d'état | ||||||
|  |  | ||||||
| ## 11.2.8 - L'éclairage d'Akarlikarlikar | ## 11.2.8 - L'éclairage d'Akarlikarlikar | ||||||
|  |  | ||||||
| - l'ajustement de la lumière jour/nuit s'étale sur moins de temps (vaisseau et Lyre) | - l'ajustement de la lumière jour/nuit s'étale sur moins de temps (vaisseau et Lyre) | ||||||
| - les nouveaux tooltips ne masquent plus l'information d'expérience | - les nouveaux tooltips ne masquent plus l'information d'expérience | ||||||
| - les jets de dés pour maîtriser les rencontres fonctionnent de nouveau | - les jets de dés pour maîtriser les rencontres fonctionnent de nouveau | ||||||
|  |  | ||||||
| ## 11.2.7 - Les explications d'Akarlikarlikar | ## 11.2.7 - Les explications d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Ajout de tooltips sur la plupart des boutons, liens clickables, objets, tâches, ... | - Ajout de tooltips sur la plupart des boutons, liens clickables, objets, tâches, ... | ||||||
| - Fix: on peut de nouveau regarder l'inventaire avec les droits limités/observateur | - Fix: on peut de nouveau regarder l'inventaire avec les droits limités/observateur | ||||||
|  |  | ||||||
| ## 11.2.6 - Les réveils difficiles d'Akarlikarlikar | ## 11.2.6 - Les réveils difficiles d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Les changements de points de Cœur sont temporaires jusqu'à fin Château Dormant | - Les changements de points de Cœur sont temporaires jusqu'à fin Château Dormant | ||||||
| - Fix: tous les petits fixes (feuille qui s'ouvre plus, compagnons animaux, potions qui bloquent Château Dormant, ...) | - Fix: tous les petits fixes (feuille qui s'ouvre plus, compagnons animaux, potions qui bloquent Château Dormant, ...) | ||||||
|  |  | ||||||
| ## 11.2.2 - Les tendres moments d'Akarlikarlikar | ## 11.2.2 - Les tendres moments d'Akarlikarlikar | ||||||
|  |  | ||||||
| - On peut maintenant avoir des points de Cœur pour des suivants/compagnons | - On peut maintenant avoir des points de Cœur pour des suivants/compagnons | ||||||
|   - diminuer les points de coeurs fait perdre du moral |   - diminuer les points de coeurs fait perdre du moral | ||||||
|   - on peut proposer un tendre moment |   - on peut proposer un tendre moment | ||||||
| @@ -422,11 +543,14 @@ | |||||||
|     ne bloquent plus les jets de dés |     ne bloquent plus les jets de dés | ||||||
|  |  | ||||||
| ## v11.2.1 - La technique d'Akarlikarlikar | ## v11.2.1 - La technique d'Akarlikarlikar | ||||||
|  |  | ||||||
| - On peut créer des armes pour Corps à corps et Esquive. Barreaux de chaise, armes improvisées, techniques d'art martiaux, pas de côté pour faire trébucher l'adversaire... A vous de voir comment imaginer de nouvelles "armes". | - On peut créer des armes pour Corps à corps et Esquive. Barreaux de chaise, armes improvisées, techniques d'art martiaux, pas de côté pour faire trébucher l'adversaire... A vous de voir comment imaginer de nouvelles "armes". | ||||||
| - Les armes avec une résistance de 0 ne peuvent pas être utilisées, une image et un rappel indiquent qu'elles sont cassées | - Les armes avec une résistance de 0 ne peuvent pas être utilisées, une image et un rappel indiquent qu'elles sont cassées | ||||||
|  |  | ||||||
| Vu qu'elles ne peuvent pas être utilisées, permet de savoir pourquoi | Vu qu'elles ne peuvent pas être utilisées, permet de savoir pourquoi | ||||||
|  |  | ||||||
| ## v11.2.0 - Les Terres médianes d'Akarlikarlikar | ## v11.2.0 - Les Terres médianes d'Akarlikarlikar | ||||||
|  |  | ||||||
| - Les TMRs sont redimensionables | - Les TMRs sont redimensionables | ||||||
| - Nouveaux graphismes plus lisibles dans les TMRs | - Nouveaux graphismes plus lisibles dans les TMRs | ||||||
| - Nouveau code couleur des icônes dans les TMR: | - Nouveau code couleur des icônes dans les TMR: | ||||||
| @@ -440,12 +564,15 @@ Vu qu'elles ne peuvent pas être utilisées, permet de savoir pourquoi | |||||||
| - Fix: Les jets d'encaissement forcés par le gardien à un résultat inférieur à 11 ne peuvent plus donner un deuxième d10 négatif | - Fix: Les jets d'encaissement forcés par le gardien à un résultat inférieur à 11 ne peuvent plus donner un deuxième d10 négatif | ||||||
|  |  | ||||||
| # v11.1 | # v11.1 | ||||||
|  |  | ||||||
| ## v11.1.6 - Les dissections de Werther de Zloth | ## v11.1.6 - Les dissections de Werther de Zloth | ||||||
|  |  | ||||||
| - Fix: on peut de nouveau donner des compétences aux créatures | - Fix: on peut de nouveau donner des compétences aux créatures | ||||||
| - Fix: le délai de guérison d'une blessure rétrogradée est correctement appliqué | - Fix: le délai de guérison d'une blessure rétrogradée est correctement appliqué | ||||||
| - Fix: l'encaissement à valider par le MJ fonctionne de nouveau | - Fix: l'encaissement à valider par le MJ fonctionne de nouveau | ||||||
|  |  | ||||||
| ## v11.1.5 - Werther de Zloth l'Onirique | ## v11.1.5 - Werther de Zloth l'Onirique | ||||||
|  |  | ||||||
| - Fixes: | - Fixes: | ||||||
|   - la demande de défense ne marchait plus |   - la demande de défense ne marchait plus | ||||||
|   - la tête réserve extensible crée bien une case de réserve extensible (à modifier) |   - la tête réserve extensible crée bien une case de réserve extensible (à modifier) | ||||||
| @@ -460,6 +587,7 @@ Vu qu'elles ne peuvent pas être utilisées, permet de savoir pourquoi | |||||||
|   - pas de jets de vie pour les morts |   - pas de jets de vie pour les morts | ||||||
|  |  | ||||||
| ## v11.1.4 - Werther de Zloth l'Onirique | ## v11.1.4 - Werther de Zloth l'Onirique | ||||||
|  |  | ||||||
| - Ajout du facteur de significative à côté du pourcentage dans le résultat des jets de dés pour rappeler que le pourcentage n'est pas diviasé | - Ajout du facteur de significative à côté du pourcentage dans le résultat des jets de dés pour rappeler que le pourcentage n'est pas diviasé | ||||||
| - Fix: dans les TMRs, les tooltips affichent bien les informations de tous les effets sur la case | - Fix: dans les TMRs, les tooltips affichent bien les informations de tous les effets sur la case | ||||||
| - Fix: la fatigue et l'éthylisme sont de nouveau pris en compte dans le calcul de l'éthylisme | - Fix: la fatigue et l'éthylisme sont de nouveau pris en compte dans le calcul de l'éthylisme | ||||||
| @@ -469,15 +597,18 @@ Vu qu'elles ne peuvent pas être utilisées, permet de savoir pourquoi | |||||||
| - Esthétique: ne pas afficher "+0" pour les ajustements de jets/encaissement | - Esthétique: ne pas afficher "+0" pour les ajustements de jets/encaissement | ||||||
|  |  | ||||||
| ## v11.1.2 - Les vertèbres de Werther de Zloth | ## v11.1.2 - Les vertèbres de Werther de Zloth | ||||||
|  |  | ||||||
| - Fix: les jets d'encaissement fonctionnent de nouveau normalement | - Fix: les jets d'encaissement fonctionnent de nouveau normalement | ||||||
| - Macro "Mon personnage" permettant au joueur d'accéder à sa feuille de personnage depuis la barre de macros | - Macro "Mon personnage" permettant au joueur d'accéder à sa feuille de personnage depuis la barre de macros | ||||||
|  |  | ||||||
| ## v11.1.1 - Les fumebols de Werther de Zloth | ## v11.1.1 - Les fumebols de Werther de Zloth | ||||||
|  |  | ||||||
| - Fix: on peut de nouveau afficher les vues détaillées | - Fix: on peut de nouveau afficher les vues détaillées | ||||||
| - Fix: on peut ouvrir les sacs et contenants portés par les véhicules et créatures | - Fix: on peut ouvrir les sacs et contenants portés par les véhicules et créatures | ||||||
| - Fix: cuisiner du gibier prend maintenant bien les proportaions en compte | - Fix: cuisiner du gibier prend maintenant bien les proportaions en compte | ||||||
|  |  | ||||||
| ## v11.1.0 - Les choix de Werther de Zloth | ## v11.1.0 - Les choix de Werther de Zloth | ||||||
|  |  | ||||||
| - Les options suivantes peuvent être désactivées: | - Les options suivantes peuvent être désactivées: | ||||||
|   - La transformation de stress à Château Dormant |   - La transformation de stress à Château Dormant | ||||||
|   - La récuperation de chance à Château Dormant |   - La récuperation de chance à Château Dormant | ||||||
| @@ -495,7 +626,9 @@ Vu qu'elles ne peuvent pas être utilisées, permet de savoir pourquoi | |||||||
|   - en cas de charge, les particulières sont toujours en force (p125) |   - en cas de charge, les particulières sont toujours en force (p125) | ||||||
|  |  | ||||||
| # v11.0 | # v11.0 | ||||||
|  |  | ||||||
| ## v11.0.28 - les fractures de Khrachtchoum | ## v11.0.28 - les fractures de Khrachtchoum | ||||||
|  |  | ||||||
| - La gravité de la blessure est affichée dans le résumé de l'encaissement | - La gravité de la blessure est affichée dans le résumé de l'encaissement | ||||||
| - Lors du changement d'acteur pendant le round | - Lors du changement d'acteur pendant le round | ||||||
|   - le message annonçant le joueur dont c'est le tour ne contient plus d'informations de santé |   - le message annonçant le joueur dont c'est le tour ne contient plus d'informations de santé | ||||||
| @@ -507,12 +640,14 @@ Vu qu'elles ne peuvent pas être utilisées, permet de savoir pourquoi | |||||||
|   - le moral est indiqué avant l'icone d'appel au moral |   - le moral est indiqué avant l'icone d'appel au moral | ||||||
|  |  | ||||||
| ## v11.0.27 - Khrachtchoum le méticuleux | ## v11.0.27 - Khrachtchoum le méticuleux | ||||||
|  |  | ||||||
| - le tooltip dans les TMR reste visible si on ne bouge pas la souris | - le tooltip dans les TMR reste visible si on ne bouge pas la souris | ||||||
| - le surencombrement n'affecte QUE les actions physiques | - le surencombrement n'affecte QUE les actions physiques | ||||||
| - on peut de nouveau fabriquer une potion depuis la fenêtre d'édition de l'herbe | - on peut de nouveau fabriquer une potion depuis la fenêtre d'édition de l'herbe | ||||||
| - si les TMR sont minimisées alors qu'une action est requise, elles sont bien réaffichées lorsque l'action est faite | - si les TMR sont minimisées alors qu'une action est requise, elles sont bien réaffichées lorsque l'action est faite | ||||||
|  |  | ||||||
| ## v11.0.26 - le crépuscule de Khrachtchoum | ## v11.0.26 - le crépuscule de Khrachtchoum | ||||||
|  |  | ||||||
| - gestion correcte des TMRs | - gestion correcte des TMRs | ||||||
|   - les TMRs ne sont jamais minimisées (par le système) quand le haut-rêvant est en demi-rêve |   - les TMRs ne sont jamais minimisées (par le système) quand le haut-rêvant est en demi-rêve | ||||||
|   - lorsqu'une fenêtre liée aux demi-rêve est affichée, cliquer sur les TMRs n'a pas d'effet |   - lorsqu'une fenêtre liée aux demi-rêve est affichée, cliquer sur les TMRs n'a pas d'effet | ||||||
| @@ -531,45 +666,57 @@ Vu qu'elles ne peuvent pas être utilisées, permet de savoir pourquoi | |||||||
| - les jets de compétences d'attaque des créatures fonctionnent de nouveau | - les jets de compétences d'attaque des créatures fonctionnent de nouveau | ||||||
|  |  | ||||||
| ## v11.0.25 - la vision du rêve de Khrachtchoum | ## v11.0.25 - la vision du rêve de Khrachtchoum | ||||||
|  |  | ||||||
| - Les TMRs restent affichées tant que le Haut-rêvant est en demi-rêve | - Les TMRs restent affichées tant que le Haut-rêvant est en demi-rêve | ||||||
|  |  | ||||||
| ## v11.0.24 - les couleurs de Khrachtchoum | ## v11.0.24 - les couleurs de Khrachtchoum | ||||||
|  |  | ||||||
| - nouvelle carte des TMRs | - nouvelle carte des TMRs | ||||||
|  |  | ||||||
| ## v11.0.23 - la lumière de Khrachtchoum | ## v11.0.23 - la lumière de Khrachtchoum | ||||||
|  |  | ||||||
| - ajustement automatique de la luminosité selon l'heure pour les scènes: | - ajustement automatique de la luminosité selon l'heure pour les scènes: | ||||||
|   - avec une vision des tokens (sinon: ce n'est pas une scène de carte pour tokens) |   - avec une vision des tokens (sinon: ce n'est pas une scène de carte pour tokens) | ||||||
|   - avec illumination globale (correspondant à une illumination extérieure) |   - avec illumination globale (correspondant à une illumination extérieure) | ||||||
|   - quand lampe "allumée" dans la fenêtre du calendrier |   - quand lampe "allumée" dans la fenêtre du calendrier | ||||||
|  |  | ||||||
| ## v11.0.22 - les automatismes de Khrachtchoum le Problémeux | ## v11.0.22 - les automatismes de Khrachtchoum le Problémeux | ||||||
|  |  | ||||||
| - Macro pour attaquer avec les compétences de créatures | - Macro pour attaquer avec les compétences de créatures | ||||||
|  |  | ||||||
| ## v11.0.20 | ## v11.0.20 | ||||||
|  |  | ||||||
| - Macro pour attaquer avec les armes des personnages | - Macro pour attaquer avec les armes des personnages | ||||||
|  |  | ||||||
| ## v11.0.17 | ## v11.0.17 | ||||||
|  |  | ||||||
| - Fix: les actions de commerce ne s'appliquait pas bien aux personnages des tokens non liés | - Fix: les actions de commerce ne s'appliquait pas bien aux personnages des tokens non liés | ||||||
|  |  | ||||||
| ## v11.0.15 - L'apprentissage de Khrachtchoum | ## v11.0.15 - L'apprentissage de Khrachtchoum | ||||||
|  |  | ||||||
| - Fix: l'expérience ne s'appliquait plus sur certaines réussites particulières (régression depuis la 11.0.7) | - Fix: l'expérience ne s'appliquait plus sur certaines réussites particulières (régression depuis la 11.0.7) | ||||||
|  |  | ||||||
| ## v11.0.14 - Les pincettes de Khrachtchoum le Problémeux | ## v11.0.14 - Les pincettes de Khrachtchoum le Problémeux | ||||||
|  |  | ||||||
| - Correction du calcul de la place restante lors de l'ajout dans un conteneur | - Correction du calcul de la place restante lors de l'ajout dans un conteneur | ||||||
|  |  | ||||||
| ## v11.0.13 - La multiplication de l'eau de Khrachtchoum le Problémeux | ## v11.0.13 - La multiplication de l'eau de Khrachtchoum le Problémeux | ||||||
|  |  | ||||||
| - Correction de la vente depuis un commerce ayant des quantités illimitées | - Correction de la vente depuis un commerce ayant des quantités illimitées | ||||||
|  |  | ||||||
| ## v11.0.12 - Les poids de la mesure de Khrachtchoum le Problémeux | ## v11.0.12 - Les poids de la mesure de Khrachtchoum le Problémeux | ||||||
|  |  | ||||||
| - Correction des malus de surencombrement | - Correction des malus de surencombrement | ||||||
| - Le malus armure est correctement affiché dans l'onglet des caractéristiques | - Le malus armure est correctement affiché dans l'onglet des caractéristiques | ||||||
| - Correction d'orthographe et amélioration des messages des oeuvres d'art | - Correction d'orthographe et amélioration des messages des oeuvres d'art | ||||||
|  |  | ||||||
| ## v11.0.11 - Les bleus de Khrachtchoum le Problémeux | ## v11.0.11 - Les bleus de Khrachtchoum le Problémeux | ||||||
|  |  | ||||||
| - si le gardien configure le sommeil, les joueurs sont notifiés que chateau dormant vient de passer | - si le gardien configure le sommeil, les joueurs sont notifiés que chateau dormant vient de passer | ||||||
| - possibilité de créer des armes et des compétences de créatures non-mortelles. | - possibilité de créer des armes et des compétences de créatures non-mortelles. | ||||||
|  |  | ||||||
| ## v11.0.10 - Les Songes de Khrachtchoum le Problémeux | ## v11.0.10 - Les Songes de Khrachtchoum le Problémeux | ||||||
|  |  | ||||||
| - on peut de nouveau se déplacer dans les TMRs d'un clic sur la case à atteindre | - on peut de nouveau se déplacer dans les TMRs d'un clic sur la case à atteindre | ||||||
| - Lire un livre depuis l'inventaire permet de nouveau de faire un jet de la tâche | - Lire un livre depuis l'inventaire permet de nouveau de faire un jet de la tâche | ||||||
|   créée au lieu de créer toujours une nouvelle tâche |   créée au lieu de créer toujours une nouvelle tâche | ||||||
| @@ -580,12 +727,14 @@ Vu qu'elles ne peuvent pas être utilisées, permet de savoir pourquoi | |||||||
|   les heures dormies sont déduites des heures restant à dormir |   les heures dormies sont déduites des heures restant à dormir | ||||||
|  |  | ||||||
| ## v11.0.9 - Les Souvenirs de Khrachtchoum le Problémeux | ## v11.0.9 - Les Souvenirs de Khrachtchoum le Problémeux | ||||||
|  |  | ||||||
| - mode de saisie de l'archétype en vue détaillée | - mode de saisie de l'archétype en vue détaillée | ||||||
| - création  une nouvelle incarnation depuis l'archétype | - création  une nouvelle incarnation depuis l'archétype | ||||||
| - réorganisation de la fenêtre de sélection des règles optionnelles | - réorganisation de la fenêtre de sélection des règles optionnelles | ||||||
| - correction de l'affichage du type dans les fenêtres d'objets | - correction de l'affichage du type dans les fenêtres d'objets | ||||||
|  |  | ||||||
| ## v11.0.8 - la poigne de Sémolosse | ## v11.0.8 - la poigne de Sémolosse | ||||||
|  |  | ||||||
| - lien vers le changelog | - lien vers le changelog | ||||||
| - organisation des compendiums du système | - organisation des compendiums du système | ||||||
| - correction de l'empoignade | - correction de l'empoignade | ||||||
|   | |||||||
| @@ -12,14 +12,14 @@ | |||||||
|  |  | ||||||
|   /* =================== 3. some constants ============ */ |   /* =================== 3. some constants ============ */ | ||||||
|     --fieldset-background: url(/ui/parchment.jpg); |     --fieldset-background: url(/ui/parchment.jpg); | ||||||
|     --rdd-color-text-primary: rgba(10, 10, 10, 0.9); |     --rdd-color-text-primary: hsla(0, 0%, 4%, 0.9); | ||||||
|     --rdd-input-background:rgba(0, 0, 0, 0.05); |     --rdd-input-background:hsla(0, 0%, 0%, 0.1); | ||||||
|     --rdd-color-border-input: rgba(0, 0, 0, 0.2); |     --rdd-color-border-input: hsla(0, 0%, 0%, 0.2); | ||||||
|     --rdd-bg-input: rgba(255, 255, 255, 0.1); |     --rdd-bg-input: hsla(0, 0%, 100%, 0.1); | ||||||
|     --color-controls:rgba(0, 0, 0, 0.9); |     --color-controls:hsla(0, 0%, 0%, 0.9); | ||||||
|     --color-controls-light:hsla(0, 0%, 20%, 0.8); |     --color-controls-light:hsla(0, 0%, 20%, 0.8); | ||||||
|     --color-controls-hover:hsla(60, 100%, 75%, 0.7); |     --color-controls-hover:hsla(60, 100%, 75%, 0.7); | ||||||
|     --color-control-border-hover:rgba(255, 128, 0, 0.8); |     --color-control-border-hover:hsla(30, 100%, 50%, 0.8); | ||||||
|     --color-gold: rgba(191, 149, 63, 0.8); |     --color-gold: rgba(191, 149, 63, 0.8); | ||||||
|     --gradient-gold: linear-gradient(30deg, rgba(191, 149, 63, 0.3), rgba(252, 246, 186, 0.3), rgba(179, 135, 40, 0.3), rgba(251, 245, 183, 0.3), rgba(170, 119, 28, 0.3)); |     --gradient-gold: linear-gradient(30deg, rgba(191, 149, 63, 0.3), rgba(252, 246, 186, 0.3), rgba(179, 135, 40, 0.3), rgba(251, 245, 183, 0.3), rgba(170, 119, 28, 0.3)); | ||||||
|     --gradient-silver: linear-gradient(30deg, rgba(61, 55, 93, 0.3), rgba(178, 179, 196, 0.3), rgba(59, 62, 63, 0.6), rgba(206, 204, 199, 0.3), rgba(61, 46, 49, 0.3)); |     --gradient-silver: linear-gradient(30deg, rgba(61, 55, 93, 0.3), rgba(178, 179, 196, 0.3), rgba(59, 62, 63, 0.6), rgba(206, 204, 199, 0.3), rgba(61, 46, 49, 0.3)); | ||||||
| @@ -39,12 +39,20 @@ | |||||||
|       hsla(50, 100%, 80%, 0.7) |       hsla(50, 100%, 80%, 0.7) | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     --background-custom-button: linear-gradient(to bottom, rgba(33, 55, 74, 0.988) 5%, rgba(21, 40, 51, 0.671) 100%); |     --background-custom-button: linear-gradient(to bottom, hsla(208, 38%, 21%, 0.988) 5%, hsla(202, 42%, 14%, 0.671) 100%); | ||||||
|     --background-custom-button-hover: linear-gradient(to bottom, rgb(128, 0, 0) 5%, rgb(62, 1, 1) 100%); |     --background-custom-button-hover: linear-gradient(to bottom, hsla(0, 100%, 25%, 1) 5%, hsla(0, 97%, 12%, 1) 100%); | ||||||
|     --background-control-selected: linear-gradient(to bottom, hsla(0, 100%, 25%, 0.5) 5%, hsla(0, 100%, 12%, 0.5) 100%); |     --background-control-selected: linear-gradient(to bottom, hsla(0, 100%, 25%, 0.5) 5%, hsla(0, 100%, 12%, 0.5) 100%); | ||||||
|     --background-tooltip: hsla(60, 12%, 85%, 0.95); |     --background-tooltip: hsla(60, 12%, 85%, 0.95); | ||||||
|  |     --background-tooltip-alt: hsla(60, 12%, 74%, 0.95); | ||||||
|     --color-tooltip:hsla(282, 47%, 33%, 0.9); |     --color-tooltip:hsla(282, 47%, 33%, 0.9); | ||||||
|     --color-tooltip-faint:hsla(282, 47%, 66%, 0.5); |     --color-tooltip-faint:hsla(282, 47%, 66%, 0.5); | ||||||
|     --background-error:hsla(16, 100%, 50%, 0.8); |     --background-error:hsla(16, 100%, 50%, 0.8); | ||||||
|     --color-profile-border: hsla(0, 0%, 80%, 0.05); |     --color-profile-border: hsla(0, 0%, 80%, 0.05); | ||||||
|  |  | ||||||
|  |     --color-background-chat-message: hsla(60, 12%, 85%, 0.9); | ||||||
|  |     --color-background-chat-whisper: repeating-linear-gradient(120deg, | ||||||
|  |       hsla(60, 12%, 85%, 0.75), | ||||||
|  |       hsla(60, 12%, 85%, 0.75) 1rem,  | ||||||
|  |       hsla(60, 12%, 85%, 0.8) 1rem,  | ||||||
|  |       hsla(60, 12%, 85%, 0.75) 1.5rem); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -59,6 +59,7 @@ | |||||||
| } | } | ||||||
|  |  | ||||||
| /* Global styles & Font */ | /* Global styles & Font */ | ||||||
|  | .application, | ||||||
| .window-app { | .window-app { | ||||||
|   font-family: CaslonAntique; |   font-family: CaslonAntique; | ||||||
|   text-align: justify; |   text-align: justify; | ||||||
|   | |||||||
| @@ -6,17 +6,14 @@ | |||||||
|   @import "item/monnaie.less"; |   @import "item/monnaie.less"; | ||||||
|   @import "item/munition.less"; |   @import "item/munition.less"; | ||||||
|   @import "item/tarot.less"; |   @import "item/tarot.less"; | ||||||
|  |   @import "roll-dialog.less"; | ||||||
|   // body { |  | ||||||
|   //   --input-height: 1.4rem; |  | ||||||
|   // } |  | ||||||
|  |  | ||||||
|   .window-header{ |   .window-header{ | ||||||
|     background: rgba(0,0,0,0.75); |     background: rgba(0,0,0,0.75); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   .application .window-content, | ||||||
|   .window-app.sheet .window-content { |   .window-app.sheet .window-content { | ||||||
|     margin: 0; |     margin: 0.2rem; | ||||||
|     padding: 0; |     padding: 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -77,6 +74,17 @@ | |||||||
|   .sheet-header :is(.header-compteurs,.header-etats,.profile-img, .profile-img-token){ |   .sheet-header :is(.header-compteurs,.header-etats,.profile-img, .profile-img-token){ | ||||||
|     padding: 0 0.4rem; |     padding: 0 0.4rem; | ||||||
|   } |   } | ||||||
|  |   .sheet-header div.header-etats { | ||||||
|  |     width: calc(40% - 32px - 1rem); | ||||||
|  |     height: 48px; | ||||||
|  |     max-width: fit-content; | ||||||
|  |     flex: initial; | ||||||
|  |     flex-grow: 3; | ||||||
|  |     div div{ | ||||||
|  |       display: flex; | ||||||
|  |       flex-direction: row; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   .sheet-header :is(.profile-img, .profile-img-token)  { |   .sheet-header :is(.profile-img, .profile-img-token)  { | ||||||
|     -webkit-box-flex: 0; |     -webkit-box-flex: 0; | ||||||
| @@ -115,13 +123,6 @@ | |||||||
|     max-width: fit-content; |     max-width: fit-content; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .sheet-header div.header-etats { |  | ||||||
|     width: calc(40% - 32px - 1rem); |  | ||||||
|     height: 48px; |  | ||||||
|     max-width: fit-content; |  | ||||||
|     flex: initial; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .sheet-header .resource-content { |   .sheet-header .resource-content { | ||||||
|     width: 2rem; |     width: 2rem; | ||||||
|   } |   } | ||||||
| @@ -217,7 +218,6 @@ | |||||||
|     padding: 0; |     padding: 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   .grid-competence-archetype { |   .grid-competence-archetype { | ||||||
|     display: grid; |     display: grid; | ||||||
|     grid-column: span 3 / span 3; |     grid-column: span 3 / span 3; | ||||||
| @@ -356,6 +356,7 @@ | |||||||
|     margin: 0; |     margin: 0; | ||||||
|     justify-content: center; |     justify-content: center; | ||||||
|     text-align: left; |     text-align: left; | ||||||
|  |     display: ruby; | ||||||
|   } |   } | ||||||
|   .equipement-valeur { |   .equipement-valeur { | ||||||
|     margin: 0; |     margin: 0; | ||||||
| @@ -375,6 +376,8 @@ | |||||||
|     align-items: center; |     align-items: center; | ||||||
|     justify-content: center; |     justify-content: center; | ||||||
|     text-align: center; |     text-align: center; | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: row; | ||||||
|   } |   } | ||||||
|   .equipement-button { |   .equipement-button { | ||||||
|     margin: 0; |     margin: 0; | ||||||
| @@ -494,6 +497,7 @@ | |||||||
|     max-width: 1.5em; |     max-width: 1.5em; | ||||||
|     max-height: 1.5em; |     max-height: 1.5em; | ||||||
|     border-width: 0; |     border-width: 0; | ||||||
|  |     display: inline; | ||||||
|   } |   } | ||||||
|   .dimmed { |   .dimmed { | ||||||
|     opacity: 50%; |     opacity: 50%; | ||||||
| @@ -512,13 +516,21 @@ | |||||||
|     padding: 0.2em; |     padding: 0.2em; | ||||||
|     border-width: 0; |     border-width: 0; | ||||||
|   } |   } | ||||||
|   .small-button-direction { |   .grid-move-tmr { display: grid; } | ||||||
|  |   .move-tmr-topleft { grid-column: 2/2; grid-row: 2/4;} | ||||||
|  |   .move-tmr-top { grid-column: 3/3; grid-row: 1/3; } | ||||||
|  |   .move-tmr-topright { grid-column: 4/4; grid-row: 2/4; } | ||||||
|  |   .move-tmr-bottomleft { grid-column: 2/2; grid-row: 4/6; } | ||||||
|  |   .move-tmr-bottom { grid-column: 3/3; grid-row: 5/7; } | ||||||
|  |   .move-tmr-bottomright{ grid-column: 4/4; grid-row: 4/6; } | ||||||
|  |  | ||||||
|  |   .tmr-move { | ||||||
|     max-height: 32px; |     max-height: 32px; | ||||||
|     max-width: 32px; |     max-width: 32px; | ||||||
|     border: 0; |     border: 0; | ||||||
|     vertical-align: bottom; |     vertical-align: bottom; | ||||||
|   } |   } | ||||||
|   :is(.button-img,.button-effect-img,.small-button-direction):hover { |   :is(.button-img,.button-effect-img,.tmr-move):hover { | ||||||
|     color: var(--color-controls-hover); |     color: var(--color-controls-hover); | ||||||
|     border: 1px solid var(--color-control-border-hover); |     border: 1px solid var(--color-control-border-hover); | ||||||
|     text-shadow: 1px 0px 0px #ff6600; |     text-shadow: 1px 0px 0px #ff6600; | ||||||
| @@ -562,51 +574,55 @@ | |||||||
|     height: 100%; |     height: 100%; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .rdd.sheet .window-content {overflow: hidden;} |   .carac-label { | ||||||
|   .rdd.sheet .window-content .sheet-body {overflow-y: scroll;} |     font-weight: bold; | ||||||
|   .rdd.sheet .window-content .sheet-body .tab {padding-bottom: 30px;} |     flex-basis: 40%; | ||||||
|   .rdd.sheet .window-content .sheet-body .competence-list {width: 100%;} |   } | ||||||
|   .rdd.sheet .window-content .sheet-body .carac-list { |   .rdd.sheet { | ||||||
|  |     .window-content { | ||||||
|  |       overflow: hidden; | ||||||
|  |       .sheet-body { | ||||||
|  |         overflow-y: scroll; | ||||||
|  |         .tab {padding-bottom: 30px;} | ||||||
|  |         .competence-list {width: 100%;} | ||||||
|  |         .carac-list { | ||||||
|           width: 100%; |           width: 100%; | ||||||
|           flex-grow: 0; |           flex-grow: 0; | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .rdd.sheet .window-content .sheet-body .carac-list .caracteristique { |           .caracteristique.streched { | ||||||
|     flex-wrap: nowrap; |  | ||||||
|     justify-content: stretch; |  | ||||||
|   } |  | ||||||
|   .rdd.sheet .window-content .sheet-body .carac-list .caracteristique.streched { |  | ||||||
|             flex-wrap: nowrap; |             flex-wrap: nowrap; | ||||||
|             justify-content: stretch; |             justify-content: stretch; | ||||||
|             flex-basis: 7.5em; |             flex-basis: 7.5em; | ||||||
|             width: max-content; |             width: max-content; | ||||||
|           } |           } | ||||||
|  |  | ||||||
|   .carac-label { |           .caracteristique { | ||||||
|     font-weight: bold; |             flex-wrap: nowrap; | ||||||
|     flex-basis: 40%; |             justify-content: stretch; | ||||||
|   } |  | ||||||
|   .rdd.sheet .window-content .sheet-body .carac-list .caracteristique > .utiliser-attribut { |             .carac-value { | ||||||
|     flex-basis: available; |  | ||||||
|     flex-grow: 1; |  | ||||||
|   } |  | ||||||
|   .rdd.sheet .window-content .sheet-body .carac-list .caracteristique .carac-value { |  | ||||||
|               flex-basis: 15%; |               flex-basis: 15%; | ||||||
|               flex-grow: 0; |               flex-grow: 0; | ||||||
|             } |             } | ||||||
|   .rdd.sheet .window-content .sheet-body .carac-list .caracteristique .carac-xp { |             .carac-xp { | ||||||
|               flex-basis: 13%; |               flex-basis: 13%; | ||||||
|               flex-grow: 0; |               flex-grow: 0; | ||||||
|             } |             } | ||||||
|   .rdd.sheet .window-content .sheet-body .carac-list .caracteristique .derivee-label  { |             .derivee-label  { | ||||||
|               flex-grow: 1; |               flex-grow: 1; | ||||||
|             } |             } | ||||||
|   .rdd.sheet .window-content .sheet-body .carac-list .caracteristique .derivee-value { |             .derivee-value { | ||||||
|               flex-grow: 0; |               flex-grow: 0; | ||||||
|               flex-basis: 15%; |               flex-basis: 15%; | ||||||
|               margin-right: 0.2rem; |               margin-right: 0.2rem; | ||||||
|               margin-left: 0.2rem; |               margin-left: 0.2rem; | ||||||
|             } |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   .flex-grow-1 { |   .flex-grow-1 { | ||||||
|     flex-grow: 1; |     flex-grow: 1; | ||||||
|   } |   } | ||||||
| @@ -624,13 +640,14 @@ | |||||||
|     margin-inline: 0.1rem; |     margin-inline: 0.1rem; | ||||||
|     margin-block: 0.1rem; |     margin-block: 0.1rem; | ||||||
|   } |   } | ||||||
|   form.application.sheet.fvtt-rdd fieldset :is(label, input) { |   .app.sheet fieldset :is(label, input) { | ||||||
|     font-family: CaslonAntique; |     font-family: CaslonAntique; | ||||||
|     text-align: justify; |     text-align: justify; | ||||||
|     font-size: 1rem; |     font-size: 1rem; | ||||||
|     letter-spacing: 1px; |     letter-spacing: 1px; | ||||||
|   } |   } | ||||||
|   form.application.sheet.fvtt-rdd div.form-group { |  | ||||||
|  |   .app.sheet div.form-group { | ||||||
|     clear: both; |     clear: both; | ||||||
|     display: flex; |     display: flex; | ||||||
|     flex-direction: row; |     flex-direction: row; | ||||||
| @@ -638,15 +655,17 @@ | |||||||
|     margin: 0.1rem 0; |     margin: 0.1rem 0; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|   } |   } | ||||||
|   form.application.sheet.fvtt-rdd .editor.prosemirror { |   .app.sheet .editor.prosemirror { | ||||||
|     height: fit-content; |     height: fit-content; | ||||||
|     min-height: 5rem; |     min-height: 5rem; | ||||||
|   } |   } | ||||||
|   form.application.sheet.fvtt-rdd prose-mirror.prosemirror .editor-container { |   .app.sheet .editor.prosemirror .editor-container { | ||||||
|     min-height: 5rem; |     min-height: 5rem; | ||||||
|     height: fit-content; |     height: 8rem; | ||||||
|     margin: 0; |     margin: 0; | ||||||
|  |     flex: none; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .large-editor { |   .large-editor { | ||||||
|     border: 2; |     border: 2; | ||||||
|     height: fit-content; |     height: fit-content; | ||||||
| @@ -795,6 +814,7 @@ | |||||||
|     font-size: 0.8rem; |     font-size: 0.8rem; | ||||||
|     text-align: right; |     text-align: right; | ||||||
|   } |   } | ||||||
|  |    | ||||||
|   .placeholder-ajustements { |   .placeholder-ajustements { | ||||||
|     flex-direction: column; |     flex-direction: column; | ||||||
|   } |   } | ||||||
| @@ -807,32 +827,31 @@ | |||||||
|     background-color: lightblue; |     background-color: lightblue; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   div.placeholder-resolution span.table-proba-reussite{ |   span.table-proba-reussite{ | ||||||
|     font-size: 0.8rem; |     font-size: 0.8rem; | ||||||
|     padding: 5px; |     padding: 5px; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .poesie-extrait { |   .poesie-extrait { | ||||||
|     font-size: 0.9rem; |     max-height: 8rem; | ||||||
|  |     font-size: 0.8rem; | ||||||
|     font-style: italic; |     font-style: italic; | ||||||
|  |     color: rgba(82, 17, 131, 0.9); | ||||||
|  |     overflow: hidden; | ||||||
|   } |   } | ||||||
|   .poesie-reference{ |    | ||||||
|  |   .poesie-extrait:hover { | ||||||
|  |     max-height: unset; | ||||||
|  |     overflow: visible; | ||||||
|  |     opacity: 1; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .poesie-reference { | ||||||
|     font-size: 0.7rem; |     font-size: 0.7rem; | ||||||
|     text-align: right; |     text-align: right; | ||||||
|   } |   } | ||||||
|   .poesie-overflow { |  | ||||||
|     color: rgba(82, 17, 131, 0.9); |  | ||||||
|     max-height: 1.5rem; |  | ||||||
|     overflow: hidden; |  | ||||||
|     border-left: 1px dotted black; /* If you want dots under the hoverable text */ |  | ||||||
|   } |  | ||||||
|   .poesie-overflow:hover { |  | ||||||
|     max-height: unset; |  | ||||||
|     overflow: visible; |  | ||||||
|     border-left: 0px |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .type-compendium{ |   .type-compendium { | ||||||
|     font-size: 0.6rem; |     font-size: 0.6rem; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -901,28 +920,27 @@ | |||||||
|     color: var(--color-text-dark-primary); |     color: var(--color-text-dark-primary); | ||||||
|     border-radius: 3px; |     border-radius: 3px; | ||||||
|   } |   } | ||||||
|   .app-calendar-astrologie div.theme-astral{ |   .app-calendar-astrologie{ | ||||||
|  |     div.theme-astral{ | ||||||
|       width: 14rem; |       width: 14rem; | ||||||
|       margin: 0.4rem; |       margin: 0.4rem; | ||||||
|     } |     } | ||||||
|  |     div.horloge-roue { | ||||||
|   .app-calendar-astrologie div.horloge-roue { |  | ||||||
|       position: relative; |       position: relative; | ||||||
|       left: calc(50% - 6.5rem); |       left: calc(50% - 6.5rem); | ||||||
|       width: 13rem; |       width: 13rem; | ||||||
|       height: 13rem; |       height: 13rem; | ||||||
|   } |       div.horloge-heure { | ||||||
|  |  | ||||||
|   .app-calendar-astrologie div.horloge-roue div.horloge-heure { |  | ||||||
|         position: absolute; |         position: absolute; | ||||||
|         width: 1.8rem; |         width: 1.8rem; | ||||||
|         height: 1.8rem; |         height: 1.8rem; | ||||||
|   } |         img.horloge-heure-img { | ||||||
|  |  | ||||||
|   .app-calendar-astrologie div.horloge-roue div.horloge-heure img.horloge-heure-img { |  | ||||||
|           width: 2rem; |           width: 2rem; | ||||||
|           height: 2rem; |           height: 2rem; | ||||||
|         } |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   .window-app .window-content, .window-app.sheet .window-content .sheet-body{ |   .window-app .window-content, .window-app.sheet .window-content .sheet-body{ | ||||||
|     background: rgb(245,245,240) url(../assets/ui/bg_left.webp) no-repeat left top; |     background: rgb(245,245,240) url(../assets/ui/bg_left.webp) no-repeat left top; | ||||||
| @@ -962,8 +980,7 @@ | |||||||
|     word-break: break-all; |     word-break: break-all; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   span.content-link, |   .content-link { | ||||||
|   a.content-link { |  | ||||||
|     background: hsla(45, 100%, 80%, 0.2); |     background: hsla(45, 100%, 80%, 0.2); | ||||||
|     color: hsla(300, 70%, 20%, 0.8); |     color: hsla(300, 70%, 20%, 0.8); | ||||||
|     font-weight: 560; |     font-weight: 560; | ||||||
| @@ -972,6 +989,7 @@ | |||||||
|     border-radius: 0.25rem; |     border-radius: 0.25rem; | ||||||
|     white-space: nowrap; |     white-space: nowrap; | ||||||
|     word-break: break-all; |     word-break: break-all; | ||||||
|  |     display: ruby; | ||||||
|   } |   } | ||||||
|   a.roll-text i.fas{ |   a.roll-text i.fas{ | ||||||
|     color: var(--color-text-dark-inactive); |     color: var(--color-text-dark-inactive); | ||||||
| @@ -1004,7 +1022,7 @@ | |||||||
|     max-width: 90%; |     max-width: 90%; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .window-app.sheet .window-content .tooltip:hover .tooltiptext { |   .window-app.sheet .window-content :is(.tooltip, .tooltip-overflow):hover .tooltiptext { | ||||||
|     top: 2rem; |     top: 2rem; | ||||||
|     left: 2rem; |     left: 2rem; | ||||||
|     margin: 0; |     margin: 0; | ||||||
| @@ -1222,6 +1240,8 @@ | |||||||
|   .list-item-label, |   .list-item-label, | ||||||
|   .list-title-label { |   .list-title-label { | ||||||
|     flex-grow: 2; |     flex-grow: 2; | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: row; | ||||||
|   } |   } | ||||||
|   .attribut-value, |   .attribut-value, | ||||||
|   .carac-value { |   .carac-value { | ||||||
| @@ -1275,9 +1295,13 @@ | |||||||
|   table.table-nombres-astraux th >td { |   table.table-nombres-astraux th >td { | ||||||
|     font-size: 1rem; |     font-size: 1rem; | ||||||
|   } |   } | ||||||
|   table.table-nombres-astraux tr >td { |   table.table-nombres-astraux tr td { | ||||||
|     font-size: 0.8rem; |     font-size: 0.8rem; | ||||||
|   } |   } | ||||||
|  |   table.table-nombres-astraux tr td.info-acteur { | ||||||
|  |     flex-direction: row; | ||||||
|  |     display: flex; | ||||||
|  |   } | ||||||
|   table.table-nombres-astraux :is(tr, th, td) { |   table.table-nombres-astraux :is(tr, th, td) { | ||||||
|     border-style: solid; |     border-style: solid; | ||||||
|     border-width: 1px; |     border-width: 1px; | ||||||
| @@ -1450,19 +1474,28 @@ | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   .chat-message { |   .chat-message { | ||||||
|     background: rgba(220,220,210,0.5); |     background: var(--color-background-chat-message); | ||||||
|     font-size: 1rem; |  | ||||||
|   } |  | ||||||
|      |      | ||||||
|   .chat-message header.message-header .heure-rdd { |     h4 { | ||||||
|  |       font-size: 0.9rem; | ||||||
|  |     } | ||||||
|  |     .message-content { | ||||||
|  |       text-align: justify; | ||||||
|  |     } | ||||||
|  |     header.message-header .heure-rdd { | ||||||
|       font-size: 0.7rem; |       font-size: 0.7rem; | ||||||
|       flex-grow: 3; |       flex-grow: 3; | ||||||
|     } |     } | ||||||
|  |     hr { | ||||||
|  |       margin: 0.2rem 0; | ||||||
|  |     } | ||||||
|      |      | ||||||
|  |   } | ||||||
|   .chat-message.whisper { |   .chat-message.whisper { | ||||||
|     background: rgba(220,220,210,0.75); |     background: var(--color-background-chat-whisper); | ||||||
|     border: 2px solid #545469; |     border: 2px solid #545469; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .chat-icon { |   .chat-icon { | ||||||
|     border: 0; |     border: 0; | ||||||
|     padding: 2px 6px 2px 2px; |     padding: 2px 6px 2px 2px; | ||||||
| @@ -1478,49 +1511,57 @@ | |||||||
|     vertical-align: text-top; |     vertical-align: text-top; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   #sidebar-tabs { |   .actor-img-small { | ||||||
|     flex: 0 0 28px; |     max-width: 1.5rem; | ||||||
|     box-sizing: border-box; |     max-height: 1.5rem; | ||||||
|     margin: 0 0 3px; |     flex-grow: 0; | ||||||
|     border-bottom: 1px solid rgba(0,0,0,0); |     margin-right: 0.2rem; | ||||||
|     box-shadow: inset 0 0 2rem rgba(0,0,0,0.5); |     vertical-align: bottom; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   #sidebar-tabs > .item.active { |   #sidebar-tabs menu { | ||||||
|     border: 1px solid rgba(114,98,72,1); |     button:is( | ||||||
|     background: rgba(30, 25, 20, 0.75); |       [data-tab="chat"], | ||||||
|     box-shadow: 0 0 6px inset rgba(114,98,72,1); |       [data-tab="combat"], | ||||||
|  |       [data-tab="scenes"], | ||||||
|  |       [data-tab="actors"], | ||||||
|  |       [data-tab="items"], | ||||||
|  |       [data-tab="journal"], | ||||||
|  |       [data-tab="cards"], | ||||||
|  |       [data-tab="macros"], | ||||||
|  |       [data-tab="tables"], | ||||||
|  |       [data-tab="playlists"], | ||||||
|  |       [data-tab="compendium"], | ||||||
|  |       [data-tab="settings"] | ||||||
|  |     )::before{ content: none; } | ||||||
|  |  | ||||||
|  |     button { | ||||||
|  |       background-repeat: no-repeat; | ||||||
|  |     } | ||||||
|  |     button[aria-pressed="false"] { | ||||||
|  |       background-color: hsla(30, 37%, 50%, 0.5); | ||||||
|  |     } | ||||||
|  |     button[aria-pressed="true"] { | ||||||
|  |       border: 1px solid hsla(15, 80%, 30%, 1); | ||||||
|  |       background-color: hsla(30, 100%, 90%, 0.6); | ||||||
|  |       box-shadow: 0 0 3px inset hsla(15, 80%, 30%, 1); | ||||||
|  |     } | ||||||
|  |     button[data-tab="chat"] { background-image: url("../assets/ui/icon_sidebar_chat.svg"); } | ||||||
|  |     button[data-tab="combat"] { background-image: url("../assets/ui/icon_sidebar_fight.svg"); } | ||||||
|  |     button[data-tab="scenes"] { background-image: url("../assets/ui/icon_sidebar_scene.svg"); } | ||||||
|  |     button[data-tab="actors"] { background-image: url("../assets/ui/icon_sidebar_actor.svg"); } | ||||||
|  |     button[data-tab="items"] { background-image: url("../assets/ui/icon_sidebar_item.svg"); } | ||||||
|  |     button[data-tab="journal"] { background-image: url("../assets/ui/icon_sidebar_journal.svg"); } | ||||||
|  |     button[data-tab="cards"] { background-image: url("../assets/ui/icon_sidebar_cards.svg"); } | ||||||
|  |     button[data-tab="macros"] { background-image: url("../assets/ui/icon_sidebar_macros.svg"); } | ||||||
|  |     button[data-tab="tables"] { background-image: url("../assets/ui/d100.svg"); } | ||||||
|  |     button[data-tab="playlists"] { background-image: url("../assets/ui/icon_sidebar_music.svg"); } | ||||||
|  |     button[data-tab="compendium"] { background-image: url("../assets/ui/icon_sidebar_compendium.svg"); } | ||||||
|  |     button[data-tab="settings"] { background-image: url("../assets/ui/icon_sidebar_settings.svg"); } | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   #sidebar #sidebar-tabs i{ |  | ||||||
|     width: 23px; |  | ||||||
|     height: 23px; |  | ||||||
|     display: inline-block; |  | ||||||
|     background-position:center; |  | ||||||
|     background-size:cover; |  | ||||||
|     text-shadow: 1px 1px 0 rgba(0,0,0,0.75); |  | ||||||
|  |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   #sidebar #sidebar-tabs i:is( |  | ||||||
|     .fa-comments, .fa-fist-raised, .fa-swords, |  | ||||||
|     .fa-users, .fa-user, .fa-map, .fa-suitcase, |  | ||||||
|     .fa-book-open, .fa-th-list, .fa-music, |  | ||||||
|     .fa-atlas,.fa-cogs |  | ||||||
|   ):before {content: "";} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-comments {background: url("../assets/ui/icon_sidebar_chat.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-fist-raised {background: url("../assets/ui/icon_sidebar_fight.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-swords {background: url("../assets/ui/icon_sidebar_fight.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-user {background: url("../assets/ui/icon_sidebar_actor.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-users {background: url("../assets/ui/icon_sidebar_actor.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-map {background: url("../assets/ui/icon_sidebar_scene.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-suitcase {background: url("../assets/ui/icon_sidebar_item.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-book-open {background: url("../assets/ui/icon_sidebar_journal.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-th-list {background: url("../assets/ui/icon_sidebar_rolltable.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-music {background: url("../assets/ui/icon_sidebar_music.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-atlas {background: url("../assets/ui/icon_sidebar_compendium.svg") no-repeat;} |  | ||||||
|   #sidebar #sidebar-tabs i.fa-cogs {background: url("../assets/ui/icon_sidebar_settings.svg") no-repeat;} |  | ||||||
|    |    | ||||||
|  |   // #sidebar #sidebar-tabs i.fa-th-list {background: url("../assets/ui/icon_sidebar_rolltable.svg") no-repeat;} | ||||||
|   #combat #combat-controls { |   #combat #combat-controls { | ||||||
|     box-shadow: inset 0 0 2rem rgba(0,0,0,0.5); |     box-shadow: inset 0 0 2rem rgba(0,0,0,0.5); | ||||||
|   } |   } | ||||||
| @@ -1605,63 +1646,6 @@ | |||||||
|     border-image-outset: 0px; |     border-image-outset: 0px; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   .window-app.calendar { |  | ||||||
|     display: inline-block; |  | ||||||
|     background: none; |  | ||||||
|     margin: 0; |  | ||||||
|     padding: 0; |  | ||||||
|     box-shadow: none; |  | ||||||
|     pointer-events: none; |  | ||||||
|     max-height: fit-content; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .window-app.calendar header.window-header { |  | ||||||
|     min-width: fit-content; |  | ||||||
|     height: 1.4rem; |  | ||||||
|     pointer-events: all; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .window-app.calendar .window-content { |  | ||||||
|     margin: 0; |  | ||||||
|     padding: 0; |  | ||||||
|     z-index: 100; |  | ||||||
|     flex-direction: column; |  | ||||||
|     min-width: 250px; |  | ||||||
|     height: fit-content; |  | ||||||
|     background: hsla(0, 0%, 0%, 0.0); |  | ||||||
|     font-family: "GoudyAcc"; |  | ||||||
|     pointer-events: none; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .window-app.calendar .window-content div:is(.calendar-boutons-heure, .horloge-digitale) { |  | ||||||
|     pointer-events: all; |  | ||||||
|   } |  | ||||||
|   .window-app.calendar .window-content div.horloge-analogique { |  | ||||||
|     pointer-events: none; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .window-app.calendar .window-content div.horloge-analogique div.horloge-roue { |  | ||||||
|     pointer-events: all; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .window-app.calendar div.horloge-roue { |  | ||||||
|     position: relative; |  | ||||||
|     margin-bottom: 7px; |  | ||||||
|     left: 0; |  | ||||||
|     width: 8rem; |  | ||||||
|     height: 8rem; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .window-app.calendar div.horloge-roue div.horloge-heure { |  | ||||||
|     width: 1.4rem; |  | ||||||
|     height: 1.4rem; |  | ||||||
|   } |  | ||||||
|   .window-app.calendar div.horloge-roue div.horloge-heure img.horloge-heure-img { |  | ||||||
|     width: 1.4rem; |  | ||||||
|     height: 1.4rem; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   div.horloge-roue div { |   div.horloge-roue div { | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     border: none; |     border: none; | ||||||
| @@ -1708,59 +1692,111 @@ | |||||||
|   } |   } | ||||||
|    |    | ||||||
|    |    | ||||||
|   .window-app.calendar div.horloge-heure.heure-01 { top: calc(50% - 0.7rem + sin(-180deg) *38%); left: calc(50% - 0.7rem + cos(-180deg) *38%); } |   .calendar { | ||||||
|   .window-app.calendar div.horloge-heure.heure-02 { top: calc(50% - 0.7rem + sin(-150deg) *38%); left: calc(50% - 0.7rem + cos(-150deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-03 { top: calc(50% - 0.7rem + sin(-120deg) *38%); left: calc(50% - 0.7rem + cos(-120deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-04 { top: calc(50% - 0.7rem + sin(-90deg) *38%); left: calc(50% - 0.7rem + cos(-90deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-05 { top: calc(50% - 0.7rem + sin(-60deg) *38%); left: calc(50% - 0.7rem + cos(-60deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-06 { top: calc(50% - 0.7rem + sin(-30deg) *38%); left: calc(50% - 0.7rem + cos(-30deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-07 { top: calc(50% - 0.7rem + sin(-0deg) *38%); left: calc(50% - 0.7rem + cos(-0deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-08 { top: calc(50% - 0.7rem + sin(30deg) *38%); left: calc(50% - 0.7rem + cos(30deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-09 { top: calc(50% - 0.7rem + sin(60deg) *38%); left: calc(50% - 0.7rem + cos(60deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-10 { top: calc(50% - 0.7rem + sin(90deg) *38%); left: calc(50% - 0.7rem + cos(90deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-11 { top: calc(50% - 0.7rem + sin(120deg) *38%); left: calc(50% - 0.7rem + cos(120deg) *38%); } |  | ||||||
|   .window-app.calendar div.horloge-heure.heure-12 { top: calc(50% - 0.7rem + sin(150deg) *38%); left: calc(50% - 0.7rem + cos(150deg) *41%); } |  | ||||||
|      |      | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-01 { top: calc(50% - 1rem + sin(-180deg) *41%); left: calc(50% - 1rem + cos(-180deg) *41%); } |     display: inline-block; | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-02 { top: calc(50% - 1rem + sin(-150deg) *41%); left: calc(50% - 1rem + cos(-150deg) *41%); } |     background: none; | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-03 { top: calc(50% - 1rem + sin(-120deg) *41%); left: calc(50% - 1rem + cos(-120deg) *41%); } |     margin: 0; | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-04 { top: calc(50% - 1rem + sin(-90deg) *41%); left: calc(50% - 1rem + cos(-90deg) *41%); } |     padding: 0; | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-05 { top: calc(50% - 1rem + sin(-60deg) *41%); left: calc(50% - 1rem + cos(-60deg) *41%); } |     box-shadow: none; | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-06 { top: calc(50% - 1rem + sin(-30deg) *41%); left: calc(50% - 1rem + cos(-30deg) *41%); } |     pointer-events: none; | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-07 { top: calc(50% - 1rem + sin(-0deg) *41%); left: calc(50% - 1rem + cos(-0deg) *41%); } |     max-height: fit-content; | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-08 { top: calc(50% - 1rem + sin(30deg) *41%); left: calc(50% - 1rem + cos(30deg) *41%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-09 { top: calc(50% - 1rem + sin(60deg) *41%); left: calc(50% - 1rem + cos(60deg) *41%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-10 { top: calc(50% - 1rem + sin(90deg) *41%); left: calc(50% - 1rem + cos(90deg) *41%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-11 { top: calc(50% - 1rem + sin(120deg) *41%); left: calc(50% - 1rem + cos(120deg) *41%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-heure.heure-12 { top: calc(50% - 1rem + sin(150deg) *41%); left: calc(50% - 1rem + cos(150deg) *41%); } |  | ||||||
|      |      | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-01 { top: calc(50% - 0.4rem + sin(180deg) * 28%); left: calc(50% - 0.4rem + cos(180deg) * 28%); } |     header.window-header { | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-02 { top: calc(50% - 0.4rem + sin(-150deg) * 28%); left: calc(50% - 0.4rem + cos(-150deg) * 28%); } |       min-width: fit-content; | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-03 { top: calc(50% - 0.4rem + sin(-120deg) * 28%); left: calc(50% - 0.4rem + cos(-120deg) * 28%); } |       height: 1.4rem; | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-04 { top: calc(50% - 0.4rem + sin(-90deg) * 28%); left: calc(50% - 0.4rem + cos(-90deg) * 28%); } |       pointer-events: all; | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-05 { top: calc(50% - 0.4rem + sin(-60deg) * 28%); left: calc(50% - 0.4rem + cos(-60deg) * 28%); } |       h4 { | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-06 { top: calc(50% - 0.4rem + sin(-30deg) * 28%); left: calc(50% - 0.4rem + cos(-30deg) * 28%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-07 { top: calc(50% - 0.4rem + sin(0deg) * 28%); left: calc(50% - 0.4rem + cos(0deg) * 28%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-08 { top: calc(50% - 0.4rem + sin(30deg) * 28%); left: calc(50% - 0.4rem + cos(30deg) * 28%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-09 { top: calc(50% - 0.4rem + sin(60deg) * 28%); left: calc(50% - 0.4rem + cos(60deg) * 28%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-10 { top: calc(50% - 0.4rem + sin(90deg) * 28%); left: calc(50% - 0.4rem + cos(90deg) * 28%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-11 { top: calc(50% - 0.4rem + sin(120deg) * 28%); left: calc(50% - 0.4rem + cos(120deg) * 28%); } |  | ||||||
|   .window-app.calendar-astrologie div.horloge-ajustement.heure-12 { top: calc(50% - 0.4rem + sin(150deg) * 28%); left: calc(50% - 0.4rem + cos(150deg) * 28%); } |  | ||||||
|  |  | ||||||
|   .window-app.calendar header.window-header h4 { |  | ||||||
|         font-size: 0.8rem; |         font-size: 0.8rem; | ||||||
|       } |       } | ||||||
|  |     } | ||||||
|   .window-app.calendar section.window-content div.calendar-boutons-heure { |     .window-content { | ||||||
|  |       margin: 0; | ||||||
|  |       padding: 0; | ||||||
|  |       z-index: 100; | ||||||
|  |       flex-direction: column; | ||||||
|  |       min-width: 250px; | ||||||
|  |       height: fit-content; | ||||||
|  |       background: hsla(0, 0%, 0%, 0.0); | ||||||
|  |       font-family: "GoudyAcc"; | ||||||
|  |       pointer-events: none; | ||||||
|  |       div.calendar-boutons-heure { | ||||||
|         display: grid; |         display: grid; | ||||||
|         background: hsla(0, 0%, 20%, 1); |         background: hsla(0, 0%, 20%, 1); | ||||||
|         color: hsla(0, 0%, 80%, 0.8); |         color: hsla(0, 0%, 80%, 0.8); | ||||||
|  |         pointer-events: all; | ||||||
|     grid-row: 1; |       } | ||||||
|     grid-column: 10; |       div.horloge-digitale { | ||||||
|  |         pointer-events: all; | ||||||
|  |       } | ||||||
|  |       div.horloge-analogique { | ||||||
|  |         pointer-events: none; | ||||||
|  |       } | ||||||
|  |       div.horloge-analogique div.horloge-roue { | ||||||
|  |         pointer-events: all; | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   .calendar-boutons-heure .calendar-btn:is(.calendar-lyre,.calendar-vaisseau) img { |     div.horloge-roue { | ||||||
|  |       position: relative; | ||||||
|  |       margin-bottom: 7px; | ||||||
|  |       left: 0; | ||||||
|  |       width: 8rem; | ||||||
|  |       height: 8rem; | ||||||
|  |       div.horloge-heure { | ||||||
|  |         width: 1.4rem; | ||||||
|  |         height: 1.4rem; | ||||||
|  |         img.horloge-heure-img { | ||||||
|  |           width: 1.4rem; | ||||||
|  |           height: 1.4rem; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     div.horloge-heure.heure-01 { top: calc(50% - 0.7rem + sin(-180deg) *38%); left: calc(50% - 0.7rem + cos(-180deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-02 { top: calc(50% - 0.7rem + sin(-150deg) *38%); left: calc(50% - 0.7rem + cos(-150deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-03 { top: calc(50% - 0.7rem + sin(-120deg) *38%); left: calc(50% - 0.7rem + cos(-120deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-04 { top: calc(50% - 0.7rem + sin(-90deg) *38%); left: calc(50% - 0.7rem + cos(-90deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-05 { top: calc(50% - 0.7rem + sin(-60deg) *38%); left: calc(50% - 0.7rem + cos(-60deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-06 { top: calc(50% - 0.7rem + sin(-30deg) *38%); left: calc(50% - 0.7rem + cos(-30deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-07 { top: calc(50% - 0.7rem + sin(-0deg) *38%); left: calc(50% - 0.7rem + cos(-0deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-08 { top: calc(50% - 0.7rem + sin(30deg) *38%); left: calc(50% - 0.7rem + cos(30deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-09 { top: calc(50% - 0.7rem + sin(60deg) *38%); left: calc(50% - 0.7rem + cos(60deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-10 { top: calc(50% - 0.7rem + sin(90deg) *38%); left: calc(50% - 0.7rem + cos(90deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-11 { top: calc(50% - 0.7rem + sin(120deg) *38%); left: calc(50% - 0.7rem + cos(120deg) *38%); } | ||||||
|  |     div.horloge-heure.heure-12 { top: calc(50% - 0.7rem + sin(150deg) *38%); left: calc(50% - 0.7rem + cos(150deg) *41%); } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .calendar-astrologie { | ||||||
|  |     div.horloge-heure.heure-01 { top: calc(50% - 1rem + sin(-180deg) *41%); left: calc(50% - 1rem + cos(-180deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-02 { top: calc(50% - 1rem + sin(-150deg) *41%); left: calc(50% - 1rem + cos(-150deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-03 { top: calc(50% - 1rem + sin(-120deg) *41%); left: calc(50% - 1rem + cos(-120deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-04 { top: calc(50% - 1rem + sin(-90deg) *41%); left: calc(50% - 1rem + cos(-90deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-05 { top: calc(50% - 1rem + sin(-60deg) *41%); left: calc(50% - 1rem + cos(-60deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-06 { top: calc(50% - 1rem + sin(-30deg) *41%); left: calc(50% - 1rem + cos(-30deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-07 { top: calc(50% - 1rem + sin(-0deg) *41%); left: calc(50% - 1rem + cos(-0deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-08 { top: calc(50% - 1rem + sin(30deg) *41%); left: calc(50% - 1rem + cos(30deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-09 { top: calc(50% - 1rem + sin(60deg) *41%); left: calc(50% - 1rem + cos(60deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-10 { top: calc(50% - 1rem + sin(90deg) *41%); left: calc(50% - 1rem + cos(90deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-11 { top: calc(50% - 1rem + sin(120deg) *41%); left: calc(50% - 1rem + cos(120deg) *41%); } | ||||||
|  |     div.horloge-heure.heure-12 { top: calc(50% - 1rem + sin(150deg) *41%); left: calc(50% - 1rem + cos(150deg) *41%); } | ||||||
|  |    | ||||||
|  |     div.horloge-ajustement.heure-01 { top: calc(50% - 0.4rem + sin(180deg) * 28%); left: calc(50% - 0.4rem + cos(180deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-02 { top: calc(50% - 0.4rem + sin(-150deg) * 28%); left: calc(50% - 0.4rem + cos(-150deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-03 { top: calc(50% - 0.4rem + sin(-120deg) * 28%); left: calc(50% - 0.4rem + cos(-120deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-04 { top: calc(50% - 0.4rem + sin(-90deg) * 28%); left: calc(50% - 0.4rem + cos(-90deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-05 { top: calc(50% - 0.4rem + sin(-60deg) * 28%); left: calc(50% - 0.4rem + cos(-60deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-06 { top: calc(50% - 0.4rem + sin(-30deg) * 28%); left: calc(50% - 0.4rem + cos(-30deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-07 { top: calc(50% - 0.4rem + sin(0deg) * 28%); left: calc(50% - 0.4rem + cos(0deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-08 { top: calc(50% - 0.4rem + sin(30deg) * 28%); left: calc(50% - 0.4rem + cos(30deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-09 { top: calc(50% - 0.4rem + sin(60deg) * 28%); left: calc(50% - 0.4rem + cos(60deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-10 { top: calc(50% - 0.4rem + sin(90deg) * 28%); left: calc(50% - 0.4rem + cos(90deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-11 { top: calc(50% - 0.4rem + sin(120deg) * 28%); left: calc(50% - 0.4rem + cos(120deg) * 28%); } | ||||||
|  |     div.horloge-ajustement.heure-12 { top: calc(50% - 0.4rem + sin(150deg) * 28%); left: calc(50% - 0.4rem + cos(150deg) * 28%); } | ||||||
|  |   }   | ||||||
|  |  | ||||||
|  |   .calendar-boutons-heure { | ||||||
|  |     .calendar-btn:is(.calendar-lyre,.calendar-vaisseau) img { | ||||||
|       color: hsla(0, 0%, 100%, 0.5); |       color: hsla(0, 0%, 100%, 0.5); | ||||||
|       border: none; |       border: none; | ||||||
|       vertical-align: bottom; |       vertical-align: bottom; | ||||||
| @@ -1768,27 +1804,29 @@ | |||||||
|       max-height: 1.2em; |       max-height: 1.2em; | ||||||
|       margin: 1px; |       margin: 1px; | ||||||
|     } |     } | ||||||
|  |     i { | ||||||
|   .calendar-boutons-heure i { |  | ||||||
|       border: 1px solid rgba(0, 0, 0, 0); |       border: 1px solid rgba(0, 0, 0, 0); | ||||||
|     } |     } | ||||||
|   .calendar-boutons-heure i:hover { |     a:hover { | ||||||
|       color: var(--color-controls-hover); |       color: var(--color-controls-hover); | ||||||
|       border: 1px solid var(--color-control-border-hover); |       border: 1px solid var(--color-control-border-hover); | ||||||
|       cursor: pointer; |       cursor: pointer; | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   .calendar-1min     { grid-column: 1;} |  | ||||||
|   .calendar-5min     { grid-column: 2;} |  | ||||||
|   .calendar-15min    { grid-column: 3;} |  | ||||||
|   .calendar-30min    { grid-column: 4;} |  | ||||||
|   .calendar-60min    { grid-column: 5;} |  | ||||||
|   .calendar-1heure   { grid-column: 6;} |  | ||||||
|   .calendar-lyre     { grid-column: 7;} |  | ||||||
|   .calendar-vaisseau { grid-column: 8;} |  | ||||||
|   .calendar-set-datetime { grid-column: 9;} |  | ||||||
|   .calendar-astrologie   { grid-column: 10;} |  | ||||||
|  |  | ||||||
|  |   .calendar-1min     { grid-column: 1/1; } | ||||||
|  |   .calendar-5min     { grid-column: 2/2; } | ||||||
|  |   .calendar-15min    { grid-column: 3/3; } | ||||||
|  |   .calendar-30min    { grid-column: 4/4; } | ||||||
|  |   .calendar-60min    { grid-column: 5/5; } | ||||||
|  |   .calendar-1heure   { grid-column: 6/6; } | ||||||
|  |   .calendar-lyre     { grid-column: 7/8; } | ||||||
|  |   .calendar-vaisseau { grid-column: 9/10; } | ||||||
|  |   :is(.calendar-lyre,.calendar-vaisseau) { | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: row; | ||||||
|  |   } | ||||||
|   div.horloge-analogique { |   div.horloge-analogique { | ||||||
|     border: none; |     border: none; | ||||||
|     margin: 0; |     margin: 0; | ||||||
| @@ -1803,22 +1841,20 @@ | |||||||
|     background: hsla(0, 0%, 20%, 1); |     background: hsla(0, 0%, 20%, 1); | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|   } |     :is(.calendar-heure-texte,.calendar-minute-texte) { | ||||||
|  |  | ||||||
|   div.horloge-digitale :is(.calendar-heure-texte,.calendar-minute-texte) { |  | ||||||
|       font-size: 1rem; |       font-size: 1rem; | ||||||
|       pointer-events: all; |       pointer-events: all; | ||||||
|       margin: 0; |       margin: 0; | ||||||
|     } |     } | ||||||
|  |     a { | ||||||
|   div.horloge-digitale a { |  | ||||||
|       border: 1px solid rgba(0, 0, 0, 0); |       border: 1px solid rgba(0, 0, 0, 0); | ||||||
|     } |     } | ||||||
|   div.horloge-digitale a:hover { |     a:hover { | ||||||
|       color: var(--color-controls-hover); |       color: var(--color-controls-hover); | ||||||
|       border: 1px solid var(--color-control-border-hover); |       border: 1px solid var(--color-control-border-hover); | ||||||
|       cursor: pointer; |       cursor: pointer; | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   div.calendar-timestamp-edit select.calendar-signe-heure { |   div.calendar-timestamp-edit select.calendar-signe-heure { | ||||||
|     width: max-content; |     width: max-content; | ||||||
| @@ -1829,13 +1865,34 @@ | |||||||
|     position: relative; |     position: relative; | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|   } |   } | ||||||
|  |   .tooltip-overflow { | ||||||
|  |     display: inline-block; | ||||||
|  |   } | ||||||
|    |    | ||||||
|   .tooltip-dotted { |   .tooltip-dotted { | ||||||
|     border-bottom: 1px dotted black; /* If you want dots under the hoverable text */ |     border-bottom: 1px dotted black; /* If you want dots under the hoverable text */ | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* Tooltip text */ |   div.message-content span .tooltip-overflow { | ||||||
|   .tooltip .tooltiptext { |     overflow: visible; | ||||||
|  |     position: absolute; | ||||||
|  |     span { | ||||||
|  |       overflow: visible; | ||||||
|  |       position: relative; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* Show the tooltip text when you mouse over the tooltip container */ | ||||||
|  |   :is(.tooltip, .tooltip-overflow):hover { | ||||||
|  |     .tooltiptext { | ||||||
|  |       visibility: visible; | ||||||
|  |       opacity: 1; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   /* html Tooltips html*/ | ||||||
|  |   :is(.tooltip, .tooltip-overflow){ | ||||||
|  |    | ||||||
|  |     .tooltiptext { | ||||||
|       text-align: center; |       text-align: center; | ||||||
|       /* Position the tooltip text */ |       /* Position the tooltip text */ | ||||||
|       position: absolute; |       position: absolute; | ||||||
| @@ -1846,11 +1903,7 @@ | |||||||
|       transition: opacity 0.3s; |       transition: opacity 0.3s; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   .tooltip .left-competence { |     .ttt-fatigue { | ||||||
|     transform: translate(-100%, 0%); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .tooltip .ttt-fatigue{ |  | ||||||
|       width: 360px; |       width: 360px; | ||||||
|  |  | ||||||
|       background: rgba(30, 25, 20, 0.9); |       background: rgba(30, 25, 20, 0.9); | ||||||
| @@ -1864,31 +1917,26 @@ | |||||||
|       padding: 3px 0; |       padding: 3px 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   .tooltip .ttt-ajustements { |     .ttt-ajustements { | ||||||
|     width: 150px; |       width: 10rem; | ||||||
|       background: var(--background-tooltip); |       background: var(--background-tooltip); | ||||||
|       border-radius: 6px; |       border-radius: 6px; | ||||||
|       font-size: 0.9rem; |       font-size: 0.9rem; | ||||||
|       padding: 3px 0; |       padding: 3px 0; | ||||||
|  |       div:nth-child(odd) { | ||||||
|  |         background: var(--background-tooltip-alt); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   .tooltip .ttt-titre { |  | ||||||
|     text-align: justify; |  | ||||||
|     width: 100%; |  | ||||||
|     top: 30px; |  | ||||||
|     background: var(--background-tooltip); |  | ||||||
|     border-radius: 6px; |  | ||||||
|     font-size: 0.9rem; |  | ||||||
|     padding: 3px; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   aside#tooltip { |   aside#tooltip { | ||||||
|  |     max-width: 15rem; | ||||||
|     background: var(--background-tooltip); |     background: var(--background-tooltip); | ||||||
|     /*color: var(--color-text-dark-primary);*/ |  | ||||||
|     color: rgba(100, 100, 50, 0.85); |     color: rgba(100, 100, 50, 0.85); | ||||||
|     font-size: 1rem; |     font-size: 0.9rem; | ||||||
|     border-radius: 0.2rem; |     border-radius: 0.2rem; | ||||||
|     padding: 0.4rem; |     padding: 0.3rem; | ||||||
|  |     font-family: "CaslonAntique"; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   aside#tooltip span.reference { |   aside#tooltip span.reference { | ||||||
| @@ -1900,19 +1948,6 @@ | |||||||
|     color: var(--color-tooltip-faint); |     color: var(--color-tooltip-faint); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .tooltip :is(.ttt-xp,.ttt-levelup) { |  | ||||||
|     width: 250px; |  | ||||||
|     background: var(--background-tooltip) !important; |  | ||||||
|     border-radius: 6px; |  | ||||||
|     font-size: 0.9rem; |  | ||||||
|     padding: 3px 0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* Show the tooltip text when you mouse over the tooltip container */ |  | ||||||
|   .tooltip:hover .tooltiptext { |  | ||||||
|     visibility: visible; |  | ||||||
|     opacity: 1; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .chat-card-button, .chat-card-button-pushed { |   .chat-card-button, .chat-card-button-pushed { | ||||||
|     border-radius: 0.2rem; |     border-radius: 0.2rem; | ||||||
|   | |||||||
							
								
								
									
										229
									
								
								less/roll-dialog.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,229 @@ | |||||||
|  | .roll-dialog { | ||||||
|  |   font-family: CaslonAntique; | ||||||
|  |   display: grid; | ||||||
|  |   grid-template-areas: | ||||||
|  |     "header header     header     header     header     header     header" | ||||||
|  |     "action action     action     action     action     action     action" | ||||||
|  |     "mode   separation separation separation separation separation separation" | ||||||
|  |     "mode   carac      carac      carac      comp       comp       resume" | ||||||
|  |     "mode   choix      choix      choix      choix      choix      modifiers" | ||||||
|  |     "mode   resolution resolution resolution resolution resolution modifiers" | ||||||
|  |     "mode   chances    chances    chances    chances    chances    buttons" | ||||||
|  |     "footer footer     footer     footer     footer     footer     footer"; | ||||||
|  |   grid-template-columns: 2rem 1rem 1fr 1fr 2fr 2fr 3fr; | ||||||
|  |   gap: 0.2rem; | ||||||
|  |  | ||||||
|  |   roll-header { grid-area: header; } | ||||||
|  |   roll-line  { grid-area: separation; } | ||||||
|  |   roll-action { grid-area: action; } | ||||||
|  |   roll-carac { grid-area: carac; } | ||||||
|  |   roll-comp { grid-area: comp; } | ||||||
|  |    | ||||||
|  |   roll-choix { grid-area: choix; } | ||||||
|  |    | ||||||
|  |   roll-table { grid-area: resolution; } | ||||||
|  |   roll-conditions { grid-area: modifiers; } | ||||||
|  |   roll-chances { grid-area: chances; } | ||||||
|  |   roll-resume { grid-area: resume; } | ||||||
|  |   roll-buttons  { grid-area: buttons; } | ||||||
|  |    | ||||||
|  |   roll-mode { | ||||||
|  |     grid-area: mode; | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |   } | ||||||
|  |   roll-conditions roll-section[name="rollmode"], | ||||||
|  |   roll-mode { | ||||||
|  |     button[data-checked="true"] { | ||||||
|  |       background-color: var(--color-text-selection-bg); | ||||||
|  |       color: var(--color-controls); | ||||||
|  |       i { filter: invert(0.8); } | ||||||
|  |       img { filter: invert(0.2); } | ||||||
|  |     } | ||||||
|  |     button { | ||||||
|  |       height: 1.8rem; | ||||||
|  |       width: 1.8rem; | ||||||
|  |       gap: 0.5rem; | ||||||
|  |       padding: 0.2rem; | ||||||
|  |       background-color: var(--button-background-color); | ||||||
|  |       color: var(--color-controls); | ||||||
|  |       i { filter: invert(0.2); } | ||||||
|  |       img { filter: invert(0.8); } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   :is(roll-carac, roll-comp) { | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: row; | ||||||
|  |     align-items: baseline; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   roll-section, | ||||||
|  |   roll-section div { | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: row; | ||||||
|  |     align-items: anchor-center; | ||||||
|  |     margin: 0 0.2rem; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   roll-resume { | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: row; | ||||||
|  |     img.button-effect-img { | ||||||
|  |       filter: invert(0.8); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   roll-choix roll-section { | ||||||
|  |     display: grid; | ||||||
|  |     grid-template-areas: | ||||||
|  |       "selection selection" | ||||||
|  |       "img roll-part"; | ||||||
|  |     grid-template-columns: 3.2rem 1fr; | ||||||
|  |     gap: 0.2rem; | ||||||
|  |     align-items: start; | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     subline { | ||||||
|  |       grid-area: selection; | ||||||
|  |       display: flex; | ||||||
|  |       flex-direction: row; | ||||||
|  |       margin: 0.1rem 0; | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |     roll-part-img { | ||||||
|  |       display: flex; | ||||||
|  |       flex-direction: column; | ||||||
|  |       grid-area: img; | ||||||
|  |       img{ | ||||||
|  |         border: 0; | ||||||
|  |         padding: 1px; | ||||||
|  |         max-height: 3rem; | ||||||
|  |         max-width: 3rem; | ||||||
|  |         object-fit: contain; | ||||||
|  |         height: 100%; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     roll-part-detail { | ||||||
|  |       grid-area: roll-part; | ||||||
|  |       display: flex; | ||||||
|  |       flex-direction: column; | ||||||
|  |       align-items: normal; | ||||||
|  |        | ||||||
|  |       subline { | ||||||
|  |         display: flex; | ||||||
|  |         flex-direction: row; | ||||||
|  |         margin: 0.1rem 0; | ||||||
|  |         div.poesie-extrait{ | ||||||
|  |           display: flex; | ||||||
|  |           flex-direction: column; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   roll-section selected-numeric-value { | ||||||
|  |     display: flow; | ||||||
|  |     width: 2.5rem; | ||||||
|  |     text-align: right; | ||||||
|  |     margin: 0 0.2rem 0 0.5rem; | ||||||
|  |     padding: 0 0.2rem; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   roll-action { | ||||||
|  |     flex-basis: content; | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: row; | ||||||
|  |     align-items: center; | ||||||
|  |     border-bottom: 0.2rem solid; | ||||||
|  |     font-size: 1.2rem; | ||||||
|  |     font-weight: bold; | ||||||
|  |      | ||||||
|  |     roll-section { | ||||||
|  |       display: flex; | ||||||
|  |       flex-direction: row; | ||||||
|  |       align-items: center; | ||||||
|  |  | ||||||
|  |       img.action-img { | ||||||
|  |         float: left; | ||||||
|  |       } | ||||||
|  |       img { | ||||||
|  |         max-width: 3rem; | ||||||
|  |         max-height: 3rem; | ||||||
|  |         margin: 0 1rem; | ||||||
|  |         padding: 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   roll-conditions { | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |   } | ||||||
|  |   :is(roll-action, roll-carac, roll-comp) roll-section { | ||||||
|  |     flex-basis: content; | ||||||
|  |   }   | ||||||
|  |  | ||||||
|  |   :is(roll-choix, roll-conditions, roll-carac, roll-comp) { | ||||||
|  |     select { | ||||||
|  |       max-height: 1.6rem; | ||||||
|  |       margin: 0 0.2rem; | ||||||
|  |       padding: 0 0.2rem; | ||||||
|  |     } | ||||||
|  |     input[type="number"] { | ||||||
|  |       max-height: 1.6rem; | ||||||
|  |       max-width: 2.5rem; | ||||||
|  |       margin: 0 0.2rem; | ||||||
|  |       padding: 0 0.2rem; | ||||||
|  |     } | ||||||
|  |     img { | ||||||
|  |           max-width: 1.8rem; | ||||||
|  |           max-height: 1.8rem; | ||||||
|  |           margin: 0 0.2rem; | ||||||
|  |           padding: 0; | ||||||
|  |     } | ||||||
|  |     img.button-effect-img { | ||||||
|  |           max-width: 1rem; | ||||||
|  |           max-height: 1rem; | ||||||
|  |           margin: 0 0.1rem; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   roll-carac select[name="select-carac"] { | ||||||
|  |     max-width: 6rem; | ||||||
|  |  | ||||||
|  |   }     | ||||||
|  |   roll-comp select[name="select-comp"] { | ||||||
|  |     min-width: 8rem; | ||||||
|  |     max-width: 11rem; | ||||||
|  |     margin-left: 1rem; | ||||||
|  |   }      | ||||||
|  |  | ||||||
|  |   roll-conditions roll-section[name="coeur"] select[name="coeur"]  { | ||||||
|  |     max-width: 4rem; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   roll-conditions roll-section[name="tricher"] img { | ||||||
|  |     /* image de d100 */ | ||||||
|  |     max-width: 2.5rem; | ||||||
|  |     max-height: 2.5rem; | ||||||
|  |     gap: 0; | ||||||
|  |     margin: 0; | ||||||
|  |     padding: 0; | ||||||
|  |     filter: invert(0.8); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   roll-buttons {  | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: row-reverse; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   roll-table { | ||||||
|  |     table tr :is(th, td) { | ||||||
|  |         padding: 0.1rem; | ||||||
|  |         width: 1.5rem; | ||||||
|  |         text-align: center; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,7 +1,5 @@ | |||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
| import { HtmlUtility } from "./html-utility.js"; | import { HtmlUtility } from "./html-utility.js"; | ||||||
| import { RdDItemArme } from "./item-arme.js"; |  | ||||||
| import { RdDItemCompetence } from "./item-competence.js"; |  | ||||||
| import { RdDBonus } from "./rdd-bonus.js"; | import { RdDBonus } from "./rdd-bonus.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDCombatManager } from "./rdd-combat.js"; | import { RdDCombatManager } from "./rdd-combat.js"; | ||||||
| @@ -9,11 +7,12 @@ import { RdDCarac } from "./rdd-carac.js"; | |||||||
| import { DialogSplitItem } from "./dialog-split-item.js"; | import { DialogSplitItem } from "./dialog-split-item.js"; | ||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||||
| import { RdDSheetUtility } from "./rdd-sheet-utility.js"; | import { RdDSheetUtility } from "./rdd-sheet-utility.js"; | ||||||
| import { STATUSES } from "./settings/status-effects.js"; |  | ||||||
| import { MAINS_DIRECTRICES } from "./actor.js"; | import { MAINS_DIRECTRICES } from "./actor.js"; | ||||||
| import { RdDBaseActorReveSheet } from "./actor/base-actor-reve-sheet.js"; | import { RdDBaseActorReveSheet } from "./actor/base-actor-reve-sheet.js"; | ||||||
| import { ITEM_TYPES } from "./constants.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { RdDItem } from "./item.js"; | import { RdDItem } from "./item.js"; | ||||||
|  | import { RdDItemArme } from "./item/arme.js"; | ||||||
|  | import { RdDItemCompetence } from "./item-competence.js"; | ||||||
| import { RdDItemBlessure } from "./item/blessure.js"; | import { RdDItemBlessure } from "./item/blessure.js"; | ||||||
| import { RdDEmpoignade } from "./rdd-empoignade.js"; | import { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||||
| import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js"; | import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js"; | ||||||
| @@ -34,7 +33,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|       width: 550, |       width: 550, | ||||||
|       showCompNiveauBase: false, |       showCompNiveauBase: false, | ||||||
|       vueArchetype: false, |       vueArchetype: false, | ||||||
|     }, { inplace: false }); |     }, { inplace: false }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -50,7 +49,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|     }); |     }); | ||||||
|     foundry.utils.mergeObject(formData.calc, { |     foundry.utils.mergeObject(formData.calc, { | ||||||
|       surenc: this.actor.computeMalusSurEncombrement(), |       surenc: this.actor.computeMalusSurEncombrement(), | ||||||
|       surprise: RdDBonus.find(this.actor.getSurprise(false)).descr, |       surprise: RdDBonus.find(this.actor.getSurprise(false)).label, | ||||||
|       resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures), |       resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures), | ||||||
|       caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute), |       caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute), | ||||||
|       surEncombrementMessage: this.actor.isSurenc() ? "Sur-Encombrement!" : "", |       surEncombrementMessage: this.actor.isSurenc() ? "Sur-Encombrement!" : "", | ||||||
| @@ -78,14 +77,10 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|       }); |       }); | ||||||
|  |  | ||||||
|       // toujours avoir une liste d'armes (pour mettre esquive et corps à corps) |       // toujours avoir une liste d'armes (pour mettre esquive et corps à corps) | ||||||
|       const actor = this.actor; |       const actor = this.actor | ||||||
|       formData.combat = foundry.utils.duplicate(formData.armes); |  | ||||||
|       RdDItemArme.computeNiveauArmes(formData.combat, formData.competences); |  | ||||||
|       formData.combat.push(RdDItemArme.corpsACorps(actor)); |  | ||||||
|       formData.combat.push(RdDItemArme.empoignade(actor)); |  | ||||||
|  |  | ||||||
|       formData.esquives = this.actor.getCompetencesEsquive() |       formData.esquives = this.actor.getCompetencesEsquive() | ||||||
|       formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac); |       formData.combat = actor.listActionsAttaque() | ||||||
|       formData.empoignades = this.actor.getEmpoignades(); |       formData.empoignades = this.actor.getEmpoignades(); | ||||||
|  |  | ||||||
|       this.armesList = formData.combat; |       this.armesList = formData.combat; | ||||||
| @@ -95,7 +90,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|       formData.difficultesLibres = CONFIG.RDD.difficultesLibres; |       formData.difficultesLibres = CONFIG.RDD.difficultesLibres; | ||||||
|  |  | ||||||
|       formData.hautreve = { |       formData.hautreve = { | ||||||
|         isDemiReve: this.actor.getEffect(STATUSES.StatusDemiReve), |         isDemiReve: this.actor.isDemiReve(), | ||||||
|         cacheTMR: this.actor.isTMRCache() |         cacheTMR: this.actor.isTMRCache() | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -217,13 +212,17 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|     this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac('reve-actuel', { resistance: true })) |     this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac('reve-actuel', { resistance: true })) | ||||||
|     this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) |     this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) | ||||||
|  |  | ||||||
|     this.html.find('.roll-arme').click(async event => await this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence')) |     this.html.find('.roll-arme').click(async event => { | ||||||
|  |       const action = this._getActionCombat(event); | ||||||
|  |       await this.actor.rollArme(action.arme, action.main) | ||||||
|  |  | ||||||
|  |     }) | ||||||
|  |  | ||||||
|     // Initiative pour l'arme |     // Initiative pour l'arme | ||||||
|     this.html.find('.roll-init-arme').click(async event => { |     this.html.find('.roll-init-arme').click(async event => { | ||||||
|       let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id) |       let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id) | ||||||
|       if (combatant) { |       if (combatant) { | ||||||
|         RdDCombatManager.rollInitiativeAction(combatant._id, this._getEventArmeCombat(event)); |         RdDCombatManager.rollInitiativeAction(combatant._id, this._getActionCombat(event)); | ||||||
|       } else { |       } else { | ||||||
|         ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat."); |         ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat."); | ||||||
|       } |       } | ||||||
| @@ -237,7 +236,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|  |  | ||||||
|     this.html.find('.carac-xp-augmenter').click(async event => await this.actor.updateCaracXPAuto(event.currentTarget.name.replace("augmenter.", ""))) |     this.html.find('.carac-xp-augmenter').click(async event => await this.actor.updateCaracXPAuto(event.currentTarget.name.replace("augmenter.", ""))) | ||||||
|     this.html.find('.competence-xp-augmenter').click(async event => await this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event))) |     this.html.find('.competence-xp-augmenter').click(async event => await this.actor.updateCompetenceXPAuto(RdDSheetUtility.getItemId(event))) | ||||||
|     this.html.find('.competence-stress-augmenter').click(async event =>{ |     this.html.find('.competence-stress-augmenter').click(async event => { | ||||||
|       await this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event)) |       await this.actor.updateCompetenceStress(RdDSheetUtility.getItemId(event)) | ||||||
|       this.render(true) |       this.render(true) | ||||||
|     } |     } | ||||||
| @@ -347,13 +346,17 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|     await this.actor.createItem('tache', 'Nouvelle tache'); |     await this.actor.createItem('tache', 'Nouvelle tache'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   _getEventArmeCombat(event) { |   _getActionCombat(event) { | ||||||
|     const li = this.html.find(event.currentTarget)?.parents(".item"); |     const li = this.html.find(event.currentTarget)?.parents(".item"); | ||||||
|     let armeName = li.data("arme-name"); |     let armeName = li.data("arme-name"); | ||||||
|     let compName = li.data('competence-name'); |     let compName = li.data('competence-name'); | ||||||
|     const arme = this.armesList.find(a => a.name == armeName && a.system.competence == compName); |     const arme = this.armesList.find(a => a.arme.name == armeName && a.comp.name == compName); | ||||||
|     if (!arme) { |     if (!arme) { | ||||||
|       return { name: armeName, system: { competence: compName } }; |       return { | ||||||
|  |         name: armeName, | ||||||
|  |         arme: { name: armeName }, | ||||||
|  |         comp: { name: compName } | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|     return arme; |     return arme; | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								module/actor-token.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,40 @@ | |||||||
|  | /** | ||||||
|  |  * class providing the actor and token, and choosing the name and image from the token if available. | ||||||
|  |  */ | ||||||
|  | export class ActorToken { | ||||||
|  |  | ||||||
|  |   static fromActorId(actorId, onError = () => undefined) { | ||||||
|  |     actorId = actorId ?? (canvas.tokens.controlled.length > 0 | ||||||
|  |       ? canvas.tokens.controlled[0].actor.id | ||||||
|  |       : undefined) | ||||||
|  |     const actor = actorId ? game.actors.get(actorId) : undefined | ||||||
|  |     if (actor) { | ||||||
|  |       return this.fromActor(actor) | ||||||
|  |     } | ||||||
|  |     return onError() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static fromActor(actor) { | ||||||
|  |     const token = actor.isToken ? actor.token : actor.prototypeToken | ||||||
|  |     return ActorToken.fromToken(token) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static fromTokenId(tokenId, sceneId = undefined) { | ||||||
|  |     const tokensList = sceneId ? game.scenes.get(sceneId).tokens : canvas.tokens.placeables | ||||||
|  |     const token = tokensList.get(tokenId) | ||||||
|  |     return ActorToken.fromToken(token) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static fromToken(token) { | ||||||
|  |     return new ActorToken(token) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   constructor(token) { | ||||||
|  |     this.name = token.name ?? token.actor.name | ||||||
|  |     this.img = token.texture.src ?? token.actor.img | ||||||
|  |     this.actor = token.actor | ||||||
|  |     this.id = token.actor?.id | ||||||
|  |     this.token = token | ||||||
|  |     this.tokenId = token?.id | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										522
									
								
								module/actor.js
									
									
									
									
									
								
							
							
						
						| @@ -8,12 +8,9 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js"; | |||||||
| import { RdDDice } from "./rdd-dice.js"; | import { RdDDice } from "./rdd-dice.js"; | ||||||
| import { RdDRollTables } from "./rdd-rolltables.js"; | import { RdDRollTables } from "./rdd-rolltables.js"; | ||||||
| import { ChatUtility } from "./chat-utility.js"; | import { ChatUtility } from "./chat-utility.js"; | ||||||
| import { RdDItemSort } from "./item-sort.js"; |  | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { RdDItemCompetence } from "./item-competence.js"; |  | ||||||
| import { RdDAlchimie } from "./rdd-alchimie.js"; | import { RdDAlchimie } from "./rdd-alchimie.js"; | ||||||
| import { STATUSES } from "./settings/status-effects.js"; | import { STATUSES } from "./settings/status-effects.js"; | ||||||
| import { RdDItemSigneDraconique } from "./item/signedraconique.js"; |  | ||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||||
| import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; | import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; | ||||||
| import { Draconique } from "./tmr/draconique.js"; | import { Draconique } from "./tmr/draconique.js"; | ||||||
| @@ -22,13 +19,11 @@ import { DialogConsommer } from "./dialog-item-consommer.js"; | |||||||
| import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js"; | import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js"; | ||||||
| import { RollDataAjustements } from "./rolldata-ajustements.js"; | import { RollDataAjustements } from "./rolldata-ajustements.js"; | ||||||
| import { RdDPossession } from "./rdd-possession.js"; | import { RdDPossession } from "./rdd-possession.js"; | ||||||
| import { SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | import { ACTOR_TYPES, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | ||||||
| import { RdDConfirm } from "./rdd-confirm.js"; | import { RdDConfirm } from "./rdd-confirm.js"; | ||||||
| import { RdDRencontre } from "./item/rencontre.js"; |  | ||||||
| import { DialogRepos } from "./sommeil/dialog-repos.js"; | import { DialogRepos } from "./sommeil/dialog-repos.js"; | ||||||
| import { RdDBaseActor } from "./actor/base-actor.js"; | import { RdDBaseActor } from "./actor/base-actor.js"; | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||||
| import { RdDItemBlessure } from "./item/blessure.js"; |  | ||||||
| import { AppAstrologie } from "./sommeil/app-astrologie.js"; | import { AppAstrologie } from "./sommeil/app-astrologie.js"; | ||||||
| import { RdDEmpoignade } from "./rdd-empoignade.js"; | import { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||||
| import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js"; | import { ExperienceLog, XP_TOPIC } from "./actor/experience-log.js"; | ||||||
| @@ -36,13 +31,23 @@ import { ITEM_TYPES } from "./constants.js"; | |||||||
| import { RdDBaseActorSang } from "./actor/base-actor-sang.js"; | import { RdDBaseActorSang } from "./actor/base-actor-sang.js"; | ||||||
| import { RdDCoeur } from "./coeur/rdd-coeur.js"; | import { RdDCoeur } from "./coeur/rdd-coeur.js"; | ||||||
| import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js"; | import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js"; | ||||||
| import { RdDItemArme } from "./item-arme.js"; |  | ||||||
| import { RdDCombatManager } from "./rdd-combat.js"; | import { RdDCombatManager } from "./rdd-combat.js"; | ||||||
|  |  | ||||||
|  | import { RdDItemArme } from "./item/arme.js"; | ||||||
|  | import { RdDItemBlessure } from "./item/blessure.js"; | ||||||
| import { RdDItemTete } from "./item/tete.js"; | import { RdDItemTete } from "./item/tete.js"; | ||||||
|  | import { RdDItemSort } from "./item-sort.js"; | ||||||
|  | import { RdDItemRace } from "./item/race.js"; | ||||||
|  | import { RdDItemCompetence } from "./item-competence.js"; | ||||||
|  | import { RdDItemSigneDraconique } from "./item/signedraconique.js"; | ||||||
|  | import { RdDRencontre } from "./item/rencontre.js"; | ||||||
| import { DialogSelect } from "./dialog-select.js"; | import { DialogSelect } from "./dialog-select.js"; | ||||||
| import { PAS_DE_DRACONIC, POSSESSION_SANS_DRACONIC } from "./item/base-items.js"; | import { PAS_DE_DRACONIC, POSSESSION_SANS_DRACONIC } from "./item/base-items.js"; | ||||||
| import { RdDItemRace } from "./item/race.js"; |  | ||||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | import { RdDRollResult } from "./rdd-roll-result.js"; | ||||||
|  | import { RdDInitiative } from "./initiative.mjs"; | ||||||
|  | import RollDialog from "./roll/roll-dialog.mjs"; | ||||||
|  | import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js"; | ||||||
|  |  | ||||||
| export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] | export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] | ||||||
|  |  | ||||||
| @@ -105,7 +110,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     return Number.isNumeric(this.system.compteurs.chance.value) ? |     return Number.isNumeric(this.system.compteurs.chance.value) ? | ||||||
|       Misc.toInt(this.system.compteurs.chance.value) : this.getChance() |       Misc.toInt(this.system.compteurs.chance.value) : this.getChance() | ||||||
|   } |   } | ||||||
|   getMoralTotal() { return this.system.compteurs.moral?.value ?? 0 } |   getMoralTotal() { return parseInt(this.system.compteurs.moral?.value ?? 0) } | ||||||
|  |  | ||||||
|   getEnduranceMax() { return Math.max(1, Math.max(this.getTaille() + this.getConstitution(), this.getVieMax() + this.getVolonte())) } |   getEnduranceMax() { return Math.max(1, Math.max(this.getTaille() + this.getConstitution(), this.getVieMax() + this.getVolonte())) } | ||||||
|  |  | ||||||
| @@ -113,8 +118,10 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   getEtatGeneral(options = { ethylisme: false }) { |   getEtatGeneral(options = { ethylisme: false }) { | ||||||
|     const etatGeneral = this.system.compteurs.etat?.value ?? 0 |     const etatGeneral = this.system.compteurs.etat?.value ?? 0 | ||||||
|     // Pour les jets d'Ethylisme, on retire le malus d'éthylisme (p.162) |     // Pour les jets d'Ethylisme, on retire le malus d'éthylisme (p.162) | ||||||
|     const annuleMalusEthylisme = options.ethylisme ? this.malusEthylisme() : 0 |     if (options.ethylisme) { | ||||||
|     return etatGeneral - annuleMalusEthylisme |       return etatGeneral - this.malusEthylisme() | ||||||
|  |     } | ||||||
|  |     return etatGeneral | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -129,19 +136,13 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|       .reduce(Misc.sum(), 0); |       .reduce(Misc.sum(), 0); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   listActionsCombat() { |   listActions({ isAttaque = false, isEquipe = false }) { | ||||||
|     // Recupération des armes |     // Recupération des armes | ||||||
|     const actions = RdDCombatManager.listActionsArmes( |     const actions = this.listActionsAttaque() | ||||||
|       this.itemTypes[ITEM_TYPES.arme] |       .filter(it => !isEquipe || it.arme.system.equipe) | ||||||
|         .filter(it => RdDItemArme.isAttaque(it)) |  | ||||||
|         .concat(RdDItemArme.corpsACorps(this)) |  | ||||||
|         .concat(RdDItemArme.empoignade(this)) |  | ||||||
|       , |  | ||||||
|       this.itemTypes[ITEM_TYPES.competence], |  | ||||||
|       this.system.carac) |  | ||||||
|  |  | ||||||
|     if (this.system.attributs.hautrevant.value) { |     if (!isAttaque && this.system.attributs.hautrevant.value) { | ||||||
|       actions.push({ name: "Draconic", action: 'haut-reve', system: { initOnly: true, competence: "Draconic" } }); |       actions.push({ name: "Draconic", action: 'haut-reve', initOnly: true }) | ||||||
|     } |     } | ||||||
|     return actions |     return actions | ||||||
|   } |   } | ||||||
| @@ -166,6 +167,86 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|       .find(it => true) |       .find(it => true) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   /** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main / lancer */ | ||||||
|  |   listActionsAttaque() { | ||||||
|  |     let actions = [ | ||||||
|  |       this.$prepareAttaqueArme(RdDItemArme.empoignade(this)), | ||||||
|  |       this.$prepareAttaqueArme(RdDItemArme.corpsACorps(this)), | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  |     const armes = this.itemTypes[ITEM_TYPES.arme] | ||||||
|  |       .filter(it => RdDItemArme.isAttaque(it)) | ||||||
|  |       .sort(Misc.ascending(it => it.name)); | ||||||
|  |  | ||||||
|  |     for (const arme of armes) { | ||||||
|  |       if (arme.system.unemain && arme.system.competence) { | ||||||
|  |         actions.push(this.$prepareAttaqueArme(arme, '(1 main)')) | ||||||
|  |       } | ||||||
|  |       if (arme.system.deuxmains && arme.system.competence) { | ||||||
|  |         actions.push(this.$prepareAttaqueArme(arme, '(2 mains)')) | ||||||
|  |       } | ||||||
|  |       if (arme.system.lancer) { | ||||||
|  |         actions.push(this.$prepareAttaqueArme(arme, '(lancer)')) | ||||||
|  |       } | ||||||
|  |       if (arme.system.tir) { | ||||||
|  |         actions.push(this.$prepareAttaqueArme(arme, '(tir)')) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return actions; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   $prepareAttaqueArme(arme, main) { | ||||||
|  |     const comp = this.getCompetence(RdDActor.$getCompetenceAction(arme, main)) | ||||||
|  |     const caracCode = RdDActor.$getCaracAction(comp, main) | ||||||
|  |     const caracValue = this.system.carac[caracCode].value | ||||||
|  |     const dommages = arme.system.dommages.toString() | ||||||
|  |  | ||||||
|  |     // TODO: déplacer sur RdDItemArme | ||||||
|  |     if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) { | ||||||
|  |       ui.notifications.info(`Les dommages de l'arme à 1/2 mains ${arme.name} ne sont pas corrects (ie sous la forme X/Y)`) | ||||||
|  |     } | ||||||
|  |     const tableauDommages = dommages.includes("/") ? dommages.split("/") : [dommages, dommages] | ||||||
|  |     const dommagesArme = parseInt(main == '(2 mains)' ? tableauDommages[1] : tableauDommages[0]) | ||||||
|  |     const niveau = comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(main) ? -8 : -6) | ||||||
|  |     const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + (arme.system.magique) ? arme.system.ecaille_efficacite : 0 | ||||||
|  |  | ||||||
|  |     return { | ||||||
|  |       name: arme.name + (main ? ' ' + main : ''), | ||||||
|  |       action: 'attaque', | ||||||
|  |       initOnly: false, | ||||||
|  |       arme: arme, | ||||||
|  |       comp: comp, | ||||||
|  |       main: main, | ||||||
|  |       carac: { key: caracCode, value: caracValue }, | ||||||
|  |       equipe: arme.system.equipe, | ||||||
|  |       dommagesArme: dommagesArme, | ||||||
|  |       initiative: RdDInitiative.calculInitiative(niveau, caracValue, ajustement) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $getCaracAction(comp, main) { | ||||||
|  |     if (comp?.system.defaut_carac) { | ||||||
|  |       return comp.system.defaut_carac | ||||||
|  |     } | ||||||
|  |     switch (main) { | ||||||
|  |       case '(lancer)': return 'lancer' | ||||||
|  |       case '(tir)': return 'tir' | ||||||
|  |       default: return 'melee' | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $getCompetenceAction(arme, main) { | ||||||
|  |     switch (main) { | ||||||
|  |       case '(1 main)': return arme.competence1Mains() | ||||||
|  |       case '(2 mains)': return arme.competence2Mains() | ||||||
|  |       case '(lancer)': return arme.system.lancer | ||||||
|  |       case '(tir)': return arme.system.tir | ||||||
|  |       default: return arme.system.competence | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async $perteReveEnchantementsChateauDormants() { |   async $perteReveEnchantementsChateauDormants() { | ||||||
|     const toUpdate = this.items.filter(it => [ITEM_TYPES.potion, ITEM_TYPES.gemme].includes(it.type)) |     const toUpdate = this.items.filter(it => [ITEM_TYPES.potion, ITEM_TYPES.gemme].includes(it.type)) | ||||||
| @@ -895,8 +976,14 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|  |   ethylisme() { | ||||||
|  |     return this.system.compteurs.ethylisme?.value ?? 1; | ||||||
|  |   } | ||||||
|   malusEthylisme() { |   malusEthylisme() { | ||||||
|     return Math.min(0, (this.system.compteurs.ethylisme?.value ?? 0)); |     return Math.min(0, this.ethylisme()) | ||||||
|  |   } | ||||||
|  |   isAlcoolise() { | ||||||
|  |     return this.ethylisme() < 1 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1482,7 +1569,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   createCallbackAppelAuMoral() { /* Si l'appel au moral est utilisé, on l'affiche dans le chat et on diminue éventuellement le moral */ |   createCallbackAppelAuMoral() { /* Si l'appel au moral est utilisé, on l'affiche dans le chat et on diminue éventuellement le moral */ | ||||||
|     return { |     return { | ||||||
|       action: r => this._appliquerAppelMoral(r) |       action: r => this.appliquerAppelMoral(r) | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1578,12 +1665,12 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async _appliquerAppelMoral(rollData) { |   async appliquerAppelMoral(rollData) { | ||||||
|     if (!rollData.use.moral || game.settings.get("core", "rollMode") == 'selfroll') { |     if (!rollData.use.moral || game.settings.get("core", "rollMode") == 'selfroll') { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     if (rollData.rolled.isEchec || |     if (rollData.rolled.isEchec || | ||||||
|       (rollData.ajustements.diviseurSignificative && (rollData.rolled.roll * rollData.ajustements.diviseurSignificative > rollData.score))) { |       (rollData.diviseurSignificative && (rollData.rolled.roll * rollData.diviseurSignificative > rollData.rolled.score))) { | ||||||
|       rollData.perteMoralEchec = rollData.moral <= -3 ? 'dissolution' : 'perte'; |       rollData.perteMoralEchec = rollData.moral <= -3 ? 'dissolution' : 'perte'; | ||||||
|       rollData.moral = await this.moralIncDec(-1); /* L'appel au moral a échoué. Le personnage perd un point de moral */ |       rollData.moral = await this.moralIncDec(-1); /* L'appel au moral a échoué. Le personnage perd un point de moral */ | ||||||
|     } |     } | ||||||
| @@ -1591,20 +1678,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   $filterSortList(sortList, coord) { |   $filterSortList(sortList, coord) { | ||||||
|     let tmr = TMRUtility.getTMR(coord); |     return sortList.filter(it => RdDItemSort.isSortOnCoord(it, coord)) | ||||||
|     let filtered = [] |  | ||||||
|     for (let sort of sortList) { |  | ||||||
|       if (sort.system.caseTMR.toLowerCase().includes('variable')) { |  | ||||||
|         filtered.push(sort); |  | ||||||
|       } else if (sort.system.caseTMRspeciale.toLowerCase().includes('variable')) { |  | ||||||
|         filtered.push(sort); |  | ||||||
|       } else if (sort.system.caseTMR.toLowerCase() == tmr.type) { |  | ||||||
|         filtered.push(sort); |  | ||||||
|       } else if (sort.system.caseTMR.toLowerCase().includes('special') && sort.system.caseTMRspeciale.toLowerCase().includes(coord.toLowerCase())) { |  | ||||||
|         filtered.push(sort); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     return filtered; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -1630,8 +1704,8 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|       ui.notifications.error("Une queue ou un souffle vous empèche de lancer de sort!") |       ui.notifications.error("Une queue ou un souffle vous empèche de lancer de sort!") | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     // Duplication car les pts de reve sont modifiés dans le sort |     // Duplication car les pts de reve sont modifiés dans le sort! | ||||||
|     let sorts = foundry.utils.duplicate(this.$filterSortList(this.itemTypes['sort'], coord)); |     let sorts = foundry.utils.duplicate(this.itemTypes[ITEM_TYPES.sort].filter(it => RdDItemSort.isSortOnCoord(it, coord))) | ||||||
|     if (sorts.length == 0) { |     if (sorts.length == 0) { | ||||||
|       ui.notifications.info(`Aucun sort disponible en ${TMRUtility.getTMR(coord).label} !`); |       ui.notifications.info(`Aucun sort disponible en ${TMRUtility.getTMR(coord).label} !`); | ||||||
|       return; |       return; | ||||||
| @@ -1919,153 +1993,6 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async _rollArt(artData, selected, oeuvre, callbackAction = async r => await this._resultArt(r)) { |  | ||||||
|     oeuvre.system.niveau = oeuvre.system.niveau ?? 0; |  | ||||||
|     foundry.utils.mergeObject(artData, |  | ||||||
|       { |  | ||||||
|         oeuvre: oeuvre, |  | ||||||
|         art: oeuvre.type, |  | ||||||
|         competence: foundry.utils.duplicate(this.getCompetence(artData.compName ?? oeuvre.system.competence ?? artData.art)), |  | ||||||
|         diffLibre: - oeuvre.system.niveau, |  | ||||||
|         diffConditions: 0, |  | ||||||
|         use: { libre: false, conditions: true, surenc: false }, |  | ||||||
|         selectedCarac: foundry.utils.duplicate(this.system.carac[selected]) |  | ||||||
|       }, |  | ||||||
|       { overwrite: false }); |  | ||||||
|     artData.competence.system.defaut_carac = selected; |  | ||||||
|     if (!artData.forceCarac) { |  | ||||||
|       artData.forceCarac = {}; |  | ||||||
|       artData.forceCarac[selected] = foundry.utils.duplicate(this.system.carac[selected]); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     await this.openRollDialog({ |  | ||||||
|       name: `jet-${artData.art}`, |  | ||||||
|       label: `${artData.verbe} ${oeuvre.name}`, |  | ||||||
|       template: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.hbs`, |  | ||||||
|       rollData: artData, |  | ||||||
|       callbacks: [{ action: callbackAction }], |  | ||||||
|     }) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async _resultArt(artData) { |  | ||||||
|     const niveau = artData.oeuvre.system.niveau ?? 0; |  | ||||||
|     const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau); |  | ||||||
|     artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite; |  | ||||||
|  |  | ||||||
|     await RdDRollResult.displayRollData(artData, this.name, `chat-resultat-${artData.art}.hbs`); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async rollChant(id) { |  | ||||||
|     const artData = { art: 'chant', verbe: 'Chanter' }; |  | ||||||
|     const oeuvre = foundry.utils.duplicate(this.getChant(id)); |  | ||||||
|     await this._rollArt(artData, "ouie", oeuvre); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async rollDanse(id) { |  | ||||||
|     const artData = { art: 'danse', verbe: 'Danser', forceCarac: {} }; |  | ||||||
|     const oeuvre = foundry.utils.duplicate(this.findItemLike(id, artData.art)); |  | ||||||
|     if (oeuvre.system.agilite) { |  | ||||||
|       artData.forceCarac['agilite'] = foundry.utils.duplicate(this.system.carac.agilite); |  | ||||||
|     } |  | ||||||
|     if (oeuvre.system.apparence) { |  | ||||||
|       artData.forceCarac['apparence'] = foundry.utils.duplicate(this.system.carac.apparence); |  | ||||||
|     } |  | ||||||
|     const selectedCarac = this._getCaracDanse(oeuvre); |  | ||||||
|     await this._rollArt(artData, selectedCarac, oeuvre); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   _getCaracDanse(oeuvre) { |  | ||||||
|     if (oeuvre.system.agilite) { return "agilite"; } |  | ||||||
|     else if (oeuvre.system.apparence) { return "apparence"; } |  | ||||||
|     const compData = this.getCompetence(oeuvre.system.competence); |  | ||||||
|     return compData.system.defaut_carac; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async rollMusique(id) { |  | ||||||
|     const artData = { art: 'musique', verbe: 'Jouer' }; |  | ||||||
|     const oeuvre = this.findItemLike(id, artData.art); |  | ||||||
|     await this._rollArt(artData, "ouie", oeuvre); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async rollRecetteCuisine(id) { |  | ||||||
|     const oeuvre = this.getRecetteCuisine(id); |  | ||||||
|     const artData = { |  | ||||||
|       verbe: 'Cuisiner', |  | ||||||
|       compName: 'cuisine', |  | ||||||
|       proportions: 1, |  | ||||||
|       ajouterEquipement: false |  | ||||||
|     }; |  | ||||||
|     await this._rollArt(artData, 'odoratgout', oeuvre, r => this._resultRecetteCuisine(r)); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async _resultRecetteCuisine(cuisine) { |  | ||||||
|     const niveauRecette = cuisine.oeuvre.system.niveau ?? 0; |  | ||||||
|     const baseQualite = (cuisine.rolled.isSuccess ? niveauRecette : cuisine.competence.system.niveau); |  | ||||||
|     cuisine.qualiteFinale = Math.min(baseQualite, niveauRecette) + cuisine.rolled.ptQualite; |  | ||||||
|     cuisine.exotismeFinal = Math.min(Math.min(cuisine.qualiteFinale, cuisine.oeuvre.system.exotisme ?? 0), 0); |  | ||||||
|     cuisine.sust = cuisine.oeuvre.system.sust * Math.min(cuisine.proportions, cuisine.proportionsMax ?? cuisine.proportions) |  | ||||||
|     const platCuisine = { |  | ||||||
|       name: cuisine.oeuvre.name, |  | ||||||
|       type: 'nourritureboisson', |  | ||||||
|       img: 'systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp', |  | ||||||
|       system: { |  | ||||||
|         "description": cuisine.oeuvre.system.description, |  | ||||||
|         "sust": 1, |  | ||||||
|         "qualite": cuisine.qualiteFinale, |  | ||||||
|         "exotisme": cuisine.exotismeFinal, |  | ||||||
|         "encombrement": 0.1, |  | ||||||
|         "quantite": Math.max(1, Math.floor(cuisine.sust)), |  | ||||||
|         "cout": Math.max(cuisine.qualiteFinale) * 0.01 |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     if (cuisine.ajouterEquipement) { |  | ||||||
|       await this.createEmbeddedDocuments('Item', [platCuisine]); |  | ||||||
|       ui.notifications.info(`${platCuisine.system.quantite} rations de ${platCuisine.name} ont été ajoutés à votre équipement`); |  | ||||||
|     } |  | ||||||
|     cuisine.platCuisine = platCuisine; |  | ||||||
|     await RdDRollResult.displayRollData(cuisine, this.name, `chat-resultat-${cuisine.art}.hbs`); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async preparerNourriture(item) { |  | ||||||
|     if (item.getUtilisationCuisine() == 'brut') { |  | ||||||
|       const nourriture = { |  | ||||||
|         name: 'Plat de ' + item.name, |  | ||||||
|         type: 'recettecuisine', |  | ||||||
|         img: item.img, |  | ||||||
|         system: { |  | ||||||
|           sust: item.system.sust, |  | ||||||
|           exotisme: item.system.exotisme, |  | ||||||
|           ingredients: item.name |  | ||||||
|         } |  | ||||||
|       }; |  | ||||||
|       const artData = { |  | ||||||
|         verbe: 'Préparer', |  | ||||||
|         compName: 'cuisine', |  | ||||||
|         proportions: 1, |  | ||||||
|         proportionsMax: Math.min(50, item.system.quantite), |  | ||||||
|         ajouterEquipement: true |  | ||||||
|       }; |  | ||||||
|       await this._rollArt(artData, 'odoratgout', nourriture, async (cuisine) => { |  | ||||||
|         await this._resultRecetteCuisine(cuisine); |  | ||||||
|         const remaining = Math.max(item.system.quantite - cuisine.proportions, 0); |  | ||||||
|         if (remaining > 0) { |  | ||||||
|           await item.update({ 'system.quantite': remaining }) |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|           await this.deleteEmbeddedDocuments('Item', [item.id]); |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollJeu(id) { |   async rollJeu(id) { | ||||||
|     const oeuvre = this.getJeu(id); |     const oeuvre = this.getJeu(id); | ||||||
| @@ -2081,14 +2008,9 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]); |     listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]); | ||||||
|     artData.competence.system.niveauReel = artData.competence.system.niveau; |     artData.competence.system.niveauReel = artData.competence.system.niveau; | ||||||
|     artData.competence.system.niveau = Math.max(artData.competence.system.niveau, oeuvre.system.base); |     artData.competence.system.niveau = Math.max(artData.competence.system.niveau, oeuvre.system.base); | ||||||
|     await this._rollArt(artData, carac, oeuvre); |     await this._rollArtV1(artData, carac, oeuvre); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async rollOeuvre(id) { |  | ||||||
|     const artData = { art: 'oeuvre', verbe: 'Interpréter' } |  | ||||||
|     const oeuvre = foundry.utils.duplicate(this.findItemLike(id, artData.art)) |  | ||||||
|     await this._rollArt(artData, oeuvre.system.default_carac, oeuvre) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollMeditation(id) { |   async rollMeditation(id) { | ||||||
| @@ -2122,7 +2044,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     if (meditationRoll.rolled.isSuccess) { |     if (meditationRoll.rolled.isSuccess) { | ||||||
|       await this.createEmbeddedDocuments("Item", [RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditationRoll.meditation, meditationRoll.rolled)]); |       await this.createEmbeddedDocuments("Item", [RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditationRoll.meditation, meditationRoll.rolled)]); | ||||||
|     } |     } | ||||||
|     if (meditationRoll.rolled.isEPart){ |     if (meditationRoll.rolled.isEPart) { | ||||||
|       await this.updateEmbeddedDocuments('Item', [{ _id: meditationRoll.meditation._id, 'system.malus': meditationRoll.meditation.system.malus - 1 }]); |       await this.updateEmbeddedDocuments('Item', [{ _id: meditationRoll.meditation._id, 'system.malus': meditationRoll.meditation.system.malus - 1 }]); | ||||||
|     } |     } | ||||||
|     await this.santeIncDec("fatigue", 2); |     await this.santeIncDec("fatigue", 2); | ||||||
| @@ -2432,7 +2354,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|       this.tmrApp.forceTMRDisplay() |       this.tmrApp.forceTMRDisplay() | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     if (mode != 'visu' && this.getEffect(STATUSES.StatusDemiReve)) { |     if (mode != 'visu' && this.isDemiReve()) { | ||||||
|       ui.notifications.warn("Les personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation") |       ui.notifications.warn("Les personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation") | ||||||
|       mode = "visu"; // bascule le mode en visu automatiquement |       mode = "visu"; // bascule le mode en visu automatiquement | ||||||
|     } |     } | ||||||
| @@ -2712,8 +2634,11 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   listeSuivants(filter = suivant => true) { |   listeSuivants(filter = suivant => true) { | ||||||
|     return RdDActor.$buildSubActorLinks( |     return RdDActor.$buildSubActorLinks( | ||||||
|       this.system.subacteurs.suivants.filter(filter), RdDActor.$transformSubActeurSuivant |       this.system.subacteurs.suivants, RdDActor.$transformSubActeurSuivant | ||||||
|     ) |     ).filter(filter) | ||||||
|  |   } | ||||||
|  |   listeAmoureux() { | ||||||
|  |     return this.listeSuivants(it => it.coeur > 0 && it.type == ACTOR_TYPES.personnage) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getSuivant(subActorId) { |   getSuivant(subActorId) { | ||||||
| @@ -3123,5 +3048,204 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     await incarnation.remiseANeuf(); |     await incarnation.remiseANeuf(); | ||||||
|     incarnation.sheet.render(true); |     incarnation.sheet.render(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   async _rollArtV2(oeuvreId, callbackAction = async (actor, rd) => await actor._resultArtV2(rd)) { | ||||||
|  |     const oeuvre = this.items.get(oeuvreId) | ||||||
|  |     const rollData = { | ||||||
|  |       title: `Interpretation de ${oeuvre.name} par ${this.name}`, | ||||||
|  |       mode: { | ||||||
|  |         allowed: ["oeuvre"] | ||||||
|  |       }, | ||||||
|  |       selected: { | ||||||
|  |         mode: "oeuvre", | ||||||
|  |         oeuvre: { key: oeuvre.id }, | ||||||
|  |       }, | ||||||
|  |       ids: { | ||||||
|  |         actorId: this.id | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     await RollDialog.create(rollData, { | ||||||
|  |       onRoll: (dialog) => { | ||||||
|  |         this._onCloseRollDialog(), | ||||||
|  |           dialog.close() | ||||||
|  |       }, | ||||||
|  |       customChatMessage: true, | ||||||
|  |       callbacks: [callbackAction] | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _resultArtV2(artData) { | ||||||
|  |     const niveau = artData.oeuvre.system.niveau ?? 0; | ||||||
|  |     const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau); | ||||||
|  |     artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite; | ||||||
|  |  | ||||||
|  |     await RdDRollResult.displayRollData(artData, this.name, `chat-resultat-${artData.art}.hbs`); | ||||||
|  |   } | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |  | ||||||
|  |   async rollOeuvre(id) { | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       return await this._rollArtV2(id) | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       const artData = { art: 'oeuvre', verbe: 'Interpréter' } | ||||||
|  |       const oeuvre = foundry.utils.duplicate(this.findItemLike(id, artData.art)) | ||||||
|  |       await this._rollArtV1(artData, oeuvre.system.default_carac, oeuvre) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async rollChant(id) { | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       await this._rollArtV2(id) | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       const artData = { art: 'chant', verbe: 'Chanter' } | ||||||
|  |       const oeuvre = foundry.utils.duplicate(this.getChant(id)) | ||||||
|  |       await this._rollArtV1(artData, "ouie", oeuvre) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async rollDanse(id) { | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       await this._rollArtV2(id) | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       const artData = { art: 'danse', verbe: 'Danser', forceCarac: {} } | ||||||
|  |       const oeuvre = foundry.utils.duplicate(this.findItemLike(id, artData.art)) | ||||||
|  |       let selectedCarac = this.getCompetence(oeuvre.system.competence)?.system.defaut_carac | ||||||
|  |       if (oeuvre.system.apparence) { | ||||||
|  |         artData.forceCarac['apparence'] = foundry.utils.duplicate(this.system.carac.apparence) | ||||||
|  |         selectedCarac = "apparence" | ||||||
|  |       } | ||||||
|  |       if (oeuvre.system.agilite) { | ||||||
|  |         artData.forceCarac['agilite'] = foundry.utils.duplicate(this.system.carac.agilite) | ||||||
|  |         selectedCarac = "agilite" | ||||||
|  |       } | ||||||
|  |       await this._rollArtV1(artData, selectedCarac, oeuvre) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async rollMusique(id) { | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       await this._rollArtV2(id) | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       const artData = { art: 'musique', verbe: 'Jouer' } | ||||||
|  |       const oeuvre = this.findItemLike(id, artData.art) | ||||||
|  |       await this._rollArtV1(artData, "ouie", oeuvre) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   async _rollArtV1(artData, selected, oeuvre, callbackAction = async r => await this._resultArt(r)) { | ||||||
|  |     oeuvre.system.niveau = oeuvre.system.niveau ?? 0; | ||||||
|  |     foundry.utils.mergeObject(artData, | ||||||
|  |       { | ||||||
|  |         oeuvre: oeuvre, | ||||||
|  |         art: oeuvre.type, | ||||||
|  |         competence: foundry.utils.duplicate(this.getCompetence(artData.compName ?? oeuvre.system.competence ?? artData.art)), | ||||||
|  |         diffLibre: - oeuvre.system.niveau, | ||||||
|  |         diffConditions: 0, | ||||||
|  |         use: { libre: false, conditions: true, surenc: false }, | ||||||
|  |         selectedCarac: foundry.utils.duplicate(this.system.carac[selected]) | ||||||
|  |       }, | ||||||
|  |       { overwrite: false }); | ||||||
|  |     artData.competence.system.defaut_carac = selected; | ||||||
|  |     if (!artData.forceCarac) { | ||||||
|  |       artData.forceCarac = {}; | ||||||
|  |       artData.forceCarac[selected] = foundry.utils.duplicate(this.system.carac[selected]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     await this.openRollDialog({ | ||||||
|  |       name: `jet-${artData.art}`, | ||||||
|  |       label: `${artData.verbe} ${oeuvre.name}`, | ||||||
|  |       template: `systems/foundryvtt-reve-de-dragon/templates/dialog-roll-${oeuvre.type}.hbs`, | ||||||
|  |       rollData: artData, | ||||||
|  |       callbacks: [{ action: callbackAction }], | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _resultArt(artData) { | ||||||
|  |     const niveau = artData.oeuvre.system.niveau ?? 0; | ||||||
|  |     const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau); | ||||||
|  |     artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite; | ||||||
|  |  | ||||||
|  |     await RdDRollResult.displayRollData(artData, this.name, `chat-resultat-${artData.art}.hbs`); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   async rollRecetteCuisine(id) { | ||||||
|  |     const oeuvre = this.getRecetteCuisine(id); | ||||||
|  |     const artData = { | ||||||
|  |       verbe: 'Cuisiner', | ||||||
|  |       compName: 'cuisine', | ||||||
|  |       proportions: 1, | ||||||
|  |       ajouterEquipement: false | ||||||
|  |     }; | ||||||
|  |     await this._rollArtV1(artData, 'odoratgout', oeuvre, r => this._resultRecetteCuisine(r)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   async _resultRecetteCuisine(cuisine) { | ||||||
|  |     const niveauRecette = cuisine.oeuvre.system.niveau ?? 0; | ||||||
|  |     const baseQualite = (cuisine.rolled.isSuccess ? niveauRecette : cuisine.competence.system.niveau); | ||||||
|  |     cuisine.qualiteFinale = Math.min(baseQualite, niveauRecette) + cuisine.rolled.ptQualite; | ||||||
|  |     cuisine.exotismeFinal = Math.min(Math.min(cuisine.qualiteFinale, cuisine.oeuvre.system.exotisme ?? 0), 0); | ||||||
|  |     cuisine.sust = cuisine.oeuvre.system.sust * Math.min(cuisine.proportions, cuisine.proportionsMax ?? cuisine.proportions) | ||||||
|  |     const platCuisine = { | ||||||
|  |       name: cuisine.oeuvre.name, | ||||||
|  |       type: 'nourritureboisson', | ||||||
|  |       img: 'systems/foundryvtt-reve-de-dragon/icons/objets/provision_cuite.webp', | ||||||
|  |       system: { | ||||||
|  |         "description": cuisine.oeuvre.system.description, | ||||||
|  |         "sust": 1, | ||||||
|  |         "qualite": cuisine.qualiteFinale, | ||||||
|  |         "exotisme": cuisine.exotismeFinal, | ||||||
|  |         "encombrement": 0.1, | ||||||
|  |         "quantite": Math.max(1, Math.floor(cuisine.sust)), | ||||||
|  |         "cout": Math.max(cuisine.qualiteFinale) * 0.01 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     if (cuisine.ajouterEquipement) { | ||||||
|  |       await this.createEmbeddedDocuments('Item', [platCuisine]); | ||||||
|  |       ui.notifications.info(`${platCuisine.system.quantite} rations de ${platCuisine.name} ont été ajoutés à votre équipement`); | ||||||
|  |     } | ||||||
|  |     cuisine.platCuisine = platCuisine; | ||||||
|  |     await RdDRollResult.displayRollData(cuisine, this.name, `chat-resultat-${cuisine.art}.hbs`); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async preparerNourriture(item) { | ||||||
|  |     if (item.getUtilisationCuisine() == 'brut') { | ||||||
|  |       const nourriture = { | ||||||
|  |         name: 'Plat de ' + item.name, | ||||||
|  |         type: 'recettecuisine', | ||||||
|  |         img: item.img, | ||||||
|  |         system: { | ||||||
|  |           sust: item.system.sust, | ||||||
|  |           exotisme: item.system.exotisme, | ||||||
|  |           ingredients: item.name | ||||||
|  |         } | ||||||
|  |       }; | ||||||
|  |       const artData = { | ||||||
|  |         verbe: 'Préparer', | ||||||
|  |         compName: 'cuisine', | ||||||
|  |         proportions: 1, | ||||||
|  |         proportionsMax: Math.min(50, item.system.quantite), | ||||||
|  |         ajouterEquipement: true | ||||||
|  |       }; | ||||||
|  |       await this._rollArtV1(artData, 'odoratgout', nourriture, async (cuisine) => { | ||||||
|  |         await this._resultRecetteCuisine(cuisine); | ||||||
|  |         const remaining = Math.max(item.system.quantite - cuisine.proportions, 0); | ||||||
|  |         if (remaining > 0) { | ||||||
|  |           await item.update({ 'system.quantite': remaining }) | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |           await this.deleteEmbeddedDocuments('Item', [item.id]); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,15 +8,16 @@ import { RdDUtility } from "../rdd-utility.js"; | |||||||
| import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | ||||||
| import { RdDBaseActor } from "./base-actor.js"; | import { RdDBaseActor } from "./base-actor.js"; | ||||||
| import { ITEM_TYPES } from "../constants.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { RdDItemCompetence } from "../item-competence.js"; | import { StatusEffects, STATUSES } from "../settings/status-effects.js"; | ||||||
| import { RdDItemCompetenceCreature } from "../item-competencecreature.js"; |  | ||||||
| import { RdDItemArme } from "../item-arme.js"; |  | ||||||
| import { StatusEffects } from "../settings/status-effects.js"; |  | ||||||
| import { Targets } from "../targets.js"; | import { Targets } from "../targets.js"; | ||||||
| import { RdDConfirm } from "../rdd-confirm.js"; | import { RdDConfirm } from "../rdd-confirm.js"; | ||||||
| import { RdDCarac } from "../rdd-carac.js"; | import { RdDCarac } from "../rdd-carac.js"; | ||||||
| import { RdDRollResult } from "../rdd-roll-result.js"; | import { RdDRollResult } from "../rdd-roll-result.js"; | ||||||
|  |  | ||||||
|  | import { RdDItemCompetence } from "../item-competence.js"; | ||||||
|  | import { RdDItemCompetenceCreature } from "../item-competencecreature.js"; | ||||||
|  | import { RdDItemArme } from "../item/arme.js"; | ||||||
|  |  | ||||||
| import { ChatUtility } from "../chat-utility.js"; | import { ChatUtility } from "../chat-utility.js"; | ||||||
| import { DialogValidationEncaissement } from "../dialog-validation-encaissement.js"; | import { DialogValidationEncaissement } from "../dialog-validation-encaissement.js"; | ||||||
| import { RdDCombat } from "../rdd-combat.js"; | import { RdDCombat } from "../rdd-combat.js"; | ||||||
| @@ -79,6 +80,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   getBonusDegat() { return RdDCarac.getCaracDerivee(this.getEncombrementMax()).plusdom } |   getBonusDegat() { return RdDCarac.getCaracDerivee(this.getEncombrementMax()).plusdom } | ||||||
|  |  | ||||||
|   getMoralTotal() { return 0 } |   getMoralTotal() { return 0 } | ||||||
|  |   listeAmoureux() {return []} | ||||||
|   getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) } |   getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) } | ||||||
|   getSConst() { return 0 } |   getSConst() { return 0 } | ||||||
|  |  | ||||||
| @@ -108,10 +110,11 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     } |     } | ||||||
|     return this.system.carac[competence.system.defaut_carac].value; |     return this.system.carac[competence.system.defaut_carac].value; | ||||||
|   } |   } | ||||||
|   listActionsCombat() { |  | ||||||
|  |   listActions({ isAttaque = false, isEquipe = false }) { | ||||||
|     return this.itemTypes[ITEM_TYPES.competencecreature] |     return this.itemTypes[ITEM_TYPES.competencecreature] | ||||||
|       .filter(it => RdDItemCompetenceCreature.isAttaque(it)) |       .filter(it => RdDItemCompetenceCreature.isAttaque(it)) | ||||||
|       .map(it => RdDItemCompetenceCreature.armeCreature(it)) |       .map(it => RdDItemCompetenceCreature.attaqueCreature(it)) | ||||||
|       .filter(it => it != undefined); |       .filter(it => it != undefined); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -164,11 +167,16 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     if (idOrName instanceof Item) { |     if (idOrName instanceof Item) { | ||||||
|       return idOrName.isCompetence() ? idOrName : undefined |       return idOrName.isCompetence() ? idOrName : undefined | ||||||
|     } |     } | ||||||
|     return RdDItemCompetence.findCompetence(this.items, idOrName, options) |     return RdDItemCompetence.findCompetence( | ||||||
|  |       this.items.filter(it => [ITEM_TYPES.competence, ITEM_TYPES.competencecreature].includes(it.type)), | ||||||
|  |       idOrName, options) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getCompetences(name, options = { onMessage: message => { } }) { |   getCompetences(name = undefined, options = { onMessage: message => { } }) { | ||||||
|     return RdDItemCompetence.findCompetences(this.items, name, options) |     if (name == undefined) { | ||||||
|  |       return this.itemTypes[ITEM_TYPES.competence] | ||||||
|  |     } | ||||||
|  |     return RdDItemCompetence.findCompetences(this.itemTypes[ITEM_TYPES.competence], name, options) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getCompetenceCorpsACorps(options = { onMessage: message => { } }) { |   getCompetenceCorpsACorps(options = { onMessage: message => { } }) { | ||||||
| @@ -218,27 +226,24 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     return this.getEmbeddedCollection("ActiveEffect").filter(filter); |     return this.getEmbeddedCollection("ActiveEffect").filter(filter); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getEffect(effectId) { |   getEffectByStatus(statusId) { | ||||||
|     return this.getEmbeddedCollection("ActiveEffect").find(it => it.statuses?.has(effectId)); |     return this.getEffects().find(it => it.statuses.has(statusId)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async setEffect(effectId, status) { |   async setEffect(statusId, status) { | ||||||
|     if (this.isEffectAllowed(effectId)) { |     if (this.isEffectAllowed(statusId)) { | ||||||
|       const effect = this.getEffect(effectId); |       const effect = this.getEffectByStatus(statusId); | ||||||
|       if (!status && effect) { |       if (!status && effect) { | ||||||
|         await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]); |         await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]); | ||||||
|       } |       } | ||||||
|       if (status && !effect) { |       if (status && !effect) { | ||||||
|         await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.prepareActiveEffect(effectId)]); |         await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.prepareActiveEffect(statusId)]); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async removeEffect(id) { |   async removeEffect(id) { | ||||||
|     const effect = this.getEmbeddedCollection("ActiveEffect").find(it => it.id == id); |     this.removeEffects(it => it.id == id) | ||||||
|     if (effect) { |  | ||||||
|       await this.deleteEmbeddedDocuments('ActiveEffect', [id]); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async removeEffects(filter = e => true) { |   async removeEffects(filter = e => true) { | ||||||
| @@ -249,17 +254,16 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|  |   isDemiReve() { | ||||||
|  |     return this.getEffectByStatus(STATUSES.StatusDemiReve) != undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|   getSurprise(isCombat = undefined) { |   getSurprise(isCombat = undefined) { | ||||||
|     let niveauSurprise = this.getEffects() |     return StatusEffects.typeSurprise( | ||||||
|       .map(effect => StatusEffects.valeurSurprise(effect, isCombat)) |       this.getEffects() | ||||||
|       .reduce(Misc.sum(), 0); |         .map(it => StatusEffects.niveauSurprise(it, isCombat)) | ||||||
|     if (niveauSurprise > 1) { |         .reduce(Misc.sum(), 0) | ||||||
|       return 'totale'; |     ) | ||||||
|     } |  | ||||||
|     if (niveauSurprise == 1) { |  | ||||||
|       return 'demi'; |  | ||||||
|     } |  | ||||||
|     return ''; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -277,8 +281,20 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     return dialog |     return dialog | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   createCallbackExperience() { return { action: r => { } } } |  | ||||||
|   createCallbackAppelAuMoral() { return { action: r => { } } } |   /* -------------------------------------------- */ | ||||||
|  |   createCallbackExperience() { | ||||||
|  |     return { action: r => this.appliquerAjoutExperience(r) } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   createCallbackAppelAuMoral() { | ||||||
|  |     /* Si l'appel au moral est utilisé, on l'affiche dans le chat et on diminue éventuellement le moral */ | ||||||
|  |     return { action: r => this.appliquerAppelMoral(r) } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { } | ||||||
|  |   async appliquerAppelMoral(rollData) { } | ||||||
|  |  | ||||||
|   async _onCloseRollDialog(html) { } |   async _onCloseRollDialog(html) { } | ||||||
|  |  | ||||||
| @@ -341,6 +357,9 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     const selectedCaracName = ['apparence', 'perception', 'force', 'reve'].find(it => carac[it] != undefined) |     const selectedCaracName = ['apparence', 'perception', 'force', 'reve'].find(it => carac[it] != undefined) | ||||||
|  |  | ||||||
|     await this.openRollDialog({ |     await this.openRollDialog({ | ||||||
|  |       name: 'jet-quelconque', | ||||||
|  |       label: 'Jet', | ||||||
|  |       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll.hbs', | ||||||
|       rollData: { |       rollData: { | ||||||
|         alias: this.getAlias(), |         alias: this.getAlias(), | ||||||
|         carac: carac, |         carac: carac, | ||||||
| @@ -430,9 +449,9 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|    * @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession |    * @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession | ||||||
|    * @returns  |    * @returns  | ||||||
|    */ |    */ | ||||||
|   rollArme(arme, categorieArme, token) { |   rollArme(arme, categorieArme = 'competence', token = undefined) { | ||||||
|     token = token ?? RdDUtility.getSelectedToken(this) |     token = token ?? RdDUtility.getSelectedToken(this) | ||||||
|     const compToUse = this.$getCompetenceArme(arme, categorieArme) |     const compToUse = RdDItemArme.getCompetenceArme(arme, categorieArme) | ||||||
|     if (!RdDItemArme.isUtilisable(arme)) { |     if (!RdDItemArme.isUtilisable(arme)) { | ||||||
|       ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`) |       ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`) | ||||||
|       return |       return | ||||||
| @@ -466,10 +485,6 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   $getCompetenceArme(arme, competenceName) { |  | ||||||
|     return RdDItemArme.getCompetenceArme(arme, competenceName) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   verifierForceMin(item) { } |   verifierForceMin(item) { } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -292,7 +292,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   isSonne() { |   isSonne() { | ||||||
|     return this.getEffect(STATUSES.StatusStunned) |     return this.getEffectByStatus(STATUSES.StatusStunned) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isEffectAllowed(effectId) { return true } |   isEffectAllowed(effectId) { return true } | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ export class RdDBaseActor extends Actor { | |||||||
|     } |     } | ||||||
|     return entry && entry.length > 0 ? carac[entry[0]] : undefined; |     return entry && entry.length > 0 ? carac[entry[0]] : undefined; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getDefaultValue(actorType, path) { |   static getDefaultValue(actorType, path) { | ||||||
|     if (path.includes('.')) { |     if (path.includes('.')) { | ||||||
|       path = path.split('.') |       path = path.split('.') | ||||||
| @@ -213,6 +214,7 @@ export class RdDBaseActor extends Actor { | |||||||
|   isCreatureEntite() { return this.isCreature() || this.isEntite() } |   isCreatureEntite() { return this.isCreature() || this.isEntite() } | ||||||
|   isCreature() { return false } |   isCreature() { return false } | ||||||
|   isEntite(typeentite = []) { return false } |   isEntite(typeentite = []) { return false } | ||||||
|  |   isHautRevant() { return false } | ||||||
|   isVehicule() { return false } |   isVehicule() { return false } | ||||||
|   isPersonnage() { return false } |   isPersonnage() { return false } | ||||||
|   getItem(id, type = undefined) { |   getItem(id, type = undefined) { | ||||||
| @@ -742,6 +744,7 @@ export class RdDBaseActor extends Actor { | |||||||
|     ui.notifications.info(`${this.getAlias()} ne peut pas faire cette action: ${action}`) |     ui.notifications.info(`${this.getAlias()} ne peut pas faire cette action: ${action}`) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   isAlcoolise() { return false } | ||||||
|   async jetEthylisme() { this.actionImpossible("jet d'éthylisme") } |   async jetEthylisme() { this.actionImpossible("jet d'éthylisme") } | ||||||
|   async rollAppelChance() { this.actionImpossible("appel à la chance") } |   async rollAppelChance() { this.actionImpossible("appel à la chance") } | ||||||
|   async jetDeMoral() { this.actionImpossible("jet de moral") } |   async jetDeMoral() { this.actionImpossible("jet de moral") } | ||||||
| @@ -754,18 +757,21 @@ export class RdDBaseActor extends Actor { | |||||||
|   isActorCombat() { return false } |   isActorCombat() { return false } | ||||||
|   getCaracInit(competence) { return 0 } |   getCaracInit(competence) { return 0 } | ||||||
|  |  | ||||||
|   listActionsCombat() { return [] } |   listAttaques() { | ||||||
|  |     return this.listActions({ isAttaque: true, isEquipe:false }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   listActions({ isAttaque = false, isEquipe=false }) { return [] } | ||||||
|  |  | ||||||
|   listActionsPossessions() { |   listActionsPossessions() { | ||||||
|     return this.itemTypes[ITEM_TYPES.possession] |     return this.itemTypes[ITEM_TYPES.possession] | ||||||
|       .map(p => { |       .map(p => { | ||||||
|         return { |         return { | ||||||
|           name: p.name, |           name: p.name, | ||||||
|           action: 'possession', |           action: 'possession', | ||||||
|           system: { |  | ||||||
|             competence: p.name, |  | ||||||
|           possessionid: p.system.possessionid, |           possessionid: p.system.possessionid, | ||||||
|         } |         } | ||||||
|         } |  | ||||||
|       }) |       }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -1,6 +1,4 @@ | |||||||
| import { DialogItemAchat } from "../achat-vente/dialog-item-achat.js"; |  | ||||||
| import { RdDItem } from "../item.js"; | import { RdDItem } from "../item.js"; | ||||||
| import { RdDUtility } from "../rdd-utility.js"; |  | ||||||
| import { RdDBaseActorSheet } from "./base-actor-sheet.js"; | import { RdDBaseActorSheet } from "./base-actor-sheet.js"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -44,13 +42,8 @@ export class RdDCommerceSheet extends RdDBaseActorSheet { | |||||||
|   activateListeners(html) { |   activateListeners(html) { | ||||||
|     super.activateListeners(html); |     super.activateListeners(html); | ||||||
|  |  | ||||||
|     this.html.find('a.item-acheter').click(async event => await this.vente(this.getItem(event))); |  | ||||||
|     this.html.find('.service-acheter').click(async event => await this.vente(this.getItem(event))); |  | ||||||
|  |  | ||||||
|     if (!this.options.editable) return; |     if (!this.options.editable) return; | ||||||
|  |  | ||||||
|     this.html.find('a.item-quantite-moins').click(async event => await this.getItem(event)?.quantiteIncDec(-1, { supprimerSiZero: false })); |  | ||||||
|     this.html.find('a.item-quantite-plus').click(async event => await this.getItem(event)?.quantiteIncDec(1)); |  | ||||||
|     this.html.find('input.item-quantite').change(async event => { |     this.html.find('input.item-quantite').change(async event => { | ||||||
|       const newQuantite = Math.max(0, Number.parseInt(this.html.find(event.currentTarget).val())); |       const newQuantite = Math.max(0, Number.parseInt(this.html.find(event.currentTarget).val())); | ||||||
|       await this.getItem(event)?.update({ "system.quantite": newQuantite }); |       await this.getItem(event)?.update({ "system.quantite": newQuantite }); | ||||||
| @@ -64,28 +57,4 @@ export class RdDCommerceSheet extends RdDBaseActorSheet { | |||||||
|   getTypesInventaire() { |   getTypesInventaire() { | ||||||
|     return RdDItem.getItemTypesInventaire('all'); |     return RdDItem.getItemTypesInventaire('all'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   async vente(item) { |  | ||||||
|     const acheteur = RdDUtility.getSelectedActor(); |  | ||||||
|     if (!acheteur) { |  | ||||||
|       ui.notifications.warn(`Pas d'acheteur sélectionné`); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     const disponible = this.actor.getQuantiteDisponible(item) |  | ||||||
|     if (disponible == 0) { |  | ||||||
|       ui.notifications.warn(`${this.getAlias()} n'a plus de ${item.name} en vente`); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     await DialogItemAchat.onAcheter({ |  | ||||||
|       item, |  | ||||||
|       vendeur: this.actor, |  | ||||||
|       acheteur, |  | ||||||
|       quantiteIllimite: disponible == undefined, |  | ||||||
|       nbLots: disponible ?? 1, |  | ||||||
|       tailleLot: 1, |  | ||||||
|       prixLot: item.calculerPrixCommercant() |  | ||||||
|     }); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,6 @@ | |||||||
|  | import { DialogItemAchat } from "../achat-vente/dialog-item-achat.js"; | ||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
|  | import { RdDUtility } from "../rdd-utility.js"; | ||||||
| import { RdDBaseActor } from "./base-actor.js"; | import { RdDBaseActor } from "./base-actor.js"; | ||||||
|  |  | ||||||
| export class RdDCommerce extends RdDBaseActor { | export class RdDCommerce extends RdDBaseActor { | ||||||
| @@ -37,4 +39,27 @@ export class RdDCommerce extends RdDBaseActor { | |||||||
|     const pourcentage = this.system.pourcentage ?? 100; |     const pourcentage = this.system.pourcentage ?? 100; | ||||||
|     return Misc.keepDecimals(Math.ceil(item.system.cout * pourcentage) / 100, 2); |     return Misc.keepDecimals(Math.ceil(item.system.cout * pourcentage) / 100, 2); | ||||||
|   } |   } | ||||||
|  |   async vente(item) { | ||||||
|  |     const acheteur = RdDUtility.getSelectedActor(); | ||||||
|  |     if (!acheteur) { | ||||||
|  |       ui.notifications.warn(`Pas d'acheteur sélectionné`); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     const disponible = this.getQuantiteDisponible(item) | ||||||
|  |     if (disponible == 0) { | ||||||
|  |       ui.notifications.warn(`${this.getAlias()} n'a plus de ${item.name} en vente`); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     await DialogItemAchat.onAcheter({ | ||||||
|  |       item, | ||||||
|  |       vendeur: this, | ||||||
|  |       acheteur, | ||||||
|  |       quantiteIllimite: disponible == undefined, | ||||||
|  |       nbLots: disponible ?? 1, | ||||||
|  |       tailleLot: 1, | ||||||
|  |       prixLot: item.calculerPrixCommercant() | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |    | ||||||
| } | } | ||||||
| @@ -9,6 +9,7 @@ export class RdDActorExportSheet extends RdDActorSheet { | |||||||
|   static init() { |   static init() { | ||||||
|     foundry.applications.handlebars.loadTemplates([ |     foundry.applications.handlebars.loadTemplates([ | ||||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs", |       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme.hbs", | ||||||
|  |       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/arme-titre.hbs", | ||||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs", |       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessure.hbs", | ||||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs", |       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/blessures.hbs", | ||||||
|       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs", |       "systems/foundryvtt-reve-de-dragon/templates/actor/export-scriptarium/carac.hbs", | ||||||
| @@ -41,6 +42,7 @@ export class RdDActorExportSheet extends RdDActorSheet { | |||||||
|     const formData = await super.getData() |     const formData = await super.getData() | ||||||
|     // Add any structured, precomputed list of data |     // Add any structured, precomputed list of data | ||||||
|     formData.context = Mapping.prepareContext(this.actor) |     formData.context = Mapping.prepareContext(this.actor) | ||||||
|  |     formData.attaques = this.actor.listActionsAttaque() | ||||||
|     formData.export = this.getMappingValues(formData.context, this.actor) |     formData.export = this.getMappingValues(formData.context, this.actor) | ||||||
|     formData.competences = this.getCompetences(CATEGORIES_COMPETENCES) |     formData.competences = this.getCompetences(CATEGORIES_COMPETENCES) | ||||||
|     formData.draconic = this.getCompetences(CATEGORIES_DRACONIC) |     formData.draconic = this.getCompetences(CATEGORIES_DRACONIC) | ||||||
|   | |||||||
| @@ -12,14 +12,18 @@ export class ExportScriptarium { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   constructor() { |   constructor() { | ||||||
|     Hooks.on("getActorDirectoryFolderContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) }) |     //Hooks.on("getActorDirectoryFolderContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) }) | ||||||
|     Hooks.on("getActorDirectoryEntryContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) }) |     Hooks.on("getFolderContextOptions", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) }) | ||||||
|  |     //Hooks.on("getActorDirectoryEntryContext", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) }) | ||||||
|  |     Hooks.on("getActorContextOptions", (actorDirectory, menus) => { ExportScriptarium.INSTANCE.onActorDirectoryMenu(actorDirectory, menus) }) | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   onActorDirectoryMenu(actorDirectory, menus) { |   onActorDirectoryMenu(actorDirectory, menus) { | ||||||
|  |     // DEBUG console.log("ExportScriptarium.onActorDirectoryMenu", actorDirectory, menus) | ||||||
|     menus.push({ |     menus.push({ | ||||||
|       name: 'Export Personnages <i class="fa-regular fa-file-csv"></i>', |       name: 'Export Personnages', | ||||||
|       icon: IMG_SCRIPTARIUM, |       icon: '<i class="fa-solid fa-download"></i>', //IMG_SCRIPTARIUM, | ||||||
|       condition: (target) => game.user.isGM && |       condition: (target) => game.user.isGM && | ||||||
|         OptionsAvancees.isUsing(EXPORT_CSV_SCRIPTARIUM) && |         OptionsAvancees.isUsing(EXPORT_CSV_SCRIPTARIUM) && | ||||||
|         this.$getActors(actorDirectory, target).length > 0, |         this.$getActors(actorDirectory, target).length > 0, | ||||||
| @@ -28,22 +32,28 @@ export class ExportScriptarium { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   $getTargetName(actorDirectory, target) { |   $getTargetName(actorDirectory, target) { | ||||||
|  |     target = $(target) | ||||||
|     const li = target.closest(".directory-item") |     const li = target.closest(".directory-item") | ||||||
|     const folderId = li.data("folderId") |     const folderId = li.data("folderId") | ||||||
|     const actorId = li.data("documentId") |     const actorId = li.data("entryId") | ||||||
|     return actorId |     return actorId | ||||||
|       ? game.actors.get(actorId).name |       ? game.actors.get(actorId).name | ||||||
|       : actorDirectory.folders.find(it => it.id == folderId).name |       : actorDirectory.collection.filter(it => it.folder.id == folderId).name | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   $getActors(actorDirectory, target) { |   $getActors(actorDirectory, target) { | ||||||
|  |     if (actorDirectory.id != "actors") { | ||||||
|  |       return [] | ||||||
|  |     } | ||||||
|  |     // DEBUG console.log("ExportScriptarium.$getActors", actorDirectory, target) | ||||||
|  |     target = $(target) | ||||||
|     const li = target.closest(".directory-item") |     const li = target.closest(".directory-item") | ||||||
|     const folderId = li.data("folderId") |     const folderId = li.data("folderId") | ||||||
|     const actorId = li.data("documentId") |     const actorId = li.data("entryId") | ||||||
|     const actors = actorId |     const actors = actorId | ||||||
|       ? [game.actors.get(actorId)] |       ? [game.actors.get(actorId)] | ||||||
|       : folderId |       : folderId | ||||||
|         ? actorDirectory.folders.find(it => it.id == folderId).contents |         ? actorDirectory.collection.filter(it => it.folder.id == folderId) | ||||||
|         : [] |         : [] | ||||||
|     return actors.filter(it => it.type == ACTOR_TYPES.personnage) |     return actors.filter(it => it.type == ACTOR_TYPES.personnage) | ||||||
|   } |   } | ||||||
| @@ -54,7 +64,7 @@ export class ExportScriptarium { | |||||||
|     const actorLines = actors.map(actor => Misc.join(this.getActorLine(actor), ';')) |     const actorLines = actors.map(actor => Misc.join(this.getActorLine(actor), ';')) | ||||||
|     const data = Misc.join([header, ...actorLines], eol) |     const data = Misc.join([header, ...actorLines], eol) | ||||||
|     const filename = `scriptarium-${targetName?.slugify()}.csv`; |     const filename = `scriptarium-${targetName?.slugify()}.csv`; | ||||||
|     saveDataToFile(data, "text/csv;charset=windows-1252", `${filename}`); |     foundry.utils.saveDataToFile(data, "text/csv;charset=windows-1252", `${filename}`); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getHeaderLine() { |   getHeaderLine() { | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { Grammar } from "../../grammar.js" | import { Grammar } from "../../grammar.js" | ||||||
| import { RdDItemArme } from "../../item-arme.js" | import { RdDItemArme } from "../../item/arme.js" | ||||||
| import { RdDItemCompetence } from "../../item-competence.js" | import { RdDItemCompetence } from "../../item-competence.js" | ||||||
| import { RdDItemSort } from "../../item-sort.js" | import { RdDItemSort } from "../../item-sort.js" | ||||||
| import { ITEM_TYPES } from "../../constants.js" | import { ITEM_TYPES } from "../../constants.js" | ||||||
| @@ -144,7 +144,7 @@ export class Mapping { | |||||||
|     armes.push(RdDItemArme.corpsACorps(actor)); |     armes.push(RdDItemArme.corpsACorps(actor)); | ||||||
|     armes.push(RdDItemArme.empoignade(actor)); |     armes.push(RdDItemArme.empoignade(actor)); | ||||||
|     return armes.map(arme => [ |     return armes.map(arme => [ | ||||||
|       arme.system.unemain ? Mapping.prepareArme(actor, arme, 'unemain') : undefined, |       arme.system.unemain ? Mapping.prepareArme(actor, arme, '(1 main)') : undefined, | ||||||
|       arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined, |       arme.system.deuxmains ? Mapping.prepareArme(actor, arme, 'deuxmains') : undefined, | ||||||
|       !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined, |       !(arme.system.unemain || arme.system.deuxmains) ? Mapping.prepareArme(actor, arme, 'competence') : undefined, | ||||||
|       arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined, |       arme.system.lancer != "" ? Mapping.prepareArme(actor, arme, 'lancer') : undefined, | ||||||
| @@ -256,8 +256,8 @@ export class Mapping { | |||||||
|   static descriptionSort(sort) { |   static descriptionSort(sort) { | ||||||
|     const ptSeuil = Array(sort.system.coutseuil).map(it => '*') |     const ptSeuil = Array(sort.system.coutseuil).map(it => '*') | ||||||
|     const caseTMR = sort.system.caseTMRspeciale.length > 0 ? Mapping.toVar(sort.system.caseTMRspeciale) : Misc.upperFirst(TMRType[sort.system.caseTMR].name) |     const caseTMR = sort.system.caseTMRspeciale.length > 0 ? Mapping.toVar(sort.system.caseTMRspeciale) : Misc.upperFirst(TMRType[sort.system.caseTMR].name) | ||||||
|     const coutReve = 'r' + RdDItemSort.addSpaceToNonNumeric(sort.system.ptreve) |     const coutReve =RdDItemSort.coutReve(sort) | ||||||
|     const diff = 'R' + RdDItemSort.addSpaceToNonNumeric(sort.system.difficulte) |     const diff = RdDItemSort.diffReve(sort) | ||||||
|     return `${sort.name}${ptSeuil} (${caseTMR}) ${diff} ${coutReve}` |     return `${sort.name}${ptSeuil} (${caseTMR}) ${diff} ${coutReve}` | ||||||
|   } |   } | ||||||
|   static toVar(caseSpeciale) { |   static toVar(caseSpeciale) { | ||||||
|   | |||||||
| @@ -83,8 +83,8 @@ export class ChatUtility { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async createChatWithRollMode(messageData, actor = undefined) { |   static async createChatWithRollMode(messageData, actor = undefined, rollMode = game.settings.get("core", "rollMode")) { | ||||||
|     switch (game.settings.get("core", "rollMode")) { |     switch (rollMode) { | ||||||
|       case "blindroll": // GM only |       case "blindroll": // GM only | ||||||
|         if (!game.user.isGM) { |         if (!game.user.isGM) { | ||||||
|           ChatUtility.blindMessageToGM(messageData) |           ChatUtility.blindMessageToGM(messageData) | ||||||
|   | |||||||
| @@ -4,8 +4,7 @@ import { Misc } from "../misc.js" | |||||||
|  |  | ||||||
| export const ACTION_ITEM_ENCHANTER =  { | export const ACTION_ITEM_ENCHANTER =  { | ||||||
|   code: 'item-enchanter', label: 'Enchanter', icon: it => 'fa-solid fa-sparkles', |   code: 'item-enchanter', label: 'Enchanter', icon: it => 'fa-solid fa-sparkles', | ||||||
|   filter: it => game.user.isGM || DialogEnchanter.isEnchantable(it), |   filter: it => game.user.isGM || DialogEnchanter.isEnchantable(it) && it.parent?.type != ACTOR_TYPES.commerce, | ||||||
|   optionsFilter: options => options.editable, |  | ||||||
|   action: (item, actor) => DialogEnchanter.enchanter(item) |   action: (item, actor) => DialogEnchanter.enchanter(item) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								module/initiative.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,7 @@ | |||||||
|  | export class RdDInitiative { | ||||||
|  |  | ||||||
|  |   static calculInitiative(niveau, caracValue, bonus = 0) { | ||||||
|  |     let base = niveau + Math.floor(caracValue / 2) + bonus; | ||||||
|  |     return "1d6" + (base >= 0 ? "+" : "") + base; | ||||||
|  |   } | ||||||
|  | }  | ||||||
| @@ -103,8 +103,8 @@ export class RdDItemCompetence extends Item { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static isMalusEncombrementTotal(competence) { |   static isMalusEncombrementTotal(competenceName) { | ||||||
|     return competence?.name.toLowerCase().match(/(natation|acrobatie)/) || 0; |     return competenceName?.toLowerCase().match(/(natation|acrobatie)/) || 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
|  |  | ||||||
| import { ITEM_TYPES } from "./constants.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { RdDCombatManager } from "./rdd-combat.js"; | import { RdDInitiative } from "./initiative.mjs"; | ||||||
|  | import { RdDItem } from "./item.js"; | ||||||
|  |  | ||||||
| export const CATEGORIES_COMPETENCES_CREATURES = { | export const CATEGORIES_COMPETENCES_CREATURES = { | ||||||
|   "generale": { base: 0, label: "Générale" }, |   "generale": { base: 0, label: "Générale" }, | ||||||
| @@ -37,7 +38,7 @@ export class RdDItemCompetenceCreature extends Item { | |||||||
|           competence: item.name, |           competence: item.name, | ||||||
|           cac: categorieAttaque == "naturelle" ? "naturelle" : "", |           cac: categorieAttaque == "naturelle" ? "naturelle" : "", | ||||||
|           niveau: item.system.niveau, |           niveau: item.system.niveau, | ||||||
|           initiative: RdDCombatManager.calculInitiative(item.system.niveau, item.system.carac_value), |           initiative: RdDInitiative.calculInitiative(item.system.niveau, item.system.carac_value), | ||||||
|           equipe: true, |           equipe: true, | ||||||
|           resistance: 100, |           resistance: 100, | ||||||
|           dommagesReels: item.system.dommages, |           dommagesReels: item.system.dommages, | ||||||
| @@ -49,6 +50,44 @@ export class RdDItemCompetenceCreature extends Item { | |||||||
|     } |     } | ||||||
|     return undefined; |     return undefined; | ||||||
|   } |   } | ||||||
|  |   static attaqueCreature(comp) { | ||||||
|  |     const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(comp) | ||||||
|  |     if (categorieAttaque != undefined) { | ||||||
|  |       const initative = RdDInitiative.calculInitiative(comp.system.niveau, comp.system.carac_value); | ||||||
|  |       const armeComp = new RdDItem({ | ||||||
|  |         name: comp.name, | ||||||
|  |         type: ITEM_TYPES.arme, | ||||||
|  |         img: comp.img, | ||||||
|  |         system: { | ||||||
|  |           competence: comp.name, | ||||||
|  |           cac: categorieAttaque == "naturelle" ? "naturelle" : "", | ||||||
|  |           niveau: comp.system.niveau, | ||||||
|  |           initiative: initative, | ||||||
|  |           mortalite: comp.system.mortalite, | ||||||
|  |           dommages: comp.system.dommages, | ||||||
|  |           equipe: true, | ||||||
|  |           resistance: 100, | ||||||
|  |           penetration: 0, | ||||||
|  |           force: 0, | ||||||
|  |           rapide: true, | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |       const attaque = { | ||||||
|  |         name: comp.name, | ||||||
|  |         action: comp.isCompetencePossession() ? 'possession' : 'attaque', | ||||||
|  |         initOnly: false, | ||||||
|  |         arme: armeComp, | ||||||
|  |         comp: comp, | ||||||
|  |         carac: { key: comp.name, value: comp.system.carac_value }, | ||||||
|  |         equipe: true, | ||||||
|  |         mortalite: comp.system.mortalite, | ||||||
|  |         dmg: comp.system.dommages, | ||||||
|  |         initiative: initative | ||||||
|  |       }; | ||||||
|  |       return attaque | ||||||
|  |     } | ||||||
|  |     return undefined; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static isAttaque(item) { |   static isAttaque(item) { | ||||||
|   | |||||||
| @@ -16,13 +16,10 @@ export const VOIES_DRACONIC = [ | |||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RdDItemSort extends Item { | export class RdDItemSort extends Item { | ||||||
|   static preloadHandlebars() { |   static preloadHandlebars() { | ||||||
|     Handlebars.registerHelper('itemSort-spaceIfText', val => RdDItemSort.addSpaceToNonNumeric(val)) |  | ||||||
|     Handlebars.registerHelper('itemSort-codeDraconic', voie => RdDItemSort.getCode(voie)) |     Handlebars.registerHelper('itemSort-codeDraconic', voie => RdDItemSort.getCode(voie)) | ||||||
|     Handlebars.registerHelper('itemSort-shortDraconic', voie => RdDItemSort.getShortVoie(voie)) |     Handlebars.registerHelper('itemSort-shortDraconic', voie => RdDItemSort.getShortVoie(voie)) | ||||||
|   } |     Handlebars.registerHelper('itemSort-diffReve', sort => RdDItemSort.diffReve(sort)) | ||||||
|  |     Handlebars.registerHelper('itemSort-coutReve', sort => RdDItemSort.coutReve(sort)) | ||||||
|   static addSpaceToNonNumeric(value) { |  | ||||||
|     return Number.isNumeric(value) || ['-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(String(value).charAt[0]) ? value : ' ' + RdDItemSort.toVar(value) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static lancements(sort) { return sort?.system.lancements.length ?? 0 } |   static lancements(sort) { return sort?.system.lancements.length ?? 0 } | ||||||
| @@ -43,21 +40,44 @@ export class RdDItemSort extends Item { | |||||||
|     return value ? value.replace('variable', 'var') : '' |     return value ? value.replace('variable', 'var') : '' | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static isSortOnCoord(sort, coord) { | ||||||
|  |     let tmr = TMRUtility.getTMR(coord) | ||||||
|  |     const caseTMR = sort.system.caseTMR.toLowerCase(); | ||||||
|  |     const caseTMRspeciale = sort.system.caseTMRspeciale.toLowerCase(); | ||||||
|  |  | ||||||
|  |     return caseTMR.includes('variable') | ||||||
|  |       || caseTMRspeciale.includes('variable') | ||||||
|  |       || (caseTMR == tmr.type) | ||||||
|  |       || (caseTMR.includes('special') && caseTMRspeciale.includes(coord.toLowerCase())) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static getCaseTMR(sort) { | ||||||
|  |     const caseTMR = sort.system.caseTMR.toLowerCase(); | ||||||
|  |     const caseTMRspeciale = sort.system.caseTMRspeciale.toLowerCase(); | ||||||
|  |     if (caseTMR.includes('variable') || caseTMRspeciale.includes('variable') || caseTMR.includes('special')) { | ||||||
|  |       return sort.system.caseTMRspeciale | ||||||
|  |     } | ||||||
|  |     return sort.system.caseTMR | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   static diffReve(sort) { return RdDItemSort.toVar((sort.system.difficulte.match(/\-?(\d)+/) ? 'R' : 'R ') + sort.system.difficulte) } | ||||||
|  |   static coutReve(sort) { return RdDItemSort.toVar((sort.system.ptreve.match(/(\d)+\+?/) ? 'r' : 'r ') + sort.system.ptreve) } | ||||||
|   static getDraconicsSort(competencesDraconic, sort) { |   static getDraconicsSort(competencesDraconic, sort) { | ||||||
|     // se baser sur la voie du sort? |     // se baser sur la voie du sort? | ||||||
|     switch (Grammar.toLowerCaseNoAccent(sort.name)) { |     switch (Grammar.toLowerCaseNoAccent(sort.name)) { | ||||||
|       case "lecture d'aura": |       case "lecture d'aura": | ||||||
|       case "detection d'aura": |       case "detection d'aura": | ||||||
|         return competencesDraconic; |         return competencesDraconic | ||||||
|       case "annulation de magie": |       case "annulation de magie": | ||||||
|         return competencesDraconic.filter(it => !RdDItemCompetence.isThanatos(it)); |         return competencesDraconic.filter(it => !RdDItemCompetence.isThanatos(it)) | ||||||
|     } |     } | ||||||
|     const voies = sort.system.draconic.split('/') |     const voies = sort.system.draconic.split('/') | ||||||
|     return voies.map(voie => RdDItemCompetence.getVoieDraconic(competencesDraconic, voie)) |     return voies.map(voie => RdDItemCompetence.getVoieDraconic(competencesDraconic, voie)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getBestDraconicSort(competencesDraconic, sort) { |   static getBestDraconicSort(competencesDraconic, sort) { | ||||||
|     return  RdDItemSort.getDraconicsSort(competencesDraconic, sort).sort(Misc.descending(it => it.system.niveau)).find(it=>true) |     return RdDItemSort.getDraconicsSort(competencesDraconic, sort).sort(Misc.descending(it => it.system.niveau)).find(it => true) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getOrdreCode(code) { |   static getOrdreCode(code) { | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| import { ITEM_TYPES } from "./constants.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
| import { DialogItemVente } from "./achat-vente/dialog-item-vente.js"; |  | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
|  | import { DialogItemVente } from "./achat-vente/dialog-item-vente.js"; | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
| import { SystemCompendiums } from "./settings/system-compendiums.js"; | import { SystemCompendiums } from "./settings/system-compendiums.js"; | ||||||
| @@ -84,6 +85,7 @@ export const defaultItemImg = { | |||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RdDItem extends Item { | export class RdDItem extends Item { | ||||||
|  |    | ||||||
|   static get defaultIcon() { |   static get defaultIcon() { | ||||||
|     return undefined; |     return undefined; | ||||||
|   } |   } | ||||||
| @@ -95,12 +97,12 @@ export class RdDItem extends Item { | |||||||
|   static isFieldInventaireModifiable(type, field) { |   static isFieldInventaireModifiable(type, field) { | ||||||
|     switch (field) { |     switch (field) { | ||||||
|       case 'quantite': |       case 'quantite': | ||||||
|         if ([ITEM_TYPES.conteneur].includes(type)) { |         if (ITEM_TYPES.conteneur == type) { | ||||||
|           return false; |           return false; | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|       case 'cout': |       case 'cout': | ||||||
|         if ([ITEM_TYPES.monnaie].includes(type)) { |         if (ITEM_TYPES.monnaie == type) { | ||||||
|           return game.user.isGM; |           return game.user.isGM; | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|   | |||||||
| @@ -1,8 +1,10 @@ | |||||||
| import { Grammar } from "./grammar.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js" | import { RdDItem } from "../item.js"; | ||||||
| import { ITEM_TYPES } from "./constants.js"; | 
 | ||||||
| import { BASE_CORPS_A_CORPS } from "./item/base-items.js"; | import { RdDItemCompetenceCreature } from "../item-competencecreature.js" | ||||||
| import { RdDCombatManager } from "./rdd-combat.js"; | import { BASE_CORPS_A_CORPS } from "./base-items.js"; | ||||||
|  | import { Grammar } from "../grammar.js"; | ||||||
|  | import { RdDInitiative } from "../initiative.mjs"; | ||||||
| 
 | 
 | ||||||
| const nomCategorieParade = { | const nomCategorieParade = { | ||||||
|   "sans-armes": "Sans arme", |   "sans-armes": "Sans arme", | ||||||
| @@ -19,13 +21,21 @@ const nomCategorieParade = { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RdDItemArme extends Item { | export class RdDItemArme extends RdDItem { | ||||||
| 
 | 
 | ||||||
|   static isArme(item) { |   static get ITEM_TYPE() { return ITEM_TYPES.arme } | ||||||
|     return item.type == ITEM_TYPES.arme || RdDItemCompetenceCreature.getCategorieAttaque(item); | 
 | ||||||
|  |   static get defaultIcon() { | ||||||
|  |     return defaultItemImgArme | ||||||
|  |     //return "systems/foundryvtt-reve-de-dragon/icons/armes_armure/epee_sord.webp";
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   penetration() { | ||||||
|  |     return parseInt(this.system.penetration ?? 0); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|  | 
 | ||||||
|   static getArme(arme) { |   static getArme(arme) { | ||||||
|     switch (arme ? arme.type : '') { |     switch (arme ? arme.type : '') { | ||||||
|       case ITEM_TYPES.arme: return arme; |       case ITEM_TYPES.arme: return arme; | ||||||
| @@ -42,10 +52,10 @@ export class RdDItemArme extends Item { | |||||||
|       case ITEM_TYPES.arme: |       case ITEM_TYPES.arme: | ||||||
|         switch (maniement) { |         switch (maniement) { | ||||||
|           case 'competence': return arme.system.competence; |           case 'competence': return arme.system.competence; | ||||||
|           case 'unemain': return RdDItemArme.competence1Mains(arme); |           case '(1 main)': return arme.competence1Mains() | ||||||
|           case 'deuxmains': return RdDItemArme.competence2Mains(arme); |           case '(2 mains)': return arme.competence2Mains() | ||||||
|           case 'tir': return arme.system.tir; |           case '(tir)': case 'tir': return arme.system.tir | ||||||
|           case 'lancer': return arme.system.lancer; |           case '(lancer)': case 'lancer': return arme.system.lancer; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
| @@ -186,7 +196,7 @@ export class RdDItemArme extends Item { | |||||||
|         return Number(arme.system.dommages) |         return Number(arme.system.dommages) | ||||||
|       } |       } | ||||||
|       const tableauDegats = arme.system.dommages.split("/"); |       const tableauDegats = arme.system.dommages.split("/"); | ||||||
|       return Number(tableauDegats[maniement == 'unemain' ? 0 : 1]) |       return Number(tableauDegats[maniement == '(1 main)' ? 0 : 1]) | ||||||
|     } |     } | ||||||
|     return Number(arme.system.dommages); |     return Number(arme.system.dommages); | ||||||
|   } |   } | ||||||
| @@ -195,17 +205,17 @@ export class RdDItemArme extends Item { | |||||||
|   static armeUneOuDeuxMains(arme, aUneMain) { |   static armeUneOuDeuxMains(arme, aUneMain) { | ||||||
|     if (arme && !arme.system.cac) { |     if (arme && !arme.system.cac) { | ||||||
|       arme = foundry.utils.duplicate(arme); |       arme = foundry.utils.duplicate(arme); | ||||||
|       arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? 'unemain' : 'deuxmains') |       arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? '(1 main)' : '(2 mains)') | ||||||
|     } |     } | ||||||
|     return arme; |     return arme; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static competence1Mains(arme) { |   competence1Mains() { | ||||||
|     return arme.system.competence.replace(" 2 mains", " 1 main"); |     return this.system.competence.replace(" 2 mains", " 1 main"); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static competence2Mains(arme) { |   competence2Mains() { | ||||||
|     return arme.system.competence.replace(" 1 main", " 2 mains"); |     return this.system.competence.replace(" 1 main", " 2 mains"); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static isUtilisable(arme) { |   static isUtilisable(arme) { | ||||||
| @@ -218,10 +228,8 @@ export class RdDItemArme extends Item { | |||||||
| 
 | 
 | ||||||
|   static isAttaque(arme) { |   static isAttaque(arme) { | ||||||
|     switch (arme.type) { |     switch (arme.type) { | ||||||
|       case ITEM_TYPES.arme: |       case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0) | ||||||
|         return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0) |       case ITEM_TYPES.competencecreature: return arme.system.iscombat && RdDItemCompetenceCreature.isAttaque(item) | ||||||
|       case ITEM_TYPES.competencecreature: |  | ||||||
|         return arme.system.iscombat && RdDItemCompetenceCreature.isAttaque(item) |  | ||||||
|     } |     } | ||||||
|     return false |     return false | ||||||
|   } |   } | ||||||
| @@ -229,23 +237,24 @@ export class RdDItemArme extends Item { | |||||||
|   static isParade(arme) { |   static isParade(arme) { | ||||||
|     switch (arme.type) { |     switch (arme.type) { | ||||||
|       case ITEM_TYPES.arme: |       case ITEM_TYPES.arme: | ||||||
|         return arme.system.equipe && arme.system.resistance > 0 && true/* TODO: regarder la categorie d'arme?*/ |         return arme.system.resistance > 0 && true/* TODO: regarder la categorie d'arme?*/ | ||||||
|       case ITEM_TYPES.competencecreature: |       case ITEM_TYPES.competencecreature: | ||||||
|         return arme.system.iscombat && RdDItemCompetenceCreature.isParade(arme) |         return arme.system.iscombat && RdDItemCompetenceCreature.isParade(arme) | ||||||
|     } |     } | ||||||
|     return false |     return false | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|   static corpsACorps(actor) { |   static corpsACorps(actor) { | ||||||
|     let competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS |     let competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS | ||||||
|     let melee = actor ? actor.system.carac['melee'].value : 0 |     let melee = actor ? actor.system.carac['melee'].value : 0 | ||||||
|     return { |     return new RdDItemArme({ | ||||||
|       _id: competence.id, |       _id: competence.id, | ||||||
|       name: 'Corps à corps', |       name: 'Corps à corps', | ||||||
|       type: ITEM_TYPES.arme, |       type: ITEM_TYPES.arme, | ||||||
|       img: competence.img, |       img: competence.img, | ||||||
|       system: { |       system: { | ||||||
|         initiative: RdDCombatManager.calculInitiative(competence.system.niveau, melee), |         initiative: RdDInitiative.calculInitiative(competence.system.niveau, melee), | ||||||
|         equipe: true, |         equipe: true, | ||||||
|         rapide: true, |         rapide: true, | ||||||
|         force: 0, |         force: 0, | ||||||
| @@ -259,7 +268,7 @@ export class RdDItemArme extends Item { | |||||||
|         deuxmains: true, |         deuxmains: true, | ||||||
|         categorie_parade: 'sans-armes' |         categorie_parade: 'sans-armes' | ||||||
|       } |       } | ||||||
|     } |     }) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static mainsNues(actor) { |   static mainsNues(actor) { | ||||||
| @@ -1,9 +1,8 @@ | |||||||
|  | import { ACTOR_TYPES } from "../constants.js" | ||||||
| import { Misc } from "../misc.js" | import { Misc } from "../misc.js" | ||||||
| import { RdDSheetUtility } from "../rdd-sheet-utility.js" | import { RdDSheetUtility } from "../rdd-sheet-utility.js" | ||||||
| import { RdDUtility } from "../rdd-utility.js" | import { RdDUtility } from "../rdd-utility.js" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * TODO: |  * TODO: | ||||||
|  * options.editable ? |  * options.editable ? | ||||||
| @@ -14,22 +13,21 @@ const _SPACEHOLDER = { placeholder: true } | |||||||
| const _VENDRE = { | const _VENDRE = { | ||||||
|   code: 'item-vendre', label: 'Vendre ou donner', icon: it => 'fa-solid fa-comments-dollar', |   code: 'item-vendre', label: 'Vendre ou donner', icon: it => 'fa-solid fa-comments-dollar', | ||||||
|   filter: it => Misc.toInt(it.system.quantite) > 0, |   filter: it => Misc.toInt(it.system.quantite) > 0, | ||||||
|   optionsFilter: options => options.editable, |  | ||||||
|   action: (item, actor) => item.proposerVente() |   action: (item, actor) => item.proposerVente() | ||||||
| } | } | ||||||
| const _ACHAT_SERVICE = { | const _ACHETER = { | ||||||
|   code: 'item-service-acheter', label: 'Acheter', icon: it => 'fa-regular fa-coins', |   code: 'item-acheter', label: 'Acheter', icon: it => 'fa-regular fa-coins', | ||||||
|   //filter: it => Misc.toInt(it.system.quantite) > 0, |   filter: it => Misc.toInt(it.system.quantite) > 0 && it.parent?.type == ACTOR_TYPES.commerce, | ||||||
|   //optionsFilter: options => options.editable, |   action: (item, actor) => actor.vente(item) | ||||||
|   //action: (item, actor) => item.proposerVente() |  | ||||||
| } | } | ||||||
| const _MONTRER = { | const _MONTRER = { | ||||||
|   code: 'item-montrer', label: 'Montrer', icon: it => 'fa-solid fa-comment', |   code: 'item-montrer', label: 'Montrer', icon: it => 'fa-solid fa-comment', | ||||||
|  |   allowLimited: true, | ||||||
|   action: (item, actor) => item.postItemToChat() |   action: (item, actor) => item.postItemToChat() | ||||||
| } | } | ||||||
| const _SPLIT = { | const _SPLIT = { | ||||||
|   code: 'item-split', label: 'Séparer le goupe', icon: it => 'fa-solid fa-unlink', |   code: 'item-split', label: 'Séparer le goupe', icon: it => 'fa-solid fa-unlink', | ||||||
|   filter: it => Misc.toInt(it.system.quantite) > 1, |   filter: it => Misc.toInt(it.system.quantite) > 1 && it.parent?.type != ACTOR_TYPES.commerce, | ||||||
|   action: (item, actor) => RdDSheetUtility.splitItem(item, actor) |   action: (item, actor) => RdDSheetUtility.splitItem(item, actor) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -39,7 +37,7 @@ const _EDIT = { | |||||||
| } | } | ||||||
| const _DELETE = { | const _DELETE = { | ||||||
|   code: 'item-delete', label: 'Supprimer', icon: it => 'fa-solid fa-trash', |   code: 'item-delete', label: 'Supprimer', icon: it => 'fa-solid fa-trash', | ||||||
|   optionsFilter: options => options.editable && options.isOwner, |   optionsFilter: options => options.isOwner, | ||||||
|   action: (item, actor) => RdDUtility.confirmActorItemDelete(item, actor) |   action: (item, actor) => RdDUtility.confirmActorItemDelete(item, actor) | ||||||
| } | } | ||||||
| const _EQUIPER = { | const _EQUIPER = { | ||||||
| @@ -51,30 +49,25 @@ const _EQUIPER = { | |||||||
| const _CUISINER = { | const _CUISINER = { | ||||||
|   code: 'item-cuisiner', label: 'Cuisiner', icon: it => 'fa-solid fa-utensils', |   code: 'item-cuisiner', label: 'Cuisiner', icon: it => 'fa-solid fa-utensils', | ||||||
|   filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0, |   filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0, | ||||||
|   optionsFilter: options => options.editable, |  | ||||||
|   action: (item, actor) => actor.preparerNourriture(item) |   action: (item, actor) => actor.preparerNourriture(item) | ||||||
| } | } | ||||||
| const _MANGER_CRU = { | const _MANGER_CRU = { | ||||||
|   code: 'item-manger-cru', label: 'Manger cru', icon: it => 'fa-solid fa-drumstick-bite', |   code: 'item-manger-cru', label: 'Manger cru', icon: it => 'fa-solid fa-drumstick-bite', | ||||||
|   filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0, |   filter: it => it.getUtilisation() == 'cuisine' && it.system.sust > 0, | ||||||
|   optionsFilter: options => options.editable, |  | ||||||
|   action: (item, actor) => actor.mangerNourriture(item) |   action: (item, actor) => actor.mangerNourriture(item) | ||||||
| } | } | ||||||
| const _MANGER = { | const _MANGER = { | ||||||
|   code: 'item-manger', label: 'Manger', icon: it => 'fa-solid fa-utensils', |   code: 'item-manger', label: 'Manger', icon: it => 'fa-solid fa-utensils', | ||||||
|   filter: it => !(it.system.boisson), |   filter: it => !(it.system.boisson), | ||||||
|   optionsFilter: options => options.editable, |  | ||||||
|   action: (item, actor) => actor.mangerNourriture(item) |   action: (item, actor) => actor.mangerNourriture(item) | ||||||
| } | } | ||||||
| const _BOIRE = { | const _BOIRE = { | ||||||
|   code: 'item-boire', label: 'Boire', icon: it => 'fa-solid fa-glass-water', |   code: 'item-boire', label: 'Boire', icon: it => 'fa-solid fa-glass-water', | ||||||
|   filter: it => it.system.boisson, |   filter: it => it.system.boisson, | ||||||
|   optionsFilter: options => options.editable, |  | ||||||
|   action: (item, actor) => actor.mangerNourriture(item) |   action: (item, actor) => actor.mangerNourriture(item) | ||||||
| } | } | ||||||
| const _DECOCTION = { | const _DECOCTION = { | ||||||
|   code: 'item-decoction', label: 'Décoction', icon: it => 'fa-solid fa-flask-vial', |   code: 'item-decoction', label: 'Décoction', icon: it => 'fa-solid fa-flask-vial', | ||||||
|   optionsFilter: options => options.editable, |  | ||||||
|   action: (item, actor) => actor.fabriquerDecoctionHerbe(item) |   action: (item, actor) => actor.fabriquerDecoctionHerbe(item) | ||||||
| } | } | ||||||
| const _OUVRIR = { | const _OUVRIR = { | ||||||
| @@ -84,14 +77,12 @@ const _OUVRIR = { | |||||||
|  |  | ||||||
| const _LIRE = { | const _LIRE = { | ||||||
|   code: 'item-lire', label: 'Lire', icon: it => 'fa-solid fa-book-open', |   code: 'item-lire', label: 'Lire', icon: it => 'fa-solid fa-book-open', | ||||||
|   optionsFilter: options => options.editable, |  | ||||||
|   action: (item, actor) => actor.actionLire(item) |   action: (item, actor) => actor.actionLire(item) | ||||||
| } | } | ||||||
|  |  | ||||||
| const _REFOULER = { | const _REFOULER = { | ||||||
|   code: 'item-refouler', label: 'Refouler', icon: it => 'fa-solid fa-burst', |   code: 'item-refouler', label: 'Refouler', icon: it => 'fa-solid fa-burst', | ||||||
|   filter: it => it.system.refoulement > 0, |   filter: it => it.system.refoulement > 0, | ||||||
|   optionsFilter: options => options.editable, |  | ||||||
|   action: (item, actor) => actor.actionRefoulement(item) |   action: (item, actor) => actor.actionRefoulement(item) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -102,7 +93,7 @@ const _SORT_RESERVE = { | |||||||
| } | } | ||||||
|  |  | ||||||
| export const COMMON_ACTIONS = [_EQUIPER] | export const COMMON_ACTIONS = [_EQUIPER] | ||||||
| export const DEFAULT_ACTIONS = [_SPACEHOLDER, _SPLIT, _VENDRE, _MONTRER, _EDIT, _DELETE] | export const DEFAULT_ACTIONS = [_ACHETER, _SPACEHOLDER, _SPLIT, _VENDRE, _MONTRER, _EDIT, _DELETE] | ||||||
|  |  | ||||||
| export const ITEM_ACTIONS = { | export const ITEM_ACTIONS = { | ||||||
|   faune: [_CUISINER, _MANGER_CRU], |   faune: [_CUISINER, _MANGER_CRU], | ||||||
| @@ -114,17 +105,16 @@ export const ITEM_ACTIONS = { | |||||||
|   ombre: [_REFOULER], |   ombre: [_REFOULER], | ||||||
|   plante: [_CUISINER, _MANGER_CRU], |   plante: [_CUISINER, _MANGER_CRU], | ||||||
|   queue: [_REFOULER], |   queue: [_REFOULER], | ||||||
|   sort: [_SORT_RESERVE], |   sort: [_SORT_RESERVE] | ||||||
|   service: [_ACHAT_SERVICE] |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| export class ItemAction { | export class ItemAction { | ||||||
|  |  | ||||||
|   static applies(action, item, options) { |   static applies(action, item, options) { | ||||||
|     return action && item |     return action && item | ||||||
|       && item.isActionAllowed(action.code) |       && item.isActionAllowed(action.code) | ||||||
|       && (!action.filter || action.filter(item)) |       && (!action.filter || action.filter(item)) | ||||||
|  |       && (action.allowLimited || options.editable) | ||||||
|       && (!action.optionsFilter || action.optionsFilter(options)) |       && (!action.optionsFilter || action.optionsFilter(options)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -136,10 +126,10 @@ export class ItemAction { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async onActionItem(event, actor, options) { |   static async onActionItem(event, actor, options) { | ||||||
|     const item = RdDSheetUtility.getItem(event, actor) |  | ||||||
|     const code = $(event.currentTarget).data('code') |     const code = $(event.currentTarget).data('code') | ||||||
|  |     const item = RdDSheetUtility.getItem(event, actor) | ||||||
|     const action = item?.itemActions().find(it => it.code == code) |     const action = item?.itemActions().find(it => it.code == code) | ||||||
|     if (action && (!action.optionsFilter || action.optionsFilter(options))) { |     if (action && ItemAction.applies(action, item, options)) { | ||||||
|       await action.action(item, actor) |       await action.action(item, actor) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import { RdDRaretes } from "./raretes.js"; | |||||||
|  |  | ||||||
| const TYPE_ITEMS_NATURELS = ["faune", "herbe", "plante", "ingredient"]; | const TYPE_ITEMS_NATURELS = ["faune", "herbe", "plante", "ingredient"]; | ||||||
|  |  | ||||||
| export class RdDItemInventaireSheet extends RdDItemSheetV1 { | export class RdDInventaireItemSheet extends RdDItemSheetV1 { | ||||||
|  |  | ||||||
|   static get defaultOptions() { |   static get defaultOptions() { | ||||||
|     return foundry.utils.mergeObject(RdDItemSheetV1.defaultOptions, { |     return foundry.utils.mergeObject(RdDItemSheetV1.defaultOptions, { | ||||||
|   | |||||||
| @@ -2,9 +2,9 @@ import { RdDBaseActorSheet } from "../actor/base-actor-sheet.js"; | |||||||
| import { ITEM_TYPES } from "../constants.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| import { RdDSheetUtility } from "../rdd-sheet-utility.js"; | import { RdDSheetUtility } from "../rdd-sheet-utility.js"; | ||||||
| import { RdDUtility } from "../rdd-utility.js"; | import { RdDUtility } from "../rdd-utility.js"; | ||||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | import { RdDInventaireItemSheet } from "./sheet-base-inventaire.js"; | ||||||
|  |  | ||||||
| export class RdDConteneurItemSheet extends RdDItemInventaireSheet { | export class RdDConteneurItemSheet extends RdDInventaireItemSheet { | ||||||
|  |  | ||||||
|   static get ITEM_TYPE() { return ITEM_TYPES.conteneur }; |   static get ITEM_TYPE() { return ITEM_TYPES.conteneur }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | import { RdDInventaireItemSheet } from "./sheet-base-inventaire.js"; | ||||||
|  |  | ||||||
| export class RdDFauneItemSheet extends RdDItemInventaireSheet { | export class RdDFauneItemSheet extends RdDInventaireItemSheet { | ||||||
|  |  | ||||||
|   static get ITEM_TYPE() { return "faune" }; |   static get ITEM_TYPE() { return "faune" }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,9 +2,9 @@ import { ITEM_TYPES } from "../constants.js"; | |||||||
| import { DialogEnchanter } from "../enchantement/dialog-enchanter.js"; | import { DialogEnchanter } from "../enchantement/dialog-enchanter.js"; | ||||||
| import { RdDTimestamp } from "../time/rdd-timestamp.js"; | import { RdDTimestamp } from "../time/rdd-timestamp.js"; | ||||||
| import { RdDItemGemme } from "./gemme.js"; | import { RdDItemGemme } from "./gemme.js"; | ||||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | import { RdDInventaireItemSheet } from "./sheet-base-inventaire.js"; | ||||||
|  |  | ||||||
| export class RdDGemmeItemSheet extends RdDItemInventaireSheet { | export class RdDGemmeItemSheet extends RdDInventaireItemSheet { | ||||||
|  |  | ||||||
|   static get ITEM_TYPE() { return ITEM_TYPES.gemme }; |   static get ITEM_TYPE() { return ITEM_TYPES.gemme }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | import { RdDInventaireItemSheet } from "./sheet-base-inventaire.js"; | ||||||
|  |  | ||||||
| export class RdDHerbeItemSheet extends RdDItemInventaireSheet { | export class RdDHerbeItemSheet extends RdDInventaireItemSheet { | ||||||
|  |  | ||||||
|   static get ITEM_TYPE() { return "herbe" }; |   static get ITEM_TYPE() { return "herbe" }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | import { RdDInventaireItemSheet } from "./sheet-base-inventaire.js"; | ||||||
|  |  | ||||||
| export class RdDIngredientItemSheet extends RdDItemInventaireSheet { | export class RdDIngredientItemSheet extends RdDInventaireItemSheet { | ||||||
|   static get ITEM_TYPE() { return "ingredient" }; |   static get ITEM_TYPE() { return "ingredient" }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | import { RdDInventaireItemSheet } from "./sheet-base-inventaire.js"; | ||||||
|  |  | ||||||
| export class RdDPlanteItemSheet extends RdDItemInventaireSheet { | export class RdDPlanteItemSheet extends RdDInventaireItemSheet { | ||||||
|  |  | ||||||
|   static get ITEM_TYPE() { return "plante" }; |   static get ITEM_TYPE() { return "plante" }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,10 +2,10 @@ import { ITEM_TYPES } from "../constants.js"; | |||||||
| import { DialogEnchanter } from "../enchantement/dialog-enchanter.js"; | import { DialogEnchanter } from "../enchantement/dialog-enchanter.js"; | ||||||
| import { RdDTimestamp } from "../time/rdd-timestamp.js"; | import { RdDTimestamp } from "../time/rdd-timestamp.js"; | ||||||
| import { RdDItemPotion } from "./potion.js"; | import { RdDItemPotion } from "./potion.js"; | ||||||
| import { RdDItemInventaireSheet } from "./sheet-base-inventaire.js"; | import { RdDInventaireItemSheet } from "./sheet-base-inventaire.js"; | ||||||
|  |  | ||||||
|  |  | ||||||
| export class RdDPotionItemSheet extends RdDItemInventaireSheet { | export class RdDPotionItemSheet extends RdDInventaireItemSheet { | ||||||
|  |  | ||||||
|   static get ITEM_TYPE() { return ITEM_TYPES.potion }; |   static get ITEM_TYPE() { return ITEM_TYPES.potion }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -247,7 +247,7 @@ class _10_2_10_DesirLancinant_IdeeFixe extends Migration { | |||||||
|     await this.applyItemsUpdates(items => items |     await this.applyItemsUpdates(items => items | ||||||
|       .filter(it => ['queue', 'ombre'].includes(it.type)) |       .filter(it => ['queue', 'ombre'].includes(it.type)) | ||||||
|       .map(it => this.migrateQueue(it)) |       .map(it => this.migrateQueue(it)) | ||||||
|     ); |     ) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -631,13 +631,37 @@ class _12_0_38_TachesEcriture extends Migration { | |||||||
|  |  | ||||||
|   async migrate() { |   async migrate() { | ||||||
|     await this.applyItemsUpdates(items => items |     await this.applyItemsUpdates(items => items | ||||||
|       .filter(it => [ITEM_TYPES.tache, ITEM_TYPES.livre, ITEM_TYPES.oeuvre, ITEM_TYPES.meditation].includes(it.type) ) |       .filter(it => [ITEM_TYPES.tache, ITEM_TYPES.livre, ITEM_TYPES.oeuvre, ITEM_TYPES.meditation].includes(it.type)) | ||||||
|       .filter(it => it.system.competence == 'Ecriture') |       .filter(it => Grammar.equalsInsensitive(it.system.competence, 'ecriture')) | ||||||
|       .map(it => { return { _id: it.id, 'system.competence': 'Écriture' } }) |       .map(it => { return { _id: it.id, 'system.competence': 'Écriture' } }) | ||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | class _13_0_4_FixReveActuel extends Migration { | ||||||
|  |   get code() { return "fix-reve-actuel" } | ||||||
|  |   get version() { return "13.0.4" } | ||||||
|  |  | ||||||
|  |   async migrate() { | ||||||
|  |     game.actors.forEach(it => it.update({ 'system.carac.-=reve-actuel': null })) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _13_0_7_FixNiveauOeuvres extends Migration { | ||||||
|  |   get code() { return "fix-niveau-oeuvres" } | ||||||
|  |   get version() { return "13.0.7" } | ||||||
|  |  | ||||||
|  |   async migrate() { | ||||||
|  |     await this.applyItemsUpdates(items => items | ||||||
|  |       .filter(it => [ITEM_TYPES.musique, ITEM_TYPES.chant, ITEM_TYPES.danse, ITEM_TYPES.recettecuisine].includes(it.type)) | ||||||
|  |       .map(it => { | ||||||
|  |         const niveau = isNaN(it.system.niveau) ? 0 : parseInt(it.system.niveau) | ||||||
|  |         return { _id: it.id, 'system.niveau': niveau } | ||||||
|  |       }) | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| export class Migrations { | export class Migrations { | ||||||
|   static getMigrations() { |   static getMigrations() { | ||||||
|     return [ |     return [ | ||||||
| @@ -660,7 +684,9 @@ export class Migrations { | |||||||
|       new _12_0_26_MigrationVoieSorts(), |       new _12_0_26_MigrationVoieSorts(), | ||||||
|       new _12_0_32_MigrationRaces(), |       new _12_0_32_MigrationRaces(), | ||||||
|       new _12_0_37_MigrationAlchimieEtat(), |       new _12_0_37_MigrationAlchimieEtat(), | ||||||
|       new _12_0_38_TachesEcriture() |       new _12_0_38_TachesEcriture(), | ||||||
|  |       new _13_0_4_FixReveActuel(), | ||||||
|  |       new _13_0_7_FixNiveauOeuvres(), | ||||||
|     ]; |     ]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -38,6 +38,12 @@ export class Misc { | |||||||
|     return (a, b) => Number(a) + Number(b); |     return (a, b) => Number(a) + Number(b); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static and(predicates) { | ||||||
|  |     return value => predicates.map(predicate => predicate(value)) | ||||||
|  |       .reduce((v1, v2) => v1 && v2, true); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   static ascending(orderFunction = x => x) { |   static ascending(orderFunction = x => x) { | ||||||
|     return (a, b) => Misc.sortingBy(orderFunction(a), orderFunction(b)); |     return (a, b) => Misc.sortingBy(orderFunction(a), orderFunction(b)); | ||||||
|   } |   } | ||||||
| @@ -60,6 +66,11 @@ export class Misc { | |||||||
|   static arrayOrEmpty(items) { |   static arrayOrEmpty(items) { | ||||||
|     return items?.length ? items : []; |     return items?.length ? items : []; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static findOrFirst(list, predicate) { | ||||||
|  |     return list.find(predicate) ?? list[0] | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Converts the value to an integer, or to 0 if undefined/null/not representing integer |    * Converts the value to an integer, or to 0 if undefined/null/not representing integer | ||||||
|    * @param {*} value value to convert to an integer using parseInt |    * @param {*} value value to convert to an integer using parseInt | ||||||
| @@ -75,13 +86,17 @@ export class Misc { | |||||||
|     return Math.round(num * power10n) / power10n; |     return Math.round(num * power10n) / power10n; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getFractionHtml(diviseur) { |  | ||||||
|     if (!diviseur || diviseur <= 1) return undefined; |   static getFractionOneN(divider) { | ||||||
|     switch (diviseur || 1) { |     if (!divider || divider == 1) { | ||||||
|       case 2: return '½'; |       return 1 | ||||||
|       case 4: return '¼'; |  | ||||||
|       default: return '1/' + diviseur; |  | ||||||
|     } |     } | ||||||
|  |     switch (divider) { | ||||||
|  |       case 2: return '½' | ||||||
|  |       case 4: return '¼' | ||||||
|  |       case 8: return '⅛' | ||||||
|  |     } | ||||||
|  |     return `1/${divider}` | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static indexLowercase(list) { |   static indexLowercase(list) { | ||||||
|   | |||||||
| @@ -1,21 +1,23 @@ | |||||||
| import { RdDCarac } from "./rdd-carac.js"; |  | ||||||
| import { RdDPossession } from "./rdd-possession.js"; | import { RdDPossession } from "./rdd-possession.js"; | ||||||
|  |  | ||||||
| const conditionsTactiques = [ | const conditionsTactiques = [ | ||||||
|   { type: '', descr: '', dmg: 0, attaque: 0, parade: 0, esquive: true }, |   { key: '', label: '', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false }, | ||||||
|   { type: 'charge', descr: 'Charge', dmg: 2, attaque: 4, parade: -4, esquive: false }, |   { key: 'normale', label: 'Attaque normale', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: true }, | ||||||
|   { type: 'feinte', descr: 'Feinte', dmg: 1, attaque: 1, parade: 0, esquive: true }, |   { key: 'charge', label: 'Charge', dmg: 2, attaque: 4, parade: -4, esquive: false, isTactique: true }, | ||||||
|   { type: 'pret', descr: 'prêt', dmg: 0, attaque: 0, parade: 0, esquive: true }, |   { key: 'feinte', label: 'Feinte', dmg: 1, attaque: 1, parade: 0, esquive: true, isTactique: true }, | ||||||
|   { type: 'demi', descr: 'Demi-surprise', dmg: 1, attaque: 0, parade: 0, esquive: true }, |   { key: 'pret', label: 'prêt', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false }, | ||||||
|   { type: 'totale', descr: 'Surprise totale', dmg: 10, attaque: 6, parade: 0, esquive: true }, |   { key: 'demi', label: 'Demi-surprise', dmg: 1, attaque: 0, parade: 0, esquive: true, isTactique: false }, | ||||||
|  |   { key: 'totale', label: 'Surprise totale', dmg: 10, attaque: 6, parade: 0, esquive: true, isTactique: false }, | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RdDBonus { | export class RdDBonus { | ||||||
|  |   static get tactiques(){ | ||||||
|  |     return conditionsTactiques.filter(it => it.isTactique) | ||||||
|  |   } | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static find(condition) { |   static find(condition) { | ||||||
|     return conditionsTactiques.find(e => e.type == condition) || conditionsTactiques.find(e => e.type == 'pret'); |     return conditionsTactiques.find(e => e.key == condition) || conditionsTactiques[0]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -32,7 +34,7 @@ export class RdDBonus { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static dmg(rollData, actor, isEntiteIncarnee = false) { |   static dmg(rollData, actor, isEntiteIncarnee = false) { | ||||||
|     const dmgArme = RdDBonus.dmgArme(rollData.arme) |     const dmgArme = RdDBonus.dmgArme(rollData.arme, rollData.arme?.system.dommagesReels) | ||||||
|     let dmg = { |     let dmg = { | ||||||
|       total: 0, |       total: 0, | ||||||
|       dmgArme: dmgArme, |       dmgArme: dmgArme, | ||||||
| @@ -49,31 +51,35 @@ export class RdDBonus { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static description(condition) { |   static description(condition) { | ||||||
|     return RdDBonus.find(condition).descr; |     return RdDBonus.find(condition).label | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static dmgBonus(condition) { |   static dmgBonus(condition) { | ||||||
|     return RdDBonus.find(condition).dmg; |     return RdDBonus.find(condition).dmg | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static bonusAttaque(condition) { |   static bonusAttaque(condition) { | ||||||
|     return RdDBonus.find(condition).attaque; |     return RdDBonus.find(condition).attaque | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static _calculMortalite(rollData, isEntiteIncarnee) { |   static _calculMortalite(rollData, isEntiteIncarnee) { | ||||||
|  |     return RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite, isEntiteIncarnee) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static mortalite(mortaliteSelect, mortaliteArme, isEntiteIncarnee) { | ||||||
|     return isEntiteIncarnee ? "entiteincarnee" |     return isEntiteIncarnee ? "entiteincarnee" | ||||||
|       : rollData.dmg?.mortalite |       : mortaliteSelect | ||||||
|       ?? rollData.arme?.system.mortalite |       ?? mortaliteArme | ||||||
|       ?? "mortel"; |       ?? "mortel"; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static dmgArme(arme) { |   static dmgArme(arme, dommagesMain) { | ||||||
|     if (arme) { |     if (arme) { | ||||||
|       let dmgBase = arme.system.dommagesReels ?? Number(arme.system.dommages ?? 0); |       let dmgBase = dommagesMain ?? Number(arme.system.dommages ?? 0); | ||||||
|       //Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278) |       //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); |       return dmgBase + Math.min(dmgBase, arme.system.magique ? arme.system.ecaille_efficacite : 0); | ||||||
|     } |     } | ||||||
| @@ -92,8 +98,8 @@ export class RdDBonus { | |||||||
|       return 0 |       return 0 | ||||||
|     } |     } | ||||||
|     switch (categorie) { |     switch (categorie) { | ||||||
|       case "tir": return 0; |       case "(tir)": case "tir": return 0 | ||||||
|       case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor)); |       case "(lancer)": case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor)); | ||||||
|     } |     } | ||||||
|     return dmgActor; |     return dmgActor; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -37,21 +37,37 @@ const TABLE_CARACTERISTIQUES_DERIVEES = { | |||||||
|   32: { xp: 180, niveau: 11, poids: "1501-2000", poidsMin: 1501, poidsMax: 2000, plusdom: +11, sconst: 10, sust: 17 } |   32: { xp: 180, niveau: 11, poids: "1501-2000", poidsMin: 1501, poidsMax: 2000, plusdom: +11, sconst: 10, sust: 17 } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | export const CARACS = { | ||||||
|  |   TAILLE: 'taille', | ||||||
|  |   APPARENCE: 'apparence', | ||||||
|  |   CONSTITUTION: 'constitution', | ||||||
|  |   FORCE: 'force', | ||||||
|  |   AGILITE: 'agilite', | ||||||
|  |   DEXTERITE: 'dexterite', | ||||||
|  |   VUE: 'vue', | ||||||
|  |   OUIE: 'ouie', | ||||||
|  |   ODORATGOUT: 'odoratgout', | ||||||
|  |   VOLONTE: 'volonte', | ||||||
|  |   INTELLECT: 'intellect', | ||||||
|  |   EMPATHIE: 'empathie', | ||||||
|  |   REVE: 'reve', | ||||||
|  |   CHANCE: 'chance', | ||||||
|  | } | ||||||
| export const LIST_CARAC_PERSONNAGE = { | export const LIST_CARAC_PERSONNAGE = { | ||||||
|   'taille': { code: 'taille', label: 'Taille', isCarac: true, path: 'system.carac.taille.value' }, |   [CARACS.TAILLE]: { code: CARACS.TAILLE, label: 'Taille', isCarac: true, path: 'system.carac.taille.value' }, | ||||||
|   'apparence': { code: 'apparence', label: 'Apparence', isCarac: true, path: 'system.carac.apparence.value' }, |   [CARACS.APPARENCE]: { code: CARACS.APPARENCE, label: 'Apparence', isCarac: true, path: 'system.carac.apparence.value' }, | ||||||
|   'constitution': { code: 'constitution', label: 'Constitution', isCarac: true, path: 'system.carac.constitution.value' }, |   [CARACS.CONSTITUTION]: { code: CARACS.CONSTITUTION, label: 'Constitution', isCarac: true, path: 'system.carac.constitution.value' }, | ||||||
|   'force': { code: 'force', label: 'Force', isCarac: true, path: 'system.carac.force.value' }, |   [CARACS.FORCE]: { code: CARACS.FORCE, label: 'Force', isCarac: true, path: 'system.carac.force.value' }, | ||||||
|   'agilite': { code: 'agilite', label: 'Agilité', isCarac: true, path: 'system.carac.agilite.value' }, |   [CARACS.AGILITE]: { code: CARACS.AGILITE, label: 'Agilité', isCarac: true, path: 'system.carac.agilite.value' }, | ||||||
|   'dexterite': { code: 'dexterite', label: 'Dextérité', isCarac: true, path: 'system.carac.dexterite.value' }, |   [CARACS.DEXTERITE]: { code: CARACS.DEXTERITE, label: 'Dextérité', isCarac: true, path: 'system.carac.dexterite.value' }, | ||||||
|   'vue': { code: 'vue', label: 'Vue', isCarac: true, path: 'system.carac.vue.value' }, |   [CARACS.VUE]: { code: CARACS.VUE, label: 'Vue', isCarac: true, path: 'system.carac.vue.value' }, | ||||||
|   'ouie': { code: 'ouie', label: 'Ouïe', isCarac: true, path: 'system.carac.ouie.value' }, |   [CARACS.OUIE]: { code: CARACS.OUIE, label: 'Ouïe', isCarac: true, path: 'system.carac.ouie.value' }, | ||||||
|   'odoratgout': { code: 'odoratgout', label: 'Odorat-Goût', isCarac: true, path: 'system.carac.odoratgout.value' }, |   [CARACS.ODORATGOUT]: { code: CARACS.ODORATGOUT, label: 'Odorat-Goût', isCarac: true, path: 'system.carac.odoratgout.value' }, | ||||||
|   'volonte': { code: 'volonte', label: 'Volonté', isCarac: true, path: 'system.carac.volonte.value' }, |   [CARACS.VOLONTE]: { code: CARACS.VOLONTE, label: 'Volonté', isCarac: true, path: 'system.carac.volonte.value' }, | ||||||
|   'intellect': { code: 'intellect', label: 'Intellect', isCarac: true, path: 'system.carac.intellect.value' }, |   [CARACS.INTELLECT]: { code: CARACS.INTELLECT, label: 'Intellect', isCarac: true, path: 'system.carac.intellect.value' }, | ||||||
|   'empathie': { code: 'empathie', label: 'Empathie', isCarac: true, path: 'system.carac.empathie.value' }, |   [CARACS.EMPATHIE]: { code: CARACS.EMPATHIE, label: 'Empathie', isCarac: true, path: 'system.carac.empathie.value' }, | ||||||
|   'reve': { code: 'reve', label: 'Rêve', isCarac: true, path: 'system.carac.reve.value' }, |   [CARACS.REVE]: { code: CARACS.REVE, label: 'Rêve', isCarac: true, path: 'system.carac.reve.value' }, | ||||||
|   'chance': { code: 'chance', label: 'Chance', isCarac: true, path: 'system.carac.chance.value' }, |   [CARACS.CHANCE]: { code: CARACS.CHANCE, label: 'Chance', isCarac: true, path: 'system.carac.chance.value' }, | ||||||
|   'protection': { code: 'protection', label: 'Protection naturelle', isCarac: false, path: 'system.attributs.protection.value' }, |   'protection': { code: 'protection', label: 'Protection naturelle', isCarac: false, path: 'system.attributs.protection.value' }, | ||||||
|   'beaute': { code: 'beaute', label: 'Beauté', isCarac: false, path: 'system.background.beaute.value' } |   'beaute': { code: 'beaute', label: 'Beauté', isCarac: false, path: 'system.background.beaute.value' } | ||||||
| } | } | ||||||
| @@ -69,7 +85,7 @@ const LIST_CARAC_DERIVEE = { | |||||||
|   'reve-actuel': { code: "reve-actuel", label: 'Rêve actuel', path: 'system.reve.reve.value' }, |   'reve-actuel': { code: "reve-actuel", label: 'Rêve actuel', path: 'system.reve.reve.value' }, | ||||||
| } | } | ||||||
|  |  | ||||||
| const LIST_CARAC_ROLL = Object.values(LIST_CARAC_PERSONNAGE).filter(it => it.isCarac && it.code != 'taille') | export const LIST_CARAC_ROLL = Object.values(LIST_CARAC_PERSONNAGE).filter(it => it.isCarac && it.code != 'taille') | ||||||
|   .concat(Object.values(LIST_CARAC_AUTRES)) |   .concat(Object.values(LIST_CARAC_AUTRES)) | ||||||
|   .concat(Object.values(LIST_CARAC_DERIVEE)) |   .concat(Object.values(LIST_CARAC_DERIVEE)) | ||||||
|  |  | ||||||
| @@ -95,27 +111,41 @@ export class RdDCarac { | |||||||
|     return Object.values(LIST_CARAC_PERSONNAGE).filter(filter) |     return Object.values(LIST_CARAC_PERSONNAGE).filter(filter) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static isAgiliteOuDerobee(selectedCarac) { |   static isAgiliteOuDerobee(caracLabel) { | ||||||
|     return selectedCarac?.label.match(/(Agilité|Dérobée)/); |     return RdDCarac.isAgilite(caracLabel) | ||||||
|  |       || RdDCarac.isDerobee(caracLabel) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static isVolonte(selectedCarac) { |   static isDerobee(caracLabel) { | ||||||
|     return selectedCarac?.label == 'Volonté'; |     return Grammar.equalsInsensitive(caracLabel, LIST_CARAC_PERSONNAGE.agilite.code); | ||||||
|   } |   } | ||||||
|   static isChance(selectedCarac) { |  | ||||||
|     return selectedCarac?.label?.toLowerCase()?.match(/chance( actuelle)?/); |   static isAgilite(caracLabel) { | ||||||
|  |     return Grammar.equalsInsensitive(caracLabel, LIST_CARAC_DERIVEE.derobee.code); | ||||||
|   } |   } | ||||||
|   static isReve(selectedCarac) { |  | ||||||
|     return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/); |   static isIntellect(caracLabel) { | ||||||
|  |     return Grammar.toLowerCaseNoAccent(caracLabel) == 'intellect'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static isVolonte(caracLabel) { | ||||||
|  |     return Grammar.toLowerCaseNoAccent(caracLabel) == 'volonte'; | ||||||
|  |   } | ||||||
|  |   static isChance(caracLabel) { | ||||||
|  |     return Grammar.toLowerCaseNoAccent(caracLabel)?.match(/chance(( |-)?actuelle)?/); | ||||||
|  |   } | ||||||
|  |   static isReve(caracLabel) { | ||||||
|  |     return Grammar.toLowerCaseNoAccent(caracLabel)?.match(/reve(( |-)?actuel)?/); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * L’appel à la chance n’est possible que pour recommencer les jets d’actions physiques : |    * L’appel à la chance n’est possible que pour recommencer les jets d’actions physiques : | ||||||
|    * tous les jets de combat, de FORCE, d’AGILITÉ, de DEXTÉRITÉ, de Dérobée, d’APPARENCE, |    * tous les jets de combat, de FORCE, d’AGILITÉ, de DEXTÉRITÉ, de Dérobée, d’APPARENCE, | ||||||
|    * ainsi que de Perception active et volontaire. |    * ainsi que de Perception active et volontaire. | ||||||
|  |    * Le moral ne s'utilise aussi que sur les actions physiques | ||||||
|    */ |    */ | ||||||
|   static isActionPhysique(selectedCarac) { |   static isActionPhysique(caracLabel) { | ||||||
|     return Grammar.toLowerCaseNoAccent(selectedCarac?.label) |     return Grammar.toLowerCaseNoAccent(caracLabel) | ||||||
|       ?.match(/(apparence|force|agilite|dexterite|vue|ouie|gout|odorat|empathie|melee|tir|lancer|derobee)/) != null |       ?.match(/(apparence|force|agilite|dexterite|vue|ouie|gout|odorat|empathie|melee|tir|lancer|derobee)/) != null | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,9 +1,6 @@ | |||||||
| import { ChatUtility } from "./chat-utility.js"; | import { ChatUtility } from "./chat-utility.js"; | ||||||
| import { ENTITE_BLURETTE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | import { ENTITE_BLURETTE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { RdDItemArme } from "./item-arme.js"; |  | ||||||
| import { RdDItemCompetence } from "./item-competence.js"; |  | ||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; |  | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDBonus } from "./rdd-bonus.js"; | import { RdDBonus } from "./rdd-bonus.js"; | ||||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||||
| @@ -14,26 +11,30 @@ import { STATUSES } from "./settings/status-effects.js"; | |||||||
| import { Targets } from "./targets.js"; | import { Targets } from "./targets.js"; | ||||||
| import { RdDEmpoignade } from "./rdd-empoignade.js"; | import { RdDEmpoignade } from "./rdd-empoignade.js"; | ||||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | import { RdDRollResult } from "./rdd-roll-result.js"; | ||||||
|  | import { RdDItemArme } from "./item/arme.js"; | ||||||
|  | import { RdDItemCompetence } from "./item-competence.js"; | ||||||
|  | import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||||
|  | import { RdDInitiative } from "./initiative.mjs"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| const premierRoundInit = [ | const premierRoundInit = [ | ||||||
|   { pattern: 'hast', init: 5.90 }, |   { pattern: 'hast' }, | ||||||
|   { pattern: 'lance', init: 5.85 }, |   { pattern: 'lance' }, | ||||||
|   { pattern: 'baton', init: 5.80 }, |   { pattern: 'baton' }, | ||||||
|   { pattern: 'doubledragonne', init: 5.75 }, |   { pattern: 'doubledragonne' }, | ||||||
|   { pattern: 'esparlongue', init: 5.70 }, |   { pattern: 'esparlongue' }, | ||||||
|   { pattern: 'epeedragonne', init: 5.65 }, |   { pattern: 'epeedragonne' }, | ||||||
|   { pattern: 'epeebatarde', init: 5.60 }, |   { pattern: 'epeebatarde' }, | ||||||
|   { pattern: 'epeecyane', init: 5.55 }, |   { pattern: 'epeecyane' }, | ||||||
|   { pattern: 'epeesorde', init: 5.50 }, |   { pattern: 'epeesorde' }, | ||||||
|   { pattern: 'grandehache', init: 5.45 }, |   { pattern: 'grandehache' }, | ||||||
|   { pattern: 'bataille', init: 5.40 }, |   { pattern: 'bataille' }, | ||||||
|   { pattern: 'epeegnome', init: 5.35 }, |   { pattern: 'epeegnome' }, | ||||||
|   { pattern: 'masse', init: 5.30 }, |   { pattern: 'masse' }, | ||||||
|   { pattern: 'gourdin', init: 5.25 }, |   { pattern: 'gourdin' }, | ||||||
|   { pattern: 'fleau', init: 5.20 }, |   { pattern: 'fleau' }, | ||||||
|   { pattern: 'dague', init: 5.15 }, |   { pattern: 'dague' }, | ||||||
|   { pattern: 'autre', init: 5.10 }, |   { pattern: 'autre' }, | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| @@ -45,6 +46,10 @@ export class RdDCombatManager extends Combat { | |||||||
|     Hooks.on("updateCombat", (combat, change, options, userId) => { RdDCombat.onUpdateCombat(combat, change, options, userId) }); |     Hooks.on("updateCombat", (combat, change, options, userId) => { RdDCombat.onUpdateCombat(combat, change, options, userId) }); | ||||||
|     Hooks.on("preDeleteCombat", (combat, html, id) => { combat.onPreDeleteCombat() }) |     Hooks.on("preDeleteCombat", (combat, html, id) => { combat.onPreDeleteCombat() }) | ||||||
|     Hooks.on("deleteCombat", (combat, html, id) => { combat.onDeleteCombat() }) |     Hooks.on("deleteCombat", (combat, html, id) => { combat.onDeleteCombat() }) | ||||||
|  |  | ||||||
|  |     for (let i = 0.0; i < premierRoundInit.length; i++) { | ||||||
|  |       premierRoundInit[i].init = 5.99 - i / 100 | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -108,9 +113,7 @@ export class RdDCombatManager extends Combat { | |||||||
|   async rollInitiative(ids, messageOptions = {}) { |   async rollInitiative(ids, messageOptions = {}) { | ||||||
|     console.log(`${game.system.title} | Combat.rollInitiative()`, ids, messageOptions) |     console.log(`${game.system.title} | Combat.rollInitiative()`, ids, messageOptions) | ||||||
|     ids = typeof ids === "string" ? [ids] : ids |     ids = typeof ids === "string" ? [ids] : ids | ||||||
|     ids.forEach(async id => |     Promise.all(ids.map(id => this.rollInitRdD(id, undefined, messageOptions))) | ||||||
|       await this.rollInitRdD(id, undefined, messageOptions) |  | ||||||
|     ) |  | ||||||
|     return this |     return this | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -148,7 +151,7 @@ export class RdDCombatManager extends Combat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getFirstInitRollFormula(actor) { |   static getFirstInitRollFormula(actor) { | ||||||
|     const actions = actor.listActionsCombat() |     const actions = actor.listActions({ isEquipe: true }) | ||||||
|     if (actions.length > 0) { |     if (actions.length > 0) { | ||||||
|       const action = actions[0] |       const action = actions[0] | ||||||
|       const init = RdDCombatManager.getInitData(actor, action) |       const init = RdDCombatManager.getInitData(actor, action) | ||||||
| @@ -161,87 +164,7 @@ export class RdDCombatManager extends Combat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static formuleInitiative(rang, carac, niveau, bonusMalus) { |   static formuleInitiative(rang, carac, niveau, bonusMalus) { | ||||||
|     return `${rang} +( (${RdDCombatManager.calculInitiative(niveau, carac, bonusMalus)} )/100)`; |     return `${rang} +( (${RdDInitiative.calculInitiative(niveau, carac, bonusMalus)} )/100)`; | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   static calculInitiative(niveau, caracValue, bonus = 0) { |  | ||||||
|     let base = niveau + Math.floor(caracValue / 2) + bonus; |  | ||||||
|     return "1d6" + (base >= 0 ? "+" : "") + base; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   /** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main / lancer */ |  | ||||||
|   static listActionsArmes(armes, competences, carac) { |  | ||||||
|     let actions = []; |  | ||||||
|     for (const arme of armes) { |  | ||||||
|       if (arme.system.equipe) { |  | ||||||
|         const dommages = arme.system.dommages.toString(); |  | ||||||
|         const tableauDommages = dommages.includes("/") ? dommages.split("/") : [dommages, dommages]; |  | ||||||
|         if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) { |  | ||||||
|           ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)"); |  | ||||||
|         } |  | ||||||
|         if (arme.system.unemain && arme.system.competence) { |  | ||||||
|           actions.push(RdDCombatManager.$prepareAttaqueArme({ |  | ||||||
|             arme: arme, |  | ||||||
|             infoMain: "(1 main)", |  | ||||||
|             dommagesReel: Number(tableauDommages[0]), |  | ||||||
|             competence: arme.system.competence, |  | ||||||
|             carac: carac, |  | ||||||
|             competences: competences |  | ||||||
|           })); |  | ||||||
|         } |  | ||||||
|         if (arme.system.deuxmains && arme.system.competence) { |  | ||||||
|           actions.push(RdDCombatManager.$prepareAttaqueArme({ |  | ||||||
|             arme: arme, |  | ||||||
|             infoMain: "(2 mains)", |  | ||||||
|             dommagesReel: Number(tableauDommages[1]), |  | ||||||
|             competence: RdDItemArme.competence2Mains(arme), |  | ||||||
|             carac: carac, |  | ||||||
|             competences: competences |  | ||||||
|           })); |  | ||||||
|         } |  | ||||||
|         if (arme.system.lancer) { |  | ||||||
|           actions.push(RdDCombatManager.$prepareAttaqueArme({ |  | ||||||
|             arme: arme, |  | ||||||
|             infoMain: "(lancer)", |  | ||||||
|             dommagesReel: Number(tableauDommages[0]), |  | ||||||
|             competence: arme.system.lancer, |  | ||||||
|             carac: carac, |  | ||||||
|             competences: competences |  | ||||||
|           })); |  | ||||||
|         } |  | ||||||
|         if (arme.system.tir) { |  | ||||||
|           actions.push(RdDCombatManager.$prepareAttaqueArme({ |  | ||||||
|             arme: arme, |  | ||||||
|             infoMain: "(tir)", |  | ||||||
|             dommagesReel: Number(tableauDommages[0]), |  | ||||||
|             competence: arme.system.tir, |  | ||||||
|             carac: carac, |  | ||||||
|             competences: competences |  | ||||||
|           })); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     return actions.sort(Misc.ascending(action => action.name + (action.system.infoMain ?? ''))); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static $prepareAttaqueArme(infoAttaque) { |  | ||||||
|     const comp = infoAttaque.competences.find(it => Grammar.equalsInsensitive(it.name, infoAttaque.competence)) |  | ||||||
|     const arme = infoAttaque.arme; |  | ||||||
|     const attaque = foundry.utils.duplicate(arme) |  | ||||||
|  |  | ||||||
|     const carac = comp?.system.defaut_carac ?? (infoAttaque.infoMain == '(lancer)' ? 'lancer' : infoAttaque.infoMain == '(lancer)' ? 'tir' : 'melee') |  | ||||||
|     const niveau = comp?.system.niveau ?? (infoAttaque.infoMain == '(lancer)' ? -8 : -6) |  | ||||||
|     attaque.action = 'attaque'; |  | ||||||
|     attaque.system.competence = infoAttaque.competence; |  | ||||||
|     attaque.system.dommagesReels = infoAttaque.dommagesReel; |  | ||||||
|     attaque.system.infoMain = infoAttaque.infoMain; |  | ||||||
|     attaque.system.niveau = niveau |  | ||||||
|  |  | ||||||
|     const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + (arme.system.magique) ? arme.system.ecaille_efficacite : 0 |  | ||||||
|     attaque.system.initiative = RdDCombatManager.calculInitiative(niveau, infoAttaque.carac[carac].value, ajustement) |  | ||||||
|     return attaque |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -251,11 +174,13 @@ export class RdDCombatManager extends Combat { | |||||||
|       let initMissing = game.combat.combatants.find(it => !it.initiative); |       let initMissing = game.combat.combatants.find(it => !it.initiative); | ||||||
|       if (!initMissing) { // Premier round ! |       if (!initMissing) { // Premier round ! | ||||||
|         for (let combatant of game.combat.combatants) { |         for (let combatant of game.combat.combatants) { | ||||||
|           let action = combatant.initiativeData?.arme; |           if (combatant.initiativeData?.arme?.type == "arme") { | ||||||
|           //console.log("Parsed !!!", combatant, initDone, game.combat.current, arme); |             // TODO: get init data premier round | ||||||
|           if (action && action.type == "arme") { |             const initiativeData = combatant.initiativeData; | ||||||
|             for (let initData of premierRoundInit) { |             const action = combatant.initiativeData.arme; | ||||||
|               if (Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround).includes(initData.pattern)) { |             const fromArme = Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround) | ||||||
|  |             const initData = premierRoundInit.find(it => fromArme.includes(initData.pattern)) | ||||||
|  |             if (initData) { | ||||||
|               let msg = `<h4>L'initiative de ${combatant.actor.getAlias()} a été modifiée !</h4> |               let msg = `<h4>L'initiative de ${combatant.actor.getAlias()} a été modifiée !</h4> | ||||||
|                       <hr> |                       <hr> | ||||||
|                       <div> |                       <div> | ||||||
| @@ -269,7 +194,6 @@ export class RdDCombatManager extends Combat { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static incDecInit(combatantId, incDecValue) { |   static incDecInit(combatantId, incDecValue) { | ||||||
| @@ -297,7 +221,7 @@ export class RdDCombatManager extends Combat { | |||||||
|     ].concat(options); |     ].concat(options); | ||||||
|   } |   } | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static rollInitiativeAction(combatantId, action) { |   static async rollInitiativeAction(combatantId, action) { | ||||||
|     const combatant = game.combat.combatants.get(combatantId) |     const combatant = game.combat.combatants.get(combatantId) | ||||||
|     const actor = RdDCombatManager.getActorCombatant(combatant) |     const actor = RdDCombatManager.getActorCombatant(combatant) | ||||||
|     if (actor == undefined) { return [] } |     if (actor == undefined) { return [] } | ||||||
| @@ -305,10 +229,11 @@ export class RdDCombatManager extends Combat { | |||||||
|     combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0 |     combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0 | ||||||
|  |  | ||||||
|     const init = RdDCombatManager.getInitData(actor, action) |     const init = RdDCombatManager.getInitData(actor, action) | ||||||
|     const ajustement = RdDCombatManager.calculAjustementInit(actor, action) |     const ajustement = RdDCombatManager.calculAjustementInit(actor, action.arme) | ||||||
|     const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement); |     const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement); | ||||||
|  |  | ||||||
|     game.combat.rollInitRdD(combatantId, rollFormula, init); |     await game.combat.rollInitRdD(combatantId, rollFormula, init); | ||||||
|  |     combatant.initiativeData | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getInitData(actor, action) { |   static getInitData(actor, action) { | ||||||
| @@ -318,12 +243,12 @@ export class RdDCombatManager extends Combat { | |||||||
|     if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } } |     if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } } | ||||||
|     if (action.action == 'haut-reve') { return { offset: 9, info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } } |     if (action.action == 'haut-reve') { return { offset: 9, info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } } | ||||||
|  |  | ||||||
|     const comp = RdDItemCompetence.findCompetence(actor.items, action.system.competence); |     const comp = action.comp | ||||||
|     return { |     return { | ||||||
|       offset: RdDCombatManager.initOffset(comp?.system.categorie, action), |       offset: RdDCombatManager.initOffset(comp?.system.categorie, action.arme), | ||||||
|       info: action.name + " / " + action.system.competence, |       info: action.name + " / " + comp.name, | ||||||
|       carac: actor.getCaracInit(comp), |       carac: actor.getCaracInit(comp), | ||||||
|       niveau: comp?.system.niveau ?? -8 |       niveau: comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(action.main) ? -8 : -6) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -366,7 +291,7 @@ export class RdDCombatManager extends Combat { | |||||||
|     const possessions = actor.listActionsPossessions() |     const possessions = actor.listActionsPossessions() | ||||||
|     const actions = possessions.length > 0 |     const actions = possessions.length > 0 | ||||||
|       ? possessions |       ? possessions | ||||||
|       : actor.listActionsCombat() |       : actor.listActions({ isEquipe: true }) | ||||||
|  |  | ||||||
|     for (let index = 0; index < actions.length; index++) { |     for (let index = 0; index < actions.length; index++) { | ||||||
|       actions[index].index = index |       actions[index].index = index | ||||||
| @@ -710,8 +635,9 @@ export class RdDCombat { | |||||||
|     if (taille <= 20) return { msg: "ogre", diff: 2 }; |     if (taille <= 20) return { msg: "ogre", diff: 2 }; | ||||||
|     return { msg: "gigantesque", diff: 4 }; |     return { msg: "gigantesque", diff: 4 }; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   _ajustementMouvement(defender) { |   _ajustementMouvement(defender) { | ||||||
|     if (defender.getSurprise(true)) return { msg: "immobile (surprise)", diff: 0 }; |     if (defender.getSurprise(true) != '') return { msg: "immobile (surprise)", diff: 0 }; | ||||||
|     if (game.combat?.combatants.find(it => it.actorId == defender.id)) return { msg: "en mouvement (combat)", diff: -4 }; |     if (game.combat?.combatants.find(it => it.actorId == defender.id)) return { msg: "en mouvement (combat)", diff: -4 }; | ||||||
|     return { msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3 }; |     return { msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3 }; | ||||||
|   } |   } | ||||||
| @@ -775,7 +701,7 @@ export class RdDCombat { | |||||||
|       // sans armes: à mains nues |       // sans armes: à mains nues | ||||||
|       rollData.arme = RdDItemArme.corpsACorps(this.attacker) |       rollData.arme = RdDItemArme.corpsACorps(this.attacker) | ||||||
|       rollData.arme.system.niveau = competence.system.niveau |       rollData.arme.system.niveau = competence.system.niveau | ||||||
|       rollData.arme.system.initiative = RdDCombatManager.calculInitiative(competence.system.niveau, this.attacker.system.carac['melee'].value); |       rollData.arme.system.initiative = RdDInitiative.calculInitiative(competence.system.niveau, this.attacker.system.carac['melee'].value); | ||||||
|     } |     } | ||||||
|     return rollData; |     return rollData; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { RdDItemArme } from "./item-arme.js"; | import { RdDItemArme } from "./item/arme.js"; | ||||||
| import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; | ||||||
| import { ITEM_TYPES } from "./constants.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
|  |  | ||||||
| @@ -22,13 +22,12 @@ export class RdDHotbar { | |||||||
|  |  | ||||||
|   static $macroNameSuffix(armeCompetence) { |   static $macroNameSuffix(armeCompetence) { | ||||||
|     switch (armeCompetence) { |     switch (armeCompetence) { | ||||||
|       case 'unemain': return ' (1 main)'; |       case '(1 main)': return ' (1 main)'; | ||||||
|       case 'deuxmains': return ' (2 main)'; |       case '(2 mains)': return ' (2 main)'; | ||||||
|       case 'tir': return ' (tir)'; |       case 'tir': return ' (tir)'; | ||||||
|       case 'lancer': return ' (lancer)'; |       case 'lancer': return ' (lancer)'; | ||||||
|       case 'pugilat': return ' (pugilat)'; |       case 'pugilat': return ' (pugilat)'; | ||||||
|       case 'empoignade': return ' (empoignade)'; |       case 'empoignade': return ' (empoignade)'; | ||||||
|  |  | ||||||
|     } |     } | ||||||
|     return '' |     return '' | ||||||
|   } |   } | ||||||
| @@ -40,10 +39,10 @@ export class RdDHotbar { | |||||||
|           // Les armes peuvent avoir plusieurs usages |           // Les armes peuvent avoir plusieurs usages | ||||||
|           if (item.system.competence != '') { |           if (item.system.competence != '') { | ||||||
|             if (item.system.unemain) { |             if (item.system.unemain) { | ||||||
|               await this.createItemMacro(item, slot++, 'unemain') |               await this.createItemMacro(item, slot++, '(1 main)') | ||||||
|             } |             } | ||||||
|             if (item.system.deuxmains) { |             if (item.system.deuxmains) { | ||||||
|               await this.createItemMacro(item, slot++, 'deuxmains') |               await this.createItemMacro(item, slot++, '(2 mains)') | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|           if (item.system.lancer != '') { |           if (item.system.lancer != '') { | ||||||
| @@ -121,9 +120,9 @@ export class RdDHotbar { | |||||||
|         if (item.isCorpsACorps()) { |         if (item.isCorpsACorps()) { | ||||||
|           switch (categorieArme) { |           switch (categorieArme) { | ||||||
|             case 'pugilat': |             case 'pugilat': | ||||||
|               return actor.rollArme(RdDItemArme.corpsACorps(actor), 'competence'); |               return actor.rollArme(RdDItemArme.corpsACorps(actor)); | ||||||
|             case 'empoignade': |             case 'empoignade': | ||||||
|               return actor.rollArme(RdDItemArme.empoignade(actor), 'competence'); |               return actor.rollArme(RdDItemArme.empoignade(actor)); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         return actor.rollCompetence(item); |         return actor.rollCompetence(item); | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| import { SYSTEM_RDD, SYSTEM_SOCKET_ID, RDD_CONFIG } from "./constants.js" | import { SYSTEM_RDD, SYSTEM_SOCKET_ID, RDD_CONFIG, ITEM_TYPES } from "./constants.js" | ||||||
| import { Migrations } from './migrations.js' |  | ||||||
|  |  | ||||||
| import { RdDUtility } from "./rdd-utility.js" | import { RdDUtility } from "./rdd-utility.js" | ||||||
| import { TMRUtility } from "./tmr-utility.js" | import { TMRUtility } from "./tmr-utility.js" | ||||||
| @@ -11,7 +10,6 @@ import { DialogChronologie } from "./dialog-chronologie.js" | |||||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js" | import { RdDResolutionTable } from "./rdd-resolution-table.js" | ||||||
| import { RdDTokenHud } from "./rdd-token-hud.js" | import { RdDTokenHud } from "./rdd-token-hud.js" | ||||||
| import { RdDCommands } from "./rdd-commands.js" | import { RdDCommands } from "./rdd-commands.js" | ||||||
| import { RdDCombatManager, RdDCombat } from "./rdd-combat.js" |  | ||||||
| import { ChatUtility } from "./chat-utility.js" | import { ChatUtility } from "./chat-utility.js" | ||||||
| import { StatusEffects } from "./settings/status-effects.js" | import { StatusEffects } from "./settings/status-effects.js" | ||||||
| import { RdDCompendiumOrganiser } from "./rdd-compendium-organiser.js" | import { RdDCompendiumOrganiser } from "./rdd-compendium-organiser.js" | ||||||
| @@ -39,31 +37,40 @@ import { RdDActorEntiteSheet } from "./actor/entite-sheet.js" | |||||||
| import { RdDActorVehiculeSheet } from "./actor/vehicule-sheet.js" | import { RdDActorVehiculeSheet } from "./actor/vehicule-sheet.js" | ||||||
|  |  | ||||||
| import { RdDItem } from "./item.js" | import { RdDItem } from "./item.js" | ||||||
|  |  | ||||||
|  | import * as models from "./models/_module.mjs" | ||||||
|  | import * as items from "./documents/_module.mjs" | ||||||
|  | import * as sheets from "./applications/sheets/_module.mjs" | ||||||
|  |  | ||||||
|  | import { RdDItemArme } from "./item/arme.js" | ||||||
| import { RdDItemArmure } from "./item/armure.js" | import { RdDItemArmure } from "./item/armure.js" | ||||||
| import { RdDItemBlessure } from "./item/blessure.js" | import { RdDItemBlessure } from "./item/blessure.js" | ||||||
| import { RdDItemService } from "./item/service.js" | import { RdDItemGemme } from "./item/gemme.js" | ||||||
| import { RdDItemMaladie } from "./item/maladie.js" | import { RdDItemMaladie } from "./item/maladie.js" | ||||||
| import { RdDItemPoison } from "./item/poison.js" |  | ||||||
| import { RdDItemSigneDraconique } from "./item/signedraconique.js" |  | ||||||
| import { RdDItemQueue } from "./item/queue.js" |  | ||||||
| import { RdDItemOmbre } from "./item/ombre.js" | import { RdDItemOmbre } from "./item/ombre.js" | ||||||
| import { RdDItemSort } from "./item-sort.js" | import { RdDItemPoison } from "./item/poison.js" | ||||||
| import { RdDItemTete } from "./item/tete.js" | import { RdDItemPotion } from "./item/potion.js" | ||||||
|  | import { RdDItemQueue } from "./item/queue.js" | ||||||
|  | import { RdDItemService } from "./item/service.js" | ||||||
| import { RdDItemRace } from "./item/race.js" | import { RdDItemRace } from "./item/race.js" | ||||||
|  | import { RdDItemSigneDraconique } from "./item/signedraconique.js" | ||||||
|  | import { RdDItemSort } from "./item-sort.js" | ||||||
| import { RdDItemSouffle } from "./item/souffle.js" | import { RdDItemSouffle } from "./item/souffle.js" | ||||||
|  | import { RdDItemTete } from "./item/tete.js" | ||||||
| import { RdDRencontre } from "./item/rencontre.js" | import { RdDRencontre } from "./item/rencontre.js" | ||||||
|  |  | ||||||
| import { RdDItemSheetV1 } from "./item-sheet.js" | import { RdDItemSheetV1 } from "./item-sheet.js" | ||||||
| import { RdDBlessureItemSheet } from "./item/sheet-blessure.js" | import { RdDBlessureItemSheet } from "./item/sheet-blessure.js" | ||||||
| import { RdDServiceItemSheet } from "./item/sheet-service.js" |  | ||||||
| import { RdDRencontreItemSheet } from "./item/sheet-rencontre.js" |  | ||||||
| import { RdDHerbeItemSheet } from "./item/sheet-herbe.js" |  | ||||||
| import { RdDPlanteItemSheet } from "./item/sheet-plante.js" |  | ||||||
| import { RdDIngredientItemSheet } from "./item/sheet-ingredient.js" |  | ||||||
| import { RdDFauneItemSheet } from "./item/sheet-faune.js" |  | ||||||
| import { RdDConteneurItemSheet } from "./item/sheet-conteneur.js" | import { RdDConteneurItemSheet } from "./item/sheet-conteneur.js" | ||||||
| import { RdDItemInventaireSheet } from "./item/sheet-base-inventaire.js" | import { RdDGemmeItemSheet } from "./item/sheet-gemme.js" | ||||||
|  | import { RdDHerbeItemSheet } from "./item/sheet-herbe.js" | ||||||
|  | import { RdDFauneItemSheet } from "./item/sheet-faune.js" | ||||||
|  | import { RdDIngredientItemSheet } from "./item/sheet-ingredient.js" | ||||||
|  | import { RdDInventaireItemSheet } from "./item/sheet-base-inventaire.js" | ||||||
|  | import { RdDPlanteItemSheet } from "./item/sheet-plante.js" | ||||||
|  | import { RdDPotionItemSheet } from "./item/sheet-potion.js" | ||||||
|  | import { RdDRencontreItemSheet } from "./item/sheet-rencontre.js" | ||||||
|  | import { RdDServiceItemSheet } from "./item/sheet-service.js" | ||||||
| import { RdDSigneDraconiqueItemSheet } from "./item/sheet-signedraconique.js" | import { RdDSigneDraconiqueItemSheet } from "./item/sheet-signedraconique.js" | ||||||
|  |  | ||||||
| import { AppAstrologie } from "./sommeil/app-astrologie.js" | import { AppAstrologie } from "./sommeil/app-astrologie.js" | ||||||
| @@ -75,14 +82,10 @@ import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire. | |||||||
| import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" | import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" | ||||||
| import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" | import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" | ||||||
| import { RdDJournalSheet } from "./journal/journal-sheet.js" | import { RdDJournalSheet } from "./journal/journal-sheet.js" | ||||||
| import { RdDPotionItemSheet } from "./item/sheet-potion.js" | import { RdDCombatManager, RdDCombat } from "./rdd-combat.js" | ||||||
| import { RdDItemPotion } from "./item/potion.js" | import { Migrations } from './migrations.js' | ||||||
| import { RdDItemGemme } from "./item/gemme.js" |  | ||||||
| import { RdDGemmeItemSheet } from "./item/sheet-gemme.js" |  | ||||||
|  |  | ||||||
| import * as models from "./models/_module.mjs" | import RollDialog from "./roll/roll-dialog.mjs" | ||||||
| import * as items from "./documents/_module.mjs" |  | ||||||
| import * as sheets from "./applications/sheets/_module.mjs" |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * RdD system |  * RdD system | ||||||
| @@ -106,7 +109,7 @@ export class SystemReveDeDragon { | |||||||
|     this.itemClasses = { |     this.itemClasses = { | ||||||
|       monnaie: items.RdDItemMonnaie, |       monnaie: items.RdDItemMonnaie, | ||||||
|       munition: items.RdDItemMunition, |       munition: items.RdDItemMunition, | ||||||
|       tarot: items.RdDModelTarot, |       arme: RdDItemArme, | ||||||
|       armure: RdDItemArmure, |       armure: RdDItemArmure, | ||||||
|       blessure: RdDItemBlessure, |       blessure: RdDItemBlessure, | ||||||
|       gemme: RdDItemGemme, |       gemme: RdDItemGemme, | ||||||
| @@ -120,6 +123,7 @@ export class SystemReveDeDragon { | |||||||
|       service: RdDItemService, |       service: RdDItemService, | ||||||
|       signedraconique: RdDItemSigneDraconique, |       signedraconique: RdDItemSigneDraconique, | ||||||
|       souffle: RdDItemSouffle, |       souffle: RdDItemSouffle, | ||||||
|  |       tarot: items.RdDModelTarot, | ||||||
|       tete: RdDItemTete, |       tete: RdDItemTete, | ||||||
|     } |     } | ||||||
|     this.actorClasses = { |     this.actorClasses = { | ||||||
| @@ -206,11 +210,16 @@ export class SystemReveDeDragon { | |||||||
|     foundry.documents.collections.Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true }) |     foundry.documents.collections.Actors.registerSheet(SYSTEM_RDD, RdDActorVehiculeSheet, { types: ["vehicule"], makeDefault: true }) | ||||||
|     foundry.documents.collections.Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true }) |     foundry.documents.collections.Actors.registerSheet(SYSTEM_RDD, RdDActorEntiteSheet, { types: ["entite"], makeDefault: true }) | ||||||
|     foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet) |     foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet) | ||||||
|  |  | ||||||
|     RdDActorExportSheet.init() |     RdDActorExportSheet.init() | ||||||
|  |  | ||||||
|     foundry.documents.collections.Items.registerSheet(SYSTEM_RDD, RdDItemInventaireSheet, { |     foundry.documents.collections.Items.registerSheet(SYSTEM_RDD, RdDInventaireItemSheet, { | ||||||
|       types: [ |       types: [ | ||||||
|         "objet", "arme", "armure", "livre", "nourritureboisson", |         ITEM_TYPES.objet, | ||||||
|  |         ITEM_TYPES.arme, | ||||||
|  |         ITEM_TYPES.armure, | ||||||
|  |         ITEM_TYPES.livre, | ||||||
|  |         ITEM_TYPES.nourritureboisson, | ||||||
|       ], |       ], | ||||||
|       makeDefault: true |       makeDefault: true | ||||||
|     }) |     }) | ||||||
| @@ -223,12 +232,31 @@ export class SystemReveDeDragon { | |||||||
|  |  | ||||||
|     foundry.documents.collections.Items.registerSheet(SYSTEM_RDD, RdDItemSheetV1, { |     foundry.documents.collections.Items.registerSheet(SYSTEM_RDD, RdDItemSheetV1, { | ||||||
|       types: [ |       types: [ | ||||||
|         "competence", "competencecreature", |         ITEM_TYPES.competence, | ||||||
|         "recettealchimique", "musique", "chant", "danse", "jeu", "race", |         ITEM_TYPES.competencecreature, | ||||||
|         "recettecuisine", "oeuvre", "meditation", |         ITEM_TYPES.recettealchimique, | ||||||
|         "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve", |         ITEM_TYPES.musique, | ||||||
|         "nombreastral", "tache", "maladie", "poison", "possession", |         ITEM_TYPES.chant, | ||||||
|         "extraitpoetique", "empoignade" |         ITEM_TYPES.danse, | ||||||
|  |         ITEM_TYPES.jeu, | ||||||
|  |         ITEM_TYPES.race, | ||||||
|  |         ITEM_TYPES.recettecuisine, | ||||||
|  |         ITEM_TYPES.oeuvre,  | ||||||
|  |         ITEM_TYPES.meditation, | ||||||
|  |         ITEM_TYPES.queue, | ||||||
|  |         ITEM_TYPES.ombre,  | ||||||
|  |         ITEM_TYPES.souffle,  | ||||||
|  |         ITEM_TYPES.tete, | ||||||
|  |         ITEM_TYPES.casetmr, | ||||||
|  |         ITEM_TYPES.sort, | ||||||
|  |         ITEM_TYPES.sortreserve, | ||||||
|  |         ITEM_TYPES.nombreastral, | ||||||
|  |         ITEM_TYPES.tache, | ||||||
|  |         ITEM_TYPES.maladie, | ||||||
|  |         ITEM_TYPES.poison, | ||||||
|  |         ITEM_TYPES.possession, | ||||||
|  |         ITEM_TYPES.extraitpoetique, | ||||||
|  |         ITEM_TYPES.empoignade | ||||||
|       ], |       ], | ||||||
|       makeDefault: true |       makeDefault: true | ||||||
|     }) |     }) | ||||||
| @@ -263,6 +291,7 @@ export class SystemReveDeDragon { | |||||||
|     RdDPossession.init() |     RdDPossession.init() | ||||||
|     TMRRencontres.init() |     TMRRencontres.init() | ||||||
|     ExportScriptarium.init() |     ExportScriptarium.init() | ||||||
|  |     RollDialog.init() | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   initSettings() { |   initSettings() { | ||||||
| @@ -346,7 +375,7 @@ export class SystemReveDeDragon { | |||||||
|  |  | ||||||
|     StatusEffects.onReady() |     StatusEffects.onReady() | ||||||
|     RdDDice.onReady() |     RdDDice.onReady() | ||||||
|  |     RollDialog.onReady() | ||||||
|     RdDStatBlockParser.parseStatBlock() |     RdDStatBlockParser.parseStatBlock() | ||||||
|     /* -------------------------------------------- */ |     /* -------------------------------------------- */ | ||||||
|     /* Affiche/Init le calendrier */ |     /* Affiche/Init le calendrier */ | ||||||
| @@ -375,6 +404,10 @@ export class SystemReveDeDragon { | |||||||
|       ` }) |       ` }) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   roll(rollData, actors, options){ | ||||||
|  |     RollDialog.create(rollData, actors, options) | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| SystemReveDeDragon.start() | SystemReveDeDragon.start() | ||||||
|   | |||||||
| @@ -109,7 +109,7 @@ export class RdDResolutionTable { | |||||||
|     rolled.caracValue = caracValue; |     rolled.caracValue = caracValue; | ||||||
|     rolled.finalLevel = finalLevel; |     rolled.finalLevel = finalLevel; | ||||||
|     rolled.bonus = rollData.bonus; |     rolled.bonus = rollData.bonus; | ||||||
|     rolled.factorHtml = Misc.getFractionHtml(rollData.diviseurSignificative); |     rolled.factorHtml = Misc.getFractionOneN(rollData.diviseurSignificative); | ||||||
|  |  | ||||||
|     if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) { |     if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) { | ||||||
|       rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll); |       rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll); | ||||||
|   | |||||||
| @@ -123,7 +123,7 @@ export class RdDRollResolutionTable extends Dialog { | |||||||
|  |  | ||||||
|     // Mise à jour valeurs |     // Mise à jour valeurs | ||||||
|     this.html.find("[name='carac']").val(rollData.caracValue); |     this.html.find("[name='carac']").val(rollData.caracValue); | ||||||
|     this.html.find(".roll-param-resolution").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel)); |     this.html.find(".roll-part-resolution").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel)); | ||||||
|     this.html.find("div.placeholder-resolution").empty().append(htmlTable) |     this.html.find("div.placeholder-resolution").empty().append(htmlTable) | ||||||
|  |  | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -5,7 +5,8 @@ export class RdDRollResult { | |||||||
|   static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.hbs') { |   static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.hbs') { | ||||||
|     const chatMessage = await ChatUtility.createChatWithRollMode( |     const chatMessage = await ChatUtility.createChatWithRollMode( | ||||||
|       { content: await RdDRollResult.buildRollDataHtml(rollData, template) }, |       { content: await RdDRollResult.buildRollDataHtml(rollData, template) }, | ||||||
|       actor |       actor, | ||||||
|  |       rollData.current?.rollmode?.key | ||||||
|     ) |     ) | ||||||
|     return chatMessage |     return chatMessage | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -39,8 +39,8 @@ export class RdDRoll extends Dialog { | |||||||
|       difficultesLibres: CONFIG.RDD.difficultesLibres, |       difficultesLibres: CONFIG.RDD.difficultesLibres, | ||||||
|       etat: actor.getEtatGeneral(), |       etat: actor.getEtatGeneral(), | ||||||
|       moral: actor.getMoralTotal(), /* La valeur du moral pour les jets de volonté */ |       moral: actor.getMoralTotal(), /* La valeur du moral pour les jets de volonté */ | ||||||
|       amoureux: actor.listeSuivants(it => it.coeur > 0), |       amoureux: actor.listeAmoureux(), | ||||||
|       carac: actor.system.carac, |       carac: foundry.utils.duplicate(actor.system.carac), | ||||||
|       finalLevel: 0, |       finalLevel: 0, | ||||||
|       diffConditions: 0, |       diffConditions: 0, | ||||||
|       diffLibre: rollData.competence?.system.default_diffLibre ?? 0, |       diffLibre: rollData.competence?.system.default_diffLibre ?? 0, | ||||||
| @@ -54,7 +54,7 @@ export class RdDRoll extends Dialog { | |||||||
|         surenc: actor.isSurenc(), |         surenc: actor.isSurenc(), | ||||||
|         encTotal: true |         encTotal: true | ||||||
|       }, |       }, | ||||||
|       isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence), |       isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence?.name), | ||||||
|       encTotal: actor.getEncTotal(), |       encTotal: actor.getEncTotal(), | ||||||
|       ajustementAstrologique: actor.ajustementAstrologique(), |       ajustementAstrologique: actor.ajustementAstrologique(), | ||||||
|       surprise: actor.getSurprise(false), |       surprise: actor.getSurprise(false), | ||||||
| @@ -314,15 +314,15 @@ export class RdDRoll extends Dialog { | |||||||
|     rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor) |     rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor) | ||||||
|     rollData.caracValue = parseInt(rollData.selectedCarac.value) |     rollData.caracValue = parseInt(rollData.selectedCarac.value) | ||||||
|     rollData.dmg.mortalite = rollData.dmg.mortalite ?? 'mortel'; |     rollData.dmg.mortalite = rollData.dmg.mortalite ?? 'mortel'; | ||||||
|     rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac); |     rollData.use.appelAuMoral = this.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac?.label); | ||||||
|  |  | ||||||
|     RollDataAjustements.calcul(rollData, this.actor); |     RollDataAjustements.calcul(rollData, this.actor); | ||||||
|  |  | ||||||
|     const resolutionTable = await RdDResolutionTable.buildHTMLTable(RdDResolutionTable.subTable(rollData.caracValue, rollData.finalLevel)) |     const resolutionTable = await RdDResolutionTable.buildHTMLTable(RdDResolutionTable.subTable(rollData.caracValue, rollData.finalLevel)) | ||||||
|     const adjustements = await this.buildAjustements(rollData); |     const adjustements = await this.buildAjustements(rollData); | ||||||
|  |  | ||||||
|     HtmlUtility.showControlWhen(this.html.find(".use-encTotal"), rollData.ajustements.encTotal.visible && RdDCarac.isAgiliteOuDerobee(rollData.selectedCarac)); |     HtmlUtility.showControlWhen(this.html.find(".use-encTotal"), rollData.ajustements.encTotal.visible && RdDCarac.isAgiliteOuDerobee(rollData.selectedCarac?.label)); | ||||||
|     HtmlUtility.showControlWhen(this.html.find(".use-surenc"), rollData.ajustements.surenc.visible && RdDCarac.isActionPhysique(rollData.selectedCarac)); |     HtmlUtility.showControlWhen(this.html.find(".use-surenc"), rollData.ajustements.surenc.visible && RdDCarac.isActionPhysique(rollData.selectedCarac?.label)); | ||||||
|     HtmlUtility.showControlWhen(this.html.find(".use-astrologique"), rollData.ajustements.astrologique.visible); |     HtmlUtility.showControlWhen(this.html.find(".use-astrologique"), rollData.ajustements.astrologique.visible); | ||||||
|     HtmlUtility.showControlWhen(this.html.find(".utilisation-moral"), rollData.use.appelAuMoral); |     HtmlUtility.showControlWhen(this.html.find(".utilisation-moral"), rollData.use.appelAuMoral); | ||||||
|     HtmlUtility.showControlWhen(this.html.find(".divAppelAuMoral"), rollData.use.appelAuMoral); |     HtmlUtility.showControlWhen(this.html.find(".divAppelAuMoral"), rollData.use.appelAuMoral); | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { SHOW_DICE, SYSTEM_RDD } from "./constants.js"; | import { SHOW_DICE, SYSTEM_RDD } from "./constants.js"; | ||||||
| import { RollDataAjustements } from "./rolldata-ajustements.js"; | import { RollDataAjustements } from "./rolldata-ajustements.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
| import { TMRUtility } from "./tmr-utility.js"; | import { COORD_TMR_INCONNU, TMRUtility } from "./tmr-utility.js"; | ||||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||||
| import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js"; | import { RdDTMRRencontreDialog } from "./rdd-tmr-rencontre-dialog.js"; | ||||||
| import { ChatUtility } from "./chat-utility.js"; | import { ChatUtility } from "./chat-utility.js"; | ||||||
| @@ -996,6 +996,10 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     const targetOddq = this.pixiTMR.computeEventOddq(event) |     const targetOddq = this.pixiTMR.computeEventOddq(event) | ||||||
|     const targetCoord = TMRUtility.oddqToCoordTMR(targetOddq) |     const targetCoord = TMRUtility.oddqToCoordTMR(targetOddq) | ||||||
|  |  | ||||||
|  |     if (targetCoord == COORD_TMR_INCONNU){ | ||||||
|  |       ui.notifications.error("Vous ne pouvez pas vous déplacer ici"); | ||||||
|  |       return | ||||||
|  |     } | ||||||
|     // Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter) |     // Validation de la case de destination (gestion du cas des rencontres qui peuvent téléporter) | ||||||
|     const typeDeplacement = this._calculDeplacement(targetCoord, currentCoord, currentOddq, targetOddq); |     const typeDeplacement = this._calculDeplacement(targetCoord, currentCoord, currentOddq, targetOddq); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| import { HtmlUtility } from "./html-utility.js"; | import { HtmlUtility } from "./html-utility.js"; | ||||||
| import { Misc } from "./misc.js"; |  | ||||||
| import { RdDCombatManager } from "./rdd-combat.js"; | import { RdDCombatManager } from "./rdd-combat.js"; | ||||||
| import { Targets } from "./targets.js"; | import { Targets } from "./targets.js"; | ||||||
|  |  | ||||||
| @@ -31,11 +30,11 @@ export class RdDTokenHud { | |||||||
|       const combatant = game.combat.combatants.find(c => c.tokenId == tokenId) |       const combatant = game.combat.combatants.find(c => c.tokenId == tokenId) | ||||||
|       const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false }) |       const actor = RdDCombatManager.getActorCombatant(combatant, { warning: false }) | ||||||
|       if (actor) { |       if (actor) { | ||||||
|         let actions = RdDCombatManager.listActionsActorCombatant(actor) |         const actions = RdDCombatManager.listActionsActorCombatant(actor) | ||||||
|         // initiative |         // initiative | ||||||
|         await RdDTokenHud.addExtensionHudInit(html, combatant, actions) |         await RdDTokenHud.addExtensionHudInit(html, combatant, actions) | ||||||
|         // combat |         // combat | ||||||
|         await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions) |         await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions.filter(it => !it.initOnly)) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -68,18 +67,19 @@ export class RdDTokenHud { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async addExtensionHudCombat(html, combatant, token, actions) { |   static async addExtensionHudCombat(html, combatant, token, actions) { | ||||||
|  |  | ||||||
|     const hudData = { combatant, token, actions, commandes: [] }; |     const hudData = { combatant, token, actions, commandes: [] }; | ||||||
|     const controlIconTarget = $(html).find('.control-icon[data-action=target]'); |     const controlIconTarget = $(html).find('.control-icon[data-action=target]'); | ||||||
|     await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs', hudData, |     await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs', hudData, | ||||||
|       (event) => { |       (event) => { | ||||||
|         const actionIndex = event.currentTarget.attributes['data-action-index']?.value; |         const actionIndex = event.currentTarget.attributes['data-action-index']?.value; | ||||||
|         const action = hudData.actions[actionIndex]; |         const action = hudData.actions[actionIndex]; | ||||||
|         const possession = action.action == 'possession' ? combatant.actor.getPossession(action.system.possessionid) : undefined; |         const possession = action.action == 'possession' ? combatant.actor.getPossession(action.possessionid) : undefined; | ||||||
|         if (possession) { |         if (possession) { | ||||||
|           combatant.actor.conjurerPossession(possession); |           combatant.actor.conjurerPossession(possession); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|           combatant.actor.rollArme(action, 'competence', token) |           combatant.actor.rollArme(action.arme, action.main, token) | ||||||
|         } |         } | ||||||
|       }); |       }); | ||||||
|   } |   } | ||||||
| @@ -89,7 +89,7 @@ export class RdDTokenHud { | |||||||
|     if (target?.actor) { |     if (target?.actor) { | ||||||
|       const hudSoins = { blessures: target.actor.blessuresASoigner() ?? [] }; |       const hudSoins = { blessures: target.actor.blessuresASoigner() ?? [] }; | ||||||
|       if (hudSoins.blessures.length > 0) { |       if (hudSoins.blessures.length > 0) { | ||||||
|         const controlIconTarget = html.find('.control-icon[data-action=combat]'); |         const controlIconTarget = $(html).find('.control-icon[data-action=combat]'); | ||||||
|         await RdDTokenHud._configureSubMenu(controlIconTarget, |         await RdDTokenHud._configureSubMenu(controlIconTarget, | ||||||
|           'systems/foundryvtt-reve-de-dragon/templates/hud-actor-soins.hbs', |           'systems/foundryvtt-reve-de-dragon/templates/hud-actor-soins.hbs', | ||||||
|           hudSoins, |           hudSoins, | ||||||
|   | |||||||
| @@ -221,6 +221,7 @@ export class RdDUtility { | |||||||
|       'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/partial-description-overflow.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/partial-description-sort.hbs', | ||||||
|  |       'systems/foundryvtt-reve-de-dragon/templates/partial-description.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-astrologique.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-astrologique.hbs', | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-coeur.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/partial-roll-coeur.hbs', | ||||||
| @@ -273,7 +274,8 @@ export class RdDUtility { | |||||||
|     Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name)); |     Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name)); | ||||||
|     Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionnelles.isUsing(option)); |     Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionnelles.isUsing(option)); | ||||||
|  |  | ||||||
|     Handlebars.registerHelper('plusMoins', diff => (diff > 0 ? '+' : '') + Math.round(diff)) |     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 |     // Handle v12 removal of this helper | ||||||
|     Handlebars.registerHelper('select', function (selected, options) { |     Handlebars.registerHelper('select', function (selected, options) { | ||||||
| @@ -318,6 +320,7 @@ export class RdDUtility { | |||||||
|     // gestion des dates et heures |     // gestion des dates et heures | ||||||
|     Handlebars.registerHelper('timestamp-imgSigneHeure', (heure) => { return new Handlebars.SafeString(RdDTimestamp.imgSigneHeure(heure)) }); |     Handlebars.registerHelper('timestamp-imgSigneHeure', (heure) => { return new Handlebars.SafeString(RdDTimestamp.imgSigneHeure(heure)) }); | ||||||
|     Handlebars.registerHelper('timestamp-imgSigne', (heure) => { return new Handlebars.SafeString(RdDTimestamp.imgSigne(heure)) }); |     Handlebars.registerHelper('timestamp-imgSigne', (heure) => { return new Handlebars.SafeString(RdDTimestamp.imgSigne(heure)) }); | ||||||
|  |     Handlebars.registerHelper('timestamp-label', (heure) => RdDTimestamp.definition(heure)?.label ?? 'inconnue') | ||||||
|     Handlebars.registerHelper('timestamp-definition', (heure) => RdDTimestamp.definition(heure)) |     Handlebars.registerHelper('timestamp-definition', (heure) => RdDTimestamp.definition(heure)) | ||||||
|     Handlebars.registerHelper('timestamp-extract', timestamp => new RdDTimestamp(timestamp).toCalendrier()); |     Handlebars.registerHelper('timestamp-extract', timestamp => new RdDTimestamp(timestamp).toCalendrier()); | ||||||
|     Handlebars.registerHelper('timestamp-formulesDuree', () => RdDTimestamp.formulesDuree()); |     Handlebars.registerHelper('timestamp-formulesDuree', () => RdDTimestamp.formulesDuree()); | ||||||
| @@ -813,9 +816,8 @@ export class RdDUtility { | |||||||
|  |  | ||||||
|   static getSelectedToken(actor) { |   static getSelectedToken(actor) { | ||||||
|     if (canvas.tokens.controlled.length > 0) { |     if (canvas.tokens.controlled.length > 0) { | ||||||
|       const tokens = canvas.tokens.controlled |       return canvas.tokens.controlled | ||||||
|         .filter(it => it.actor.id == actor.id) |         .find(it => it.actor.id == actor.id) | ||||||
|       return tokens[0] |  | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										60
									
								
								module/roll/roll-basic-parts.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,60 @@ | |||||||
|  | import { ActorToken } from "../actor-token.mjs" | ||||||
|  |  | ||||||
|  | export class RollBasicParts { | ||||||
|  |  | ||||||
|  |   restore(rollData) { | ||||||
|  |     rollData.ids.sceneId = rollData.ids.sceneId ?? canvas.scene.id | ||||||
|  |     rollData.active = RollBasicParts.$getActor(rollData) | ||||||
|  |     rollData.opponent = RollBasicParts.$getOpponent(rollData) | ||||||
|  |     if (rollData.mode.opposed == undefined) { | ||||||
|  |       rollData.mode.opposed = rollData.opponent != null | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   initFrom(rollData) { | ||||||
|  |     return { | ||||||
|  |       selected: {}, | ||||||
|  |       mode: { | ||||||
|  |         current: rollData.mode.current | ||||||
|  |       }, | ||||||
|  |       ids: { | ||||||
|  |         sceneId: rollData.ids.sceneId, | ||||||
|  |         actorId: rollData.active.id, | ||||||
|  |         actorTokenId: rollData.active.tokenId, | ||||||
|  |         opponentId: rollData.mode.opposed ? rollData.opponent.id : undefined, | ||||||
|  |         opponentTokenId: rollData.mode.opposed ? rollData.opponent.tokenId : undefined, | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $getActor(rollData) { | ||||||
|  |     if (rollData.ids.actorTokenId) { | ||||||
|  |       return ActorToken.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId) | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       const actorId = rollData.ids.actorId ?? (canvas.tokens.controlled.length == 1 | ||||||
|  |         /** TODO: jets de plusieurs personnages??? */ | ||||||
|  |         ? canvas.tokens.controlled[0] | ||||||
|  |         : undefined) | ||||||
|  |       return ActorToken.fromActorId(actorId, () => { throw new Error("Pas d'acteur sélectionné") }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $getOpponent(rollData) { | ||||||
|  |     if (rollData.ids.opponentTokenId) { | ||||||
|  |       return ActorToken.fromTokenId(rollData.ids.opponentTokenId, rollData.ids.sceneId) | ||||||
|  |     } | ||||||
|  |     else if (rollData.ids.opponentId) { | ||||||
|  |       return ActorToken.fromActorId(rollData.ids.opponentId) | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       const targets = Array.from(game.user.targets) | ||||||
|  |       if (targets.length == 1) { | ||||||
|  |         return ActorToken.fromToken(targets[0]) | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         return undefined | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								module/roll/roll-constants.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,28 @@ | |||||||
|  |  | ||||||
|  | export const ROLL_MODE_ATTAQUE = 'attaque' | ||||||
|  | export const ROLL_MODE_COMP = 'comp' | ||||||
|  | export const ROLL_MODE_DEFENSE = 'defense' | ||||||
|  | export const ROLL_MODE_JEU = 'jeu' | ||||||
|  | export const ROLL_MODE_MEDITATION = 'meditation' | ||||||
|  | export const ROLL_MODE_OEUVRE = 'oeuvre' | ||||||
|  | export const ROLL_MODE_SORT = 'sort' | ||||||
|  | export const ROLL_MODE_TACHE = 'tache' | ||||||
|  |  | ||||||
|  | export const DIFF_MODE = { | ||||||
|  |   LIBRE: 'libre', | ||||||
|  |   ATTAQUE: 'attaque', | ||||||
|  |   IMPOSEE: 'imposee', | ||||||
|  |   DEFENSE: 'defense', | ||||||
|  |   DEFAUT: 'defaut', | ||||||
|  |   AUCUN: 'aucun' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const DIFF_MODES = { | ||||||
|  |   [DIFF_MODE.LIBRE]: { key: DIFF_MODE.LIBRE, label: "Difficulté libre", libre: true, visible: true, max: 0 }, | ||||||
|  |   [DIFF_MODE.ATTAQUE]: { key: DIFF_MODE.ATTAQUE, label: "Difficulté d'attaque", libre: true, visible: true, max: 0 }, | ||||||
|  |   [DIFF_MODE.IMPOSEE]: { key: DIFF_MODE.IMPOSEE, label: "Diffficulté imposée", libre: false, visible: true, max: 0 }, | ||||||
|  |   [DIFF_MODE.DEFENSE]: { key: DIFF_MODE.DEFENSE, label: "Diffficulté défense", libre: false, visible: true, max: 0 }, | ||||||
|  |   [DIFF_MODE.DEFAUT]: { key: DIFF_MODE.DEFAUT, label: "Difficulté", libre: true, visible: true, max: 5 }, | ||||||
|  |   [DIFF_MODE.AUCUN]: { key: DIFF_MODE.AUCUN, label: "", libre: false, visible: false, max: 0 }, | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										90
									
								
								module/roll/roll-dialog-adapter.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,90 @@ | |||||||
|  | import { Misc } from "../misc.js"; | ||||||
|  | import { PART_APPELMORAL } from "./roll-part-appelmoral.mjs"; | ||||||
|  | import { PART_COMP } from "./roll-part-comp.mjs"; | ||||||
|  | import { RdDResolutionTable } from "../rdd-resolution-table.js"; | ||||||
|  | import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | ||||||
|  | import { PART_OEUVRE } from "./roll-part-oeuvre.mjs"; | ||||||
|  |  | ||||||
|  | /* -------------------------------------------- */ | ||||||
|  | export class RollDialogAdapter { | ||||||
|  |  | ||||||
|  |   async rollDice(rollData, rollTitle) { | ||||||
|  |     const chances = this.computeChances({ | ||||||
|  |       carac: rollData.current.carac.value, | ||||||
|  |       diff: rollData.current.totaldiff, | ||||||
|  |       bonus: rollData.current.bonus, | ||||||
|  |       sign: rollData.current.sign, | ||||||
|  |       showDice: rollData.options.showDice, | ||||||
|  |       rollMode: rollData.current.rollmode.key | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     const rolled = await this.rollChances(rollData, chances) | ||||||
|  |     this.adjustRollDataForV1(rollData, rolled, rollTitle) | ||||||
|  |  | ||||||
|  |     return rolled | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   computeChances({ carac, diff, bonus, sign, showDice, rollMode }) { | ||||||
|  |     const chances = foundry.utils.duplicate(RdDResolutionTable.computeChances(carac, diff)) | ||||||
|  |     RdDResolutionTable._updateChancesWithBonus(chances, bonus, diff) | ||||||
|  |     RdDResolutionTable._updateChancesFactor(chances, sign) | ||||||
|  |     chances.showDice = showDice | ||||||
|  |     chances.rollMode = rollMode | ||||||
|  |     return chances | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async rollChances(rollData, chances) { | ||||||
|  |     const rolled = await RdDResolutionTable.rollChances(chances, rollData.current.sign, rollData.current.resultat) | ||||||
|  |     rolled.caracValue = rollData.current.carac.value | ||||||
|  |     rolled.finalLevel = rollData.current.totaldiff | ||||||
|  |     rolled.bonus = rollData.current.bonus ?? 0 | ||||||
|  |     rolled.factorHtml = Misc.getFractionOneN(rollData.current.sign.diviseur) | ||||||
|  |     return rolled | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   adjustRollDataForV1(rollData, rolled, rollTitle) { | ||||||
|  |     // temporaire pour être homogène roll v1 | ||||||
|  |     rollData.alias = rollData.active.actor.getAlias() | ||||||
|  |     // pour experience | ||||||
|  |     rollData.finalLevel = rollData.current.totaldiff | ||||||
|  |     if (rollData.use == undefined) { rollData.use = {} } | ||||||
|  |     if (rollData.show == undefined) { rollData.show = {} } | ||||||
|  |     if (rollData.ajustements == undefined) { | ||||||
|  |       rollData.ajustements = {} | ||||||
|  |     } | ||||||
|  |     rollData.selectedCarac = rollData.active.actor.system.carac[rollData.current.carac.key] | ||||||
|  |  | ||||||
|  |     const compKey = rollData.current.comp?.key | ||||||
|  |     if (compKey) { | ||||||
|  |       rollData.competence = rollData.refs[PART_COMP].all.find(it => it.key == compKey)?.comp | ||||||
|  |       rollData.jetResistance = rollData.mode.jetResistance | ||||||
|  |     } | ||||||
|  |     const oeuvreKey = rollData.current.oeuvre?.key | ||||||
|  |     if (oeuvreKey) { | ||||||
|  |       const oeuvreCurrent = rollData.current[PART_OEUVRE]; | ||||||
|  |       rollData.oeuvre = oeuvreCurrent.oeuvre | ||||||
|  |       // rollData.oeuvre = rollData.refs[PART_OEUVRE].oeuvres.find(it => it.key == oeuvreKey)?.oeuvre | ||||||
|  |       rollData.art = oeuvreCurrent.art.type | ||||||
|  |     } | ||||||
|  |     // pour appel moral | ||||||
|  |     rollData.diviseurSignificative = rollData.current.sign | ||||||
|  |     if (rollData.current[PART_APPELMORAL]?.checked) { | ||||||
|  |       rollData.use.moral = true | ||||||
|  |     } | ||||||
|  |     rollData.rolled = rolled | ||||||
|  |     if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) { | ||||||
|  |       rolled.niveauNecessaire = this.findNiveauNecessaire(carac, rolled.roll) | ||||||
|  |       rolled.ajustementNecessaire = rolled.niveauNecessaire - diff | ||||||
|  |     } | ||||||
|  |     rollData.ajustements = rollData.ajustements.map(aj => { | ||||||
|  |       return { | ||||||
|  |         used: true, | ||||||
|  |         label: aj.label, | ||||||
|  |         value: aj.diff, | ||||||
|  |         descr: aj.diff == undefined ? aj.label : undefined | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |     rollData.show.title = rollTitle | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										443
									
								
								module/roll/roll-dialog.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,443 @@ | |||||||
|  | import { Misc } from "../misc.js"; | ||||||
|  | import { RollModeComp } from "./roll-mode-comp.mjs"; | ||||||
|  | import { RollModeTache } from "./roll-mode-tache.mjs"; | ||||||
|  | import { RollModeAttaque } from "./roll-mode-attaque.mjs"; | ||||||
|  | import { RollModeDefense } from "./roll-mode-defense.mjs"; | ||||||
|  | import { RollModeMeditation } from "./roll-mode-meditation.mjs"; | ||||||
|  | import { RollModeSort } from "./roll-mode-sort.mjs"; | ||||||
|  | import { RollModeOeuvre } from "./roll-mode-oeuvre.mjs"; | ||||||
|  | import { RollModeJeu } from "./roll-mode-jeu.mjs"; | ||||||
|  |  | ||||||
|  | import { RollPartAction } from "./roll-part-action.mjs"; | ||||||
|  | import { RollPartActor } from "./roll-part-actor.mjs"; | ||||||
|  | import { RollPartAppelMoral } from "./roll-part-appelmoral.mjs"; | ||||||
|  | import { RollPartAstrologique } from "./roll-part-astrologique.mjs"; | ||||||
|  | import { RollPartCarac } from "./roll-part-carac.mjs"; | ||||||
|  | import { RollPartCoeur } from "./roll-part-coeur.mjs"; | ||||||
|  | import { PART_COMP, RollPartComp } from "./roll-part-comp.mjs"; | ||||||
|  | import { RollPartConditions } from "./roll-part-conditions.mjs"; | ||||||
|  | import { RollPartDiff } from "./roll-part-diff.mjs"; | ||||||
|  | import { RollPartEncTotal } from "./roll-part-enctotal.mjs"; | ||||||
|  | import { RollPartEtat } from "./roll-part-etat.mjs"; | ||||||
|  | import { RollPartEthylisme } from "./roll-part-ethylisme.mjs"; | ||||||
|  | import { RollPartMalusArmure } from "./roll-part-malusarmure.mjs"; | ||||||
|  | import { RollPartMeditation } from "./roll-part-meditation.mjs"; | ||||||
|  | import { RollPartMoral } from "./roll-part-moral.mjs"; | ||||||
|  | import { RollPartOpponent } from "./roll-part-opponent.mjs"; | ||||||
|  | import { RollPartSurEnc } from "./roll-part-surenc.mjs"; | ||||||
|  | import { RollPartTricher } from "./roll-part-tricher.mjs"; | ||||||
|  | import { RollPartTache } from "./roll-part-tache.mjs"; | ||||||
|  | import { RollPartOeuvre } from "./roll-part-oeuvre.mjs"; | ||||||
|  | import { RollPartSort } from "./roll-part-sort.mjs"; | ||||||
|  | import { RollBasicParts } from "./roll-basic-parts.mjs"; | ||||||
|  | import { RollPartRollMode } from "./roll-part-rollmode.mjs"; | ||||||
|  | import { RollPartJeu } from "./roll-part-jeu.mjs"; | ||||||
|  | import { RollPartSign } from "./roll-part-sign.mjs"; | ||||||
|  | import { RollPartAttaque } from "./roll-part-attaque.mjs"; | ||||||
|  | import { RollPartDefense } from "./roll-part-defense.mjs"; | ||||||
|  | import { RollDialogAdapter } from "./roll-dialog-adapter.mjs"; | ||||||
|  | import { ROLLDIALOG_SECTION } from "./roll-part.mjs"; | ||||||
|  | import { ROLL_MODE_COMP } from "./roll-constants.mjs"; | ||||||
|  |  | ||||||
|  | const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api | ||||||
|  | const doNothing = (dialog) => { } | ||||||
|  |  | ||||||
|  | const ROLL_MODE_TABS = [ | ||||||
|  |   new RollModeComp(), | ||||||
|  |   new RollModeTache(), | ||||||
|  |   new RollModeAttaque(), | ||||||
|  |   new RollModeDefense(), | ||||||
|  |   // new RollModeParade?? | ||||||
|  |   // new RollModeEsquive?? | ||||||
|  |   // new RollModeResistance ?? | ||||||
|  |   new RollModeSort(), | ||||||
|  |   new RollModeMeditation(), | ||||||
|  |   new RollModeOeuvre(), | ||||||
|  |   new RollModeJeu(), | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | const BASIC_PARTS = new RollBasicParts() | ||||||
|  |  | ||||||
|  | const ROLL_PARTS = [ | ||||||
|  |   new RollPartActor(), | ||||||
|  |   new RollPartAction(), | ||||||
|  |   new RollPartOpponent(), | ||||||
|  |   new RollPartCarac(), | ||||||
|  |   new RollPartComp(), | ||||||
|  |  | ||||||
|  |   new RollPartDiff(), | ||||||
|  |   new RollPartAttaque(), | ||||||
|  |   new RollPartDefense(), | ||||||
|  |   new RollPartMeditation(), | ||||||
|  |   new RollPartSort(), | ||||||
|  |   new RollPartTache(), | ||||||
|  |   new RollPartOeuvre(), | ||||||
|  |   new RollPartJeu(), | ||||||
|  |  | ||||||
|  |   new RollPartSign(), | ||||||
|  |  | ||||||
|  |   new RollPartEtat(), | ||||||
|  |   new RollPartConditions(), | ||||||
|  |   new RollPartEthylisme(), | ||||||
|  |   new RollPartMalusArmure(), | ||||||
|  |   new RollPartEncTotal(), | ||||||
|  |   new RollPartSurEnc(), | ||||||
|  |   new RollPartAppelMoral(), | ||||||
|  |   new RollPartMoral(), | ||||||
|  |   new RollPartCoeur(), | ||||||
|  |   new RollPartAstrologique(), | ||||||
|  |   new RollPartTricher(), | ||||||
|  |   new RollPartRollMode(), | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Extend the base Dialog entity to select roll parameters | ||||||
|  |  * @extends {Dialog} | ||||||
|  |  * # Principes | ||||||
|  |  * - une seule fenêtre de dialogue (classe RollDialog) | ||||||
|  |  * - plusieurs modes de fonctionnement (classe RollMode) | ||||||
|  |  * - gestion uniforme des modificateurs (classe RollPart) | ||||||
|  |  * - un objet rollData contient les informations liées à un jet de dés | ||||||
|  |  * - un rollData doit pouvoir être "réduit" pour fournir les informations significatives | ||||||
|  |  *   d'un jet de dés | ||||||
|  |  * - un rollData réduit doit pouvoir être complété pour afficher la même fenêtre | ||||||
|  |  * - un rollData réduit sera utilisé pour piloter l'ouverture de la fenêtre | ||||||
|  |  * | ||||||
|  |  * - TODO: une classe de base RollChatMessage gerera les messages correspondant aux résultats du dés | ||||||
|  |  * - TODO: réfléchir aux messages supplémentaires gérés par RdDCombat ? | ||||||
|  |  * | ||||||
|  |  * ## Modes de fonctionnement - RollMode | ||||||
|  |  *  | ||||||
|  |  * Un mode de fonctionnement (RollMode) détermine quelles parties (RollPart) de la | ||||||
|  |  * fenêtre RollDialog sont actives, mais aussi quels sont les effets du jet. | ||||||
|  |  *  | ||||||
|  |  * - chaque mode de fonctionnement peut impacter les RollPart utilisés, les données | ||||||
|  |  *   attendues et ajoutées au rollData. | ||||||
|  |  * - chaque mode de fonctionnement peut définir le template de ChatMessage correspondant | ||||||
|  |  * - Le mode de fonctionnement détermine aussi quelles sont les effets du jet: | ||||||
|  |  *    - quelle ChatMessage afficher dans le tchat? | ||||||
|  |  *    - en cas d'attaque/de défense, quelles sont les suites à donner? | ||||||
|  |  *    - en cas de lancement de sort, réduire les points de rêve | ||||||
|  |  *    - en cas de méditation, créer le signe draconique | ||||||
|  |  *    - en cas de tâche, ajuster les points de tâche | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * ## Modificateurs - RollPart | ||||||
|  |  * - Chaque modificateur a: | ||||||
|  |  *    - un code (comp, carac, diff, ...) | ||||||
|  |  *    - une partie dédiée pour sauvegarder son contexte | ||||||
|  |  * - le contexte d'un RollPart est stocké dans le rollData de la fenêtre RollDialog,  | ||||||
|  |  *   dans des parties dédiés: | ||||||
|  |  *    - `rollData.refs[code]` pour les données de référentiel (liste de compétences, ...) | ||||||
|  |  *    - `rollData.current[code]` pour les informations d'état courante (la compétence sélectionnée, ...) | ||||||
|  |  *    - `rollData.selected[code]` pour les informations à sauvegarder, et utilisées pour paramétrer l'ouverture | ||||||
|  |  * - Chaque RollPart gère ses données dans cet espace dédié. | ||||||
|  |  * - Chaque RollPart a un sous-template dédié, et indique où il doit s'afficher dans le RollDialog | ||||||
|  |  * - Chaque RollPart peut enregistrer ses propres events handlers pour mettre à jour son contexte (et généralement réafficher le RollDialo) | ||||||
|  |  * - Chaque RollPart fournit les informations contextuelles associées au jet | ||||||
|  |  * - TODO: chaque RollPart peut fournir un sous-template pour le ChatMessage correspondant au résultat du dé. | ||||||
|  |  * | ||||||
|  |  * ## boucle de rétroaction | ||||||
|  |  * Lors de l'affichage, chaque RollPart peut fournir un filtre pour les autres RollParts. | ||||||
|  |  * Ce filtre sert principalement à filtrer les caractéristiques/compétense. | ||||||
|  |  * | ||||||
|  |  * Une fois ce filtrage effectué, chaque RollPart va pouvoir modifier sa partie du contexte | ||||||
|  |  * de la fenêtre, permettant à son template hbs d'avoir les donnéers à afficher. | ||||||
|  |  * | ||||||
|  |  * Enfin, lors de l'affichage (vu que les contrêles sont réaffichés), il peut  | ||||||
|  |  * enregistrer les listeners appropriés. | ||||||
|  |  * | ||||||
|  |  * ## Utilisation des informations sélectionnées | ||||||
|  |  * | ||||||
|  |  * Le rollData est la structure de stockage, et sert à préparer le jet de dé. | ||||||
|  |  * Le résultat du jet est stocké dans le noeud `rollData.rolled` (comme pour | ||||||
|  |  * la première version de jets de dés) | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * # TODO | ||||||
|  |  * - intégration pour un jet (oeuvres / tâches / méditation / compétence) | ||||||
|  |  * - RdDRollResult V2 (affichage avec templates basés sur roll-dialog) | ||||||
|  |  * - Extraction de jet résumé (pour appel chance) | ||||||
|  |  * - gestion significative | ||||||
|  |  * - Attaque | ||||||
|  |  * - Défense | ||||||
|  |  * - intégration rdd-combat | ||||||
|  |  * - combat rencontres | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | /* -------------------------------------------- */ | ||||||
|  | export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2) | ||||||
|  | { | ||||||
|  |  | ||||||
|  |   static init() { | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static onReady() { | ||||||
|  |  | ||||||
|  |     foundry.applications.handlebars.loadTemplates({ | ||||||
|  |       'roll-section': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-section.hbs', | ||||||
|  |       'roll-mode': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-mode.hbs', | ||||||
|  |       'roll-table': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-table.hbs', | ||||||
|  |       'roll-ajustements': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-ajustements.hbs', | ||||||
|  |       'roll-chances': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-chances.hbs', | ||||||
|  |       'roll-button': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-button.hbs', | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     foundry.applications.handlebars.loadTemplates(ROLL_MODE_TABS.map(m => m.template)) | ||||||
|  |     foundry.applications.handlebars.loadTemplates(ROLL_PARTS.map(p => p.template)) | ||||||
|  |     ROLL_PARTS.forEach(p => p.onReady()) | ||||||
|  |  | ||||||
|  |     Handlebars.registerHelper('roll-centered-array', (base, show) => { | ||||||
|  |       show = Math.abs(show) | ||||||
|  |       const start = base - show | ||||||
|  |       return [...Array(2 * show + 1).keys()].map(it => start + it) | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     Handlebars.registerHelper('roll-list-item-value', (list, key, path = undefined) => { | ||||||
|  |       const selected = list.find(p => p.key == key) | ||||||
|  |       if (selected && path && path != '') { | ||||||
|  |         return foundry.utils.getProperty(selected, path) | ||||||
|  |       } | ||||||
|  |       return selected | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     Handlebars.registerHelper('roll-part-context', (rollData, code) => { | ||||||
|  |       const rollPart = ROLL_PARTS.find(it => it.code == code) | ||||||
|  |       if (rollPart == undefined) { | ||||||
|  |         return {} | ||||||
|  |       } | ||||||
|  |       return { | ||||||
|  |         code: code, | ||||||
|  |         name: rollPart.name, | ||||||
|  |         template: rollPart.template, | ||||||
|  |         rollData: rollData, | ||||||
|  |         refs: rollPart.getRefs(rollData), | ||||||
|  |         current: rollPart.getCurrent(rollData) | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |    | ||||||
|  |   static async create(rollData, rollOptions = {}) { | ||||||
|  |     const rollDialog = new RollDialog(rollData, rollOptions) | ||||||
|  |     rollDialog.render(true) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static get PARTS() { | ||||||
|  |     return { form: { template: 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-dialog.hbs', } } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static get DEFAULT_OPTIONS() { | ||||||
|  |     const default_options = { | ||||||
|  |       tag: "form", | ||||||
|  |       form: { | ||||||
|  |         handler: RollDialog.handler, | ||||||
|  |         submitOnChange: false, | ||||||
|  |         closeOnSubmit: false | ||||||
|  |       }, | ||||||
|  |       position: { | ||||||
|  |         width: 600, | ||||||
|  |         height: "auto", | ||||||
|  |       }, | ||||||
|  |     } | ||||||
|  |     return default_options | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async handler(event, form, formData) { | ||||||
|  |     // rien pour l'instant | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   constructor(rollData, rollOptions) { | ||||||
|  |     super() | ||||||
|  |     this.rollData = rollData | ||||||
|  |     // const callbacks = this.rollOptions.callbacks.map(c => | ||||||
|  |     //   r => r.activve.actor Promise.all(this.rollOptions.callbacks.map(async callback => await callback(rollData.active.actor, rollData))) | ||||||
|  |     // ) | ||||||
|  |     this.rollOptions = { | ||||||
|  |       callbacks: [ | ||||||
|  |         async (actor, r) => await actor.appliquerAjoutExperience(r), | ||||||
|  |         async (actor, r) => await actor.appliquerAppelMoral(r), | ||||||
|  |         ...(rollOptions.callbacks ?? []) | ||||||
|  |       ], | ||||||
|  |       customChatMessage: rollOptions.customChatMessage, | ||||||
|  |       onRoll: rollOptions.onRoll ?? doNothing | ||||||
|  |     } | ||||||
|  |     this.$loadParts() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** pre-configure les paramètres des différentes parties de la fenêtre (par exemple, prépare les listes de caractéristiques/compétences */ | ||||||
|  |   $loadParts() { | ||||||
|  |     const rollData = this.rollData; | ||||||
|  |     rollData.current = rollData.current ?? {} | ||||||
|  |     rollData.selected = rollData.selected ?? {} | ||||||
|  |     rollData.mode = rollData.mode ?? {} | ||||||
|  |     rollData.mode.retry = rollData.mode.retry ?? false | ||||||
|  |     BASIC_PARTS.restore(rollData) | ||||||
|  |  | ||||||
|  |     const loadedMode = ROLL_MODE_TABS.find(m => m.code == rollData.mode?.current)?.code | ||||||
|  |     const allowedModes = ROLL_MODE_TABS.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code) | ||||||
|  |  | ||||||
|  |     rollData.mode.allowed = rollData.mode.retry ? [loadedMode] : rollData.mode.allowed ?? ROLL_MODE_TABS.map(m => m.code) | ||||||
|  |     rollData.mode.current = allowedModes.find(m => m == rollData.mode?.current) ?? (allowedModes.length > 0 ? allowedModes[0] : ROLL_MODE_COMP) | ||||||
|  |  | ||||||
|  |     this.getSelectedMode().setRollDataMode(rollData) | ||||||
|  |  | ||||||
|  |     rollData.refs = this.$prepareRefs(rollData) | ||||||
|  |     rollData.options = rollData.options ?? { showDice: true, rollMode: game.settings.get("core", "rollMode") } | ||||||
|  |  | ||||||
|  |     ROLL_PARTS.forEach(p => p.initialize(rollData)) | ||||||
|  |     ROLL_PARTS.forEach(p => p.restore(rollData)) | ||||||
|  |     ROLL_PARTS.filter(p => p.isValid(rollData)) | ||||||
|  |       .forEach(p => { | ||||||
|  |         p.loadRefs(rollData) | ||||||
|  |         p.prepareContext(rollData) | ||||||
|  |       }) | ||||||
|  |     this.selectMode(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   selectMode() { | ||||||
|  |     this.rollData.mode.label = this.getSelectedMode().title(this.rollData) | ||||||
|  |     this.getSelectedMode().setRollDataMode(this.rollData) | ||||||
|  |     this.getSelectedMode().onSelect(this.rollData); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $prepareRefs(rollData) { | ||||||
|  |     return foundry.utils.mergeObject(rollData.refs ?? {}, Object.fromEntries(ROLL_PARTS.map(p => [p.code, {}]))); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $saveParts() { | ||||||
|  |     const target = BASIC_PARTS.initFrom(this.rollData) | ||||||
|  |     ROLL_PARTS.filter(p => p.isActive(this.rollData)) | ||||||
|  |       .forEach(p => p.store(this.rollData, target)) | ||||||
|  |     return target | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getActiveParts() { | ||||||
|  |     return ROLL_PARTS.filter(p => p.isActive(this.rollData)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   get title() { | ||||||
|  |     return this.rollData.title ?? `Jet de dés de ${this.rollData.active.actor.name}` | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(context, options) { | ||||||
|  |     this.window.title.innerText = this.rollTitle(this.rollData) | ||||||
|  |     const buttonRoll = this.element.querySelector(`button[name="roll-dialog-button"]`) | ||||||
|  |     buttonRoll?.addEventListener( | ||||||
|  |       "click", e => { | ||||||
|  |         e.preventDefault() | ||||||
|  |         this.roll() | ||||||
|  |       } | ||||||
|  |     ) | ||||||
|  |     const buttonsMode = this.element.querySelectorAll(`button[name="roll-mode"]`) | ||||||
|  |     buttonsMode?.forEach(it => it.addEventListener( | ||||||
|  |       "click", e => { | ||||||
|  |         e.preventDefault() | ||||||
|  |         this.rollData.mode.current = e.currentTarget.dataset.mode | ||||||
|  |         this.selectMode() | ||||||
|  |         this.render() | ||||||
|  |       } | ||||||
|  |     )) | ||||||
|  |  | ||||||
|  |     Promise.all( | ||||||
|  |       this.getActiveParts().map(async p => await p._onRender(this, context, options)) | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getAjustements() { | ||||||
|  |     return this.getActiveParts() | ||||||
|  |       .map(p => p.getAjustements(this.rollData)) | ||||||
|  |       .reduce((a, b) => a.concat(b)) | ||||||
|  |       .sort((a, b) => a.diff == undefined ? 1 : b.diff == undefined ? -1 : 0) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async buildHTMLTable(carac, diff) { | ||||||
|  |     return await foundry.applications.handlebars.renderTemplate('roll-table', { carac, diff }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   async _prepareContext() { | ||||||
|  |     const rollData = this.rollData | ||||||
|  |  | ||||||
|  |     const modes = ROLL_MODE_TABS.filter(m => m.isAllowed(rollData) && m.visible(rollData)) | ||||||
|  |       .map(m => m.toModeData(rollData)) | ||||||
|  |     this.setModeTitle() | ||||||
|  |  | ||||||
|  |     const visibleRollParts = this.getActiveParts() | ||||||
|  |     visibleRollParts.forEach(p => p.setExternalFilter(visibleRollParts, rollData)) | ||||||
|  |  | ||||||
|  |     this.setSpecialComp(visibleRollParts); | ||||||
|  |  | ||||||
|  |     visibleRollParts.forEach(p => p.prepareContext(rollData)) | ||||||
|  |  | ||||||
|  |     this.calculAjustements() | ||||||
|  |  | ||||||
|  |     const templates = this.getActiveParts().map(p => p.toTemplateData()) | ||||||
|  |     const context = await super._prepareContext() | ||||||
|  |     return foundry.utils.mergeObject( | ||||||
|  |       { | ||||||
|  |         modes: modes, | ||||||
|  |         templates: templates, | ||||||
|  |         rollData: rollData, | ||||||
|  |       }, context) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   setSpecialComp(visibleRollParts) { | ||||||
|  |     const specialComp = visibleRollParts.map(p => p.getSpecialComp(this.rollData)) | ||||||
|  |       .reduce((a, b) => a.concat(b)) | ||||||
|  |     if (specialComp.length > 0) { | ||||||
|  |       const rollPartComp = this.getActiveParts() | ||||||
|  |         .find(it => it.code == PART_COMP); | ||||||
|  |       rollPartComp?.setSpecialComp(this.rollData, specialComp) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   calculAjustements() { | ||||||
|  |     this.rollData.ajustements = this.getAjustements() | ||||||
|  |     this.rollData.ajustements.forEach(it => it.isDiff = it.diff != undefined) | ||||||
|  |     this.rollData.current.totaldiff = this.rollData.ajustements | ||||||
|  |       .map(adj => adj.diff) | ||||||
|  |       .filter(d => d != undefined) | ||||||
|  |       .reduce(Misc.sum(), 0) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   setModeTitle() { | ||||||
|  |     this.rollData.mode.label = this.getSelectedMode()?.title(this.rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getSelectedMode() { | ||||||
|  |     return ROLL_MODE_TABS.find(m => m.code == this.rollData.mode.current) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async roll() { | ||||||
|  |     this.calculAjustements() | ||||||
|  |     const rollData = this.rollData | ||||||
|  |     console.info('Roll parts:', this.$saveParts()) | ||||||
|  |     const rolled = await this.$rollDice(rollData) | ||||||
|  |     rollData.rolled = rolled | ||||||
|  |     Promise.all(this.rollOptions.callbacks.map(async callback => await callback(rollData.active.actor, rollData))) | ||||||
|  |     if (!this.rollOptions.customChatMessage) { | ||||||
|  |       rollData.active.actor.$onRollCompetence(this.rollData) | ||||||
|  |     } | ||||||
|  |     this.rollOptions.onRoll(this) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   async defaultCallback(rollData, rolled) { | ||||||
|  |     await rollData.active.actor.appliquerAjoutExperience(rollData) | ||||||
|  |     await rollData.active.actor.appliquerAppelMoral(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async $rollDice(rollData) { | ||||||
|  |     const adapter = new RollDialogAdapter(ROLL_PARTS); | ||||||
|  |     return await adapter.rollDice(rollData, this.rollTitle(rollData)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   rollTitle(rollData) { | ||||||
|  |     return ROLL_PARTS | ||||||
|  |       .filter(it => it.section == ROLLDIALOG_SECTION.ACTION) | ||||||
|  |       .filter(it => it.isActive(rollData)) | ||||||
|  |       .map(it => it.title(rollData)) | ||||||
|  |       .reduce(Misc.joining(' ')) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								module/roll/roll-mode-attaque.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,13 @@ | |||||||
|  | import { DIFF_MODE, ROLL_MODE_ATTAQUE } from "./roll-constants.mjs" | ||||||
|  | import { RollMode } from "./roll-mode.mjs" | ||||||
|  |  | ||||||
|  | export class RollModeAttaque extends RollMode { | ||||||
|  |   get code() { return ROLL_MODE_ATTAQUE } | ||||||
|  |   get name() { return `Attaquer` } | ||||||
|  |  | ||||||
|  |   title(rollData) { return `attaque` } | ||||||
|  |  | ||||||
|  |   onSelect(rollData) { | ||||||
|  |     this.setDiffMode(rollData, DIFF_MODE.ATTAQUE) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								module/roll/roll-mode-comp.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,9 @@ | |||||||
|  | import { ROLL_MODE_COMP } from "./roll-constants.mjs" | ||||||
|  | import { RollMode } from "./roll-mode.mjs" | ||||||
|  |  | ||||||
|  | export class RollModeComp extends RollMode { | ||||||
|  |   get code() { return ROLL_MODE_COMP } | ||||||
|  |   get name() { return `Jet de caractéristique / compétence` } | ||||||
|  |  | ||||||
|  |   title(rollData) { return `fait un jet ${rollData.mode.opposed ? ' contre ' : ''}` } | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								module/roll/roll-mode-defense.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,17 @@ | |||||||
|  | import { DIFF_MODE, ROLL_MODE_DEFENSE } from "./roll-constants.mjs" | ||||||
|  | import { RollMode } from "./roll-mode.mjs" | ||||||
|  |  | ||||||
|  | export class RollModeDefense extends RollMode { | ||||||
|  |   get code() { return ROLL_MODE_DEFENSE } | ||||||
|  |   get name() { return `Se défendre` } | ||||||
|  |  | ||||||
|  |   title(rollData) { return `se défend${rollData.attacker ? ' de' : ''}` } | ||||||
|  |  | ||||||
|  |   getOpponent(rollData) { | ||||||
|  |     return rollData.attacker | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   onSelect(rollData) { | ||||||
|  |     this.setDiffMode(rollData, DIFF_MODE.DEFENSE) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								module/roll/roll-mode-jeu.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,17 @@ | |||||||
|  | import { PART_JEU } from "./roll-part-jeu.mjs" | ||||||
|  | import { RollMode } from "./roll-mode.mjs" | ||||||
|  | import { ROLL_MODE_JEU } from "./roll-constants.mjs" | ||||||
|  |  | ||||||
|  | export class RollModeJeu extends RollMode { | ||||||
|  |   get code() { return ROLL_MODE_JEU } | ||||||
|  |   get name() { return `Jouer` } | ||||||
|  |  | ||||||
|  |   visible(rollData) { return rollData.active.actor.isPersonnage() } | ||||||
|  |   title(rollData) { | ||||||
|  |     if (rollData.opponent) { | ||||||
|  |       return `joue contre` | ||||||
|  |     } | ||||||
|  |     return `joue: ${rollData.current[PART_JEU].label}` | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								module/roll/roll-mode-meditation.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | |||||||
|  | import { DIFF_MODE, ROLL_MODE_MEDITATION } from "./roll-constants.mjs" | ||||||
|  | import { PART_MEDITATION } from "./roll-part-meditation.mjs" | ||||||
|  | import { RollMode } from "./roll-mode.mjs" | ||||||
|  |  | ||||||
|  | export class RollModeMeditation extends RollMode { | ||||||
|  |   get code() { return ROLL_MODE_MEDITATION } | ||||||
|  |   get name() { return `Méditation draconique` } | ||||||
|  |  | ||||||
|  |   visible(rollData) { return rollData.active.actor.isHautRevant() } | ||||||
|  |   title(rollData) { | ||||||
|  |     const current = rollData.current[PART_MEDITATION] | ||||||
|  |     const theme = current?.meditation.system.theme | ||||||
|  |     return theme ? 'médite sur ' + theme : 'médite' | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   onSelect(rollData) { | ||||||
|  |     this.setDiffMode(rollData, DIFF_MODE.AUCUN) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								module/roll/roll-mode-oeuvre.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | |||||||
|  | import { DIFF_MODE, ROLL_MODE_OEUVRE } from "./roll-constants.mjs" | ||||||
|  | import { PART_OEUVRE } from "./roll-part-oeuvre.mjs" | ||||||
|  | import { RollMode } from "./roll-mode.mjs" | ||||||
|  |  | ||||||
|  | export class RollModeOeuvre extends RollMode { | ||||||
|  |   get code() { return ROLL_MODE_OEUVRE } | ||||||
|  |   get name() { return `Interpréter une oeuvre` } | ||||||
|  |  | ||||||
|  |   visible(rollData) { return rollData.active.actor.isPersonnage() } | ||||||
|  |   title(rollData) { | ||||||
|  |     const current = rollData.current[PART_OEUVRE] | ||||||
|  |     return `${current.art.action} ${current.label}` | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   onSelect(rollData) { | ||||||
|  |     this.setDiffMode(rollData, DIFF_MODE.AUCUN) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										15
									
								
								module/roll/roll-mode-sort.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,15 @@ | |||||||
|  | import { DIFF_MODE, ROLL_MODE_SORT } from "./roll-constants.mjs" | ||||||
|  | import { RollMode } from "./roll-mode.mjs" | ||||||
|  | import { PART_SORT } from "./roll-part-sort.mjs" | ||||||
|  |  | ||||||
|  | export class RollModeSort extends RollMode { | ||||||
|  |   get code() { return ROLL_MODE_SORT } | ||||||
|  |   get name() { return `lancer un sort` } | ||||||
|  |  | ||||||
|  |   visible(rollData) { return rollData.active.actor.isHautRevant() } | ||||||
|  |   title(rollData) { return `lance le sort:` } | ||||||
|  |  | ||||||
|  |   onSelect(rollData) { | ||||||
|  |     this.setDiffMode(rollData, DIFF_MODE.AUCUN) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								module/roll/roll-mode-tache.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | |||||||
|  | import { DIFF_MODE, ROLL_MODE_TACHE } from "./roll-constants.mjs" | ||||||
|  | import { PART_TACHE } from "./roll-part-tache.mjs" | ||||||
|  | import { RollMode } from "./roll-mode.mjs" | ||||||
|  |  | ||||||
|  | export class RollModeTache extends RollMode { | ||||||
|  |   get code() { return ROLL_MODE_TACHE } | ||||||
|  |   get name() { return `Travailler à une tâche` } | ||||||
|  |  | ||||||
|  |   visible(rollData) { return rollData.active.actor.isPersonnage() } | ||||||
|  |   title(rollData) { | ||||||
|  |     const current = rollData.current[PART_TACHE] | ||||||
|  |     const tache = current?.tache | ||||||
|  |     return `travaille à sa tâche: ${tache.name ?? ''}` | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   onSelect(rollData) { | ||||||
|  |     this.setDiffMode(rollData, DIFF_MODE.AUCUN) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								module/roll/roll-mode.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,54 @@ | |||||||
|  | import { DIFF_MODE } from "./roll-constants.mjs" | ||||||
|  | import { PART_DIFF } from "./roll-part-diff.mjs" | ||||||
|  |  | ||||||
|  | const DEFAULT_DIFF_MODES = [DIFF_MODE.LIBRE, DIFF_MODE.IMPOSEE, DIFF_MODE.DEFAUT] | ||||||
|  |  | ||||||
|  | export class RollMode { | ||||||
|  |  | ||||||
|  |   onReady() { } | ||||||
|  |  | ||||||
|  |   get code() { throw new Error(`Pas de code défini pour ${this}`) } | ||||||
|  |   get name() { return this.code } | ||||||
|  |   get icon() { return `systems/foundryvtt-reve-de-dragon/assets/actions/${this.code}.svg` } | ||||||
|  |  | ||||||
|  |   toModeData(rollData) { | ||||||
|  |     return { code: this.code, name: this.name, icon: this.icon, section: 'mode', template: this.template, selected: this.isSelected(rollData) } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   isAllowed(rollData) { return rollData.mode.allowed == undefined || rollData.mode.allowed.includes(this.code) } | ||||||
|  |   visible(rollData) { return true } | ||||||
|  |  | ||||||
|  |   title(rollData) { return this.code } | ||||||
|  |   isSelected(rollData) { return rollData.mode.current == this.code } | ||||||
|  |  | ||||||
|  |   setRollDataMode(rollData) { | ||||||
|  |     rollData.mode.opposed = rollData.opponent != undefined | ||||||
|  |     rollData.mode.resistance = false /** TODO */ | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   onSelect(rollData) { | ||||||
|  |     const mode = [ | ||||||
|  |       rollData.current[PART_DIFF].mode, | ||||||
|  |       this.modeFromOpponents(rollData), | ||||||
|  |       rollData.selected[PART_DIFF].mode].find(m => DEFAULT_DIFF_MODES.includes(m)) | ||||||
|  |  | ||||||
|  |     this.setDiffMode(rollData, mode ?? | ||||||
|  |       DIFF_MODE.DEFAUT) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   modeFromOpponents(rollData) { | ||||||
|  |     if (rollData.mode.opposed) { | ||||||
|  |       if (rollData.mode.resistance) { | ||||||
|  |         return DIFF_MODE.IMPOSEE | ||||||
|  |       } | ||||||
|  |       return DIFF_MODE.LIBRE | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   setDiffMode(rollData, mode) { | ||||||
|  |     rollData.current[PART_DIFF].mode = mode | ||||||
|  |     this.setRollDataMode(rollData) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								module/roll/roll-part-action.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | |||||||
|  | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_ACTION = "action" | ||||||
|  |  | ||||||
|  | export class RollPartAction extends RollPart { | ||||||
|  |  | ||||||
|  |   get code() { return PART_ACTION } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.ACTION } | ||||||
|  |  | ||||||
|  |   title(rollData) { | ||||||
|  |     return rollData.mode.label | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   prepareContext(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     current.verb = rollData.mode.label | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								module/roll/roll-part-actor.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,11 @@ | |||||||
|  | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_ACTOR = "actor" | ||||||
|  |  | ||||||
|  | export class RollPartActor extends RollPart { | ||||||
|  |  | ||||||
|  |   get code() { return PART_ACTOR } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.ACTION } | ||||||
|  |  | ||||||
|  |   title(rollData) { return rollData.active.name } | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								module/roll/roll-part-appelmoral.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,43 @@ | |||||||
|  | import { RdDCarac } from "../rdd-carac.js" | ||||||
|  | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
|  |  | ||||||
|  | export const PART_APPELMORAL = "appelmoral" | ||||||
|  |  | ||||||
|  | export class RollPartAppelMoral extends RollPartCheckbox { | ||||||
|  |  | ||||||
|  |   get code() { return PART_APPELMORAL } | ||||||
|  |   get useCheckboxTemplate() { return false } | ||||||
|  |   get isDefaultChecked() { return false } | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     return rollData.active.actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.current.carac.key) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   restore(rollData) { | ||||||
|  |     this.getCurrent(rollData).checked = this.getSaved(rollData).checked ?? false | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   store(rollData, targetData) { | ||||||
|  |     this.setSaved(targetData, { checked: this.getCurrent(rollData).checked }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.moral = rollData.active.actor.getMoralTotal() | ||||||
|  |     refs.label = refs.moral > 0 ? "Appel au moral" : "Énergie du désespoir" | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxIcon(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     if (refs.moral > 0) { | ||||||
|  |       return '<i class="fa-regular fa-face-smile-beam"></i>' | ||||||
|  |     } | ||||||
|  |     if (refs.moral < 0) { | ||||||
|  |       return '<i class="fa-regular fa-face-sad-tear"></i>' | ||||||
|  |     } | ||||||
|  |     return '<i class="fa-regular fa-face-meh"></i>' | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxLabel(rollData) { return "Appel au moral" } | ||||||
|  |   getCheckboxValue(rollData) { return 1 } | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								module/roll/roll-part-astrologique.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,33 @@ | |||||||
|  | import { Grammar } from "../grammar.js" | ||||||
|  | import { ReglesOptionnelles } from "../settings/regles-optionnelles.js" | ||||||
|  | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
|  |  | ||||||
|  | export const PART_ASTROLOGIQUE = "astrologique" | ||||||
|  |  | ||||||
|  | export class RollPartAstrologique extends RollPartCheckbox { | ||||||
|  |  | ||||||
|  |   get code() { return PART_ASTROLOGIQUE } | ||||||
|  |   get useCheckboxTemplate() { return false } | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     return this.$isUsingAstrologie() && ( | ||||||
|  |       this.isJetChance(rollData) | ||||||
|  |       || this.isLancementRituel(rollData) | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   isLancementRituel(rollData) { | ||||||
|  |     return false | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   isJetChance(rollData) { | ||||||
|  |     return Grammar.includesLowerCaseNoAccent(rollData.current.carac.key, 'chance') | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $isUsingAstrologie() { | ||||||
|  |     return ReglesOptionnelles.isUsing("astrologie") | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxLabel(rollData) { return "Astrologique" } | ||||||
|  |   getCheckboxValue(rollData) { return rollData.active.actor.ajustementAstrologique() } | ||||||
|  | } | ||||||
							
								
								
									
										132
									
								
								module/roll/roll-part-attaque.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,132 @@ | |||||||
|  | import { Grammar } from "../grammar.js" | ||||||
|  | import { RdDBonus } from "../rdd-bonus.js" | ||||||
|  | import { StatusEffects } from "../settings/status-effects.js" | ||||||
|  | import { ROLL_MODE_ATTAQUE } from "./roll-constants.mjs" | ||||||
|  | import { PART_CARAC } from "./roll-part-carac.mjs" | ||||||
|  | import { PART_COMP } from "./roll-part-comp.mjs" | ||||||
|  | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
|  | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_ATTAQUE = 'attaque' | ||||||
|  |  | ||||||
|  | const TACTIQUES = RdDBonus.tactiques.filter(it => it.isTactique) | ||||||
|  |  | ||||||
|  | export class RollPartAttaque extends RollPartSelect { | ||||||
|  |  | ||||||
|  |   get code() { return PART_ATTAQUE } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||||
|  |  | ||||||
|  |   visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_ATTAQUE) } | ||||||
|  |  | ||||||
|  |   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.tactiques = TACTIQUES | ||||||
|  |     if (refs.attaques.length > 0) { | ||||||
|  |       this.$selectAttaque(rollData) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   choices(refs) { return refs.attaques } | ||||||
|  |  | ||||||
|  |   static $extractAttaque(action, actor) { | ||||||
|  |     return { | ||||||
|  |       key: `${action.action}::${action.name}`, | ||||||
|  |       label: action.name, | ||||||
|  |       action: action, | ||||||
|  |       tactique: TACTIQUES[0], | ||||||
|  |       arme: action.arme, | ||||||
|  |       comp: action.comp, | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   prepareContext(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     const effetsSurprise = rollData.opponent?.actor?.getEffects(it => StatusEffects.niveauSurprise(it, true) > 0) ?? [] | ||||||
|  |     current.defenseur = effetsSurprise | ||||||
|  |       ? { | ||||||
|  |         surprise: RdDBonus.find(rollData.opponent?.actor?.getSurprise(true)), | ||||||
|  |         effects: effetsSurprise | ||||||
|  |       } | ||||||
|  |       : undefined | ||||||
|  |     current.dmg = this.dmgRollV2(rollData, current) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getAjustements(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     const tactique = current.tactique | ||||||
|  |     const surprise = current.defenseur?.surprise | ||||||
|  |     const ajustements = [] | ||||||
|  |     if (tactique) { | ||||||
|  |       ajustements.push({ label: tactique.label, diff: tactique.attaque }) | ||||||
|  |     } | ||||||
|  |     if (surprise) { | ||||||
|  |       ajustements.push({ label: surprise.label, diff: surprise.attaque }) | ||||||
|  |     } | ||||||
|  |     return ajustements | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   dmgRollV2(rollData, current) { | ||||||
|  |     const actor = rollData.active.actor | ||||||
|  |     const defender = rollData.opponent.actor | ||||||
|  |     const dmgArme = RdDBonus.dmgArme(current.arme, current.action.dommagesArme) | ||||||
|  |     const dmg = { | ||||||
|  |       total: 0, | ||||||
|  |       dmgArme: dmgArme, | ||||||
|  |       penetration: current.arme.penetration(), | ||||||
|  |       dmgTactique: current.tactique?.dmg ?? 0, | ||||||
|  |       dmgParticuliere: 0, // TODO RdDBonus._dmgParticuliere(rollData), | ||||||
|  |       dmgSurprise: current.defenseur?.surprise.dmg, | ||||||
|  |       mortalite: RdDBonus.mortalite(current.dmg?.mortalite, current.arme.system.mortalite, defender?.isEntite()), | ||||||
|  |       dmgActor: RdDBonus.bonusDmg(actor, current.action.carac.key, dmgArme) | ||||||
|  |     } | ||||||
|  |     dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere | ||||||
|  |     return dmg; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $selectAttaque(rollData, key) { | ||||||
|  |     this.selectByKey(rollData, key, 0) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     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 current = this.getCurrent(rollDialog.rollData) | ||||||
|  |  | ||||||
|  |     selectAttaque.addEventListener("change", e => { | ||||||
|  |       const selectOptions = e.currentTarget.options | ||||||
|  |       const index = selectOptions.selectedIndex | ||||||
|  |       this.$selectAttaque(rollDialog.rollData, selectOptions[index]?.value) | ||||||
|  |       rollDialog.setModeTitle() | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     selectTactique.addEventListener("change", e => { | ||||||
|  |       const selectOptions = e.currentTarget.options | ||||||
|  |       const index = selectOptions.selectedIndex | ||||||
|  |       current.tactique = RdDBonus.find(selectOptions[index]?.value) | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     checkMortalite?.addEventListener("change", e => { | ||||||
|  |       current.dmg.mortalite = (e.currentTarget.checked ? 'mortel' : 'non-mortel') | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getExternalPartsFilter(partCode, rollData) { | ||||||
|  |     if (this.visible(rollData)) { | ||||||
|  |       const current = this.getCurrent(rollData) | ||||||
|  |       switch (partCode) { | ||||||
|  |         case PART_CARAC: return p => Grammar.equalsInsensitive(current.action.carac.key, p.key) | ||||||
|  |         case PART_COMP: return p => p.label == current.comp?.name | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										66
									
								
								module/roll/roll-part-carac.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,66 @@ | |||||||
|  | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
|  | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_CARAC = "carac" | ||||||
|  |  | ||||||
|  | export class RollPartCarac extends RollPartSelect { | ||||||
|  |   /** TODO: remplacer selectOption par une sorte de sélecteur plus sympa? */ | ||||||
|  |  | ||||||
|  |   get code() { return PART_CARAC } | ||||||
|  |   get name() { return 'Caractéristiques' } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CARAC } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.all = this.$getActorCaracs(rollData) | ||||||
|  |     refs.caracs = refs.all | ||||||
|  |     this.$selectCarac(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   choices(refs) { return refs.caracs } | ||||||
|  |  | ||||||
|  |   $getActorCaracs(rollData) { | ||||||
|  |     return Object.entries(rollData.active.actor.getCarac()) | ||||||
|  |       .filter(([key, c]) => key != 'taille') | ||||||
|  |       /* TODO: filter by context */ | ||||||
|  |       .map(([key, carac]) => { | ||||||
|  |         return RollPartCarac.$extractCarac(key, carac) | ||||||
|  |       }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $extractCarac(key, carac) { | ||||||
|  |     return { | ||||||
|  |       key: key, | ||||||
|  |       label: carac.label, | ||||||
|  |       value: parseInt(carac.value) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   setFilter(rollData, filter) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.caracs = refs.all.filter(filter) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   prepareContext(rollData) { | ||||||
|  |     this.$selectCarac(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getAjustements(rollData) { | ||||||
|  |     return [] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const select = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select`) | ||||||
|  |  | ||||||
|  |     select?.addEventListener("change", async e => { | ||||||
|  |       const selectOptions = e.currentTarget.options | ||||||
|  |       const index = selectOptions.selectedIndex | ||||||
|  |       this.$selectCarac(rollDialog.rollData, selectOptions[index]?.value) | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $selectCarac(rollData, key) { | ||||||
|  |     this.selectByKey(rollData, key, 10) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										61
									
								
								module/roll/roll-part-checkbox.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,61 @@ | |||||||
|  | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export class RollPartCheckbox extends RollPart { | ||||||
|  |  | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CONDITIONS } | ||||||
|  |  | ||||||
|  |   get useCheckboxTemplate() { return true } | ||||||
|  |   get template() { return this.useCheckboxTemplate ? 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-part-checkbox.hbs' : super.template } | ||||||
|  |   get isDefaultChecked() { return true } | ||||||
|  |  | ||||||
|  |   restore(rollData) { | ||||||
|  |     const checked = this.getSaved(rollData).checked | ||||||
|  |     this.getCurrent(rollData).checked = checked == undefined? this.isDefaultChecked : checked | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   store(rollData, targetData) { | ||||||
|  |     this.setSaved(targetData, { checked: this.getCurrent(rollData).checked }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.label = this.getCheckboxLabel(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   prepareContext(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     if (current.checked == undefined) { | ||||||
|  |       /* TODO: user setting? */ | ||||||
|  |       current.checked = true | ||||||
|  |     } | ||||||
|  |     if (current.value == undefined) { | ||||||
|  |       current.value = this.getCheckboxValue(rollData) | ||||||
|  |     } | ||||||
|  |     current.icon = this.getCheckboxIcon(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getAjustements(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     if (current.checked) { | ||||||
|  |       return [{ label: this.getCheckboxLabelAjustement(rollData), diff: current.value }] | ||||||
|  |     } | ||||||
|  |     return [] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxLabelAjustement(rollData) { | ||||||
|  |     return `${this.getCheckboxIcon(rollData)} ${this.getRefs(rollData).label}` | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const checkbox = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`) | ||||||
|  |      | ||||||
|  |     checkbox?.addEventListener("change", e => { | ||||||
|  |       this.getCurrent(rollDialog.rollData).checked = e.currentTarget.checked | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxIcon(rollData) { return '' } | ||||||
|  |   getCheckboxLabel(rollData) { return "LABEL" } | ||||||
|  |   getCheckboxValue(rollData) { return 0 } | ||||||
|  | } | ||||||
							
								
								
									
										66
									
								
								module/roll/roll-part-coeur.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,66 @@ | |||||||
|  | import { RdDCarac } from "../rdd-carac.js" | ||||||
|  | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
|  | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | const COEUR = "coeur" | ||||||
|  |  | ||||||
|  | const SANS_AMOUR = { key: '', label: "", value: 0 } | ||||||
|  |  | ||||||
|  | export class RollPartCoeur extends RollPartSelect { | ||||||
|  |  | ||||||
|  |   get code() { return COEUR } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CONDITIONS } | ||||||
|  |  | ||||||
|  |   get useCheckboxTemplate() { return false } | ||||||
|  |  | ||||||
|  |   isValid(rollData) { return rollData.active.actor.isPersonnage() } | ||||||
|  |   visible(rollData) { | ||||||
|  |     return this.getRefs(rollData).amoureux.length > 1 && RdDCarac.isVolonte(rollData.current.carac.key) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const liste = rollData.active.actor.listeAmoureux() | ||||||
|  |       .filter(amour => amour.coeur > 0) | ||||||
|  |       .map(RollPartCoeur.$extractAmoureux) | ||||||
|  |  | ||||||
|  |     this.getRefs(rollData).amoureux = [SANS_AMOUR, ...liste] | ||||||
|  |     this.$selectAmoureux(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   choices(refs) { return refs.amoureux } | ||||||
|  |  | ||||||
|  |   static $extractAmoureux(amour) { | ||||||
|  |     return { | ||||||
|  |       key: amour.id, | ||||||
|  |       label: amour.name, | ||||||
|  |       value: -2 * (amour?.coeur ?? 0), | ||||||
|  |       amour: amour | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $selectAmoureux(rollData, key) { | ||||||
|  |     this.selectByKey(rollData, key, 0) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getAjustements(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     if (current.key != '') { | ||||||
|  |       return [{ | ||||||
|  |         label: "Coeur pour " + current.label, | ||||||
|  |         diff: current.value | ||||||
|  |       }] | ||||||
|  |     } | ||||||
|  |     return [] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const selectAmour = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="${this.code}"]`) | ||||||
|  |  | ||||||
|  |     selectAmour?.addEventListener("change", e => { | ||||||
|  |       const selectOptions = e.currentTarget.options | ||||||
|  |       const index = selectOptions.selectedIndex | ||||||
|  |       this.$selectAmoureux(rollDialog.rollData, selectOptions[index]?.value) | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								module/roll/roll-part-comp.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,77 @@ | |||||||
|  | import { Grammar } from "../grammar.js" | ||||||
|  | import { Misc } from "../misc.js" | ||||||
|  | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
|  | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_COMP = "comp" | ||||||
|  |  | ||||||
|  | const SANS_COMPETENCE = { key: '', label: "Sans compétence", value: 0 } | ||||||
|  |  | ||||||
|  | export class RollPartComp extends RollPartSelect { | ||||||
|  |  | ||||||
|  |   /** TODO: remplacer selectOption par un sélecteur plus sympa (avec image de compétence, par exemple? */ | ||||||
|  |  | ||||||
|  |   get code() { return PART_COMP } | ||||||
|  |   get name() { return 'Compétences' } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.COMP } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.all = this.$getActorComps(rollData) | ||||||
|  |     refs.comps = refs.all | ||||||
|  |     this.$selectComp(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   choices(refs) { return refs.comps } | ||||||
|  |  | ||||||
|  |   $getActorComps(rollData) { | ||||||
|  |     const competences = (rollData.active.actor?.getCompetences() ?? []) | ||||||
|  |       .map(RollPartComp.$extractComp) | ||||||
|  |       .sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label))) | ||||||
|  |     /* TODO: filter competences */ | ||||||
|  |     const listCompetences = [ | ||||||
|  |       SANS_COMPETENCE, | ||||||
|  |       ...competences | ||||||
|  |     ] | ||||||
|  |     return listCompetences | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $extractComp(comp) { | ||||||
|  |     return { | ||||||
|  |       key: comp.name, | ||||||
|  |       label: comp.name, | ||||||
|  |       value: comp.system.niveau, | ||||||
|  |       comp: comp | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   setFilter(rollData, filter) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.comps = refs.all.filter(filter) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   prepareContext(rollData) { | ||||||
|  |     this.$selectComp(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   setSpecialComp(rollData, comps) { | ||||||
|  |     this.getRefs(rollData).comps = comps.map(RollPartComp.$extractComp) | ||||||
|  |       .sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label))) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const select = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select`) | ||||||
|  |  | ||||||
|  |     select?.addEventListener("change", e => { | ||||||
|  |       const selectOptions = e.currentTarget.options | ||||||
|  |       const index = selectOptions.selectedIndex | ||||||
|  |       this.$selectComp(rollDialog.rollData, selectOptions[index]?.value) | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $selectComp(rollData, key) { | ||||||
|  |     this.selectByKey(rollData, key, 0) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										74
									
								
								module/roll/roll-part-conditions.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,74 @@ | |||||||
|  | import { SYSTEM_RDD } from "../constants.js"; | ||||||
|  | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"; | ||||||
|  |  | ||||||
|  | const CONDITIONS = "conditions" | ||||||
|  | const DESCR_CONDITIONS = "Conditions" | ||||||
|  |  | ||||||
|  | export class RollPartConditions extends RollPart { | ||||||
|  |   /** TODO: use alternate to numberInput that supports displaying '+' sign */ | ||||||
|  |   settingMin() { return RollPart.settingKey(this, 'min') } | ||||||
|  |   settingMax() { return RollPart.settingKey(this, 'max') } | ||||||
|  |  | ||||||
|  |   onReady() { | ||||||
|  |     game.settings.register(SYSTEM_RDD, this.settingMin(), | ||||||
|  |       { | ||||||
|  |         name: "Malus maximal de conditions", | ||||||
|  |         type: Number, | ||||||
|  |         config: true, | ||||||
|  |         scope: "world", | ||||||
|  |         range: { min: -20, max: -10, step: 1 }, | ||||||
|  |         default: -16 | ||||||
|  |       } | ||||||
|  |     ) | ||||||
|  |     game.settings.register(SYSTEM_RDD, this.settingMax(), | ||||||
|  |       { | ||||||
|  |         name: "Bonus maximal de conditions", | ||||||
|  |         type: Number, | ||||||
|  |         config: true, | ||||||
|  |         scope: "world", | ||||||
|  |         range: { min: 5, max: 15, step: 1 }, | ||||||
|  |         default: 10 | ||||||
|  |       } | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   restore(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     current.value = this.getSaved(rollData)?.value ?? current.value ?? 0 | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   store(rollData, targetData) { | ||||||
|  |     this.setSaved(targetData, { value: this.getCurrent(rollData).value }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** @override */ | ||||||
|  |   get code() { return CONDITIONS } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CONDITIONS } | ||||||
|  |  | ||||||
|  |   prepareContext(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     current.min = game.settings.get(SYSTEM_RDD, this.settingMin()) | ||||||
|  |     current.max = game.settings.get(SYSTEM_RDD, this.settingMax()) | ||||||
|  |     current.value = current.value ?? 0 | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getAjustements(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     if (current.value != 0) { | ||||||
|  |       return [{ label: DESCR_CONDITIONS, diff: current.value }] | ||||||
|  |     } | ||||||
|  |     return [] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const input = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`) | ||||||
|  |      | ||||||
|  |     input?.addEventListener("change", e => { | ||||||
|  |       const current = this.getCurrent(rollDialog.rollData) | ||||||
|  |       current.value = parseInt(e.currentTarget.value) | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								module/roll/roll-part-defense.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,21 @@ | |||||||
|  | import { ROLL_MODE_DEFENSE } from "./roll-constants.mjs" | ||||||
|  | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_DEFENSE = 'defense' | ||||||
|  |  | ||||||
|  | export class RollPartDefense extends RollPart { | ||||||
|  |  | ||||||
|  |   get code() { return PART_DEFENSE } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||||
|  |   visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_DEFENSE) } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.defenses =[] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   isForceInsuffisante(rollData) { | ||||||
|  |     return true | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										70
									
								
								module/roll/roll-part-diff.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,70 @@ | |||||||
|  | import { DIFF_MODE, DIFF_MODES, ROLL_MODE_MEDITATION, ROLL_MODE_OEUVRE, ROLL_MODE_SORT, ROLL_MODE_TACHE } from "./roll-constants.mjs"; | ||||||
|  | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"; | ||||||
|  |  | ||||||
|  | export const PART_DIFF = "diff" | ||||||
|  |  | ||||||
|  | const EXCLUDED_ROLL_MODES = [ROLL_MODE_TACHE, ROLL_MODE_MEDITATION, ROLL_MODE_SORT, ROLL_MODE_OEUVRE] | ||||||
|  |  | ||||||
|  | export class RollPartDiff extends RollPart { | ||||||
|  |  | ||||||
|  |   get code() { return PART_DIFF } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||||
|  |  | ||||||
|  |   restore(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     const saved = this.getSaved(rollData) | ||||||
|  |     current.value = saved?.value ?? current.value ?? 0 | ||||||
|  |     current.mode = saved?.mode ?? current.mode | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   store(rollData, targetData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     this.setSaved(targetData, { | ||||||
|  |       value: current.value, | ||||||
|  |       mode: current.mode | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     if (EXCLUDED_ROLL_MODES.includes(rollData.mode.current)) { | ||||||
|  |       return false | ||||||
|  |     } | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     /* TODO: affiner les cas où afficher ou non. devrait s'afficher pour les jets basiques (même si pas d'opposant sélectionné)*/ | ||||||
|  |     return Object.values(DIFF_MODE).includes(current.mode) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   prepareContext(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     const diffMode = DIFF_MODES[current.mode] ?? DIFF_MODES[DIFF_MODE.AUCUN] | ||||||
|  |     foundry.utils.mergeObject(current, | ||||||
|  |       { | ||||||
|  |         mode: diffMode.key, | ||||||
|  |         label: diffMode?.label ?? '', | ||||||
|  |         value: current.value ?? 0, | ||||||
|  |         disabled: !diffMode.libre, | ||||||
|  |         min: -10, | ||||||
|  |         max: diffMode.max | ||||||
|  |       }, | ||||||
|  |       { inplace: true } | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getAjustements(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     return [{ | ||||||
|  |       label: current.label, | ||||||
|  |       diff: current.value | ||||||
|  |     }] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const input = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`) | ||||||
|  |  | ||||||
|  |     input?.addEventListener("change", e => { | ||||||
|  |       this.getCurrent(rollDialog.rollData).value = parseInt(e.currentTarget.value) | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								module/roll/roll-part-enctotal.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,31 @@ | |||||||
|  | import { RdDItemCompetence } from "../item-competence.js" | ||||||
|  | import { RdDCarac } from "../rdd-carac.js" | ||||||
|  | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
|  |  | ||||||
|  | const ENCTOTAL = "enctotal" | ||||||
|  |  | ||||||
|  | export class RollPartEncTotal extends RollPartCheckbox { | ||||||
|  |  | ||||||
|  |   get code() { return ENCTOTAL } | ||||||
|  |   get useCheckboxTemplate() { return false } | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     return RdDCarac.isAgiliteOuDerobee(rollData.current.carac.key) | ||||||
|  |       && RdDItemCompetence.isMalusEncombrementTotal(rollData.current.comp?.key) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     super._onRender(rollDialog, context, options) | ||||||
|  |  | ||||||
|  |     const inputMalusEnc = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="malusenc"]`) | ||||||
|  |      | ||||||
|  |     inputMalusEnc?.addEventListener("change", e => { | ||||||
|  |       this.getCurrent(rollDialog.rollData).value = parseInt(e.currentTarget.value) | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxIcon(rollData) { return '<i class="fa-solid fa-weight-hanging"></i>' } | ||||||
|  |   getCheckboxLabel(rollData) { return "Enc. total" } | ||||||
|  |   getCheckboxValue(rollData) { return - rollData.active.actor.getEncTotal() } | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								module/roll/roll-part-etat.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,30 @@ | |||||||
|  | import { RdDCarac } from "../rdd-carac.js" | ||||||
|  | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
|  |  | ||||||
|  | const ETAT = "etat" | ||||||
|  |  | ||||||
|  | export class RollPartEtat extends RollPartCheckbox { | ||||||
|  |  | ||||||
|  |   get code() { return ETAT } | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     const selectedCarac = rollData.current.carac?.key ?? '' | ||||||
|  |     if (selectedCarac == '') { | ||||||
|  |       return false | ||||||
|  |     } | ||||||
|  |     if (RdDCarac.isChance(selectedCarac)) { | ||||||
|  |       return false | ||||||
|  |     } | ||||||
|  |     if (RdDCarac.isReve(selectedCarac)) { | ||||||
|  |       if ((rollData.current.comp?.key ?? '') == '') { | ||||||
|  |         return false | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return this.getCheckboxValue(rollData) != 0 | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxLabel(rollData) { return "État général" } | ||||||
|  |   getCheckboxValue(rollData) { | ||||||
|  |     return rollData.active.actor.getEtatGeneral({ ethylisme: true }) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								module/roll/roll-part-ethylisme.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,28 @@ | |||||||
|  | import { RdDCarac } from "../rdd-carac.js" | ||||||
|  | import { RdDUtility } from "../rdd-utility.js" | ||||||
|  | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
|  |  | ||||||
|  | const ETHYLISME = "ethylisme" | ||||||
|  |  | ||||||
|  | export class RollPartEthylisme extends RollPartCheckbox { | ||||||
|  |  | ||||||
|  |   get code() { return ETHYLISME } | ||||||
|  |  | ||||||
|  |   isValid(rollData) { return rollData.active.actor.isPersonnage()} | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     return rollData.active.actor.isAlcoolise() && !RdDCarac.isChance(rollData.current.carac.key) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxIcon(rollData) { | ||||||
|  |     return '<i class="fa-solid fa-champagne-glasses"></i>' | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxLabel(rollData) { | ||||||
|  |     return `${RdDUtility.getNomEthylisme(rollData.active.actor.ethylisme())}` | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxValue(rollData) { | ||||||
|  |     return rollData.active.actor.malusEthylisme() | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										110
									
								
								module/roll/roll-part-jeu.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,110 @@ | |||||||
|  | import { Grammar } from "../grammar.js" | ||||||
|  | import { ITEM_TYPES } from "../constants.js" | ||||||
|  | import { CARACS } from "../rdd-carac.js" | ||||||
|  | import { ROLL_MODE_JEU } from "./roll-constants.mjs" | ||||||
|  | import { PART_CARAC } from "./roll-part-carac.mjs" | ||||||
|  | import { PART_COMP } from "./roll-part-comp.mjs" | ||||||
|  | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
|  | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_JEU = "jeu" | ||||||
|  |  | ||||||
|  | const COMPETENCE_JEU = 'Jeu' | ||||||
|  |  | ||||||
|  | export class RollPartJeu extends RollPartSelect { | ||||||
|  |  | ||||||
|  |   get code() { return PART_JEU } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||||
|  |  | ||||||
|  |   isValid(rollData) { return rollData.active.actor.isPersonnage() } | ||||||
|  |   visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_JEU) } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.jeux = rollData.active.actor.itemTypes[ITEM_TYPES.jeu] | ||||||
|  |       .map(it => RollPartJeu.$extractJeu(it, rollData.active.actor)) | ||||||
|  |     if (refs.jeux.length > 0) { | ||||||
|  |       this.$selectJeu(rollData) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   choices(refs) { return refs.jeux } | ||||||
|  |  | ||||||
|  |   static $extractJeu(jeu, actor) { | ||||||
|  |     const comp = actor.getCompetence(COMPETENCE_JEU) | ||||||
|  |     const caracs = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim()) | ||||||
|  |     const base = RollPartJeu.$getJeuBase(jeu, comp, caracs) | ||||||
|  |     return { | ||||||
|  |       key: jeu.id, | ||||||
|  |       label: jeu.name, | ||||||
|  |       caracs: caracs, | ||||||
|  |       jeu: jeu, | ||||||
|  |       value: (base ?? comp).system.niveau, | ||||||
|  |       base: base, | ||||||
|  |       comp: comp | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $getJeuBase(jeu, comp, caracs) { | ||||||
|  |     if (jeu.system.base < comp.system.niveau) { | ||||||
|  |       return undefined | ||||||
|  |     } | ||||||
|  |     return { | ||||||
|  |       id: comp.id, | ||||||
|  |       name: `Jeu ${jeu.name}`, | ||||||
|  |       type: comp.type, | ||||||
|  |       img: comp.img, | ||||||
|  |       system: foundry.utils.mergeObject( | ||||||
|  |         { | ||||||
|  |           niveau: jeu.system.base, | ||||||
|  |           base: jeu.system.base, | ||||||
|  |           default_carac: caracs.length > 0 ? caracs[0] : CARACS.CHANCE | ||||||
|  |         }, | ||||||
|  |         comp.system, | ||||||
|  |         { inplace: true, overwrite: false } | ||||||
|  |       ) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   prepareContext(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     if (rollData.mode.current == ROLL_MODE_JEU && current) { | ||||||
|  |       rollData.mode.opposed = true | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getAjustements(rollData) { return [] } | ||||||
|  |  | ||||||
|  |   $selectJeu(rollData, key) { | ||||||
|  |     this.selectByKey(rollData, key, 0) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const selectjeu = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-jeu"]`) | ||||||
|  |  | ||||||
|  |     selectjeu.addEventListener("change", e => { | ||||||
|  |       const selectOptions = e.currentTarget.options | ||||||
|  |       const index = selectOptions.selectedIndex | ||||||
|  |       this.$selectJeu(rollDialog.rollData, selectOptions[index]?.value) | ||||||
|  |       rollDialog.setModeTitle() | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getExternalPartsFilter(partCode, rollData) { | ||||||
|  |     if (this.visible(rollData)) { | ||||||
|  |       const current = this.getCurrent(rollData) | ||||||
|  |       switch (partCode) { | ||||||
|  |         case PART_CARAC: return p => current.caracs?.includes(Grammar.toLowerCaseNoAccent(p.key)) | ||||||
|  |         case PART_COMP: return p => p.label == current.comp?.name | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getSpecialComp(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     return current.base ? [current.base] : [] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								module/roll/roll-part-malusarmure.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,16 @@ | |||||||
|  | import { RdDCarac } from "../rdd-carac.js" | ||||||
|  | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
|  |  | ||||||
|  | const MALUSARMURE = "malusarmure" | ||||||
|  |  | ||||||
|  | export class RollPartMalusArmure extends RollPartCheckbox { | ||||||
|  |  | ||||||
|  |   get code() { return MALUSARMURE } | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     return RdDCarac.isAgiliteOuDerobee(rollData.current.carac.key) && this.getCheckboxValue(rollData) != 0 | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxLabel(rollData) { return "Malus armure" } | ||||||
|  |   getCheckboxValue(rollData) { return rollData.active.actor.getMalusArmure() } | ||||||
|  | } | ||||||
							
								
								
									
										117
									
								
								module/roll/roll-part-meditation.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,117 @@ | |||||||
|  | import { ITEM_TYPES } from "../constants.js" | ||||||
|  | import { Grammar } from "../grammar.js" | ||||||
|  | import { RdDCarac } from "../rdd-carac.js" | ||||||
|  | import { RdDTimestamp } from "../time/rdd-timestamp.js" | ||||||
|  | import { TMRUtility } from "../tmr-utility.js" | ||||||
|  | import { ROLL_MODE_MEDITATION } from "./roll-constants.mjs" | ||||||
|  | import { PART_CARAC } from "./roll-part-carac.mjs" | ||||||
|  | import { PART_COMP } from "./roll-part-comp.mjs" | ||||||
|  | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
|  | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_MEDITATION = "meditation" | ||||||
|  |  | ||||||
|  | export class RollPartMeditation extends RollPartSelect { | ||||||
|  |  | ||||||
|  |   get code() { return PART_MEDITATION } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||||
|  |  | ||||||
|  |   isValid(rollData) { return rollData.active.actor.isPersonnage() && rollData.active.actor.isHautRevant() } | ||||||
|  |   visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_MEDITATION) } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     foundry.utils.mergeObject(refs, | ||||||
|  |       { | ||||||
|  |         meditations: rollData.active.actor.itemTypes[ITEM_TYPES.meditation] | ||||||
|  |           .map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor)) | ||||||
|  |       } | ||||||
|  |     ) | ||||||
|  |     if (refs.meditations.length > 0) { | ||||||
|  |       this.$selectMeditation(rollData) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   choices(refs) { return refs.meditations } | ||||||
|  |  | ||||||
|  |   static $extractMeditation(meditation, actor) { | ||||||
|  |     return { | ||||||
|  |       key: meditation.id, | ||||||
|  |       label: meditation.name, | ||||||
|  |       meditation: meditation, | ||||||
|  |       comp: actor.getCompetence(meditation.system.competence) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   prepareContext(rollData) { | ||||||
|  |     this.getCurrent(rollData).value = this.getMalusConditions(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getMalusConditions(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     const conditionsManquantes = [ | ||||||
|  |       current.isComportement, | ||||||
|  |       current.isHeure, | ||||||
|  |       current.isPurification, | ||||||
|  |       current.isVeture | ||||||
|  |     ].filter(it => !it).length | ||||||
|  |     return -2 * conditionsManquantes | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getMalusEchecs(rollData) { | ||||||
|  |     return this.getCurrent(rollData).meditation.system.malus | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getAjustements(rollData) { | ||||||
|  |     const malusEchecs = { label: "Méditation", diff: this.getMalusEchecs(rollData) } | ||||||
|  |     const malusConditions = { label: "Conditions", diff: this.getMalusConditions(rollData) } | ||||||
|  |     return [malusConditions, ...(malusEchecs.diff == 0 ? [] : [malusEchecs])] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $selectMeditation(rollData, key) { | ||||||
|  |     const previous = this.getCurrent(rollData) | ||||||
|  |     const current = this.selectByKey(rollData, key, 0) | ||||||
|  |     if (current.key != previous.key) { | ||||||
|  |       const heureMonde = RdDTimestamp.getWorldTime().heure | ||||||
|  |       const heureMeditation = RdDTimestamp.findHeure(current.meditation.system.heure)?.heure | ||||||
|  |       current.isHeure = heureMeditation == heureMonde | ||||||
|  |       current.isTMR = Grammar.equalsInsensitive(current.meditation.system.tmr, TMRUtility.getTMRType(rollData.active.actor.system.reve.tmrpos.coord)) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |  | ||||||
|  |     const selectMeditation = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-meditation"]`) | ||||||
|  |     selectMeditation.addEventListener("change", e => { | ||||||
|  |       const selectOptions = e.currentTarget.options | ||||||
|  |       const index = selectOptions.selectedIndex | ||||||
|  |       this.$selectMeditation(rollDialog.rollData, selectOptions[index]?.value) | ||||||
|  |       rollDialog.render() | ||||||
|  |       rollDialog.setModeTitle() | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     this.setupListenerCondition(rollDialog, 'isComportement') | ||||||
|  |     this.setupListenerCondition(rollDialog, 'isHeure') | ||||||
|  |     this.setupListenerCondition(rollDialog, 'isPurification') | ||||||
|  |     this.setupListenerCondition(rollDialog, 'isVeture') | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   setupListenerCondition(rollDialog, inputName) { | ||||||
|  |     const checkbox = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${inputName}"]`) | ||||||
|  |     checkbox.addEventListener("change", e => { | ||||||
|  |       const current = this.getCurrent(rollDialog.rollData) | ||||||
|  |       current[inputName] = e.currentTarget.checked | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getExternalPartsFilter(partCode, rollData) { | ||||||
|  |     if (this.visible(rollData)) { | ||||||
|  |       const current = this.getCurrent(rollData) | ||||||
|  |       switch (partCode) { | ||||||
|  |         case PART_CARAC: return p => RdDCarac.isIntellect(p.key) | ||||||
|  |         case PART_COMP: return p => p.label == current.comp?.name | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								module/roll/roll-part-moral.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,16 @@ | |||||||
|  | import { RdDCarac } from "../rdd-carac.js" | ||||||
|  | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
|  |  | ||||||
|  | const MORAL = "moral" | ||||||
|  |  | ||||||
|  | export class RollPartMoral extends RollPartCheckbox { | ||||||
|  |  | ||||||
|  |   get code() { return MORAL } | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     return RdDCarac.isVolonte(rollData.current.carac.key) && this.getCheckboxValue(rollData) != 0 | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxLabel(rollData) { return "Moral" } | ||||||
|  |   getCheckboxValue(rollData) { return rollData.active.actor.getMoralTotal() } | ||||||
|  | } | ||||||
							
								
								
									
										99
									
								
								module/roll/roll-part-oeuvre.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,99 @@ | |||||||
|  | import { ITEM_TYPES } from "../constants.js" | ||||||
|  | import { Grammar } from "../grammar.js" | ||||||
|  | import { Misc } from "../misc.js" | ||||||
|  | import { CARACS } from "../rdd-carac.js" | ||||||
|  | import { ROLL_MODE_OEUVRE } from "./roll-constants.mjs" | ||||||
|  | import { PART_CARAC } from "./roll-part-carac.mjs" | ||||||
|  | import { PART_COMP } from "./roll-part-comp.mjs" | ||||||
|  | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
|  | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_OEUVRE = "oeuvre" | ||||||
|  |  | ||||||
|  | const ARTS = [ | ||||||
|  |   { type: ITEM_TYPES.oeuvre, action: "interpréte l'oeuvre", competence: it => it.system.competence, caracs: it => [it.system.default_carac] }, | ||||||
|  |   { type: ITEM_TYPES.chant, action: "chante", competence: it => 'Chant', caracs: it => [CARACS.OUIE] }, | ||||||
|  |   { | ||||||
|  |     type: ITEM_TYPES.danse, action: "danse:", competence: it => 'Danse', caracs: it => { | ||||||
|  |       const caracs = [] | ||||||
|  |       if (it.system.agilite) { caracs.push(CARACS.AGILITE) } | ||||||
|  |       if (it.system.apparence) { caracs.push(CARACS.APPARENCE) } | ||||||
|  |       return caracs | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   { type: ITEM_TYPES.musique, action: "joue le morceau:", competence: it => 'Musique', caracs: it => [CARACS.OUIE] }, | ||||||
|  |   { type: ITEM_TYPES.recettecuisine, action: "cuisine le plat:", competence: it => 'Cuisine', caracs: it => [CARACS.ODORATGOUT] }, | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | export class RollPartOeuvre extends RollPartSelect { | ||||||
|  |   onReady() { | ||||||
|  |     ARTS.forEach(art => art.label = Misc.typeName('Item', art.type)) | ||||||
|  |     ARTS.map(it => `roll-oeuvre-${it.type}`) | ||||||
|  |       .forEach(art => | ||||||
|  |         foundry.applications.handlebars.loadTemplates({ [art]: `systems/foundryvtt-reve-de-dragon/templates/roll/${art}.hbs` }) | ||||||
|  |       ) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   get code() { return PART_OEUVRE } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||||
|  |  | ||||||
|  |   isValid(rollData) { return rollData.active.actor.isPersonnage() } | ||||||
|  |   visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_OEUVRE) } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.oeuvres = rollData.active.actor.items | ||||||
|  |       .filter(it => it.isOeuvre() && RollPartOeuvre.getArt(it)) | ||||||
|  |       .map(it => RollPartOeuvre.$extractOeuvre(it, rollData.active.actor)) | ||||||
|  |     if (refs.oeuvres.length > 0) { | ||||||
|  |       this.$selectOeuvre(rollData) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   choices(refs) { return refs.oeuvres } | ||||||
|  |  | ||||||
|  |   static $extractOeuvre(oeuvre, actor) { | ||||||
|  |     const art = RollPartOeuvre.getArt(oeuvre) | ||||||
|  |     return { | ||||||
|  |       key: oeuvre.id, | ||||||
|  |       label: oeuvre.name, | ||||||
|  |       art: art, | ||||||
|  |       caracs: art.caracs(oeuvre), | ||||||
|  |       value: -oeuvre.system.niveau, | ||||||
|  |       oeuvre: oeuvre, | ||||||
|  |       comp: actor.getCompetence(art.competence(oeuvre)) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static getArt(oeuvre) { | ||||||
|  |     return ARTS.find(it => it.type == oeuvre.type) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $selectOeuvre(rollData, key) { | ||||||
|  |     this.selectByKey(rollData, key, 0) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const selectOeuvre = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-oeuvre"]`) | ||||||
|  |  | ||||||
|  |     selectOeuvre.addEventListener("change", e => { | ||||||
|  |       const selectOptions = e.currentTarget.options | ||||||
|  |       const index = selectOptions.selectedIndex | ||||||
|  |       this.$selectOeuvre(rollDialog.rollData, selectOptions[index]?.value) | ||||||
|  |       rollDialog.setModeTitle() | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getExternalPartsFilter(partCode, rollData) { | ||||||
|  |     if (this.visible(rollData)) { | ||||||
|  |       const current = this.getCurrent(rollData) | ||||||
|  |       switch (partCode) { | ||||||
|  |         case PART_CARAC: return p => current.caracs?.includes(Grammar.toLowerCaseNoAccent(p.key)) | ||||||
|  |         case PART_COMP: return p => p.label == current.comp?.name | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								module/roll/roll-part-opponent.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,12 @@ | |||||||
|  | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | const OPPONENT = "opponent" | ||||||
|  |  | ||||||
|  | export class RollPartOpponent extends RollPart { | ||||||
|  |  | ||||||
|  |   get code() { return OPPONENT } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.ACTION } | ||||||
|  |  | ||||||
|  |   visible(rollData) { return rollData.mode.opposed } | ||||||
|  |   title(rollData) { return rollData.opponent?.name ?? '' } | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								module/roll/roll-part-rollmode.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,32 @@ | |||||||
|  | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | const ROLLMODE = "rollmode" | ||||||
|  |  | ||||||
|  | export class RollPartRollMode extends RollPart { | ||||||
|  |  | ||||||
|  |   get code() { return ROLLMODE } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CONDITIONS } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     refs.rollmodes = Object.entries(CONFIG.Dice.rollModes).map(([k, v]) => { return { key: k, label: v.label, icon: v.icon } }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   restore(rollData) { | ||||||
|  |     this.setCurrent(rollData, { key: this.getSaved(rollData)?.key ?? game.settings.get("core", "rollMode") }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   store(rollData, targetData) { | ||||||
|  |     this.setSaved(targetData, { key: this.getCurrent(rollData).key }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const rollvisibilityButtons = rollDialog.element.querySelectorAll(`button[name="roll-rollmode"]`) | ||||||
|  |     rollvisibilityButtons?.forEach(it => it.addEventListener( | ||||||
|  |       "click", e => { | ||||||
|  |         e.preventDefault() | ||||||
|  |         this.getCurrent(rollDialog.rollData).key = e.currentTarget.dataset.key | ||||||
|  |         rollDialog.render() | ||||||
|  |       })) | ||||||
|  |   } | ||||||
|  | } | ||||||