Compare commits
	
		
			42 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0b90badb5e | |||
| 290b5029d1 | |||
| a7e4aea52d | |||
| 755d15509e | |||
| 02cea84ebb | |||
| c47fc4f5b6 | |||
| 147e49f2cb | |||
| 7f4f942d50 | |||
| 8f4df1af56 | |||
| 77f2de2c5f | |||
| e5e271e424 | |||
| 43ecca8be1 | |||
| e21f7e398a | |||
| e16f89743a | |||
| a6c593c100 | |||
| cd8e190082 | |||
| f2106763c1 | |||
| 5da5cb0314 | |||
| 6d7f66569a | |||
| 3e8963b20b | |||
| 2cf5b06da8 | |||
| 68c01fc930 | |||
| 3bc1c4871b | |||
| 3d732e9a8a | |||
| 35f226af5c | |||
| 126a0701d8 | |||
| edf920b340 | |||
| 293af5ab83 | |||
| 1bf9e330f4 | |||
| 33dc58138c | |||
| fa6769fcd7 | |||
| 47c4478303 | |||
| 52065fd6f6 | |||
| 6886f19921 | |||
| 10a89cc268 | |||
| 6a987086f8 | |||
| 54f470d531 | |||
| 37af0dd4f1 | |||
| d46b039a63 | |||
| 7370b633db | |||
| d0ba1ebf99 | |||
| 053bc23d12 | 
							
								
								
									
										1
									
								
								assets/actions/armes-disparates.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,0)" style=""><path d="m329.5 29.12-8.1 11.4L359 67.16l8.1-11.44zm-88 5.04 24.2 45.36 1.8 1.29 14.8-40.36zm57.6 12.63-16.4 44.8 40.7 28.81 35.3-31.54c-.9-.58-1.9-1.19-2.8-1.84zM59.83 48.56l10.84 45.83 29.63 2.6 2.7-29.63zM470.9 75.41c-5.6 4.71-12.2 8.59-19.5 11.74 5 46.45-14.7 83.45-45.2 109.75-26.5 22.9-60.9 38.4-95 47.9-2.5 4.8-5 9.2-7.4 13.1 41.5 5.4 93.2-21.2 129.2-60 19.8-21.3 34.8-45.9 41.1-69.2 5.2-19.4 4.7-37.42-3.2-53.29zm-351.3 8.71-3 32.48-32.35-2.9 226.55 271 20-16.7 15.3-12.8zM434 93.09c-4.2 1-8.5 2-12.8 2.7-14.9 2.5-30.1 3.1-43.5.3l-41 36.61c4 7 5 15.7 4.5 24.5-.6 12.6-4.3 26.7-9.3 40.9-3 8.3-6.3 16.6-9.9 24.6 26.9-9.2 52.6-22.3 72.5-39.4 26.2-22.8 42.5-51.6 39.5-90.21zM274 107.4l-51.2 72.2 30.6 36.5 58.2-82.1zM173.8 248.8 34.53 445.2l37.53 26.6L204.3 285.3zm233 79.2L273.3 439.5l19.2 23.1L426 351zm-18.3 77.9-35.3 29.4 39.7 47.6 35.3-29.4z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.0 KiB | 
							
								
								
									
										1
									
								
								assets/actions/cuisine.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M259.063 25.094c-56.045 0-106.836 9.775-144.438 26.125-18.8 8.174-34.34 17.96-45.594 29.53-11.254 11.57-18.28 25.338-18.28 40.188 0 9.936 3.17 19.388 8.625 28.03-10.218 21.883-15.844 45.794-15.844 70.782 0 103.158 95.757 187.844 215.532 187.844 119.776 0 215.563-84.686 215.563-187.844 0-24.99-5.653-48.897-15.875-70.78 5.454-8.644 8.625-18.096 8.625-28.032 0-14.85-7.026-28.617-18.28-40.188-11.256-11.57-26.825-21.356-45.626-29.53-37.603-16.35-88.363-26.126-144.408-26.126zm0 18.687c53.848 0 102.554 9.6 136.968 24.564 17.208 7.482 30.775 16.306 39.658 25.437 8.882 9.133 13 18.115 13 27.157 0 9.043-4.118 18.057-13 27.188-8.883 9.13-22.45 17.956-39.657 25.438-34.413 14.963-83.12 24.562-136.967 24.562-53.85 0-102.555-9.6-136.97-24.563-17.206-7.48-30.804-16.306-39.687-25.437-8.882-9.13-12.97-18.145-12.97-27.188 0-9.042 4.088-18.024 12.97-27.156 8.883-9.13 22.48-17.954 39.688-25.436 34.414-14.964 83.12-24.563 136.97-24.563zm-7.782 17.282c-80.57 0-146 26.008-146 57.844 0 31.836 65.43 57.81 146 57.813 40.04 0 76.404-6.613 102.782-16.94-21.316 3.34-45.064 5.845-70.656 5.845-86.066 0-155.937-21.656-155.937-47.906s69.868-47.282 155.936-47.282c20.43 0 39.926.725 57.813 2.906-24.816-7.704-55.957-12.28-89.94-12.28zM87.657 360.5c-9.916 19.897-14.758 36.638-15.78 49.03-1.23 14.906 2.752 22.238 6.655 24.626 3.905 2.388 11.497 2.48 23.376-5.75 9.25-6.41 20.16-17.73 31.375-34.406-16.778-9.432-32.1-20.71-45.624-33.5zm342.75.063c-13.532 12.782-28.872 24.043-45.656 33.468 11.21 16.666 22.13 27.97 31.375 34.376 11.88 8.23 19.472 8.138 23.375 5.75 3.903-2.388 7.886-9.72 6.656-24.625-1.022-12.38-5.855-29.098-15.75-48.967zm-199.25 64.25c1.36 21.275 5.296 37.554 10.344 48.468 6.272 13.56 13.26 17.82 17.72 17.908 4.457.088 11.14-3.683 17.374-16.907 5.133-10.89 9.165-27.52 10.437-49.467a267.366 267.366 0 0 1-27.967 1.468c-9.437 0-18.75-.506-27.907-1.467z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| After Width: | Height: | Size: 2.1 KiB | 
							
								
								
									
										1
									
								
								assets/actions/empoignade.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,0)" style=""><path d="M243.512 23.29c-27.105 18.337-53.533 32.92-82.274 45.337-2.843 17.364-3.948 34.497-4.05 51.584 28.913 15.41 56.096 32.85 83.33 49.634l7.045 4.344-3.432 7.482c-12.12 26.572-24.33 47.087-46.245 70.3l-5.184 5.512-6.46-3.904c-32.974-19.974-74.472-38.724-113.373-53.95l6.826-17.374c36.79 14.4 75.11 32.32 108.153 51.504 15.396-17.198 25.326-33.354 34.713-52.89-43.44-26.91-86.13-53.51-134.69-70.632-23.012 20.357-37.705 45.243-51.942 70.74 8.324 25.495 6.596 53.376-6.596 77.46 48.58-.593 97.994 2.23 150.666 10.26l5.658.837 1.787 5.44c8.85 26.46 11.79 54.41 8.325 83.588l-.987 8.432-8.466-.187c-40.508-.864-80.175-2.138-118.17.234 1.634 15.94-2.31 30.972-7.724 45.025 13.427 28.54 27.38 55.8 48.29 79.39 41.27-19.05 73.564-31.288 115.93-42.85-3.407-13.72-6.918-26.36-11.097-33.62-5.122-8.9-10.207-13.057-17.85-15.256-15.284-4.4-44.533 2.293-92.894 19.454l-6.243-17.594c48.907-17.354 79.702-26.894 104.283-19.82 9.133 2.628 16.884 8.004 23.066 15.46 14.487-7.627 28.415-16.79 42.053-26.996 12.34-45.92 37.29-81.42 66.626-112.107-7.226-13.52-13.208-27.204-20.563-40.613l-3.394-6.168 5-4.965c23.275-23.13 47.34-40.157 71.87-52.487l8.395 16.716c-20.952 10.53-41.503 25.913-61.795 45.152 12.41 23.91 22.263 45.5 39.457 64.826 37.488-27.124 74.943-51.39 116.84-74.938-13.96-30.473-31.345-58.357-56.286-79.462-32.2 13.38-62.527 17.39-92.61 12.29-14.223 13.25-30.094 22.23-48.756 23.337-29.017 1.722-60.74-15.74-99.174-57.672l6.858-6.295.017-.028.006.006 6.88-6.314c36.702 40.043 63.74 52.87 84.32 51.65 18.514-1.1 35.03-14.95 51.684-35.406-28.827-31.81-64.174-59.94-97.822-84.465zM39.324 277.884c-6.06.022-12.104.098-18.142.223 1.673 26.288 5.512 51.288 14.052 73.732 45.88-5.82 93.308-4.96 141.15-3.87 1.518-21.27-.253-41.69-6.058-61.212-45.528-6.565-88.59-9.03-131.002-8.873z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB | 
							
								
								
									
										65
									
								
								assets/actions/surenc.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,65 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    viewBox="0 0 448 434" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg6" | ||||||
|  |    sodipodi:docname="surenc.svg" | ||||||
|  |    width="448" | ||||||
|  |    height="434" | ||||||
|  |    inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata12"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title></dc:title> | ||||||
|  |       </cc:Work> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <defs | ||||||
|  |      id="defs10" /> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1" | ||||||
|  |      objecttolerance="10" | ||||||
|  |      gridtolerance="10" | ||||||
|  |      guidetolerance="10" | ||||||
|  |      inkscape:pageopacity="0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:window-width="3840" | ||||||
|  |      inkscape:window-height="2054" | ||||||
|  |      id="namedview8" | ||||||
|  |      showgrid="false" | ||||||
|  |      fit-margin-top="0" | ||||||
|  |      fit-margin-left="0" | ||||||
|  |      fit-margin-right="0" | ||||||
|  |      fit-margin-bottom="0" | ||||||
|  |      inkscape:zoom="1.4355469" | ||||||
|  |      inkscape:cx="224" | ||||||
|  |      inkscape:cy="210" | ||||||
|  |      inkscape:window-x="-11" | ||||||
|  |      inkscape:window-y="-11" | ||||||
|  |      inkscape:window-maximized="1" | ||||||
|  |      inkscape:current-layer="svg6" /> | ||||||
|  |   <g | ||||||
|  |      class="" | ||||||
|  |      id="g4" | ||||||
|  |      transform="translate(-32,-46)"> | ||||||
|  |     <path | ||||||
|  |        d="m 256,46 c -45.074,0 -82,36.926 -82,82 0,25.812 12.123,48.936 30.938,64 H 128 L 32,480 H 480 L 384,192 H 307.062 C 325.877,176.936 338,153.812 338,128 338,82.926 301.074,46 256,46 Z m 0,36 c 25.618,0 46,20.382 46,46 0,25.618 -20.382,46 -46,46 -25.618,0 -46,-20.382 -46,-46 0,-25.618 20.382,-46 46,-46 z m -82.215,202.95 h 23.5 v 33.263 l 33.873,-33.264 h 27.283 l -43.883,43.15 48.4,47.974 H 233.54 l -36.255,-35.888 v 35.888 h -23.5 z m 119.934,21.24 c 4.76,0 8.952,0.934 12.573,2.806 3.62,1.872 6.938,4.82 9.95,8.85 v -10.13 h 21.972 v 61.462 c 0,10.986 -3.48,19.368 -10.438,25.146 -6.917,5.82 -16.968,8.727 -30.152,8.727 -4.272,0 -8.4,-0.325 -12.39,-0.976 a 77.367,77.367 0 0 1 -12.024,-2.99 v -17.03 c 3.826,2.198 7.57,3.826 11.23,4.884 3.664,1.098 7.347,1.648 11.05,1.648 7.162,0 12.41,-1.566 15.746,-4.7 3.337,-3.132 5.006,-8.035 5.006,-14.708 v -4.7 c -3.01,3.986 -6.328,6.916 -9.95,8.788 -3.62,1.87 -7.813,2.808 -12.573,2.808 -8.343,0 -15.238,-3.275 -20.69,-9.826 -5.453,-6.592 -8.18,-14.974 -8.18,-25.146 0,-10.214 2.727,-18.576 8.18,-25.086 5.452,-6.55 12.347,-9.827 20.69,-9.827 z m 8.118,15.746 c -4.517,0 -8.038,1.67 -10.56,5.005 -2.523,3.338 -3.784,8.058 -3.784,14.162 0,6.266 1.22,11.026 3.662,14.28 2.442,3.215 6.003,4.823 10.682,4.823 4.557,0 8.096,-1.67 10.62,-5.006 2.522,-3.337 3.784,-8.036 3.784,-14.098 0,-6.104 -1.262,-10.824 -3.785,-14.16 -2.523,-3.337 -6.062,-5.006 -10.62,-5.006 z" | ||||||
|  |        fill="#ffffff" | ||||||
|  |        fill-opacity="1" | ||||||
|  |        id="path2" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 3.1 KiB | 
							
								
								
									
										1
									
								
								assets/ui/fatigue.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M249.094 18.25c-42.675 0-81.852 25.486-110.938 68.438C109.07 129.637 90.72 189.74 90.72 256.28c0 66.543 18.35 126.643 47.436 169.595s68.263 68.47 110.938 68.47 81.883-25.518 110.97-68.47c29.084-42.952 47.436-103.052 47.436-169.594 0-66.54-18.352-126.64-47.438-169.592C330.978 43.736 291.77 18.25 249.094 18.25zm-128.97 241.313c18.356 18.096 37.528 26.765 55.72 27.562 18.19.797 35.927-6.096 52.125-21.5l12.874 13.53c-19.214 18.274-42.25 27.658-65.813 26.626-23.56-1.03-47.1-12.3-68-32.905l13.095-13.313zm264.782 0 13.125 13.312C377.135 293.48 353.564 304.75 330 305.78c-23.563 1.033-46.598-8.35-65.813-26.624l12.875-13.53c16.2 15.403 33.934 22.296 52.125 21.5 18.192-.798 37.365-9.467 55.72-27.563zM251.562 371.656c36.423-.156 72.996 19.144 77.438 58.406-51.33 13.296-102.67 12.767-154 0 3.858-38.638 40.14-58.25 76.563-58.406z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										1
									
								
								assets/ui/maladresse.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="M221.313 16a23.682 23.695 0 0 0-23.688 23.688v106.406a23.682 23.695 0 0 0 2.156 9.72 23.682 23.695 0 0 0 3.157 13.81l41.75 71.626-79 55.438 6.094-48.625a23.682 23.695 0 0 0-8.186-20.97l-66.28-81.937a23.682 23.695 0 0 0-33.314-3.5l-9.188 7.438a23.682 23.695 0 0 0-3.53 33.344l59.78 73.906-11.25 89.937a23.682 23.695 0 0 0 12.47 23.876l37.468 53.47a23.695 23.682 1.57 0 0 2.344 2.812 23.682 23.695 0 0 0 13.594 20.062L262 491.53a23.682 23.695 0 0 0 9.97 2.22 23.682 23.695 0 0 0 23.53-2.063l87.156-60.937a23.682 23.695 0 0 0 5.844-33l-6.78-9.688a23.682 23.695 0 0 0-32.97-5.875l-72.406 50.657-59.063-27.625 120.595-84.626a23.695 23.682 1.57 0 0 5.53-5.5 23.682 23.695 0 0 0 14.626-13.594l37.22-91.53 87.813-44.845a23.694 23.682 1.18 0 0 10.312-31.875L488 122.687a23.694 23.682 1.18 0 0-31.875-10.343l-94.688 48.375a23.694 23.682 1.18 0 0-9.843 9.436 23.682 23.695 0 0 0-8.344 10.47l-27.375 67.31-5.22-7.436a23.682 23.695 0 0 0-3-8.844l-50.81-87.094V39.688A23.682 23.695 0 0 0 233.154 16h-11.843zM77.75 376A59.994 60 0 0 0 16 436a59.994 60 0 1 0 120 0 59.994 60 0 0 0-58.25-60z" fill="#fff" fill-opacity="1"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										1
									
								
								assets/ui/part-finesse.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M45.95 14.553c-19.38.81-30.594 11.357-30.282 30.283l19.768 30.78c4.43-1.213 9.36-3.838 14.248-7.335l42.474 59.935c-17.018 20.83-31.258 44.44-42.71 70.836l26.55 26.552c11.275-23.6 24.634-44.826 39.918-63.864l210.82 297.475 166.807 33.213L460.33 325.62 162.78 114.745c19.907-16.108 41.842-29.91 65.652-41.578l-26.553-26.55c-27.206 11.803-51.442 26.576-72.735 44.292L69.39 48.56c3.443-4.823 6.062-9.735 7.342-14.242l-30.78-19.765zm400.84 86.933v.008l.003-.008h-.002zm0 .008-28.028 124.97-25.116-80.593-18.105 70.667-26.862-49.64-.584 57.818 128.484 91.69 15.184 87.017-1.168-186.885-34.457 39.713-9.346-154.756zm-300.95 27.98 222.224 196.368 25.645 66.75-66.75-25.645L130.6 144.734a308.453 308.453 0 0 1 15.238-15.26zm32.305 196.274v.004h.005l-.005-.004zm.005.004 28.028 22.775-36.21 4.088 57.82 19.272-105.706 4.09 115.05 27.45L136.1 422.114l127.316 25.696-67.164 43.803 208.494 1.752-87.017-15.185-104.54-150.676-35.037-1.752z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										1
									
								
								assets/ui/part-force.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M227.227 21.777c-1.845 0-3.704.05-5.567.157-15.314.875-30.76 5.305-39.494 10.863l-.008 73.15c2.884-.094 5.777-.147 8.676-.142 23.382.036 47.104 3.286 68.47 9.513l.01-87.507c-7.034-3.518-19.178-6.03-32.087-6.033zm80.74 9.16c-11.925.15-23.077 2.364-29.967 5.596l-.008 77.602v7.658c38.486 15.67 64.814 42.48 58.735 78.764l-.96 5.73-5.562 1.674c-17.45 5.253-34.872 9.703-52.225 13.335v25.234c25.562-.704 51.327-2.687 77.145-6.098l.02-197.928c-8.284-5.563-23.508-10.243-38.842-11.328a100.065 100.065 0 0 0-8.336-.238zM143.223 46.294a99.206 99.206 0 0 0-16.491 1.172c-15.67 2.454-31.477 8.565-40.406 15.402l-.01 72.955c18.808-15.81 46.704-25.143 77.15-28.54l.007-57.966c-4.82-1.752-12.018-2.916-20.25-3.023zm258.394 3.46c-10.804.117-20.722 1.93-27.043 4.655l-.02 183.182c25.074-4.02 50.16-9.412 75.122-16.358l1.99-158.447c-8.352-5.9-23.648-11.025-39.05-12.553a100.98 100.98 0 0 0-11-.478zm-222.775 74.202c-53.72.702-101.407 20.365-97.887 66.6 15.836-3.918 30.84-5.893 44.94-6.1 34.84-.51 64.213 9.704 87.318 27.613 34.608-3.11 69.852-10 105.412-20.314.14-41.287-74.098-68.657-139.783-67.8zm-48.877 78.65c-1.296-.003-2.603.012-3.92.045-17.256.436-36.45 4.03-57.566 11.037 5.79 53.808 26.325 106.41 58.5 143.346 6.226 7.15 12.856 13.712 19.875 19.615 29.303 9.282 69.26 12.917 110.534 12.14 3.777-55.805-8.717-108.357-36.193-142.74-21.265-26.61-51.064-43.39-91.232-43.444zm129.326 22.282a545.177 545.177 0 0 1-27.995 4.15 138.77 138.77 0 0 1 4.502 5.346c3.146 3.937 6.094 8.062 8.873 12.334 9.916.144 19.868.125 29.857-.106H259.29v-21.723zm191.817 15.343c-65.406 17.826-131.462 25.41-195.85 25.315 16.998 35.144 23.828 78.093 21.013 122.6 42.482-2.08 85.03-8.23 118.187-15.983 26.693-32.78 47.37-77.118 56.65-131.932zM400.51 389.9c-38.334 9.145-87.95 16.056-136.873 17.454-47.67 1.36-94.336-2.228-129.448-15.262l-.01 78.93c27.187 12.568 76.414 20.205 127.318 20.298 51.224.094 104.214-7.173 139-20.773l.012-80.647z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| After Width: | Height: | Size: 2.1 KiB | 
							
								
								
									
										1
									
								
								assets/ui/part-rapidite.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M275.03 20c35.223 49.563 53.59 113.64 55.69 173.47C315.154 143 289.092 88.423 250.81 48.75c40.294 79.527 51.15 172.312 37.938 256.094-12.287-75.777-40.564-159.524-92.375-227.156 29.6 70.937 36.64 149.785 24.813 221.843-8.745-51.804-25.41-107.4-52.594-158.81 13.023 54.315 12.854 107.64 3.437 159.28l21.657 6.813 15 4.718-11.28 10.908c-10.68 10.332-19.868 21.905-27.345 34.343 93.614 35.486 232.952 64.53 298.032 41.376-41.02 56.466-210.332 13.822-309.313-18.687-1.514 3.775-2.918 7.594-4.124 11.467a152.536 152.536 0 0 0-6.062 29.657l176.47 66.375c98.5 31.095 150.5-24.62 158.655-81.72C505.253 254.472 485.016 105.66 426.06 20h-22.187c40.092 65.52 66.67 154.216 60.47 255.344-8.154-79.833-42.8-157.214-98.44-219.5 38.676 85.094 56.566 185.746 34.376 288.625.057-118.816-33.1-225.865-105.092-324.47H275.03zm-110.186 1.594c41.255 29.176 74.328 74.093 97.5 120.656-7.702-46.15-21.3-86.79-44-120.656h-53.5zm176.375 0c28.882 15.143 52.096 36.614 71.28 66.78-7.14-27.79-17.217-49.85-31.438-66.78H341.22zM123.686 304.406a179.344 179.344 0 0 1-4.062 64L18.812 336.344V366l91.938 29.094a178.602 178.602 0 0 1-30.313 48.28l50.094 15.75c-3.038-24.898-1.136-49.885 6.282-73.718 7.446-23.92 20.223-46.108 37.032-65.22l-50.156-15.78z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg> | ||||||
| After Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										79
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						| @@ -1,4 +1,83 @@ | |||||||
| # 13.0 | # 13.0 | ||||||
|  | ## 13.0.14 - Le familier d'Illysis | ||||||
|  |  | ||||||
|  | - Les réussites particulières en demi-surprise sont de simples réussites | ||||||
|  | - Les images des scènes par défaut sont corrigées | ||||||
|  | - Ajout d'une image de status "sur-encombré" | ||||||
|  | - Correction V13 | ||||||
|  |   - couleur lisible dans les sommaires des journaux et des compendiums | ||||||
|  | - Amélioration des entités: | ||||||
|  |   - l'attaquant ne sait plus que c'est une entité de cauchemar (surprise!) | ||||||
|  |   - l'encaissement indique une blessure dans le tchat... même si ce n'est que de l'endurance | ||||||
|  |   - les blurettes suivent les règles des entités de cauchemar (p322) | ||||||
|  | - Nouvelle fenêtre de jets de dés | ||||||
|  |   - attaque/défense des créatures | ||||||
|  |   - les attaques/parades avec une arme trop lourde se font en demi-surprise | ||||||
|  |   - les demandes de défense disparaîssent une fois prises en compte | ||||||
|  |   - empoignade | ||||||
|  |     - l'empoignade est possible avec une initiative d'empoignade, ou en cours d'empoignade | ||||||
|  |     - seule la dague, le pugilat et la dague sont possibles en cours d'empoignade | ||||||
|  |     - jet de Dextérité/Dague pour utiliser la dague en cours d'empoignade (p136) | ||||||
|  |     - attaquer avec une arme un empoigneur donne un +4 si pas d'empoignade (p134) | ||||||
|  |     - la différence de taille donne un bonus/malus en cours d'empoignade (p135) | ||||||
|  |     - les dommages de l'empoignade ajoutent/enlèvent un point d'empoignade | ||||||
|  |     - le statut d'empoignade est affiché sur les tokens | ||||||
|  |     - les défenses contre une empoignade sont corrigées | ||||||
|  |  | ||||||
|  | ## 13.0.13 - L'épanouissement d'Illysis | ||||||
|  |  | ||||||
|  | - Fix d'erreur au chargement de templates RollDialog | ||||||
|  | - Nouvelle fenêtre de jets de dés | ||||||
|  |   - Fix: affichage des points de tâche | ||||||
|  |   - Fix: affichage des ajustements cohérent | ||||||
|  |   - L'ouverture depuis les caractéristiques permet plusieurs types de jets | ||||||
|  |   - On peut créer ou modifier les tâches dans la fenêtre de jets de tâches | ||||||
|  |   - attaque/défense | ||||||
|  |     - les maladresses sont affichées dans le résultat du jet | ||||||
|  |     - le message au défenseur s'affiche correctement | ||||||
|  |     - la difficulté d'attaque s'applique à la défense | ||||||
|  |     - on peut choisir les particulières en rapidité | ||||||
|  |  | ||||||
|  | ## 13.0.12 - La méditation d'Illysis | ||||||
|  |  | ||||||
|  | - les signes draconiques éphémères de 1 round sont supprimés à la descente des TMRs | ||||||
|  | - Générateur de description | ||||||
|  |   - correction des termes pour les couleurs des yeux/cheveux | ||||||
|  |   - ajout de boutons pour forcer le sexe masculin/féminin | ||||||
|  | - Nouvelle fenêtre de jets de dés | ||||||
|  |   - les méditations proposent un bouton pour monter dans les TMRs | ||||||
|  |   - fenêtre de lancer de sorts | ||||||
|  |   - Correction: les compétences de jeux ne remplacent plus les compétences en dehors des jets de jeu | ||||||
|  |   - gestion des maladresses d'attaque et défense | ||||||
|  |  | ||||||
|  | ## 13.0.11 - Le gambit d'Illysis | ||||||
|  |  | ||||||
|  | - Nouvelle fenêtre de jets de dés | ||||||
|  |   - jeux | ||||||
|  |   - cuisine et préparation de nourriture | ||||||
|  |  | ||||||
|  | ## 13.0.10 - Les papilles d'Illysis | ||||||
|  |  | ||||||
|  | - Ajout d'un statut "saignement" en cas de blessure grave ou critique sans premiers soins | ||||||
|  |  | ||||||
|  | - Nouvelle fenêtre de jets de dés | ||||||
|  |   - jets de méditation | ||||||
|  |   - jets de tâches | ||||||
|  |   - jets de caractéristiques | ||||||
|  |   - jets de compétences | ||||||
|  |   - Boutons d'initiative et d'attaque V2 | ||||||
|  |   - fenêtre d'attaque | ||||||
|  |     - choix des armes | ||||||
|  |     - gestion des particulières | ||||||
|  |     - message au défenseur | ||||||
|  |     - gestion des demi-surprises (attaquant/défenseur) | ||||||
|  |     - gestion des tactiques (attaquant/défenseur) | ||||||
|  |   - en cours nouvelle fenêtre de jets | ||||||
|  |     - jets de compétence avec messages | ||||||
|  |     - jets de cuisine séparés avec messages (pour gérer plus tard les spécificités: fabricatioon de plats) | ||||||
|  |     - gestion des empoignades | ||||||
|  |  | ||||||
|  | - Technique: suppression de warnings foundry sur renderTemplate | ||||||
|  |  | ||||||
| ## 13.0.9 - Le combat d'Illysis | ## 13.0.9 - Le combat d'Illysis | ||||||
| - Fix | - Fix | ||||||
|   | |||||||
| @@ -96,6 +96,7 @@ select, | |||||||
|   --gradient-red: linear-gradient(150deg, rgba(255, 0, 0, 0.3), rgba(255, 200, 128, 0.05), rgba(255, 200, 128, 0.1), rgba(255, 10, 0, 0.3)); |   --gradient-red: linear-gradient(150deg, rgba(255, 0, 0, 0.3), rgba(255, 200, 128, 0.05), rgba(255, 200, 128, 0.1), rgba(255, 10, 0, 0.3)); | ||||||
|   --gradient-violet: linear-gradient(150deg, rgba(100, 45, 124, 0.6), rgba(216, 157, 192, 0.3), rgba(177, 157, 216, 0.5), rgba(107, 62, 121, 0.3), rgba(100, 45, 124, 0.6)); |   --gradient-violet: linear-gradient(150deg, rgba(100, 45, 124, 0.6), rgba(216, 157, 192, 0.3), rgba(177, 157, 216, 0.5), rgba(107, 62, 121, 0.3), rgba(100, 45, 124, 0.6)); | ||||||
|   --gradient-purple-black: linear-gradient(150deg, rgba(0, 0, 0, 0.7), rgba(100, 45, 124, 0.4), rgba(82, 17, 131, 0.3), rgba(100, 45, 124, 0.4), rgba(0, 0, 0, 0.7)); |   --gradient-purple-black: linear-gradient(150deg, rgba(0, 0, 0, 0.7), rgba(100, 45, 124, 0.4), rgba(82, 17, 131, 0.3), rgba(100, 45, 124, 0.4), rgba(0, 0, 0, 0.7)); | ||||||
|  |   --gradient-warning: linear-gradient(150deg, hsla(32, 100%, 50%, 0.3), hsla(52, 60%, 50%, 0.1), hsla(32, 60%, 50%, 0.1), hsla(32, 100%, 50%, 0.3)); | ||||||
|   --gradient-silver-light: linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2)); |   --gradient-silver-light: linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2)); | ||||||
|   --gradient-daylight: conic-gradient(from 0deg, hsla(50, 100%, 80%, 0.7), hsla(30, 30%, 40%, 0.1) 25%, hsla(250, 50%, 40%, 0.1) 25%, hsla(250, 30%, 30%, 0.7) 50%, hsla(250, 50%, 40%, 0.1) 75%, hsla(30, 30%, 40%, 0.1) 75%, hsla(50, 100%, 80%, 0.7)); |   --gradient-daylight: conic-gradient(from 0deg, hsla(50, 100%, 80%, 0.7), hsla(30, 30%, 40%, 0.1) 25%, hsla(250, 50%, 40%, 0.1) 25%, hsla(250, 30%, 30%, 0.7) 50%, hsla(250, 50%, 40%, 0.1) 75%, hsla(30, 30%, 40%, 0.1) 75%, hsla(50, 100%, 80%, 0.7)); | ||||||
|   --background-custom-button: linear-gradient(to bottom, hsla(208, 38%, 21%, 0.988) 5%, hsla(202, 42%, 14%, 0.671) 100%); |   --background-custom-button: linear-gradient(to bottom, hsla(208, 38%, 21%, 0.988) 5%, hsla(202, 42%, 14%, 0.671) 100%); | ||||||
| @@ -159,7 +160,7 @@ select, | |||||||
|   min-height: 100px; |   min-height: 100px; | ||||||
|   background: var(--rdd-bg-input-alt); |   background: var(--rdd-bg-input-alt); | ||||||
|   padding: 5px; |   padding: 5px; | ||||||
|   border-radius: 3px; |   border-radius: 0.2rem; | ||||||
|   color: var(--rdd-color-text-primary); |   color: var(--rdd-color-text-primary); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .monnaie-content .window-content { | .system-foundryvtt-reve-de-dragon .monnaie-content .window-content { | ||||||
| @@ -176,7 +177,7 @@ select, | |||||||
|   background: var(--fieldset-background); |   background: var(--fieldset-background); | ||||||
|   color: var(--rdd-color-text-primary); |   color: var(--rdd-color-text-primary); | ||||||
|   margin-bottom: 4px; |   margin-bottom: 4px; | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   border-color: var(--rdd-color-text-primary); |   border-color: var(--rdd-color-text-primary); | ||||||
|   border-width: 2px; |   border-width: 2px; | ||||||
| } | } | ||||||
| @@ -206,7 +207,7 @@ select, | |||||||
|   border: 1px solid var(--rdd-color-border-input); |   border: 1px solid var(--rdd-color-border-input); | ||||||
|   color: var(--rdd-color-text-input); |   color: var(--rdd-color-text-input); | ||||||
|   padding: 2px 2px; |   padding: 2px 2px; | ||||||
|   border-radius: 3px; |   border-radius: 0.2rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .monnaie-content .form-group input[type="checkbox"] { | .system-foundryvtt-reve-de-dragon .monnaie-content .form-group input[type="checkbox"] { | ||||||
|   flex: 0 0 20px; |   flex: 0 0 20px; | ||||||
| @@ -250,7 +251,7 @@ select, | |||||||
|   min-height: 100px; |   min-height: 100px; | ||||||
|   background: var(--rdd-bg-input-alt); |   background: var(--rdd-bg-input-alt); | ||||||
|   padding: 5px; |   padding: 5px; | ||||||
|   border-radius: 3px; |   border-radius: 0.2rem; | ||||||
|   color: var(--rdd-color-text-primary); |   color: var(--rdd-color-text-primary); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .munition-content .window-content { | .system-foundryvtt-reve-de-dragon .munition-content .window-content { | ||||||
| @@ -267,7 +268,7 @@ select, | |||||||
|   background: var(--fieldset-background); |   background: var(--fieldset-background); | ||||||
|   color: var(--rdd-color-text-primary); |   color: var(--rdd-color-text-primary); | ||||||
|   margin-bottom: 4px; |   margin-bottom: 4px; | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   border-color: var(--rdd-color-text-primary); |   border-color: var(--rdd-color-text-primary); | ||||||
|   border-width: 2px; |   border-width: 2px; | ||||||
| } | } | ||||||
| @@ -297,7 +298,7 @@ select, | |||||||
|   border: 1px solid var(--rdd-color-border-input); |   border: 1px solid var(--rdd-color-border-input); | ||||||
|   color: var(--rdd-color-text-input); |   color: var(--rdd-color-text-input); | ||||||
|   padding: 2px 2px; |   padding: 2px 2px; | ||||||
|   border-radius: 3px; |   border-radius: 0.2rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .munition-content .form-group input[type="checkbox"] { | .system-foundryvtt-reve-de-dragon .munition-content .form-group input[type="checkbox"] { | ||||||
|   flex: 0 0 20px; |   flex: 0 0 20px; | ||||||
| @@ -341,7 +342,7 @@ select, | |||||||
|   min-height: 100px; |   min-height: 100px; | ||||||
|   background: var(--rdd-bg-input-alt); |   background: var(--rdd-bg-input-alt); | ||||||
|   padding: 5px; |   padding: 5px; | ||||||
|   border-radius: 3px; |   border-radius: 0.2rem; | ||||||
|   color: var(--rdd-color-text-primary); |   color: var(--rdd-color-text-primary); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .tarot-content .window-content { | .system-foundryvtt-reve-de-dragon .tarot-content .window-content { | ||||||
| @@ -358,7 +359,7 @@ select, | |||||||
|   background: var(--fieldset-background); |   background: var(--fieldset-background); | ||||||
|   color: var(--rdd-color-text-primary); |   color: var(--rdd-color-text-primary); | ||||||
|   margin-bottom: 4px; |   margin-bottom: 4px; | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   border-color: var(--rdd-color-text-primary); |   border-color: var(--rdd-color-text-primary); | ||||||
|   border-width: 2px; |   border-width: 2px; | ||||||
| } | } | ||||||
| @@ -388,7 +389,7 @@ select, | |||||||
|   border: 1px solid var(--rdd-color-border-input); |   border: 1px solid var(--rdd-color-border-input); | ||||||
|   color: var(--rdd-color-text-input); |   color: var(--rdd-color-text-input); | ||||||
|   padding: 2px 2px; |   padding: 2px 2px; | ||||||
|   border-radius: 3px; |   border-radius: 0.2rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .tarot-content .form-group input[type="checkbox"] { | .system-foundryvtt-reve-de-dragon .tarot-content .form-group input[type="checkbox"] { | ||||||
|   flex: 0 0 20px; |   flex: 0 0 20px; | ||||||
| @@ -528,6 +529,10 @@ select, | |||||||
|   flex-direction: row; |   flex-direction: row; | ||||||
|   margin: 0.1rem 0; |   margin: 0.1rem 0; | ||||||
| } | } | ||||||
|  | .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section subline .warning { | ||||||
|  |   border-radius: 0.5rem; | ||||||
|  |   background: var(--gradient-warning); | ||||||
|  | } | ||||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-img { | .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-img { | ||||||
|   display: flex; |   display: flex; | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
| @@ -555,6 +560,7 @@ select, | |||||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline div.poesie-extrait { | .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline div.poesie-extrait { | ||||||
|   display: flex; |   display: flex; | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
|  |   align-items: normal; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline span.status-surprise { | .system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline span.status-surprise { | ||||||
|   display: flex; |   display: flex; | ||||||
| @@ -571,8 +577,12 @@ select, | |||||||
|   display: flow; |   display: flow; | ||||||
|   width: 2.5rem; |   width: 2.5rem; | ||||||
|   text-align: right; |   text-align: right; | ||||||
|   margin: 0 0.2rem 0 0.5rem; |   margin: 0 0.2rem; | ||||||
|   padding: 0 0.2rem; |   padding: 0 0.2rem; | ||||||
|  |   border: 1px solid ; | ||||||
|  |   border-radius: 0.2rem; | ||||||
|  |   height: 1.5rem; | ||||||
|  |   background: hsla(0, 0%, 0%, 0.2); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-action { | .system-foundryvtt-reve-de-dragon .roll-dialog roll-action { | ||||||
|   flex-basis: content; |   flex-basis: content; | ||||||
| @@ -627,24 +637,29 @@ select, | |||||||
|   margin: 0 0.1rem; |   margin: 0 0.1rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-carac select[name="select-carac"] { | .system-foundryvtt-reve-de-dragon .roll-dialog roll-carac select[name="select-carac"] { | ||||||
|   max-width: 6rem; |   min-width: 6.5rem; | ||||||
|  |   max-width: 8rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-comp select[name="select-comp"] { | .system-foundryvtt-reve-de-dragon .roll-dialog roll-comp select[name="select-comp"] { | ||||||
|   min-width: 8rem; |   min-width: 8rem; | ||||||
|   max-width: 11rem; |   max-width: 10rem; | ||||||
|   margin-left: 1rem; |   margin-left: 1.5rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="coeur"] select[name="coeur"] { | .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="coeur"] select[name="coeur"] { | ||||||
|   max-width: 4rem; |   max-width: 4rem; | ||||||
| } | } | ||||||
|  | .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section img { | ||||||
|  |   max-width: 1rem; | ||||||
|  |   max-height: 1rem; | ||||||
|  |   gap: 0; | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0; | ||||||
|  |   filter: invert(0.8); | ||||||
|  | } | ||||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="tricher"] img { | .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="tricher"] img { | ||||||
|   /* image de d100 */ |   /* image de d100 */ | ||||||
|   max-width: 2.5rem; |   max-width: 2.5rem; | ||||||
|   max-height: 2.5rem; |   max-height: 2.5rem; | ||||||
|   gap: 0; |  | ||||||
|   margin: 0; |  | ||||||
|   padding: 0; |  | ||||||
|   filter: invert(0.8); |  | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .roll-dialog roll-buttons { | .system-foundryvtt-reve-de-dragon .roll-dialog roll-buttons { | ||||||
|   display: flex; |   display: flex; | ||||||
| @@ -655,7 +670,8 @@ select, | |||||||
|   width: 1.5rem; |   width: 1.5rem; | ||||||
|   text-align: center; |   text-align: center; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat { | ||||||
|   font-family: CaslonAntique; |   font-family: CaslonAntique; | ||||||
|   display: grid; |   display: grid; | ||||||
|   grid-template-areas: "img     header  buttons" "img     resume  buttons" "details details details" "actions actions actions"; |   grid-template-areas: "img     header  buttons" "img     resume  buttons" "details details details" "actions actions actions"; | ||||||
| @@ -663,51 +679,65 @@ select, | |||||||
|   grid-template-rows: max-content max-content max-content max-content; |   grid-template-rows: max-content max-content max-content max-content; | ||||||
|   gap: 0 0.5rem; |   gap: 0 0.5rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-img { | ||||||
|   grid-area: img; |   grid-area: img; | ||||||
|   display: flex; |   display: flex; | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img img { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img img, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-img img { | ||||||
|   border: 0; |   border: 0; | ||||||
|   max-height: 3rem; |   max-height: 3rem; | ||||||
|   max-width: 3rem; |   max-width: 3rem; | ||||||
|   object-fit: contain; |   object-fit: contain; | ||||||
|   height: 100%; |   height: 100%; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-header { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-header, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-header { | ||||||
|   grid-area: header; |   grid-area: header; | ||||||
|   font-weight: bold; |   font-weight: bold; | ||||||
|   font-size: 0.9rem; |   font-size: 0.9rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-resume { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-resume, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-resume { | ||||||
|   grid-area: resume; |   grid-area: resume; | ||||||
|   text-align: justify; |   text-align: justify; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-details { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-details, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-details { | ||||||
|   grid-area: details; |   grid-area: details; | ||||||
|   text-align: justify; |   text-align: justify; | ||||||
|   display: flex; |   display: flex; | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-details div, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-details div { | ||||||
|  |   display: block; | ||||||
|  | } | ||||||
|  | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions { | ||||||
|   grid-area: actions; |   grid-area: actions; | ||||||
|   display: flex; |   display: flex; | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions a { | ||||||
|   display: flex; |   display: flex; | ||||||
|   flex-direction: row; |   flex-direction: row; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a img { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a img, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions a img { | ||||||
|   margin-right: 0.5rem; |   margin-right: 0.5rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons { | ||||||
|   grid-area: buttons; |   grid-area: buttons; | ||||||
|   display: flex; |   display: flex; | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a { | ||||||
|   border-radius: 0.2rem; |   border-radius: 0.2rem; | ||||||
|   cursor: pointer; |   cursor: pointer; | ||||||
|   padding: 0.2rem; |   padding: 0.2rem; | ||||||
| @@ -718,21 +748,27 @@ select, | |||||||
|   display: inline-block; |   display: inline-block; | ||||||
|   align-items: center; |   align-items: center; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a img { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a img, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a img { | ||||||
|   max-width: 1rem; |   max-width: 1rem; | ||||||
|   max-height: 1rem; |   max-height: 1rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:hover { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:hover, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a:hover { | ||||||
|   background: var(--background-custom-button-hover); |   background: var(--background-custom-button-hover); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:active { | .system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:active, | ||||||
|  | .system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a:active { | ||||||
|   position: relative; |   position: relative; | ||||||
|   top: 1px; |   top: 1px; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .window-header { | .system-foundryvtt-reve-de-dragon .window-header { | ||||||
|   background: rgba(0, 0, 0, 0.75); |   background: rgba(0, 0, 0, 0.75); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .application .window-content, | .system-foundryvtt-reve-de-dragon .application .window-content { | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0.2rem; | ||||||
|  | } | ||||||
| .system-foundryvtt-reve-de-dragon .window-app.sheet .window-content { | .system-foundryvtt-reve-de-dragon .window-app.sheet .window-content { | ||||||
|   margin: 0.2rem; |   margin: 0.2rem; | ||||||
|   padding: 0; |   padding: 0; | ||||||
| @@ -823,7 +859,7 @@ select, | |||||||
|   max-width: 1.4rem; |   max-width: 1.4rem; | ||||||
|   max-height: 1.4rem; |   max-height: 1.4rem; | ||||||
|   border: 1px; |   border: 1px; | ||||||
|   background: center / contain no-repeat url('../../assets/ui/icone_parchement_vierge.webp'); |   background: center / contain no-repeat url('../../icons/templates/icone_parchement_vierge.webp'); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .sheet-header .header-compteurs { | .system-foundryvtt-reve-de-dragon .sheet-header .header-compteurs { | ||||||
|   width: calc(60% - 110px - 1rem); |   width: calc(60% - 110px - 1rem); | ||||||
| @@ -899,6 +935,12 @@ select, | |||||||
| .system-foundryvtt-reve-de-dragon a:hover { | .system-foundryvtt-reve-de-dragon a:hover { | ||||||
|   text-shadow: 1px 0px 0px #ff6600; |   text-shadow: 1px 0px 0px #ff6600; | ||||||
| } | } | ||||||
|  | .system-foundryvtt-reve-de-dragon .tabs .item.active img, | ||||||
|  | .system-foundryvtt-reve-de-dragon .blessures-list li ul li:first-child:hover img, | ||||||
|  | .system-foundryvtt-reve-de-dragon i.moral-radio-checkmark-off:hover img, | ||||||
|  | .system-foundryvtt-reve-de-dragon a:hover img { | ||||||
|  |   filter: drop-shadow(1px 0px 0px #ff6600); | ||||||
|  | } | ||||||
| .system-foundryvtt-reve-de-dragon .rollable:hover, | .system-foundryvtt-reve-de-dragon .rollable:hover, | ||||||
| .system-foundryvtt-reve-de-dragon .rollable:focus { | .system-foundryvtt-reve-de-dragon .rollable:focus { | ||||||
|   color: #000; |   color: #000; | ||||||
| @@ -1423,12 +1465,27 @@ select, | |||||||
| .system-foundryvtt-reve-de-dragon .competence-list .item-controls.hidden-controls { | .system-foundryvtt-reve-de-dragon .competence-list .item-controls.hidden-controls { | ||||||
|   display: none !important; |   display: none !important; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .item-actions-controls a.actionItem i:is(.fas, .fa, .fa-solid, .fa-regular), | .system-foundryvtt-reve-de-dragon .item-actions-controls, | ||||||
|  | .system-foundryvtt-reve-de-dragon .item-controls { | ||||||
|  |   vertical-align: super; | ||||||
|  | } | ||||||
|  | .system-foundryvtt-reve-de-dragon .item-actions-controls img, | ||||||
|  | .system-foundryvtt-reve-de-dragon .item-controls img { | ||||||
|  |   display: inline; | ||||||
|  |   max-width: 1rem; | ||||||
|  |   max-height: 1rem; | ||||||
|  |   margin: 0 0.1rem; | ||||||
|  |   border: none; | ||||||
|  |   filter: invert(0.8); | ||||||
|  | } | ||||||
|  | .system-foundryvtt-reve-de-dragon .item-actions-controls i:is(.fas, .fa, .fa-solid, .fa-regular), | ||||||
| .system-foundryvtt-reve-de-dragon .item-controls i:is(.fas, .fa, .fa-solid, .fa-regular) { | .system-foundryvtt-reve-de-dragon .item-controls i:is(.fas, .fa, .fa-solid, .fa-regular) { | ||||||
|   font-size: 0.8em; |   font-size: 0.8em; | ||||||
|   color: var(--color-controls-light); |   color: var(--color-controls-light); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .item-actions-controls a.actionItem i:is(.fas, .fa, .fa-solid, .fa-regular):hover, | .system-foundryvtt-reve-de-dragon .item-actions-controls img:hover, | ||||||
|  | .system-foundryvtt-reve-de-dragon .item-controls img:hover, | ||||||
|  | .system-foundryvtt-reve-de-dragon .item-actions-controls i:is(.fas, .far, .fa-solid, .fa-regular):hover, | ||||||
| .system-foundryvtt-reve-de-dragon .item-controls i:is(.fas, .far, .fa-solid, .fa-regular):hover { | .system-foundryvtt-reve-de-dragon .item-controls i:is(.fas, .far, .fa-solid, .fa-regular):hover { | ||||||
|   opacity: 0.6; |   opacity: 0.6; | ||||||
| } | } | ||||||
| @@ -1444,38 +1501,38 @@ select, | |||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .rdd-roll-part { | .system-foundryvtt-reve-de-dragon .rdd-roll-part { | ||||||
|   align-items: center; |   align-items: center; | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   padding: 3px; |   padding: 3px; | ||||||
|   background: var(--gradient-gold); |   background: var(--gradient-gold); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .rdd-roll-sign { | .system-foundryvtt-reve-de-dragon .rdd-roll-sign { | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   padding: 3px; |   padding: 3px; | ||||||
|   background: var(--gradient-silver); |   background: var(--gradient-silver); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .rdd-roll-norm { | .system-foundryvtt-reve-de-dragon .rdd-roll-norm { | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   padding: 3px; |   padding: 3px; | ||||||
|   background: var(--gradient-green); |   background: var(--gradient-green); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .rdd-roll-notSign, | .system-foundryvtt-reve-de-dragon .rdd-roll-notSign, | ||||||
| .system-foundryvtt-reve-de-dragon .rdd-roll-echec { | .system-foundryvtt-reve-de-dragon .rdd-roll-echec { | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   padding: 3px; |   padding: 3px; | ||||||
|   background: var(--gradient-red); |   background: var(--gradient-red); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .rdd-roll-epart { | .system-foundryvtt-reve-de-dragon .rdd-roll-epart { | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   padding: 3px; |   padding: 3px; | ||||||
|   background: var(--gradient-violet); |   background: var(--gradient-violet); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .rdd-roll-etotal { | .system-foundryvtt-reve-de-dragon .rdd-roll-etotal { | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   padding: 3px; |   padding: 3px; | ||||||
|   background: var(--gradient-purple-black); |   background: var(--gradient-purple-black); | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .rdd-diviseur { | .system-foundryvtt-reve-de-dragon .rdd-diviseur { | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   padding: 3px; |   padding: 3px; | ||||||
|   background: var(--gradient-red); |   background: var(--gradient-red); | ||||||
| } | } | ||||||
| @@ -1502,12 +1559,8 @@ select, | |||||||
|   font-size: 0.8rem; |   font-size: 0.8rem; | ||||||
|   font-style: italic; |   font-style: italic; | ||||||
|   color: rgba(82, 17, 131, 0.9); |   color: rgba(82, 17, 131, 0.9); | ||||||
|   overflow: hidden; |   overflow-y: scroll; | ||||||
| } |   width: 100%; | ||||||
| .system-foundryvtt-reve-de-dragon .poesie-extrait:hover { |  | ||||||
|   max-height: unset; |  | ||||||
|   overflow: visible; |  | ||||||
|   opacity: 1; |  | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .poesie-reference { | .system-foundryvtt-reve-de-dragon .poesie-reference { | ||||||
|   font-size: 0.7rem; |   font-size: 0.7rem; | ||||||
| @@ -1516,6 +1569,12 @@ select, | |||||||
| .system-foundryvtt-reve-de-dragon .type-compendium { | .system-foundryvtt-reve-de-dragon .type-compendium { | ||||||
|   font-size: 0.6rem; |   font-size: 0.6rem; | ||||||
| } | } | ||||||
|  | .system-foundryvtt-reve-de-dragon .sheet.journal-entry .journal-sidebar { | ||||||
|  |   color: var(--color-text-dark-primary); | ||||||
|  | } | ||||||
|  | .system-foundryvtt-reve-de-dragon .sheet.journal-entry .journal-sidebar button { | ||||||
|  |   color: var(--color-text-dark-primary); | ||||||
|  | } | ||||||
| .system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .sheet-header { | .system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .sheet-header { | ||||||
|   background: #011d33 url(../assets/ui/bg_header.webp) no-repeat left top; |   background: #011d33 url(../assets/ui/bg_header.webp) no-repeat left top; | ||||||
|   color: #ffffff; |   color: #ffffff; | ||||||
| @@ -1573,7 +1632,10 @@ select, | |||||||
|   height: var(--form-field-height); |   height: var(--form-field-height); | ||||||
|   margin: 0; |   margin: 0; | ||||||
|   color: var(--color-text-dark-primary); |   color: var(--color-text-dark-primary); | ||||||
|   border-radius: 3px; |   border-radius: 0.2rem; | ||||||
|  | } | ||||||
|  | .system-foundryvtt-reve-de-dragon form.app-personnage-aleatoire h2 { | ||||||
|  |   min-width: 30rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .app-calendar-astrologie div.theme-astral { | .system-foundryvtt-reve-de-dragon .app-calendar-astrologie div.theme-astral { | ||||||
|   width: 14rem; |   width: 14rem; | ||||||
| @@ -1595,8 +1657,9 @@ select, | |||||||
|   height: 2rem; |   height: 2rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .window-app .window-content, | .system-foundryvtt-reve-de-dragon .window-app .window-content, | ||||||
| .system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .sheet-body { | .system-foundryvtt-reve-de-dragon .window-app.sheet .window-content .sheet-body, | ||||||
|   background: #f5f5f0 url(../assets/ui/bg_left.webp) no-repeat left top; | .system-foundryvtt-reve-de-dragon .application .window-content { | ||||||
|  |   background: url(../assets/ui/bg_left.webp) no-repeat left top; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon section.sheet-body { | .system-foundryvtt-reve-de-dragon section.sheet-body { | ||||||
|   padding: 0.25rem 0.5rem; |   padding: 0.25rem 0.5rem; | ||||||
| @@ -1624,7 +1687,7 @@ select, | |||||||
|   background: hsla(280, 50%, 50%, 0.1); |   background: hsla(280, 50%, 50%, 0.1); | ||||||
|   padding: 1px 4px; |   padding: 1px 4px; | ||||||
|   border: 1px solid var(--color-border-dark-tertiary); |   border: 1px solid var(--color-border-dark-tertiary); | ||||||
|   border-radius: 2px; |   border-radius: 0.2rem; | ||||||
|   white-space: nowrap; |   white-space: nowrap; | ||||||
|   word-break: break-all; |   word-break: break-all; | ||||||
| } | } | ||||||
| @@ -1634,7 +1697,7 @@ select, | |||||||
|   font-weight: 560; |   font-weight: 560; | ||||||
|   padding: 0.1rem 0.3rem; |   padding: 0.1rem 0.3rem; | ||||||
|   border: 1px solid var(--color-border-dark-tertiary); |   border: 1px solid var(--color-border-dark-tertiary); | ||||||
|   border-radius: 0.25rem; |   border-radius: 0.2rem; | ||||||
|   white-space: nowrap; |   white-space: nowrap; | ||||||
|   word-break: break-all; |   word-break: break-all; | ||||||
|   display: ruby; |   display: ruby; | ||||||
| @@ -1754,7 +1817,7 @@ select, | |||||||
| .system-foundryvtt-reve-de-dragon .xp-level-up { | .system-foundryvtt-reve-de-dragon .xp-level-up { | ||||||
|   margin: 0.1rem; |   margin: 0.1rem; | ||||||
|   box-shadow: inset 0px 0px 1px #00000096; |   box-shadow: inset 0px 0px 1px #00000096; | ||||||
|   border-radius: 0.25rem; |   border-radius: 0.2rem; | ||||||
|   padding: 0.1rem; |   padding: 0.1rem; | ||||||
|   flex: 1 1 5rem; |   flex: 1 1 5rem; | ||||||
|   background: var(--gradient-gold) !important; |   background: var(--gradient-gold) !important; | ||||||
| @@ -1785,7 +1848,7 @@ select, | |||||||
| .system-foundryvtt-reve-de-dragon .list-item { | .system-foundryvtt-reve-de-dragon .list-item { | ||||||
|   margin: 0.1rem; |   margin: 0.1rem; | ||||||
|   box-shadow: inset 0px 0px 1px #00000096; |   box-shadow: inset 0px 0px 1px #00000096; | ||||||
|   border-radius: 0.25rem; |   border-radius: 0.2rem; | ||||||
|   padding: 0.1rem; |   padding: 0.1rem; | ||||||
|   flex: 1 1 1.5rem; |   flex: 1 1 1.5rem; | ||||||
|   display: flex; |   display: flex; | ||||||
| @@ -1954,13 +2017,13 @@ select, | |||||||
|   justify-content: flex-start; |   justify-content: flex-start; | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
|   position: absolute; |   position: absolute; | ||||||
|   top: 4.6rem; |   top: 10rem; | ||||||
|   left: -19rem; |   left: -9rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .token-hud-ext.soins { | .system-foundryvtt-reve-de-dragon .token-hud-ext.soins { | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
|   position: absolute; |   position: absolute; | ||||||
|   top: 14.7rem; |   top: 15.5rem; | ||||||
|   left: -6rem; |   left: -6rem; | ||||||
|   max-width: 8rem; |   max-width: 8rem; | ||||||
|   line-height: 1rem; |   line-height: 1rem; | ||||||
| @@ -1975,14 +2038,18 @@ select, | |||||||
|   width: 9rem; |   width: 9rem; | ||||||
|   height: fit-content; |   height: fit-content; | ||||||
|   border-radius: 0.3rem; |   border-radius: 0.3rem; | ||||||
|   min-width: 6rem; |   min-width: 8rem; | ||||||
|   flex-basis: auto; |   flex-basis: auto; | ||||||
|   padding: 0; |   padding: 0; | ||||||
|   line-height: 0.95rem; |   line-height: 1.6rem; | ||||||
|   margin: 0.2rem; |   margin: 0.2rem; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: row; | ||||||
|  |   align-items: center; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .rdd-hud-menu label { | .system-foundryvtt-reve-de-dragon div.control-icon.token-hud-icon select, | ||||||
|   font-size: 0.8rem; | .system-foundryvtt-reve-de-dragon div.control-icon.token-hud-icon label { | ||||||
|  |   font-size: 1rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .item-checkbox { | .system-foundryvtt-reve-de-dragon .item-checkbox { | ||||||
|   height: 25px; |   height: 25px; | ||||||
| @@ -2094,6 +2161,9 @@ select, | |||||||
|   font-size: 0.7rem; |   font-size: 0.7rem; | ||||||
|   flex-grow: 3; |   flex-grow: 3; | ||||||
| } | } | ||||||
|  | .system-foundryvtt-reve-de-dragon .chat-message header.message-header .message-metadata { | ||||||
|  |   flex-grow: 3.5; | ||||||
|  | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-message hr { | .system-foundryvtt-reve-de-dragon .chat-message hr { | ||||||
|   margin: 0.2rem 0; |   margin: 0.2rem 0; | ||||||
| } | } | ||||||
| @@ -2264,7 +2334,7 @@ select, | |||||||
|   pointer-events: all; |   pointer-events: all; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon div.horloge-roue div.horloge-cercle { | .system-foundryvtt-reve-de-dragon div.horloge-roue div.horloge-cercle { | ||||||
|   background: hsl(60, 20%, 95%) url(../assets/ui/bg_left.webp) no-repeat left top; |   background: hsla(60, 20%, 90%, 0.8); | ||||||
|   top: 2%; |   top: 2%; | ||||||
|   left: 2%; |   left: 2%; | ||||||
|   width: 96%; |   width: 96%; | ||||||
| @@ -2314,7 +2384,7 @@ select, | |||||||
|   font-size: 0.8rem; |   font-size: 0.8rem; | ||||||
|   text-align: center; |   text-align: center; | ||||||
|   vertical-align: middle; |   vertical-align: middle; | ||||||
|   border-radius: 0.3rem; |   border-radius: 0.2rem; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon div.horloge-roue div img { | .system-foundryvtt-reve-de-dragon div.horloge-roue div img { | ||||||
|   border: none; |   border: none; | ||||||
| @@ -2641,13 +2711,20 @@ select, | |||||||
| .system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements { | .system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements { | ||||||
|   width: 10rem; |   width: 10rem; | ||||||
|   background: var(--background-tooltip); |   background: var(--background-tooltip); | ||||||
|   border-radius: 6px; |   border-radius: 0.5rem; | ||||||
|   font-size: 0.9rem; |   font-size: 0.9rem; | ||||||
|   padding: 3px 0; |   padding: 3px 0; | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements div:nth-child(odd) { | .system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements div:nth-child(odd) { | ||||||
|   background: var(--background-tooltip-alt); |   background: var(--background-tooltip-alt); | ||||||
| } | } | ||||||
|  | .system-foundryvtt-reve-de-dragon :is(.tooltip, .tooltip-overflow) .ttt-ajustements div img { | ||||||
|  |   display: inline; | ||||||
|  |   margin: 0; | ||||||
|  |   max-width: 1rem; | ||||||
|  |   max-height: 1rem; | ||||||
|  |   filter: invert(0.8); | ||||||
|  | } | ||||||
| .system-foundryvtt-reve-de-dragon aside#tooltip { | .system-foundryvtt-reve-de-dragon aside#tooltip { | ||||||
|   max-width: 15rem; |   max-width: 15rem; | ||||||
|   background: var(--background-tooltip); |   background: var(--background-tooltip); | ||||||
| @@ -2709,11 +2786,9 @@ select, | |||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-card-button:hover { | .system-foundryvtt-reve-de-dragon .chat-card-button:hover { | ||||||
|   background: var(--background-custom-button-hover); |   background: var(--background-custom-button-hover); | ||||||
|   background-color: red; |  | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-card-button-pushed:hover { | .system-foundryvtt-reve-de-dragon .chat-card-button-pushed:hover { | ||||||
|   background: var(--background-custom-button-hover); |   background: var(--background-custom-button-hover); | ||||||
|   background-color: red; |  | ||||||
| } | } | ||||||
| .system-foundryvtt-reve-de-dragon .chat-card-button:active, | .system-foundryvtt-reve-de-dragon .chat-card-button:active, | ||||||
| .system-foundryvtt-reve-de-dragon .chat-card-button-pushed:active { | .system-foundryvtt-reve-de-dragon .chat-card-button-pushed:active { | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								icons/cuisine/gibier.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.8 KiB | 
							
								
								
									
										1
									
								
								icons/cuisine/herbe.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 5.6 KiB | 
							
								
								
									
										1
									
								
								icons/cuisine/mortadelle.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 8.6 KiB | 
							
								
								
									
										1
									
								
								icons/cuisine/plante.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.8 KiB | 
							
								
								
									
										1
									
								
								icons/cuisine/ragout.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.3 KiB | 
							
								
								
									
										1
									
								
								icons/cuisine/saucisson.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 8.2 KiB | 
							
								
								
									
										1
									
								
								icons/cuisine/volaille.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 10 KiB | 
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "TYPES": { |   "TYPES": { | ||||||
|     "Actor": {  |     "Actor": { | ||||||
|       "personnage": "Personnage", |       "personnage": "Personnage", | ||||||
|       "creature": "Créature", |       "creature": "Créature", | ||||||
|       "entite": "Entité de cauchemar", |       "entite": "Entité de cauchemar", | ||||||
| @@ -67,6 +67,7 @@ | |||||||
|     "StatusComma": "Comma", |     "StatusComma": "Comma", | ||||||
|     "StatusDead": "Mort", |     "StatusDead": "Mort", | ||||||
|     "StatusDemiReve": "Demi-rêve", |     "StatusDemiReve": "Demi-rêve", | ||||||
|  |     "StatusSurEnc": "Sur-encombrement", | ||||||
|     "StatusForceWeak": "Force insuffisante" |     "StatusForceWeak": "Force insuffisante" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -27,6 +27,11 @@ | |||||||
|     --gradient-red: linear-gradient(150deg, rgba(255, 0, 0, 0.3), rgba(255, 200, 128, 0.05),rgba(255, 200, 128, 0.1), rgba(255,10,0,0.3)); |     --gradient-red: linear-gradient(150deg, rgba(255, 0, 0, 0.3), rgba(255, 200, 128, 0.05),rgba(255, 200, 128, 0.1), rgba(255,10,0,0.3)); | ||||||
|     --gradient-violet: linear-gradient(150deg, rgba(100, 45, 124, 0.6), rgba(216, 157, 192, 0.3), rgba(177, 157, 216, 0.5), rgba(107, 62, 121, 0.3), rgba(100, 45, 124, 0.6)); |     --gradient-violet: linear-gradient(150deg, rgba(100, 45, 124, 0.6), rgba(216, 157, 192, 0.3), rgba(177, 157, 216, 0.5), rgba(107, 62, 121, 0.3), rgba(100, 45, 124, 0.6)); | ||||||
|     --gradient-purple-black: linear-gradient(150deg,  rgba(0, 0, 0, 0.7), rgba(100, 45, 124, 0.4), rgba(82, 17, 131, 0.3),rgba(100, 45, 124, 0.4), rgba(0, 0, 0, 0.7)); |     --gradient-purple-black: linear-gradient(150deg,  rgba(0, 0, 0, 0.7), rgba(100, 45, 124, 0.4), rgba(82, 17, 131, 0.3),rgba(100, 45, 124, 0.4), rgba(0, 0, 0, 0.7)); | ||||||
|  |     --gradient-warning: linear-gradient(150deg, | ||||||
|  |       hsla(32, 100%, 50%, 0.3), | ||||||
|  |       hsla(52, 60%, 50%, 0.1), | ||||||
|  |       hsla(32, 60%, 50%, 0.1), | ||||||
|  |       hsla(32, 100%, 50%, 0.3)); | ||||||
|     --gradient-silver-light: linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2)); |     --gradient-silver-light: linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2)); | ||||||
|     --gradient-daylight: conic-gradient( |     --gradient-daylight: conic-gradient( | ||||||
|       from 0deg, |       from 0deg, | ||||||
|   | |||||||
| @@ -12,7 +12,10 @@ | |||||||
|     background: rgba(0,0,0,0.75); |     background: rgba(0,0,0,0.75); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .application .window-content, |   .application .window-content { | ||||||
|  |     margin: 0; | ||||||
|  |     padding: 0.2rem; | ||||||
|  |   } | ||||||
|   .window-app.sheet .window-content { |   .window-app.sheet .window-content { | ||||||
|     margin: 0.2rem; |     margin: 0.2rem; | ||||||
|     padding: 0; |     padding: 0; | ||||||
| @@ -115,7 +118,7 @@ | |||||||
|     max-width: 1.4rem; |     max-width: 1.4rem; | ||||||
|     max-height: 1.4rem; |     max-height: 1.4rem; | ||||||
|     border: 1px; |     border: 1px; | ||||||
|     background: center / contain no-repeat url('../../assets/ui/icone_parchement_vierge.webp'); |     background: center / contain no-repeat url('../../icons/templates/icone_parchement_vierge.webp'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .sheet-header .header-compteurs { |   .sheet-header .header-compteurs { | ||||||
| @@ -200,6 +203,9 @@ | |||||||
|   i.moral-radio-checkmark-off:hover, |   i.moral-radio-checkmark-off:hover, | ||||||
|   a:hover { |   a:hover { | ||||||
|     text-shadow: 1px 0px 0px #ff6600; |     text-shadow: 1px 0px 0px #ff6600; | ||||||
|  |     img { | ||||||
|  |       filter: drop-shadow(1px 0px 0px #ff6600); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .rollable:hover, .rollable:focus { |   .rollable:hover, .rollable:focus { | ||||||
| @@ -741,11 +747,11 @@ | |||||||
|   .foundryvtt-reve-de-dragon .item-list .item img { |   .foundryvtt-reve-de-dragon .item-list .item img { | ||||||
|     display: inline; |     display: inline; | ||||||
|   } |   } | ||||||
|  |    | ||||||
|   .foundryvtt-reve-de-dragon .item-list .item-name { |   .foundryvtt-reve-de-dragon .item-list .item-name { | ||||||
|     margin: 0; |     margin: 0; | ||||||
|   } |   } | ||||||
|  |    | ||||||
|   .competence-list .item-controls, |   .competence-list .item-controls, | ||||||
|   .competence-list .item-actions-controls { |   .competence-list .item-actions-controls { | ||||||
|     display: contents !important; |     display: contents !important; | ||||||
| @@ -754,15 +760,30 @@ | |||||||
|   .competence-list .item-controls.hidden-controls { |   .competence-list .item-controls.hidden-controls { | ||||||
|     display: none !important; |     display: none !important; | ||||||
|   } |   } | ||||||
|  |   .item-actions-controls, | ||||||
|  |   .item-controls { | ||||||
|  |     vertical-align: super; | ||||||
|  |     // a { | ||||||
|  |     // } | ||||||
|  |  | ||||||
|   .item-actions-controls a.actionItem i:is(.fas, .fa, .fa-solid, .fa-regular), |     img { | ||||||
|   .item-controls i:is(.fas, .fa, .fa-solid, .fa-regular) { |         display: inline; | ||||||
|     font-size: 0.8em; |         max-width: 1rem; | ||||||
|     color: var(--color-controls-light); |         max-height: 1rem; | ||||||
|   } |         margin: 0 0.1rem; | ||||||
|   .item-actions-controls a.actionItem i:is(.fas, .fa, .fa-solid, .fa-regular):hover, |         border: none; | ||||||
|   .item-controls i:is(.fas, .far, .fa-solid, .fa-regular):hover { |         filter: invert(0.8); | ||||||
|     opacity: 0.6; |     } | ||||||
|  |      | ||||||
|  |     i:is(.fas, .fa, .fa-solid, .fa-regular) { | ||||||
|  |       font-size: 0.8em; | ||||||
|  |       color: var(--color-controls-light); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     img:hover, | ||||||
|  |     i:is(.fas, .far, .fa-solid, .fa-regular):hover { | ||||||
|  |       opacity: 0.6; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .rdd-roll-dialog .description-sort { |   .rdd-roll-dialog .description-sort { | ||||||
| @@ -777,31 +798,31 @@ | |||||||
|   } |   } | ||||||
|   .rdd-roll-part { |   .rdd-roll-part { | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     border-radius: 6px; padding: 3px; |     border-radius: 0.5rem; padding: 3px; | ||||||
|     background: var(--gradient-gold); |     background: var(--gradient-gold); | ||||||
|   } |   } | ||||||
|   .rdd-roll-sign{ |   .rdd-roll-sign{ | ||||||
|     border-radius: 6px; padding: 3px; |     border-radius: 0.5rem; padding: 3px; | ||||||
|     background: var(--gradient-silver); |     background: var(--gradient-silver); | ||||||
|   } |   } | ||||||
|   .rdd-roll-norm{ |   .rdd-roll-norm{ | ||||||
|     border-radius: 6px; padding: 3px; |     border-radius: 0.5rem; padding: 3px; | ||||||
|     background: var(--gradient-green); |     background: var(--gradient-green); | ||||||
|   } |   } | ||||||
|   .rdd-roll-notSign, .rdd-roll-echec{ |   .rdd-roll-notSign, .rdd-roll-echec{ | ||||||
|     border-radius: 6px; padding: 3px; |     border-radius: 0.5rem; padding: 3px; | ||||||
|     background: var(--gradient-red); |     background: var(--gradient-red); | ||||||
|   } |   } | ||||||
|   .rdd-roll-epart{ |   .rdd-roll-epart{ | ||||||
|     border-radius: 6px; padding: 3px; |     border-radius: 0.5rem; padding: 3px; | ||||||
|     background: var(--gradient-violet); |     background: var(--gradient-violet); | ||||||
|   } |   } | ||||||
|   .rdd-roll-etotal{ |   .rdd-roll-etotal{ | ||||||
|     border-radius: 6px; padding: 3px; |     border-radius: 0.5rem; padding: 3px; | ||||||
|     background: var(--gradient-purple-black); |     background: var(--gradient-purple-black); | ||||||
|   } |   } | ||||||
|   .rdd-diviseur{ |   .rdd-diviseur{ | ||||||
|     border-radius: 6px; padding: 3px; |     border-radius: 0.5rem; padding: 3px; | ||||||
|     background: var(--gradient-red); |     background: var(--gradient-red); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -832,15 +853,10 @@ | |||||||
|     font-size: 0.8rem; |     font-size: 0.8rem; | ||||||
|     font-style: italic; |     font-style: italic; | ||||||
|     color: rgba(82, 17, 131, 0.9); |     color: rgba(82, 17, 131, 0.9); | ||||||
|     overflow: hidden; |     overflow-y: scroll; | ||||||
|  |     width: 100%; | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   .poesie-extrait:hover { |  | ||||||
|     max-height: unset; |  | ||||||
|     overflow: visible; |  | ||||||
|     opacity: 1; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .poesie-reference { |   .poesie-reference { | ||||||
|     font-size: 0.7rem; |     font-size: 0.7rem; | ||||||
|     text-align: right; |     text-align: right; | ||||||
| @@ -849,6 +865,12 @@ | |||||||
|   .type-compendium { |   .type-compendium { | ||||||
|     font-size: 0.6rem; |     font-size: 0.6rem; | ||||||
|   } |   } | ||||||
|  |   .sheet.journal-entry .journal-sidebar { | ||||||
|  |     color: var(--color-text-dark-primary); | ||||||
|  |     button { | ||||||
|  |       color: var(--color-text-dark-primary); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* ======================================== */ |   /* ======================================== */ | ||||||
|   /* Sheet  */ |   /* Sheet  */ | ||||||
| @@ -913,7 +935,12 @@ | |||||||
|     height: var(--form-field-height); |     height: var(--form-field-height); | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     color: var(--color-text-dark-primary); |     color: var(--color-text-dark-primary); | ||||||
|     border-radius: 3px; |     border-radius: 0.2rem; | ||||||
|  |   } | ||||||
|  |   form.app-personnage-aleatoire { | ||||||
|  |     h2 { | ||||||
|  |       min-width: 30rem, | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|   .app-calendar-astrologie{ |   .app-calendar-astrologie{ | ||||||
|     div.theme-astral{ |     div.theme-astral{ | ||||||
| @@ -937,8 +964,10 @@ | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .window-app .window-content, .window-app.sheet .window-content .sheet-body{ |   .window-app .window-content, | ||||||
|     background: rgb(245,245,240) url(../assets/ui/bg_left.webp) no-repeat left top; |   .window-app.sheet .window-content .sheet-body, | ||||||
|  |   .application .window-content { | ||||||
|  |     background: url(../assets/ui/bg_left.webp) no-repeat left top; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   section.sheet-body { |   section.sheet-body { | ||||||
| @@ -970,7 +999,7 @@ | |||||||
|     background: hsla(280, 50%, 50%, 0.1); |     background: hsla(280, 50%, 50%, 0.1); | ||||||
|     padding: 1px 4px; |     padding: 1px 4px; | ||||||
|     border: 1px solid var(--color-border-dark-tertiary); |     border: 1px solid var(--color-border-dark-tertiary); | ||||||
|     border-radius: 2px; |     border-radius: 0.2rem; | ||||||
|     white-space: nowrap; |     white-space: nowrap; | ||||||
|     word-break: break-all; |     word-break: break-all; | ||||||
|   } |   } | ||||||
| @@ -981,7 +1010,7 @@ | |||||||
|     font-weight: 560; |     font-weight: 560; | ||||||
|     padding: 0.1rem 0.3rem; |     padding: 0.1rem 0.3rem; | ||||||
|     border: 1px solid var(--color-border-dark-tertiary); |     border: 1px solid var(--color-border-dark-tertiary); | ||||||
|     border-radius: 0.25rem; |     border-radius: 0.2rem; | ||||||
|     white-space: nowrap; |     white-space: nowrap; | ||||||
|     word-break: break-all; |     word-break: break-all; | ||||||
|     display: ruby; |     display: ruby; | ||||||
| @@ -1111,7 +1140,7 @@ | |||||||
|   .xp-level-up { |   .xp-level-up { | ||||||
|     margin: 0.1rem; |     margin: 0.1rem; | ||||||
|     box-shadow: inset 0px 0px 1px #00000096; |     box-shadow: inset 0px 0px 1px #00000096; | ||||||
|     border-radius: 0.25rem; |     border-radius: 0.2rem; | ||||||
|     padding: 0.1rem; |     padding: 0.1rem; | ||||||
|     flex: 1 1 5rem; |     flex: 1 1 5rem; | ||||||
|     background: var(--gradient-gold) !important; |     background: var(--gradient-gold) !important; | ||||||
| @@ -1142,7 +1171,7 @@ | |||||||
|   .list-item { |   .list-item { | ||||||
|     margin: 0.1rem; |     margin: 0.1rem; | ||||||
|     box-shadow: inset 0px 0px 1px #00000096; |     box-shadow: inset 0px 0px 1px #00000096; | ||||||
|     border-radius: 0.25rem; |     border-radius: 0.2rem; | ||||||
|     padding: 0.1rem; |     padding: 0.1rem; | ||||||
|     flex: 1 1 1.5rem; |     flex: 1 1 1.5rem; | ||||||
|     display: flex; |     display: flex; | ||||||
| @@ -1319,13 +1348,13 @@ | |||||||
|     justify-content: flex-start; |     justify-content: flex-start; | ||||||
|     flex-direction: column; |     flex-direction: column; | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     top: 4.6rem; |     top: 10rem; | ||||||
|     left: -19rem; |     left: -9rem; | ||||||
|   } |   } | ||||||
|   .token-hud-ext.soins { |   .token-hud-ext.soins { | ||||||
|     flex-direction: column; |     flex-direction: column; | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     top: 14.7rem; |     top: 15.5rem; | ||||||
|     left: -6rem; |     left: -6rem; | ||||||
|     max-width: 8rem; |     max-width: 8rem; | ||||||
|     line-height: 1rem; |     line-height: 1rem; | ||||||
| @@ -1341,14 +1370,18 @@ | |||||||
|     width: 9rem; |     width: 9rem; | ||||||
|     height: fit-content; |     height: fit-content; | ||||||
|     border-radius: 0.3rem; |     border-radius: 0.3rem; | ||||||
|     min-width: 6rem; |     min-width: 8rem; | ||||||
|     flex-basis: auto; |     flex-basis: auto; | ||||||
|     padding: 0; |     padding: 0; | ||||||
|     line-height: 0.95rem; |     line-height: 1.6rem; | ||||||
|     margin: 0.2rem; |     margin: 0.2rem; | ||||||
|   } |  | ||||||
|   .rdd-hud-menu label { |     display: flex; | ||||||
|     font-size: 0.8rem; |     flex-direction: row; | ||||||
|  |     align-items: center; | ||||||
|  |     select, label { | ||||||
|  |       font-size: 1rem; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|   /* ======================================== */ |   /* ======================================== */ | ||||||
|   .item-checkbox { |   .item-checkbox { | ||||||
| @@ -1479,10 +1512,15 @@ | |||||||
|     .message-content { |     .message-content { | ||||||
|       text-align: justify; |       text-align: justify; | ||||||
|     } |     } | ||||||
|     header.message-header .heure-rdd { |     header.message-header{ | ||||||
|       font-size: 0.7rem; |       .heure-rdd { | ||||||
|       flex-grow: 3; |         font-size: 0.7rem; | ||||||
|     } |         flex-grow: 3; | ||||||
|  |       } | ||||||
|  |      .message-metadata { | ||||||
|  |         flex-grow: 3.5; | ||||||
|  |      } | ||||||
|  |     }  | ||||||
|     hr { |     hr { | ||||||
|       margin: 0.2rem 0; |       margin: 0.2rem 0; | ||||||
|     } |     } | ||||||
| @@ -1650,7 +1688,7 @@ | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   div.horloge-roue div.horloge-cercle { |   div.horloge-roue div.horloge-cercle { | ||||||
|     background: hsl(60, 20%, 95%) url(../assets/ui/bg_left.webp) no-repeat left top; |     background: hsla(60, 20%, 90%, 0.8); | ||||||
|     top: 2%; left: 2%; width: 96%; height: 96%; border-radius: 50%; |     top: 2%; left: 2%; width: 96%; height: 96%; border-radius: 50%; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1681,7 +1719,7 @@ | |||||||
|     font-size: 0.8rem; |     font-size: 0.8rem; | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     vertical-align: middle; |     vertical-align: middle; | ||||||
|     border-radius: 0.3rem; |     border-radius: 0.2rem; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   div.horloge-roue div img { |   div.horloge-roue div img { | ||||||
| @@ -1917,12 +1955,19 @@ | |||||||
|     .ttt-ajustements { |     .ttt-ajustements { | ||||||
|       width: 10rem; |       width: 10rem; | ||||||
|       background: var(--background-tooltip); |       background: var(--background-tooltip); | ||||||
|       border-radius: 6px; |       border-radius: 0.5rem; | ||||||
|       font-size: 0.9rem; |       font-size: 0.9rem; | ||||||
|       padding: 3px 0; |       padding: 3px 0; | ||||||
|       div:nth-child(odd) { |       div:nth-child(odd) { | ||||||
|         background: var(--background-tooltip-alt); |         background: var(--background-tooltip-alt); | ||||||
|       } |       } | ||||||
|  |       div img { | ||||||
|  |         display: inline; | ||||||
|  |         margin: 0; | ||||||
|  |         max-width: 1rem; | ||||||
|  |         max-height: 1rem; | ||||||
|  |         filter: invert(0.8); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1994,12 +2039,10 @@ | |||||||
|  |  | ||||||
|   .chat-card-button:hover { |   .chat-card-button:hover { | ||||||
|     background: var(--background-custom-button-hover); |     background: var(--background-custom-button-hover); | ||||||
|     background-color: red; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .chat-card-button-pushed:hover { |   .chat-card-button-pushed:hover { | ||||||
|     background: var(--background-custom-button-hover); |     background: var(--background-custom-button-hover); | ||||||
|     background-color: red; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .chat-card-button:active, .chat-card-button-pushed:active { |   .chat-card-button:active, .chat-card-button-pushed:active { | ||||||
|   | |||||||
| @@ -1,87 +1,89 @@ | |||||||
| .chat-message { | .chat-message div.roll-chat, | ||||||
|   div.roll-chat { | .dialog-content div.roll-chat { | ||||||
|     font-family: CaslonAntique; |   font-family: CaslonAntique; | ||||||
|     display: grid; |   display: grid; | ||||||
|     grid-template-areas: |   grid-template-areas: | ||||||
|       "img     header  buttons" |     "img     header  buttons" | ||||||
|       "img     resume  buttons" |     "img     resume  buttons" | ||||||
|       "details details details" |     "details details details" | ||||||
|       "actions actions actions"; |     "actions actions actions"; | ||||||
|     grid-template-columns: 3rem 1fr 1.4rem; |   grid-template-columns: 3rem 1fr 1.4rem; | ||||||
|     grid-template-rows: max-content max-content max-content max-content; |   grid-template-rows: max-content max-content max-content max-content; | ||||||
|     gap: 0 0.5rem; |   gap: 0 0.5rem; | ||||||
|  |  | ||||||
|     div.chat-img { |   div.chat-img { | ||||||
|       grid-area: img; |     grid-area: img; | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |     img { | ||||||
|  |       border: 0; | ||||||
|  |       max-height: 3rem; | ||||||
|  |       max-width: 3rem; | ||||||
|  |       object-fit: contain; | ||||||
|  |       height: 100%; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   div.chat-header { | ||||||
|  |     grid-area: header; | ||||||
|  |     font-weight: bold; | ||||||
|  |     font-size: 0.9rem; | ||||||
|  |   } | ||||||
|  |   div.chat-resume { | ||||||
|  |     grid-area: resume; | ||||||
|  |     text-align: justify; | ||||||
|  |   } | ||||||
|  |   div.chat-details { | ||||||
|  |     grid-area: details; | ||||||
|  |     text-align: justify; | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |     div { | ||||||
|  |       display: block; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   div.chat-actions { | ||||||
|  |     grid-area: actions; | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |     a { | ||||||
|       display: flex; |       display: flex; | ||||||
|       flex-direction: column; |       flex-direction: row; | ||||||
|       img { |       img { | ||||||
|         border: 0; |         margin-right: 0.5rem; | ||||||
|         max-height: 3rem; |  | ||||||
|         max-width: 3rem; |  | ||||||
|         object-fit: contain; |  | ||||||
|         height: 100%; |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     div.chat-header { |   } | ||||||
|       grid-area: header; |    | ||||||
|       font-weight: bold; |   div.chat-buttons { | ||||||
|       font-size: 0.9rem; |     grid-area: buttons; | ||||||
|     } |     display: flex; | ||||||
|     div.chat-resume { |     flex-direction: column; | ||||||
|       grid-area: resume; |  | ||||||
|       text-align: justify; |     a { | ||||||
|     } |       border-radius: 0.2rem; | ||||||
|     div.chat-details { |       cursor: pointer; | ||||||
|       grid-area: details; |       padding: 0.2rem; | ||||||
|       text-align: justify; |       position: relative; | ||||||
|       display: flex; |       box-shadow: inset 1x 1px #a6827e; | ||||||
|       flex-direction: column; |       color: var(--color-controls); | ||||||
|     } |       border: 1px ridge #846109; | ||||||
|     div.chat-actions { |       display: inline-block; | ||||||
|       grid-area: actions; |       align-items: center; | ||||||
|       display: flex; |        | ||||||
|       flex-direction: column; |       img { | ||||||
|       a { |         max-width: 1rem; | ||||||
|         display: flex; |         max-height: 1rem; | ||||||
|         flex-direction: row; |  | ||||||
|         img { |  | ||||||
|           margin-right: 0.5rem; |  | ||||||
|         } |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     div.chat-buttons { |     a:hover { | ||||||
|       grid-area: buttons; |       background: var(--background-custom-button-hover); | ||||||
|       display: flex; |  | ||||||
|       flex-direction: column; |  | ||||||
|  |  | ||||||
|       a { |  | ||||||
|         border-radius: 0.2rem; |  | ||||||
|         cursor: pointer; |  | ||||||
|         padding: 0.2rem; |  | ||||||
|         position: relative; |  | ||||||
|         box-shadow: inset 1x 1px #a6827e; |  | ||||||
|         color: var(--color-controls); |  | ||||||
|         border: 1px ridge #846109; |  | ||||||
|         display: inline-block; |  | ||||||
|         align-items: center; |  | ||||||
|          |  | ||||||
|         img { |  | ||||||
|           max-width: 1rem; |  | ||||||
|           max-height: 1rem; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|        |  | ||||||
|       a:hover { |  | ||||||
|         background: var(--background-custom-button-hover); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       a:active{ |  | ||||||
|         position:relative; |  | ||||||
|         top:1px; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     a:active{ | ||||||
|  |       position:relative; | ||||||
|  |       top:1px; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -89,8 +89,12 @@ | |||||||
|       display: flex; |       display: flex; | ||||||
|       flex-direction: row; |       flex-direction: row; | ||||||
|       margin: 0.1rem 0; |       margin: 0.1rem 0; | ||||||
|  |       .warning { | ||||||
|  |         border-radius: 0.5rem; | ||||||
|  |         background: var(--gradient-warning); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|    |  | ||||||
|     roll-part-img { |     roll-part-img { | ||||||
|       display: flex; |       display: flex; | ||||||
|       flex-direction: column; |       flex-direction: column; | ||||||
| @@ -117,6 +121,7 @@ | |||||||
|         div.poesie-extrait{ |         div.poesie-extrait{ | ||||||
|           display: flex; |           display: flex; | ||||||
|           flex-direction: column; |           flex-direction: column; | ||||||
|  |           align-items: normal; | ||||||
|         } |         } | ||||||
|         span.status-surprise{ |         span.status-surprise{ | ||||||
|           display: flex; |           display: flex; | ||||||
| @@ -137,8 +142,13 @@ | |||||||
|     display: flow; |     display: flow; | ||||||
|     width: 2.5rem; |     width: 2.5rem; | ||||||
|     text-align: right; |     text-align: right; | ||||||
|     margin: 0 0.2rem 0 0.5rem; |     margin: 0 0.2rem; | ||||||
|     padding: 0 0.2rem; |     padding: 0 0.2rem; | ||||||
|  |     border: 1px solid ; | ||||||
|  |     border-radius: 0.2rem ; | ||||||
|  |     background: hsla(0, 0%, 0%, 0.2); | ||||||
|  |     height: 1.5rem; | ||||||
|  |     background: hsla(0, 0%, 0%, 0.2); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   roll-action { |   roll-action { | ||||||
| @@ -201,28 +211,32 @@ | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   roll-carac select[name="select-carac"] { |   roll-carac select[name="select-carac"] { | ||||||
|     max-width: 6rem; |     min-width: 6.5rem; | ||||||
|  |     max-width: 8rem; | ||||||
|   }     |   } | ||||||
|   roll-comp select[name="select-comp"] { |   roll-comp select[name="select-comp"] { | ||||||
|     min-width: 8rem; |     min-width: 8rem; | ||||||
|     max-width: 11rem; |     max-width: 10rem; | ||||||
|     margin-left: 1rem; |     margin-left: 1.5rem; | ||||||
|   }      |   } | ||||||
|  |  | ||||||
|   roll-conditions roll-section[name="coeur"] select[name="coeur"]  { |   roll-conditions roll-section[name="coeur"] select[name="coeur"]  { | ||||||
|     max-width: 4rem; |     max-width: 4rem; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   roll-conditions roll-section[name="tricher"] img { |   roll-conditions roll-section img { | ||||||
|     /* image de d100 */ |     max-width: 1rem; | ||||||
|     max-width: 2.5rem; |     max-height: 1rem; | ||||||
|     max-height: 2.5rem; |  | ||||||
|     gap: 0; |     gap: 0; | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     padding: 0; |     padding: 0; | ||||||
|     filter: invert(0.8); |     filter: invert(0.8); | ||||||
|   } |   } | ||||||
|  |   roll-conditions roll-section[name="tricher"] img { | ||||||
|  |     /* image de d100 */ | ||||||
|  |     max-width: 2.5rem; | ||||||
|  |     max-height: 2.5rem; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   roll-buttons {  |   roll-buttons {  | ||||||
|     display: flex; |     display: flex; | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|     min-height: 100px; // Hauteur minimale pour la description |     min-height: 100px; // Hauteur minimale pour la description | ||||||
|     background: var(--rdd-bg-input-alt); // Une couleur de fond alternative |     background: var(--rdd-bg-input-alt); // Une couleur de fond alternative | ||||||
|     padding: 5px; |     padding: 5px; | ||||||
|     border-radius: 3px; |     border-radius: 0.2rem; | ||||||
|     color: var(--rdd-color-text-primary); |     color: var(--rdd-color-text-primary); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -28,7 +28,7 @@ | |||||||
|     background: var(--fieldset-background); |     background: var(--fieldset-background); | ||||||
|     color: var(--rdd-color-text-primary); |     color: var(--rdd-color-text-primary); | ||||||
|     margin-bottom: 4px; |     margin-bottom: 4px; | ||||||
|     border-radius: 6px; |     border-radius: 0.5rem; | ||||||
|     border-color: var(--rdd-color-text-primary); |     border-color: var(--rdd-color-text-primary); | ||||||
|     border-width: 2px; |     border-width: 2px; | ||||||
|   } |   } | ||||||
| @@ -64,7 +64,7 @@ | |||||||
|         --rdd-color-text-input |         --rdd-color-text-input | ||||||
|       ); // Assurez-vous que cette variable existe |       ); // Assurez-vous que cette variable existe | ||||||
|       padding: 2px 2px; // Augmentation du padding vertical |       padding: 2px 2px; // Augmentation du padding vertical | ||||||
|       border-radius: 3px; |       border-radius: 0.2rem; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     input[type="checkbox"] { |     input[type="checkbox"] { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { SYSTEM_RDD } from "../constants.js"; | import { renderTemplate, SYSTEM_RDD } from "../constants.js"; | ||||||
| import { RdDUtility } from "../rdd-utility.js"; | import { RdDUtility } from "../rdd-utility.js"; | ||||||
|  |  | ||||||
| const DETAIL_VENTE = 'detailVente'; | const DETAIL_VENTE = 'detailVente'; | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { renderTemplate } from "../constants.js"; | ||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
| import { RdDUtility } from "../rdd-utility.js"; | import { RdDUtility } from "../rdd-utility.js"; | ||||||
| import { ChatVente } from "./chat-vente.js"; | import { ChatVente } from "./chat-vente.js"; | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { renderTemplate } from "../constants.js"; | ||||||
| import { HtmlUtility } from "../html-utility.js"; | import { HtmlUtility } from "../html-utility.js"; | ||||||
| import { RdDUtility } from "../rdd-utility.js"; | import { RdDUtility } from "../rdd-utility.js"; | ||||||
| import { ChatVente } from "./chat-vente.js"; | import { ChatVente } from "./chat-vente.js"; | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ import { HtmlUtility } from "./html-utility.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"; | ||||||
| import { RdDCarac } from "./rdd-carac.js"; | import { CARACS, 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"; | ||||||
| @@ -174,7 +174,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|       await this.getBlessure(event)?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } }) |       await this.getBlessure(event)?.setSoinsBlessure({ soinscomplets: { bonus: Number(event.currentTarget.value) } }) | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     this.html.find('.roll-chance-actuelle').click(async event => await this.actor.rollCarac('chance-actuelle')) |     this.html.find('.roll-chance-actuelle').click(async event => await this.actor.rollCarac(CARACS.CHANCE_ACTUELLE)) | ||||||
|     this.html.find('.button-appel-chance').click(async event => await this.actor.rollAppelChance()) |     this.html.find('.button-appel-chance').click(async event => await this.actor.rollAppelChance()) | ||||||
|  |  | ||||||
|     this.html.find('[name="jet-astrologie"]').click(async event => await this.actor.astrologieNombresAstraux()) |     this.html.find('[name="jet-astrologie"]').click(async event => await this.actor.astrologieNombresAstraux()) | ||||||
| @@ -208,7 +208,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Points de reve actuel |     // Points de reve actuel | ||||||
|     this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac('reve-actuel', { resistance: true })) |     this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac(CARACS.REVE_ACTUEL, { resistance: true })) | ||||||
|     this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) |     this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) | ||||||
|  |  | ||||||
|     this.html.find('.roll-arme').click(async event => { |     this.html.find('.roll-arme').click(async event => { | ||||||
| @@ -342,7 +342,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async createEmptyTache() { |   async createEmptyTache() { | ||||||
|     await this.actor.createItem('tache', 'Nouvelle tache'); |     await this.actor.createItem(ITEM_TYPES.tache, 'Nouvelle tache') | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   _getActionCombat(event) { |   _getActionCombat(event) { | ||||||
| @@ -375,14 +375,6 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { | |||||||
|     return position; |     return position; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   /** @override */ |  | ||||||
|   _updateObject(event, formData) { |  | ||||||
|     // Update the Actor |  | ||||||
|     return this.actor.update(formData); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async splitItem(item) { |   async splitItem(item) { | ||||||
|     const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split)); |     const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split)); | ||||||
|     dialog.render(true); |     dialog.render(true); | ||||||
|   | |||||||
							
								
								
									
										298
									
								
								module/actor.js
									
									
									
									
									
								
							
							
						
						| @@ -17,9 +17,9 @@ import { Draconique } from "./tmr/draconique.js"; | |||||||
| import { CARACS, LIST_CARAC_PERSONNAGE, RdDCarac } from "./rdd-carac.js"; | import { CARACS, LIST_CARAC_PERSONNAGE, RdDCarac } from "./rdd-carac.js"; | ||||||
| import { DialogConsommer } from "./dialog-item-consommer.js"; | 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-v1.js"; | ||||||
| import { RdDPossession } from "./rdd-possession.js"; | import { RdDPossession } from "./rdd-possession.js"; | ||||||
| import { ACTOR_TYPES, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | import { ACTOR_TYPES, renderTemplate, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | ||||||
| import { RdDConfirm } from "./rdd-confirm.js"; | import { RdDConfirm } from "./rdd-confirm.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"; | ||||||
| @@ -47,6 +47,12 @@ import { RdDRollResult } from "./rdd-roll-result.js"; | |||||||
| import { RdDInitiative } from "./initiative.mjs"; | import { RdDInitiative } from "./initiative.mjs"; | ||||||
| import RollDialog from "./roll/roll-dialog.mjs"; | import RollDialog from "./roll/roll-dialog.mjs"; | ||||||
| import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js"; | import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js"; | ||||||
|  | import { ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_SORT } from "./roll/roll-constants.mjs"; | ||||||
|  | import { PART_TACHE } from "./roll/roll-part-tache.mjs"; | ||||||
|  | import { PART_COMP } from "./roll/roll-part-comp.mjs"; | ||||||
|  | import { PART_OEUVRE } from "./roll/roll-part-oeuvre.mjs"; | ||||||
|  | import { PART_CUISINE } from "./roll/roll-part-cuisine.mjs"; | ||||||
|  | import { PART_SORT } from "./roll/roll-part-sort.mjs"; | ||||||
|  |  | ||||||
| export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] | export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre'] | ||||||
|  |  | ||||||
| @@ -98,6 +104,8 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   isPersonnage() { return true } |   isPersonnage() { return true } | ||||||
|  |   isFeminin() { return this.system.sexe.length > 0 && this.system.sexe.charAt(0).toLowerCase() == 'f' } | ||||||
|  |  | ||||||
|   isHautRevant() { return this.system.attributs.hautrevant.value != "" } |   isHautRevant() { return this.system.attributs.hautrevant.value != "" } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -136,12 +144,12 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   listActions({ isAttaque = false, isEquipe = false }) { |   listActions({ isAttaque = false, isEquipe = false }) { | ||||||
|     // Recupération des armes |     // Recupération des attaques | ||||||
|     const actions = this.listActionsAttaque() |     const actions = this.listActionsAttaque() | ||||||
|       .filter(it => !isEquipe || it.arme.system.equipe) |       .filter(it => !isEquipe || it.arme.system.equipe) | ||||||
|  |  | ||||||
|     if (!isAttaque && this.system.attributs.hautrevant.value) { |     if (!isAttaque && this.system.attributs.hautrevant.value) { | ||||||
|       actions.push({ name: "Draconic", action: 'haut-reve', initOnly: true }) |       actions.push({ label: "Draconic", action: 'haut-reve', initOnly: true }) | ||||||
|     } |     } | ||||||
|     return actions |     return actions | ||||||
|   } |   } | ||||||
| @@ -158,10 +166,10 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   getDemiReve() { return this.system.reve.tmrpos.coord } |   getDemiReve() { return this.system.reve.tmrpos.coord } | ||||||
|   getDraconicList() { return this.itemTypes[ITEM_TYPES.competence].filter(it => it.system.categorie == 'draconic') } |   getDraconics() { return this.itemTypes[ITEM_TYPES.competence].filter(it => it.system.categorie == 'draconic') } | ||||||
|   getBestDraconic() { return foundry.utils.duplicate([...this.getDraconicList(), PAS_DE_DRACONIC].sort(Misc.descending(it => it.system.niveau)).find(it => true)) } |   getBestDraconic() { return foundry.utils.duplicate([...this.getDraconics(), PAS_DE_DRACONIC].sort(Misc.descending(it => it.system.niveau)).find(it => true)) } | ||||||
|   getDraconicOuPossession() { |   getDraconicOuPossession() { | ||||||
|     return [...this.getDraconicList().filter(it => it.system.niveau >= 0), POSSESSION_SANS_DRACONIC] |     return [...this.getDraconics().filter(it => it.system.niveau >= 0), POSSESSION_SANS_DRACONIC] | ||||||
|       .sort(Misc.descending(it => it.system.niveau)) |       .sort(Misc.descending(it => it.system.niveau)) | ||||||
|       .find(it => true) |       .find(it => true) | ||||||
|   } |   } | ||||||
| @@ -177,13 +185,13 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     const actions = [] |     const actions = [] | ||||||
|     const uniques = [] |     const uniques = [] | ||||||
|  |  | ||||||
|     const addAttaque = (arme, main) => { |     const addAttaque = (arme, main = undefined) => { | ||||||
|       const dommagesArme = RdDItemArme.valeurMain(arme.system.dommages, main) |       const dommages = RdDItemArme.valeurMain(arme.system.dommages, main) | ||||||
|       const forceRequise = RdDItemArme.valeurMain(arme.system.force ?? 0, main) |       const forceRequise = RdDItemArme.valeurMain(arme.system.force ?? 0, main) | ||||||
|       const ecaillesEfficacite = arme.system.magique ? arme.system.ecaille_efficacite : 0; |       const ecaillesEfficacite = arme.system.magique ? arme.system.ecaille_efficacite : 0; | ||||||
|  |  | ||||||
|       const comp = this.getCompetence(RdDActor.$getCompetenceAction(arme, main)) |       const comp = this.getCompetence(RdDActor.$getCompetenceAction(arme, main)) | ||||||
|       const unique = [comp.id, arme.name, dommagesArme, forceRequise, ecaillesEfficacite].join('|'); |       const unique = [comp.id, arme.name, dommages, forceRequise, ecaillesEfficacite].join('|'); | ||||||
|       if (uniques.includes(unique)) { |       if (uniques.includes(unique)) { | ||||||
|         return |         return | ||||||
|       } |       } | ||||||
| @@ -196,7 +204,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|       const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + ecaillesEfficacite |       const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + ecaillesEfficacite | ||||||
|  |  | ||||||
|       actions.push({ |       actions.push({ | ||||||
|         name: arme.name + (main ? ' ' + main : ''), |         label: arme.name + (main ? ' ' + main : ''), | ||||||
|         action: 'attaque', |         action: 'attaque', | ||||||
|         initOnly: false, |         initOnly: false, | ||||||
|         arme: arme, |         arme: arme, | ||||||
| @@ -204,24 +212,24 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|         main: main, |         main: main, | ||||||
|         carac: { key: caracCode, value: caracValue }, |         carac: { key: caracCode, value: caracValue }, | ||||||
|         equipe: arme.system.equipe, |         equipe: arme.system.equipe, | ||||||
|         dommagesArme: dommagesArme, |         dommages: dommages, | ||||||
|         forceRequise: forceRequise, |         forceRequise: forceRequise, | ||||||
|         initiative: RdDInitiative.calculInitiative(niveau, caracValue, ajustement) |         initiative: RdDInitiative.getRollInitiative(caracValue, niveau, ajustement) | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     addAttaque(RdDItemArme.empoignade(this)) |     addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS) | ||||||
|     addAttaque(RdDItemArme.corpsACorps(this)) |  | ||||||
|  |  | ||||||
|     this.itemTypes[ITEM_TYPES.arme] |     this.itemTypes[ITEM_TYPES.arme] | ||||||
|       .filter(it => it.isAttaque()) |       .filter(it => it.isAttaque()) | ||||||
|       .sort(Misc.ascending(it => it.name)) |       .sort(Misc.ascending(it => it.name)) | ||||||
|       .forEach(arme => { |       .forEach(arme => { | ||||||
|         if (arme.system.unemain && arme.system.competence) { addAttaque(arme, ATTAQUE_TYPE.UNE_MAIN) } |         if (arme.system.unemain && arme.system.competence && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.UNE_MAIN) } | ||||||
|         if (arme.system.deuxmains && arme.system.competence) { addAttaque(arme, ATTAQUE_TYPE.DEUX_MAINS) } |         if (arme.system.deuxmains && arme.system.competence && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.DEUX_MAINS) } | ||||||
|         if (arme.system.lancer) { addAttaque(arme, ATTAQUE_TYPE.LANCER) } |         if (arme.system.lancer && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.LANCER) } | ||||||
|         if (arme.system.tir) { addAttaque(arme, ATTAQUE_TYPE.TIR) } |         if (arme.system.tir) { addAttaque(arme, ATTAQUE_TYPE.TIR) } | ||||||
|       }) |       }) | ||||||
|  |     addAttaque(RdDItemArme.pugilat(this), ATTAQUE_TYPE.CORPS_A_CORPS) | ||||||
|  |  | ||||||
|     return actions |     return actions | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -697,11 +705,12 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async combattreReveDeDragon(force) { |   async combattreReveDeDragon(force) { | ||||||
|  |     const rencontre = await game.system.rdd.rencontresTMR.getReveDeDragon(force); | ||||||
|     let rollData = { |     let rollData = { | ||||||
|       actor: this, |       actor: this, | ||||||
|       competence: this.getDraconicOuPossession(), |       competence: this.getDraconicOuPossession(), | ||||||
|       canClose: false, |       canClose: false, | ||||||
|       rencontre: await game.system.rdd.rencontresTMR.getReveDeDragon(force), |       rencontre: rencontre, | ||||||
|       tmr: true, |       tmr: true, | ||||||
|       use: { libre: false, conditions: false }, |       use: { libre: false, conditions: false }, | ||||||
|       forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } } |       forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } } | ||||||
| @@ -732,12 +741,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async sortMisEnReserve(sort, draconic, coord, ptreve) { |   async sortMisEnReserve(sort, draconic, coord, ptreve) { | ||||||
|     await this.createEmbeddedDocuments("Item", [{ |     await this.createEmbeddedDocuments("Item", [RdDItemSort.prepareSortEnReserve(sort, draconic, ptreve, coord)], | ||||||
|       type: ITEM_TYPES.sortreserve, |  | ||||||
|       name: sort.name, |  | ||||||
|       img: sort.img, |  | ||||||
|       system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' } |  | ||||||
|     }], |  | ||||||
|       { renderSheet: false }); |       { renderSheet: false }); | ||||||
|     this.tmrApp.updateTokens(); |     this.tmrApp.updateTokens(); | ||||||
|   } |   } | ||||||
| @@ -751,20 +755,18 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     let updates = {}; |     let updates = {}; | ||||||
|     if (caracName == LIST_CARAC_PERSONNAGE.reve.code) { |     if (caracName == LIST_CARAC_PERSONNAGE.reve.code) { | ||||||
|       if (to > Misc.toInt(this.system.reve.seuil.value)) { |       if (to > Misc.toInt(this.system.reve.seuil.value)) { | ||||||
|         updates[`system.reve.seuil.value`] = to; // SFA : Direct and packed changes |         updates[`system.reve.seuil.value`] = to | ||||||
|         //this.setPointsDeSeuil(to); |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     if (caracName == LIST_CARAC_PERSONNAGE.chance.code) { |     if (caracName == LIST_CARAC_PERSONNAGE.chance.code) { | ||||||
|       if (to > Misc.toInt(this.system.compteurs.chance.value)) { |       if (to > Misc.toInt(this.system.compteurs.chance.value)) { | ||||||
|         updates[`system.compteurs.chance.value`] = to; // SFA : Direct and packed changes |         updates[`system.compteurs.chance.value`] = to | ||||||
|         //this.setPointsDeChance(to); |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     let selectedCarac = this.findCaracByName(caracName); |     let selectedCarac = this.findCaracByName(caracName); | ||||||
|     const from = selectedCarac.value |     const from = selectedCarac.value | ||||||
|     updates[`system.carac.${caracName}.value`] = to; |     updates[`system.carac.${caracName}.value`] = to; | ||||||
|     await this.update(updates); |     await this.update(updates, { noHook: true }); | ||||||
|     await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName); |     await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1342,7 +1344,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   async _apprecierCuisine(item, seForcer) { |   async _apprecierCuisine(item, seForcer) { | ||||||
|     const surmonteExotisme = await this._surmonterExotisme(item, seForcer); |     const surmonteExotisme = await this._surmonterExotisme(item, seForcer); | ||||||
|     if (surmonteExotisme) { |     if (surmonteExotisme) { | ||||||
|       await this.apprecier('gout', 'cuisine', item.system.qualite, item.system.boisson ? "apprécie la boisson" : "apprécie le plat"); |       await this.apprecier(CARACS.ODORATGOUT, 'cuisine', item.system.qualite, item.system.boisson ? "apprécie la boisson" : "apprécie le plat"); | ||||||
|     } |     } | ||||||
|     else if (seForcer) { |     else if (seForcer) { | ||||||
|       await this.jetDeMoral('malheureux'); |       await this.jetDeMoral('malheureux'); | ||||||
| @@ -1360,7 +1362,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     if (exotisme < 0 || qualite < 0) { |     if (exotisme < 0 || qualite < 0) { | ||||||
|       const competence = qualite > 0 ? 'cuisine' : undefined |       const competence = qualite > 0 ? 'cuisine' : undefined | ||||||
|       const difficulte = Math.min(exotisme, qualite) |       const difficulte = Math.min(exotisme, qualite) | ||||||
|       const rolled = await this.doRollCaracCompetence('volonte', competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` }) |       const rolled = await this.doRollCaracCompetence(CARACS.VOLONTE, competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` }) | ||||||
|       return rolled.isSuccess |       return rolled.isSuccess | ||||||
|     } |     } | ||||||
|     return true; |     return true; | ||||||
| @@ -1682,7 +1684,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   computeDraconicAndSortIndex(sortList) { |   computeDraconicAndSortIndex(sortList) { | ||||||
|     let draconicList = this.getDraconicList(); |     let draconicList = this.getDraconics(); | ||||||
|     for (let sort of sortList) { |     for (let sort of sortList) { | ||||||
|       let draconicsSort = RdDItemSort.getDraconicsSort(draconicList, sort).map(it => it.name); |       let draconicsSort = RdDItemSort.getDraconicsSort(draconicList, sort).map(it => it.name); | ||||||
|       for (let index = 0; index < draconicList.length && sort.system.listIndex == undefined; index++) { |       for (let index = 0; index < draconicList.length && sort.system.listIndex == undefined; index++) { | ||||||
| @@ -1703,15 +1705,18 @@ 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 | ||||||
|     } |     } | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       return await this.rollUnSortV2(); | ||||||
|  |     } | ||||||
|     // 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.itemTypes[ITEM_TYPES.sort].filter(it => RdDItemSort.isSortOnCoord(it, 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 | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const draconicList = this.computeDraconicAndSortIndex(sorts); |     const draconicList = this.computeDraconicAndSortIndex(sorts) | ||||||
|     const reve = foundry.utils.duplicate(this.system.carac.reve); |     const reve = foundry.utils.duplicate(this.system.carac.reve) | ||||||
|  |  | ||||||
|     const dialog = await this.openRollDialog({ |     const dialog = await this.openRollDialog({ | ||||||
|       name: 'lancer-un-sort', |       name: 'lancer-un-sort', | ||||||
| @@ -1734,6 +1739,27 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     this.tmrApp?.setTMRPendingAction(dialog); |     this.tmrApp?.setTMRPendingAction(dialog); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async rollUnSortV2() { | ||||||
|  |     const rollData = { | ||||||
|  |       ids: { actorId: this.id }, | ||||||
|  |       type: { allowed: [ROLL_TYPE_SORT], current: ROLL_TYPE_SORT } | ||||||
|  |     }; | ||||||
|  |     const dialog = await RollDialog.create(rollData, { | ||||||
|  |       callbacks: [roll => { | ||||||
|  |         this.tmrApp?.restoreTMRAfterAction(); | ||||||
|  |         if (roll.closeTMR) { | ||||||
|  |           this.tmrApp?.close(); | ||||||
|  |           this.tmrApp = undefined; | ||||||
|  |         } | ||||||
|  |       }], | ||||||
|  |       onRollDone: RollDialog.onRollDoneClose, | ||||||
|  |       onClose: () => { | ||||||
|  |         this.tmrApp?.restoreTMRAfterAction(); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |     this.tmrApp?.setTMRPendingAction(dialog); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   isMauvaiseRencontre() { // Gestion queue/souffle 'Mauvaise Rencontre en Perpective' |   isMauvaiseRencontre() { // Gestion queue/souffle 'Mauvaise Rencontre en Perpective' | ||||||
|     let addMsg = ""; |     let addMsg = ""; | ||||||
| @@ -1805,11 +1831,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|           console.log('lancement de sort', rollData.selectedSort) |           console.log('lancement de sort', rollData.selectedSort) | ||||||
|           const precedents = rollData.selectedSort.system.lancements ?? [] |           const lancements = RdDItemSort.prepareSortAddLancement(rollData.selectedSort, rollData.selectedSort.system.ptreve_reel) | ||||||
|           const lancements = [...precedents, { |  | ||||||
|             timestamp: game.system.rdd.calendrier.getTimestamp(), |  | ||||||
|             reve: rollData.selectedSort.system.ptreve_reel |  | ||||||
|           }] |  | ||||||
|           await this.updateEmbeddedDocuments('Item', |           await this.updateEmbeddedDocuments('Item', | ||||||
|             [{ _id: rollData.selectedSort._id, 'system.lancements': lancements }] |             [{ _id: rollData.selectedSort._id, 'system.lancements': lancements }] | ||||||
|           ) |           ) | ||||||
| @@ -1922,6 +1944,21 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) { |   async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) { | ||||||
|  |  | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       const rollData = { | ||||||
|  |         ids: { actorId: this.id }, | ||||||
|  |         type: { allowed: [PART_COMP], current: PART_COMP }, | ||||||
|  |         selected: { | ||||||
|  |           carac: { key: caracName }, | ||||||
|  |           comp: { key: compName, forced: options.forced }, | ||||||
|  |           diff: { value: diff ?? 0 } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       RollDialog.create(rollData, foundry.utils.mergeObject(options, { onRollDone: RollDialog.onRollDoneClose })) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) |     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||||
|     const competence = this.getCompetence(compName); |     const competence = this.getCompetence(compName); | ||||||
|     await this.openRollDialog({ |     await this.openRollDialog({ | ||||||
| @@ -1944,23 +1981,34 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollTache(id, options = {}) { |   async rollTache(id, options = {}) { | ||||||
|  |  | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) |     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||||
|     const tacheData = this.getTache(id) |     const tache = this.getTache(id) | ||||||
|     const compData = this.getCompetence(tacheData.system.competence) |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|     compData.system.defaut_carac = tacheData.system.carac; // Patch ! |       const rollData = { | ||||||
|  |         ids: { actorId: this.id }, | ||||||
|  |         selected: { tache: { key: tache.id, forced: options.forced } }, | ||||||
|  |         type: { allowed: [PART_TACHE], current: PART_TACHE } | ||||||
|  |       } | ||||||
|  |       RollDialog.create(rollData, options) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const compData = this.getCompetence(tache.system.competence) | ||||||
|  |     compData.system.defaut_carac = tache.system.carac; // Patch ! | ||||||
|  |  | ||||||
|     await this.openRollDialog({ |     await this.openRollDialog({ | ||||||
|       name: 'jet-competence', |       name: 'jet-competence', | ||||||
|       label: 'Jet de Tâche ' + tacheData.name, |       label: 'Jet de Tâche ' + tache.name, | ||||||
|       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs', |       template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs', | ||||||
|       rollData: { |       rollData: { | ||||||
|         competence: compData, |         competence: compData, | ||||||
|         tache: tacheData, |         tache: tache, | ||||||
|         diffLibre: tacheData.system.difficulte, |         diffLibre: tache.system.difficulte, | ||||||
|         diffConditions: 0, |         diffConditions: 0, | ||||||
|         use: { libre: false, conditions: true }, |         use: { libre: false, conditions: true }, | ||||||
|         carac: { |         carac: { | ||||||
|           [tacheData.system.carac]: foundry.utils.duplicate(this.system.carac[tacheData.system.carac]) |           [tache.system.carac]: foundry.utils.duplicate(this.system.carac[tache.system.carac]) | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       callbacks: [{ action: r => this._tacheResult(r, options) }] |       callbacks: [{ action: r => this._tacheResult(r, options) }] | ||||||
| @@ -1994,9 +2042,19 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollJeu(id) { |   async rollJeu(id) { | ||||||
|     const oeuvre = this.getJeu(id); |     const jeu = this.getJeu(id); | ||||||
|  |  | ||||||
|     const listCarac = oeuvre.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim()); |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       const rollData = { | ||||||
|  |         ids: { actorId: this.id }, | ||||||
|  |         selected: { jeu: { key: jeu.id } }, | ||||||
|  |         type: { allowed: [ROLL_TYPE_JEU], current: ROLL_TYPE_JEU } | ||||||
|  |       } | ||||||
|  |       await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose }) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const listCarac = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim()); | ||||||
|     const carac = listCarac.length > 0 ? listCarac[0] : 'chance' |     const carac = listCarac.length > 0 ? listCarac[0] : 'chance' | ||||||
|     const artData = { |     const artData = { | ||||||
|       art: 'jeu', verbe: 'Jeu', |       art: 'jeu', verbe: 'Jeu', | ||||||
| @@ -2006,14 +2064,25 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     }; |     }; | ||||||
|     listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]); |     listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]); | ||||||
|     artData.competence.system.niveauReel = artData.competence.system.niveau; |     artData.competence.system.niveauReel = artData.competence.system.niveau; | ||||||
|     artData.competence.system.niveau = Math.max(artData.competence.system.niveau, oeuvre.system.base); |     artData.competence.system.niveau = Math.max(artData.competence.system.niveau, jeu.system.base); | ||||||
|     await this._rollArtV1(artData, carac, oeuvre); |     await this._rollArtV1(artData, carac, jeu); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollMeditation(id) { |   async rollMeditation(id) { | ||||||
|     const meditation = foundry.utils.duplicate(this.getMeditation(id)); |     const meditation = foundry.utils.duplicate(this.getMeditation(id)); | ||||||
|  |  | ||||||
|  |     if (meditation && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       const rollData = { | ||||||
|  |         ids: { actorId: this.id }, | ||||||
|  |         selected: { meditation: { key: id } }, | ||||||
|  |         type: { allowed: [ROLL_TYPE_MEDITATION], current: ROLL_TYPE_MEDITATION } | ||||||
|  |       } | ||||||
|  |       await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose }) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const competence = foundry.utils.duplicate(this.getCompetence(meditation.system.competence)); |     const competence = foundry.utils.duplicate(this.getCompetence(meditation.system.competence)); | ||||||
|     competence.system.defaut_carac = "intellect"; // Meditation = toujours avec intellect |     competence.system.defaut_carac = "intellect"; // Meditation = toujours avec intellect | ||||||
|     let meditationData = { |     let meditationData = { | ||||||
| @@ -2053,7 +2122,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _getSignesDraconiques(coord) { |   _getSignesDraconiques(coord) { | ||||||
|     const type = TMRUtility.getTMRType(coord); |     const type = TMRUtility.getTMRType(coord); | ||||||
|     return this.itemTypes["signedraconique"].filter(it => it.system.typesTMR.includes(type)); |     return this.itemTypes[ITEM_TYPES.signedraconique].filter(it => it.system.typesTMR.includes(type)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -2065,18 +2134,19 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   async rollLireSigneDraconique(coord) { |   async rollLireSigneDraconique(coord) { | ||||||
|     if (!this.isHautRevant()) { |     if (!this.isHautRevant()) { | ||||||
|       ui.notifications.info("Seul un haut rêvant peut lire un signe draconique!"); |       ui.notifications.info("Seul un haut rêvant peut lire un signe draconique!"); | ||||||
|       return; |       return | ||||||
|     } |     } | ||||||
|     let signes = this._getSignesDraconiques(coord); |     let signes = this._getSignesDraconiques(coord) | ||||||
|     if (signes.length == 0) { |     if (signes.length == 0) { | ||||||
|       ui.notifications.info(`Aucun signe draconiques en ${coord} !`); |       ui.notifications.info(`Aucun signe draconiques en ${coord} !`) | ||||||
|       return; |       return | ||||||
|     } |     } | ||||||
|     let draconicList = this.getDraconicList() |  | ||||||
|  |     let draconicList = this.getDraconics() | ||||||
|       .map(draconic => { |       .map(draconic => { | ||||||
|         let draconicLecture = foundry.utils.duplicate(draconic); |         let draconicLecture = foundry.utils.duplicate(draconic) | ||||||
|         draconicLecture.system.defaut_carac = "intellect"; |         draconicLecture.system.defaut_carac = "intellect" | ||||||
|         return draconicLecture; |         return draconicLecture | ||||||
|       }); |       }); | ||||||
|  |  | ||||||
|     const intellect = this.system.carac.intellect; |     const intellect = this.system.carac.intellect; | ||||||
| @@ -2350,14 +2420,15 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     if (this.tmrApp) { |     if (this.tmrApp) { | ||||||
|       ui.notifications.warn("Vous êtes déja dans les TMR....") |       ui.notifications.warn("Vous êtes déja dans les TMR....") | ||||||
|       this.tmrApp.forceTMRDisplay() |       this.tmrApp.forceTMRDisplay() | ||||||
|       return |       return false | ||||||
|     } |     } | ||||||
|     if (mode != 'visu' && this.isDemiReve()) { |     if (mode != 'visu' && this.isDemiReve()) { | ||||||
|       ui.notifications.warn("Les personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation") |       ui.notifications.warn("Le personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation") | ||||||
|       mode = "visu"; // bascule le mode en visu automatiquement |       mode = "visu"; // bascule le mode en visu automatiquement | ||||||
|     } |     } | ||||||
|     if (mode == 'visu') { |     if (mode == 'visu') { | ||||||
|       await this._doDisplayTMR(mode) |       await this._doDisplayTMR(mode) | ||||||
|  |       return false | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       const rencontre = this.getRencontreTMREnAttente(); |       const rencontre = this.getRencontreTMREnAttente(); | ||||||
| @@ -2370,6 +2441,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|         buttonLabel: 'Monter dans les TMR', |         buttonLabel: 'Monter dans les TMR', | ||||||
|         onAction: async () => await this._doDisplayTMR(mode) |         onAction: async () => await this._doDisplayTMR(mode) | ||||||
|       }) |       }) | ||||||
|  |       return true | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -2392,7 +2464,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     let tmrFormData = { |     let tmrFormData = { | ||||||
|       mode: mode, |       mode: mode, | ||||||
|       fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance), |       fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance), | ||||||
|       draconic: this.getDraconicList(), |       draconic: this.getDraconics(), | ||||||
|       sort: this.itemTypes['sort'], |       sort: this.itemTypes['sort'], | ||||||
|       signes: this.itemTypes['signedraconique'], |       signes: this.itemTypes['signedraconique'], | ||||||
|       caracReve: parseInt(this.system.carac.reve.value), |       caracReve: parseInt(this.system.carac.reve.value), | ||||||
| @@ -2407,6 +2479,29 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     await this.tmrApp.onDeplacement() |     await this.tmrApp.onDeplacement() | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async quitterTMR(message, viewOnly, cumulFatigue) { | ||||||
|  |     if (this.tmrApp) { | ||||||
|  |       this.tmrApp = undefined | ||||||
|  |       const appliquerFatigue = ReglesOptionnelles.isUsing("appliquer-fatigue"); | ||||||
|  |       await this.santeIncDec( | ||||||
|  |         appliquerFatigue ? "fatigue" : "endurance", | ||||||
|  |         (appliquerFatigue ? 1 : -1) * cumulFatigue) | ||||||
|  |       if (!viewOnly) { | ||||||
|  |         await this.supprimerSignesDraconiques(it => it.system.ephemere && it.system.duree == '1 round', { render: false }) | ||||||
|  |         await this.setEffect(STATUSES.StatusDemiReve, false) | ||||||
|  |         ChatUtility.tellToUserAndGM(message) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async supprimerSignesDraconiques(filter = it => true, options = { render: true }) { | ||||||
|  |     const signes = this.itemTypes[ITEM_TYPES.signedraconique].filter(filter) | ||||||
|  |     if (signes.length > 0) { | ||||||
|  |       this.deleteEmbeddedDocuments("Item", signes.map(item => item.id), options) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollSoins(blesse, blessureId) { |   async rollSoins(blesse, blessureId) { | ||||||
|     const blessure = blesse.blessuresASoigner().find(it => it.id == blessureId); |     const blessure = blesse.blessuresASoigner().find(it => it.id == blessureId); | ||||||
| @@ -2414,14 +2509,17 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|       if (!blessure.system.premierssoins.done) { |       if (!blessure.system.premierssoins.done) { | ||||||
|         const tache = await this.getTacheBlessure(blesse, blessure); |         const tache = await this.getTacheBlessure(blesse, blessure); | ||||||
|         return await this.rollTache(tache.id, { |         return await this.rollTache(tache.id, { | ||||||
|           onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r) |           onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r), | ||||||
|  |           title: 'Premiers soins', | ||||||
|  |           forced: true | ||||||
|         }); |         }); | ||||||
|       } |       } | ||||||
|       if (!blessure.system.soinscomplets.done) { |       else if (!blessure.system.soinscomplets.done) { | ||||||
|         const diff = blessure.system.difficulte + (blessure.system.premierssoins.bonus ?? 0); |         const diff = blessure.system.difficulte + (blessure.system.premierssoins.bonus ?? 0); | ||||||
|         return await this.rollCaracCompetence("dexterite", "Chirurgie", diff, { |         return await this.rollCaracCompetence(CARACS.DEXTERITE, "Chirurgie", diff, { | ||||||
|           title: "Soins complets", |           title: "Soins complets", | ||||||
|           onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r) |           onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r), | ||||||
|  |           forced: true | ||||||
|         }) |         }) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -2436,6 +2534,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|     const blessure = this.getItem(blessureId, 'blessure') |     const blessure = this.getItem(blessureId, 'blessure') | ||||||
|  |  | ||||||
|     if (blessure && !blessure.system.premierssoins.done) { |     if (blessure && !blessure.system.premierssoins.done) { | ||||||
|       const tache = rollData.tache; |       const tache = rollData.tache; | ||||||
|       if (rollData.rolled.isETotal) { |       if (rollData.rolled.isETotal) { | ||||||
| @@ -2506,7 +2605,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     if (item?.isEquipable()) { |     if (item?.isEquipable()) { | ||||||
|       const isEquipe = !item.system.equipe; |       const isEquipe = !item.system.equipe; | ||||||
|       await item.update({ "system.equipe": isEquipe }); |       await item.update({ "system.equipe": isEquipe }); | ||||||
|       this.computeEncTotal(); |       this.computeEncTotal() | ||||||
|       if (isEquipe) |       if (isEquipe) | ||||||
|         this.verifierForceMin(item); |         this.verifierForceMin(item); | ||||||
|     } |     } | ||||||
| @@ -2897,6 +2996,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|     if (updatedEndurance && options.diff) { |     if (updatedEndurance && options.diff) { | ||||||
|       await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0) |       await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0) | ||||||
|     } |     } | ||||||
|  |     await super.onUpdateActor(update, options, actorId) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -2916,7 +3016,9 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|         break |         break | ||||||
|       case ITEM_TYPES.race: |       case ITEM_TYPES.race: | ||||||
|         await this.onCreateOwnedRace(item, options, id) |         await this.onCreateOwnedRace(item, options, id) | ||||||
|  |         break | ||||||
|     } |     } | ||||||
|  |     await super.onCreateItem(item, options, id) | ||||||
|     await item.onCreateItemTemporel(this); |     await item.onCreateItemTemporel(this); | ||||||
|     await item.onCreateDecoupeComestible(this); |     await item.onCreateDecoupeComestible(this); | ||||||
|   } |   } | ||||||
| @@ -2937,9 +3039,12 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|         break |         break | ||||||
|       case ITEM_TYPES.empoignade: |       case ITEM_TYPES.empoignade: | ||||||
|         await RdDEmpoignade.deleteLinkedEmpoignade(this.id, item) |         await RdDEmpoignade.deleteLinkedEmpoignade(this.id, item) | ||||||
|  |         // TODO: check remaining emp. | ||||||
|  |         await this.setEffect(STATUSES.StatusGrappled, false) | ||||||
|  |         await this.setEffect(STATUSES.StatusGrappling, false) | ||||||
|         break |         break | ||||||
|     } |     } | ||||||
|     super.onDeleteItem(item, options, id) |     await super.onDeleteItem(item, options, id) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -3050,24 +3155,11 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   async _rollArtV2(oeuvreId) { |   async _rollArtV2(oeuvreId) { | ||||||
|     const oeuvre = this.items.get(oeuvreId) |     const oeuvre = this.items.get(oeuvreId) | ||||||
|     const rollData = { |     const rollData = { | ||||||
|       title: `Interpretation de ${oeuvre.name} par ${this.name}`, |       ids: { actorId: this.id }, | ||||||
|       type: { |       selected: { oeuvre: { key: oeuvre.id } }, | ||||||
|         allowed: ["oeuvre"], |       type: { allowed: [PART_OEUVRE], current: PART_OEUVRE, }, | ||||||
|         current: "oeuvre", |  | ||||||
|       }, |  | ||||||
|       selected: { |  | ||||||
|         oeuvre: { key: oeuvre.id }, |  | ||||||
|       }, |  | ||||||
|       ids: { |  | ||||||
|         actorId: this.id |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     await RollDialog.create(rollData, { |     await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose }) | ||||||
|       onRollDone: (dialog) => { |  | ||||||
|         if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST)) |  | ||||||
|           dialog.close() |  | ||||||
|       } |  | ||||||
|     }) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -3163,14 +3255,26 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollRecetteCuisine(id) { |   async rollRecetteCuisine(id) { | ||||||
|     const oeuvre = this.getRecetteCuisine(id); |     const recette = this.getRecetteCuisine(id); | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       const rollData = { | ||||||
|  |         ids: { actorId: this.id }, | ||||||
|  |         type: { allowed: [PART_CUISINE], current: PART_CUISINE }, | ||||||
|  |         selected: { | ||||||
|  |           cuisine: { key: recette.id } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose }) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const artData = { |     const artData = { | ||||||
|       verbe: 'Cuisiner', |       verbe: 'Cuisiner', | ||||||
|       compName: 'cuisine', |       compName: 'cuisine', | ||||||
|       proportions: 1, |       proportions: 1, | ||||||
|       ajouterEquipement: false |       ajouterEquipement: false | ||||||
|     }; |     }; | ||||||
|     await this._rollArtV1(artData, 'odoratgout', oeuvre, r => this._resultRecetteCuisine(r)); |     await this._rollArtV1(artData, 'odoratgout', recette, r => this._resultRecetteCuisine(r)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -3203,6 +3307,18 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   async preparerNourriture(item) { |   async preparerNourriture(item) { | ||||||
|  |     if (item.getUtilisationCuisine() == 'brut' && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       const rollData = { | ||||||
|  |         ids: { actorId: this.id }, | ||||||
|  |         type: { allowed: [PART_CUISINE], current: PART_CUISINE }, | ||||||
|  |         selected: { | ||||||
|  |           cuisine: { key: item.id } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose }) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (item.getUtilisationCuisine() == 'brut') { |     if (item.getUtilisationCuisine() == 'brut') { | ||||||
|       const nourriture = { |       const nourriture = { | ||||||
|         name: 'Plat de ' + item.name, |         name: 'Plat de ' + item.name, | ||||||
| @@ -3213,7 +3329,7 @@ export class RdDActor extends RdDBaseActorSang { | |||||||
|           exotisme: item.system.exotisme, |           exotisme: item.system.exotisme, | ||||||
|           ingredients: item.name |           ingredients: item.name | ||||||
|         } |         } | ||||||
|       }; |       } | ||||||
|       const artData = { |       const artData = { | ||||||
|         verbe: 'Préparer', |         verbe: 'Préparer', | ||||||
|         compName: 'cuisine', |         compName: 'cuisine', | ||||||
|   | |||||||
| @@ -56,13 +56,15 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet { | |||||||
|     if (this.options.vueDetaillee) { |     if (this.options.vueDetaillee) { | ||||||
|       // On carac change |       // On carac change | ||||||
|       this.html.find('.carac-value').change(async event => { |       this.html.find('.carac-value').change(async event => { | ||||||
|         let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "") |         if (event.currentTarget.name.includes("carac.")) { | ||||||
|         await this.actor.updateCarac(caracName, parseInt(event.target.value)) |           let caracName = event.currentTarget.name.replace("carac.", "") | ||||||
|       }); |           await this.actor.updateCarac(caracName, parseInt(event.currentTarget.value)) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|       // On competence change |       // On competence change | ||||||
|       this.html.find('.competence-value').change(async event => { |       this.html.find('.competence-value').change(async event => { | ||||||
|         let compName = event.currentTarget.attributes.compname.value |         let compName = event.currentTarget.attributes.compname.value | ||||||
|         await this.actor.updateCompetence(compName, parseInt(event.target.value)) |         await this.actor.updateCompetence(compName, parseInt(event.currentTarget.value)) | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js"; | import { renderTemplate, SHOW_DICE, SYSTEM_RDD } from "../constants.js"; | ||||||
| import { Grammar } from "../grammar.js"; | import { Grammar } from "../grammar.js"; | ||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
| import { RdDResolutionTable } from "../rdd-resolution-table.js"; | import { RdDResolutionTable } from "../rdd-resolution-table.js"; | ||||||
| @@ -11,7 +11,7 @@ import { ITEM_TYPES } from "../constants.js"; | |||||||
| import { StatusEffects, STATUSES } from "../settings/status-effects.js"; | import { StatusEffects, STATUSES } 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 { CARACS, RdDCarac } from "../rdd-carac.js"; | ||||||
| import { RdDRollResult } from "../rdd-roll-result.js"; | import { RdDRollResult } from "../rdd-roll-result.js"; | ||||||
|  |  | ||||||
| import { RdDItemArme } from "../item/arme.js"; | import { RdDItemArme } from "../item/arme.js"; | ||||||
| @@ -23,8 +23,12 @@ import { RdDCombat } from "../rdd-combat.js"; | |||||||
| import { RdDEmpoignade } from "../rdd-empoignade.js"; | import { RdDEmpoignade } from "../rdd-empoignade.js"; | ||||||
| import { RdDPossession } from "../rdd-possession.js"; | import { RdDPossession } from "../rdd-possession.js"; | ||||||
| import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, POSSESSION_SANS_DRACONIC } from "../item/base-items.js"; | import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, POSSESSION_SANS_DRACONIC } from "../item/base-items.js"; | ||||||
| import { RollDataAjustements } from "../rolldata-ajustements.js"; | import { RollDataAjustements } from "../rolldata-ajustements-v1.js"; | ||||||
| import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs"; | import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs"; | ||||||
|  | import RollDialog from "../roll/roll-dialog.mjs"; | ||||||
|  | import { ATTAQUE_ROLL_TYPES, DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP, ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE } from "../roll/roll-constants.mjs"; | ||||||
|  | import { OptionsAvancees, ROLL_DIALOG_V2 } from "../settings/options-avancees.js"; | ||||||
|  | import { PART_COMP } from "../roll/roll-part-comp.mjs"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Classe de base pour les acteurs disposant de rêve (donc, pas des objets) |  * Classe de base pour les acteurs disposant de rêve (donc, pas des objets) | ||||||
| @@ -85,7 +89,6 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   getSConst() { return 0 } |   getSConst() { return 0 } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   isSurenc() { return false } |  | ||||||
|   computeMalusSurEncombrement() { return 0 } |   computeMalusSurEncombrement() { return 0 } | ||||||
|  |  | ||||||
|   ajustementAstrologique() { return 0 } |   ajustementAstrologique() { return 0 } | ||||||
| @@ -122,6 +125,8 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   async remiseANeuf() { } |   async remiseANeuf() { } | ||||||
|   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { } |   async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { } | ||||||
|  |  | ||||||
|  |   computeResumeBlessure() { } | ||||||
|  |   countBlessures(filter = it => !it.isContusion()) { return 0 } | ||||||
|   async santeIncDec(name, inc, isCritique = false) { } |   async santeIncDec(name, inc, isCritique = false) { } | ||||||
|  |  | ||||||
|   async finDeRound(options = { terminer: false }) { |   async finDeRound(options = { terminer: false }) { | ||||||
| @@ -172,10 +177,11 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   getCompetences(name = undefined, options = { onMessage: message => { } }) { |   getCompetences(name = undefined, options = { onMessage: message => { } }) { | ||||||
|  |     const all = [...this.itemTypes[ITEM_TYPES.competence], ...this.itemTypes[ITEM_TYPES.competencecreature]] | ||||||
|     if (name == undefined) { |     if (name == undefined) { | ||||||
|       return this.itemTypes[ITEM_TYPES.competence] |       return all | ||||||
|     } |     } | ||||||
|     return RdDItemCompetence.findCompetences(this.itemTypes[ITEM_TYPES.competence], name, options) |     return RdDItemCompetence.findCompetences(all, name, options) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getCompetenceCorpsACorps(options = { onMessage: message => { } }) { |   getCompetenceCorpsACorps(options = { onMessage: message => { } }) { | ||||||
| @@ -199,6 +205,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   getPossession(possessionId) { |   getPossession(possessionId) { | ||||||
|     return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId); |     return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getEmpoignades() { |   getEmpoignades() { | ||||||
|     return this.itemTypes[ITEM_TYPES.empoignade]; |     return this.itemTypes[ITEM_TYPES.empoignade]; | ||||||
|   } |   } | ||||||
| @@ -222,53 +229,13 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   isEffectAllowed(effectId) { return false } |  | ||||||
|  |  | ||||||
|   getEffects(filter = e => true, forceRequise = undefined) { |  | ||||||
|     const effects = this.getEmbeddedCollection("ActiveEffect") |  | ||||||
|     const selected = effects.filter(filter) |  | ||||||
|     if (forceRequise && this.isForceInsuffisante(forceRequise)) { |  | ||||||
|       selected.push(StatusEffects.prepareActiveEffect(STATUSES.StatusForceWeak)) |  | ||||||
|     } |  | ||||||
|     return selected |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   getEffectByStatus(statusId) { |  | ||||||
|     return this.getEffects().find(it => it.statuses.has(statusId)); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async setEffect(statusId, status) { |  | ||||||
|     if (this.isEffectAllowed(statusId)) { |  | ||||||
|       const effect = this.getEffectByStatus(statusId); |  | ||||||
|       if (!status && effect) { |  | ||||||
|         await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]); |  | ||||||
|       } |  | ||||||
|       if (status && !effect) { |  | ||||||
|         await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.prepareActiveEffect(statusId)]); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async removeEffect(id) { |  | ||||||
|     this.removeEffects(it => it.id == id) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async removeEffects(filter = e => true) { |  | ||||||
|     if (game.user.isGM) { |  | ||||||
|       const effectsToRemove = this.getEffects(filter); |  | ||||||
|       const ids = effectsToRemove.map(it => it.id); |  | ||||||
|       await this.deleteEmbeddedDocuments('ActiveEffect', ids); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   isDemiReve() { |   isDemiReve() { | ||||||
|     return this.getEffectByStatus(STATUSES.StatusDemiReve) != undefined |     return this.getEffectsByStatus(STATUSES.StatusDemiReve).length > 0 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getSurprise(isCombat = undefined) { |   getSurprise(isCombat = undefined, forceRequise = undefined) { | ||||||
|     return StatusEffects.getSurprise(this.getEffects(), isCombat) |     return StatusEffects.getSurprise(this.getEffects(e => true, isCombat, forceRequise), isCombat) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -305,6 +272,22 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|  |  | ||||||
|   async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) { |   async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) { | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) |     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||||
|  |  | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       const competence = this.getCompetence(compName); | ||||||
|  |       const rollData = { | ||||||
|  |         ids: { actorId: this.id }, | ||||||
|  |         type: { allowed: DEFAULT_ROLL_TYPES, current: PART_COMP }, | ||||||
|  |         selected: { | ||||||
|  |           carac: { key: caracName }, | ||||||
|  |           comp: { key: competence.name }, | ||||||
|  |           diff: { value: diff } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       RollDialog.create(rollData, options) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|     const competence = this.getCompetence(compName); |     const competence = this.getCompetence(compName); | ||||||
|     await this.openRollDialog({ |     await this.openRollDialog({ | ||||||
|       name: 'jet-competence', |       name: 'jet-competence', | ||||||
| @@ -377,9 +360,22 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   } |   } | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async rollCarac(caracName, options = {}) { |   async rollCarac(caracName, options = {}) { | ||||||
|     if (Grammar.equalsInsensitive(caracName, 'taille')) { |     if (Grammar.equalsInsensitive(caracName, CARACS.TAILLE)) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       const rollData = { | ||||||
|  |         ids: { actorId: this.id }, | ||||||
|  |         type: { allowed: DEFAULT_ROLL_TYPES, current: PART_COMP }, | ||||||
|  |         selected: { | ||||||
|  |           carac: { key: caracName }, | ||||||
|  |           comp: options.resistance ? { key: undefined, forced: true } : undefined | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       RollDialog.create(rollData, options) | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|     foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false }) |     foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false }) | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) |     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||||
|     let selectedCarac = this.getCaracByName(caracName) |     let selectedCarac = this.getCaracByName(caracName) | ||||||
| @@ -406,10 +402,24 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-general.hbs'); |     await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-general.hbs'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   async rollCompetence(idOrName, options = { tryTarget: true, arme: undefined }) { |   async rollCompetence(idOrName, options = { tryTarget: true, arme: undefined }) { | ||||||
|     RdDEmpoignade.checkEmpoignadeEnCours(this) |     RdDEmpoignade.checkEmpoignadeEnCours(this) | ||||||
|  |  | ||||||
|     const competence = this.getCompetence(idOrName); |     const competence = this.getCompetence(idOrName); | ||||||
|  |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       const rollData = { | ||||||
|  |         ids: { actorId: this.id }, | ||||||
|  |         type: { allowed: options.arme ? ATTAQUE_ROLL_TYPES : DEFAULT_ROLL_TYPES }, | ||||||
|  |         selected: { | ||||||
|  |           carac: competence.type == ITEM_TYPES.competencecreature ? { key: competence.name } : undefined, | ||||||
|  |           comp: { key: competence.name }, | ||||||
|  |           diff: { type: options.arme ? DIFF.ATTAQUE : DIFF.LIBRE, value: competence.system.default_diffLibre ?? 0 }, | ||||||
|  |           attaque: options.arme ? { arme: { key: options.arme.id } } : undefined | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       return await RollDialog.create(rollData) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     let rollData = { |     let rollData = { | ||||||
|       carac: this.system.carac, |       carac: this.system.carac, | ||||||
|       competence: competence, |       competence: competence, | ||||||
| @@ -427,7 +437,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|             RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme) |             RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme) | ||||||
|           } |           } | ||||||
|         }); |         }); | ||||||
|         return; |         return | ||||||
|       } |       } | ||||||
|       // Transformer la competence de créature |       // Transformer la competence de créature | ||||||
|       MappingCreatureArme.setRollDataCreature(rollData) |       MappingCreatureArme.setRollDataCreature(rollData) | ||||||
| @@ -449,6 +459,40 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   rollAttaque(token) { | ||||||
|  |     token = token ?? RdDUtility.getSelectedToken(this) | ||||||
|  |  | ||||||
|  |     if (Targets.hasTargets()) { | ||||||
|  |       Targets.selectOneTargetToken(target => { | ||||||
|  |         if (Targets.isTargetEntite(target)) { | ||||||
|  |           ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée!!!!`) | ||||||
|  |           return | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         RdDCombat.rddCombatTarget(target, this, token).attaqueV2(); | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       return RdDConfirm.confirmer({ | ||||||
|  |         settingConfirmer: "confirmer-combat-sans-cible", | ||||||
|  |         content: `<p>Voulez vous faire une attaque sans choisir de cible valide? | ||||||
|  |                   <br>Tous les jets de combats devront être gérés à la main | ||||||
|  |                   </p>`, | ||||||
|  |         title: 'Ne pas utiliser les automatisation de combat', | ||||||
|  |         buttonLabel: "Pas d'automatisation", | ||||||
|  |         onAction: async () => { | ||||||
|  |           const rollData = { | ||||||
|  |             ids: { actorId: this.id, actorTokenId: token?.id, }, | ||||||
|  |             type: { | ||||||
|  |               allowed: [ROLL_TYPE_ATTAQUE], current: ROLL_TYPE_ATTAQUE | ||||||
|  |             } | ||||||
|  |           }; | ||||||
|  |           return await RollDialog.create(rollData) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /** -------------------------------------------- |   /** -------------------------------------------- | ||||||
|    * @param {*} arme item d'arme/compétence de créature |    * @param {*} arme item d'arme/compétence de créature | ||||||
|    * @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 | ||||||
| @@ -588,7 +632,7 @@ export class RdDBaseActorReve extends RdDBaseActor { | |||||||
|   async accorder(entite, when = 'avant-encaissement') { |   async accorder(entite, when = 'avant-encaissement') { | ||||||
|     if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar") |     if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar") | ||||||
|       || entite == undefined |       || entite == undefined | ||||||
|       || !entite.isEntite([ENTITE_INCARNE]) |       || !entite.isEntiteIncarnee() | ||||||
|       || entite.isEntiteAccordee(this)) { |       || entite.isEntiteAccordee(this)) { | ||||||
|       return true |       return true | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -34,17 +34,17 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|  |  | ||||||
|   getFatigueActuelle() { |   getFatigueActuelle() { | ||||||
|     if (ReglesOptionnelles.isUsing("appliquer-fatigue")) { |     if (ReglesOptionnelles.isUsing("appliquer-fatigue")) { | ||||||
|       return Math.max(0, Math.min(this.getFatigueMax(),  Misc.toInt(this.system.sante.fatigue?.value))) |       return Math.max(0, Math.min(this.getFatigueMax(), Misc.toInt(this.system.sante.fatigue?.value))) | ||||||
|     } |     } | ||||||
|     return 0; |     return 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isCumulFatigueCauseSommeil(cumulFatigue){ |   isCumulFatigueCauseSommeil(cumulFatigue) { | ||||||
|     return ReglesOptionnelles.isUsing("appliquer-fatigue") |     return ReglesOptionnelles.isUsing("appliquer-fatigue") | ||||||
|     ? (this.getFatigueRestante() <= cumulFatigue) |       ? (this.getFatigueRestante() <= cumulFatigue) | ||||||
|     : (this.getEnduranceActuelle() <= cumulFatigue) |       : (this.getEnduranceActuelle() <= cumulFatigue) | ||||||
|   } |   } | ||||||
|   getFatigueRestante() {return this.getFatigueMax() - this.getFatigueActuelle() } |   getFatigueRestante() { return this.getFatigueMax() - this.getFatigueActuelle() } | ||||||
|   getFatigueMin() { return this.system.sante.endurance.max - this.system.sante.endurance.value } |   getFatigueMin() { return this.system.sante.endurance.max - this.system.sante.endurance.value } | ||||||
|  |  | ||||||
|   malusFatigue() { |   malusFatigue() { | ||||||
| @@ -116,6 +116,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|       blessure: blessure |       blessure: blessure | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async santeIncDec(name, inc, isCritique = false) { |   async santeIncDec(name, inc, isCritique = false) { | ||||||
|     if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) { |     if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) { | ||||||
| @@ -161,7 +162,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|     if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) { |     if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) { | ||||||
|       sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this.getFatigueMin()); |       sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this.getFatigueMin()); | ||||||
|     } |     } | ||||||
|     await this.update({ "system.sante": sante }) |     await this.update({ "system.sante": sante }, { render: true }) | ||||||
|     if (this.isDead()) { |     if (this.isDead()) { | ||||||
|       await this.setEffect(STATUSES.StatusComma, true); |       await this.setEffect(STATUSES.StatusComma, true); | ||||||
|     } |     } | ||||||
| @@ -179,6 +180,28 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|     return Math.max(0, Math.min(maxEndVie, maxEndGraves, maxEndCritiques)); |     return Math.max(0, Math.min(maxEndVie, maxEndGraves, maxEndCritiques)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async onCreateItem(item, options, id) { | ||||||
|  |     switch (item.type) { | ||||||
|  |       case ITEM_TYPES.blessure: | ||||||
|  |         await this.changeBleedingState() | ||||||
|  |         break | ||||||
|  |     } | ||||||
|  |     await super.onCreateItem(item, options, id) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async onUpdateItem(item, options, id) { | ||||||
|  |     switch (item.type) { | ||||||
|  |       case ITEM_TYPES.blessure: | ||||||
|  |         await this.changeBleedingState() | ||||||
|  |         break | ||||||
|  |     } | ||||||
|  |     await super.onUpdateItem(item, options, id) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async changeBleedingState() { | ||||||
|  |     const bleeding = this.itemTypes[ITEM_TYPES.blessure].find(it => it.isBleeding()) | ||||||
|  |     await this.setEffect(STATUSES.StatusBleeding, bleeding ? true : false) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async ajouterBlessure(encaissement, attackerToken = undefined) { |   async ajouterBlessure(encaissement, attackerToken = undefined) { | ||||||
| @@ -195,7 +218,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|     const endActuelle = this.getEnduranceActuelle(); |     const endActuelle = this.getEnduranceActuelle(); | ||||||
|     const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken); |     const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken); | ||||||
|     if (blessure.isCritique()) { |     if (blessure.isCritique()) { | ||||||
|       encaissement.endurance = endActuelle; |       encaissement.endurance = endActuelle | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (blessure.isMort()) { |     if (blessure.isMort()) { | ||||||
| @@ -292,7 +315,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   isSonne() { |   isSonne() { | ||||||
|     return this.getEffectByStatus(STATUSES.StatusStunned) |     return this.getEffectsByStatus(STATUSES.StatusStunned).length > 0 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isEffectAllowed(effectId) { return true } |   isEffectAllowed(effectId) { return true } | ||||||
|   | |||||||
| @@ -49,17 +49,14 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet { | |||||||
|     formData.calc = { |     formData.calc = { | ||||||
|       fortune: Monnaie.toSolsDeniers(this.actor.getFortune()), |       fortune: Monnaie.toSolsDeniers(this.actor.getFortune()), | ||||||
|       prixTotalEquipement: this.actor.computePrixTotalEquipement(), |       prixTotalEquipement: this.actor.computePrixTotalEquipement(), | ||||||
|       encTotal: await this.actor.computeEncTotal(), |       encTotal: this.actor.getEncTotal(), | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires); |     this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires); | ||||||
|     this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires); |     this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires); | ||||||
|     formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs); |     formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs); | ||||||
|     formData.competences.filter(it => it.type == ITEM_TYPES.competencecreature) |     formData.competences.filter(it => it.type == ITEM_TYPES.competencecreature) | ||||||
|       .forEach(it => { |       .forEach(it => it.isdommages = it.isDommages()) | ||||||
|         const competenceCreature = new RdDItemCompetenceCreature(it.toObject(), { parent: it.parent }); |  | ||||||
|         it.isdommages = competenceCreature.isDommages(); |  | ||||||
|       }) |  | ||||||
|  |  | ||||||
|     return formData; |     return formData; | ||||||
|   } |   } | ||||||
| @@ -232,14 +229,6 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet { | |||||||
|     return position; |     return position; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   /** @override */ |  | ||||||
|   _updateObject(event, formData) { |  | ||||||
|     // Update the Actor |  | ||||||
|     return this.actor.update(formData); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   async splitItem(item) { |   async splitItem(item) { | ||||||
|     const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split)); |     const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split)); | ||||||
|     dialog.render(true); |     dialog.render(true); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { ChatVente } from "../achat-vente/chat-vente.js"; | import { ChatVente } from "../achat-vente/chat-vente.js"; | ||||||
| import { ChatUtility } from "../chat-utility.js"; | import { ChatUtility } from "../chat-utility.js"; | ||||||
| import { SYSTEM_SOCKET_ID } from "../constants.js"; | import { renderTemplate, SYSTEM_SOCKET_ID } from "../constants.js"; | ||||||
| import { Grammar } from "../grammar.js"; | import { Grammar } from "../grammar.js"; | ||||||
| import { Monnaie } from "../item-monnaie.js"; | import { Monnaie } from "../item-monnaie.js"; | ||||||
| import { ITEM_TYPES } from "../constants.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
| @@ -10,6 +10,7 @@ import { RdDConfirm } from "../rdd-confirm.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"; | ||||||
| import { RdDItem } from "../item.js"; | import { RdDItem } from "../item.js"; | ||||||
|  | import { StatusEffects, STATUSES } from "../settings/status-effects.js"; | ||||||
|  |  | ||||||
| export class RdDBaseActor extends Actor { | export class RdDBaseActor extends Actor { | ||||||
|  |  | ||||||
| @@ -45,8 +46,10 @@ export class RdDBaseActor extends Actor { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static init() { |   static init() { | ||||||
|  |     Handlebars.registerHelper('actor-isFeminin', actor => actor.isFeminin()) | ||||||
|     Hooks.on("preUpdateItem", (item, change, options, id) => Misc.documentIfResponsible(item.parent)?.onPreUpdateItem(item, change, options, id)) |     Hooks.on("preUpdateItem", (item, change, options, id) => Misc.documentIfResponsible(item.parent)?.onPreUpdateItem(item, change, options, id)) | ||||||
|     Hooks.on("createItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onCreateItem(item, options, id)) |     Hooks.on("createItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onCreateItem(item, options, id)) | ||||||
|  |     Hooks.on("updateItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onUpdateItem(item, options, id)) | ||||||
|     Hooks.on("deleteItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onDeleteItem(item, options, id)) |     Hooks.on("deleteItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onDeleteItem(item, options, id)) | ||||||
|     Hooks.on("updateActor", (actor, change, options, actorId) => Misc.documentIfResponsible(actor)?.onUpdateActor(change, options, actorId)) |     Hooks.on("updateActor", (actor, change, options, actorId) => Misc.documentIfResponsible(actor)?.onUpdateActor(change, options, actorId)) | ||||||
|   } |   } | ||||||
| @@ -212,12 +215,15 @@ export class RdDBaseActor extends Actor { | |||||||
|     return game.users.players.find(player => player.active && player.character?.id == this.id); |     return game.users.players.find(player => player.active && player.character?.id == this.id); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isCreatureEntite() { return this.isCreature() || this.isEntite() } |   isCreatureOuEntite() { return this.isCreature() || this.isEntite() } | ||||||
|   isCreature() { return false } |   isCreature() { return false } | ||||||
|   isEntite(typeentite = []) { return false } |   isEntite() { return false } | ||||||
|  |   isEntiteIncarnee() { return false } | ||||||
|  |   isEntiteNonIncarnee() { return false } | ||||||
|   isHautRevant() { return false } |   isHautRevant() { return false } | ||||||
|   isVehicule() { return false } |   isVehicule() { return false } | ||||||
|   isPersonnage() { return false } |   isPersonnage() { return false } | ||||||
|  |   isFeminin() { return false } | ||||||
|   getItem(id, type = undefined) { |   getItem(id, type = undefined) { | ||||||
|     const item = this.items.get(id); |     const item = this.items.get(id); | ||||||
|     if (type == undefined || (item?.type == type)) { |     if (type == undefined || (item?.type == type)) { | ||||||
| @@ -237,20 +243,76 @@ export class RdDBaseActor extends Actor { | |||||||
|  |  | ||||||
|   getMonnaie(id) { return this.findItemLike(id, 'monnaie'); } |   getMonnaie(id) { return this.findItemLike(id, 'monnaie'); } | ||||||
|   getEncombrementMax() { return 0 } |   getEncombrementMax() { return 0 } | ||||||
|  |   isSurenc() { return false } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   isEffectAllowed(effectId) { return false } | ||||||
|  |  | ||||||
|  |   getEffects(filter = e => true, forceRequise = undefined) { | ||||||
|  |     const effects = this.getEmbeddedCollection("ActiveEffect") | ||||||
|  |     const selected = effects.filter(filter) | ||||||
|  |     if (forceRequise && this.isForceInsuffisante(forceRequise)) { | ||||||
|  |       selected.push(StatusEffects.prepareActiveEffect(STATUSES.StatusForceWeak)) | ||||||
|  |     } | ||||||
|  |     return selected | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getEffectsByStatus(effectId) { | ||||||
|  |     return this.getEffects().filter(it => it.statuses.has(effectId)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async setEffect(effectId, status) { | ||||||
|  |     if (this.isEffectAllowed(effectId)) { | ||||||
|  |       const effects = this.getEffectsByStatus(effectId) | ||||||
|  |       if (!status && effects.length > 0) { | ||||||
|  |         await this.deleteEmbeddedDocuments('ActiveEffect', effects.map(it => it.id), { render: true }) | ||||||
|  |       } | ||||||
|  |       if (status && effects.length == 0) { | ||||||
|  |         await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.prepareActiveEffect(effectId)], { render: true }) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async removeEffect(id) { | ||||||
|  |     this.removeEffects(it => it.id == id) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async removeEffects(filter = e => true) { | ||||||
|  |     if (game.user.isGM) { | ||||||
|  |       const effectsToRemove = this.getEffects(filter); | ||||||
|  |       const ids = effectsToRemove.map(it => it.id); | ||||||
|  |       await this.deleteEmbeddedDocuments('ActiveEffect', ids); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async updateCarac(caracName, to) { |   async updateCarac(caracName, to) { | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async onUpdateActor(change, options, actorId) { | ||||||
|  |     const updatedCarac = change?.system?.carac | ||||||
|  |     if (updatedCarac && (updatedCarac.force || updatedCarac.reve || updatedCarac.taille)) { | ||||||
|  |       console.log(' onUpdateActor', change, options, actorId) | ||||||
|  |       await this.setEffect(STATUSES.StatusSurEnc, this.isSurenc()) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onPreUpdateItem(item, change, options, id) { } |   async onPreUpdateItem(item, change, options, id) { } | ||||||
|   async onCreateItem(item, options, id) { } |  | ||||||
|   async onUpdateActor(update, options, actorId) { } |   async onCreateItem(item, options, id) { | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async onUpdateItem(item, options, id) { | ||||||
|  |   } | ||||||
|  |  | ||||||
|   async onDeleteItem(item, options, id) { |   async onDeleteItem(item, options, id) { | ||||||
|     if (item.isInventaire()) { |     if (item.isInventaire()) { | ||||||
|       await this._removeItemFromConteneur(item) |       await this._removeItemFromConteneur(item) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   async _removeItemFromConteneur(item) { |   async _removeItemFromConteneur(item) { | ||||||
|     const updates = this.items.filter(it => it.isConteneur() && it.system.contenu.includes(item.id)) |     const updates = this.items.filter(it => it.isConteneur() && it.system.contenu.includes(item.id)) | ||||||
|       .map(conteneur => { |       .map(conteneur => { | ||||||
| @@ -499,16 +561,22 @@ export class RdDBaseActor extends Actor { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async computeEncTotal() { |   async computeEncTotal() { | ||||||
|     if (!this.pack) { |     if (this.pack) { | ||||||
|  |       this.encTotal = 0 | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       const wasSurenc = this.isSurenc() | ||||||
|       this.encTotal = this.items.filter(it => RdDItem.getItemTypesInventaire().includes(it.type)) |       this.encTotal = this.items.filter(it => RdDItem.getItemTypesInventaire().includes(it.type)) | ||||||
|         .map(it => it.getEncTotal()).reduce(Misc.sum(), 0) |         .map(it => it.getEncTotal()).reduce(Misc.sum(), 0) | ||||||
|       return this.encTotal; |       const isSurenc = this.isSurenc() | ||||||
|  |       if (isSurenc != wasSurenc) { | ||||||
|  |         await this.setEffect(STATUSES.StatusSurEnc, isSurenc) | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|     return 0; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getEncTotal() { |   getEncTotal() { | ||||||
|     return Math.floor(this.encTotal ?? 0); |     return Math.floor(this.encTotal ?? 0) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async createItem(type, name = undefined) { |   async createItem(type, name = undefined) { | ||||||
| @@ -559,7 +627,7 @@ export class RdDBaseActor extends Actor { | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     await this.computeEncTotal(); |     await this.computeEncTotal() | ||||||
|     return result; |     return result; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -738,7 +806,7 @@ export class RdDBaseActor extends Actor { | |||||||
|       name: this.getAlias(), |       name: this.getAlias(), | ||||||
|       system: { description: this.system.description } |       system: { description: this.system.description } | ||||||
|     } |     } | ||||||
|     foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.hbs', chatData) |     renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.hbs', chatData) | ||||||
|       .then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride))); |       .then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride))); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -769,11 +837,15 @@ export class RdDBaseActor extends Actor { | |||||||
|     return this.itemTypes[ITEM_TYPES.possession] |     return this.itemTypes[ITEM_TYPES.possession] | ||||||
|       .map(p => { |       .map(p => { | ||||||
|         return { |         return { | ||||||
|           name: p.name, |           label: p.name, | ||||||
|           action: 'possession', |           action: 'possession', | ||||||
|           possessionid: p.system.possessionid, |           possessionid: p.system.possessionid, | ||||||
|         } |         } | ||||||
|       }) |       }) | ||||||
|   } |   } | ||||||
|  |   listActionsCombat() { | ||||||
|  |     const possessions = this.listActionsPossessions() | ||||||
|  |     return possessions.length > 0 ? possessions : this.listActions({}) | ||||||
|  |  | ||||||
|  |   } | ||||||
| } | } | ||||||
| @@ -43,7 +43,7 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet { | |||||||
|     this.html.find('.resonance-add').click(async event => |     this.html.find('.resonance-add').click(async event => | ||||||
|       await DialogSelect.select({ |       await DialogSelect.select({ | ||||||
|         label: "Choisir un acteur à accorder", |         label: "Choisir un acteur à accorder", | ||||||
|         list: game.actors.filter(it => it.isPersonnage() && it.prototypeToken.actorLink) |         list: game.actors.filter(it => true) | ||||||
|       }, |       }, | ||||||
|         it => this.resonanceAdd(it.id)) |         it => this.resonanceAdd(it.id)) | ||||||
|     ) |     ) | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; | import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; | ||||||
| import { ITEM_TYPES } from "../constants.js"; | import { ITEM_TYPES } from "../constants.js"; | ||||||
|  | import { RdDItemBlessure } from "../item/blessure.js"; | ||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
| import { RdDCarac } from "../rdd-carac.js"; | import { RdDCarac } from "../rdd-carac.js"; | ||||||
| import { RdDEncaisser } from "../rdd-roll-encaisser.js"; | import { RdDEncaisser } from "../rdd-roll-encaisser.js"; | ||||||
| @@ -16,11 +17,10 @@ export class RdDEntite extends RdDBaseActorReve { | |||||||
|     return item.type == ITEM_TYPES.competencecreature |     return item.type == ITEM_TYPES.competencecreature | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isEntite(typeentite = []) { |   isEntite() { return true } | ||||||
|     return (typeentite.length == 0 || typeentite.includes(this.system.definition.typeentite)); |   isEntiteNonIncarnee() { return this.system.definition.typeentite == ENTITE_NONINCARNE } | ||||||
|   } |   isEntiteIncarnee() { return [ENTITE_INCARNE, ENTITE_BLURETTE].includes(this.system.definition.typeentite) } | ||||||
|  |   isEntiteBlurette() { return this.system.definition.typeentite !== ENTITE_BLURETTE } | ||||||
|   isNonIncarnee() { return this.isEntite([ENTITE_NONINCARNE]) } |  | ||||||
|  |  | ||||||
|   getReveActuel() { |   getReveActuel() { | ||||||
|     return Misc.toInt(this.system.carac.reve?.value) |     return Misc.toInt(this.system.carac.reve?.value) | ||||||
| @@ -49,20 +49,20 @@ export class RdDEntite extends RdDBaseActorReve { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   async remiseANeuf() { |   async remiseANeuf() { | ||||||
|     await this.removeEffects(e => true); |     if (!this.isEntiteNonIncarnee()) { | ||||||
|     if (!this.isNonIncarnee()) { |  | ||||||
|       await this.update({ |       await this.update({ | ||||||
|         'system.sante.endurance.value': this.system.sante.endurance.max |         'system.sante.endurance.value': this.system.sante.endurance.max | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|  |     await this.removeEffects(e => true) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isDead() { |   isDead() { | ||||||
|     return this.isNonIncarnee() ? false : this.system.sante.endurance.value <= 0 |     return this.isEntiteNonIncarnee() ? false : this.system.sante.endurance.value <= 0 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async santeIncDec(name, inc, isCritique = false) { |   async santeIncDec(name, inc, isCritique = false) { | ||||||
|     if (name == 'endurance' && !this.isNonIncarnee()) { |     if (name == 'endurance' && !this.isEntiteNonIncarnee()) { | ||||||
|       const oldValue = this.system.sante.endurance.value; |       const oldValue = this.system.sante.endurance.value; | ||||||
|       const endurance = Math.max(0, |       const endurance = Math.max(0, | ||||||
|         Math.min(oldValue + inc, |         Math.min(oldValue + inc, | ||||||
| @@ -78,7 +78,7 @@ export class RdDEntite extends RdDBaseActorReve { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   async encaisser() { |   async encaisser() { | ||||||
|     if (this.isNonIncarnee()) { |     if (this.isEntiteNonIncarnee()) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     await RdDEncaisser.encaisser(this) |     await RdDEncaisser.encaisser(this) | ||||||
| @@ -89,15 +89,19 @@ export class RdDEntite extends RdDBaseActorReve { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   async onAppliquerJetEncaissement(encaissement, attackerToken) { |   async onAppliquerJetEncaissement(encaissement, attackerToken) { | ||||||
|  |     if (this.isEntiteNonIncarnee()) { | ||||||
|  |       return | ||||||
|  |     } | ||||||
|     const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance); |     const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance); | ||||||
|     foundry.utils.mergeObject(encaissement, { |     foundry.utils.mergeObject(encaissement, { | ||||||
|       resteEndurance: perteEndurance.newValue, |       resteEndurance: perteEndurance.newValue, | ||||||
|       endurance: perteEndurance.perte |       endurance: perteEndurance.perte, | ||||||
|     }); |       blessure: RdDItemBlessure.prepareBlessure(encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken) | ||||||
|  |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isEntiteAccordee(attacker) { |   isEntiteAccordee(attacker) { | ||||||
|     if (this.isEntite([ENTITE_INCARNE])) { |     if (this.isEntiteIncarnee()) { | ||||||
|       let resonnance = this.system.sante.resonnance |       let resonnance = this.system.sante.resonnance | ||||||
|       return (resonnance.actors.find(it => it == attacker.id)) |       return (resonnance.actors.find(it => it == attacker.id)) | ||||||
|     } |     } | ||||||
| @@ -106,7 +110,7 @@ export class RdDEntite extends RdDBaseActorReve { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async setEntiteReveAccordee(actor) { |   async setEntiteReveAccordee(actor) { | ||||||
|     if (this.isEntite([ENTITE_INCARNE])) { |     if (this.isEntiteIncarnee()) { | ||||||
|       if (this.system.sante.resonnance.actors.find(it => it == actor.id)) { |       if (this.system.sante.resonnance.actors.find(it => it == actor.id)) { | ||||||
|         // déjà accordé |         // déjà accordé | ||||||
|         return |         return | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ export class ExperienceLog { | |||||||
|     }; |     }; | ||||||
|     console.log('ExperienceLog.add', newXpLog) |     console.log('ExperienceLog.add', newXpLog) | ||||||
|     const newExperienceLog = (actor.system.experiencelog ?? []).concat([newXpLog]); |     const newExperienceLog = (actor.system.experiencelog ?? []).concat([newXpLog]); | ||||||
|     await actor.update({ [`system.experiencelog`]: newExperienceLog }); |     await actor.update({ [`system.experiencelog`]: newExperienceLog }, { noHook: true }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static labelTopic(topic) { |   static labelTopic(topic) { | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import { Grammar } from "../../grammar.js" | import { Grammar } from "../../grammar.js" | ||||||
| import { RdDItemArme } from "../../item/arme.js" | import { EMPOIGNADE, RdDItemArme } from "../../item/arme.js" | ||||||
| import { RdDItemCompetence } from "../../item-competence.js" | import { 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, RDD_CONFIG } from "../../constants.js" | ||||||
| import { Misc } from "../../misc.js" | import { Misc } from "../../misc.js" | ||||||
| import { RdDTimestamp } from "../../time/rdd-timestamp.js" | import { RdDTimestamp } from "../../time/rdd-timestamp.js" | ||||||
| import { RdDBonus } from "../../rdd-bonus.js" | import { RdDBonus } from "../../rdd-bonus.js" | ||||||
| @@ -141,7 +141,7 @@ export class Mapping { | |||||||
|  |  | ||||||
|   static prepareArmes(actor) { |   static prepareArmes(actor) { | ||||||
|     const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme) |     const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme) | ||||||
|     armes.push(RdDItemArme.corpsACorps(actor)); |     armes.push(RdDItemArme.pugilat(actor)); | ||||||
|     armes.push(RdDItemArme.empoignade(actor)); |     armes.push(RdDItemArme.empoignade(actor)); | ||||||
|     return armes.map(arme => [ |     return armes.map(arme => [ | ||||||
|       arme.system.unemain ? Mapping.prepareArme(actor, arme, '(1 main)') : undefined, |       arme.system.unemain ? Mapping.prepareArme(actor, arme, '(1 main)') : undefined, | ||||||
| @@ -160,7 +160,7 @@ export class Mapping { | |||||||
|       return undefined |       return undefined | ||||||
|     } |     } | ||||||
|     const categorie = Mapping.complementCategorie(arme, maniement) |     const categorie = Mapping.complementCategorie(arme, maniement) | ||||||
|     const dommages = Mapping.dommagesArme(actor, arme, maniement) |     const dommages = Mapping.dommages(actor, arme, maniement) | ||||||
|     return { |     return { | ||||||
|       name: arme.name + categorie, |       name: arme.name + categorie, | ||||||
|       niveau: Misc.toSignedString(competence.system.niveau), |       niveau: Misc.toSignedString(competence.system.niveau), | ||||||
| @@ -170,12 +170,13 @@ export class Mapping { | |||||||
|       arme: arme |       arme: arme | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   static dommagesArme(actor, arme, maniement) { |  | ||||||
|  |   static dommages(actor, arme, maniement) { | ||||||
|     const dmgArme = RdDItemArme.dommagesReels(arme, maniement) |     const dmgArme = RdDItemArme.dommagesReels(arme, maniement) | ||||||
|     const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)) |     const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)) | ||||||
|     switch (arme.system.mortalite) { |     switch (arme.system.mortalite) { | ||||||
|       case 'non-mortel': return `(${dommages})` |       case RDD_CONFIG.encaissement.nonmortel: return `(${dommages})` | ||||||
|       case 'empoignade': return '-' |       case RDD_CONFIG.encaissement.empoignade: return '-' | ||||||
|     } |     } | ||||||
|     return dommages |     return dommages | ||||||
|   } |   } | ||||||
| @@ -274,11 +275,10 @@ export class Mapping { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getDescription(actor) { |   static getDescription(actor) { | ||||||
|     const sexe = actor.system.sexe |     const naissance = actor.isFeminin() ? 'née' : 'né' | ||||||
|     const sexeFeminin = sexe.length > 0 && sexe.charAt(0).toLowerCase() == 'f' ? 'Née' : 'Né' |  | ||||||
|     const race = ['', 'humain'].includes(Grammar.toLowerCaseNoAccent(actor.system.race)) ? '' : (actor.system.race + ' ') |     const race = ['', 'humain'].includes(Grammar.toLowerCaseNoAccent(actor.system.race)) ? '' : (actor.system.race + ' ') | ||||||
|     const heure = actor.system.heure |     const heure = actor.system.heure | ||||||
|     const hn = `${sexeFeminin} à l'heure ${RdDTimestamp.definition(heure).avecArticle}` |     const hn = `${naissance} à l'heure ${RdDTimestamp.definition(heure).avecArticle}` | ||||||
|     const age = (actor.system.age && actor.system.age >0) ? `${actor.system.age} ans` : undefined |     const age = (actor.system.age && actor.system.age >0) ? `${actor.system.age} ans` : undefined | ||||||
|     const taille = actor.system.taille |     const taille = actor.system.taille | ||||||
|     const poids = actor.system.poids |     const poids = actor.system.poids | ||||||
|   | |||||||
| @@ -20,14 +20,15 @@ const PATHS = [ | |||||||
| const RANDOM_VALUES = { | const RANDOM_VALUES = { | ||||||
|   'system.sexe': { 'masculin': 1, 'féminin': 1 }, |   'system.sexe': { 'masculin': 1, 'féminin': 1 }, | ||||||
|   'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidextre': 6 }, |   'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidextre': 6 }, | ||||||
|   'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains clair': 5, 'blonds': 4, 'blonds très clair': 1, 'roux carotte': 1, 'roux cuivré': 3 }, |   'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains': 3, 'châtain clair': 5, 'blonds': 4, 'blond platine': 1, 'roux carotte': 1, 'roux cuivré': 3, 'chauve': 1 }, | ||||||
|   'system.yeux': { 'noirs': 2, 'noisettes': 3, 'bruns vert': 4, 'verts': 3, 'bleus clair': 3, 'bleus gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 }, |   'system.yeux': { 'noirs': 2, 'noisette': 3, 'brun-vert': 4, 'verts': 3, 'bleu clair': 3, 'bleu gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 }, | ||||||
| } | } | ||||||
|  |  | ||||||
| export class AppPersonnageAleatoire extends FormApplication { | export class AppPersonnageAleatoire extends FormApplication { | ||||||
|   static preloadHandlebars() { |   static preloadHandlebars() { | ||||||
|     foundry.applications.handlebars.loadTemplates([ |     foundry.applications.handlebars.loadTemplates([ | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs', | ||||||
|  |       'systems/foundryvtt-reve-de-dragon/templates/actor/random/sexe-aleatoire.hbs', | ||||||
|     ]) |     ]) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -49,14 +50,14 @@ export class AppPersonnageAleatoire extends FormApplication { | |||||||
|     this.current = foundry.utils.duplicate(actor) |     this.current = foundry.utils.duplicate(actor) | ||||||
|     this.checked = { |     this.checked = { | ||||||
|       'name': false, |       'name': false, | ||||||
|       'system.sexe': true, |       'system.sexe': (this.actor.system.sexe ?? '') == '', | ||||||
|       'system.age': true, |       'system.age': this.actor.system.age == 0, | ||||||
|       'system.taille': true, |       'system.taille': (this.actor.system.taille ?? '') == '', | ||||||
|       'system.poids': true, |       'system.poids': (this.actor.system.poids ?? '') == '', | ||||||
|       'system.main': true, |       'system.main': (this.actor.system.main ?? '') == '', | ||||||
|       'system.heure': true, |       'system.heure': (this.actor.system.heure ?? '') == '', | ||||||
|       'system.cheveux': true, |       'system.cheveux': (this.actor.system.cheveux ?? '') == '', | ||||||
|       'system.yeux': true |       'system.yeux': (this.actor.system.yeux ?? '') == '', | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -76,6 +77,8 @@ export class AppPersonnageAleatoire extends FormApplication { | |||||||
|     this.html.find("button.button-apply").click(async event => await this.onApply()) |     this.html.find("button.button-apply").click(async event => await this.onApply()) | ||||||
|     this.html.find("input.current-value").change(async event => await this.onChange(event)) |     this.html.find("input.current-value").change(async event => await this.onChange(event)) | ||||||
|     this.html.find("div.random-field[data-path='system.heure'] select.current-value").change(async event => await this.onChange(event)) |     this.html.find("div.random-field[data-path='system.heure'] select.current-value").change(async event => await this.onChange(event)) | ||||||
|  |     this.html.find('a[data-action="sexe-masculin"]').click(async event => await this.onSexe('masculin')) | ||||||
|  |     this.html.find('a[data-action="sexe-feminin"]').click(async event => await this.onSexe('féminin')) | ||||||
|     this.html.find("a.random").click(async event => await this.onRandom(event)) |     this.html.find("a.random").click(async event => await this.onRandom(event)) | ||||||
|     this.html.find("a.reset").click(async event => await this.onReset(event)) |     this.html.find("a.reset").click(async event => await this.onReset(event)) | ||||||
|     this.html.find("a.randomize-selected").click(async event => await this.onRandomizeSelected()) |     this.html.find("a.randomize-selected").click(async event => await this.onRandomizeSelected()) | ||||||
| @@ -96,6 +99,10 @@ export class AppPersonnageAleatoire extends FormApplication { | |||||||
|     const fields = this.html.find(selector).parents("div.random-field:first") |     const fields = this.html.find(selector).parents("div.random-field:first") | ||||||
|     return fields[0].attributes['data-path'].value |     return fields[0].attributes['data-path'].value | ||||||
|   } |   } | ||||||
|  |   async onSexe(sexe) { | ||||||
|  |     this.current['system.sexe'] = sexe | ||||||
|  |     this.render() | ||||||
|  |   } | ||||||
|  |  | ||||||
|   async onChange(event) { |   async onChange(event) { | ||||||
|     const path = this.getPath(event.currentTarget) |     const path = this.getPath(event.currentTarget) | ||||||
| @@ -180,8 +187,9 @@ export class AppPersonnageAleatoire extends FormApplication { | |||||||
|     const variation = Math.floor((caracTaille.poidsMax - caracTaille.poidsMin + base / 5) / 2) |     const variation = Math.floor((caracTaille.poidsMax - caracTaille.poidsMin + base / 5) / 2) | ||||||
|     const total = await RdDDice.rollTotal(`2d${variation} + ${base}`) |     const total = await RdDDice.rollTotal(`2d${variation} + ${base}`) | ||||||
|     const cm = total % 100 |     const cm = total % 100 | ||||||
|  |     const dm = cm < 10 ? '0' : '' | ||||||
|     const m = (total - cm) / 100 |     const m = (total - cm) / 100 | ||||||
|     return `${m}m${cm}` |     return `${m}m${dm}${cm}` | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { renderTemplate } from "../../constants.js"; | ||||||
|  |  | ||||||
| export class TextRollManager { | export class TextRollManager { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | import { renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||||
| import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js"; | import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js"; | ||||||
|  |  | ||||||
| @@ -106,6 +106,25 @@ export class ChatUtility { | |||||||
|     return await ChatMessage.create(messageData) |     return await ChatMessage.create(messageData) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static tellToUser(message) { | ||||||
|  |     ChatMessage.create({ content: message, user: game.user.id, whisper: [game.user.id] }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static tellToGM(message) { | ||||||
|  |     ChatMessage.create({ | ||||||
|  |       user: game.user.id, | ||||||
|  |       content: message, | ||||||
|  |       whisper: ChatUtility.getGMs() | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static tellToUserAndGM(message) { | ||||||
|  |     ChatMessage.create({ | ||||||
|  |       user: game.user.id, | ||||||
|  |       content: message, | ||||||
|  |       whisper: ChatUtility.getUserAndGMs() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|   static getOwners(document) { |   static getOwners(document) { | ||||||
|     return document ? game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) : [game.user] |     return document ? game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) : [game.user] | ||||||
|   } |   } | ||||||
| @@ -190,8 +209,8 @@ export class ChatUtility { | |||||||
|     if (rddTimestamp) { |     if (rddTimestamp) { | ||||||
|       const timestamp = new RdDTimestamp(rddTimestamp); |       const timestamp = new RdDTimestamp(rddTimestamp); | ||||||
|       const timestampData = timestamp.toCalendrier(); |       const timestampData = timestamp.toCalendrier(); | ||||||
|       const dateHeure = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData); |       const dateHeure = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData); | ||||||
|       $(html).find('header.message-header .message-sender').after(dateHeure) |       $(html).find('header.message-header .message-timestamp').after(dateHeure) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| import { RdDBaseActor } from "../actor/base-actor.js"; | import { RdDBaseActor } from "../actor/base-actor.js"; | ||||||
| import { ChatUtility } from "../chat-utility.js"; | import { ChatUtility } from "../chat-utility.js"; | ||||||
|  | import { renderTemplate } from "../constants.js"; | ||||||
|  |  | ||||||
| const INFO_COEUR = 'info-coeur'; | const INFO_COEUR = 'info-coeur'; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,47 +9,67 @@ export const ENTITE_INCARNE = 'incarne' | |||||||
| export const ENTITE_NONINCARNE = 'nonincarne' | export const ENTITE_NONINCARNE = 'nonincarne' | ||||||
| export const ENTITE_BLURETTE = 'blurette' | export const ENTITE_BLURETTE = 'blurette' | ||||||
|  |  | ||||||
|  | export const renderTemplate = foundry.applications.handlebars.renderTemplate | ||||||
|  |  | ||||||
| export const RDD_CONFIG = { | export const RDD_CONFIG = { | ||||||
|   niveauEthylisme : [ |   niveauEthylisme: [ | ||||||
|     {value: "1", label: "Aucun"}, |     { value: '1', label: 'Aucun' }, | ||||||
|     {value: "0", label: "Eméché (0)"}, |     { value: '0', label: 'Eméché (0)' }, | ||||||
|     {value: "-1", label: "Gris (-1)"}, |     { value: '-1', label: 'Gris (-1)' }, | ||||||
|     {value: "-2", label: "Pinté (-2)"}, |     { value: '-2', label: 'Pinté (-2)' }, | ||||||
|     {value: "-3", label: "Pas Frais (-3)"}, |     { value: '-3', label: 'Pas Frais (-3)' }, | ||||||
|     {value: "-4", label: "Ivre (-4)"}, |     { value: '-4', label: 'Ivre (-4)' }, | ||||||
|     {value: "-5", label: "Bu (-5)"}, |     { value: '-5', label: 'Bu (-5)' }, | ||||||
|     {value: "-6", label: "Complètement fait (-6)"}, |     { value: '-6', label: 'Complètement fait (-6)' }, | ||||||
|     {value: "-7", label: "Ivre mort (-7)"} |     { value: '-7', label: 'Ivre mort (-7)' } | ||||||
|   ], |   ], | ||||||
|   categorieEntite: { |   categorieEntite: { | ||||||
|     "cauchemar": "Cauchemar", |     'cauchemar': 'Cauchemar', | ||||||
|     "reve": "Rêve" |     'reve': 'Rêve' | ||||||
|   }, |   }, | ||||||
|   typeEntite: { |   typeEntite: { | ||||||
|     "incarne": "Incarnée", |     [ENTITE_INCARNE]: 'Incarnée', | ||||||
|     "nonincarne": "Non Incarnée", |     [ENTITE_NONINCARNE]: 'Non Incarnée', | ||||||
|     "blurette": "Blurette" |     [ENTITE_BLURETTE]: 'Blurette' | ||||||
|   }, |   }, | ||||||
|   heuresRdD : [ |   heuresRdD: [ | ||||||
|     {value : "vaisseau", label: "Vaisseau", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd01.webp"}, |     { value: 'vaisseau', label: 'Vaisseau', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd01.webp' }, | ||||||
|     {value : "sirene", label: "Sirène", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd02.webp"}, |     { value: 'sirene', label: 'Sirène', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd02.webp' }, | ||||||
|     {value : "faucon", label: "Faucon", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd03.webp"}, |     { value: 'faucon', label: 'Faucon', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd03.webp' }, | ||||||
|     {value : "couronne", label: "Couronne", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd04.webp"}, |     { value: 'couronne', label: 'Couronne', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd04.webp' }, | ||||||
|     {value : "dragon", label: "Dragon", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd05.webp"}, |     { value: 'dragon', label: 'Dragon', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd05.webp' }, | ||||||
|     {value : "epees", label: "Epées", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd06.webp"}, |     { value: 'epees', label: 'Epées', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd06.webp' }, | ||||||
|     {value : "lyre", label: "Lyre", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd07.webp"}, |     { value: 'lyre', label: 'Lyre', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd07.webp' }, | ||||||
|     {value : "serpent", label: "Serpent", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd08.webp"}, |     { value: 'serpent', label: 'Serpent', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd08.webp' }, | ||||||
|     {value : "poissonacrobate", label: "Poisson Acrobate", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd09.webp"}, |     { value: 'poissonacrobate', label: 'Poisson Acrobate', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd09.webp' }, | ||||||
|     {value : "araignee", label: "Araignée", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd10.webp"}, |     { value: 'araignee', label: 'Araignée', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd10.webp' }, | ||||||
|     {value : "roseau", label: "Roseau", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd11.webp"}, |     { value: 'roseau', label: 'Roseau', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd11.webp' }, | ||||||
|     {value : "chateaudormant", label: "Chateau Dormant", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd12.webp"}     |     { value: 'chateaudormant', label: 'Chateau Dormant', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.webp' } | ||||||
|   ], |   ], | ||||||
|   raretes: [ |   raretes: [ | ||||||
|     {value: "Commune", label: "Commune"}, |     { value: 'Commune', label: 'Commune' }, | ||||||
|     {value: "Frequente", label: "Fréquente"}, |     { value: 'Frequente', label: 'Fréquente' }, | ||||||
|     {value: "Rare", label: "Rare"}, |     { value: 'Rare', label: 'Rare' }, | ||||||
|     {value: "Rarissime", label: "Rarissime"} |     { value: 'Rarissime', label: 'Rarissime' } | ||||||
|   ] |   ], | ||||||
|  |   particuliere: { | ||||||
|  |     force: { key: 'force', descr: 'en force', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-force.svg' }, | ||||||
|  |     finesse: { key: 'finesse', descr: 'en finesse', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-finesse.svg' }, | ||||||
|  |     rapidite: { key: 'rapidite', descr: 'en rapidité', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-rapidite.svg' }, | ||||||
|  |   }, | ||||||
|  |   icons: { | ||||||
|  |     armesDisparates: 'systems/foundryvtt-reve-de-dragon/assets/actions/armes-disparates.svg', | ||||||
|  |     demiReve: 'systems/foundryvtt-reve-de-dragon/assets/actions/sort.svg', | ||||||
|  |     empoignade: 'systems/foundryvtt-reve-de-dragon/assets/actions/empoignade.svg', | ||||||
|  |     forceWeak: 'systems/foundryvtt-reve-de-dragon/assets/actions/weak.svg', | ||||||
|  |     surenc: 'systems/foundryvtt-reve-de-dragon/assets/actions/surenc.svg', | ||||||
|  |   }, | ||||||
|  |   encaissement: { | ||||||
|  |     mortel: 'mortel', | ||||||
|  |     nonmortel: 'non-mortel', | ||||||
|  |     entiteincarnee: 'entiteincarnee', | ||||||
|  |     empoignade: 'empoignade' | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| export const ACTOR_TYPES = { | export const ACTOR_TYPES = { | ||||||
| @@ -107,13 +127,3 @@ export const ITEM_TYPES = { | |||||||
|   extraitpoetique: 'extraitpoetique', |   extraitpoetique: 'extraitpoetique', | ||||||
| } | } | ||||||
|  |  | ||||||
| export const CATEGORIES_COMPETENCES = { |  | ||||||
|   "generale": { base: -4, label: "Générales" }, |  | ||||||
|   "particuliere": { base: -8, label: "Particulières" }, |  | ||||||
|   "specialisee": { base: -11, label: "Spécialisées" }, |  | ||||||
|   "connaissance": { base: -11, label: "Connaissances" }, |  | ||||||
|   "draconic": { base: -11, label: "Draconic" }, |  | ||||||
|   "melee": { base: -6, label: "Mêlée" }, |  | ||||||
|   "tir": { base: -8, label: "Tir" }, |  | ||||||
|   "lancer": { base: -8, label: "Lancer" } |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { renderTemplate } from "./constants.js" | ||||||
|  |  | ||||||
| export class DialogChoixXpCarac extends Dialog { | export class DialogChoixXpCarac extends Dialog { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { SYSTEM_RDD } from "./constants.js"; | import { renderTemplate, SYSTEM_RDD } from "./constants.js"; | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { HtmlUtility } from "./html-utility.js"; | import { HtmlUtility } from "./html-utility.js"; | ||||||
| import { RdDTimestamp } from "./time/rdd-timestamp.js"; | import { RdDTimestamp } from "./time/rdd-timestamp.js"; | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { ChatUtility } from "./chat-utility.js"; | import { ChatUtility } from "./chat-utility.js"; | ||||||
|  | import { renderTemplate } from "./constants.js"; | ||||||
| import { HtmlUtility } from "./html-utility.js"; | import { HtmlUtility } from "./html-utility.js"; | ||||||
| import { RdDItemSigneDraconique } from "./item/signedraconique.js"; | import { RdDItemSigneDraconique } from "./item/signedraconique.js"; | ||||||
| import { TMRUtility } from "./tmr-utility.js"; | import { TMRUtility } from "./tmr-utility.js"; | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { renderTemplate } from "./constants.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { renderTemplate } from "./constants.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
|  |  | ||||||
| export class DialogConsommer extends Dialog { | export class DialogConsommer extends Dialog { | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { renderTemplate } from "./constants.js" | ||||||
|  |  | ||||||
| export class DialogSelect extends Dialog { | export class DialogSelect extends Dialog { | ||||||
|   static extractIdNameImg(it) { return { id: it.id, name: it.name, img: it.img } } |   static extractIdNameImg(it) { return { id: it.id, name: it.name, img: it.img } } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { Misc } from "./misc.js"; | import { renderTemplate } from "./constants.js"; | ||||||
|  |  | ||||||
| export class DialogSplitItem extends Dialog { | export class DialogSplitItem extends Dialog { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { HIDE_DICE, SHOW_DICE } from "./constants.js"; | import { HIDE_DICE, renderTemplate, SHOW_DICE } from "./constants.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { ITEM_TYPES } from "../constants.js" | import { ITEM_TYPES, renderTemplate } from "../constants.js" | ||||||
| import { RdDItemSort } from "../item-sort.js" | import { RdDItemSort } from "../item-sort.js" | ||||||
| import { Misc } from "../misc.js" | import { Misc } from "../misc.js" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,66 @@ | |||||||
|  | export const MAP_PHASE = { | ||||||
|  |   possession: { label: "possession", rang: 10 }, | ||||||
|  |   draconic: { label: "draconic", rang: 9 }, | ||||||
|  |   tir: { label: "tir", rang: 8 }, | ||||||
|  |   lancer: { label: "lancer", rang: 7 }, | ||||||
|  |   arme: { label: "mêlée", rang: 5 }, | ||||||
|  |   pugilat: { label: "pugilat", rang: 4 }, | ||||||
|  |   naturelle: { label: "créature", rang: 4 }, | ||||||
|  |   empoignade: { label: "empoignade", rang: 3 }, | ||||||
|  |   autre: { label: "autre action", rang: 2 }, | ||||||
|  |   demi: { label: "demi-surprise", rang: 0 }, | ||||||
|  |   totale: { label: "surprise totale", rang: -1 }, | ||||||
|  | } | ||||||
|  | export const PHASE = Object.values(MAP_PHASE) | ||||||
|  |  | ||||||
| export class RdDInitiative { | export class RdDInitiative { | ||||||
|  |  | ||||||
|   static calculInitiative(niveau, caracValue, bonus = 0) { |   static getRollInitiative(caracValue, niveau, bonus = 0) { | ||||||
|     let base = niveau + Math.floor(caracValue / 2) + bonus; |     const base = RdDInitiative.ajustementInitiative(caracValue, niveau, bonus) | ||||||
|     return "1d6" + (base >= 0 ? "+" : "") + base; |     return "1d6" + (base >= 0 ? "+" : "") + base | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static ajustementInitiative(caracValue, niveau, bonus) { | ||||||
|  |     return niveau + Math.floor(caracValue / 2) + bonus | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static formule(phase, carac, niveau, bonusMalus) { | ||||||
|  |     const ajustement = RdDInitiative.ajustementInitiative(carac, niveau, bonusMalus) | ||||||
|  |     return { phase, ajustement } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static phaseArme(categorie, arme) { | ||||||
|  |     switch (categorie) { | ||||||
|  |       case "tir": | ||||||
|  |       case "lancer": | ||||||
|  |         return MAP_PHASE[categorie] | ||||||
|  |       default: | ||||||
|  |         switch (arme.system.cac) { | ||||||
|  |           case "empoignade": | ||||||
|  |           case "pugilat": | ||||||
|  |           case "naturelle": | ||||||
|  |             return MAP_PHASE[arme.system.cac] | ||||||
|  |           default: | ||||||
|  |             return MAP_PHASE['arme'] | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static phase(keyOrRang) { | ||||||
|  |     return MAP_PHASE[keyOrRang] ?? PHASE.find(it => it.rang == keyOrRang) ?? MAP_PHASE.autre | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async roll(formule) { | ||||||
|  |     const sign = formule.ajustement >= 0 ? "+" : "" | ||||||
|  |     const roll = new Roll(`1d6 + ${sign} + ${formule.ajustement}`) | ||||||
|  |     await roll.evaluate() | ||||||
|  |     const value = Math.max(roll.total, 0) | ||||||
|  |     return { | ||||||
|  |       roll: roll, | ||||||
|  |       value: value, | ||||||
|  |       rang: formule.phase.rang, | ||||||
|  |       init: formule.phase.rang + value / 100, | ||||||
|  |       label: formule.phase.label | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| }  | }  | ||||||
|   | |||||||
| @@ -10,15 +10,15 @@ export class RdDItemCompetenceCreature extends RdDItem { | |||||||
|  |  | ||||||
|   static get defaultIcon() { return "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp" } |   static get defaultIcon() { return "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp" } | ||||||
|  |  | ||||||
|  |   isAttaque() { return this.getCategorieAttaque() != undefined } | ||||||
|   isParade() { return this.system.iscombat && (this.system.categorie_parade ?? '') != '' } |   isParade() { return this.system.iscombat && (this.system.categorie_parade ?? '') != '' } | ||||||
|   isBouclier() { return this.system.categorie_parade.includes('bouclier') } |   isBouclier() { return this.system.categorie_parade.includes('bouclier') } | ||||||
|  |  | ||||||
|   attaqueCreature() { |   attaqueCreature() { | ||||||
|     const categorieAttaque = this.getCategorieAttaque() |     const categorieAttaque = this.getCategorieAttaque() | ||||||
|     if (categorieAttaque != undefined) { |     if (categorieAttaque != undefined) { | ||||||
|       const initative = RdDInitiative.calculInitiative(this.system.niveau, this.system.carac_value); |       const initative = RdDInitiative.getRollInitiative(this.system.carac_value, this.system.niveau); | ||||||
|       const attaque = { |       const attaque = { | ||||||
|         name: this.name, |         label: this.name, | ||||||
|         action: this.isCompetencePossession() ? 'possession' : 'attaque', |         action: this.isCompetencePossession() ? 'possession' : 'attaque', | ||||||
|         initOnly: false, |         initOnly: false, | ||||||
|         arme: new RdDItemArme({ |         arme: new RdDItemArme({ | ||||||
| @@ -32,6 +32,7 @@ export class RdDItemCompetenceCreature extends RdDItem { | |||||||
|             initiative: initative, |             initiative: initative, | ||||||
|             mortalite: this.system.mortalite, |             mortalite: this.system.mortalite, | ||||||
|             dommages: this.system.dommages, |             dommages: this.system.dommages, | ||||||
|  |             forceRequise: 0, | ||||||
|             equipe: true, |             equipe: true, | ||||||
|             resistance: 100, |             resistance: 100, | ||||||
|             penetration: 0, |             penetration: 0, | ||||||
| @@ -43,7 +44,8 @@ export class RdDItemCompetenceCreature extends RdDItem { | |||||||
|         carac: { key: this.name, value: this.system.carac_value }, |         carac: { key: this.name, value: this.system.carac_value }, | ||||||
|         equipe: true, |         equipe: true, | ||||||
|         mortalite: this.system.mortalite, |         mortalite: this.system.mortalite, | ||||||
|         dmg: this.system.dommages, |         dommages: this.system.dommages, | ||||||
|  |         //dmg: this.system.dommages, | ||||||
|         initiative: initative |         initiative: initative | ||||||
|       }; |       }; | ||||||
|       return attaque |       return attaque | ||||||
| @@ -51,10 +53,6 @@ export class RdDItemCompetenceCreature extends RdDItem { | |||||||
|     return undefined; |     return undefined; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isAttaque() { |  | ||||||
|     return this.getCategorieAttaque() != undefined |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   getCategorieAttaque() { |   getCategorieAttaque() { | ||||||
|     switch (this.system.categorie) { |     switch (this.system.categorie) { | ||||||
|       case "melee": |       case "melee": | ||||||
|   | |||||||
| @@ -260,7 +260,7 @@ export class RdDItemSheetV1 extends foundry.appv1.sheets.ItemSheet { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   /** @override */ |   /** @override */ | ||||||
|   _updateObject(event, formData) { |   async _updateObject(event, formData) { | ||||||
|     switch (this.item.type) { |     switch (this.item.type) { | ||||||
|       case ITEM_TYPES.sort: |       case ITEM_TYPES.sort: | ||||||
|         formData['system.bonuscase'] = RdDItemSort.bonuscasesToString(RdDItemSheetV1._listCaseTmr( |         formData['system.bonuscase'] = RdDItemSort.bonuscasesToString(RdDItemSheetV1._listCaseTmr( | ||||||
| @@ -273,8 +273,7 @@ export class RdDItemSheetV1 extends foundry.appv1.sheets.ItemSheet { | |||||||
|         formData['system.niveau'] = formData['system.niveau'] ?? formData['system.base'] |         formData['system.niveau'] = formData['system.niveau'] ?? formData['system.base'] | ||||||
|         break |         break | ||||||
|     } |     } | ||||||
|  |     return await super._updateObject(event, formData) | ||||||
|     return this.item.update(formData) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -148,10 +148,17 @@ export class RdDItemSort extends Item { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static incrementBonusCase(actor, sort, coord) { |   static incrementBonusCase(actor, sort, coord) { | ||||||
|  |     let bonuscase = RdDItemSort.calculBonuscase(sort, coord) | ||||||
|  |  | ||||||
|  |     actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'system.bonuscase': bonuscase }]); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   static calculBonuscase(sort, coord) { | ||||||
|     if (TMRUtility.isFleuve(coord)) { |     if (TMRUtility.isFleuve(coord)) { | ||||||
|       coord = FLEUVE_COORD; |       coord = FLEUVE_COORD | ||||||
|     } |     } | ||||||
|     let list = RdDItemSort.stringToBonuscases(sort.system.bonuscase); |     let list = RdDItemSort.stringToBonuscases(sort.system.bonuscase) | ||||||
|     const existing = list.find(it => it.case == coord) |     const existing = list.find(it => it.case == coord) | ||||||
|     const bonus = Number(existing?.bonus ?? 0) + 1 |     const bonus = Number(existing?.bonus ?? 0) + 1 | ||||||
|     if (existing) { |     if (existing) { | ||||||
| @@ -160,11 +167,9 @@ export class RdDItemSort extends Item { | |||||||
|     else { |     else { | ||||||
|       list.push({ case: coord, bonus: 1 }) |       list.push({ case: coord, bonus: 1 }) | ||||||
|     } |     } | ||||||
|  |     return RdDItemSort.bonuscasesToString(list) | ||||||
|     actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'system.bonuscase': RdDItemSort.bonuscasesToString(list) }]); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static getCaseBonus(sort, coord) { |   static getCaseBonus(sort, coord) { | ||||||
|     const search = TMRUtility.isFleuve(coord) |     const search = TMRUtility.isFleuve(coord) | ||||||
| @@ -189,4 +194,22 @@ export class RdDItemSort extends Item { | |||||||
|       .map(it => it.split(':')) |       .map(it => it.split(':')) | ||||||
|       .map(it => { return { case: it[0], bonus: it[1] } }); |       .map(it => { return { case: it[0], bonus: it[1] } }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static prepareSortEnReserve(sort, draconic, ptreve, coord) { | ||||||
|  |     return { | ||||||
|  |       type: ITEM_TYPES.sortreserve, | ||||||
|  |       name: sort.name, | ||||||
|  |       img: sort.img, | ||||||
|  |       system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' } | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static prepareSortAddLancement(sort, reveSort) { | ||||||
|  |     const precedents = sort.system.lancements ?? [] | ||||||
|  |     const lancements = [...precedents, { | ||||||
|  |       timestamp: game.system.rdd.calendrier.getTimestamp(), | ||||||
|  |       reve: reveSort | ||||||
|  |     }] | ||||||
|  |     return lancements | ||||||
|  |   } | ||||||
| } | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { ITEM_TYPES } from "./constants.js"; | import { ITEM_TYPES, RDD_CONFIG, renderTemplate } from "./constants.js"; | ||||||
| import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES, CATEGORIES_COMPETENCES_CREATURES } from "./item/base-items.js"; | import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES, CATEGORIES_COMPETENCES_CREATURES } from "./item/base-items.js"; | ||||||
| import { ITEM_ACTIONS, DEFAULT_ACTIONS, COMMON_ACTIONS } from "./item/item-actions.js"; | import { ITEM_ACTIONS, DEFAULT_ACTIONS, COMMON_ACTIONS } from "./item/item-actions.js"; | ||||||
|  |  | ||||||
| @@ -629,7 +629,7 @@ export class RdDItem extends Item { | |||||||
|   _armeChatData() { |   _armeChatData() { | ||||||
|     return [ |     return [ | ||||||
|       `<b>Compétence</b>: ${this.system.competence}`, |       `<b>Compétence</b>: ${this.system.competence}`, | ||||||
|       `<b>Dommages</b>: ${this.system.dommages} ${this.system.mortalite == 'non-mortel' ? '(Non mortel)' : ''}`, |       `<b>Dommages</b>: ${this.system.dommages} ${this.system.mortalite == RDD_CONFIG.encaissement.nonmortel ? '(Non mortel)' : ''}`, | ||||||
|       `<b>Force minimum</b>: ${this.system.force}`, |       `<b>Force minimum</b>: ${this.system.force}`, | ||||||
|       `<b>Resistance</b>: ${this.system.resistance}`, |       `<b>Resistance</b>: ${this.system.resistance}`, | ||||||
|       ...this._inventaireTemplateChatData() |       ...this._inventaireTemplateChatData() | ||||||
|   | |||||||
| @@ -1,9 +1,10 @@ | |||||||
| import { ITEM_TYPES } from "../constants.js"; | import { ITEM_TYPES, RDD_CONFIG } from "../constants.js"; | ||||||
| import { RdDItem } from "../item.js"; | import { RdDItem } from "../item.js"; | ||||||
| import { BASE_CORPS_A_CORPS } from "./base-items.js"; | import { BASE_CORPS_A_CORPS } from "./base-items.js"; | ||||||
| import { Grammar } from "../grammar.js"; | import { Grammar } from "../grammar.js"; | ||||||
| import { RdDInitiative } from "../initiative.mjs"; | import { RdDInitiative } from "../initiative.mjs"; | ||||||
| import { MappingCreatureArme } from "./mapping-creature-arme.mjs"; | import { MappingCreatureArme } from "./mapping-creature-arme.mjs"; | ||||||
|  | import { Misc } from "../misc.js"; | ||||||
|  |  | ||||||
| const nomCategorieParade = { | const nomCategorieParade = { | ||||||
|   "sans-armes": "Sans arme", |   "sans-armes": "Sans arme", | ||||||
| @@ -21,10 +22,16 @@ const nomCategorieParade = { | |||||||
| export const ATTAQUE_TYPE = { | export const ATTAQUE_TYPE = { | ||||||
|   UNE_MAIN: '(1 main)', |   UNE_MAIN: '(1 main)', | ||||||
|   DEUX_MAINS: '(2 mains)', |   DEUX_MAINS: '(2 mains)', | ||||||
|  |   CORPS_A_CORPS: '(corps à corps)', | ||||||
|   COMPETENCE: 'competence', |   COMPETENCE: 'competence', | ||||||
|   TIR: '(tir)', |   TIR: '(tir)', | ||||||
|   LANCER: '(lancer)' |   LANCER: '(lancer)' | ||||||
| } | } | ||||||
|  | export const ATTAQUE_TYPE_MELEE = [ATTAQUE_TYPE.UNE_MAIN, ATTAQUE_TYPE.DEUX_MAINS, ATTAQUE_TYPE.CORPS_A_CORPS] | ||||||
|  |  | ||||||
|  | export const CORPS_A_CORPS = 'Corps à corps' | ||||||
|  | export const PUGILAT = 'pugilat' | ||||||
|  | export const EMPOIGNADE = RDD_CONFIG.encaissement.empoignade | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RdDItemArme extends RdDItem { | export class RdDItemArme extends RdDItem { | ||||||
| @@ -62,7 +69,7 @@ export class RdDItemArme extends RdDItem { | |||||||
|       case ITEM_TYPES.competencecreature: |       case ITEM_TYPES.competencecreature: | ||||||
|         return MappingCreatureArme.armeCreature(arme); |         return MappingCreatureArme.armeCreature(arme); | ||||||
|     } |     } | ||||||
|     return RdDItemArme.corpsACorps(); |     return RdDItemArme.pugilat(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getCompetenceArme(arme, maniement) { |   static getCompetenceArme(arme, maniement) { | ||||||
| @@ -76,6 +83,7 @@ export class RdDItemArme extends RdDItem { | |||||||
|           case ATTAQUE_TYPE.DEUX_MAINS: return arme.competence2Mains() |           case ATTAQUE_TYPE.DEUX_MAINS: return arme.competence2Mains() | ||||||
|           case ATTAQUE_TYPE.TIR: case 'tir': return arme.system.tir |           case ATTAQUE_TYPE.TIR: case 'tir': return arme.system.tir | ||||||
|           case ATTAQUE_TYPE.LANCER: case 'lancer': return arme.system.lancer; |           case ATTAQUE_TYPE.LANCER: case 'lancer': return arme.system.lancer; | ||||||
|  |           case ATTAQUE_TYPE.CORPS_A_CORPS: return CORPS_A_CORPS | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
| @@ -244,47 +252,49 @@ export class RdDItemArme extends RdDItem { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   isAttaque() { |   isAttaque() { | ||||||
|     return this.system.resistance > 0 || this.system.portee_courte > 0 |     return this.system.resistance > 0 || (this.system.tir != '' && this.system.portee_courte > 0) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static corpsACorps(actor) { |   isEmpoignade() { | ||||||
|     let competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS |     return this.system.mortalite == RDD_CONFIG.encaissement.empoignade | ||||||
|     let melee = actor ? actor.system.carac['melee'].value : 0 |   } | ||||||
|  |  | ||||||
|  |   isUtilisableEmpoigne() { | ||||||
|  |     return this.system.baseInit == 3 || this.system.baseInit == 4 || this.system.competence == "Dague" | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static pugilat(actor) { | ||||||
|  |     return RdDItemArme.$corpsACorps(actor, 'Pugilat', PUGILAT) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static empoignade(actor) { | ||||||
|  |     return RdDItemArme.$corpsACorps(actor, 'Empoignade', RDD_CONFIG.encaissement.empoignade) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $corpsACorps(actor, name, cac) { | ||||||
|  |     const competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS | ||||||
|  |     const melee = actor ? actor.system.carac['melee'].value : 0 | ||||||
|     return new RdDItemArme({ |     return new RdDItemArme({ | ||||||
|       _id: competence.id, |       _id: Misc.fakeId(cac), | ||||||
|       name: 'Corps à corps', |       name: name, | ||||||
|       type: ITEM_TYPES.arme, |       type: ITEM_TYPES.arme, | ||||||
|       img: competence.img, |       img: competence.img, | ||||||
|       system: { |       system: { | ||||||
|         initiative: RdDInitiative.calculInitiative(competence.system.niveau, melee), |         initiative: RdDInitiative.getRollInitiative(melee, competence.system.niveau), | ||||||
|         equipe: true, |         equipe: true, | ||||||
|         rapide: true, |         rapide: true, | ||||||
|         force: 0, |         force: 0, | ||||||
|         dommages: "0", |         dommages: "0", | ||||||
|         dommagesReels: 0, |         dommagesReels: 0, | ||||||
|         mortalite: 'non-mortel', |         mortalite: cac == RDD_CONFIG.encaissement.empoignade ? RDD_CONFIG.encaissement.empoignade : RDD_CONFIG.encaissement.nonmortel, | ||||||
|         competence: 'Corps à corps', |         competence: CORPS_A_CORPS, | ||||||
|         resistance: 1, |         resistance: 1, | ||||||
|         baseInit: 4, |         baseInit: cac == RDD_CONFIG.encaissement.empoignade ? 3 : 4, | ||||||
|         cac: 'pugilat', |         cac: cac, | ||||||
|         deuxmains: true, |         deuxmains: true, | ||||||
|         categorie_parade: 'sans-armes' |         categorie_parade: 'sans-armes' | ||||||
|       } |       } | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static mainsNues(actor) { |  | ||||||
|     const mainsNues = RdDItemArme.corpsACorps(actor) |  | ||||||
|     mainsNues.name = 'Mains nues' |  | ||||||
|     return mainsNues; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static empoignade(actor) { |  | ||||||
|     const empoignade = RdDItemArme.corpsACorps(actor) |  | ||||||
|     empoignade.name = 'Empoignade' |  | ||||||
|     empoignade.system.cac = 'empoignade' |  | ||||||
|     empoignade.system.baseInit = 3 |  | ||||||
|     empoignade.system.mortalite = 'empoignade' |  | ||||||
|     return empoignade |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -71,21 +71,25 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|     return 0 |     return 0 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async createBlessure(actor, gravite, localisation = '', attackerToken) { |   static async createBlessure(actor, gravite, localisation = '', attackerToken = undefined) { | ||||||
|     const definition = RdDItemBlessure.getDefinition(gravite) |     const blessure = RdDItemBlessure.prepareBlessure(gravite, localisation, attackerToken); | ||||||
|     const blessure = { |     const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) | ||||||
|  |     return blessures[0] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static prepareBlessure(gravite, localisation, attackerToken) { | ||||||
|  |     const definition = RdDItemBlessure.getDefinition(gravite); | ||||||
|  |     return { | ||||||
|       name: definition.label, |       name: definition.label, | ||||||
|       type: 'blessure', |       type: 'blessure', | ||||||
|       img: definition.icon, |       img: definition.icon, | ||||||
|       system: { |       system: { | ||||||
|         gravite: gravite, |         gravite: gravite, | ||||||
|         difficulte: - gravite, |         difficulte: -gravite, | ||||||
|         localisation: localisation, |         localisation: localisation, | ||||||
|         origine: attackerToken?.name ?? "" |         origine: attackerToken?.name ?? "" | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) |  | ||||||
|     return blessures[0] |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async createTacheSoinBlessure(actor, gravite) { |   static async createTacheSoinBlessure(actor, gravite) { | ||||||
| @@ -209,6 +213,9 @@ export class RdDItemBlessure extends RdDItem { | |||||||
|   isCritique() { |   isCritique() { | ||||||
|     return this.system.gravite > 4 && this.system.gravite <= 6 |     return this.system.gravite > 4 && this.system.gravite <= 6 | ||||||
|   } |   } | ||||||
|  |   isBleeding() { | ||||||
|  |     return this.system.gravite > 2 && !this.system.premierssoins.done | ||||||
|  |   } | ||||||
|   isMort() { |   isMort() { | ||||||
|     return this.system.gravite > 6 |     return this.system.gravite > 6 | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ import { RdDInitiative } from "../initiative.mjs"; | |||||||
|  |  | ||||||
| export class MappingCreatureArme { | export class MappingCreatureArme { | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static setRollDataCreature(rollData) { |   static setRollDataCreature(rollData) { | ||||||
|     const code = Grammar.toLowerCaseNoAccentNoSpace(rollData.competence.name); |     const code = Grammar.toLowerCaseNoAccentNoSpace(rollData.competence.name); | ||||||
| @@ -26,7 +25,7 @@ export class MappingCreatureArme { | |||||||
|           competence: item.name, |           competence: item.name, | ||||||
|           cac: categorieAttaque == "naturelle" ? "naturelle" : "", |           cac: categorieAttaque == "naturelle" ? "naturelle" : "", | ||||||
|           niveau: item.system.niveau, |           niveau: item.system.niveau, | ||||||
|           initiative: RdDInitiative.calculInitiative(item.system.niveau, item.system.carac_value), |           initiative: RdDInitiative.getRollInitiative(item.system.carac_value, item.system.niveau), | ||||||
|           equipe: true, |           equipe: true, | ||||||
|           resistance: 100, |           resistance: 100, | ||||||
|           dommagesReels: item.system.dommages, |           dommagesReels: item.system.dommages, | ||||||
|   | |||||||
| @@ -6,8 +6,8 @@ const tableEffets = [ | |||||||
|   { code: "passeur", resultat: "succes", description: "Déplacer le demi-rêve à (force) cases", method: EffetsRencontre.passeur}, |   { code: "passeur", resultat: "succes", description: "Déplacer le demi-rêve à (force) cases", method: EffetsRencontre.passeur}, | ||||||
|   { code: "reve+f", resultat: "succes", description: "Gain de (force) points de rêve" , method: EffetsRencontre.reve_plus_force}, |   { code: "reve+f", resultat: "succes", description: "Gain de (force) points de rêve" , method: EffetsRencontre.reve_plus_force}, | ||||||
|   { code: "teleport", resultat: "succes", description: "Déplacer le demi-rêve (même type)", method: EffetsRencontre.teleportation_typecase }, |   { code: "teleport", resultat: "succes", description: "Déplacer le demi-rêve (même type)", method: EffetsRencontre.teleportation_typecase }, | ||||||
|   { code: "part+tete", resultat: "succes", description: "Tête de dragon sur réussite particulière", method: EffetsRencontre.rdd_part_tete }, |   { code: "part+tete", resultat: "succes", description: "Tête de dragon sur particulière", method: EffetsRencontre.rdd_part_tete }, | ||||||
|   { code: "part+xp", resultat: "succes", description: "Expérience sur réussite particulière", method: EffetsRencontre.experience_particuliere }, |   { code: "part+xp", resultat: "succes", description: "Expérience sur particulière", method: EffetsRencontre.experience_particuliere }, | ||||||
|   { code: "seuil", resultat: "succes", description: "Récupération de seuil de rêve", method: EffetsRencontre.regain_seuil }, |   { code: "seuil", resultat: "succes", description: "Récupération de seuil de rêve", method: EffetsRencontre.regain_seuil }, | ||||||
|  |  | ||||||
|   { code: "reve-1", resultat: "echec", description: "Perte de 1 point de rêve", method: EffetsRencontre.reve_moins_1 }, |   { code: "reve-1", resultat: "echec", description: "Perte de 1 point de rêve", method: EffetsRencontre.reve_moins_1 }, | ||||||
| @@ -19,7 +19,7 @@ const tableEffets = [ | |||||||
|   { code: "aleatoire", resultat: "echec", description: "Déplacement aléatoire", method: EffetsRencontre.deplacement_aleatoire }, |   { code: "aleatoire", resultat: "echec", description: "Déplacement aléatoire", method: EffetsRencontre.deplacement_aleatoire }, | ||||||
|   { code: "sort-aleatoire", resultat: "echec", description: "Déclenche un sort en réserve aléatoire", method: EffetsRencontre.sort_aleatoire }, |   { code: "sort-aleatoire", resultat: "echec", description: "Déclenche un sort en réserve aléatoire", method: EffetsRencontre.sort_aleatoire }, | ||||||
|   { code: "rompu", resultat: "echec", description: "Demi-rêve interrompu", method: EffetsRencontre.demireve_rompu }, |   { code: "rompu", resultat: "echec", description: "Demi-rêve interrompu", method: EffetsRencontre.demireve_rompu }, | ||||||
|   { code: "echec-queue", resultat: "echec", description: "Queue(s) de dragon sur échec", method: EffetsRencontre.rdd_echec_queue }, |   { code: "echec-queue", resultat: "echec", description: "Queue(s) de dragon", method: EffetsRencontre.rdd_echec_queue }, | ||||||
|  |  | ||||||
|   { code: "reve+1", resultat: "succes", description: "Gain de 1 point de rêve", method: EffetsRencontre.reve_plus_1 }, |   { code: "reve+1", resultat: "succes", description: "Gain de 1 point de rêve", method: EffetsRencontre.reve_plus_1 }, | ||||||
|   { code: "vie-f", resultat: "echec", description: "Perte de (force) points de vie", method: EffetsRencontre.vie_moins_force }, |   { code: "vie-f", resultat: "echec", description: "Perte de (force) points de vie", method: EffetsRencontre.vie_moins_force }, | ||||||
|   | |||||||
| @@ -34,9 +34,13 @@ export class Misc { | |||||||
|     return ((n % m) + m) % m; |     return ((n % m) + m) % m; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static inRange(value, min,max){ |   static inRange(value, min, max) { | ||||||
|  |     if (min > max) { | ||||||
|  |       return Misc.inRange(value, max, min) | ||||||
|  |     } | ||||||
|     return Math.max(min, Math.min(value, max)) |     return Math.max(min, Math.min(value, max)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static sum() { |   static sum() { | ||||||
|     return (a, b) => Number(a) + Number(b); |     return (a, b) => Number(a) + Number(b); | ||||||
|   } |   } | ||||||
| @@ -61,6 +65,10 @@ export class Misc { | |||||||
|     return 0; |     return 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static fakeId(base) { | ||||||
|  |     return (base + foundry.utils.randomID(16)).substring(0, 16) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static typeName(type, subType) { |   static typeName(type, subType) { | ||||||
|     return subType ? game.i18n.localize(`TYPES.${type}.${subType}`) |     return subType ? game.i18n.localize(`TYPES.${type}.${subType}`) | ||||||
|       : ''; |       : ''; | ||||||
| @@ -111,6 +119,10 @@ export class Misc { | |||||||
|     list.forEach(it => addToObj(obj, it)) |     list.forEach(it => addToObj(obj, it)) | ||||||
|     return obj; |     return obj; | ||||||
|   } |   } | ||||||
|  |   static indexed(list, index = 'index') { | ||||||
|  |     let i = 0; | ||||||
|  |     return list.map(it => { it[index] = i++; return it }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static concat(lists) { |   static concat(lists) { | ||||||
|     return lists.reduce((a, b) => a.concat(b), []); |     return lists.reduce((a, b) => a.concat(b), []); | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { RDD_CONFIG } from "./constants.js"; | ||||||
| import { RdDItemArme } from "./item/arme.js"; | import { RdDItemArme } from "./item/arme.js"; | ||||||
| import { RdDPossession } from "./rdd-possession.js"; | import { RdDPossession } from "./rdd-possession.js"; | ||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||||
| @@ -35,7 +36,7 @@ export class RdDBonus { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static dmg(rollData, actor, isEntiteIncarnee = false) { |   static dmg(rollData, actor) { | ||||||
|     const diff = rollData.diffLibre; |     const diff = rollData.diffLibre; | ||||||
|     const dmgArme = RdDBonus.dmgArme(rollData.arme, rollData.arme?.system.dommagesReels) |     const dmgArme = RdDBonus.dmgArme(rollData.arme, rollData.arme?.system.dommagesReels) | ||||||
|     const forceRequise = rollData.arme ? RdDItemArme.valeurMain(rollData.arme.system.force ?? 0, RdDItemArme.getMainAttaque(rollData.competence)) : 0 |     const forceRequise = rollData.arme ? RdDItemArme.valeurMain(rollData.arme.system.force ?? 0, RdDItemArme.getMainAttaque(rollData.competence)) : 0 | ||||||
| @@ -47,33 +48,33 @@ export class RdDBonus { | |||||||
|       penetration: RdDBonus._peneration(rollData), |       penetration: RdDBonus._peneration(rollData), | ||||||
|       dmgTactique: RdDBonus.dmgBonus(rollData.tactique), |       dmgTactique: RdDBonus.dmgBonus(rollData.tactique), | ||||||
|       dmgParticuliere: RdDBonus._dmgParticuliere(rollData), |       dmgParticuliere: RdDBonus._dmgParticuliere(rollData), | ||||||
|       dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used), |       dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris?.used), | ||||||
|       mortalite: RdDBonus._calculMortalite(rollData, isEntiteIncarnee), |       mortalite: RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite), | ||||||
|       dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme), |       dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme), | ||||||
|       dmgForceInsuffisante: Math.min(0, actor.getForce() - forceRequise) |       dmgForceInsuffisante: Math.min(0, actor.getForce() - forceRequise) | ||||||
|     } |     } | ||||||
|     dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante |     dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante | ||||||
|     return dmg; |     return dmg | ||||||
|   } |   } | ||||||
|    |  | ||||||
|   static dmgRollV2(rollData, current) { |   static dmgRollV2(rollData, attaque) { | ||||||
|     const actor = rollData.active.actor |     const actor = rollData.active.actor | ||||||
|     const attaque = current.attaque |  | ||||||
|     const arme = attaque.arme |     const arme = attaque.arme | ||||||
|     const dmgArme = RdDBonus.dmgArme(arme, attaque.dommagesArme) |     const dmgArme = RdDBonus.dmgArme(arme, attaque.dommages) | ||||||
|     const dmg = { |     const dmg = { | ||||||
|       total: 0, |       total: 0, | ||||||
|       dmgArme: dmgArme, |       dmgArme: dmgArme, | ||||||
|       penetration: arme.penetration(), |       penetration: arme?.penetration() ?? 0, | ||||||
|       diff: attaque.diff, |       diff: attaque.diff, | ||||||
|       dmgTactique: current.tactique?.dmg ?? 0, |       dmgTactique: attaque.tactique?.dmg ?? 0, | ||||||
|       dmgParticuliere: 0, // TODO RdDBonus._dmgParticuliere(rollData), |       dmgParticuliere: RdDBonus._dmgParticuliere(rollData), | ||||||
|       dmgSurprise: rollData.opponent?.surprise?.dmg ?? 0, |       dmgSurprise: rollData.opponent?.surprise?.dmg ?? 0, | ||||||
|       mortalite: RdDBonus.mortalite(current.dmg?.mortalite, arme.system.mortalite, rollData.opponent?.actor?.isEntite()), |       mortalite: RdDBonus.mortalite(attaque.dmg?.mortalite, arme?.system.mortalite), | ||||||
|       dmgActor: RdDBonus.bonusDmg(actor, attaque.carac.key, dmgArme, attaque.forceRequise), |       dmgActor: RdDBonus.bonusDmg(actor, attaque.carac.key, dmgArme, attaque.forceRequise), | ||||||
|       dmgForceInsuffisante: Math.min(0, actor.getForce() - attaque.forceRequise), |       dmgForceInsuffisante: Math.min(0, actor.getForce() - (attaque.forceRequise ?? 0)), | ||||||
|       dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0 |       dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0 | ||||||
|     } |     } | ||||||
|  |     dmg.isEmpoignade = dmg.mortalite == RDD_CONFIG.encaissement.empoignade | ||||||
|     dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante + dmg.dmgDiffLibre |     dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante + dmg.dmgDiffLibre | ||||||
|     return dmg |     return dmg | ||||||
|   } |   } | ||||||
| @@ -94,21 +95,14 @@ export class RdDBonus { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static _calculMortalite(rollData, isEntiteIncarnee) { |   static mortalite(mortaliteSelect, mortaliteArme) { | ||||||
|     return RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite, isEntiteIncarnee) |     return mortaliteSelect ?? mortaliteArme ?? RDD_CONFIG.encaissement.mortel | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static mortalite(mortaliteSelect, mortaliteArme, isEntiteIncarnee) { |  | ||||||
|     return isEntiteIncarnee ? "entiteincarnee" |  | ||||||
|       : mortaliteSelect |  | ||||||
|       ?? mortaliteArme |  | ||||||
|       ?? "mortel"; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static dmgArme(arme, dommagesMain) { |   static dmgArme(arme, dommages) { | ||||||
|     if (arme) { |     if (arme) { | ||||||
|       let dmgBase = dommagesMain ?? Number(arme.system.dommages ?? 0); |       let dmgBase = dommages ?? Number(arme.system.dommages ?? 0); | ||||||
|       //Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278) |       //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); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| 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 { HIDE_DICE, renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDBonus } from "./rdd-bonus.js"; | import { RdDBonus } from "./rdd-bonus.js"; | ||||||
| @@ -10,15 +10,15 @@ import { ReglesOptionnelles } from "./settings/regles-optionnelles.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 { EMPOIGNADE, RdDItemArme } from "./item/arme.js"; | ||||||
| import { RdDItemCompetence } from "./item-competence.js"; | import { RdDItemCompetence } from "./item-competence.js"; | ||||||
| import { RdDInitiative } from "./initiative.mjs"; | import { MAP_PHASE, RdDInitiative } from "./initiative.mjs"; | ||||||
| import RollDialog from "./roll/roll-dialog.mjs"; | import RollDialog from "./roll/roll-dialog.mjs"; | ||||||
| import { PART_DEFENSE } from "./roll/roll-part-defense.mjs"; | import { PART_DEFENSE } from "./roll/roll-part-defense.mjs"; | ||||||
| import { RollDialogAdapter } from "./roll/roll-dialog-adapter.mjs"; |  | ||||||
| import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs"; | import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs"; | ||||||
| import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js"; | import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js"; | ||||||
| import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs"; | import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs"; | ||||||
|  | import { RollBasicParts } from "./roll/roll-basic-parts.mjs"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| const premierRoundInit = [ | const premierRoundInit = [ | ||||||
| @@ -56,6 +56,12 @@ export class RdDCombatManager extends Combat { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   static getCombatant(actorId, tokenId) { | ||||||
|  |     return game.combat.combatants.find(it => it.actor.id == actorId && | ||||||
|  |       it.token.id == tokenId | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async nextRound() { |   async nextRound() { | ||||||
|     await this.finDeRound(); |     await this.finDeRound(); | ||||||
| @@ -67,7 +73,7 @@ export class RdDCombatManager extends Combat { | |||||||
|     if (Misc.isFirstConnectedGM()) { |     if (Misc.isFirstConnectedGM()) { | ||||||
|       await this.finDeRound({ terminer: true }) |       await this.finDeRound({ terminer: true }) | ||||||
|       ChatUtility.removeChatMessageContaining(`<div data-combatid="${this.id}" data-combatmessage="actor-turn-summary">`) |       ChatUtility.removeChatMessageContaining(`<div data-combatid="${this.id}" data-combatmessage="actor-turn-summary">`) | ||||||
|       game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined) |       game.messages.filter(m => ChatUtility.getMessageData(m, 'rollData') != undefined && ChatUtility.getMessageData(m, 'rollData') != undefined) | ||||||
|         .forEach(it => it.delete()) |         .forEach(it => it.delete()) | ||||||
|       RdDEmpoignade.deleteAllEmpoignades() |       RdDEmpoignade.deleteAllEmpoignades() | ||||||
|     } |     } | ||||||
| @@ -106,14 +112,18 @@ export class RdDCombatManager extends Combat { | |||||||
|     return combatant.actor |     return combatant.actor | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static calculAjustementInit(actor, arme) { |   static bonusArme(arme) { | ||||||
|     const efficacite = (arme?.system.magique) ? arme.system.ecaille_efficacite : 0 |     return (arme?.system.magique) ? arme.system.ecaille_efficacite : 0 | ||||||
|     const etatGeneral = actor.getEtatGeneral() ?? 0 |  | ||||||
|     return efficacite + etatGeneral |  | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /************************************************************************************/ |   static etatGeneral(actor) { | ||||||
|  |     return actor.getEtatGeneral() ?? 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /** *********************************************************************************** | ||||||
|  |    * @override lance l'initiative de plusieurs combattants (tous/ous les PNJs) en une fois | ||||||
|  |    */ | ||||||
|   async rollInitiative(ids, messageOptions = {}) { |   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 | ||||||
| @@ -121,18 +131,17 @@ export class RdDCombatManager extends Combat { | |||||||
|     return this |     return this | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async rollInitRdD(id, formula, messageOptions = {}) { |   async rollInitRdD(id, formule, messageOptions = {}) { | ||||||
|     const combatant = this.combatants.get(id); |     const combatant = this.combatants.get(id); | ||||||
|     const actor = RdDCombatManager.getActorCombatant(combatant) |     const actor = RdDCombatManager.getActorCombatant(combatant) | ||||||
|     if (actor) { |     if (actor) { | ||||||
|       const rollFormula = formula ?? RdDCombatManager.getFirstInitRollFormula(actor) |       formule = formule ?? RdDCombatManager.getFirstInitRollFormula(actor) | ||||||
|       const roll = combatant.getInitiativeRoll(rollFormula); |       const init = await RdDInitiative.roll(formule) | ||||||
|       if (!roll.total) { |  | ||||||
|         await roll.evaluate(); |       await this.updateEmbeddedDocuments("Combatant", [{ | ||||||
|       } |         _id: combatant._id || combatant.id, | ||||||
|       const total = Math.max(roll.total, 0.00); |         initiative: init.init, 'system.init': init | ||||||
|       console.log("Compute init for", rollFormula, roll, total, combatant); |       }]) | ||||||
|       await this.updateEmbeddedDocuments("Combatant", [{ _id: combatant._id || combatant.id, initiative: total }]); |  | ||||||
|  |  | ||||||
|       // Send a chat message |       // Send a chat message | ||||||
|       let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode"); |       let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode"); | ||||||
| @@ -144,10 +153,10 @@ export class RdDCombatManager extends Combat { | |||||||
|           alias: combatant.token?.name, |           alias: combatant.token?.name, | ||||||
|           sound: CONFIG.sounds.dice, |           sound: CONFIG.sounds.dice, | ||||||
|         }, |         }, | ||||||
|         flavor: `${combatant.token?.name} a fait son jet d'Initiative (${messageOptions.info})<br>` |         flavor: `${combatant.token?.name} a une initiatyive de ${init.value} : ${messageOptions.info}<br>` | ||||||
|       }, |       }, | ||||||
|         messageOptions); |         messageOptions); | ||||||
|       roll.toMessage(messageData, { rollMode, create: true }); |       init.roll.toMessage(messageData, { rollMode, create: true }); | ||||||
|  |  | ||||||
|       RdDCombatManager.processPremierRoundInit(); |       RdDCombatManager.processPremierRoundInit(); | ||||||
|     } |     } | ||||||
| @@ -159,16 +168,11 @@ export class RdDCombatManager extends Combat { | |||||||
|     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) | ||||||
|       const ajustement = RdDCombatManager.calculAjustementInit(actor, action) |       const ajustement = RdDCombatManager.bonusArme(action.arme) + RdDCombatManager.etatGeneral(actor) | ||||||
|       return RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement); |       return RdDInitiative.formule(init.phase, init.carac, init.niveau, ajustement); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     let ajustement = RdDCombatManager.calculAjustementInit(actor, undefined); |     return RdDInitiative.formule(MAP_PHASE['autre'], 10, 0, actor.getEtatGeneral() ?? 0); | ||||||
|     return RdDCombatManager.formuleInitiative(2, 10, 0, ajustement); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static formuleInitiative(rang, carac, niveau, bonusMalus) { |  | ||||||
|     return `${rang} +( (${RdDInitiative.calculInitiative(niveau, carac, bonusMalus)} )/100)`; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -180,7 +184,6 @@ export class RdDCombatManager extends Combat { | |||||||
|         for (let combatant of game.combat.combatants) { |         for (let combatant of game.combat.combatants) { | ||||||
|           if (combatant.initiativeData?.arme?.type == "arme") { |           if (combatant.initiativeData?.arme?.type == "arme") { | ||||||
|             // TODO: get init data premier round |             // TODO: get init data premier round | ||||||
|             const initiativeData = combatant.initiativeData; |  | ||||||
|             const action = combatant.initiativeData.arme; |             const action = combatant.initiativeData.arme; | ||||||
|             const fromArme = Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround) |             const fromArme = Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround) | ||||||
|             const initData = premierRoundInit.find(it => fromArme.includes(initData.pattern)) |             const initData = premierRoundInit.find(it => fromArme.includes(initData.pattern)) | ||||||
| @@ -200,10 +203,27 @@ export class RdDCombatManager extends Combat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static incDecInit(combatantId, incDecValue) { |  | ||||||
|     const combatant = game.combat.combatants.get(combatantId); |   static applyInitiativeCommand(combatantId, command, commandValue) { | ||||||
|     let initValue = combatant.initiative + incDecValue; |     switch (command) { | ||||||
|     game.combat.setInitiative(combatantId, initValue); |       case 'delta': return RdDCombatManager.incDecInit(combatantId, commandValue); | ||||||
|  |       case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId, | ||||||
|  |         { name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async incDecInit(combatantId, incDecValue) { | ||||||
|  |     const combatant = game.combat.combatants.get(combatantId) | ||||||
|  |     if (combatant?.initiative && incDecValue != 0) { | ||||||
|  |       const value = combatant.system.init.value + incDecValue | ||||||
|  |       const newInit = combatant.initiative + incDecValue / 100; | ||||||
|  |       await game.combat.updateEmbeddedDocuments("Combatant", [{ | ||||||
|  |         _id: combatantId, | ||||||
|  |         initiative: newInit, | ||||||
|  |         'system.init.value': value, | ||||||
|  |         'system.init.init': newInit, | ||||||
|  |       }]) | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -220,56 +240,42 @@ export class RdDCombatManager extends Combat { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     options = [ |     options = [ | ||||||
|       { name: "Incrémenter initiative", condition: true, icon: '<i class="fa-solid fa-plus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +0.01); } }, |       { name: "Incrémenter initiative", condition: true, icon: '<i class="fa-solid fa-plus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +1); } }, | ||||||
|       { name: "Décrémenter initiative", condition: true, icon: '<i class="fa-solid fa-minus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -0.01); } } |       { name: "Décrémenter initiative", condition: true, icon: '<i class="fa-solid fa-minus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -1); } } | ||||||
|     ].concat(options); |     ].concat(options); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async 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 [] } |  | ||||||
|  |  | ||||||
|     combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0 |     if (actor == undefined) { return } | ||||||
|  |  | ||||||
|     const init = RdDCombatManager.getInitData(actor, action) |     const init = RdDCombatManager.getInitData(actor, action) | ||||||
|     const ajustement = RdDCombatManager.calculAjustementInit(actor, action.arme) |     const ajustement = RdDCombatManager.bonusArme(actor, action.arme) + RdDCombatManager.etatGeneral(actor) | ||||||
|     const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement); |     const formule = RdDInitiative.formule(init.phase, init.carac, init.niveau, ajustement); | ||||||
|  |  | ||||||
|     await game.combat.rollInitRdD(combatantId, rollFormula, init); |     await game.combat.rollInitRdD(combatantId, formule, init); | ||||||
|     combatant.initiativeData |     combatant.initiativeData = { action, formule } // pour reclasser l'init au round 0 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static getInitData(actor, action) { |   static getInitData(actor, action) { | ||||||
|     if (actor.getSurprise() == "totale") { return { offset: -1, info: "Surprise Totale", carac: 0, niveau: 0 } } |     if (actor.getSurprise() == "totale") { return { phase: MAP_PHASE['totale'], info: "Surprise Totale", carac: 0, niveau: 0 } } | ||||||
|     if (actor.getSurprise() == "demi") { return { offset: 0, info: "Demi Surprise", carac: 0, niveau: 0 } } |     if (actor.getSurprise() == "demi") { return { phase: MAP_PHASE['demi'], info: "Demi Surprise", carac: 0, niveau: 0 } } | ||||||
|     if (action.action == 'autre') { return { offset: 2, info: "Autre Action", carac: 0, niveau: 0 } } |     if (action.action == 'autre') { return { phase: MAP_PHASE['autre'], info: "Autre Action", carac: 0, niveau: 0 } } | ||||||
|     if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } } |     if (action.action == 'possession') { return { phase: MAP_PHASE['possession'], 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 { phase: MAP_PHASE['draconic'], info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } } | ||||||
|  |  | ||||||
|     const comp = action.comp |     const comp = action.comp | ||||||
|     return { |     return { | ||||||
|       offset: RdDCombatManager.initOffset(comp?.system.categorie, action.arme), |       phase: RdDInitiative.phaseArme(comp?.system.categorie, action.arme), | ||||||
|       info: action.name + " / " + comp.name, |       info: action.label, | ||||||
|       carac: actor.getCaracInit(comp), |       carac: actor.getCaracInit(comp), | ||||||
|       niveau: comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(action.main) ? -8 : -6) |       niveau: comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(action.main) ? -8 : -6) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static initOffset(categorie, arme) { |  | ||||||
|     switch (categorie) { |  | ||||||
|       case "tir": return 8 |  | ||||||
|       case "lancer": return 7 |  | ||||||
|       default: |  | ||||||
|         switch (arme.system.cac) { |  | ||||||
|           case "empoignade": return 3 |  | ||||||
|           case "pugilat": return 4 |  | ||||||
|           case "naturelle": return 4 |  | ||||||
|           default: return 5 |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static displayInitiativeMenu(html, combatantId) { |   static displayInitiativeMenu(html, combatantId) { | ||||||
|     const combatant = game.combat.combatants.get(combatantId) |     const combatant = game.combat.combatants.get(combatantId) | ||||||
| @@ -297,13 +303,8 @@ export class RdDCombatManager extends Combat { | |||||||
|       ? possessions |       ? possessions | ||||||
|       : actor.listActions({ isEquipe: true }) |       : actor.listActions({ isEquipe: true }) | ||||||
|  |  | ||||||
|     for (let index = 0; index < actions.length; index++) { |     return Misc.indexed(actions) | ||||||
|       actions[index].index = index |  | ||||||
|     } |  | ||||||
|     return actions |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| @@ -383,8 +384,13 @@ export class RdDCombat { | |||||||
|     let defenderToken = canvas.tokens.get(msg.defenderToken.id) |     let defenderToken = canvas.tokens.get(msg.defenderToken.id) | ||||||
|     if (defenderToken && Misc.isFirstConnectedGM()) { |     if (defenderToken && Misc.isFirstConnectedGM()) { | ||||||
|       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id) |       const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id) | ||||||
|       rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme) |       rddCombat?.removeChatMessageActionsPasseArme(msg.paramChatDefense.attackerRoll.passeArme) | ||||||
|       rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll) |       if (msg.defenderRoll.v2) {/* TODO: delete roll V1 */ | ||||||
|  |         RollDialog.loadRollData(msg.paramChatDefense) | ||||||
|  |         rddCombat?._chatMessageDefenseV2(msg.paramChatDefense) | ||||||
|  |       } else { | ||||||
|  |         rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll) | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -402,7 +408,6 @@ export class RdDCombat { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static registerChatCallbacks(html) { |   static registerChatCallbacks(html) { | ||||||
|     for (let button of [ |     for (let button of [ | ||||||
|       '.button-defense', |  | ||||||
|       '.button-parade', |       '.button-parade', | ||||||
|       '.button-esquive', |       '.button-esquive', | ||||||
|       '.button-encaisser', |       '.button-encaisser', | ||||||
| @@ -464,8 +469,8 @@ export class RdDCombat { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onEvent(button, event) { |   async onEvent(button, event) { | ||||||
|     const chatMessage = ChatUtility.getChatMessage(event); |     const chatMessage = ChatUtility.getChatMessage(event); | ||||||
|     const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll'); |     const defenderRoll = ChatUtility.getMessageData(chatMessage, 'rollData'); | ||||||
|     const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll'); |     const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'rollData'); | ||||||
|     console.log('RdDCombat', attackerRoll, defenderRoll); |     console.log('RdDCombat', attackerRoll, defenderRoll); | ||||||
|  |  | ||||||
|     const armeParadeId = event.currentTarget.attributes['data-armeid']?.value; |     const armeParadeId = event.currentTarget.attributes['data-armeid']?.value; | ||||||
| @@ -474,8 +479,6 @@ export class RdDCombat { | |||||||
|  |  | ||||||
|     switch (button) { |     switch (button) { | ||||||
|       case '.particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); |       case '.particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); | ||||||
|       case '.button-defense': return this.defenseV2(attackerRoll); |  | ||||||
|  |  | ||||||
|       case '.button-parade': return this.parade(attackerRoll, armeParadeId); |       case '.button-parade': return this.parade(attackerRoll, armeParadeId); | ||||||
|       case '.button-esquive': return this.esquive(attackerRoll, compId, competence); |       case '.button-esquive': return this.esquive(attackerRoll, compId, competence); | ||||||
|       case '.button-encaisser': return this.encaisser(attackerRoll, defenderRoll); |       case '.button-encaisser': return this.encaisser(attackerRoll, defenderRoll); | ||||||
| @@ -560,7 +563,7 @@ export class RdDCombat { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static isEchecTotal(rollData) { |   static isEchecTotal(rollData) { | ||||||
|     if (rollData.ids /* roll V2*/) { |     if (rollData.v2 /* roll V2*/) { | ||||||
|       // TODO: en cas de demi-surprise à l'attaque, tout échec est un echec total. |       // TODO: en cas de demi-surprise à l'attaque, tout échec est un echec total. | ||||||
|       // TODO: en cas de demi-surprise en défense, pas de changement à la règle de base |       // TODO: en cas de demi-surprise en défense, pas de changement à la règle de base | ||||||
|       return rollData.rolled.isETotal |       return rollData.rolled.isETotal | ||||||
| @@ -574,7 +577,7 @@ export class RdDCombat { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static isParticuliere(rollData) { |   static isParticuliere(rollData) { | ||||||
|     if (rollData.ids /* roll V2*/) { |     if (rollData.v2 /* roll V2*/) { | ||||||
|       return rollData.rolled.isPart |       return rollData.rolled.isPart | ||||||
|     } |     } | ||||||
|     if (rollData.attackerRoll || !rollData.ajustements.surprise.used) { |     if (rollData.attackerRoll || !rollData.ajustements.surprise.used) { | ||||||
| @@ -585,7 +588,7 @@ export class RdDCombat { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static isReussite(rollData) { |   static isReussite(rollData) { | ||||||
|     if (rollData.ids /* roll V2*/) { |     if (rollData.v2 /* roll V2*/) { | ||||||
|       return rollData.rolled.isSuccess |       return rollData.rolled.isSuccess | ||||||
|     } |     } | ||||||
|     if (!rollData.ajustements.surprise.used) { |     if (!rollData.ajustements.surprise.used) { | ||||||
| @@ -601,7 +604,7 @@ export class RdDCombat { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async proposerAjustementTirLancer(rollData) { |   async proposerAjustementTirLancer(rollData) { | ||||||
|     if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) { |     if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) { | ||||||
|       if (this.defender.isEntite([ENTITE_BLURETTE])) { |       if (this.defender.isEntiteBlurette()) { | ||||||
|         ChatMessage.create({ |         ChatMessage.create({ | ||||||
|           content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`, |           content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`, | ||||||
|           whisper: ChatUtility.getGMs() |           whisper: ChatUtility.getGMs() | ||||||
| @@ -665,12 +668,95 @@ export class RdDCombat { | |||||||
|     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 }; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   async attaqueV2() { | ||||||
|  |     if (!await this.attacker.accorder(this.defender, 'avant-attaque')) { | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |     await this.doRollAttaque({ | ||||||
|  |       ids: { | ||||||
|  |         actorId: this.attackerId, | ||||||
|  |         actorTokenId: this.attackerTokenId, | ||||||
|  |         opponentId: this.defender.id, | ||||||
|  |         opponentTokenId: this.defenderTokenId, | ||||||
|  |       }, | ||||||
|  |       type: { allowed: ['attaque'], current: 'attaque' }, | ||||||
|  |       passeArme: foundry.utils.randomID(16), | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async doRollAttaque(rollData, callbacks = []) { | ||||||
|  |     // TODO V2 await this.proposerAjustementTirLancer(rollData) | ||||||
|  |     await RollDialog.create(rollData, { | ||||||
|  |       onRollDone: RollDialog.onRollDoneClose, | ||||||
|  |       callbacks: [ | ||||||
|  |         async (roll) => await this.onAttaqueV2(roll), | ||||||
|  |         ...callbacks | ||||||
|  |       ] | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async onAttaqueV2(attackerRoll) { | ||||||
|  |     if (!this.defender || !attackerRoll.rolled.isSuccess || attackerRoll.particulieres?.length > 1) { | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |     if (!await this.attacker.accorder(this.defender, 'avant-defense')) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     RollDialog.loadRollData(attackerRoll) | ||||||
|  |  | ||||||
|  |     const surpriseDefender = this.defender.getSurprise(true); | ||||||
|  |     const paramChatDefense = { | ||||||
|  |       attackerRoll: attackerRoll, | ||||||
|  |       isPossession: this.isPossession(attackerRoll), | ||||||
|  |       defender: this.defender, | ||||||
|  |       attacker: this.attacker, | ||||||
|  |       attackerId: this.attackerId, | ||||||
|  |       attackerToken: this.attackerToken, | ||||||
|  |       defenderToken: this.defenderToken, | ||||||
|  |       surprise: surpriseDefender, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (Misc.isFirstConnectedGM()) { | ||||||
|  |       await this._chatMessageDefenseV2(paramChatDefense); | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       this._socketSendMessageDefense(paramChatDefense, {}); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   async _chatMessageDefenseV2(paramDemandeDefense) { | ||||||
|  |     const attackerRoll = paramDemandeDefense.attackerRoll; | ||||||
|  |     RollBasicParts.loadSurprises(attackerRoll) | ||||||
|  |     attackerRoll.dmg = RdDBonus.dmgRollV2(attackerRoll, attackerRoll.current.attaque) | ||||||
|  |  | ||||||
|  |     const defenseData = RollBasicParts.prepareDefense(attackerRoll) | ||||||
|  |  | ||||||
|  |     const choixDefense = await ChatMessage.create({ | ||||||
|  |       // message privé: du défenseur à lui même (et aux GMs) | ||||||
|  |       speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), | ||||||
|  |       alias: this.attacker?.getAlias(), | ||||||
|  |       whisper: ChatUtility.getOwners(this.defender), | ||||||
|  |       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', defenseData) | ||||||
|  |     }); | ||||||
|  |     // flag pour garder les jets d'attaque/defense | ||||||
|  |     ChatUtility.setMessageData(choixDefense, 'demande-defense', true) | ||||||
|  |     ChatUtility.setMessageData(choixDefense, 'rollData', { | ||||||
|  |       ids: defenseData.ids, | ||||||
|  |       attackerRoll: RollDialog.saveParts(attackerRoll), | ||||||
|  |       passeArme: defenseData.passeArme | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async attaque(competence, arme) { |   async attaque(competence, arme) { | ||||||
|     if (!await this.attacker.accorder(this.defender, 'avant-attaque')) { |     if (!await this.attacker.accorder(this.defender, 'avant-attaque')) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     if (arme.system.cac == 'empoignade') { |     if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|  |       return this.attacker.rollCompetence(competence.name, { arme: arme }) | ||||||
|  |     } | ||||||
|  |     if (arme.system.cac == EMPOIGNADE) { | ||||||
|       RdDEmpoignade.onAttaqueEmpoignade(this.attacker, this.defender) |       RdDEmpoignade.onAttaqueEmpoignade(this.attacker, this.defender) | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
| @@ -714,7 +800,7 @@ export class RdDCombat { | |||||||
|       essais: {} |       essais: {} | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (this.attacker.isCreatureEntite()) { |     if (this.attacker.isCreatureOuEntite()) { | ||||||
|       MappingCreatureArme.setRollDataCreature(rollData); |       MappingCreatureArme.setRollDataCreature(rollData); | ||||||
|     } |     } | ||||||
|     else if (arme) { |     else if (arme) { | ||||||
| @@ -723,9 +809,9 @@ export class RdDCombat { | |||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       // sans armes: à mains nues |       // sans armes: à mains nues | ||||||
|       rollData.arme = RdDItemArme.corpsACorps(this.attacker) |       rollData.arme = RdDItemArme.pugilat(this.attacker) | ||||||
|       rollData.arme.system.niveau = competence.system.niveau |       rollData.arme.system.niveau = competence.system.niveau | ||||||
|       rollData.arme.system.initiative = RdDInitiative.calculInitiative(competence.system.niveau, this.attacker.system.carac['melee'].value); |       rollData.arme.system.initiative = RdDInitiative.getRollInitiative(this.attacker.system.carac['melee'].value, competence.system.niveau); | ||||||
|     } |     } | ||||||
|     return rollData; |     return rollData; | ||||||
|   } |   } | ||||||
| @@ -776,14 +862,14 @@ export class RdDCombat { | |||||||
|         passeArme: rollData.passeArme |         passeArme: rollData.passeArme | ||||||
|       }) |       }) | ||||||
|     }); |     }); | ||||||
|     ChatUtility.setMessageData(choixParticuliere, 'attacker-roll', rollData); |     ChatUtility.setMessageData(choixParticuliere, 'rollData', rollData); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async _onAttaqueNormale(attackerRoll) { |   async _onAttaqueNormale(attackerRoll) { | ||||||
|     console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll); |     console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll); | ||||||
|  |  | ||||||
|     attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); |     attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker); | ||||||
|     let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } |     let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } | ||||||
|     attackerRoll.show = { |     attackerRoll.show = { | ||||||
|       cible: this.defender?.getAlias() ?? 'la cible', |       cible: this.defender?.getAlias() ?? 'la cible', | ||||||
| @@ -802,7 +888,10 @@ export class RdDCombat { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   isPossession(attackerRoll) { |   isPossession(attackerRoll) { | ||||||
|     return attackerRoll.selectedCarac.label.toLowerCase() == 'possession'; |     const carac = attackerRoll.v2 | ||||||
|  |       ? attackerRoll.current.carac?.label | ||||||
|  |       : attackerRoll.selectedCarac.label | ||||||
|  |     return carac?.toLowerCase() == 'possession'; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -852,10 +941,10 @@ export class RdDCombat { | |||||||
|       speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), |       speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), | ||||||
|       alias: this.attacker?.getAlias(), |       alias: this.attacker?.getAlias(), | ||||||
|       whisper: ChatUtility.getOwners(this.defender), |       whisper: ChatUtility.getOwners(this.defender), | ||||||
|       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', paramDemandeDefense), |       content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense-v1.hbs', paramDemandeDefense), | ||||||
|     }); |     }); | ||||||
|     // flag pour garder les jets d'attaque/defense |     // flag pour garder les jets d'attaque/defense | ||||||
|     ChatUtility.setMessageData(choixDefense, 'defender-roll', defenderRoll); |     ChatUtility.setMessageData(choixDefense, 'rollData', defenderRoll); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -869,7 +958,7 @@ export class RdDCombat { | |||||||
|         defenderToken: this.defenderToken, |         defenderToken: this.defenderToken, | ||||||
|         defenderRoll: defenderRoll, |         defenderRoll: defenderRoll, | ||||||
|         paramChatDefense: paramChatDefense, |         paramChatDefense: paramChatDefense, | ||||||
|         rollMode: true |         rollMode: true, | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| @@ -906,7 +995,7 @@ export class RdDCombat { | |||||||
|         essais: attackerRoll.essais |         essais: attackerRoll.essais | ||||||
|       }) |       }) | ||||||
|     }); |     }); | ||||||
|     ChatUtility.setMessageData(choixEchecTotal, 'attacker-roll', attackerRoll); |     ChatUtility.setMessageData(choixEchecTotal, 'rollData', attackerRoll); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -966,8 +1055,9 @@ export class RdDCombat { | |||||||
|     dialog.render(true); |     dialog.render(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async defenseV2(attackerRoll) { |   async defenseV2(attackerRoll, callbacks = []) { | ||||||
|     // this._prepareParade(attackerRoll, arme, competence); |     // this._prepareParade(attackerRoll, arme, competence); | ||||||
|  |     RollDialog.loadRollData(attackerRoll) | ||||||
|     await this.doRollDefense({ |     await this.doRollDefense({ | ||||||
|       ids: { |       ids: { | ||||||
|         actorId: this.defender.id, |         actorId: this.defender.id, | ||||||
| @@ -975,19 +1065,15 @@ export class RdDCombat { | |||||||
|         opponentTokenId: this.attackerTokenId, |         opponentTokenId: this.attackerTokenId, | ||||||
|         opponentId: this.attackerId, |         opponentId: this.attackerId, | ||||||
|       }, |       }, | ||||||
|       type: { allowed: ['defense'], current: 'defense' }, |       type: { allowed: [ROLL_TYPE_DEFENSE], current: ROLL_TYPE_DEFENSE }, | ||||||
|       attackerRoll: RollDialogAdapter.mapActionAttaque(attackerRoll), |       attackerRoll: attackerRoll, | ||||||
|       passeArme: attackerRoll.passeArme, |       passeArme: attackerRoll.passeArme, | ||||||
|     }) |     }, callbacks) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async doRollDefense(rollData, callbacks = []) { |   async doRollDefense(rollData, callbacks = []) { | ||||||
|     await RollDialog.create(rollData, { |     await RollDialog.create(rollData, { | ||||||
|       onRollDone: (dialog) => { |       onRollDone: RollDialog.onRollDoneClose, | ||||||
|         if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST)) |  | ||||||
|           dialog.close() |  | ||||||
|       }, |  | ||||||
|       customChatMessage: true, |  | ||||||
|       callbacks: [ |       callbacks: [ | ||||||
|         async (roll) => { |         async (roll) => { | ||||||
|           this.removeChatMessageActionsPasseArme(roll.passeArme); |           this.removeChatMessageActionsPasseArme(roll.passeArme); | ||||||
| @@ -1021,7 +1107,7 @@ export class RdDCombat { | |||||||
|       show: {} |       show: {} | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (this.defender.isCreatureEntite()) { |     if (this.defender.isCreatureOuEntite()) { | ||||||
|       MappingCreatureArme.setRollDataCreature(defenderRoll); |       MappingCreatureArme.setRollDataCreature(defenderRoll); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -1034,22 +1120,17 @@ export class RdDCombat { | |||||||
|     if (RdDCombat.isReussite(rollData)) { |     if (RdDCombat.isReussite(rollData)) { | ||||||
|       if (isParade) { |       if (isParade) { | ||||||
|         await this.computeDeteriorationArme(rollData) |         await this.computeDeteriorationArme(rollData) | ||||||
|  |         if (RdDCombat.isParticuliere(rollData)) { | ||||||
|  |           await this.infoAttaquantDesarme(rollData) | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (RdDCombat.isParticuliere(rollData)) { |  | ||||||
|         await this._onDefenseParticuliere(rollData, isEsquive) |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     this.removeChatMessageActionsPasseArme(rollData.passeArme) |     this.removeChatMessageActionsPasseArme(rollData.passeArme) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async _onDefenseParticuliere(rollData, isEsquive) { |   async infoAttaquantDesarme(rollData) { | ||||||
|     if (isEsquive) { |     if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) { | ||||||
|       ChatUtility.createChatWithRollMode( |  | ||||||
|         { content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" }, |  | ||||||
|         this.defender) |  | ||||||
|     } |  | ||||||
|     else if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) { |  | ||||||
|       // TODO: attaquant doit jouer résistance et peut être désarmé p132 |       // TODO: attaquant doit jouer résistance et peut être désarmé p132 | ||||||
|       ChatUtility.createChatWithRollMode( |       ChatUtility.createChatWithRollMode( | ||||||
|         { content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` }, |         { content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` }, | ||||||
| @@ -1153,7 +1234,7 @@ export class RdDCombat { | |||||||
|       show: {} |       show: {} | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (this.defender.isCreatureEntite()) { |     if (this.defender.isCreatureOuEntite()) { | ||||||
|       MappingCreatureArme.setRollDataCreature(rollData); |       MappingCreatureArme.setRollDataCreature(rollData); | ||||||
|     } |     } | ||||||
|     return rollData; |     return rollData; | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ import { TMRUtility } from "./tmr-utility.js"; | |||||||
| import { DialogFatigueVoyage } from "./voyage/dialog-fatigue-voyage.js"; | import { DialogFatigueVoyage } from "./voyage/dialog-fatigue-voyage.js"; | ||||||
| import { ChatUtility } from "./chat-utility.js"; | import { ChatUtility } from "./chat-utility.js"; | ||||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | import { RdDRollResult } from "./rdd-roll-result.js"; | ||||||
|  | import { renderTemplate } from "./constants.js"; | ||||||
|  |  | ||||||
| const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/; | const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/; | ||||||
|  |  | ||||||
| @@ -460,12 +461,7 @@ export class RdDCommands { | |||||||
|  |  | ||||||
|   async supprimerSignesDraconiquesEphemeres() { |   async supprimerSignesDraconiquesEphemeres() { | ||||||
|     if (game.user.isGM) { |     if (game.user.isGM) { | ||||||
|       game.actors.forEach(actor => { |       game.actors.forEach(actor => actor.supprimerSignesDraconiques(it => it.system.ephemere)) | ||||||
|         const ephemeres = actor.items.filter(item => item.type = 'signedraconique' && item.system.ephemere); |  | ||||||
|         if (ephemeres.length > 0) { |  | ||||||
|           actor.deleteEmbeddedDocuments("Item", ephemeres.map(item => item.id)); |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       ui.notifications.warn("Seul le MJ est autorisé à utiliser la commande /signe"); |       ui.notifications.warn("Seul le MJ est autorisé à utiliser la commande /signe"); | ||||||
|   | |||||||
| @@ -1,9 +1,11 @@ | |||||||
| import { STATUSES } from "./settings/status-effects.js"; | import { STATUSES } from "./settings/status-effects.js"; | ||||||
| import { ITEM_TYPES } from "./constants.js"; | import { ITEM_TYPES, renderTemplate } from "./constants.js"; | ||||||
| import { ChatUtility } from "./chat-utility.js"; | import { ChatUtility } from "./chat-utility.js"; | ||||||
| import { RdDRollResult } from "./rdd-roll-result.js"; | import { RdDRollResult } from "./rdd-roll-result.js"; | ||||||
| import { RdDRoll } from "./rdd-roll.js"; | import { RdDRoll } from "./rdd-roll.js"; | ||||||
| import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs"; | import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs"; | ||||||
|  | import { MAP_PHASE } from "./initiative.mjs"; | ||||||
|  | import { RdDCombatManager } from "./rdd-combat.js"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RdDEmpoignade { | export class RdDEmpoignade { | ||||||
| @@ -12,6 +14,49 @@ export class RdDEmpoignade { | |||||||
|   static init() { |   static init() { | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   static isCombatantEmpoignade(actorId, tokenId) { | ||||||
|  |     const combatant = RdDCombatManager.getCombatant(actorId, tokenId) | ||||||
|  |     return MAP_PHASE.empoignade.rang == combatant?.system.init.rang | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async ajustementEmpoignade(attacker, defender, adjust = 1) { | ||||||
|  |     const empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||||
|  |     const empId = empoignade?.system.empoignadeid ?? foundry.utils.randomID(16) | ||||||
|  |     if (empoignade) { | ||||||
|  |       if (empoignade.system.empoigneurid == defender.id) { | ||||||
|  |         adjust = - adjust | ||||||
|  |       } | ||||||
|  |       empoignade.system.pointsemp += adjust | ||||||
|  |       await RdDEmpoignade.$updateEtatEmpoignade(empoignade, attacker, defender) | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       await RdDEmpoignade.$createEtatEmpoignade({ | ||||||
|  |         name: `Empoignade de ${attacker.name} sur ${defender.name}`, | ||||||
|  |         type: ITEM_TYPES.empoignade, | ||||||
|  |         system: { | ||||||
|  |           description: "", | ||||||
|  |           empoignadeid: empId, | ||||||
|  |           empoigneurid: attacker.id, | ||||||
|  |           empoigneid: defender.id, | ||||||
|  |           pointsemp: adjust, | ||||||
|  |           empoigneurname: attacker.name, | ||||||
|  |           empoignename: defender.name | ||||||
|  |         } | ||||||
|  |       }, attacker, defender) | ||||||
|  |     } | ||||||
|  |     const result = RdDEmpoignade.getEmpoignadeById(defender, empId); | ||||||
|  |     const defGrappled = result.system.pointsemp == (result.system.empoigneid == defender.id ? 2 : -2) | ||||||
|  |     const attGrappled = result.system.pointsemp == (result.system.empoigneurid == attacker.id ? -2 : 2) | ||||||
|  |     const grappling = Math.abs(result.system.pointsemp) > 0 | ||||||
|  |     await defender.setEffect(STATUSES.StatusGrappling, grappling && !defGrappled) | ||||||
|  |     await attacker.setEffect(STATUSES.StatusGrappling, grappling && !attGrappled) | ||||||
|  |     await defender.setEffect(STATUSES.StatusGrappled, defGrappled) | ||||||
|  |     await attacker.setEffect(STATUSES.StatusGrappled, attGrappled) | ||||||
|  |     return result | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static registerChatCallbacks(html) { |   static registerChatCallbacks(html) { | ||||||
|     $(html).on("click", '.defense-empoignade-cac', event => { |     $(html).on("click", '.defense-empoignade-cac', event => { | ||||||
| @@ -184,7 +229,7 @@ export class RdDEmpoignade { | |||||||
|       selectedCarac: attacker.system.carac.melee, |       selectedCarac: attacker.system.carac.melee, | ||||||
|       malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender) |       malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender) | ||||||
|     } |     } | ||||||
|     if (attacker.isCreatureEntite()) { |     if (attacker.isCreatureOuEntite()) { | ||||||
|       MappingCreatureArme.setRollDataCreature(rollData) |       MappingCreatureArme.setRollDataCreature(rollData) | ||||||
|     } |     } | ||||||
|     if (empoignade.system.pointsemp >= 2) { |     if (empoignade.system.pointsemp >= 2) { | ||||||
| @@ -237,10 +282,7 @@ export class RdDEmpoignade { | |||||||
|  |  | ||||||
|  |  | ||||||
|     if (rollData.rolled.isSuccess && isNouvelle) { |     if (rollData.rolled.isSuccess && isNouvelle) { | ||||||
|       const objectEmpoignade = rollData.empoignade.toObject(); |       RdDEmpoignade.$createEtatEmpoignade(rollData.empoignade) | ||||||
|       // Creer l'empoignade sur attaquant/defenseur |  | ||||||
|       attacker.creerObjetParMJ(objectEmpoignade); |  | ||||||
|       defender.creerObjetParMJ(objectEmpoignade); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     rollData.empoignade.isSuccess = rollData.rolled.isSuccess; |     rollData.empoignade.isSuccess = rollData.rolled.isSuccess; | ||||||
| @@ -259,7 +301,7 @@ export class RdDEmpoignade { | |||||||
|       return |       return | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     let empoignade = this.getEmpoignade(attacker, defender) |     let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||||
|  |  | ||||||
|     if (!empoignade) { |     if (!empoignade) { | ||||||
|       ui.notifications.warn("Une erreur s'est produite : Aucune empoignade trouvée !!") |       ui.notifications.warn("Une erreur s'est produite : Aucune empoignade trouvée !!") | ||||||
| @@ -317,18 +359,33 @@ export class RdDEmpoignade { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async $updateEtatEmpoignade(empoignade) { |   static async $createEtatEmpoignade(empoignade) { | ||||||
|     console.log("UPDATE Empoignade", empoignade) |     console.log("CREATE Empoignade", empoignade) | ||||||
|  |  | ||||||
|     let defender = game.actors.get(empoignade.system.empoigneid) |     let defender = game.actors.get(empoignade.system.empoigneid) | ||||||
|     let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid) |  | ||||||
|     let update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol } |  | ||||||
|     await defender.updateEmbeddedDocuments('Item', [update]) |  | ||||||
|  |  | ||||||
|     let attacker = game.actors.get(empoignade.system.empoigneurid) |     let attacker = game.actors.get(empoignade.system.empoigneurid) | ||||||
|     emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid) |  | ||||||
|     update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol } |     // Creer l'empoignade sur attaquant/defenseur | ||||||
|     await attacker.updateEmbeddedDocuments('Item', [update]) |     await attacker.creerObjetParMJ(empoignade) | ||||||
|  |     await defender.creerObjetParMJ(empoignade) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   static async $updateEtatEmpoignade(empoignade, attacker, defender) { | ||||||
|  |     console.log("UPDATE Empoignade", empoignade) | ||||||
|  |     const belligerants = [ | ||||||
|  |       attacker ?? game.actors.get(empoignade.system.empoigneurid), | ||||||
|  |       defender ?? game.actors.get(empoignade.system.empoigneid)] | ||||||
|  |  | ||||||
|  |     await Promise.all( | ||||||
|  |       belligerants.map(async belligerant => { | ||||||
|  |         const emp = RdDEmpoignade.getEmpoignadeById(belligerant, empoignade.system.empoignadeid) | ||||||
|  |         return await belligerant.updateEmbeddedDocuments('Item', [{ | ||||||
|  |           _id: emp._id, | ||||||
|  |           "system.pointsemp": empoignade.system.pointsemp, | ||||||
|  |           "system.ausol": empoignade.system.ausol | ||||||
|  |         }]) | ||||||
|  |       })) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
| @@ -347,7 +404,7 @@ export class RdDEmpoignade { | |||||||
|     if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { |     if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     let empoignade = this.getEmpoignade(attacker, defender) |     let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||||
|  |  | ||||||
|     empoignade.system.ausol = true |     empoignade.system.ausol = true | ||||||
|     await this.$updateEtatEmpoignade(empoignade) |     await this.$updateEtatEmpoignade(empoignade) | ||||||
| @@ -366,7 +423,7 @@ export class RdDEmpoignade { | |||||||
|     if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { |     if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     let empoignade = this.getEmpoignade(attacker, defender) |     let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||||
|  |  | ||||||
|     await defender.setEffect(STATUSES.StatusProne, true); |     await defender.setEffect(STATUSES.StatusProne, true); | ||||||
|     await this.$deleteEmpoignade(empoignade) |     await this.$deleteEmpoignade(empoignade) | ||||||
| @@ -382,7 +439,7 @@ export class RdDEmpoignade { | |||||||
|     if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { |     if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     let empoignade = this.getEmpoignade(attacker, defender) |     let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) | ||||||
|  |  | ||||||
|     //console.log("Perte d'endurance :!!!", perteMode) |     //console.log("Perte d'endurance :!!!", perteMode) | ||||||
|     let endValue = defender.system.sante.endurance.value |     let endValue = defender.system.sante.endurance.value | ||||||
| @@ -423,9 +480,17 @@ export class RdDEmpoignade { | |||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async createEmpoignade(attacker, defender) { |   static async createEmpoignade(attacker, defender) { | ||||||
|     return await Item.create({ |     return await Item.create({ | ||||||
|       name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name, |       name: "Empoignade de " + attacker.name + ' sur ' + defender.name, | ||||||
|       type: 'empoignade', |       type: ITEM_TYPES.empoignade, | ||||||
|       system: { description: "", empoignadeid: foundry.utils.randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name } |       system: { | ||||||
|  |         description: "", | ||||||
|  |         empoignadeid: foundry.utils.randomID(16), | ||||||
|  |         empoigneurid: attacker.id, | ||||||
|  |         empoigneid: defender.id, | ||||||
|  |         pointsemp: 0, | ||||||
|  |         empoigneurname: attacker.name, | ||||||
|  |         empoignename: defender.name | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|       { |       { | ||||||
|         temporary: true |         temporary: true | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { ATTAQUE_TYPE, RdDItemArme } from "./item/arme.js"; | import { ATTAQUE_TYPE, EMPOIGNADE, PUGILAT, RdDItemArme } from "./item/arme.js"; | ||||||
| import { ITEM_TYPES } from "./constants.js"; | import { ITEM_TYPES } from "./constants.js"; | ||||||
|  |  | ||||||
| export class RdDHotbar { | export class RdDHotbar { | ||||||
| @@ -28,8 +28,8 @@ export class RdDHotbar { | |||||||
|         return ' ' + maniement |         return ' ' + maniement | ||||||
|       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 '' | ||||||
|   } |   } | ||||||
| @@ -63,8 +63,8 @@ export class RdDHotbar { | |||||||
|       case ITEM_TYPES.competence: |       case ITEM_TYPES.competence: | ||||||
|         await this.createItemMacro(item, slot++, 'competence') |         await this.createItemMacro(item, slot++, 'competence') | ||||||
|         if (item.isCorpsACorps()) { |         if (item.isCorpsACorps()) { | ||||||
|           await this.createItemMacro(item, slot++, 'pugilat') |           await this.createItemMacro(item, slot++, PUGILAT) | ||||||
|           await this.createItemMacro(item, slot++, 'empoignade') |           await this.createItemMacro(item, slot++, EMPOIGNADE) | ||||||
|         } |         } | ||||||
|         else if (item.isCompetenceArme()) { |         else if (item.isCompetenceArme()) { | ||||||
|           ui.notifications.info(`${item.name} est une compétence d'arme, la macro n'est pas liée à un arme.<br> |           ui.notifications.info(`${item.name} est une compétence d'arme, la macro n'est pas liée à un arme.<br> | ||||||
| @@ -121,9 +121,9 @@ export class RdDHotbar { | |||||||
|       case ITEM_TYPES.competence: |       case ITEM_TYPES.competence: | ||||||
|         if (item.isCorpsACorps()) { |         if (item.isCorpsACorps()) { | ||||||
|           switch (categorieArme) { |           switch (categorieArme) { | ||||||
|             case 'pugilat': |             case PUGILAT: | ||||||
|               return actor.rollArme(RdDItemArme.corpsACorps(actor)); |               return actor.rollArme(RdDItemArme.pugilat(actor)); | ||||||
|             case 'empoignade': |             case EMPOIGNADE: | ||||||
|               return actor.rollArme(RdDItemArme.empoignade(actor)); |               return actor.rollArme(RdDItemArme.empoignade(actor)); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { ChatUtility } from "./chat-utility.js" | import { ChatUtility } from "./chat-utility.js" | ||||||
|  | import { renderTemplate } from "./constants.js" | ||||||
|  |  | ||||||
| const vents = [ | const vents = [ | ||||||
|   { min: 0, max: 0, valeur: 'Calme' }, |   { min: 0, max: 0, valeur: 'Calme' }, | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| import { RdDBaseActor } from "./actor/base-actor.js"; | import { RdDBaseActor } from "./actor/base-actor.js"; | ||||||
| import { ChatUtility } from "./chat-utility.js"; | import { ChatUtility } from "./chat-utility.js"; | ||||||
|  | import { renderTemplate } from "./constants.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDDice } from "./rdd-dice.js"; | import { RdDDice } from "./rdd-dice.js"; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -95,7 +95,7 @@ export class RdDPossession { | |||||||
|  |  | ||||||
|   static selectCompetenceDraconicOuPossession(rollData, rollingActor) { |   static selectCompetenceDraconicOuPossession(rollData, rollingActor) { | ||||||
|     rollData.competence = rollingActor.getDraconicOuPossession(); |     rollData.competence = rollingActor.getDraconicOuPossession(); | ||||||
|     if (rollingActor.isCreatureEntite()) { |     if (rollingActor.isCreatureOuEntite()) { | ||||||
|       const carac = rollingActor.system.carac |       const carac = rollingActor.system.carac | ||||||
|       rollData.carac = carac |       rollData.carac = carac | ||||||
|       rollData.competence.system.defaut_carac = 'reve' |       rollData.competence.system.defaut_carac = 'reve' | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { renderTemplate } from "./constants.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDDice } from "./rdd-dice.js"; | import { RdDDice } from "./rdd-dice.js"; | ||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||||
| @@ -15,17 +16,20 @@ const levelDown = [ | |||||||
| ]; | ]; | ||||||
| const levelImpossible = { score: 0, norm: 0, sign: 0, part: 0, epart: 0, etotal: 1 }; | const levelImpossible = { score: 0, norm: 0, sign: 0, part: 0, epart: 0, etotal: 1 }; | ||||||
|  |  | ||||||
|  | const reussiteNormale = { code: "norm", isPart: false, isSign: false, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 1, ptQualite: 0, quality: "Réussite normale", condition: (target, roll) => (roll > target.sign && roll <= target.norm) }; | ||||||
|  | const reussiteSignificative = { code: "sign", isPart: false, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 2, ptQualite: 1, quality: "Réussite significative", condition: (target, roll) => (roll > target.part && roll <= target.sign) }; | ||||||
|  | const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false } | ||||||
|  |  | ||||||
| const reussites = [ | const reussites = [ | ||||||
|   { code: "etotal", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: -4, ptQualite: -6, quality: "Echec total", condition: (target, roll) => roll >= target.etotal && roll <= 100 }, |   { code: "etotal", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: -4, ptQualite: -6, quality: "Echec total", condition: (target, roll) => roll >= target.etotal && roll <= 100 }, | ||||||
|   { code: "epart", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: false, ptTache: -2, ptQualite: -4, quality: "Echec particulier", condition: (target, roll) => (roll >= target.epart && roll < target.etotal) }, |   { code: "epart", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: false, ptTache: -2, ptQualite: -4, quality: "Echec particulier", condition: (target, roll) => (roll >= target.epart && roll < target.etotal) }, | ||||||
|   { code: "echec", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Echec normal", condition: (target, roll) => (roll > target.norm && roll < target.etotal) }, |   { code: "echec", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Echec normal", condition: (target, roll) => (roll > target.norm && roll < target.etotal) }, | ||||||
|   { code: "norm", isPart: false, isSign: false, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 1, ptQualite: 0, quality: "Réussite normale", condition: (target, roll) => (roll > target.sign && roll <= target.norm) }, |   reussiteNormale, | ||||||
|   { code: "sign", isPart: false, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 2, ptQualite: 1, quality: "Réussite significative", condition: (target, roll) => (roll > target.part && roll <= target.sign) }, |   reussiteSignificative, | ||||||
|   { code: "part", isPart: true, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 3, ptQualite: 2, quality: "Réussite Particulière!", condition: (target, roll) => (roll > 0 && roll <= target.part) }, |   { code: "part", isPart: true, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 3, ptQualite: 2, quality: "Réussite Particulière!", condition: (target, roll) => (roll > 0 && roll <= target.part) }, | ||||||
|   { code: "error", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: 0, ptQualite: 0, quality: "Jet de dés invalide", condition: (target, roll) => (roll <= 0 || roll > 100) } |   { code: "error", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: 0, ptQualite: 0, quality: "Jet de dés invalide", condition: (target, roll) => (roll <= 0 || roll > 100) } | ||||||
| ]; | ]; | ||||||
|  |  | ||||||
| const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false } |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| const CARAC_MAXIMUM_RESOLUTION = 40; | const CARAC_MAXIMUM_RESOLUTION = 40; | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| @@ -66,9 +70,9 @@ export class RdDResolutionTable { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static _computeCell(niveau, percentage) { |   static _computeCell(level, percentage) { | ||||||
|     return { |     return { | ||||||
|       niveau: niveau, |       level: level, | ||||||
|       score: percentage, |       score: percentage, | ||||||
|       norm: Math.min(99, percentage), |       norm: Math.min(99, percentage), | ||||||
|       sign: this._reussiteSignificative(percentage), |       sign: this._reussiteSignificative(percentage), | ||||||
| @@ -155,6 +159,11 @@ export class RdDResolutionTable { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   static replaceParticuliereDemiSurprise(chances) { | ||||||
|  |     foundry.utils.mergeObject(chances, reussites.find(x => x.code == 'part'), { overwrite: true }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static significativeRequise(chances) { |   static significativeRequise(chances) { | ||||||
|     chances.roll = Math.min(chances.part + 1, chances.sign) |     chances.roll = Math.min(chances.part + 1, chances.sign) | ||||||
| @@ -188,9 +197,10 @@ export class RdDResolutionTable { | |||||||
|   static computeReussite(chances, roll, diviseur) { |   static computeReussite(chances, roll, diviseur) { | ||||||
|     const reussite = reussites.find(x => x.condition(chances, roll)) |     const reussite = reussites.find(x => x.condition(chances, roll)) | ||||||
|     if (diviseur > 1 && reussite.isSuccess) { |     if (diviseur > 1 && reussite.isSuccess) { | ||||||
|       if (chances > roll * diviseur) { |       if (chances.norm < roll * diviseur) { | ||||||
|         return reussiteInsuffisante |         return reussiteInsuffisante | ||||||
|       } |       } | ||||||
|  |       return reussiteSignificative | ||||||
|     } |     } | ||||||
|     return reussite |     return reussite | ||||||
|   } |   } | ||||||
| @@ -236,7 +246,7 @@ export class RdDResolutionTable { | |||||||
|     maxCarac = Math.min(maxCarac, minCarac + 20); |     maxCarac = Math.min(maxCarac, minCarac + 20); | ||||||
|     minLevel = Math.max(minLevel, -10); |     minLevel = Math.max(minLevel, -10); | ||||||
|     maxLevel = Math.max(Math.min(maxLevel, 30), minLevel + colonnes); |     maxLevel = Math.max(Math.min(maxLevel, 30), minLevel + colonnes); | ||||||
|     return await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', { |     return await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', { | ||||||
|       carac: carac, |       carac: carac, | ||||||
|       difficulte: level, |       difficulte: level, | ||||||
|       min: minLevel, |       min: minLevel, | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { ENTITE_BLURETTE, ENTITE_INCARNE } from "./constants.js"; | import { ENTITE_NONINCARNE, RDD_CONFIG, renderTemplate } from "./constants.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -16,34 +16,29 @@ export class RdDEncaisser extends Dialog { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   constructor(html, actor) { |   constructor(html, actor) { | ||||||
|     let dialogConf = { |     if (actor.isEntiteNonIncarnee([ENTITE_NONINCARNE])) { | ||||||
|  |       throw `${actor.name} est une entité non incarnée et ne peut pas subnir de dommages` | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const dialogConf = { | ||||||
|       title: "Jet d'Encaissement", |       title: "Jet d'Encaissement", | ||||||
|       content: html, |       content: html, | ||||||
|     } |       default: RDD_CONFIG.encaissement.mortel, | ||||||
|  |       buttons: { | ||||||
|     if (!actor.isEntite()) { |         [RDD_CONFIG.encaissement.mortel]: { label: "Mortel", callback: html => this.performEncaisser(RDD_CONFIG.encaissement.mortel) }, | ||||||
|       dialogConf.default = "mortel"; |  | ||||||
|       dialogConf.buttons = { |  | ||||||
|         "mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") }, |  | ||||||
|         "non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") }, |  | ||||||
|         "sonne": { label: "Sonné", callback: html => this.actor.setSonne() }, |  | ||||||
|       }; |  | ||||||
|     } |  | ||||||
|     else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])) { |  | ||||||
|       dialogConf.default = "entiteincarnee" |  | ||||||
|       dialogConf.buttons = { |  | ||||||
|         "entiteincarnee": { label: "Entité incarnée", callback: html => this.performEncaisser("entiteincarnee") } |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |     if (!actor.isEntite()) { | ||||||
|     let dialogOptions = { |       dialogConf.buttons[RDD_CONFIG.encaissement.nonmortel] = { label: "Non-mortel", callback: html => this.performEncaisser(RDD_CONFIG.encaissement.nonmortel) } | ||||||
|       classes: ["rdd-roll-dialog"], |       dialogConf.buttons["sonne"] = { label: "Sonné", callback: html => this.actor.setSonne() } | ||||||
|       width: 320, |  | ||||||
|       height: 'fit-content' |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Select proper roll dialog template and stuff |     // Select proper roll dialog template and stuff | ||||||
|     super(dialogConf, dialogOptions); |     super(dialogConf, { | ||||||
|  |       classes: ["rdd-roll-dialog"], | ||||||
|  |       width: 320, | ||||||
|  |       height: 'fit-content' | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     this.actor = actor; |     this.actor = actor; | ||||||
|     this.modifier = 0; |     this.modifier = 0; | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ export class RdDRollDialogEthylisme extends Dialog { | |||||||
|   activateListeners(html) { |   activateListeners(html) { | ||||||
|     super.activateListeners(html); |     super.activateListeners(html); | ||||||
|     this.html = html; |     this.html = html; | ||||||
|     this.bringToTop(); |     this.bringToFront(); | ||||||
|  |  | ||||||
|     this.html.find(".force-alcool").change((event) => { |     this.html.find(".force-alcool").change((event) => { | ||||||
|       this.rollData.forceAlcool = Misc.toInt(event.currentTarget.value); |       this.rollData.forceAlcool = Misc.toInt(event.currentTarget.value); | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
|  | import { renderTemplate } from "./constants.js"; | ||||||
| import { Misc } from "./misc.js"; | import { Misc } from "./misc.js"; | ||||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||||
|  | import { RdDRollResult } from "./rdd-roll-result.js"; | ||||||
|  |  | ||||||
| const titleTableDeResolution = 'Table de résolution'; | const titleTableDeResolution = 'Table de résolution'; | ||||||
| /** | /** | ||||||
| @@ -20,7 +22,7 @@ export class RdDRollResolutionTable extends Dialog { | |||||||
|       RdDRollResolutionTable.resolutionTable.render(true); |       RdDRollResolutionTable.resolutionTable.render(true); | ||||||
|     } |     } | ||||||
|     else{ |     else{ | ||||||
|       RdDRollResolutionTable.resolutionTable.bringToTop(); |       RdDRollResolutionTable.resolutionTable.bringToFront(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -68,7 +70,7 @@ export class RdDRollResolutionTable extends Dialog { | |||||||
|   activateListeners(html) { |   activateListeners(html) { | ||||||
|     super.activateListeners(html); |     super.activateListeners(html); | ||||||
|     this.html = html; |     this.html = html; | ||||||
|     this.bringToTop(); |     this.bringToFront(); | ||||||
|  |  | ||||||
|  |  | ||||||
|     this.html.find("[name='diffLibre']").val(Misc.toInt(this.rollData.diffLibre)); |     this.html.find("[name='diffLibre']").val(Misc.toInt(this.rollData.diffLibre)); | ||||||
| @@ -98,14 +100,14 @@ export class RdDRollResolutionTable extends Dialog { | |||||||
|   async onLancer() { |   async onLancer() { | ||||||
|     await RdDResolutionTable.rollData(this.rollData); |     await RdDResolutionTable.rollData(this.rollData); | ||||||
|     console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled); |     console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled); | ||||||
|     await RdDResolutionTable.displayRollData(this.rollData); |     await RdDRollResult.displayRollData(this.rollData); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async onLancerFermer() { |   async onLancerFermer() { | ||||||
|     await RdDResolutionTable.rollData(this.rollData); |     await RdDResolutionTable.rollData(this.rollData); | ||||||
|     console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled); |     console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled); | ||||||
|     await RdDResolutionTable.displayRollData(this.rollData); |     await RdDRollResult.displayRollData(this.rollData); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { ChatUtility } from "./chat-utility.js"; | import { ChatUtility } from "./chat-utility.js"; | ||||||
|  | import { renderTemplate } from "./constants.js"; | ||||||
|  |  | ||||||
| export class RdDRollResult { | export class RdDRollResult { | ||||||
|  |  | ||||||
| @@ -13,6 +14,6 @@ export class RdDRollResult { | |||||||
|  |  | ||||||
|   static async buildRollDataHtml(rollData, template = 'chat-resultat-general.hbs') { |   static async buildRollDataHtml(rollData, template = 'chat-resultat-general.hbs') { | ||||||
|     rollData.show = rollData.show || {}; |     rollData.show = rollData.show || {}; | ||||||
|     return await foundry.applications.handlebars.renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData); |     return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { RollDataAjustements } from "./rolldata-ajustements.js"; | import { RollDataAjustements } from "./rolldata-ajustements-v1.js"; | ||||||
| import { HtmlUtility } from "./html-utility.js"; | import { HtmlUtility } from "./html-utility.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"; | ||||||
| @@ -8,8 +8,8 @@ import { RdDCarac } from "./rdd-carac.js"; | |||||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||||
| import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; | ||||||
| import { Grammar } from "./grammar.js"; | import { Grammar } from "./grammar.js"; | ||||||
| import { ACTOR_TYPES } from "./constants.js"; | import { ACTOR_TYPES, RDD_CONFIG, renderTemplate } from "./constants.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { EMPOIGNADE } from "./item/arme.js"; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Extend the base Dialog entity to select roll parameters |  * Extend the base Dialog entity to select roll parameters | ||||||
| @@ -23,7 +23,7 @@ export class RdDRoll extends Dialog { | |||||||
|     RdDRoll._ensureCorrectAction(action); |     RdDRoll._ensureCorrectAction(action); | ||||||
|     RdDRoll._setDefaultOptions(actor, rollData); |     RdDRoll._setDefaultOptions(actor, rollData); | ||||||
|  |  | ||||||
|     const html = await foundry.applications.handlebars.renderTemplate(dialogConfig.html, rollData); |     const html = await renderTemplate(dialogConfig.html, rollData); | ||||||
|  |  | ||||||
|     let options = { classes: ["rdd-roll-dialog"], width: 650, height: 'fit-content', 'z-index': 99999, close: html => { } }; |     let options = { classes: ["rdd-roll-dialog"], width: 650, height: 'fit-content', 'z-index': 99999, close: html => { } }; | ||||||
|     if (dialogConfig.close) { |     if (dialogConfig.close) { | ||||||
| @@ -128,7 +128,7 @@ export class RdDRoll extends Dialog { | |||||||
|   activateListeners(html) { |   activateListeners(html) { | ||||||
|     super.activateListeners(html); |     super.activateListeners(html); | ||||||
|     this.html = html; |     this.html = html; | ||||||
|     this.bringToTop(); |     this.bringToFront(); | ||||||
|  |  | ||||||
|     console.log('RdDRoll.activateListeners', this.rollData); |     console.log('RdDRoll.activateListeners', this.rollData); | ||||||
|  |  | ||||||
| @@ -206,7 +206,7 @@ export class RdDRoll extends Dialog { | |||||||
|       this.updateRollResult(html); |       this.updateRollResult(html); | ||||||
|     }); |     }); | ||||||
|     this.html.find("input.check-mortalite").change((event) => { |     this.html.find("input.check-mortalite").change((event) => { | ||||||
|       this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel"; |       this.rollData.dmg.mortalite = event.currentTarget.checked ? RDD_CONFIG.encaissement.nonmortel : RDD_CONFIG.encaissement.mortel; | ||||||
|       this.updateRollResult(html); |       this.updateRollResult(html); | ||||||
|     }); |     }); | ||||||
|     this.html.find('.cuisine-proportions').change((event) => { |     this.html.find('.cuisine-proportions').change((event) => { | ||||||
| @@ -333,11 +333,9 @@ export class RdDRoll extends Dialog { | |||||||
|  |  | ||||||
|     // Mise à jour valeurs |     // Mise à jour valeurs | ||||||
|     this.html.find(".dialog-roll-title").text(this._getTitle(rollData)); |     this.html.find(".dialog-roll-title").text(this._getTitle(rollData)); | ||||||
|     this.html.find("input.check-mortalite").prop('checked', rollData.dmg.mortalite == 'non-mortel'); |     this.html.find("input.check-mortalite").prop('checked', rollData.dmg.mortalite == RDD_CONFIG.encaissement.nonmortel); | ||||||
|     this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == 'empoignade' ? 'empoignade' : Misc.toSignedString(rollData.dmg.total)); |     this.html.find("label.dmg-arme-actor").text(rollData.dmg.isEmpoignade ? EMPOIGNADE : Misc.toSignedString(rollData.dmg.total)); | ||||||
|     this.html.find("label.arme-mortalite").text(rollData.dmg.mortalite); |     this.html.find("label.arme-mortalite").text(rollData.dmg.mortalite); | ||||||
|     // this.html.find("[name='dmg-arme-actor']").text(rollData.dmg.mortalite == 'empoignade'? 'empoignade': Misc.toSignedString(rollData.dmg.total) ); |  | ||||||
|     // this.html.find("[name='arme-mortalite']").text(rollData.dmg.mortalite); |  | ||||||
|     this.html.find("div.placeholder-ajustements").empty().append(adjustements); |     this.html.find("div.placeholder-ajustements").empty().append(adjustements); | ||||||
|     this.html.find("div.placeholder-resolution").empty().append(resolutionTable) |     this.html.find("div.placeholder-resolution").empty().append(resolutionTable) | ||||||
|   } |   } | ||||||
| @@ -345,7 +343,7 @@ export class RdDRoll extends Dialog { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async buildAjustements(rollData) { |   async buildAjustements(rollData) { | ||||||
|     return await foundry.applications.handlebars.renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs`, rollData); |     return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/partial-roll-ajustements.hbs`, rollData); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { SHOW_DICE, SYSTEM_RDD } from "./constants.js"; | import { renderTemplate, SHOW_DICE, SYSTEM_RDD } from "./constants.js"; | ||||||
| import { RollDataAjustements } from "./rolldata-ajustements.js"; | import { RollDataAjustements } from "./rolldata-ajustements-v1.js"; | ||||||
| import { RdDUtility } from "./rdd-utility.js"; | import { RdDUtility } from "./rdd-utility.js"; | ||||||
| import { COORD_TMR_INCONNU, 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"; | ||||||
| @@ -47,7 +47,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|   static async create(actor, tmrData) { |   static async create(actor, tmrData) { | ||||||
|     await PixiTMR.init() |     await PixiTMR.init() | ||||||
|     let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.hbs', tmrData); |     let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.hbs', tmrData); | ||||||
|     if (tmrData.mode != 'visu' && !game.user.isGM) { |     if (tmrData.mode != 'visu' && !game.user.isGM) { | ||||||
|       ChatMessage.create({ content: actor.name + " est monté dans les TMR en mode : " + tmrData.mode, whisper: ChatUtility.getGMs() }); |       ChatMessage.create({ content: actor.name + " est monté dans les TMR en mode : " + tmrData.mode, whisper: ChatUtility.getGMs() }); | ||||||
|     } |     } | ||||||
| @@ -82,7 +82,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     this.subdialog = undefined |     this.subdialog = undefined | ||||||
|     this.displaySize = undefined |     this.displaySize = undefined | ||||||
|     if (!this.viewOnly && !game.user.isGM) { |     if (!this.viewOnly && !game.user.isGM) { | ||||||
|       this.$tellToGM(this.actor.name + " monte dans les terres médianes (" + tmrData.mode + ")"); |       ChatUtility.tellToGM(this.actor.name + " monte dans les terres médianes (" + tmrData.mode + ")"); | ||||||
|     } |     } | ||||||
|     this.callbacksOnAnimate = []; |     this.callbacksOnAnimate = []; | ||||||
|     const displaySize = TMR_DISPLAY_SIZE.clamp(game.settings.get(SYSTEM_RDD, TMR_DISPLAY_SIZE.code) ?? TMR_DISPLAY_SIZE.def); |     const displaySize = TMR_DISPLAY_SIZE.clamp(game.settings.get(SYSTEM_RDD, TMR_DISPLAY_SIZE.code) ?? TMR_DISPLAY_SIZE.def); | ||||||
| @@ -125,7 +125,11 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionnelles.isUsing("appliquer-fatigue")); |     HtmlUtility.showControlWhen(this.html.find(".appliquerFatigue"), ReglesOptionnelles.isUsing("appliquer-fatigue")); | ||||||
|     HtmlUtility.showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getCoordActor())); |     HtmlUtility.showControlWhen(this.html.find(".lire-signe-draconique"), this.actor.isResonanceSigneDraconique(this._getCoordActor())); | ||||||
|  |  | ||||||
|     this.html.find('form.tmr-dialog *').click(event => this.subdialog?.bringToTop()); |     this.html.find('form.tmr-dialog *').click(event => { | ||||||
|  |       if (this.subdialog?.rendered){ | ||||||
|  |         this.subdialog?.bringToFront() | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |  | ||||||
|     // Roll Sort |     // Roll Sort | ||||||
|     this.html.find('.lancer-sort').click(event => this.lancerUnSort()); |     this.html.find('.lancer-sort').click(event => this.lancerUnSort()); | ||||||
| @@ -169,26 +173,26 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|   async forceTMRDisplay() { |   async forceTMRDisplay() { | ||||||
|     if (this.rendered) { |     if (this.rendered) { | ||||||
|       this.bringToTop() |       this.bringToFront() | ||||||
|       this.bringSubDialogToTop(); |       this.bringSubDialogToFront(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   bringSubDialogToTop() { |   bringSubDialogToFront() { | ||||||
|     if (this.subdialog?.bringToTop && this.subdialog?.element && this.subdialog?.element[0]) { |     if (this.subdialog?.bringToFront && this.subdialog?.element && this.subdialog?.element[0]) { | ||||||
|       this.subdialog.bringToTop(); |       this.subdialog.bringToFront(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async restoreTMRAfterAction() { |   async restoreTMRAfterAction() { | ||||||
|     this.subdialog = undefined |     this.subdialog = undefined | ||||||
|     await this.maximize() |     await this.maximize() | ||||||
|     this.bringToTop() |     this.bringToFront() | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   forceTMRContinueAction() { |   forceTMRContinueAction() { | ||||||
|     ui.notifications.warn('Vous devez finir votre action avant de continuer dans les TMR'); |     ui.notifications.warn('Vous devez finir votre action avant de continuer dans les TMR'); | ||||||
|     this.bringSubDialogToTop(); |     this.bringSubDialogToFront(); | ||||||
|     return false |     return false | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -343,19 +347,8 @@ export class RdDTMRDialog extends Dialog { | |||||||
|       this.forceTMRContinueAction() |       this.forceTMRContinueAction() | ||||||
|       return false |       return false | ||||||
|     } |     } | ||||||
|     this.descenteTMR = true; |     this.descenteTMR = true | ||||||
|     if (this.actor.tmrApp) { |     await await this.actor.quitterTMR(message, this.viewOnly, this.cumulFatigue) | ||||||
|       this.actor.tmrApp = undefined // Cleanup reference |  | ||||||
|       const appliquerFatigue = ReglesOptionnelles.isUsing("appliquer-fatigue") |  | ||||||
|       await this.actor.santeIncDec( |  | ||||||
|         appliquerFatigue ? "fatigue" : "endurance", |  | ||||||
|         (appliquerFatigue ? 1 : -1) * this.cumulFatigue) |  | ||||||
|       if (!this.viewOnly) { |  | ||||||
|         await this.actor.setEffect(STATUSES.StatusDemiReve, false) |  | ||||||
|         this.$tellToUserAndGM(message) |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|     this.pixiTMR.close(); |     this.pixiTMR.close(); | ||||||
|     this.pixiTMR = undefined |     this.pixiTMR = undefined | ||||||
|     await super.close(); |     await super.close(); | ||||||
| @@ -412,7 +405,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|   async $ignorerRencontre() { |   async $ignorerRencontre() { | ||||||
|     if (this.currentRencontre) { |     if (this.currentRencontre) { | ||||||
|       console.log("-> ignorer", this.currentRencontre); |       console.log("-> ignorer", this.currentRencontre); | ||||||
|       this.$tellToGM(this.actor.name + " a ignoré: " + this.currentRencontre.name); |       ChatUtility.tellToGM(this.actor.name + " a ignoré: " + this.currentRencontre.name); | ||||||
|       await this.$deleteRencontreTMRAtPosition() |       await this.$deleteRencontreTMRAtPosition() | ||||||
|       this.updateTokens(); |       this.updateTokens(); | ||||||
|       this.$updateValuesDisplay(); |       this.$updateValuesDisplay(); | ||||||
| @@ -508,7 +501,7 @@ export class RdDTMRDialog extends Dialog { | |||||||
|  |  | ||||||
|     ChatMessage.create({ |     ChatMessage.create({ | ||||||
|       whisper: ChatUtility.getOwners(this.actor), |       whisper: ChatUtility.getOwners(this.actor), | ||||||
|       content: await foundry.applications.handlebars.renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.hbs`, rencData) |       content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.hbs`, rencData) | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     this.$updateValuesDisplay(); |     this.$updateValuesDisplay(); | ||||||
| @@ -578,29 +571,6 @@ export class RdDTMRDialog extends Dialog { | |||||||
|     }, 500); |     }, 500); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   _tellToUser(message) { |  | ||||||
|     ChatMessage.create({ content: message, user: game.user.id, whisper: [game.user.id] }); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   $tellToGM(message) { |  | ||||||
|     ChatMessage.create({ |  | ||||||
|       user: game.user.id, |  | ||||||
|       content: message, |  | ||||||
|       whisper: ChatUtility.getGMs() |  | ||||||
|     }); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |  | ||||||
|   $tellToUserAndGM(message) { |  | ||||||
|     ChatMessage.create({ |  | ||||||
|       user: game.user.id, |  | ||||||
|       content: message, |  | ||||||
|       whisper: ChatUtility.getUserAndGMs() |  | ||||||
|     }) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async manageRencontre(tmr) { |   async manageRencontre(tmr) { | ||||||
|     if (this.viewOnly) { |     if (this.viewOnly) { | ||||||
| @@ -676,14 +646,14 @@ export class RdDTMRDialog extends Dialog { | |||||||
|       ? TMRUtility.getTMRType(tmr.coord) + " ??" |       ? TMRUtility.getTMRType(tmr.coord) + " ??" | ||||||
|       : tmr.label + " (" + tmr.coord + ")"); |       : tmr.label + " (" + tmr.coord + ")"); | ||||||
|  |  | ||||||
|     this.setTMRPendingAction({ bringToTop: () => { } }) |     this.setTMRPendingAction({ bringToFront: () => { } }) | ||||||
|     const myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE }); |     const myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE }); | ||||||
|     this.restoreTMRAfterAction() |     this.restoreTMRAfterAction() | ||||||
|     if (myRoll == 7) { |     if (myRoll == 7) { | ||||||
|       this._tellToUser(myRoll + ": Rencontre en " + coordTMR); |       ChatUtility.tellToUser(myRoll + ": Rencontre en " + coordTMR); | ||||||
|       return await game.system.rdd.rencontresTMR.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre()) |       return await game.system.rdd.rencontresTMR.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre()) | ||||||
|     } else { |     } else { | ||||||
|       this._tellToUser(myRoll + ": Pas de rencontre en " + coordTMR); |       ChatUtility.tellToUser(myRoll + ": Pas de rencontre en " + coordTMR); | ||||||
|       return undefined; |       return undefined; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,6 +1,9 @@ | |||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
|  | import { renderTemplate } from "./constants.js"; | ||||||
| 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 { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js"; | ||||||
| import { Targets } from "./targets.js"; | import { Targets } from "./targets.js"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| @@ -30,47 +33,92 @@ 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) { | ||||||
|         const actions = RdDCombatManager.listActionsActorCombatant(actor) |         if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { | ||||||
|         // initiative |           await RdDTokenHud.addExtensionHudCombat(html, combatant, actor, token) | ||||||
|         await RdDTokenHud.addExtensionHudInit(html, combatant, actions) |         } | ||||||
|         // combat |         else { | ||||||
|         await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions.filter(it => !it.initOnly)) |           const actions = RdDCombatManager.listActionsActorCombatant(actor) | ||||||
|  |           // initiative | ||||||
|  |           await RdDTokenHud.addExtensionHudInit(html, combatant, actions) | ||||||
|  |           // combat | ||||||
|  |           await RdDTokenHud.addExtensionHudAttaques(html, combatant, token, actions.filter(it => !it.initOnly)) | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static async addExtensionHudCombat(html, combatant, actor, token) { | ||||||
|  |     const actionsActor = actor.listActionsCombat(); | ||||||
|  |     const ajustements = combatant?.initiative ? | ||||||
|  |       [ | ||||||
|  |         { label: 'Initiative +1', action: 'delta', value: 1 }, | ||||||
|  |         { label: 'Initiative -1', action: 'delta', value: -1 } | ||||||
|  |       ] : [] | ||||||
|  |     const autres = [{ label: "Autre action", action: 'autre' }] | ||||||
|  |     const actions = Misc.indexed(actionsActor.concat(ajustements).concat(autres)) | ||||||
|  |  | ||||||
|  |     const hudData = { combatant, token, actions }; | ||||||
|  |     const hud = $(await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/hud-actor-combat.hbs', hudData)) | ||||||
|  |     $(html).find('div.col.left').append(hud) | ||||||
|  |  | ||||||
|  |     const list = hud.find('div.rdd-hud-list') | ||||||
|  |     RdDTokenHud.setupHudToggle(hud, list) | ||||||
|  |  | ||||||
|  |     const selectInitiative = list.find('select[name="initiative"]'); | ||||||
|  |     selectInitiative.change(event => { | ||||||
|  |       const action = actions.find(it => it.index == event.currentTarget.value) | ||||||
|  |       console.log('select initiative', combatant.id, action) | ||||||
|  |       if (action) { | ||||||
|  |         switch (action.action) { | ||||||
|  |           case 'delta': | ||||||
|  |             RdDCombatManager.incDecInit(combatant.id, action.value); | ||||||
|  |             break | ||||||
|  |           case 'autre': | ||||||
|  |             RdDCombatManager.rollInitiativeAction(combatant.id, | ||||||
|  |               { label: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } }); | ||||||
|  |             break | ||||||
|  |           default: | ||||||
|  |             RdDCombatManager.rollInitiativeAction(combatant.id, action) | ||||||
|  |         } | ||||||
|  |         selectInitiative.select("") | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |     list.find('.rdd-attaque-v2').click(event => combatant.actor.rollAttaque(token)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async addExtensionHudInit(html, combatant, actions) { |   static async addExtensionHudInit(html, combatant, actions) { | ||||||
|     const hudData = { |     const hudData = { | ||||||
|       combatant, actions, |       combatant, actions, | ||||||
|       commandes: [ |       commandes: [ | ||||||
|         { name: "Autre action", command: 'autre' }, |         { label: "Autre action", command: 'autre' }, | ||||||
|         { name: 'Initiative +1', command: 'inc', value: 0.01 }, |         { label: 'Initiative +1', command: 'delta', value: 1 }, | ||||||
|         { name: 'Initiative -1', command: 'dec', value: -0.01 }] |         { label: 'Initiative -1', command: 'deltac', value: -1 }] | ||||||
|     }; |     }; | ||||||
|     const controlIconCombat = $(html).find('.control-icon[data-action=combat]'); |     const controlIconCombat = $(html).find('.control-icon[data-action=combat]'); | ||||||
|     await RdDTokenHud._configureSubMenu(controlIconCombat, |     await RdDTokenHud._configureSubMenu(it => controlIconCombat.after(it), | ||||||
|       'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.hbs', |       'systems/foundryvtt-reve-de-dragon/templates/hud-actor-init.hbs', | ||||||
|       hudData, |       hudData, | ||||||
|       (event) => { |       (event) => { | ||||||
|         let initCommand = event.currentTarget.attributes['data-command']?.value; |         let initCommand = event.currentTarget.attributes['data-command']?.value | ||||||
|         let combatantId = event.currentTarget.attributes['data-combatant-id']?.value; |         let initCommandValue = Number(event.currentTarget.attributes['data-command-value']?.value ?? 0) | ||||||
|  |         let combatantId = event.currentTarget.attributes['data-combatant-id']?.value | ||||||
|         if (initCommand) { |         if (initCommand) { | ||||||
|           RdDTokenHud._initiativeCommand(initCommand, combatantId); |           RdDCombatManager.applyInitiativeCommand(combatantId, initCommand, initCommandValue) | ||||||
|         } else { |         } else { | ||||||
|           let index = event.currentTarget.attributes['data-action-index'].value; |           let index = event.currentTarget.attributes['data-action-index'].value | ||||||
|           let action = hudData.actions[index]; |           let action = hudData.actions[index] | ||||||
|           RdDCombatManager.rollInitiativeAction(combatantId, action); |           RdDCombatManager.rollInitiativeAction(combatantId, action) | ||||||
|         } |         } | ||||||
|       }); |       }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static async addExtensionHudCombat(html, combatant, token, actions) { |   static async addExtensionHudAttaques(html, combatant, token, actions) { | ||||||
|  |  | ||||||
|     const hudData = { combatant, token, actions, commandes: [] }; |     const hudData = { combatant, token, actions, commandes: [] }; | ||||||
|     const controlIconTarget = $(html).find('.control-icon[data-action=target]'); |     const divColLeft = $(html).find('div.col.left'); | ||||||
|     await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.hbs', hudData, |     await RdDTokenHud._configureSubMenu(it => divColLeft.append(it), | ||||||
|  |       '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]; | ||||||
| @@ -90,7 +138,7 @@ export class RdDTokenHud { | |||||||
|       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(it => controlIconTarget.after(it), | ||||||
|           'systems/foundryvtt-reve-de-dragon/templates/hud-actor-soins.hbs', |           'systems/foundryvtt-reve-de-dragon/templates/hud-actor-soins.hbs', | ||||||
|           hudSoins, |           hudSoins, | ||||||
|           (event) => { |           (event) => { | ||||||
| @@ -101,15 +149,6 @@ export class RdDTokenHud { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static _initiativeCommand(initCommand, combatantId) { |  | ||||||
|     switch (initCommand) { |  | ||||||
|       case 'inc': return RdDCombatManager.incDecInit(combatantId, 0.01); |  | ||||||
|       case 'dec': return RdDCombatManager.incDecInit(combatantId, -0.01); |  | ||||||
|       case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId, |  | ||||||
|         { name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } }); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async addTokenHudExtensions(app, html, tokenId) { |   static async addTokenHudExtensions(app, html, tokenId) { | ||||||
|     console.log(`Adding token HUD extensions for token ${tokenId}`); |     console.log(`Adding token HUD extensions for token ${tokenId}`); | ||||||
| @@ -129,20 +168,24 @@ export class RdDTokenHud { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async _configureSubMenu(insertionPoint, template, hudData, onMenuItem) { |   static async _configureSubMenu(callInsertion, template, hudData, onMenuItem) { | ||||||
|     const hud = $(await foundry.applications.handlebars.renderTemplate(template, hudData)); |     const hud = $(await renderTemplate(template, hudData)); | ||||||
|     const list = hud.find('div.rdd-hud-list'); |     const list = hud.find('div.rdd-hud-list'); | ||||||
|  |  | ||||||
|     RdDTokenHud._toggleHudListActive(hud, list); |     RdDTokenHud.setupHudToggle(hud, list) | ||||||
|  |  | ||||||
|     hud.find('img.rdd-hud-togglebutton').click(event => RdDTokenHud._toggleHudListActive(hud, list)); |  | ||||||
|     list.find('.rdd-hud-menu').click(onMenuItem); |     list.find('.rdd-hud-menu').click(onMenuItem); | ||||||
|  |  | ||||||
|     insertionPoint.after(hud); |     callInsertion(hud); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static _toggleHudListActive(hud, list) { |   static setupHudToggle(hud, list) { | ||||||
|     hud.toggleClass('active'); |     function toggleHudList(hud, list) { | ||||||
|     HtmlUtility.showControlWhen(list, hud.hasClass('active')); |       hud.toggleClass('active') | ||||||
|  |       HtmlUtility.showControlWhen(list, hud.hasClass('active')) | ||||||
|  |     } | ||||||
|  |     toggleHudList(hud, list) | ||||||
|  |     $(hud).find('img.rdd-hud-togglebutton').click(event => toggleHudList(hud, list)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -75,30 +75,27 @@ const fatigueLineMalus = [0, -1, -2, -3, -4, -5, -6, -7]; | |||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| const nomEthylisme = ["Emeché", "Gris", "Pinté", "Pas frais", "Ivre", "Bu", "Complètement fait", "Ivre mort"]; | const nomEthylisme = ["Emeché", "Gris", "Pinté", "Pas frais", "Ivre", "Bu", "Complètement fait", "Ivre mort"]; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | const TABLE_ENCAISSEMENT_MORTEL = [ | ||||||
| const definitionsEncaissement = { |   { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, | ||||||
|   "mortel": [ |   { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, | ||||||
|     { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, |   { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2 }, | ||||||
|     { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, |   { minimum: 16, maximum: 19, endurance: "2d6", vie: "2", gravite: 4 }, | ||||||
|     { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2 }, |   { minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", gravite: 6 }, | ||||||
|     { minimum: 16, maximum: 19, endurance: "2d6", vie: "2", gravite: 4 }, | ] | ||||||
|     { minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", gravite: 6 }, | const TABLE_ENCAISSEMENT_NONMORTEL = [ | ||||||
|   ], |   { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, | ||||||
|   "non-mortel": [ |   { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, | ||||||
|     { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, |   { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 }, | ||||||
|     { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, |   { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 2 }, | ||||||
|     { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 }, |   { minimum: 20, maximum: undefined, endurance: "100", vie: "0", gravite: 2 }, | ||||||
|     { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 2 }, | ] | ||||||
|     { minimum: 20, maximum: undefined, endurance: "100", vie: "0", gravite: 2 }, | const TABLE_ENCAISSEMENT_ENTITE = [ | ||||||
|   ], |   { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, | ||||||
|   "entiteincarnee": [ |   { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, | ||||||
|     { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, |   { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2 }, | ||||||
|     { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, |   { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 4 }, | ||||||
|     { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 }, |   { minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", gravite: 6 }, | ||||||
|     { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 0 }, | ] | ||||||
|     { minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", gravite: 0 }, |  | ||||||
|   ] |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RdDUtility { | export class RdDUtility { | ||||||
| @@ -301,6 +298,8 @@ export class RdDUtility { | |||||||
|     Handlebars.registerHelper('json-stringify', object => JSON.stringify(object)) |     Handlebars.registerHelper('json-stringify', object => JSON.stringify(object)) | ||||||
|  |  | ||||||
|     // math |     // math | ||||||
|  |     Handlebars.registerHelper('math-sum', (...values) => values.slice(0, -1).reduce(Misc.sum(), 0)) | ||||||
|  |     Handlebars.registerHelper('math-abs', diff => Math.abs(parseInt(diff))) | ||||||
|     Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); |     Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); | ||||||
|     Handlebars.registerHelper('repeat', function (n, block) { |     Handlebars.registerHelper('repeat', function (n, block) { | ||||||
|       let accum = ''; |       let accum = ''; | ||||||
| @@ -611,20 +610,20 @@ export class RdDUtility { | |||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async getLocalisation(type = 'personnage') { |   static async getLocalisation(type = 'personnage') { | ||||||
|     const loc = { result:  await RdDDice.rollTotal("1d20")}; |     const loc = { result: await RdDDice.rollTotal("1d20") }; | ||||||
|     if (type == 'personnage') { |     if (type == 'personnage') { | ||||||
|       if (loc.result <= 3) loc.txt =  "Jambe, genou, pied, jarret"; |       if (loc.result <= 3) loc.txt = "Jambe, genou, pied, jarret"; | ||||||
|       else if (loc.result <= 7) loc.txt =  "Hanche, cuisse, fesse"; |       else if (loc.result <= 7) loc.txt = "Hanche, cuisse, fesse"; | ||||||
|       else if (loc.result <= 9) loc.txt =  "Ventre, reins"; |       else if (loc.result <= 9) loc.txt = "Ventre, reins"; | ||||||
|       else if (loc.result <= 12) loc.txt =  "Poitrine, dos"; |       else if (loc.result <= 12) loc.txt = "Poitrine, dos"; | ||||||
|       else if (loc.result <= 14) loc.txt =  "Avant-bras, main, coude"; |       else if (loc.result <= 14) loc.txt = "Avant-bras, main, coude"; | ||||||
|       else if (loc.result <= 18) loc.txt =  "Epaule, bras, omoplate"; |       else if (loc.result <= 18) loc.txt = "Epaule, bras, omoplate"; | ||||||
|       else if (loc.result == 19) loc.txt =  "Tête"; |       else if (loc.result == 19) loc.txt = "Tête"; | ||||||
|       else if (loc.result == 20) loc.txt =  "Tête (visage)"; |       else if (loc.result == 20) loc.txt = "Tête (visage)"; | ||||||
|     } else { |     } else { | ||||||
|       if (loc.result <= 7) loc.txt =  "Jambes/Pattes"; |       if (loc.result <= 7) loc.txt = "Jambes/Pattes"; | ||||||
|       else if (loc.result <= 18) loc.txt =  "Corps"; |       else if (loc.result <= 18) loc.txt = "Corps"; | ||||||
|       else if (loc.result <= 20) loc.txt =  "Tête"; |       else if (loc.result <= 20) loc.txt = "Tête"; | ||||||
|     } |     } | ||||||
|     return loc |     return loc | ||||||
|   } |   } | ||||||
| @@ -669,13 +668,13 @@ export class RdDUtility { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async prepareEncaissement(actor, dmg, roll, armure) { |   static async prepareEncaissement(targetActor, dmg, roll, armure) { | ||||||
|     const jetTotal = roll.total + dmg.total - armure |     const jetTotal = roll.total + dmg.total - armure | ||||||
|     const encaissement = RdDUtility._selectEncaissement(jetTotal, dmg.mortalite); |     const encaissement = RdDUtility.$selectEncaissement(targetActor, jetTotal, dmg.mortalite) | ||||||
|     const over20 = Math.max(jetTotal - 20, 0); |     const over20 = Math.max(jetTotal - 20, 0) | ||||||
|     encaissement.dmg = dmg |     encaissement.dmg = dmg | ||||||
|     if (ReglesOptionnelles.isUsing('localisation-aleatoire')) { |     if (ReglesOptionnelles.isUsing('localisation-aleatoire')) { | ||||||
|       encaissement.dmg.loc = dmg.loc ?? await RdDUtility.getLocalisation(actor.type) |       encaissement.dmg.loc = dmg.loc ?? await RdDUtility.getLocalisation(targetActor.type) | ||||||
|       encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;' |       encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;' | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
| @@ -691,15 +690,21 @@ export class RdDUtility { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static _selectEncaissement(degats, mortalite) { |   static $selectEncaissement(targetActor, degats, mortalite) { | ||||||
|     const table = definitionsEncaissement[mortalite] === undefined ? definitionsEncaissement["mortel"] : definitionsEncaissement[mortalite]; |     const table = RdDUtility.$getTableEncaissement(targetActor, mortalite) | ||||||
|     for (let encaissement of table) { |     const encaissement = table.find(it => ((it.minimum ?? degats) <= degats && degats <= (it.maximum ?? degats))) | ||||||
|       if ((encaissement.minimum === undefined || encaissement.minimum <= degats) |     return foundry.utils.duplicate(encaissement ?? table[0]) | ||||||
|         && (encaissement.maximum === undefined || degats <= encaissement.maximum)) { |   } | ||||||
|         return foundry.utils.duplicate(encaissement); |  | ||||||
|       } |   static $getTableEncaissement(targetActor, mortalite) { | ||||||
|  |     if (targetActor.isEntite()) { | ||||||
|  |       return TABLE_ENCAISSEMENT_ENTITE | ||||||
|     } |     } | ||||||
|     return foundry.utils.duplicate(table[0]); |     switch (mortalite) { | ||||||
|  |       case RDD_CONFIG.encaissement.nonmortel: return TABLE_ENCAISSEMENT_NONMORTEL | ||||||
|  |       case RDD_CONFIG.encaissement.entiteincarnee: return TABLE_ENCAISSEMENT_ENTITE | ||||||
|  |     } | ||||||
|  |     return TABLE_ENCAISSEMENT_MORTEL | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   | |||||||
| @@ -1,9 +1,17 @@ | |||||||
| import { ChatUtility } from "../chat-utility.js" | import { ChatUtility } from "../chat-utility.js" | ||||||
| import RollDialog from "./roll-dialog.mjs" | import RollDialog, { ALL_ROLL_TYPES } from "./roll-dialog.mjs" | ||||||
| import { RdDCarac } from "../rdd-carac.js" | import { RdDCarac } from "../rdd-carac.js" | ||||||
| import { RdDCombat } from "../rdd-combat.js" | import { RdDCombat } from "../rdd-combat.js" | ||||||
| import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" | import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" | ||||||
| import { RdDResolutionTable } from "../rdd-resolution-table.js" | import { RdDResolutionTable } from "../rdd-resolution-table.js" | ||||||
|  | import { RDD_CONFIG, renderTemplate } from "../constants.js" | ||||||
|  | import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js" | ||||||
|  | import { RollTypeCuisine } from "./roll-type-cuisine.mjs" | ||||||
|  | import { RollTypeMeditation } from "./roll-type-meditation.mjs" | ||||||
|  | import { PART_DEFENSE } from "./roll-part-defense.mjs" | ||||||
|  | import { PART_ATTAQUE } from "./roll-part-attaque.mjs" | ||||||
|  | import { RdDRollTables } from "../rdd-rolltables.js" | ||||||
|  | import { RdDEmpoignade } from "../rdd-empoignade.js" | ||||||
|  |  | ||||||
| export default class ChatRollResult { | export default class ChatRollResult { | ||||||
|   static init() { |   static init() { | ||||||
| @@ -14,14 +22,18 @@ export default class ChatRollResult { | |||||||
|  |  | ||||||
|   static onReady() { |   static onReady() { | ||||||
|     foundry.applications.handlebars.loadTemplates({ |     foundry.applications.handlebars.loadTemplates({ | ||||||
|  |       'partial-infojet': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-infojet.hbs', | ||||||
|       'partial-appel-chance': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-appel-chance.hbs', |       'partial-appel-chance': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-appel-chance.hbs', | ||||||
|  |       'partial-attaque-particuliere': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-attaque-particuliere.hbs', | ||||||
|  |       'partial-choix-maladresse': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-choix-maladresse.hbs', | ||||||
|  |       'partial-maladresse': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-maladresse.hbs', | ||||||
|       'partial-encaissement': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-encaissement.hbs', |       'partial-encaissement': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-encaissement.hbs', | ||||||
|       'partial-recul-choc': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-recul-choc.hbs', |       'partial-recul-choc': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-recul-choc.hbs', | ||||||
|       'partial-info-appel-moral': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-info-appel-moral.hbs', |       'partial-info-appel-moral': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-info-appel-moral.hbs', | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async display(roll) { |   async display(roll, impacts) { | ||||||
|     this.prepareDisplay(roll) |     this.prepareDisplay(roll) | ||||||
|  |  | ||||||
|     const chatMessage = await ChatUtility.createChatWithRollMode( |     const chatMessage = await ChatUtility.createChatWithRollMode( | ||||||
| @@ -31,18 +43,19 @@ export default class ChatRollResult { | |||||||
|       roll.active.actor, |       roll.active.actor, | ||||||
|       roll.current?.rollmode?.key |       roll.current?.rollmode?.key | ||||||
|     ) |     ) | ||||||
|     const save = RollDialog.saveParts(roll) |     const save = RollDialog.saveParts(roll, impacts) | ||||||
|     ChatUtility.setMessageData(chatMessage, 'rollData', save) |  | ||||||
|  |     await this.saveChatMessageRoll(chatMessage, save) | ||||||
|     return chatMessage |     return chatMessage | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   prepareDisplay(roll) { |   prepareDisplay(roll) { | ||||||
|     roll.done = roll.done || {} |     roll.done = roll.done ?? {} | ||||||
|     roll.show = roll.show || {} |     roll.show = roll.show ?? {} | ||||||
|     roll.show.chance = this.isAppelChancePossible(roll) |     roll.show.chance = this.isAppelChancePossible(roll) | ||||||
|     roll.show.encaissement = this.isShowEncaissement(roll) |     roll.show.encaissement = this.isShowEncaissement(roll) | ||||||
|     roll.show.recul = this.getReculChoc(roll) |     roll.show.recul = this.getRecul(roll) | ||||||
|  |     roll.show.maladresse = this.getMaladresse(roll) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   isAppelChancePossible(roll) { |   isAppelChancePossible(roll) { | ||||||
| @@ -52,39 +65,81 @@ export default class ChatRollResult { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   isShowEncaissement(roll) { |   isShowEncaissement(roll) { | ||||||
|     return roll.rolled.isEchec && |     switch (roll.type.current) { | ||||||
|       roll.attackerRoll?.dmg.mortalite != 'empoignade' |       case ROLL_TYPE_DEFENSE: | ||||||
|  |         return roll.rolled.isEchec | ||||||
|  |     } | ||||||
|  |     return false | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getReculChoc(roll, defender = roll.active.actor, attacker = roll.opponent.actor) { |   getMaladresse(roll) { | ||||||
|     const attaque = roll.attackerRoll |     switch (roll.type.current) { | ||||||
|     if (attaque && |       case ROLL_TYPE_DEFENSE: | ||||||
|       (roll.rolled.isEchec || !roll.current.defense.isEsquive) && |         if (roll.rolled.isETotal) { | ||||||
|       (attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)) { |           const arme = roll.current[PART_DEFENSE].arme | ||||||
|       const taille = defender.system.carac.taille.value |           return arme ? 'avec-arme' : 'sans-arme' | ||||||
|       const impact = attacker.system.carac.force.value + roll.attackerRoll?.dmg.dmgArme |         } | ||||||
|       return { |         break | ||||||
|         raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force', |       case ROLL_TYPE_ATTAQUE: | ||||||
|         taille: taille, |         if (roll.rolled.isETotal || (roll.rolled.isEchec && roll.active.surprise == 'demi')) { | ||||||
|         impact: impact, |           const arme = roll.current[PART_ATTAQUE].arme | ||||||
|         chances: RdDResolutionTable.computeChances(10, taille-impact).norm, |           return arme.system.baseInit > 4 ? 'avec-arme' : 'sans-arme' | ||||||
|         diff: taille - impact |         } | ||||||
|       } |         break | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getRecul(roll, defender = roll.active.actor, attacker = roll.opponent?.actor) { | ||||||
|  |     switch (roll.type.current) { | ||||||
|  |       case ROLL_TYPE_DEFENSE: | ||||||
|  |         { | ||||||
|  |           const attaque = roll.attackerRoll | ||||||
|  |           if (attaque && | ||||||
|  |             (roll.rolled.isEchec || !roll.current.defense.isEsquive) && | ||||||
|  |             (attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)) { | ||||||
|  |             const taille = defender.system.carac.taille.value | ||||||
|  |             const impact = attacker.system.carac.force.value + roll.attackerRoll?.dmg.dmgArme | ||||||
|  |             return { | ||||||
|  |               raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force', | ||||||
|  |               taille: taille, | ||||||
|  |               impact: impact, | ||||||
|  |               chances: RdDResolutionTable.computeChances(10, taille - impact).norm, | ||||||
|  |               diff: taille - impact | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |           break | ||||||
|  |         } | ||||||
|  |       case ROLL_TYPE_ATTAQUE: | ||||||
|  |         { | ||||||
|  |           const attaque = roll | ||||||
|  |           if (attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key) { | ||||||
|  |             return { | ||||||
|  |               raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force', | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async buildRollHtml(roll) { |   async buildRollHtml(roll) { | ||||||
|     const template = `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${roll.type.current}.hbs` |     const template = ALL_ROLL_TYPES.find(it => it.code == roll.type.current).chatResultTemplate | ||||||
|     return await foundry.applications.handlebars.renderTemplate(template, roll) |     const html = await renderTemplate(template, roll) | ||||||
|  |     return await RdDTextEditor.enrichHTML(html, undefined, { showLink: false }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async chatListeners(html) { |   async chatListeners(html) { | ||||||
|     $(html).on("click", '.appel-chance', event => this.onClickAppelChance(event)) |     $(html).on("click", '.appel-chance', event => this.onClickAppelChance(event)) | ||||||
|     $(html).on("click", '.appel-destinee', event => this.onClickAppelDestinee(event)) |     $(html).on("click", '.appel-destinee', event => this.onClickAppelDestinee(event)) | ||||||
|  |     $(html).on("click", '.button-defense', event => this.onClickDefense(event)) | ||||||
|     $(html).on("click", '.encaissement', event => this.onClickEncaissement(event)) |     $(html).on("click", '.encaissement', event => this.onClickEncaissement(event)) | ||||||
|     $(html).on("click", '.resister-recul', event => this.onClickRecul(event)) |     $(html).on("click", '.resister-recul', event => this.onClickRecul(event)) | ||||||
|  |     $(html).on("click", '.choix-particuliere', event => this.onClickChoixParticuliere(event)) | ||||||
|  |     $(html).on("click", '.faire-gouter', event => this.onClickFaireGouter(event)) | ||||||
|  |     $(html).on("click", '.monter-tmr-normale', event => this.onClickMonteeTMR(event, 'normal')) | ||||||
|  |     $(html).on("click", '.monter-tmr-rapide', event => this.onClickMonteeTMR(event, 'rapide')) | ||||||
|  |     $(html).on("click", '.tirer-maladresse', event => this.onClickTirerMaladresse(event)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getCombat(roll) { |   getCombat(roll) { | ||||||
| @@ -92,15 +147,24 @@ export default class ChatRollResult { | |||||||
|       case ROLL_TYPE_DEFENSE: |       case ROLL_TYPE_DEFENSE: | ||||||
|         return RdDCombat.rddCombatForAttackerAndDefender(roll.ids.opponentId, roll.ids.opponentTokenId, roll.ids.actorTokenId) |         return RdDCombat.rddCombatForAttackerAndDefender(roll.ids.opponentId, roll.ids.opponentTokenId, roll.ids.actorTokenId) | ||||||
|       case ROLL_TYPE_ATTAQUE: |       case ROLL_TYPE_ATTAQUE: | ||||||
|         return RdDCombat.rddCombatForAttackerAndDefender(roll.ids.actorId, roll.ids.actorTokenId, roll.ids.opponentId) |         return RdDCombat.rddCombatForAttackerAndDefender(roll.ids.actorId, roll.ids.actorTokenId, roll.ids.opponentTokenId) | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async saveChatMessageRoll(chatMessage, savedRoll) { | ||||||
|  |     await ChatUtility.setMessageData(chatMessage, 'rollData', savedRoll) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   loadChatMessageRoll(chatMessage) { | ||||||
|  |     return ChatUtility.getMessageData(chatMessage, 'rollData') | ||||||
|  |   } | ||||||
|  |  | ||||||
|   async updateChatMessage(chatMessage, savedRoll) { |   async updateChatMessage(chatMessage, savedRoll) { | ||||||
|     ChatUtility.setMessageData(chatMessage, 'rollData', savedRoll) |     await this.saveChatMessageRoll(chatMessage, savedRoll) | ||||||
|     const copy = foundry.utils.duplicate(savedRoll) |     const copy = foundry.utils.duplicate(savedRoll) | ||||||
|     RollDialog.loadRollData(copy) |     RollDialog.loadRollData(copy) | ||||||
|  |     savedRoll.dmg = copy.current.attaque?.dmg | ||||||
|     this.prepareDisplay(copy) |     this.prepareDisplay(copy) | ||||||
|     chatMessage.update({ content: await this.buildRollHtml(copy) }) |     chatMessage.update({ content: await this.buildRollHtml(copy) }) | ||||||
|     chatMessage.render(true) |     chatMessage.render(true) | ||||||
| @@ -108,7 +172,7 @@ export default class ChatRollResult { | |||||||
|  |  | ||||||
|   onClickAppelChance(event) { |   onClickAppelChance(event) { | ||||||
|     const chatMessage = ChatUtility.getChatMessage(event) |     const chatMessage = ChatUtility.getChatMessage(event) | ||||||
|     const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData') |     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||||
|     const actor = game.actors.get(savedRoll.ids.actorId) |     const actor = game.actors.get(savedRoll.ids.actorId) | ||||||
|     actor.rollAppelChance( |     actor.rollAppelChance( | ||||||
|       () => this.onAppelChanceSuccess(savedRoll, chatMessage), |       () => this.onAppelChanceSuccess(savedRoll, chatMessage), | ||||||
| @@ -116,10 +180,13 @@ export default class ChatRollResult { | |||||||
|     event.preventDefault() |     event.preventDefault() | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   onAppelChanceSuccess(savedRoll, chatMessage) { |   async onAppelChanceSuccess(savedRoll, chatMessage) { | ||||||
|     const reRoll = foundry.utils.duplicate(savedRoll) |     const reRoll = foundry.utils.duplicate(savedRoll) | ||||||
|  |     console.log('onAppelChanceSuccess savedRoll', savedRoll) | ||||||
|     reRoll.type.retry = true |     reRoll.type.retry = true | ||||||
|  |     await this.updateChatMessage(chatMessage, reRoll) | ||||||
|     const callbacks = [r => ChatUtility.removeChatMessageId(chatMessage.id)] |     const callbacks = [r => ChatUtility.removeChatMessageId(chatMessage.id)] | ||||||
|  |  | ||||||
|     // TODO: annuler les effets |     // TODO: annuler les effets | ||||||
|     switch (reRoll.type.current) { |     switch (reRoll.type.current) { | ||||||
|       case ROLL_TYPE_DEFENSE: |       case ROLL_TYPE_DEFENSE: | ||||||
| @@ -142,7 +209,7 @@ export default class ChatRollResult { | |||||||
|  |  | ||||||
|   onClickAppelDestinee(event) { |   onClickAppelDestinee(event) { | ||||||
|     const chatMessage = ChatUtility.getChatMessage(event) |     const chatMessage = ChatUtility.getChatMessage(event) | ||||||
|     const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData') |     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||||
|     const actor = game.actors.get(savedRoll.ids.actorId) |     const actor = game.actors.get(savedRoll.ids.actorId) | ||||||
|  |  | ||||||
|     actor.appelDestinee(async () => { |     actor.appelDestinee(async () => { | ||||||
| @@ -153,23 +220,46 @@ export default class ChatRollResult { | |||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async onClickDefense(event) { | ||||||
|  |     const chatMessage = ChatUtility.getChatMessage(event) | ||||||
|  |     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||||
|  |     const attackerRoll = savedRoll.attackerRoll | ||||||
|  |     this.getCombat(attackerRoll)?.defenseV2(attackerRoll, | ||||||
|  |       [roll => { ChatUtility.removeChatMessageId(chatMessage.id) }] | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   async onClickEncaissement(event) { |   async onClickEncaissement(event) { | ||||||
|     const chatMessage = ChatUtility.getChatMessage(event) |     const chatMessage = ChatUtility.getChatMessage(event) | ||||||
|     const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData') |     const isMessageDemande = ChatUtility.getMessageData(chatMessage, 'demande-defense') | ||||||
|  |     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||||
|     const attaque = savedRoll.attackerRoll |     const attaque = savedRoll.attackerRoll | ||||||
|     const defender = game.actors.get(savedRoll.ids.actorId) |  | ||||||
|     const attacker = game.actors.get(savedRoll.ids.opponentId) |  | ||||||
|     const defenderToken = savedRoll.ids.actorTokenId ? canvas.tokens.get(savedRoll.ids.actorTokenId) : undefined |     const defenderToken = savedRoll.ids.actorTokenId ? canvas.tokens.get(savedRoll.ids.actorTokenId) : undefined | ||||||
|     const attackerToken = savedRoll.ids.opponentTokenId ? canvas.tokens.get(savedRoll.ids.opponentTokenId) : undefined |     const attackerToken = savedRoll.ids.opponentTokenId ? canvas.tokens.get(savedRoll.ids.opponentTokenId) : undefined | ||||||
|     await defender?.encaisserDommages(attaque.dmg, attacker, undefined, attackerToken, defenderToken) |     switch (attaque.dmg.mortalite) { | ||||||
|  |       case RDD_CONFIG.encaissement.empoignade: | ||||||
|     savedRoll.done.encaissement = true |         savedRoll.done = savedRoll.done ?? {} | ||||||
|     await this.updateChatMessage(chatMessage, savedRoll) |         savedRoll.done.empoignade = await RdDEmpoignade.ajustementEmpoignade(attackerToken.actor, defenderToken.actor) | ||||||
|  |         break | ||||||
|  |       case RDD_CONFIG.encaissement.entiteincarnee: | ||||||
|  |       case RDD_CONFIG.encaissement.nonmortel: | ||||||
|  |       case RDD_CONFIG.encaissement.mortel: | ||||||
|  |         const defender = defenderToken?.actor ?? game.actors.get(savedRoll.ids.actorId) | ||||||
|  |         const attacker = attackerToken?.actor ?? game.actors.get(savedRoll.ids.opponentId) | ||||||
|  |         await defender?.encaisserDommages(attaque.dmg, attacker, undefined, attackerToken, defenderToken) | ||||||
|  |         break | ||||||
|  |     } | ||||||
|  |     if (isMessageDemande) { | ||||||
|  |       ChatUtility.removeChatMessageId(chatMessage.id) | ||||||
|  |     } else { | ||||||
|  |       savedRoll.done.encaissement = true | ||||||
|  |       await this.updateChatMessage(chatMessage, savedRoll) | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async onClickRecul(event) { |   async onClickRecul(event) { | ||||||
|     const chatMessage = ChatUtility.getChatMessage(event) |     const chatMessage = ChatUtility.getChatMessage(event) | ||||||
|     const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData') |     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||||
|     const defender = game.actors.get(savedRoll.ids.actorId) |     const defender = game.actors.get(savedRoll.ids.actorId) | ||||||
|     const attacker = game.actors.get(savedRoll.ids.opponentId) |     const attacker = game.actors.get(savedRoll.ids.opponentId) | ||||||
|     savedRoll.done.recul = await defender.encaisserRecul(attacker.getForce(), savedRoll.attackerRoll.dmg.dmgArme) |     savedRoll.done.recul = await defender.encaisserRecul(attacker.getForce(), savedRoll.attackerRoll.dmg.dmgArme) | ||||||
| @@ -177,4 +267,40 @@ export default class ChatRollResult { | |||||||
|     await this.updateChatMessage(chatMessage, savedRoll) |     await this.updateChatMessage(chatMessage, savedRoll) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async onClickChoixParticuliere(event) { | ||||||
|  |     const choix = event.currentTarget.attributes['data-particuliere'].value | ||||||
|  |     const chatMessage = ChatUtility.getChatMessage(event) | ||||||
|  |     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||||
|  |     savedRoll.particuliere = choix | ||||||
|  |     savedRoll.particulieres = [RDD_CONFIG.particuliere[choix]] | ||||||
|  |     await this.updateChatMessage(chatMessage, savedRoll) | ||||||
|  |     await this.getCombat(savedRoll)?.onAttaqueV2(savedRoll) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async onClickFaireGouter(event) { | ||||||
|  |     const chatMessage = ChatUtility.getChatMessage(event) | ||||||
|  |     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||||
|  |     if (!savedRoll.type.retry) { | ||||||
|  |       savedRoll.type.retry = true | ||||||
|  |       await this.updateChatMessage(chatMessage, savedRoll) | ||||||
|  |     } | ||||||
|  |     await new RollTypeCuisine().onFaireGouter(savedRoll) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async onClickMonteeTMR(event, mode) { | ||||||
|  |     const chatMessage = ChatUtility.getChatMessage(event) | ||||||
|  |     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||||
|  |     if (await new RollTypeMeditation().onMonteeTMR(savedRoll, mode)) { | ||||||
|  |       savedRoll.done.meditation = true | ||||||
|  |       await this.updateChatMessage(chatMessage, savedRoll) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   async onClickTirerMaladresse(event) { | ||||||
|  |     const chatMessage = ChatUtility.getChatMessage(event) | ||||||
|  |     const typeMaladresse = event.currentTarget.attributes['data-maladresse'].value | ||||||
|  |     const savedRoll = this.loadChatMessageRoll(chatMessage) | ||||||
|  |     savedRoll.maladresse = await RdDRollTables.getMaladresse({ arme: typeMaladresse == 'avec-arme', toChat: false }) | ||||||
|  |     savedRoll.type.retry = true | ||||||
|  |     await this.updateChatMessage(chatMessage, savedRoll) | ||||||
|  |   } | ||||||
| } | } | ||||||
| @@ -1,44 +1,46 @@ | |||||||
| import { ActorToken } from "../actor-token.mjs" | import { TokenActor } from "../technical/actor-token.mjs" | ||||||
| import { StatusEffects } from "../settings/status-effects.js" | import { StatusEffects } from "../settings/status-effects.js" | ||||||
| import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" | import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" | ||||||
| import { PART_ATTAQUE } from "./roll-part-attaque.mjs" | import { PART_ATTAQUE } from "./roll-part-attaque.mjs" | ||||||
| import { PART_DEFENSE } from "./roll-part-defense.mjs" | import { PART_DEFENSE } from "./roll-part-defense.mjs" | ||||||
|  |  | ||||||
|  |  | ||||||
| export class RollBasicParts { | export class RollBasicParts { | ||||||
|  |  | ||||||
|   restore(rollData) { |   static restore(rollData) { | ||||||
|     rollData.ids.sceneId = rollData.ids.sceneId ?? canvas.scene.id |     rollData.ids.sceneId = rollData.ids.sceneId ?? canvas.scene.id | ||||||
|     rollData.active = RollBasicParts.$getActor(rollData) |     rollData.active = RollBasicParts.getTokenActor(rollData) | ||||||
|     rollData.opponent = RollBasicParts.$getOpponent(rollData) |     rollData.opponent = RollBasicParts.getTokenActorOpponent(rollData) | ||||||
|     if (rollData.type.opposed == undefined) { |     if (rollData.type.opposed == undefined) { | ||||||
|       rollData.type.opposed = rollData.opponent != null |       rollData.type.opposed = rollData.opponent != null | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   loadSurprises(rollData, type) { |   static loadSurprises(rollData, type = rollData.type.current) { | ||||||
|     if (!rollData.type.passif) { |     if (!rollData.type.passif) { | ||||||
|       this.loadSurprise(rollData.active, this.getForceRequiseActiveActor(rollData, type)) |       RollBasicParts.loadSurprise(rollData.active, RollBasicParts.getForceRequiseActiveActor(rollData, type)) | ||||||
|       this.loadSurprise(rollData.opponent, 0) |       RollBasicParts.loadSurprise(rollData.opponent, 0) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   loadSurprise(who, forceRequise) { |   static loadSurprise(who, forceRequise) { | ||||||
|     if (who?.actor) { |     if (who?.actor) { | ||||||
|       foundry.utils.mergeObject(who, |       foundry.utils.mergeObject(who, | ||||||
|         StatusEffects.getActorEffetSurprise(who.actor, forceRequise), |         StatusEffects.getActorEffetSurprise(who.actor), | ||||||
|         { overwrite: true, inPlace: true }) |         { overwrite: true, inPlace: true }) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getForceRequiseActiveActor(rollData, type) { |   static getForceRequiseActiveActor(rollData, type) { | ||||||
|     switch (type) { |     switch (type) { | ||||||
|       case ROLL_TYPE_ATTAQUE: return rollData.current[PART_ATTAQUE].attaque.forceRequise |       case ROLL_TYPE_ATTAQUE: return rollData.current[PART_ATTAQUE].forceRequise | ||||||
|       case ROLL_TYPE_DEFENSE: return rollData.current[PART_DEFENSE].forceRequise |       case ROLL_TYPE_DEFENSE: return rollData.current[PART_DEFENSE].forceRequise | ||||||
|       default: return 0 |       default: return 0 | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   initFrom(rollData) { |   static initFrom(rollData) { | ||||||
|  |     const isOpposed = rollData.type.opposed && rollData.opponent | ||||||
|     return { |     return { | ||||||
|       selected: {}, |       selected: {}, | ||||||
|       type: rollData.type, |       type: rollData.type, | ||||||
| @@ -46,36 +48,60 @@ export class RollBasicParts { | |||||||
|         sceneId: rollData.ids.sceneId, |         sceneId: rollData.ids.sceneId, | ||||||
|         actorId: rollData.active.id, |         actorId: rollData.active.id, | ||||||
|         actorTokenId: rollData.active.tokenId, |         actorTokenId: rollData.active.tokenId, | ||||||
|         opponentId: rollData.type.opposed ? rollData.opponent.id : undefined, |         opponentId: isOpposed ? rollData.opponent.id : undefined, | ||||||
|         opponentTokenId: rollData.type.opposed ? rollData.opponent.tokenId : undefined, |         opponentTokenId: isOpposed ? rollData.opponent.tokenId : undefined, | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static $getActor(rollData) { |   static prepareDefense(attackerRoll) { | ||||||
|  |     if (!attackerRoll.passeArme) { | ||||||
|  |       attackerRoll.passeArme = foundry.utils.randomID(16); | ||||||
|  |     } | ||||||
|  |     return { | ||||||
|  |       ids: RollBasicParts.reverseIds(attackerRoll), | ||||||
|  |       active: attackerRoll.opponent, | ||||||
|  |       opponent: attackerRoll.active, | ||||||
|  |       attackerRoll: attackerRoll, | ||||||
|  |       passeArme: attackerRoll.passeArme, | ||||||
|  |       show: { encaissement: true } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static reverseIds(rollData) { | ||||||
|  |     return { | ||||||
|  |       sceneId: rollData.ids.sceneId, | ||||||
|  |       actorId: rollData.ids.opponentId, | ||||||
|  |       actorTokenId: rollData.ids.opponentTokenId, | ||||||
|  |       opponentId: rollData.ids.actorId, | ||||||
|  |       opponentTokenId: rollData.ids.actorTokenId | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static getTokenActor(rollData) { | ||||||
|     if (rollData.ids.actorTokenId) { |     if (rollData.ids.actorTokenId) { | ||||||
|       return ActorToken.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId) |       return TokenActor.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId) | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       const actorId = rollData.ids.actorId ?? (canvas.tokens.controlled.length == 1 |       const actorId = rollData.ids.actorId ?? (canvas.tokens.controlled.length == 1 | ||||||
|         /** TODO: jets de plusieurs personnages??? */ |         /** TODO: jets de plusieurs personnages??? */ | ||||||
|         ? canvas.tokens.controlled[0] |         ? canvas.tokens.controlled[0] | ||||||
|         : undefined) |         : undefined) | ||||||
|       return ActorToken.fromActorId(actorId, () => { throw new Error("Pas d'acteur sélectionné") }) |       return TokenActor.fromActorId(actorId, () => { throw new Error("Pas d'acteur sélectionné") }) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static $getOpponent(rollData) { |   static getTokenActorOpponent(rollData) { | ||||||
|     if (rollData.ids.opponentTokenId) { |     if (rollData.ids.opponentTokenId) { | ||||||
|       return ActorToken.fromTokenId(rollData.ids.opponentTokenId, rollData.ids.sceneId) |       return TokenActor.fromTokenId(rollData.ids.opponentTokenId, rollData.ids.sceneId) | ||||||
|     } |     } | ||||||
|     else if (rollData.ids.opponentId) { |     else if (rollData.ids.opponentId) { | ||||||
|       return ActorToken.fromActorId(rollData.ids.opponentId) |       return TokenActor.fromActorId(rollData.ids.opponentId) | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       const targets = Array.from(game.user.targets) |       const targets = Array.from(game.user.targets) | ||||||
|       if (targets.length == 1) { |       if (targets.length == 1) { | ||||||
|         return ActorToken.fromToken(targets[0]) |         return TokenActor.fromToken(targets[0]) | ||||||
|       } |       } | ||||||
|       else { |       else { | ||||||
|         return undefined |         return undefined | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
|  |  | ||||||
| export const ROLL_TYPE_ATTAQUE = 'attaque' | export const ROLL_TYPE_ATTAQUE = 'attaque' | ||||||
| export const ROLL_TYPE_COMP = 'comp' | export const ROLL_TYPE_COMP = 'comp' | ||||||
|  | export const ROLL_TYPE_CUISINE = 'cuisine' | ||||||
| export const ROLL_TYPE_DEFENSE = 'defense' | export const ROLL_TYPE_DEFENSE = 'defense' | ||||||
| export const ROLL_TYPE_JEU = 'jeu' | export const ROLL_TYPE_JEU = 'jeu' | ||||||
| export const ROLL_TYPE_MEDITATION = 'meditation' | export const ROLL_TYPE_MEDITATION = 'meditation' | ||||||
| @@ -8,6 +9,12 @@ export const ROLL_TYPE_OEUVRE = 'oeuvre' | |||||||
| export const ROLL_TYPE_SORT = 'sort' | export const ROLL_TYPE_SORT = 'sort' | ||||||
| export const ROLL_TYPE_TACHE = 'tache' | export const ROLL_TYPE_TACHE = 'tache' | ||||||
|  |  | ||||||
|  | export const ATTAQUE_ROLL_TYPES = [ROLL_TYPE_ATTAQUE] | ||||||
|  | export const COMBAT_ROLL_TYPES = [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE] | ||||||
|  | export const DEMIREVE_ROLL_TYPES = [ROLL_TYPE_SORT] | ||||||
|  | export const DEFAULT_ROLL_TYPES = [ROLL_TYPE_COMP, ROLL_TYPE_ATTAQUE, ROLL_TYPE_TACHE, ROLL_TYPE_MEDITATION, ROLL_TYPE_CUISINE, ROLL_TYPE_OEUVRE, ROLL_TYPE_JEU] | ||||||
|  |  | ||||||
|  |  | ||||||
| export const DIFF = { | export const DIFF = { | ||||||
|   LIBRE: 'libre', |   LIBRE: 'libre', | ||||||
|   ATTAQUE: 'attaque', |   ATTAQUE: 'attaque', | ||||||
|   | |||||||
| @@ -6,6 +6,10 @@ import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; | |||||||
| import { PART_OEUVRE } from "./roll-part-oeuvre.mjs"; | import { PART_OEUVRE } from "./roll-part-oeuvre.mjs"; | ||||||
| import { RdDItemArme } from "../item/arme.js"; | import { RdDItemArme } from "../item/arme.js"; | ||||||
| import { RdDBonus } from "../rdd-bonus.js"; | import { RdDBonus } from "../rdd-bonus.js"; | ||||||
|  | import { ITEM_TYPES, RDD_CONFIG } from "../constants.js"; | ||||||
|  | import { CARACS } from "../rdd-carac.js"; | ||||||
|  | import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE, ROLL_TYPE_OEUVRE } from "./roll-constants.mjs"; | ||||||
|  | import { PART_ATTAQUE } from "./roll-part-attaque.mjs"; | ||||||
|  |  | ||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export class RollDialogAdapter { | export class RollDialogAdapter { | ||||||
| @@ -15,21 +19,22 @@ export class RollDialogAdapter { | |||||||
|       carac: rollData.current.carac.value, |       carac: rollData.current.carac.value, | ||||||
|       diff: rollData.current.totaldiff, |       diff: rollData.current.totaldiff, | ||||||
|       bonus: rollData.current.bonus, |       bonus: rollData.current.bonus, | ||||||
|       sign: rollData.current.sign, |  | ||||||
|       showDice: rollData.options.showDice, |       showDice: rollData.options.showDice, | ||||||
|       rollMode: rollData.current.rollmode.key |       rollMode: rollData.current.rollmode.key | ||||||
|     }) |     }) | ||||||
|  |  | ||||||
|     const rolled = await RollDialogAdapter.rollChances(rollData, chances) |     const rolled = await RollDialogAdapter.rollChances(rollData, chances) | ||||||
|     RollDialogAdapter.adjustRollDataForV1(rollData, rolled, rollTitle) |     RollDialogAdapter.setRollDataRolled(rollData, rolled, rollTitle) | ||||||
|  |     RollDialogAdapter.adjustRollDataForV1(rollData) | ||||||
|  |     RollDialogAdapter.adjustAttaqueParticuliere(rollData) | ||||||
|  |     RollDialogAdapter.adjustAttaqueDmg(rollData) | ||||||
|  |     RollDialogAdapter.adjustDemiSurprise(rollData) | ||||||
|     return rolled |     return rolled | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static computeChances({ carac, diff, bonus, sign, showDice, rollMode }) { |   static computeChances({ carac, diff, bonus, showDice, rollMode }) { | ||||||
|     const chances = foundry.utils.duplicate(RdDResolutionTable.computeChances(carac, diff)) |     const chances = foundry.utils.duplicate(RdDResolutionTable.computeChances(carac, diff)) | ||||||
|     RdDResolutionTable._updateChancesWithBonus(chances, bonus, diff) |     RdDResolutionTable._updateChancesWithBonus(chances, bonus, diff) | ||||||
|     RdDResolutionTable._updateChancesFactor(chances, sign) |  | ||||||
|     chances.showDice = showDice |     chances.showDice = showDice | ||||||
|     chances.rollMode = rollMode |     chances.rollMode = rollMode | ||||||
|     return chances |     return chances | ||||||
| @@ -37,58 +42,112 @@ export class RollDialogAdapter { | |||||||
|  |  | ||||||
|   static async rollChances(rollData, chances) { |   static async rollChances(rollData, chances) { | ||||||
|     const rolled = await RdDResolutionTable.rollChances(chances, |     const rolled = await RdDResolutionTable.rollChances(chances, | ||||||
|       rollData.current.sign, |       rollData.current.sign.diviseur, | ||||||
|       rollData.current.resultat) |       rollData.current.resultat) | ||||||
|     rolled.caracValue = rollData.current.carac.value |     rolled.caracValue = rollData.current.carac.value | ||||||
|     rolled.finalLevel = rollData.current.totaldiff |     rolled.finalLevel = rollData.current.totaldiff | ||||||
|     rolled.bonus = rollData.current.bonus ?? 0 |     rolled.bonus = rollData.current.bonus ?? 0 | ||||||
|     rolled.factorHtml = Misc.getFractionOneN(rollData.current.sign.diviseur) |     rolled.factorHtml = Misc.getFractionOneN(rollData.current.sign.diviseur) | ||||||
|  |     if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) { | ||||||
|  |       rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rolled.caracValue, rolled.roll) | ||||||
|  |       rolled.ajustementNecessaire = rolled.niveauNecessaire - diff | ||||||
|  |     } | ||||||
|     return rolled |     return rolled | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static adjustRollDataForV1(rollData, rolled, rollTitle) { |   static setRollDataRolled(rollData, rolled, rollTitle) { | ||||||
|  |     rollData.rolled = rolled | ||||||
|  |     rollData.choix = rollData.choix ?? {} | ||||||
|  |     rollData.show = rollData.show ?? {} | ||||||
|  |     rollData.show.title = rollTitle | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static adjustRollDataForV1(rollData) { | ||||||
|  |     const rolled = rollData.rolled | ||||||
|     // temporaire pour être homogène roll v1 |     // temporaire pour être homogène roll v1 | ||||||
|     rollData.alias = rollData.active.actor.getAlias() |     rollData.alias = rollData.active.actor.getAlias() | ||||||
|     // pour experience |     // pour experience | ||||||
|     rollData.finalLevel = rollData.current.totaldiff |     rollData.finalLevel = rollData.current.totaldiff | ||||||
|     if (rollData.use == undefined) { rollData.use = {} } |     if (rollData.use == undefined) { rollData.use = {} } | ||||||
|     if (rollData.show == undefined) { rollData.show = {} } |  | ||||||
|     if (rollData.ajustements == undefined) { |     if (rollData.ajustements == undefined) { | ||||||
|       rollData.ajustements = {} |       rollData.ajustements = {} | ||||||
|     } |     } | ||||||
|     rollData.selectedCarac = rollData.active.actor.system.carac[rollData.current.carac.key] |     rollData.selectedCarac = rollData.active.actor.getCaracByName(rollData.current.carac.key) | ||||||
|  |  | ||||||
|     const compKey = rollData.current.comp?.key |     const compKey = rollData.current.comp?.key | ||||||
|     if (compKey) { |     if (compKey) { | ||||||
|       rollData.competence = rollData.refs[PART_COMP].all.find(it => it.key == compKey)?.comp |       rollData.competence = rollData.refs[PART_COMP].all.find(it => it.key == compKey)?.comp | ||||||
|       rollData.jetResistance = rollData.type.jetResistance |       rollData.jetResistance = rollData.type.jetResistance | ||||||
|     } |     } | ||||||
|     const oeuvreKey = rollData.current.oeuvre?.key |     if (rollData.type.current == ROLL_TYPE_OEUVRE) { | ||||||
|     if (oeuvreKey) { |       const oeuvreKey = rollData.current.oeuvre?.key | ||||||
|       const oeuvreCurrent = rollData.current[PART_OEUVRE]; |       if (rollData.type.current == ROLL_TYPE_OEUVRE && oeuvreKey) { | ||||||
|       rollData.oeuvre = oeuvreCurrent.oeuvre |         const oeuvreCurrent = rollData.current[PART_OEUVRE]; | ||||||
|       // rollData.oeuvre = rollData.refs[PART_OEUVRE].oeuvres.find(it => it.key == oeuvreKey)?.oeuvre |         rollData.oeuvre = oeuvreCurrent.oeuvre | ||||||
|       rollData.art = oeuvreCurrent.art.type |         rollData.art = oeuvreCurrent.art.type | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|     // pour appel moral |     // pour appel moral | ||||||
|     rollData.diviseurSignificative = rollData.current.sign |     rollData.diviseurSignificative = rollData.current.sign | ||||||
|     if (rollData.current[PART_APPELMORAL]?.checked) { |     if (rollData.current[PART_APPELMORAL]?.checked) { | ||||||
|       rollData.use.moral = true |       rollData.use.moral = true | ||||||
|     } |     } | ||||||
|     rollData.rolled = rolled |  | ||||||
|     if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) { |     if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) { | ||||||
|       rolled.niveauNecessaire = this.findNiveauNecessaire(carac, rolled.roll) |       rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rollData.selectedCarac.value, rolled.roll) | ||||||
|       rolled.ajustementNecessaire = rolled.niveauNecessaire - diff |       rolled.ajustementNecessaire = rolled.niveauNecessaire - diff | ||||||
|     } |     } | ||||||
|     rollData.ajustements = rollData.ajustements.map(aj => { |     rollData.ajustements = rollData.ajustements.map(a => { return { label: a.label, value: a.value } }) | ||||||
|       return { |   } | ||||||
|         used: true, |  | ||||||
|         label: aj.label, |   static adjustDemiSurprise(rollData) { | ||||||
|         value: aj.diff, |     if (rollData.active.surprise == 'demi' && rollData.rolled.isPart) { | ||||||
|         descr: aj.diff == undefined ? aj.label : undefined |       RdDResolutionTable.replaceParticuliereDemiSurprise(rollData.rolled) | ||||||
|       } |     } | ||||||
|     }) |   } | ||||||
|     rollData.show.title = rollTitle |  | ||||||
|  |   static adjustAttaqueDmg(rollData) { | ||||||
|  |     switch (rollData.type.current) { | ||||||
|  |       case ROLL_TYPE_ATTAQUE: | ||||||
|  |         rollData.dmg = RdDBonus.dmgRollV2(rollData, rollData.current.attaque) | ||||||
|  |         break | ||||||
|  |       case ROLL_TYPE_DEFENSE: | ||||||
|  |         rollData.dmg = RdDBonus.dmgRollV2(rollData.attackerRoll, rollData.attackerRoll.current.attaque) | ||||||
|  |         break | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   static adjustAttaqueParticuliere(rollData) { | ||||||
|  |     if (rollData.type.current != ROLL_TYPE_ATTAQUE || !rollData.rolled.isPart) { | ||||||
|  |       return | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const attaque = rollData.current.attaque; | ||||||
|  |     const choix = [] | ||||||
|  |     const isEmpoignade = attaque.dmg.isEmpoignade | ||||||
|  |     const isCharge = attaque.tactique == 'charge' | ||||||
|  |     /* TODO: cas de créatures faisant des lancers, Glou, Glipzouk */ | ||||||
|  |     const isMeleeDiffNegative = (attaque.comp.type == ITEM_TYPES.competencecreature || rollData.current.carac.key == CARACS.MELEE) | ||||||
|  |       && rollData.current.diff.value < 0 | ||||||
|  |  | ||||||
|  |     // force toujours, sauf empoignade | ||||||
|  |     if (!isEmpoignade) { | ||||||
|  |       choix.push(RDD_CONFIG.particuliere.force) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum | ||||||
|  |     if (!isCharge && (isEmpoignade || isMeleeDiffNegative)) { | ||||||
|  |       choix.push(RDD_CONFIG.particuliere.finesse) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // rapidité seulement en mêlée, si l'arme le permet, et si la difficulté libre est de -1 minimum | ||||||
|  |     if (!isCharge && !isEmpoignade && isMeleeDiffNegative && attaque.arme.system.rapide) { | ||||||
|  |       choix.push(RDD_CONFIG.particuliere.rapidite) | ||||||
|  |     } | ||||||
|  |     if (choix.length == 1) { | ||||||
|  |       rollData.particuliere = choix[0].key | ||||||
|  |     } | ||||||
|  |     rollData.particulieres = choix | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static mapActionAttaque(attackerRoll) { |   static mapActionAttaque(attackerRoll) { | ||||||
| @@ -99,17 +158,13 @@ export class RollDialogAdapter { | |||||||
|     return { |     return { | ||||||
|       // correspond à l'attaque de RollPartAttaque (dans rollDta.current.attaque) |       // correspond à l'attaque de RollPartAttaque (dans rollDta.current.attaque) | ||||||
|       label: label, |       label: label, | ||||||
|       attaque: { |       // correspond aux actions d'attaques dans RdDActor.listActionsAttaque | ||||||
|         // correspond aux actions d'attaques dans RdDActor.listActionsAttaque |       name: label, | ||||||
|         name: label, |       // action: 'attaque', | ||||||
|         // action: 'attaque', |       arme: attackerRoll.arme, | ||||||
|         arme: attackerRoll.arme, |       comp: attackerRoll.competence, | ||||||
|         comp: attackerRoll.competence, |       main: RdDItemArme.getMainAttaque(attackerRoll.competence), | ||||||
|         main: RdDItemArme.getMainAttaque(attackerRoll.competence), |       equipe: attackerRoll.arme.system.equipe, | ||||||
|         equipe: attackerRoll.arme.system.equipe, |  | ||||||
|         // carac: { key: caracCode, value: caracValue }, |  | ||||||
|         // dommagesArme: dommagesArme, |  | ||||||
|       }, |  | ||||||
|       diff: attackerRoll.diffLibre, |       diff: attackerRoll.diffLibre, | ||||||
|       particuliere: attackerRoll.particuliere, |       particuliere: attackerRoll.particuliere, | ||||||
|       tactique: RdDBonus.find(attackerRoll.tactique), |       tactique: RdDBonus.find(attackerRoll.tactique), | ||||||
|   | |||||||
| @@ -39,26 +39,31 @@ import { RollDialogAdapter } from "./roll-dialog-adapter.mjs"; | |||||||
| import { ROLLDIALOG_SECTION } from "./roll-part.mjs"; | import { ROLLDIALOG_SECTION } from "./roll-part.mjs"; | ||||||
| import { ROLL_TYPE_COMP } from "./roll-constants.mjs"; | import { ROLL_TYPE_COMP } from "./roll-constants.mjs"; | ||||||
| import ChatRollResult from "./chat-roll-result.mjs"; | import ChatRollResult from "./chat-roll-result.mjs"; | ||||||
|  | import { renderTemplate } from "../constants.js"; | ||||||
|  | import { RollTypeCuisine } from "./roll-type-cuisine.mjs"; | ||||||
|  | import { RollPartCuisine } from "./roll-part-cuisine.mjs"; | ||||||
|  | import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js"; | ||||||
|  | import { ActorImpacts } from "../technical/actor-impacts.mjs"; | ||||||
|  | import { RollPartEmpoignade } from "./roll-part-empoignade.mjs"; | ||||||
|  | import { RollPartEmpoignadeTaille } from "./roll-part-empoignade-taille.mjs"; | ||||||
|  |  | ||||||
|  |  | ||||||
| const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api | const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api | ||||||
| const doNothing = (dialog) => { } |  | ||||||
|  |  | ||||||
| const ALL_ROLL_TYPES = [ | export const ALL_ROLL_TYPES = [ | ||||||
|   new RollTypeComp(), |   new RollTypeComp(), | ||||||
|   new RollTypeTache(), |   new RollTypeTache(), | ||||||
|   new RollTypeAttaque(), |   new RollTypeAttaque(), | ||||||
|   new RollTypeDefense(), |   new RollTypeDefense(), | ||||||
|   new RollTypeSort(), |   new RollTypeSort(), | ||||||
|   new RollTypeMeditation(), |   new RollTypeMeditation(), | ||||||
|  |   new RollTypeCuisine(), | ||||||
|   new RollTypeOeuvre(), |   new RollTypeOeuvre(), | ||||||
|   new RollTypeJeu(), |   new RollTypeJeu(), | ||||||
|   // new RollTypeResistance ?? |   // new RollTypeResistance ?? | ||||||
|   // new RollTypeFixedCarac ?? |   // new RollTypeFixedCarac ?? | ||||||
| ] | ] | ||||||
|  |  | ||||||
| const BASIC_PARTS = new RollBasicParts() |  | ||||||
|  |  | ||||||
| const ROLL_PARTS = [ | const ROLL_PARTS = [ | ||||||
|   new RollPartActor(), |   new RollPartActor(), | ||||||
|   new RollPartAction(), |   new RollPartAction(), | ||||||
| @@ -72,6 +77,7 @@ const ROLL_PARTS = [ | |||||||
|   new RollPartMeditation(), |   new RollPartMeditation(), | ||||||
|   new RollPartSort(), |   new RollPartSort(), | ||||||
|   new RollPartTache(), |   new RollPartTache(), | ||||||
|  |   new RollPartCuisine(), | ||||||
|   new RollPartOeuvre(), |   new RollPartOeuvre(), | ||||||
|   new RollPartJeu(), |   new RollPartJeu(), | ||||||
|  |  | ||||||
| @@ -81,6 +87,8 @@ const ROLL_PARTS = [ | |||||||
|   new RollPartConditions(), |   new RollPartConditions(), | ||||||
|   new RollPartEthylisme(), |   new RollPartEthylisme(), | ||||||
|   new RollPartMalusArmure(), |   new RollPartMalusArmure(), | ||||||
|  |   new RollPartEmpoignadeTaille(), | ||||||
|  |   new RollPartEmpoignade(), | ||||||
|   new RollPartEncTotal(), |   new RollPartEncTotal(), | ||||||
|   new RollPartSurEnc(), |   new RollPartSurEnc(), | ||||||
|   new RollPartAppelMoral(), |   new RollPartAppelMoral(), | ||||||
| @@ -169,6 +177,15 @@ const ROLL_PARTS = [ | |||||||
| /* -------------------------------------------- */ | /* -------------------------------------------- */ | ||||||
| export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2) | export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2) | ||||||
| { | { | ||||||
|  |   static onCloseDoNothing() { | ||||||
|  |   } | ||||||
|  |   static onRollDoneDoNothing(dialog, roll) { | ||||||
|  |     dialog.render() | ||||||
|  |   } | ||||||
|  |   static onRollDoneClose(dialog, roll) { | ||||||
|  |     if (roll.type.retry || !OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST)) | ||||||
|  |       dialog.close() | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static init() { |   static init() { | ||||||
|   } |   } | ||||||
| @@ -186,7 +203,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|  |  | ||||||
|     ChatRollResult.onReady() |     ChatRollResult.onReady() | ||||||
|  |  | ||||||
|     foundry.applications.handlebars.loadTemplates(ALL_ROLL_TYPES.map(m => m.template)) |     foundry.applications.handlebars.loadTemplates(ALL_ROLL_TYPES.map(m => m.chatResultTemplate)) | ||||||
|     foundry.applications.handlebars.loadTemplates(ROLL_PARTS.map(p => p.template)) |     foundry.applications.handlebars.loadTemplates(ROLL_PARTS.map(p => p.template)) | ||||||
|     ROLL_PARTS.forEach(p => p.onReady()) |     ROLL_PARTS.forEach(p => p.onReady()) | ||||||
|  |  | ||||||
| @@ -224,6 +241,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|   static async create(rollData, rollOptions = {}) { |   static async create(rollData, rollOptions = {}) { | ||||||
|     const rollDialog = new RollDialog(rollData, rollOptions) |     const rollDialog = new RollDialog(rollData, rollOptions) | ||||||
|     rollDialog.render(true) |     rollDialog.render(true) | ||||||
|  |     return rollDialog | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static get PARTS() { |   static get PARTS() { | ||||||
| @@ -256,13 +274,13 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|     rollData.selected = rollData.selected ?? {} |     rollData.selected = rollData.selected ?? {} | ||||||
|     rollData.type = rollData.type ?? {} |     rollData.type = rollData.type ?? {} | ||||||
|     rollData.type.retry = rollData.type.retry ?? false |     rollData.type.retry = rollData.type.retry ?? false | ||||||
|     BASIC_PARTS.restore(rollData) |     RollBasicParts.restore(rollData) | ||||||
|  |  | ||||||
|     const potential = ALL_ROLL_TYPES.find(m => m.code == rollData.type.current)?.code |     const potential = ALL_ROLL_TYPES.find(m => m.code == rollData.type.current)?.code | ||||||
|     const allowed = rollData.type.retry && potential |     const allowed = rollData.type.retry && potential | ||||||
|       ? [potential] |       ? [potential] | ||||||
|       : (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code)) |       : (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code) ?? [ROLL_TYPE_COMP]) | ||||||
|     const rollType = allowed.find(c => c == rollData.type.current) ?? (allowed.length > 0 ? allowed[0].code : ROLL_TYPE_COMP); |     const rollType = allowed.find(c => c == rollData.type.current) ?? allowed[0] | ||||||
|  |  | ||||||
|     rollData.type.allowed = allowed |     rollData.type.allowed = allowed | ||||||
|     rollData.type.current = rollType |     rollData.type.current = rollType | ||||||
| @@ -272,29 +290,37 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|     rollData.options = rollData.options ?? { rollMode: game.settings.get("core", "rollMode") } |     rollData.options = rollData.options ?? { rollMode: game.settings.get("core", "rollMode") } | ||||||
|  |  | ||||||
|     ROLL_PARTS.forEach(p => p.initialize(rollData)) |     ROLL_PARTS.forEach(p => p.initialize(rollData)) | ||||||
|     ROLL_PARTS.forEach(p => p.restore(rollData)) |  | ||||||
|     ROLL_PARTS.filter(p => p.isValid(rollData)) |     ROLL_PARTS.filter(p => p.isValid(rollData)) | ||||||
|       .forEach(p => { |       .forEach(p => { | ||||||
|  |         p.restore(rollData) | ||||||
|         p.loadRefs(rollData) |         p.loadRefs(rollData) | ||||||
|         p.prepareContext(rollData) |         p.prepareContext(rollData) | ||||||
|       }) |       }) | ||||||
|     return rollData |     return rollData | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static saveParts(rollData) { |   static saveParts(rollData, impacts) { | ||||||
|     const target = BASIC_PARTS.initFrom(rollData) |     const target = RollBasicParts.initFrom(rollData) | ||||||
|     ROLL_PARTS.filter(p => p.isActive(rollData)) |     ROLL_PARTS.filter(p => p.isActive(rollData)) | ||||||
|       .forEach(p => p.storeClean(rollData, target)) |       .forEach(p => p.storeClean(rollData, target)) | ||||||
|     target.attackerRoll = rollData.attackerRoll |     target.attackerRoll = rollData.attackerRoll | ||||||
|     target.rolled = rollData.rolled |     target.rolled = rollData.rolled | ||||||
|     target.result = rollData.result |     target.result = rollData.result | ||||||
|     target.done = target.done ?? {} |     target.done = rollData.done ?? {} | ||||||
|  |     target.dmg = rollData.dmg | ||||||
|  |     if (impacts) { | ||||||
|  |       target.reverse = { | ||||||
|  |         active: impacts.active?.reverseImpacts(), | ||||||
|  |         opponent: impacts.opponent?.reverseImpacts() | ||||||
|  |       } | ||||||
|  |     } | ||||||
|     return target |     return target | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   constructor(rollData, rollOptions) { |   constructor(rollData, rollOptions) { | ||||||
|     super() |     super() | ||||||
|  |  | ||||||
|  |     this.hooks = [] | ||||||
|     this.rollData = RollDialog.$prepareRollData(rollData) |     this.rollData = RollDialog.$prepareRollData(rollData) | ||||||
|     this.rollOptions = { |     this.rollOptions = { | ||||||
|       callbacks: [ |       callbacks: [ | ||||||
| @@ -302,13 +328,28 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|         async r => await r.active.actor.appliquerAppelMoral(r), |         async r => await r.active.actor.appliquerAppelMoral(r), | ||||||
|         ...(rollOptions.callbacks ?? []) |         ...(rollOptions.callbacks ?? []) | ||||||
|       ], |       ], | ||||||
|       customChatMessage: rollOptions.customChatMessage, |       onRollDone: rollOptions.onRollDone ?? RollDialog.onRollDoneDoNothing, | ||||||
|       onRollDone: rollOptions.onRollDone ?? doNothing |       onClose: rollOptions.onClose ?? RollDialog.onCloseDoNothing | ||||||
|     } |     } | ||||||
|     this.chatRollResult = new ChatRollResult(); |     this.chatRollResult = new ChatRollResult() | ||||||
|     this.selectType() |     this.selectType() | ||||||
|  |     this.registerHooks(rollData); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   registerHooks(rollData) { | ||||||
|  |     ROLL_PARTS.filter(p => p.isValid(rollData)) | ||||||
|  |       .forEach(p => p.getHooks(this).forEach(h => { | ||||||
|  |         const hook = h.hook; | ||||||
|  |         const id = Hooks.on(hook, h.fn) | ||||||
|  |         this.hooks.push({ hook, id }) | ||||||
|  |       })) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   unregisterHooks() { | ||||||
|  |     this.hooks.forEach(h => Hooks.off(h.hook, h.id)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   selectType() { |   selectType() { | ||||||
|     const selectedType = this.getSelectedType(); |     const selectedType = this.getSelectedType(); | ||||||
|     this.rollData.type.label = selectedType.title(this.rollData) |     this.rollData.type.label = selectedType.title(this.rollData) | ||||||
| @@ -324,16 +365,16 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|     return ROLL_PARTS.filter(p => p.isActive(rollData)) |     return ROLL_PARTS.filter(p => p.isActive(rollData)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // get title() { |  | ||||||
|   //   return this.rollData.title ?? `Jet de dés de ${this.rollData.active.actor.name}` |  | ||||||
|   // } |  | ||||||
|  |  | ||||||
|   rollTitle(rollData) { |   rollTitle(rollData) { | ||||||
|     return rollData.label ?? ROLL_PARTS |     const title = rollData.label ?? ROLL_PARTS | ||||||
|       .filter(it => it.section == ROLLDIALOG_SECTION.ACTION) |       .filter(it => it.section == ROLLDIALOG_SECTION.ACTION) | ||||||
|       .filter(it => it.isActive(rollData)) |       .filter(it => it.isActive(rollData)) | ||||||
|       .map(it => it.title(rollData)) |       .map(it => it.title(rollData)) | ||||||
|       .reduce(Misc.joining(' ')) |       .reduce(Misc.joining(' ')); | ||||||
|  |     if (this.rollOptions.title) { | ||||||
|  |       return `${this.rollOptions.title} ${title}` | ||||||
|  |     } | ||||||
|  |     return title | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async _onRender(context, options) { |   async _onRender(context, options) { | ||||||
| @@ -364,11 +405,11 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|     return RollDialog.getActiveParts(rollData) |     return RollDialog.getActiveParts(rollData) | ||||||
|       .map(p => p.getAjustements(rollData)) |       .map(p => p.getAjustements(rollData)) | ||||||
|       .reduce((a, b) => a.concat(b)) |       .reduce((a, b) => a.concat(b)) | ||||||
|       .sort((a, b) => a.diff == undefined ? 1 : b.diff == undefined ? -1 : 0) |       .sort((a, b) => a.value == undefined ? 1 : b.value == undefined ? -1 : 0) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async buildHTMLTable(carac, diff) { |   async buildHTMLTable(carac, diff) { | ||||||
|     return await foundry.applications.handlebars.renderTemplate('roll-table', { carac, diff }) |     return await renderTemplate('roll-table', { carac, diff }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async _prepareContext() { |   async _prepareContext() { | ||||||
| @@ -376,7 +417,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|  |  | ||||||
|     const types = ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)) |     const types = ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)) | ||||||
|       .map(m => m.toTypeData(rollData)) |       .map(m => m.toTypeData(rollData)) | ||||||
|     BASIC_PARTS.loadSurprises(rollData, this.getSelectedType().code) |     RollBasicParts.loadSurprises(rollData, this.getSelectedType().code) | ||||||
|     rollData.type.label = this.getSelectedType()?.title(rollData) |     rollData.type.label = this.getSelectedType()?.title(rollData) | ||||||
|     //TOCHECK: set type.label ? |     //TOCHECK: set type.label ? | ||||||
|     const visibleRollParts = RollDialog.getActiveParts(rollData) |     const visibleRollParts = RollDialog.getActiveParts(rollData) | ||||||
| @@ -386,7 +427,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|  |  | ||||||
|     visibleRollParts.forEach(p => p.prepareContext(rollData)) |     visibleRollParts.forEach(p => p.prepareContext(rollData)) | ||||||
|  |  | ||||||
|     RollDialog.calculAjustements(rollData) |     RollDialog.calculAjustement(rollData) | ||||||
|  |  | ||||||
|     const templates = RollDialog.getActiveParts(rollData).map(p => p.toTemplateData()) |     const templates = RollDialog.getActiveParts(rollData).map(p => p.toTemplateData()) | ||||||
|     const context = await super._prepareContext() |     const context = await super._prepareContext() | ||||||
| @@ -408,12 +449,11 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static calculAjustements(rollData) { |   static calculAjustement(rollData) { | ||||||
|     rollData.ajustements = RollDialog.getAjustements(rollData) |     rollData.ajustements = RollDialog.getAjustements(rollData) | ||||||
|     rollData.ajustements.forEach(it => it.isDiff = it.diff != undefined) |  | ||||||
|     rollData.current.totaldiff = rollData.ajustements |     rollData.current.totaldiff = rollData.ajustements | ||||||
|       .map(adj => adj.diff) |       .filter(a => a.value != undefined) | ||||||
|       .filter(d => d != undefined) |       .map(a => a.value) | ||||||
|       .reduce(Misc.sum(), 0) |       .reduce(Misc.sum(), 0) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -421,34 +461,52 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 | |||||||
|     return ALL_ROLL_TYPES.find(m => m.code == this.rollData.type.current) |     return ALL_ROLL_TYPES.find(m => m.code == this.rollData.type.current) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   async close(options) { | ||||||
|  |     if (this.rollOptions.onClose) { | ||||||
|  |       this.rollOptions.onClose() | ||||||
|  |     } | ||||||
|  |     this.unregisterHooks() | ||||||
|  |     return await super.close(options) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   async roll() { |   async roll() { | ||||||
|     // ROLL_PARTS.filter(p => p.isActive(this.rollData)) |  | ||||||
|     //   .forEach(p => p.validate(this.rollData)) |  | ||||||
|  |  | ||||||
|     const roll = RollDialog.saveParts(this.rollData) |     const roll = RollDialog.saveParts(this.rollData) | ||||||
|     RollDialog.loadRollData(roll) |     RollDialog.loadRollData(roll) | ||||||
|  |     const selectedRollType = this.getSelectedType(roll); | ||||||
|  |     selectedRollType.onSelect(roll) | ||||||
|     roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1 |     roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1 | ||||||
|     roll.rolled = await this.$rollDice(roll) |     roll.choix = {} | ||||||
|     roll.result = this.getSelectedType(roll).getResult(roll) |     roll.rolled = await RollDialogAdapter.rollDice(roll, this.rollTitle(roll)) | ||||||
|     console.info('RollDialog.roll:', roll) |  | ||||||
|     await Promise.all(this.rollOptions.callbacks.map(async callback => await callback(roll))) |  | ||||||
|     await this.chatRollResult.display(roll) |  | ||||||
|  |  | ||||||
|     this.rollOptions.onRollDone(this) |     const impacts = new ActorImpacts(roll.active) | ||||||
|  |  | ||||||
|  |     roll.result = selectedRollType.getResult(roll, impacts) | ||||||
|  |  | ||||||
|  |     console.info('RollDialog.roll:', roll) | ||||||
|  |     const callbacks = [ | ||||||
|  |       ...this.rollOptions.callbacks, | ||||||
|  |       ...selectedRollType.callbacks(this.rollOptions), | ||||||
|  |     ] | ||||||
|  |  | ||||||
|  |     await Promise.all(callbacks.map(async callback => await callback(roll))) | ||||||
|  |  | ||||||
|  |     await impacts.applyImpacts() | ||||||
|  |     selectedRollType.onApplyImpacts(roll, impacts) | ||||||
|  |     await this.chatRollResult.display(roll, impacts) | ||||||
|  |     this.rollOptions.onRollDone(this, roll) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static loadRollData(roll) { |   static loadRollData(roll) { | ||||||
|     RollDialog.$prepareRollData(roll) |     RollDialog.$prepareRollData(roll) | ||||||
|     RollDialog.calculAjustements(roll) |     RollDialog.calculAjustement(roll) | ||||||
|     roll.v2 = true |     roll.v2 = true | ||||||
|  |     return roll | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async defaultCallback(rollData, rolled) { |   async defaultCallback(roll, rolled) { | ||||||
|     await rollData.active.actor.appliquerAjoutExperience(rollData) |     await roll.active.actor.appliquerAjoutExperience(roll) | ||||||
|     await rollData.active.actor.appliquerAppelMoral(rollData) |     await roll.active.actor.appliquerAppelMoral(roll) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async $rollDice(rollData) { |  | ||||||
|     return await RollDialogAdapter.rollDice(rollData, this.rollTitle(rollData)) |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,15 +1,25 @@ | |||||||
|  | import { RDD_CONFIG } from "../constants.js" | ||||||
|  | import { ATTAQUE_TYPE_MELEE } from "../item/arme.js" | ||||||
| import { RdDBonus } from "../rdd-bonus.js" | import { RdDBonus } from "../rdd-bonus.js" | ||||||
| import { ReglesOptionnelles } from "../settings/regles-optionnelles.js" | import { CARACS } from "../rdd-carac.js" | ||||||
| import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs" | import { RdDEmpoignade } from "../rdd-empoignade.js" | ||||||
|  | import { DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP } from "./roll-constants.mjs" | ||||||
|  | import RollDialog from "./roll-dialog.mjs" | ||||||
| import { PART_CARAC } from "./roll-part-carac.mjs" | import { PART_CARAC } from "./roll-part-carac.mjs" | ||||||
| import { PART_COMP } from "./roll-part-comp.mjs" | import { PART_COMP } from "./roll-part-comp.mjs" | ||||||
|  | import { PART_DIFF } from "./roll-part-diff.mjs" | ||||||
| import { RollPartSelect } from "./roll-part-select.mjs" | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
|  | import { PART_SIGN } from "./roll-part-sign.mjs" | ||||||
| import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
| export const PART_ATTAQUE = 'attaque' | export const PART_ATTAQUE = 'attaque' | ||||||
|  |  | ||||||
| const TACTIQUES = RdDBonus.tactiques.filter(it => it.isTactique) | const TACTIQUES = RdDBonus.tactiques.filter(it => it.isTactique) | ||||||
|  |  | ||||||
|  | const FILTER_ATTAQUE_EMPOIGNADE = attaque => attaque.arme.isEmpoignade() | ||||||
|  | const FILTER_ATTAQUE_NON_EMPOIGNADE = attaque => !attaque.arme.isEmpoignade() | ||||||
|  | const FILTER_ATTAQUE_EMPOIGNE = attaque => attaque.arme.isUtilisableEmpoigne() && ATTAQUE_TYPE_MELEE.includes(attaque.main) | ||||||
|  |  | ||||||
| export class RollPartAttaque extends RollPartSelect { | export class RollPartAttaque extends RollPartSelect { | ||||||
|  |  | ||||||
|   get code() { return PART_ATTAQUE } |   get code() { return PART_ATTAQUE } | ||||||
| @@ -20,49 +30,70 @@ export class RollPartAttaque extends RollPartSelect { | |||||||
|   loadRefs(rollData) { |   loadRefs(rollData) { | ||||||
|     const refs = this.getRefs(rollData) |     const refs = this.getRefs(rollData) | ||||||
|     const attaques = rollData.active.actor.listAttaques() |     const attaques = rollData.active.actor.listAttaques() | ||||||
|     refs.attaques = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor)) |     refs.all = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor)) | ||||||
|  |     this.filterAttaquesEmpoignade(rollData) | ||||||
|     refs.tactiques = TACTIQUES |     refs.tactiques = TACTIQUES | ||||||
|     if (refs.attaques.length > 0) { |     if (refs.attaques.length > 0) { | ||||||
|       this.$selectAttaque(rollData) |       const attaque = this.findAttaque(refs.attaques, this.getSaved(rollData)) | ||||||
|  |       this.$selectAttaque(rollData, attaque?.key) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   isAttaqueEmpoignade(it) { | ||||||
|  |     return it.arme.isEmpoignade() | ||||||
|  |   } | ||||||
|  |  | ||||||
|   store(rollData, targetData) { |   store(rollData, targetData) { | ||||||
|     super.store(rollData, targetData) |     super.store(rollData, targetData) | ||||||
|     this.getSaved(targetData).dmg = this.getCurrent(rollData).dmg |     this.getSaved(targetData).dmg = this.getCurrent(rollData).dmg | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   restore(rollData) { |   restore(rollData) { | ||||||
|  |     const saved = this.getSaved(rollData) | ||||||
|     super.restore(rollData) |     super.restore(rollData) | ||||||
|     this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg |     if (saved.dmg != undefined) { | ||||||
|  |       this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   findAttaque(attaques, saved) { | ||||||
|  |     return attaques.find(at => at.arme.id == saved?.arme?.id && | ||||||
|  |       at.comp.id == saved?.comp?.id | ||||||
|  |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   choices(refs) { return refs.attaques } |   choices(refs) { return refs.attaques } | ||||||
|  |  | ||||||
|   static $extractAttaque(attaque, actor) { |   static $extractAttaque(attaque, actor) { | ||||||
|     return { |     attaque.key = `${attaque.action}::${attaque.label}` | ||||||
|       key: `${attaque.action}::${attaque.name}`, |     attaque.tactique = TACTIQUES[0] | ||||||
|       label: attaque.name, |     attaque.initialDiff = attaque.comp?.system.default_diffLibre ?? 0 | ||||||
|       attaque: attaque, |     return attaque | ||||||
|       tactique: TACTIQUES[0], |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   prepareContext(rollData) { |   prepareContext(rollData) { | ||||||
|  |     this.filterAttaquesEmpoignade(rollData) | ||||||
|     const current = this.getCurrent(rollData) |     const current = this.getCurrent(rollData) | ||||||
|     current.dmg = RdDBonus.dmgRollV2(rollData, current) |     current.dmg = RdDBonus.dmgRollV2(rollData, current) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   filterAttaquesEmpoignade(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     const isEmpoignade = RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) | ||||||
|  |     refs.isEmpoignadeEnCours = RdDEmpoignade.isEmpoignadeEnCours(rollData.active.actor) | ||||||
|  |     const filterAttaques = isEmpoignade ? | ||||||
|  |       FILTER_ATTAQUE_EMPOIGNADE | ||||||
|  |       : refs.isEmpoignadeEnCours | ||||||
|  |         ? FILTER_ATTAQUE_EMPOIGNE | ||||||
|  |         : FILTER_ATTAQUE_NON_EMPOIGNADE | ||||||
|  |     refs.attaques = refs.all.filter(filterAttaques) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   getAjustements(rollData) { |   getAjustements(rollData) { | ||||||
|     const current = this.getCurrent(rollData) |     const current = this.getCurrent(rollData) | ||||||
|     const ajustements = [] |     const tactique = current.tactique ? [{ label: current.tactique.label, value: current.tactique.attaque }] : [] | ||||||
|     if (current.tactique) { |     const surprise = rollData.opponent?.surprise ? [{ label: rollData.opponent.surprise.label, value: rollData.opponent.surprise.attaque }] : [] | ||||||
|       ajustements.push({ label: current.tactique.label, diff: current.tactique.attaque }) |     return [...tactique, ...surprise] | ||||||
|     } |  | ||||||
|     if (rollData.opponent?.surprise) { |  | ||||||
|       ajustements.push({ label: rollData.opponent.surprise.label, diff: rollData.opponent.surprise.attaque }) |  | ||||||
|     } |  | ||||||
|     return ajustements |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -74,6 +105,7 @@ export class RollPartAttaque extends RollPartSelect { | |||||||
|     const selectAttaque = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-attaque"]`) |     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 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 checkMortalite = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="check-mortalite"]`) | ||||||
|  |     const utiliserDagueEmpoignade = rollDialog.element.querySelector(`roll-section[name="${this.code}"] a.utiliser-dague-empoignade`) | ||||||
|     const current = this.getCurrent(rollDialog.rollData) |     const current = this.getCurrent(rollDialog.rollData) | ||||||
|  |  | ||||||
|     selectAttaque.addEventListener("change", e => { |     selectAttaque.addEventListener("change", e => { | ||||||
| @@ -91,17 +123,42 @@ export class RollPartAttaque extends RollPartSelect { | |||||||
|     }) |     }) | ||||||
|  |  | ||||||
|     checkMortalite?.addEventListener("change", e => { |     checkMortalite?.addEventListener("change", e => { | ||||||
|       current.dmg.mortalite = (e.currentTarget.checked ? 'mortel' : 'non-mortel') |       current.dmg.mortalite = (e.currentTarget.checked ? RDD_CONFIG.encaissement.mortel : RDD_CONFIG.encaissement.nonmortel) | ||||||
|       rollDialog.render() |       rollDialog.render() | ||||||
|     }) |     }) | ||||||
|  |     utiliserDagueEmpoignade?.addEventListener("click", e => { | ||||||
|  |       e.preventDefault() | ||||||
|  |       const rollData = rollDialog.rollData | ||||||
|  |       this.utiliserDagueEmpoignade(rollData) | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   utiliserDagueEmpoignade(rollData) { | ||||||
|  |     RollDialog.create({ | ||||||
|  |       ids: { actorId: rollData.ids.actorId, actorTokenId: rollData.ids.actorTokenId }, | ||||||
|  |       type: { allowed: [ROLL_TYPE_COMP], current: ROLL_TYPE_COMP }, | ||||||
|  |       selected: { | ||||||
|  |         carac: { key: CARACS.DEXTERITE, forced: true }, | ||||||
|  |         comp: { key: 'Dague', forced: true }, | ||||||
|  |         diff: { type: DIFF.IMPOSEE, value: -4 } | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   impactOtherPart(part, rollData) { |   impactOtherPart(part, rollData) { | ||||||
|     if (this.visible(rollData)) { |     if (this.visible(rollData)) { | ||||||
|       const current = this.getCurrent(rollData) |       const current = this.getCurrent(rollData) | ||||||
|       switch (part.code) { |       switch (part.code) { | ||||||
|         case PART_CARAC: return part.filterCaracs(rollData, [current.attaque.carac.key]) |         case PART_CARAC: return part.filterCaracs(rollData, [current.carac.key]) | ||||||
|         case PART_COMP: return part.filterComps(rollData, [current.attaque.comp?.name]) |         case PART_COMP: return part.filterComps(rollData, [current.comp.name]) | ||||||
|  |         case PART_DIFF: { | ||||||
|  |           if (current.initialDiff) { | ||||||
|  |             part.setDiff(rollData, { type: DIFF.ATTAQUE, value: current.initialDiff }) | ||||||
|  |             current.initialDiff = undefined | ||||||
|  |           } | ||||||
|  |           break | ||||||
|  |         } | ||||||
|  |         case PART_SIGN: return part.setArme(rollData, false, current.forceRequise) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { Grammar } from "../grammar.js" | ||||||
| import { RollPartSelect } from "./roll-part-select.mjs" | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
| import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
| @@ -12,22 +13,36 @@ export class RollPartCarac extends RollPartSelect { | |||||||
|  |  | ||||||
|   loadRefs(rollData) { |   loadRefs(rollData) { | ||||||
|     const refs = this.getRefs(rollData) |     const refs = this.getRefs(rollData) | ||||||
|     refs.all = this.$getActorCaracs(rollData) |     const selected = this.getSelected(rollData) | ||||||
|  |     const actor = rollData.active.actor | ||||||
|  |     refs.all = [...this.$getActorCaracs(actor), ...this.$getCaracCompetenceCreature(actor)] | ||||||
|  |       .filter(c => !selected.forced || | ||||||
|  |             (selected.key ? | ||||||
|  |               Grammar.includesLowerCaseNoAccent(c.label, selected.key) | ||||||
|  |               : c.key == '') | ||||||
|  |           ) | ||||||
|     refs.caracs = refs.all |     refs.caracs = refs.all | ||||||
|     this.$selectCarac(rollData) |     this.$selectCarac(rollData) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   choices(refs) { return refs.caracs } |   choices(refs) { return refs.caracs } | ||||||
|  |  | ||||||
|   $getActorCaracs(rollData) { |   $getActorCaracs(actor) { | ||||||
|     return Object.entries(rollData.active.actor.getCarac()) |     return Object.entries(actor.getCarac()) | ||||||
|       .filter(([key, c]) => key != 'taille') |       .filter(([key, c]) => key != 'taille') | ||||||
|       /* TODO: filter by context */ |  | ||||||
|       .map(([key, carac]) => { |       .map(([key, carac]) => { | ||||||
|         return RollPartCarac.$extractCarac(key, carac) |         return RollPartCarac.$extractCarac(key, carac) | ||||||
|       }) |       }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   $getCaracCompetenceCreature(actor) { | ||||||
|  |     if (actor.isPersonnage()) { | ||||||
|  |       return [] | ||||||
|  |     } | ||||||
|  |     return actor.getCompetences() | ||||||
|  |       .map(it => { return { key: it.name, label: it.name, value: parseInt(it.system.carac_value) } }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   static $extractCarac(key, carac) { |   static $extractCarac(key, carac) { | ||||||
|     return { |     return { | ||||||
|       key: key, |       key: key, | ||||||
| @@ -40,7 +55,6 @@ export class RollPartCarac extends RollPartSelect { | |||||||
|     allowed = allowed.filter(it => it != undefined) |     allowed = allowed.filter(it => it != undefined) | ||||||
|     const refs = this.getRefs(rollData) |     const refs = this.getRefs(rollData) | ||||||
|     refs.caracs = allowed.length > 0 |     refs.caracs = allowed.length > 0 | ||||||
|       // ? refs.all.filter(it => allowed.includes(Grammar.toLowerCaseNoAccent(it.key))) |  | ||||||
|       ? refs.all.filter(it => allowed.includes(it.key)) |       ? refs.all.filter(it => allowed.includes(it.key)) | ||||||
|       : refs.all |       : refs.all | ||||||
|     this.$selectCarac(rollData) |     this.$selectCarac(rollData) | ||||||
|   | |||||||
| @@ -28,16 +28,14 @@ export class RollPartCheckbox extends RollPart { | |||||||
|       /* TODO: user setting? */ |       /* TODO: user setting? */ | ||||||
|       current.checked = true |       current.checked = true | ||||||
|     } |     } | ||||||
|     if (current.value == undefined) { |     current.value = this.getCheckboxValue(rollData) | ||||||
|       current.value = this.getCheckboxValue(rollData) |  | ||||||
|     } |  | ||||||
|     current.icon = this.getCheckboxIcon(rollData) |     current.icon = this.getCheckboxIcon(rollData) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getAjustements(rollData) { |   getAjustements(rollData) { | ||||||
|     const current = this.getCurrent(rollData) |     const current = this.getCurrent(rollData) | ||||||
|     if (current.checked) { |     if (current.checked) { | ||||||
|       return [{ label: this.getCheckboxLabelAjustement(rollData), diff: current.value }] |       return [{ label: this.getCheckboxLabelAjustement(rollData), value: current.value }] | ||||||
|     } |     } | ||||||
|     return [] |     return [] | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -47,7 +47,7 @@ export class RollPartCoeur extends RollPartSelect { | |||||||
|     if (current.key != '') { |     if (current.key != '') { | ||||||
|       return [{ |       return [{ | ||||||
|         label: "Coeur pour " + current.label, |         label: "Coeur pour " + current.label, | ||||||
|         diff: current.value |         value: current.value | ||||||
|       }] |       }] | ||||||
|     } |     } | ||||||
|     return [] |     return [] | ||||||
|   | |||||||
| @@ -17,7 +17,17 @@ export class RollPartComp extends RollPartSelect { | |||||||
|  |  | ||||||
|   loadRefs(rollData) { |   loadRefs(rollData) { | ||||||
|     const refs = this.getRefs(rollData) |     const refs = this.getRefs(rollData) | ||||||
|     refs.all = this.$getActorComps(rollData) |     const selected = this.getSelected(rollData) | ||||||
|  |     const all = this.$getActorComps(rollData) | ||||||
|  |     if (selected.forced) { | ||||||
|  |       refs.all = all.filter(comp => Grammar.equalsInsensitive(comp.label, selected.key)) | ||||||
|  |       if (refs.all.length == 0) { | ||||||
|  |         refs.all = all.filter(comp => Grammar.includesLowerCaseNoAccent(comp.label, selected.key)) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       refs.all = all | ||||||
|  |     } | ||||||
|     refs.comps = refs.all |     refs.comps = refs.all | ||||||
|     this.$selectComp(rollData) |     this.$selectComp(rollData) | ||||||
|   } |   } | ||||||
| @@ -26,7 +36,7 @@ export class RollPartComp extends RollPartSelect { | |||||||
|  |  | ||||||
|   $getActorComps(rollData) { |   $getActorComps(rollData) { | ||||||
|     const competences = (rollData.active.actor?.getCompetences() ?? []) |     const competences = (rollData.active.actor?.getCompetences() ?? []) | ||||||
|       .map(RollPartComp.$extractComp) |       .map(RollPartComp.extractComp) | ||||||
|       .sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label))) |       .sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label))) | ||||||
|     /* TODO: filter competences */ |     /* TODO: filter competences */ | ||||||
|     const listCompetences = [ |     const listCompetences = [ | ||||||
| @@ -36,7 +46,7 @@ export class RollPartComp extends RollPartSelect { | |||||||
|     return listCompetences |     return listCompetences | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   static $extractComp(comp) { |   static extractComp(comp) { | ||||||
|     return { |     return { | ||||||
|       key: comp.name, |       key: comp.name, | ||||||
|       label: comp.name, |       label: comp.name, | ||||||
| @@ -45,13 +55,16 @@ export class RollPartComp extends RollPartSelect { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   filterComps(rollData, allowed = []) { |   filterComps(rollData, allowed = [], sorting = undefined) { | ||||||
|  |     const sans = allowed.includes('') | ||||||
|     allowed = allowed.filter(it => it != undefined) |     allowed = allowed.filter(it => it != undefined) | ||||||
|     const refs = this.getRefs(rollData) |     const refs = this.getRefs(rollData) | ||||||
|     refs.comps = allowed.length > 0 |     refs.comps = allowed.length > 0 | ||||||
|       // ? refs.all.filter(it => allowed.includes(Grammar.toLowerCaseNoAccent(it.label))) |       ? refs.all.filter(it => allowed.includes(it.label) || (sans && it.key == '')) | ||||||
|       ? refs.all.filter(it => allowed.includes(it.label)) |  | ||||||
|       : refs.all |       : refs.all | ||||||
|  |     if (sorting && refs.comps.length > 0) { | ||||||
|  |       refs.comps.sort(sorting) | ||||||
|  |     } | ||||||
|     this.$selectComp(rollData) |     this.$selectComp(rollData) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -60,7 +73,7 @@ export class RollPartComp extends RollPartSelect { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   setSpecialComp(rollData, comps) { |   setSpecialComp(rollData, comps) { | ||||||
|     this.getRefs(rollData).comps = comps.map(RollPartComp.$extractComp) |     this.getRefs(rollData).comps = comps.map(RollPartComp.extractComp) | ||||||
|       .sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label))) |       .sort(Misc.ascending(it => Grammar.toLowerCaseNoAccentNoSpace(it.label))) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ export class RollPartConditions extends RollPart { | |||||||
|   getAjustements(rollData) { |   getAjustements(rollData) { | ||||||
|     const current = this.getCurrent(rollData) |     const current = this.getCurrent(rollData) | ||||||
|     if (current.value != 0) { |     if (current.value != 0) { | ||||||
|       return [{ label: DESCR_CONDITIONS, diff: current.value }] |       return [{ label: DESCR_CONDITIONS, value: current.value }] | ||||||
|     } |     } | ||||||
|     return [] |     return [] | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										174
									
								
								module/roll/roll-part-cuisine.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,174 @@ | |||||||
|  | import { ITEM_TYPES } from "../constants.js" | ||||||
|  | import { CARACS } from "../rdd-carac.js" | ||||||
|  | import { ROLL_TYPE_CUISINE } from "./roll-constants.mjs" | ||||||
|  | import { PART_CARAC } from "./roll-part-carac.mjs" | ||||||
|  | import { PART_COMP } from "./roll-part-comp.mjs" | ||||||
|  | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
|  | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
|  | export const PART_CUISINE = "cuisine" | ||||||
|  |  | ||||||
|  | export class RollPartCuisine extends RollPartSelect { | ||||||
|  |   onReady() { | ||||||
|  |     foundry.applications.handlebars.loadTemplates({ 'roll-oeuvre-recettecuisine': `systems/foundryvtt-reve-de-dragon/templates/roll/roll-oeuvre-recettecuisine.hbs` }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   get code() { return PART_CUISINE } | ||||||
|  |   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||||
|  |  | ||||||
|  |   isValid(rollData) { return rollData.active.actor.isPersonnage() } | ||||||
|  |   visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_CUISINE) } | ||||||
|  |  | ||||||
|  |   restore(rollData) { | ||||||
|  |     super.restore(rollData) | ||||||
|  |     this.$restoreSavedOptions(rollData) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   store(rollData, targetData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     this.setSaved(targetData, { | ||||||
|  |       key: current.key, | ||||||
|  |       fabriquer: current.fabriquer, | ||||||
|  |       proportions: current.proportions, | ||||||
|  |       value: current.value, | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   loadRefs(rollData) { | ||||||
|  |     const refs = this.getRefs(rollData) | ||||||
|  |     const actor = rollData.active.actor | ||||||
|  |     refs.cuisine = actor.getCompetence('Cuisine') | ||||||
|  |  | ||||||
|  |     const recettes = actor.items | ||||||
|  |       .filter(it => it.type == ITEM_TYPES.recettecuisine) | ||||||
|  |       .map(RollPartCuisine.$extractPreparationRecette) | ||||||
|  |  | ||||||
|  |     const ingredientsBruts = actor.items | ||||||
|  |       .filter(it => it.getUtilisationCuisine() == 'brut') | ||||||
|  |       .map(RollPartCuisine.$extractPreparationBrut) | ||||||
|  |  | ||||||
|  |     refs.preparations = [RollPartCuisine.$preparationBasique(), ...recettes, ...ingredientsBruts] | ||||||
|  |     refs.preparations.forEach(p => p.comp = refs.cuisine) | ||||||
|  |     if (refs.preparations.length > 0) { | ||||||
|  |       this.$selectPreparation(rollData) | ||||||
|  |       this.$restoreSavedOptions(rollData) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $restoreSavedOptions(rollData) { | ||||||
|  |     const saved = this.getSaved(rollData) | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     if (saved.fabriquer != undefined) { | ||||||
|  |       current.fabriquer = saved.fabriquer | ||||||
|  |     } | ||||||
|  |     if (saved.proportions != undefined) { | ||||||
|  |       current.proportions = saved.proportions | ||||||
|  |     } | ||||||
|  |     if (saved.value != undefined) { | ||||||
|  |       current.value = saved.value | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   choices(refs) { return refs.preparations } | ||||||
|  |  | ||||||
|  |   static $preparationBasique() { | ||||||
|  |     return { | ||||||
|  |       key: '', | ||||||
|  |       label: "Improvisation du moment", | ||||||
|  |       img: RollPartCuisine.$getImgIngredient(), | ||||||
|  |       sust: 1, | ||||||
|  |       exotisme: 0, | ||||||
|  |       ingredients: "Ce qu'il y a sous la main", | ||||||
|  |       proportions: 8, | ||||||
|  |       proportionsMax: 50, | ||||||
|  |       value: 0, | ||||||
|  |       fabriquer: false, | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $extractPreparationRecette(recette) { | ||||||
|  |     const proportions = recette.system.sust ?? 1 | ||||||
|  |     return { | ||||||
|  |       key: recette.id, | ||||||
|  |       label: recette.name, | ||||||
|  |       img: 'systems/foundryvtt-reve-de-dragon/icons/cuisine/ragout.svg', | ||||||
|  |       sust: 1, | ||||||
|  |       exotisme: recette.system.exotisme, | ||||||
|  |       ingredients: recette.system.ingredients, | ||||||
|  |       proportions: proportions, | ||||||
|  |       proportionsMax: proportions * 10, | ||||||
|  |       value: -recette.system.niveau, | ||||||
|  |       recette: recette, | ||||||
|  |       fabriquer: true, | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $extractPreparationBrut(ingredient) { | ||||||
|  |     return { | ||||||
|  |       key: ingredient.id, | ||||||
|  |       label: ingredient.name + ' cuisiné', | ||||||
|  |       img: RollPartCuisine.$getImgIngredient(ingredient.type), | ||||||
|  |       sust: ingredient.system.sust ?? 1, | ||||||
|  |       exotisme: ingredient.system.exotisme, | ||||||
|  |       ingredients: ingredient.name, | ||||||
|  |       proportions: Math.min(10, ingredient.system.quantite), | ||||||
|  |       proportionsMax: Math.min(50, ingredient.system.quantite), | ||||||
|  |       value: 0, | ||||||
|  |       ingredient: ingredient, | ||||||
|  |       fabriquer: true, | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static $getImgIngredient(type = ITEM_TYPES.ingredient) { | ||||||
|  |     switch (type) { | ||||||
|  |       case ITEM_TYPES.herbe: | ||||||
|  |       case ITEM_TYPES.plante: | ||||||
|  |         return `systems/foundryvtt-reve-de-dragon/icons/cuisine/${type}.svg` | ||||||
|  |       case ITEM_TYPES.faune: | ||||||
|  |         return 'systems/foundryvtt-reve-de-dragon/icons/cuisine/gibier.svg' | ||||||
|  |     } | ||||||
|  |     return 'systems/foundryvtt-reve-de-dragon/icons/cuisine/ragout.svg' | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   $selectPreparation(rollData, key) { | ||||||
|  |     this.selectByKey(rollData, key, 0) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async _onRender(rollDialog, context, options) { | ||||||
|  |     const current = this.getCurrent(rollDialog.rollData) | ||||||
|  |  | ||||||
|  |     const selectPreparation = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-preparation"]`) | ||||||
|  |     const inputDiff = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="diff-var"]`) | ||||||
|  |     const checkboxFabriquer = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="fabriquer"]`) | ||||||
|  |     const inputProportions = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="proportions"]`) | ||||||
|  |  | ||||||
|  |     selectPreparation.addEventListener("change", e => { | ||||||
|  |       const selectOptions = e.currentTarget.options | ||||||
|  |       const index = selectOptions.selectedIndex | ||||||
|  |       this.$selectPreparation(rollDialog.rollData, selectOptions[index]?.value) | ||||||
|  |       rollDialog.render() | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     checkboxFabriquer?.addEventListener("change", e => { | ||||||
|  |       current.fabriquer = e.currentTarget.checked | ||||||
|  |     }) | ||||||
|  |     inputDiff?.addEventListener("change", e => { | ||||||
|  |       current.value = parseInt(e.currentTarget.value) | ||||||
|  |     }) | ||||||
|  |     inputProportions?.addEventListener("change", e => { | ||||||
|  |       current.proportions = parseInt(e.currentTarget.value) | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   impactOtherPart(part, rollData) { | ||||||
|  |     if (this.visible(rollData)) { | ||||||
|  |       switch (part.code) { | ||||||
|  |         case PART_CARAC: return part.filterCaracs(rollData, [CARACS.ODORATGOUT]) | ||||||
|  |         case PART_COMP: return part.filterComps(rollData, [this.getRefs(rollData).cuisine.name]) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return undefined | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,9 +1,6 @@ | |||||||
| import { ITEM_TYPES } from "../constants.js" | import { ITEM_TYPES, RDD_CONFIG } from "../constants.js" | ||||||
| import { Grammar } from "../grammar.js" |  | ||||||
| import { ATTAQUE_TYPE, RdDItemArme } from "../item/arme.js" | import { ATTAQUE_TYPE, RdDItemArme } from "../item/arme.js" | ||||||
| import { RdDBonus } from "../rdd-bonus.js" |  | ||||||
| import { CARACS } from "../rdd-carac.js" | import { CARACS } from "../rdd-carac.js" | ||||||
| import { StatusEffects } from "../settings/status-effects.js" |  | ||||||
| import { DIFF, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" | import { DIFF, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" | ||||||
| import { PART_CARAC } from "./roll-part-carac.mjs" | import { PART_CARAC } from "./roll-part-carac.mjs" | ||||||
| import { PART_COMP } from "./roll-part-comp.mjs" | import { PART_COMP } from "./roll-part-comp.mjs" | ||||||
| @@ -18,6 +15,8 @@ export class RollPartDefense extends RollPartSelect { | |||||||
|  |  | ||||||
|   get code() { return PART_DEFENSE } |   get code() { return PART_DEFENSE } | ||||||
|   get section() { return ROLLDIALOG_SECTION.CHOIX } |   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||||
|  |  | ||||||
|  |   isValid(rollData) { return rollData.attackerRoll != undefined } | ||||||
|   visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_DEFENSE) } |   visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_DEFENSE) } | ||||||
|  |  | ||||||
|   static getDiffAttaque(attackerRoll) { |   static getDiffAttaque(attackerRoll) { | ||||||
| @@ -30,13 +29,22 @@ export class RollPartDefense extends RollPartSelect { | |||||||
|     const attackerRoll = rollData.attackerRoll |     const attackerRoll = rollData.attackerRoll | ||||||
|     const defenseur = rollData.active.actor |     const defenseur = rollData.active.actor | ||||||
|     refs.isDistance = [ATTAQUE_TYPE.TIR, ATTAQUE_TYPE.LANCER].find(it => it == attackerRoll?.main) |     refs.isDistance = [ATTAQUE_TYPE.TIR, ATTAQUE_TYPE.LANCER].find(it => it == attackerRoll?.main) | ||||||
|     const esquives = refs.isDistance == ATTAQUE_TYPE.TIR ? [] : defenseur.getCompetencesEsquive() |     const isEmpoignade = attackerRoll.dmg.isEmpoignade | ||||||
|       .map(it => RollPartDefense.$extractEsquive(it, defenseur)) |     const isEmpoignadeEnCours = isEmpoignade && defenseur.itemTypes[ITEM_TYPES.empoignade].find(it => | ||||||
|  |       [it.system.empoigneurid, it.system.empoigneid].includes(rollData.ids.opponentId) && | ||||||
|  |       it.system.pointsemp != 0) | ||||||
|  |  | ||||||
|     const parades = defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier())) |     const esquives = (refs.isDistance == ATTAQUE_TYPE.TIR || isEmpoignadeEnCours) | ||||||
|       .map(it => RollPartDefense.$extractParade(it, attackerRoll?.attaque.arme, defenseur)) |       ? [] | ||||||
|  |       : defenseur.getCompetencesEsquive() | ||||||
|  |     const parades = isEmpoignade | ||||||
|  |       ? [RdDItemArme.empoignade(defenseur)] | ||||||
|  |       : defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier())) | ||||||
|  |  | ||||||
|     refs.defenses = [...esquives, ...parades].filter(it => it != undefined) |     refs.defenses = [ | ||||||
|  |       ...esquives.map(it => RollPartDefense.$extractEsquive(it, defenseur)), | ||||||
|  |       ...parades.map(it => RollPartDefense.$extractParade(it, attackerRoll?.arme, defenseur)) | ||||||
|  |     ] | ||||||
|     this.$selectDefense(rollData) |     this.$selectDefense(rollData) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -104,7 +112,7 @@ export class RollPartDefense extends RollPartSelect { | |||||||
|         case PART_CARAC: return part.filterCaracs(rollData, [current.carac]) |         case PART_CARAC: return part.filterCaracs(rollData, [current.carac]) | ||||||
|         case PART_COMP: return part.filterComps(rollData, [current.comp?.name]) |         case PART_COMP: return part.filterComps(rollData, [current.comp?.name]) | ||||||
|         case PART_DIFF: return part.setDiff(rollData, this.getDiffDefense(rollData)) |         case PART_DIFF: return part.setDiff(rollData, this.getDiffDefense(rollData)) | ||||||
|         case PART_SIGN: return part.setArmeDisparate(rollData, this.isArmeDisparate(rollData)) |         case PART_SIGN: return part.setArme(rollData, this.isArmeDisparate(rollData), current.forceRequise) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
| @@ -113,21 +121,24 @@ export class RollPartDefense extends RollPartSelect { | |||||||
|   isArmeDisparate(rollData) { |   isArmeDisparate(rollData) { | ||||||
|     const armeDefense = this.getCurrent(rollData).arme |     const armeDefense = this.getCurrent(rollData).arme | ||||||
|     if (armeDefense) { |     if (armeDefense) { | ||||||
|       const armeAttaque = rollData.attackerRoll?.attaque.arme |       const armeAttaque = rollData.attackerRoll?.current.attaque.arme | ||||||
|       return RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) == 'sign' |       return RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) == 'sign' | ||||||
|     } |     } | ||||||
|     return false |     return false | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getDiffDefense(rollData) { |   getDiffDefense(rollData) { | ||||||
|     const current = this.getCurrent(rollData) |  | ||||||
|     const refs = this.getRefs(rollData) |     const refs = this.getRefs(rollData) | ||||||
|     if (refs.isDistance || !rollData.attackerRoll) { |     if (refs.isDistance || !rollData.attackerRoll) { | ||||||
|       // Déterminer la difficulté de parade |       // TODO: Déterminer la difficulté de parade | ||||||
|       return { diff: 0, type: DIFF.LIBRE } |       return { diff: 0, type: DIFF.LIBRE } | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       return { diff: rollData.attackerRoll.diff ?? 0, type: DIFF.DEFENSE } |       const attackerRoll = rollData.attackerRoll | ||||||
|  |       const diff = attackerRoll.v2 | ||||||
|  |         ? attackerRoll.selected.diff.value | ||||||
|  |         : attackerRoll.diff | ||||||
|  |       return { diff: diff ?? 0, type: DIFF.DEFENSE } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,10 +1,15 @@ | |||||||
| import { DIFF, DIFFS, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_SORT, ROLL_TYPE_TACHE } from "./roll-constants.mjs"; | import { DIFF, DIFFS, ROLL_TYPE_CUISINE, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_SORT, ROLL_TYPE_TACHE } from "./roll-constants.mjs"; | ||||||
| import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"; | import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"; | ||||||
| import { Misc } from "../misc.js"; | import { Misc } from "../misc.js"; | ||||||
|  |  | ||||||
| export const PART_DIFF = "diff" | export const PART_DIFF = "diff" | ||||||
|  |  | ||||||
| const EXCLUDED_ROLL_TYPES = [ROLL_TYPE_TACHE, ROLL_TYPE_MEDITATION, ROLL_TYPE_SORT, ROLL_TYPE_OEUVRE] | const EXCLUDED_ROLL_TYPES = [ | ||||||
|  |   ROLL_TYPE_TACHE, | ||||||
|  |   ROLL_TYPE_MEDITATION, | ||||||
|  |   ROLL_TYPE_SORT, | ||||||
|  |   ROLL_TYPE_CUISINE, | ||||||
|  |   ROLL_TYPE_OEUVRE] | ||||||
|  |  | ||||||
| export class RollPartDiff extends RollPart { | export class RollPartDiff extends RollPart { | ||||||
|  |  | ||||||
| @@ -51,17 +56,17 @@ export class RollPartDiff extends RollPart { | |||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   setDiff(rollData, diffDefense) { |   setDiff(rollData, diff) { | ||||||
|     const current = this.getCurrent(rollData) |     const current = this.getCurrent(rollData) | ||||||
|     current.value = diffDefense.diff |     current.value = diff.diff ?? current.value | ||||||
|     current.type = diffDefense.type |     current.type = diff.type ?? current.type | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getAjustements(rollData) { |   getAjustements(rollData) { | ||||||
|     const current = this.getCurrent(rollData) |     const current = this.getCurrent(rollData) | ||||||
|     return [{ |     return [{ | ||||||
|       label: current.label, |       label: current.label, | ||||||
|       diff: current.value |       value: current.value | ||||||
|     }] |     }] | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								module/roll/roll-part-empoignade-taille.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,40 @@ | |||||||
|  | import { RDD_CONFIG } from "../constants.js" | ||||||
|  | import { ATTAQUE_TYPE_MELEE } from "../item/arme.js" | ||||||
|  | import { RdDEmpoignade } from "../rdd-empoignade.js" | ||||||
|  | import { COMBAT_ROLL_TYPES } from "./roll-constants.mjs" | ||||||
|  | import { PART_ATTAQUE } from "./roll-part-attaque.mjs" | ||||||
|  | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
|  |  | ||||||
|  | const EMPOIGNADE_TAILLE = "empoignade-taille" | ||||||
|  |  | ||||||
|  | export class RollPartEmpoignadeTaille extends RollPartCheckbox { | ||||||
|  |  | ||||||
|  |   get code() { return EMPOIGNADE_TAILLE } | ||||||
|  |  | ||||||
|  |   isValid(rollData) { | ||||||
|  |     return RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     return COMBAT_ROLL_TYPES.includes(rollData.type.current) && | ||||||
|  |       RdDEmpoignade.isEmpoignadeEnCours(rollData.active.actor) && | ||||||
|  |       this.getTailleDiff(rollData) != 0 | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getTailleDiff(rollData) { | ||||||
|  |     const taille = rollData.active.actor.getTaille() | ||||||
|  |     const tailleOpponent = rollData.opponent.actor.getTaille() | ||||||
|  |     const diff = taille - tailleOpponent | ||||||
|  |     const diffTailleAbs = Math.max(0, Math.abs(diff) - 1) | ||||||
|  |     const signDiff = Math.sign(diff) | ||||||
|  |     return signDiff * diffTailleAbs | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxIcon(rollData) { return `<img src="${RDD_CONFIG.icons.empoignade}">` } | ||||||
|  |   getCheckboxLabel(rollData) { | ||||||
|  |     return `Taille ${rollData.active.actor.getTaille()} vs ${rollData.opponent.actor.getTaille()} ` | ||||||
|  |   } | ||||||
|  |   getCheckboxValue(rollData) { | ||||||
|  |     return this.getTailleDiff(rollData) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								module/roll/roll-part-empoignade.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,30 @@ | |||||||
|  | import { RDD_CONFIG } from "../constants.js" | ||||||
|  | import { ATTAQUE_TYPE_MELEE } from "../item/arme.js" | ||||||
|  | import { RdDEmpoignade } from "../rdd-empoignade.js" | ||||||
|  | import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs" | ||||||
|  | import { PART_ATTAQUE } from "./roll-part-attaque.mjs" | ||||||
|  | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
|  |  | ||||||
|  | const EMPOIGNADE = "empoignade" | ||||||
|  |  | ||||||
|  | export class RollPartEmpoignade extends RollPartCheckbox { | ||||||
|  |  | ||||||
|  |   get code() { return EMPOIGNADE } | ||||||
|  |  | ||||||
|  |   isValid(rollData) { | ||||||
|  |     return RdDEmpoignade.isCombatantEmpoignade(rollData.ids.opponentId, rollData.ids.opponentTokenId) && | ||||||
|  |       !RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   visible(rollData) { | ||||||
|  |     return rollData.type.current == ROLL_TYPE_ATTAQUE && | ||||||
|  |       ATTAQUE_TYPE_MELEE.includes(rollData.current[PART_ATTAQUE].main) && | ||||||
|  |       RdDEmpoignade.isCombatantEmpoignade(rollData.ids.opponentId, rollData.ids.opponentTokenId) && | ||||||
|  |       !RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) && | ||||||
|  |       !RdDEmpoignade.isEmpoignadeEnCours(rollData.active.actor) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getCheckboxIcon(rollData) { return `<img src="${RDD_CONFIG.icons.empoignade}">` } | ||||||
|  |   getCheckboxLabel(rollData) { return "vs. empoigneur" } | ||||||
|  |   getCheckboxValue(rollData) { return 4 } | ||||||
|  | } | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import { RDD_CONFIG } from "../constants.js" | ||||||
| import { RdDItemCompetence } from "../item-competence.js" | import { RdDItemCompetence } from "../item-competence.js" | ||||||
| import { RdDCarac } from "../rdd-carac.js" | import { RdDCarac } from "../rdd-carac.js" | ||||||
| import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | import { RollPartCheckbox } from "./roll-part-checkbox.mjs" | ||||||
| @@ -25,7 +26,7 @@ export class RollPartEncTotal extends RollPartCheckbox { | |||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getCheckboxIcon(rollData) { return '<i class="fa-solid fa-weight-hanging"></i>' } |   getCheckboxIcon(rollData) { return `<img src="${RDD_CONFIG.icons.surenc}">` } | ||||||
|   getCheckboxLabel(rollData) { return "Enc. total" } |   getCheckboxLabel(rollData) { return "Enc. total" } | ||||||
|   getCheckboxValue(rollData) { return - rollData.active.actor.getEncTotal() } |   getCheckboxValue(rollData) { return - rollData.active.actor.getEncTotal() } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,15 +1,16 @@ | |||||||
| import { Grammar } from "../grammar.js" |  | ||||||
| import { ITEM_TYPES } from "../constants.js" | import { ITEM_TYPES } from "../constants.js" | ||||||
| import { CARACS } from "../rdd-carac.js" | import { CARACS } from "../rdd-carac.js" | ||||||
| import { ROLL_TYPE_JEU } from "./roll-constants.mjs" | import { ROLL_TYPE_JEU } from "./roll-constants.mjs" | ||||||
| import { PART_CARAC } from "./roll-part-carac.mjs" | import { PART_CARAC } from "./roll-part-carac.mjs" | ||||||
| import { PART_COMP } from "./roll-part-comp.mjs" | import { PART_COMP, RollPartComp } from "./roll-part-comp.mjs" | ||||||
| import { RollPartSelect } from "./roll-part-select.mjs" | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
| import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  | import { RdDItem } from "../item.js" | ||||||
|  | import { Misc } from "../misc.js" | ||||||
|  |  | ||||||
| export const PART_JEU = "jeu" | export const PART_JEU = "jeu" | ||||||
|  |  | ||||||
| const COMPETENCE_JEU = 'Jeu' | export const COMPETENCE_JEU = 'Jeu' | ||||||
|  |  | ||||||
| export class RollPartJeu extends RollPartSelect { | export class RollPartJeu extends RollPartSelect { | ||||||
|  |  | ||||||
| @@ -21,8 +22,12 @@ export class RollPartJeu extends RollPartSelect { | |||||||
|  |  | ||||||
|   loadRefs(rollData) { |   loadRefs(rollData) { | ||||||
|     const refs = this.getRefs(rollData) |     const refs = this.getRefs(rollData) | ||||||
|     refs.jeux = rollData.active.actor.itemTypes[ITEM_TYPES.jeu] |     const actor = rollData.active.actor | ||||||
|       .map(it => RollPartJeu.$extractJeu(it, rollData.active.actor)) |     const compJeu = actor.getCompetence(COMPETENCE_JEU) | ||||||
|  |  | ||||||
|  |     refs.jeux = actor.itemTypes[ITEM_TYPES.jeu] | ||||||
|  |       .map(it => RollPartJeu.$extractJeu(it, compJeu)) | ||||||
|  |  | ||||||
|     if (refs.jeux.length > 0) { |     if (refs.jeux.length > 0) { | ||||||
|       this.$selectJeu(rollData) |       this.$selectJeu(rollData) | ||||||
|     } |     } | ||||||
| @@ -30,18 +35,17 @@ export class RollPartJeu extends RollPartSelect { | |||||||
|  |  | ||||||
|   choices(refs) { return refs.jeux } |   choices(refs) { return refs.jeux } | ||||||
|  |  | ||||||
|   static $extractJeu(jeu, actor) { |   static $extractJeu(jeu, compJeu) { | ||||||
|     const comp = actor.getCompetence(COMPETENCE_JEU) |  | ||||||
|     const caracs = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim()) |     const caracs = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim()) | ||||||
|     const base = RollPartJeu.$getJeuBase(jeu, comp, caracs) |     const base = RollPartJeu.$getJeuBase(jeu, compJeu, caracs) | ||||||
|     return { |     return { | ||||||
|       key: jeu.id, |       key: jeu.id, | ||||||
|       label: jeu.name, |       label: jeu.name, | ||||||
|       caracs: caracs, |       caracs: caracs, | ||||||
|       jeu: jeu, |       jeu: jeu, | ||||||
|       value: (base ?? comp).system.niveau, |       value: 0, | ||||||
|       base: base, |       base: base, | ||||||
|       comp: comp |       comp: compJeu | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -49,10 +53,10 @@ export class RollPartJeu extends RollPartSelect { | |||||||
|     if (jeu.system.base < comp.system.niveau) { |     if (jeu.system.base < comp.system.niveau) { | ||||||
|       return undefined |       return undefined | ||||||
|     } |     } | ||||||
|     return { |     return new RdDItem({ | ||||||
|       id: comp.id, |       id: comp.id, | ||||||
|       name: `Jeu ${jeu.name}`, |       name: `Jeu ${Misc.lowerFirst(jeu.name)}`, | ||||||
|       type: comp.type, |       type: ITEM_TYPES.competence, | ||||||
|       img: comp.img, |       img: comp.img, | ||||||
|       system: foundry.utils.mergeObject( |       system: foundry.utils.mergeObject( | ||||||
|         { |         { | ||||||
| @@ -61,9 +65,9 @@ export class RollPartJeu extends RollPartSelect { | |||||||
|           default_carac: caracs.length > 0 ? caracs[0] : CARACS.CHANCE |           default_carac: caracs.length > 0 ? caracs[0] : CARACS.CHANCE | ||||||
|         }, |         }, | ||||||
|         comp.system, |         comp.system, | ||||||
|         { inplace: true, overwrite: false } |         { overwrite: false } | ||||||
|       ) |       ) | ||||||
|     } |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   prepareContext(rollData) { |   prepareContext(rollData) { | ||||||
| @@ -77,6 +81,15 @@ export class RollPartJeu extends RollPartSelect { | |||||||
|  |  | ||||||
|   $selectJeu(rollData, key) { |   $selectJeu(rollData, key) { | ||||||
|     this.selectByKey(rollData, key, 0) |     this.selectByKey(rollData, key, 0) | ||||||
|  |     if (rollData.type.current == ROLL_TYPE_JEU) { | ||||||
|  |       RollPartJeu.forceCompJeu(rollData) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static forceCompJeu(rollData) { | ||||||
|  |     const jeu = rollData.current[PART_JEU].base ?? rollData.current[PART_JEU].comp | ||||||
|  |     rollData.refs[PART_COMP].comps = [jeu].map(it => RollPartComp.extractComp(it)) | ||||||
|  |     rollData.current[PART_COMP] = rollData.refs[PART_COMP].comps[0] | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async _onRender(rollDialog, context, options) { |   async _onRender(rollDialog, context, options) { | ||||||
| @@ -95,7 +108,7 @@ export class RollPartJeu extends RollPartSelect { | |||||||
|       const current = this.getCurrent(rollData) |       const current = this.getCurrent(rollData) | ||||||
|       switch (part.code) { |       switch (part.code) { | ||||||
|         case PART_CARAC: return part.filterCaracs(rollData, current.caracs) |         case PART_CARAC: return part.filterCaracs(rollData, current.caracs) | ||||||
|         case PART_COMP: return part.filterComps(rollData,[current.comp?.name]) |         case PART_COMP: return part.filterComps(rollData, [current.comp?.name]) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
|   | |||||||
| @@ -1,36 +1,52 @@ | |||||||
| import { ITEM_TYPES } from "../constants.js" | import { ITEM_TYPES } from "../constants.js" | ||||||
| import { Grammar } from "../grammar.js" | import { Grammar } from "../grammar.js" | ||||||
| import { CARACS, RdDCarac } from "../rdd-carac.js" | import { CARACS } from "../rdd-carac.js" | ||||||
| import { RdDTimestamp } from "../time/rdd-timestamp.js" | import { RdDTimestamp } from "../time/rdd-timestamp.js" | ||||||
| import { TMRUtility } from "../tmr-utility.js" | import { TMRUtility } from "../tmr-utility.js" | ||||||
| import { ROLL_TYPE_MEDITATION } from "./roll-constants.mjs" | import { ROLL_TYPE_MEDITATION } from "./roll-constants.mjs" | ||||||
| import { PART_CARAC } from "./roll-part-carac.mjs" | import { PART_CARAC, RollPartCarac } from "./roll-part-carac.mjs" | ||||||
| import { PART_COMP } from "./roll-part-comp.mjs" | import { PART_COMP } from "./roll-part-comp.mjs" | ||||||
| import { RollPartSelect } from "./roll-part-select.mjs" | import { RollPartSelect } from "./roll-part-select.mjs" | ||||||
| import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | import { ROLLDIALOG_SECTION } from "./roll-part.mjs" | ||||||
|  |  | ||||||
| export const PART_MEDITATION = "meditation" | export const PART_MEDITATION = "meditation" | ||||||
|  |  | ||||||
|  | const COMPORTEMENTS = ['isComportement', 'isHeure', 'isPurification', 'isVeture'] | ||||||
|  |  | ||||||
| export class RollPartMeditation extends RollPartSelect { | export class RollPartMeditation extends RollPartSelect { | ||||||
|  |  | ||||||
|   get code() { return PART_MEDITATION } |   get code() { return PART_MEDITATION } | ||||||
|   get section() { return ROLLDIALOG_SECTION.CHOIX } |   get section() { return ROLLDIALOG_SECTION.CHOIX } | ||||||
|  |  | ||||||
|  |   store(rollData, targetData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     this.setSaved(targetData, { | ||||||
|  |       key: current.key, | ||||||
|  |       isComportement: current.isComportement, | ||||||
|  |       isHeure: current.isHeure, | ||||||
|  |       isPurification: current.isPurification, | ||||||
|  |       isVeture: current.isVeture | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   isValid(rollData) { return rollData.active.actor.isPersonnage() && rollData.active.actor.isHautRevant() } |   isValid(rollData) { return rollData.active.actor.isPersonnage() && rollData.active.actor.isHautRevant() } | ||||||
|   visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_MEDITATION) } |   visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_MEDITATION) } | ||||||
|  |  | ||||||
|   loadRefs(rollData) { |   loadRefs(rollData) { | ||||||
|     const refs = this.getRefs(rollData) |     const refs = this.getRefs(rollData) | ||||||
|     foundry.utils.mergeObject(refs, |     const actor = rollData.active.actor | ||||||
|       { |     refs.meditations = actor.itemTypes[ITEM_TYPES.meditation] | ||||||
|         meditations: rollData.active.actor.itemTypes[ITEM_TYPES.meditation] |       .map(it => RollPartMeditation.$extractMeditation(it, actor)) | ||||||
|           .map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor)) |  | ||||||
|       } |  | ||||||
|     ) |  | ||||||
|     if (refs.meditations.length > 0) { |     if (refs.meditations.length > 0) { | ||||||
|       this.$selectMeditation(rollData) |       this.$selectMeditation(rollData) | ||||||
|  |       this.$selectConditionMeditation(rollData) | ||||||
|  |       const selected = this.getSelected(rollData) | ||||||
|  |       const current = this.getCurrent(rollData) | ||||||
|  |       COMPORTEMENTS.filter(it => selected[it]).forEach(it => current[it] = selected[it]) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   choices(refs) { return refs.meditations } |   choices(refs) { return refs.meditations } | ||||||
|  |  | ||||||
|   static $extractMeditation(meditation, actor) { |   static $extractMeditation(meditation, actor) { | ||||||
| @@ -48,12 +64,7 @@ export class RollPartMeditation extends RollPartSelect { | |||||||
|  |  | ||||||
|   getMalusConditions(rollData) { |   getMalusConditions(rollData) { | ||||||
|     const current = this.getCurrent(rollData) |     const current = this.getCurrent(rollData) | ||||||
|     const conditionsManquantes = [ |     const conditionsManquantes = COMPORTEMENTS.filter(it => !current[it]).length | ||||||
|       current.isComportement, |  | ||||||
|       current.isHeure, |  | ||||||
|       current.isPurification, |  | ||||||
|       current.isVeture |  | ||||||
|     ].filter(it => !it).length |  | ||||||
|     return -2 * conditionsManquantes |     return -2 * conditionsManquantes | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -62,22 +73,28 @@ export class RollPartMeditation extends RollPartSelect { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   getAjustements(rollData) { |   getAjustements(rollData) { | ||||||
|     const malusEchecs = { label: "Méditation", diff: this.getMalusEchecs(rollData) } |     const malus = this.getMalusEchecs(rollData) | ||||||
|     const malusConditions = { label: "Conditions", diff: this.getMalusConditions(rollData) } |     const malusEchecs = malus == 0 ? [] : [{ label: "Méditation", value: malus }] | ||||||
|     return [malusConditions, ...(malusEchecs.diff == 0 ? [] : [malusEchecs])] |     const malusConditions = { label: "Conditions", value: this.getMalusConditions(rollData) } | ||||||
|  |     return [malusConditions, ...malusEchecs] | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   $selectMeditation(rollData, key) { |   $selectMeditation(rollData, key) { | ||||||
|     const previous = this.getCurrent(rollData) |     const previous = this.getCurrent(rollData) | ||||||
|     const current = this.selectByKey(rollData, key, 0) |     const current = this.selectByKey(rollData, key, 0) | ||||||
|     if (current.key != previous.key) { |     if (current.key != previous.key) { | ||||||
|       const heureMonde = RdDTimestamp.getWorldTime().heure |       this.$selectConditionMeditation(rollData) | ||||||
|       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)) |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   $selectConditionMeditation(rollData) { | ||||||
|  |     const current = this.getCurrent(rollData) | ||||||
|  |     current.heureMonde = RdDTimestamp.getWorldTime().heure | ||||||
|  |     current.heureMeditation = RdDTimestamp.findHeure(current.meditation.system.heure)?.heure | ||||||
|  |     current.isHeure = current.heureMeditation == current.heureMonde | ||||||
|  |     current.isTMR = Grammar.equalsInsensitive(current.meditation.system.tmr, TMRUtility.getTMRType(rollData.active.actor.system.reve.tmrpos.coord)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   async _onRender(rollDialog, context, options) { |   async _onRender(rollDialog, context, options) { | ||||||
|  |  | ||||||
|     const selectMeditation = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-meditation"]`) |     const selectMeditation = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-meditation"]`) | ||||||
| @@ -88,10 +105,7 @@ export class RollPartMeditation extends RollPartSelect { | |||||||
|       rollDialog.render() |       rollDialog.render() | ||||||
|     }) |     }) | ||||||
|  |  | ||||||
|     this.setupListenerCondition(rollDialog, 'isComportement') |     COMPORTEMENTS.forEach(it => this.setupListenerCondition(rollDialog, it)) | ||||||
|     this.setupListenerCondition(rollDialog, 'isHeure') |  | ||||||
|     this.setupListenerCondition(rollDialog, 'isPurification') |  | ||||||
|     this.setupListenerCondition(rollDialog, 'isVeture') |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   setupListenerCondition(rollDialog, inputName) { |   setupListenerCondition(rollDialog, inputName) { | ||||||
| @@ -108,7 +122,7 @@ export class RollPartMeditation extends RollPartSelect { | |||||||
|       const current = this.getCurrent(rollData) |       const current = this.getCurrent(rollData) | ||||||
|       switch (part.code) { |       switch (part.code) { | ||||||
|         case PART_CARAC: return part.filterCaracs(rollData, [CARACS.INTELLECT]) |         case PART_CARAC: return part.filterCaracs(rollData, [CARACS.INTELLECT]) | ||||||
|         case PART_COMP: return part.filterComps(rollData,[current.comp?.name]) |         case PART_COMP: return part.filterComps(rollData, [current.comp?.name]) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return undefined |     return undefined | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ export const PART_OEUVRE = "oeuvre" | |||||||
|  |  | ||||||
| const ARTS = [ | 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.oeuvre, action: "interpréte l'oeuvre", competence: it => it.system.competence, caracs: it => [it.system.default_carac] }, | ||||||
|  |   { type: ITEM_TYPES.musique, action: "joue le morceau:", competence: it => 'Musique', caracs: it => [CARACS.OUIE] }, | ||||||
|   { type: ITEM_TYPES.chant, action: "chante", competence: it => 'Chant', caracs: it => [CARACS.OUIE] }, |   { type: ITEM_TYPES.chant, action: "chante", competence: it => 'Chant', caracs: it => [CARACS.OUIE] }, | ||||||
|   { |   { | ||||||
|     type: ITEM_TYPES.danse, action: "danse:", competence: it => 'Danse', caracs: it => { |     type: ITEM_TYPES.danse, action: "danse:", competence: it => 'Danse', caracs: it => { | ||||||
| @@ -20,8 +21,6 @@ const ARTS = [ | |||||||
|       return caracs |       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 { | export class RollPartOeuvre extends RollPartSelect { | ||||||
|   | |||||||