Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
33dc58138c | |||
fa6769fcd7 | |||
47c4478303 | |||
52065fd6f6 | |||
6886f19921 | |||
10a89cc268 | |||
6a987086f8 | |||
54f470d531 | |||
37af0dd4f1 | |||
d46b039a63 | |||
7370b633db | |||
d0ba1ebf99 | |||
053bc23d12 | |||
1360992daa | |||
878645491d | |||
edfaf203f7 | |||
3480b64d75 | |||
17e10d3be9 | |||
bbcd6ad363 | |||
faca73b0a1 | |||
a7e14736e4 | |||
2741fc3fbf | |||
160f10a639 | |||
d26ab59c51 | |||
1f330c734e | |||
74515d28f4 | |||
c84af21c7e | |||
0730bdf240 | |||
607eedc6d2 |
@@ -12,8 +12,8 @@ Pseudo : LeRatierBretonnien
|
|||||||
|
|
||||||
Mainteneur/Développeur : LeRatierBretonnien
|
Mainteneur/Développeur : LeRatierBretonnien
|
||||||
Développeur : VincentVk
|
Développeur : VincentVk
|
||||||
Tests, Compendiums, Données: Fred, Fab, Grendel
|
Tests, Compendiums, Données: Fred, Fab, Grendel, LeRatierBretonnien, VincentVk
|
||||||
Styles/CSS : Mandar
|
Styles/CSS : Mandar, VincentVk
|
||||||
|
|
||||||
# Mentions Légales
|
# Mentions Légales
|
||||||
|
|
||||||
@@ -23,6 +23,6 @@ La carte des Terres Médianes du Rêve est une illustration de **Jidus**, utilis
|
|||||||
Les silhouettes des créatures, humanoïdes et entités sont des illustrations de **Roland Barthélémy**, et sont utilisés dans le cadre de ce projet avec son aimable autorisation.
|
Les silhouettes des créatures, humanoïdes et entités sont des illustrations de **Roland Barthélémy**, et sont utilisés dans le cadre de ce projet avec son aimable autorisation.
|
||||||
Merci à eux !!
|
Merci à eux !!
|
||||||
|
|
||||||
Toute la propriété intellectuelle leur appartient, ce système est une adpatation destinée à fonctionner sous FoundryVTT.
|
Toute la propriété intellectuelle leur appartient, ce système est une adaptation destinée à fonctionner sous FoundryVTT.
|
||||||
|
|
||||||
L'ensemble du code est sous licence Creative Commons.
|
L'ensemble du code est sous licence Creative Commons.
|
1
assets/actions/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 |
66
assets/actions/weak.svg
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
viewBox="0 0 323.9906 329.83231"
|
||||||
|
version="1.1"
|
||||||
|
id="svg6"
|
||||||
|
sodipodi:docname="weak.svg"
|
||||||
|
width="323.9906"
|
||||||
|
height="329.83231"
|
||||||
|
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="2230"
|
||||||
|
inkscape:window-height="1388"
|
||||||
|
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="157.6092"
|
||||||
|
inkscape:cy="192.4342"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg6" />
|
||||||
|
<g
|
||||||
|
class=""
|
||||||
|
transform="translate(-98.3908,-91.5658)"
|
||||||
|
id="g4">
|
||||||
|
<path
|
||||||
|
d="M 200.094,21.094 213.969,164.814 83.72,58.343 156.344,198.249 78.624,168.779 112.906,230.905 30.844,228.843 135.874,297 31.75,327.03 141.188,348.188 c 8.39,-48.802 49.597,-85.194 97.75,-105.344 28.916,-12.1 60.67,-18.762 90.75,-18.594 19.237,0.108 37.776,3.024 54.437,9.063 l 48,-119.375 L 350,196.5 369.22,34.72 327.344,130.688 313.47,92.03 l -32.69,83.5 z m 255.78,190.687 c -17.883,-0.093 -38.852,9.04 -55.937,26.126 a 100.103,100.103 0 0 0 -13.562,16.875 C 357.123,237.155 314,237.977 273.095,250.877 c -9.17,2.484 -18.214,5.537 -26.94,9.188 -43.676,18.277 -78.503,49.837 -86.218,89.625 -6.61,30.108 5.37,63.223 47.438,94.843 H 88.062 l -26.437,47.75 H 318.78 l -88.467,-103.25 c 24.27,-26.707 67.457,-43.703 97,-45.06 13.792,45.096 36.233,113.496 71.718,148.31 h 60.876 c -43.07,-46.546 -76.57,-109.087 -81.97,-179.842 a 33.579,33.579 0 0 0 6.314,8.78 c 18.664,18.664 55.945,11.618 83.28,-15.718 27.337,-27.336 34.384,-64.618 15.72,-83.28 -7,-7 -16.645,-10.382 -27.375,-10.44 z"
|
||||||
|
fill="#ffffff"
|
||||||
|
fill-opacity="1"
|
||||||
|
transform="matrix(0.7,0,0,0.7,76.8,76.8)"
|
||||||
|
id="path2" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
126
assets/ui/chance.svg
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||||
|
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:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="80.64064mm"
|
||||||
|
height="87.145065mm"
|
||||||
|
viewBox="0 0 80.64064 87.145065"
|
||||||
|
version="1.1"
|
||||||
|
id="svg857"
|
||||||
|
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
|
||||||
|
sodipodi:docname="chance.svg">
|
||||||
|
<defs
|
||||||
|
id="defs851">
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient2797">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#800000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop2793" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#800000;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop2795" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient845"
|
||||||
|
osb:paint="gradient">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#800000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop841" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#800000;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop843" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2797"
|
||||||
|
id="radialGradient2799"
|
||||||
|
cx="150.29712"
|
||||||
|
cy="162.02298"
|
||||||
|
fx="150.29712"
|
||||||
|
fy="162.02298"
|
||||||
|
r="148.85666"
|
||||||
|
gradientTransform="matrix(1,0,0,1.0817371,0,-13.243291)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="2.8510546"
|
||||||
|
inkscape:cx="440.18041"
|
||||||
|
inkscape:cy="219.34219"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2054"
|
||||||
|
inkscape:window-x="-11"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata854">
|
||||||
|
<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>
|
||||||
|
<g
|
||||||
|
inkscape:label="Calque 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-65.513013,-104.59413)">
|
||||||
|
<g
|
||||||
|
id="g7-6"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,68.622737,106.83336)"
|
||||||
|
style="opacity:1;mix-blend-mode:normal;fill:#000000;fill-opacity:0.604288;stroke:none;stroke-width:10.56;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.4;image-rendering:auto">
|
||||||
|
<title
|
||||||
|
id="title4-3">Layer 1</title>
|
||||||
|
<path
|
||||||
|
fill="#ffffff"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-width="8"
|
||||||
|
id="path2-1"
|
||||||
|
d="m 206.5,1.5 q 8.5,0 15,3 6.5,3 12.25,8.25 5.75,5.25 12.5,15.5 Q 253,38.5 259.5,43 266,47.5 273.75,52.25 281.5,57 285.5,63 q 4,6 5.75,11.5 1.75,5.5 0,18 -1.75,12.5 -5.75,20 -4,7.5 -12.75,14.25 -8.75,6.75 -17.25,10.75 -8.5,4 -15,6 -6.5,2 -28.75,4.25 -22.25,2.25 -23,3 l -0.75,0.75 0.5,1.25 q 0.5,1.25 32,0.5 31.5,-0.75 43.5,2.75 12,3.5 18.25,8.25 6.25,4.75 9.75,10.25 3.5,5.5 5.5,10.5 2,5 0.5,19.5 -1.5,14.5 -4.75,19.75 -3.25,5.25 -3.75,6.5 l -0.5,1.25 -4.25,2.5 q -4.25,2.5 -10.25,10.5 -6,8 -10,16.5 -4,8.5 -6.75,12.25 -2.75,3.75 -5.25,5.5 -2.5,1.75 -4,4 -1.5,2.25 -9.5,6.25 -8,4 -18.5,2.5 Q 210,290.5 202.75,285.25 195.5,280 190.5,275 q -5,-5 -10.25,-12.25 -5.25,-7.25 -7,-10.5 Q 171.5,249 169,237 q -2.5,-12 -5.5,-21 l -3,-9 -1.5,6.5 q -1.5,6.5 0,28.5 1.5,22 6.5,35 5,13 9.25,18.25 4.25,5.25 10,10.5 5.75,5.25 4.75,10.75 -1,5.5 -1.25,5.75 L 188,322.5 181,321 q -7,-1.5 -13.75,-7.25 Q 160.5,308 156,301.5 q -4.5,-6.5 -8.5,-17 -4,-10.5 -5.5,-20.5 -1.5,-10 -0.25,-36.25 l 1.25,-26.25 -3.25,0.75 q -3.25,0.75 -4.75,5.25 -1.5,4.5 -5.5,29.5 -4,25 -8,32.5 -4,7.5 -7.25,10.75 -3.25,3.25 -8.25,6.75 -5,3.5 -11,5.5 -6,2 -19,0.5 Q 63,291.5 57,288 51,284.5 43.25,274.75 35.5,265 31.75,257 L 28,249 26.5,247.75 Q 25,246.5 20.75,242.75 16.5,239 10,230.5 3.5,222 2.5,219 1.5,216 3,202.5 4.5,189 9.5,181 14.5,173 21.75,167.25 29,161.5 37,158.5 q 8,-3 36.5,-3.5 28.5,-0.5 30.75,-2.75 l 2.25,-2.25 -1.25,-1.25 Q 104,147.5 74,145 44,142.5 30.5,136.5 17,130.5 11.75,125.25 6.5,120 4.5,116.5 2.5,113 2,103.5 1.5,94 5.25,84.75 9,75.5 21.5,65 34,54.5 35,54.25 L 36,54 37.5,51.25 Q 39,48.5 46.25,39.25 53.5,30 57.25,25.75 61,21.5 68,16 75,10.5 83,8 91,5.5 97,6 q 6,0.5 14,4 8,3.5 14.25,9.25 6.25,5.75 9.25,12.25 3,6.5 4.5,15.5 1.5,9 4.25,34 2.75,25 3.75,25 h 1 l 0.75,-2.5 Q 149.5,101 151.5,72 153.5,43 155,39.5 156.5,36 162.25,27.75 168,19.5 176,13.5 q 8,-6 15,-9 7,-3 15.5,-3 z"
|
||||||
|
style="fill:#000000;fill-opacity:0.604288;stroke:none;stroke-width:10.56;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.4" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g7"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,66.057598,105.25559)"
|
||||||
|
style="opacity:1;mix-blend-mode:normal;fill:#217821;stroke:none;stroke-width:10.56;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.4;image-rendering:auto">
|
||||||
|
<title
|
||||||
|
id="title4"
|
||||||
|
style="stroke:url(#radialGradient2799)">Layer 1</title>
|
||||||
|
<path
|
||||||
|
fill="#ffffff"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-width="8"
|
||||||
|
id="path2"
|
||||||
|
d="m 206.5,1.5 q 8.5,0 15,3 6.5,3 12.25,8.25 5.75,5.25 12.5,15.5 Q 253,38.5 259.5,43 266,47.5 273.75,52.25 281.5,57 285.5,63 q 4,6 5.75,11.5 1.75,5.5 0,18 -1.75,12.5 -5.75,20 -4,7.5 -12.75,14.25 -8.75,6.75 -17.25,10.75 -8.5,4 -15,6 -6.5,2 -28.75,4.25 -22.25,2.25 -23,3 l -0.75,0.75 0.5,1.25 q 0.5,1.25 32,0.5 31.5,-0.75 43.5,2.75 12,3.5 18.25,8.25 6.25,4.75 9.75,10.25 3.5,5.5 5.5,10.5 2,5 0.5,19.5 -1.5,14.5 -4.75,19.75 -3.25,5.25 -3.75,6.5 l -0.5,1.25 -4.25,2.5 q -4.25,2.5 -10.25,10.5 -6,8 -10,16.5 -4,8.5 -6.75,12.25 -2.75,3.75 -5.25,5.5 -2.5,1.75 -4,4 -1.5,2.25 -9.5,6.25 -8,4 -18.5,2.5 Q 210,290.5 202.75,285.25 195.5,280 190.5,275 q -5,-5 -10.25,-12.25 -5.25,-7.25 -7,-10.5 Q 171.5,249 169,237 q -2.5,-12 -5.5,-21 l -3,-9 -1.5,6.5 q -1.5,6.5 0,28.5 1.5,22 6.5,35 5,13 9.25,18.25 4.25,5.25 10,10.5 5.75,5.25 4.75,10.75 -1,5.5 -1.25,5.75 L 188,322.5 181,321 q -7,-1.5 -13.75,-7.25 Q 160.5,308 156,301.5 q -4.5,-6.5 -8.5,-17 -4,-10.5 -5.5,-20.5 -1.5,-10 -0.25,-36.25 l 1.25,-26.25 -3.25,0.75 q -3.25,0.75 -4.75,5.25 -1.5,4.5 -5.5,29.5 -4,25 -8,32.5 -4,7.5 -7.25,10.75 -3.25,3.25 -8.25,6.75 -5,3.5 -11,5.5 -6,2 -19,0.5 Q 63,291.5 57,288 51,284.5 43.25,274.75 35.5,265 31.75,257 L 28,249 26.5,247.75 Q 25,246.5 20.75,242.75 16.5,239 10,230.5 3.5,222 2.5,219 1.5,216 3,202.5 4.5,189 9.5,181 14.5,173 21.75,167.25 29,161.5 37,158.5 q 8,-3 36.5,-3.5 28.5,-0.5 30.75,-2.75 l 2.25,-2.25 -1.25,-1.25 Q 104,147.5 74,145 44,142.5 30.5,136.5 17,130.5 11.75,125.25 6.5,120 4.5,116.5 2.5,113 2,103.5 1.5,94 5.25,84.75 9,75.5 21.5,65 34,54.5 35,54.25 L 36,54 37.5,51.25 Q 39,48.5 46.25,39.25 53.5,30 57.25,25.75 61,21.5 68,16 75,10.5 83,8 91,5.5 97,6 q 6,0.5 14,4 8,3.5 14.25,9.25 6.25,5.75 9.25,12.25 3,6.5 4.5,15.5 1.5,9 4.25,34 2.75,25 3.75,25 h 1 l 0.75,-2.5 Q 149.5,101 151.5,72 153.5,43 155,39.5 156.5,36 162.25,27.75 168,19.5 176,13.5 q 8,-6 15,-9 7,-3 15.5,-3 z"
|
||||||
|
style="fill:#217821;stroke:none;stroke-width:10.56;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.4" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 7.6 KiB |
90
assets/ui/destinee.svg
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?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 437.49716 437.38699"
|
||||||
|
version="1.1"
|
||||||
|
id="svg13"
|
||||||
|
sodipodi:docname="destinee.svg"
|
||||||
|
width="437.49716"
|
||||||
|
height="437.38699"
|
||||||
|
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
|
||||||
|
<metadata
|
||||||
|
id="metadata17">
|
||||||
|
<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>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1776"
|
||||||
|
inkscape:window-height="1711"
|
||||||
|
id="namedview15"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:zoom="1.4355469"
|
||||||
|
inkscape:cx="217.3254"
|
||||||
|
inkscape:cy="228.937"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg13" />
|
||||||
|
<defs
|
||||||
|
id="defs7">
|
||||||
|
<radialGradient
|
||||||
|
id="lorc-aura-gradient-1"
|
||||||
|
gradientTransform="scale(1.0001259,0.9998741)"
|
||||||
|
cx="257.54889"
|
||||||
|
cy="253.53915"
|
||||||
|
fx="257.54889"
|
||||||
|
fy="253.53915"
|
||||||
|
r="243.02338"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop
|
||||||
|
offset="0%"
|
||||||
|
stop-color="#f8e71c"
|
||||||
|
stop-opacity="1"
|
||||||
|
id="stop2" />
|
||||||
|
<stop
|
||||||
|
offset="100%"
|
||||||
|
stop-color="#f5a623"
|
||||||
|
stop-opacity="0.53"
|
||||||
|
id="stop4" />
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
class=""
|
||||||
|
transform="translate(-38.6746,-35.063004)"
|
||||||
|
id="g11">
|
||||||
|
<path
|
||||||
|
d="m 320.938,13.28 c -16.646,34.584 -38.466,60.157 -63.094,60.157 -24.522,0 -47.035,-25.275 -63.656,-59.593 0.366,39.358 -9.71,90.884 -30.938,105.125 -21.228,14.24 -49.64,-12.002 -78.844,-32.126 17.455,34.04 42.095,67.5 29.78,92.28 -12.21,24.576 -59.172,35.96 -92.874,35.626 29.338,19.29 78.842,45.803 78.844,74.188 0.002,28.384 -49.504,53.71 -78.844,73 33.702,-0.333 80.663,11.612 92.876,36.187 12.227,24.61 -9.03,56.31 -33.75,85.563 44.826,-15.413 65.142,-5.735 85.374,10.812 h 31.75 C 154.822,459.086 125.5,386.671 125.5,302.936 125.498,184.316 184.42,88.03 256.906,88.03 c 72.488,0 131.406,96.29 131.406,214.907 0,83.74 -29.317,156.153 -72.062,191.563 h 27.313 c 19.847,-14.62 39.796,-25.65 89.687,-9.28 -26.233,-30.264 -42.2,-62.484 -29.97,-87.095 12.257,-24.665 56.658,-36.612 90.533,-36.188 -29.4,-19.297 -75.344,-44.584 -75.344,-73 0,-28.415 45.943,-54.89 75.342,-74.187 -33.874,0.424 -78.273,-10.962 -90.53,-35.625 -12.315,-24.78 9.982,-58.24 27.437,-92.28 -29.202,20.12 -57.583,46.385 -78.845,32.124 -21.262,-14.263 -31.382,-66.13 -30.938,-105.69 z m -68.97,93.75 c -19.56,2.543 -37.343,25.564 -37.343,55.407 0,16.447 5.67,30.986 14,41.032 l 10.156,12.218 -15.593,2.937 c -10.815,2.035 -18.743,7.737 -25.53,17.063 -6.79,9.325 -11.984,22.344 -15.626,37.343 -6.585,27.128 -8.078,60.24 -8.31,89.47 h 36.093 l 0.656,8.656 9.124,122.563 h 76.187 l 8.095,-122.5 0.563,-8.72 h 34.375 c -0.026,-29.592 -0.44,-63.166 -6.407,-90.5 -3.295,-15.095 -8.287,-28.096 -15.156,-37.313 -6.87,-9.216 -15.133,-14.897 -27.28,-16.78 l -15.94,-2.47 10.064,-12.593 c 7.97,-9.996 13.375,-24.36 13.375,-40.406 -0.002,-31.817 -19.884,-55.313 -41.44,-55.313 -2.54,0 -3.96,-0.103 -4.03,-0.094 h -0.03 z"
|
||||||
|
fill="url(#lorc-aura-gradient-1)"
|
||||||
|
stroke="#d03d02"
|
||||||
|
stroke-opacity="1"
|
||||||
|
stroke-width="4"
|
||||||
|
transform="matrix(0.9,0,0,0.9,25.6,25.6)"
|
||||||
|
id="path9"
|
||||||
|
style="fill:url(#lorc-aura-gradient-1)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
66
assets/ui/encaisser.svg
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
viewBox="0 0 410.39459 390.34079"
|
||||||
|
version="1.1"
|
||||||
|
id="svg6"
|
||||||
|
sodipodi:docname="encaisser.svg"
|
||||||
|
width="410.39459"
|
||||||
|
height="390.34079"
|
||||||
|
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="2284"
|
||||||
|
inkscape:window-height="1517"
|
||||||
|
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="206.1036"
|
||||||
|
inkscape:cy="215.2477"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg6" />
|
||||||
|
<g
|
||||||
|
class=""
|
||||||
|
transform="translate(-49.8964,-68.7523)"
|
||||||
|
id="g4">
|
||||||
|
<path
|
||||||
|
d="m 26.996,47.947 c 11.726,44.806 56.176,129.96 67.496,242.934 -6.597,76.494 -22.66,98.81 -22.66,152.74 0,27.602 11.33,38.038 23.254,38.038 11.662,0 23.72,-11.823 23.72,-40.896 0,-56.606 -16.937,-73.84 -23.283,-151.65 6.472,-83.65 59.715,-45.933 59.715,2.765 0,-112.652 101.99,-85.16 116.024,-34.77 -5.164,35.11 -15.028,45.947 -15.028,75.368 0,16.633 8.51,28.86 16.74,28.86 8.416,0 16.41,-11.433 16.41,-27.226 0,-27.953 -9.303,-41.066 -14.515,-75.825 15.447,-37.68 115.544,-34.583 115.845,-1.754 -3.41,26.414 -12.764,32.13 -12.764,51.16 0,9.714 6.58,16.855 12.943,16.855 6.506,0 12.685,-6.677 12.685,-15.9 0,-18.435 -9.164,-25.838 -12.596,-52.854 14.138,-49.16 86.57,-19.867 92.008,-73.298 -51.22,45.91 -357.175,26.76 -455.994,-134.545 z m 128.85,266.22 c -4.676,31.802 -17.635,40.28 -17.635,61.724 0,10.642 8.592,18.346 17.636,18.346 8.844,0 17.988,-8.24 17.988,-19.45 0,-22.338 -13.464,-28.757 -17.988,-60.62 z"
|
||||||
|
fill="#ffffff"
|
||||||
|
transform="matrix(0.9,0,0,0.9,25.6,25.6)"
|
||||||
|
fill-opacity="1"
|
||||||
|
id="path2" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
1
assets/ui/fatigue.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M249.094 18.25c-42.675 0-81.852 25.486-110.938 68.438C109.07 129.637 90.72 189.74 90.72 256.28c0 66.543 18.35 126.643 47.436 169.595s68.263 68.47 110.938 68.47 81.883-25.518 110.97-68.47c29.084-42.952 47.436-103.052 47.436-169.594 0-66.54-18.352-126.64-47.438-169.592C330.978 43.736 291.77 18.25 249.094 18.25zm-128.97 241.313c18.356 18.096 37.528 26.765 55.72 27.562 18.19.797 35.927-6.096 52.125-21.5l12.874 13.53c-19.214 18.274-42.25 27.658-65.813 26.626-23.56-1.03-47.1-12.3-68-32.905l13.095-13.313zm264.782 0 13.125 13.312C377.135 293.48 353.564 304.75 330 305.78c-23.563 1.033-46.598-8.35-65.813-26.624l12.875-13.53c16.2 15.403 33.934 22.296 52.125 21.5 18.192-.798 37.365-9.467 55.72-27.563zM251.562 371.656c36.423-.156 72.996 19.144 77.438 58.406-51.33 13.296-102.67 12.767-154 0 3.858-38.638 40.14-58.25 76.563-58.406z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
assets/ui/part-finesse.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M45.95 14.553c-19.38.81-30.594 11.357-30.282 30.283l19.768 30.78c4.43-1.213 9.36-3.838 14.248-7.335l42.474 59.935c-17.018 20.83-31.258 44.44-42.71 70.836l26.55 26.552c11.275-23.6 24.634-44.826 39.918-63.864l210.82 297.475 166.807 33.213L460.33 325.62 162.78 114.745c19.907-16.108 41.842-29.91 65.652-41.578l-26.553-26.55c-27.206 11.803-51.442 26.576-72.735 44.292L69.39 48.56c3.443-4.823 6.062-9.735 7.342-14.242l-30.78-19.765zm400.84 86.933v.008l.003-.008h-.002zm0 .008-28.028 124.97-25.116-80.593-18.105 70.667-26.862-49.64-.584 57.818 128.484 91.69 15.184 87.017-1.168-186.885-34.457 39.713-9.346-154.756zm-300.95 27.98 222.224 196.368 25.645 66.75-66.75-25.645L130.6 144.734a308.453 308.453 0 0 1 15.238-15.26zm32.305 196.274v.004h.005l-.005-.004zm.005.004 28.028 22.775-36.21 4.088 57.82 19.272-105.706 4.09 115.05 27.45L136.1 422.114l127.316 25.696-67.164 43.803 208.494 1.752-87.017-15.185-104.54-150.676-35.037-1.752z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
1
assets/ui/part-force.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M227.227 21.777c-1.845 0-3.704.05-5.567.157-15.314.875-30.76 5.305-39.494 10.863l-.008 73.15c2.884-.094 5.777-.147 8.676-.142 23.382.036 47.104 3.286 68.47 9.513l.01-87.507c-7.034-3.518-19.178-6.03-32.087-6.033zm80.74 9.16c-11.925.15-23.077 2.364-29.967 5.596l-.008 77.602v7.658c38.486 15.67 64.814 42.48 58.735 78.764l-.96 5.73-5.562 1.674c-17.45 5.253-34.872 9.703-52.225 13.335v25.234c25.562-.704 51.327-2.687 77.145-6.098l.02-197.928c-8.284-5.563-23.508-10.243-38.842-11.328a100.065 100.065 0 0 0-8.336-.238zM143.223 46.294a99.206 99.206 0 0 0-16.491 1.172c-15.67 2.454-31.477 8.565-40.406 15.402l-.01 72.955c18.808-15.81 46.704-25.143 77.15-28.54l.007-57.966c-4.82-1.752-12.018-2.916-20.25-3.023zm258.394 3.46c-10.804.117-20.722 1.93-27.043 4.655l-.02 183.182c25.074-4.02 50.16-9.412 75.122-16.358l1.99-158.447c-8.352-5.9-23.648-11.025-39.05-12.553a100.98 100.98 0 0 0-11-.478zm-222.775 74.202c-53.72.702-101.407 20.365-97.887 66.6 15.836-3.918 30.84-5.893 44.94-6.1 34.84-.51 64.213 9.704 87.318 27.613 34.608-3.11 69.852-10 105.412-20.314.14-41.287-74.098-68.657-139.783-67.8zm-48.877 78.65c-1.296-.003-2.603.012-3.92.045-17.256.436-36.45 4.03-57.566 11.037 5.79 53.808 26.325 106.41 58.5 143.346 6.226 7.15 12.856 13.712 19.875 19.615 29.303 9.282 69.26 12.917 110.534 12.14 3.777-55.805-8.717-108.357-36.193-142.74-21.265-26.61-51.064-43.39-91.232-43.444zm129.326 22.282a545.177 545.177 0 0 1-27.995 4.15 138.77 138.77 0 0 1 4.502 5.346c3.146 3.937 6.094 8.062 8.873 12.334 9.916.144 19.868.125 29.857-.106H259.29v-21.723zm191.817 15.343c-65.406 17.826-131.462 25.41-195.85 25.315 16.998 35.144 23.828 78.093 21.013 122.6 42.482-2.08 85.03-8.23 118.187-15.983 26.693-32.78 47.37-77.118 56.65-131.932zM400.51 389.9c-38.334 9.145-87.95 16.056-136.873 17.454-47.67 1.36-94.336-2.228-129.448-15.262l-.01 78.93c27.187 12.568 76.414 20.205 127.318 20.298 51.224.094 104.214-7.173 139-20.773l.012-80.647z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
After Width: | Height: | Size: 2.1 KiB |
1
assets/ui/part-rapidite.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,-28)" style=""><path d="M275.03 20c35.223 49.563 53.59 113.64 55.69 173.47C315.154 143 289.092 88.423 250.81 48.75c40.294 79.527 51.15 172.312 37.938 256.094-12.287-75.777-40.564-159.524-92.375-227.156 29.6 70.937 36.64 149.785 24.813 221.843-8.745-51.804-25.41-107.4-52.594-158.81 13.023 54.315 12.854 107.64 3.437 159.28l21.657 6.813 15 4.718-11.28 10.908c-10.68 10.332-19.868 21.905-27.345 34.343 93.614 35.486 232.952 64.53 298.032 41.376-41.02 56.466-210.332 13.822-309.313-18.687-1.514 3.775-2.918 7.594-4.124 11.467a152.536 152.536 0 0 0-6.062 29.657l176.47 66.375c98.5 31.095 150.5-24.62 158.655-81.72C505.253 254.472 485.016 105.66 426.06 20h-22.187c40.092 65.52 66.67 154.216 60.47 255.344-8.154-79.833-42.8-157.214-98.44-219.5 38.676 85.094 56.566 185.746 34.376 288.625.057-118.816-33.1-225.865-105.092-324.47H275.03zm-110.186 1.594c41.255 29.176 74.328 74.093 97.5 120.656-7.702-46.15-21.3-86.79-44-120.656h-53.5zm176.375 0c28.882 15.143 52.096 36.614 71.28 66.78-7.14-27.79-17.217-49.85-31.438-66.78H341.22zM123.686 304.406a179.344 179.344 0 0 1-4.062 64L18.812 336.344V366l91.938 29.094a178.602 178.602 0 0 1-30.313 48.28l50.094 15.75c-3.038-24.898-1.136-49.885 6.282-73.718 7.446-23.92 20.223-46.108 37.032-65.22l-50.156-15.78z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
After Width: | Height: | Size: 1.5 KiB |
66
assets/ui/recul.svg
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
viewBox="0 0 433.39499 347.36221"
|
||||||
|
version="1.1"
|
||||||
|
id="svg6"
|
||||||
|
sodipodi:docname="recul.svg"
|
||||||
|
width="433.39499"
|
||||||
|
height="347.36221"
|
||||||
|
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="1053"
|
||||||
|
inkscape:window-height="498"
|
||||||
|
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="216.6975"
|
||||||
|
inkscape:cy="201.682"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg6" />
|
||||||
|
<g
|
||||||
|
class=""
|
||||||
|
transform="translate(-39.3025,-82.318)"
|
||||||
|
id="g4">
|
||||||
|
<path
|
||||||
|
d="M 274.663,63.02 90.792,80.26 244.985,99.533 c 5.063,-13.339 12.952,-24.341 22.541,-31.828 a 52.072,52.072 0 0 1 7.137,-4.683 z m 19.832,12.803 c -5.092,0.166 -10.492,2.296 -15.879,6.502 -7.835,6.118 -15.009,16.575 -18.83,29.688 -3.821,13.112 -3.477,26.099 -0.289,35.927 3.188,9.829 8.73,16.071 15.633,18.395 6.903,2.324 14.766,0.596 22.601,-5.522 7.835,-6.117 15.01,-16.574 18.83,-29.687 3.822,-13.113 3.48,-26.1 0.292,-35.928 -3.189,-9.828 -8.73,-16.07 -15.633,-18.394 a 19.017,19.017 0 0 0 -6.725,-0.98 z m 166.85,9.485 c -24.113,13.949 -46.193,20.298 -87.233,17.252 L 340.48,228.452 c -0.675,2.682 -0.318,6 1.922,10.87 2.243,4.876 6.355,10.89 11.836,17.607 9.99,12.242 24.527,27.16 39.573,44.238 14.56,-5.5 28.23,-12.828 38.972,-20.19 11.841,-8.113 20.234,-16.95 21.965,-19.939 l 42.027,-118.22 c -16.748,-14.613 -29.471,-33.974 -35.43,-57.51 z m -288.07,51.261 -149.623,21.762 89.309,12.988 2.158,-5.052 z m 286.265,2.325 16.941,6.078 -39.123,109.037 -37.212,19.181 -8.247,-15.998 30.913,-15.933 z m -259.842,4.394 -70.586,36.043 -29.222,68.422 19.218,8.809 24.905,-57.764 59.299,-22.973 -14.702,75.955 -0.963,1.477 c -32.725,50.18 -71.654,93.41 -118.464,134.28 l -26.461,45.443 17.021,7.245 31.875,-43.989 1.38,-0.906 c 45.476,-29.872 75.93,-62.333 112.255,-94.492 l 4.533,-4.012 5.426,2.686 c 23.365,11.571 42.934,24.117 62.107,37.705 l 8.924,6.324 -69.006,65.643 24.649,39.794 17.67,-10.308 -20.078,-28.477 8.224,-5.004 c 29.884,-18.186 49.986,-39.43 71.938,-66.039 -23.653,-35.6 -42.006,-49.433 -71.592,-71.267 l 9.908,-7.227 c 34.703,-25.312 38.132,-54.476 41.61,-79.449 -9.203,4.441 -19.498,5.772 -29.473,2.414 -13.488,-4.54 -22.924,-16.472 -27.465,-30.473 -0.17,-0.522 -0.321,-1.054 -0.479,-1.584 z m 116.62,45.04 c -1.355,7.027 -3.324,14.17 -6.092,21.349 l 14.056,9.666 5.938,-22.223 z m -174.243,97.476 -126.85,17.953 99.67,14.105 a 598.987,598.987 0 0 0 27.18,-32.058 z m 91.781,82.73 -95.892,21.432 59.406,13.277 z"
|
||||||
|
fill="#ffffff"
|
||||||
|
fill-opacity="1"
|
||||||
|
transform="matrix(0.9,0,0,0.9,25.6,25.6)"
|
||||||
|
id="path2" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
49
changelog.md
@@ -1,5 +1,54 @@
|
|||||||
# 13.0
|
# 13.0
|
||||||
|
|
||||||
|
## 13.0.10 - Les papilles d'Illysis
|
||||||
|
|
||||||
|
- Ajout d'un statut "saignement" en cas de blessure grave ou critique sans premiers soins
|
||||||
|
|
||||||
|
- Nouvelle fenêtre de jets de dés
|
||||||
|
- jets de méditation
|
||||||
|
- jets de tâches
|
||||||
|
- jets de caractéristiques
|
||||||
|
- jets de compétences
|
||||||
|
- Boutons d'initiative et d'attaque V2
|
||||||
|
- fenêtre d'attaque
|
||||||
|
- choix des armes
|
||||||
|
- gestion des particulières
|
||||||
|
- message au défenseur
|
||||||
|
- gestion des demi-surprises (attaquant/défenseur)
|
||||||
|
- gestion des tactiques (attaquant/défenseur)
|
||||||
|
- en cours nouvelle fenêtre de jets
|
||||||
|
- jets de compétence avec messages
|
||||||
|
- jets de cuisine séparés avec messages (pour gérer plus tard les spécificités: fabricatioon de plats)
|
||||||
|
- gestion des empoignades
|
||||||
|
|
||||||
|
- Technique: suppression de warnings foundry sur renderTemplate
|
||||||
|
|
||||||
|
## 13.0.9 - Le combat d'Illysis
|
||||||
|
- Fix
|
||||||
|
- La montée en TMR fonctionne
|
||||||
|
- ajout d'un status "Force insuffisante"
|
||||||
|
- clarification des maladresses à l'attaque (en demi surprise, ou à cause d'un échec total)
|
||||||
|
- Nouvelle fenêtre de jets de dés
|
||||||
|
- ajout du statut "Force insuffisante" aux acteurs si la
|
||||||
|
force est insuffisante pour l'arme
|
||||||
|
- avancement du mode attaque
|
||||||
|
- choix de tactique
|
||||||
|
- choix mortel/non-mortel pour les dommages
|
||||||
|
- affichage des dommages ajustés delon les choix
|
||||||
|
- affichage du statut de surprise de l'attaquant
|
||||||
|
- affichage du statut de surprise du défenseur
|
||||||
|
- prise en compte des significatives (demi-surprises)
|
||||||
|
- avancement du mode défense
|
||||||
|
- sélection esquive/parade
|
||||||
|
- affichage du statut de surprise du défenseur
|
||||||
|
- prise en compte des significatives (demi-surprises, armes disparates,
|
||||||
|
particulière en finesse)
|
||||||
|
- gestion de l'appel à la chance
|
||||||
|
- gestion de l'utilisation de la destinée
|
||||||
|
- gestion du recul depuis le messages
|
||||||
|
- gestion de l'encaissement depuis le messages
|
||||||
|
- impossible de faire un jet "actif" en surprise totale (attaque, parade, ...)
|
||||||
|
|
||||||
## 13.0.8 - Le renouveau d'Illysis
|
## 13.0.8 - Le renouveau d'Illysis
|
||||||
|
|
||||||
- Fix Foundry V13
|
- Fix Foundry V13
|
||||||
|
@@ -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%);
|
||||||
@@ -424,7 +425,7 @@ select,
|
|||||||
.system-foundryvtt-reve-de-dragon .roll-dialog {
|
.system-foundryvtt-reve-de-dragon .roll-dialog {
|
||||||
font-family: CaslonAntique;
|
font-family: CaslonAntique;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-areas: "header header header header header header header" "action action action action action action action" "mode separation separation separation separation separation separation" "mode carac carac carac comp comp resume" "mode choix choix choix choix choix modifiers" "mode resolution resolution resolution resolution resolution modifiers" "mode chances chances chances chances chances buttons" "footer footer footer footer footer footer footer";
|
grid-template-areas: "header header header header header header header" "action action action action action action action" "type separation separation separation separation separation separation" "type carac carac carac comp comp resume" "type choix choix choix choix choix conditions" "type resolution resolution resolution resolution resolution conditions" "type chances chances chances chances chances buttons" "footer footer footer footer footer footer footer";
|
||||||
grid-template-columns: 2rem 1rem 1fr 1fr 2fr 2fr 3fr;
|
grid-template-columns: 2rem 1rem 1fr 1fr 2fr 2fr 3fr;
|
||||||
gap: 0.2rem;
|
gap: 0.2rem;
|
||||||
}
|
}
|
||||||
@@ -450,7 +451,7 @@ select,
|
|||||||
grid-area: resolution;
|
grid-area: resolution;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions {
|
||||||
grid-area: modifiers;
|
grid-area: conditions;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-chances {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-chances {
|
||||||
grid-area: chances;
|
grid-area: chances;
|
||||||
@@ -461,26 +462,26 @@ select,
|
|||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-buttons {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-buttons {
|
||||||
grid-area: buttons;
|
grid-area: buttons;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-mode {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-type {
|
||||||
grid-area: mode;
|
grid-area: type;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button[data-checked="true"],
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button[data-checked="true"],
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-mode button[data-checked="true"] {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-type button[data-checked="true"] {
|
||||||
background-color: var(--color-text-selection-bg);
|
background-color: var(--color-text-selection-bg);
|
||||||
color: var(--color-controls);
|
color: var(--color-controls);
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button[data-checked="true"] i,
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button[data-checked="true"] i,
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-mode button[data-checked="true"] i {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-type button[data-checked="true"] i {
|
||||||
filter: invert(0.8);
|
filter: invert(0.8);
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button[data-checked="true"] img,
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button[data-checked="true"] img,
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-mode button[data-checked="true"] img {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-type button[data-checked="true"] img {
|
||||||
filter: invert(0.2);
|
filter: invert(0.2);
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button,
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button,
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-mode button {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-type button {
|
||||||
height: 1.8rem;
|
height: 1.8rem;
|
||||||
width: 1.8rem;
|
width: 1.8rem;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
@@ -489,11 +490,11 @@ select,
|
|||||||
color: var(--color-controls);
|
color: var(--color-controls);
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button i,
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button i,
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-mode button i {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-type button i {
|
||||||
filter: invert(0.2);
|
filter: invert(0.2);
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button img,
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="rollmode"] button img,
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-mode button img {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-type button img {
|
||||||
filter: invert(0.8);
|
filter: invert(0.8);
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog :is(roll-carac, roll-comp) {
|
.system-foundryvtt-reve-de-dragon .roll-dialog :is(roll-carac, roll-comp) {
|
||||||
@@ -526,6 +527,11 @@ select,
|
|||||||
grid-area: selection;
|
grid-area: selection;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
margin: 0.1rem 0;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section subline .warning {
|
||||||
|
border-radius: 6px;
|
||||||
|
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;
|
||||||
@@ -549,11 +555,23 @@ select,
|
|||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
margin: 0.1rem 0;
|
||||||
}
|
}
|
||||||
.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;
|
||||||
}
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline span.status-surprise {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-flow: wrap;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline span.status-surprise img {
|
||||||
|
filter: invert(0.8);
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-choix roll-section roll-part-detail subline label {
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .roll-dialog roll-section selected-numeric-value {
|
.system-foundryvtt-reve-de-dragon .roll-dialog roll-section selected-numeric-value {
|
||||||
display: flow;
|
display: flow;
|
||||||
width: 2.5rem;
|
width: 2.5rem;
|
||||||
@@ -608,6 +626,11 @@ select,
|
|||||||
margin: 0 0.2rem;
|
margin: 0 0.2rem;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .roll-dialog :is(roll-choix, roll-conditions, roll-carac, roll-comp) img.button-effect-img {
|
||||||
|
max-width: 1rem;
|
||||||
|
max-height: 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;
|
max-width: 6rem;
|
||||||
}
|
}
|
||||||
@@ -637,6 +660,94 @@ 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 .dialog-content div.roll-chat {
|
||||||
|
font-family: CaslonAntique;
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas: "img header buttons" "img resume buttons" "details details details" "actions actions actions";
|
||||||
|
grid-template-columns: 3rem 1fr 1.4rem;
|
||||||
|
grid-template-rows: max-content max-content max-content max-content;
|
||||||
|
gap: 0 0.5rem;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-img {
|
||||||
|
grid-area: img;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-img img,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-img img {
|
||||||
|
border: 0;
|
||||||
|
max-height: 3rem;
|
||||||
|
max-width: 3rem;
|
||||||
|
object-fit: contain;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-header,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-header {
|
||||||
|
grid-area: header;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-resume,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-resume {
|
||||||
|
grid-area: resume;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-details,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-details {
|
||||||
|
grid-area: details;
|
||||||
|
text-align: justify;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions {
|
||||||
|
grid-area: actions;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions a {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-actions a img,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-actions a img {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons {
|
||||||
|
grid-area: buttons;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons 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;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a img,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a img {
|
||||||
|
max-width: 1rem;
|
||||||
|
max-height: 1rem;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:hover,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a:hover {
|
||||||
|
background: var(--background-custom-button-hover);
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-message div.roll-chat div.chat-buttons a:active,
|
||||||
|
.system-foundryvtt-reve-de-dragon .dialog-content div.roll-chat div.chat-buttons a:active {
|
||||||
|
position: relative;
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -925,16 +1036,18 @@ select,
|
|||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .flex-grow,
|
.system-foundryvtt-reve-de-dragon .flex-grow,
|
||||||
.system-foundryvtt-reve-de-dragon .flex-grow-3 {
|
.system-foundryvtt-reve-de-dragon .flex-grow-3 {
|
||||||
|
display: flex;
|
||||||
flex-grow: 3;
|
flex-grow: 3;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .flex-grow-2 {
|
.system-foundryvtt-reve-de-dragon .flex-grow-0-5 {
|
||||||
flex-grow: 2;
|
flex-grow: 0.5;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .flex-grow-1 {
|
.system-foundryvtt-reve-de-dragon .flex-grow-1 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .flex-grow-0-5 {
|
.system-foundryvtt-reve-de-dragon .flex-grow-2 {
|
||||||
flex-grow: 0.5;
|
display: flex;
|
||||||
|
flex-grow: 2;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .voyage-liste-survies {
|
.system-foundryvtt-reve-de-dragon .voyage-liste-survies {
|
||||||
max-width: 12rem;
|
max-width: 12rem;
|
||||||
@@ -977,14 +1090,16 @@ select,
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .item-actions-controls,
|
.system-foundryvtt-reve-de-dragon :is(.item-actions-controls, .equipement-actions) {
|
||||||
.system-foundryvtt-reve-de-dragon .equipement-actions {
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
flex-grow: 2;
|
flex-grow: 1.2;
|
||||||
align-items: end;
|
align-items: end;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .liste-equipement :is(.equipement-actions, .item-actions-controls) {
|
||||||
|
flex-grow: 2;
|
||||||
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .blessure-control {
|
.system-foundryvtt-reve-de-dragon .blessure-control {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -1218,15 +1333,6 @@ select,
|
|||||||
margin-right: 0.2rem;
|
margin-right: 0.2rem;
|
||||||
margin-left: 0.2rem;
|
margin-left: 0.2rem;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .flex-grow-1 {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
.system-foundryvtt-reve-de-dragon .flex-grow-2 {
|
|
||||||
flex-grow: 2;
|
|
||||||
}
|
|
||||||
.system-foundryvtt-reve-de-dragon .flex-grow-3 {
|
|
||||||
flex-grow: 3;
|
|
||||||
}
|
|
||||||
.system-foundryvtt-reve-de-dragon fieldset {
|
.system-foundryvtt-reve-de-dragon fieldset {
|
||||||
border-style: groove;
|
border-style: groove;
|
||||||
border-width: 0.1rem;
|
border-width: 0.1rem;
|
||||||
@@ -1867,13 +1973,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;
|
||||||
@@ -1888,14 +1994,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;
|
||||||
@@ -1973,11 +2083,13 @@ select,
|
|||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
}
|
}
|
||||||
.system-foundryvtt-reve-de-dragon #sidebar {
|
.system-foundryvtt-reve-de-dragon #sidebar {
|
||||||
font-size: 1rem;
|
|
||||||
background: #695541 url(../assets/ui/bg_sid_dark.webp) no-repeat right bottom;
|
background: #695541 url(../assets/ui/bg_sid_dark.webp) no-repeat right bottom;
|
||||||
background-position: 100%;
|
background-position: 100%;
|
||||||
color: rgba(220, 220, 220, 0.75);
|
color: rgba(220, 220, 220, 0.75);
|
||||||
}
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon #sidebar .chat-message {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
.system-foundryvtt-reve-de-dragon #sidebar-tabs > .collapsed,
|
.system-foundryvtt-reve-de-dragon #sidebar-tabs > .collapsed,
|
||||||
.system-foundryvtt-reve-de-dragon #chat-controls .chat-control-icon {
|
.system-foundryvtt-reve-de-dragon #chat-controls .chat-control-icon {
|
||||||
color: rgba(220, 220, 220, 0.75);
|
color: rgba(220, 220, 220, 0.75);
|
||||||
@@ -2588,6 +2700,22 @@ select,
|
|||||||
border: 2px ridge #846109;
|
border: 2px ridge #846109;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-card-button img,
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-card-button-pushed img {
|
||||||
|
max-width: 1rem;
|
||||||
|
max-height: 1rem;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-card-info {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.system-foundryvtt-reve-de-dragon .chat-card-info img {
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
max-width: 1rem;
|
||||||
|
max-height: 1rem;
|
||||||
|
filter: invert(0.8);
|
||||||
|
}
|
||||||
.system-foundryvtt-reve-de-dragon .chat-card-button {
|
.system-foundryvtt-reve-de-dragon .chat-card-button {
|
||||||
text-shadow: 1px 1px #4d3534;
|
text-shadow: 1px 1px #4d3534;
|
||||||
box-shadow: inset 1x 1px #a6827e;
|
box-shadow: inset 1x 1px #a6827e;
|
||||||
|
@@ -66,6 +66,7 @@
|
|||||||
"StatusRestrained": "Immobilisé",
|
"StatusRestrained": "Immobilisé",
|
||||||
"StatusComma": "Comma",
|
"StatusComma": "Comma",
|
||||||
"StatusDead": "Mort",
|
"StatusDead": "Mort",
|
||||||
"StatusDemiReve": "Demi-rêve"
|
"StatusDemiReve": "Demi-rêve",
|
||||||
|
"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,
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
@import "item/munition.less";
|
@import "item/munition.less";
|
||||||
@import "item/tarot.less";
|
@import "item/tarot.less";
|
||||||
@import "roll-dialog.less";
|
@import "roll-dialog.less";
|
||||||
|
@import "roll-chat.less";
|
||||||
.window-header{
|
.window-header{
|
||||||
background: rgba(0,0,0,0.75);
|
background: rgba(0,0,0,0.75);
|
||||||
}
|
}
|
||||||
@@ -333,16 +334,18 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.flex-grow, .flex-grow-3 {
|
.flex-grow, .flex-grow-3 {
|
||||||
|
display: flex;
|
||||||
flex-grow: 3;
|
flex-grow: 3;
|
||||||
}
|
}
|
||||||
.flex-grow-2 {
|
.flex-grow-0-5 {
|
||||||
flex-grow: 2;
|
flex-grow: 0.5;
|
||||||
}
|
}
|
||||||
.flex-grow-1 {
|
.flex-grow-1 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
.flex-grow-0-5 {
|
.flex-grow-2 {
|
||||||
flex-grow: 0.5;
|
display: flex;
|
||||||
|
flex-grow: 2;
|
||||||
}
|
}
|
||||||
.voyage-liste-survies {
|
.voyage-liste-survies {
|
||||||
max-width: 12rem;
|
max-width: 12rem;
|
||||||
@@ -386,14 +389,16 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.item-actions-controls,
|
:is(.item-actions-controls, .equipement-actions) {
|
||||||
.equipement-actions {
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
flex-grow: 2;
|
flex-grow: 1.2;
|
||||||
align-items: end;
|
align-items: end;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
.liste-equipement :is(.equipement-actions, .item-actions-controls) {
|
||||||
|
flex-grow: 2;
|
||||||
|
}
|
||||||
|
|
||||||
.blessure-control {
|
.blessure-control {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
@@ -622,16 +627,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-grow-1 {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
.flex-grow-2 {
|
|
||||||
flex-grow: 2;
|
|
||||||
}
|
|
||||||
.flex-grow-3 {
|
|
||||||
flex-grow: 3;
|
|
||||||
}
|
|
||||||
fieldset {
|
fieldset {
|
||||||
border-style: groove;
|
border-style: groove;
|
||||||
border-width: 0.1rem;
|
border-width: 0.1rem;
|
||||||
@@ -1324,13 +1319,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;
|
||||||
@@ -1346,14 +1341,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 {
|
||||||
@@ -1451,7 +1450,9 @@
|
|||||||
/* ======================================== */
|
/* ======================================== */
|
||||||
/* Sidebar CSS */
|
/* Sidebar CSS */
|
||||||
#sidebar {
|
#sidebar {
|
||||||
font-size: 1rem;
|
.chat-message{
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
background: rgb(105,85,65) url(../assets/ui/bg_sid_dark.webp) no-repeat right bottom;
|
background: rgb(105,85,65) url(../assets/ui/bg_sid_dark.webp) no-repeat right bottom;
|
||||||
background-position: 100%;
|
background-position: 100%;
|
||||||
color: rgba(220,220,220,0.75);
|
color: rgba(220,220,220,0.75);
|
||||||
@@ -1961,7 +1962,23 @@
|
|||||||
|
|
||||||
border: 2px ridge #846109;
|
border: 2px ridge #846109;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
img {
|
||||||
|
max-width: 1rem;
|
||||||
|
max-height: 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.chat-card-info{
|
||||||
|
font-size: 1.1rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
max-width: 1rem;
|
||||||
|
max-height: 1rem;
|
||||||
|
filter: invert(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.chat-card-button{
|
.chat-card-button{
|
||||||
text-shadow: 1px 1px #4d3534;
|
text-shadow: 1px 1px #4d3534;
|
||||||
|
86
less/roll-chat.less
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
.chat-message div.roll-chat,
|
||||||
|
.dialog-content div.roll-chat {
|
||||||
|
font-family: CaslonAntique;
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas:
|
||||||
|
"img header buttons"
|
||||||
|
"img resume buttons"
|
||||||
|
"details details details"
|
||||||
|
"actions actions actions";
|
||||||
|
grid-template-columns: 3rem 1fr 1.4rem;
|
||||||
|
grid-template-rows: max-content max-content max-content max-content;
|
||||||
|
gap: 0 0.5rem;
|
||||||
|
|
||||||
|
div.chat-img {
|
||||||
|
grid-area: img;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
img {
|
||||||
|
border: 0;
|
||||||
|
max-height: 3rem;
|
||||||
|
max-width: 3rem;
|
||||||
|
object-fit: contain;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div.chat-header {
|
||||||
|
grid-area: header;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
div.chat-resume {
|
||||||
|
grid-area: resume;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
div.chat-details {
|
||||||
|
grid-area: details;
|
||||||
|
text-align: justify;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
div.chat-actions {
|
||||||
|
grid-area: actions;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
a {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
img {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.chat-buttons {
|
||||||
|
grid-area: buttons;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
a {
|
||||||
|
border-radius: 0.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.2rem;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: inset 1x 1px #a6827e;
|
||||||
|
color: var(--color-controls);
|
||||||
|
border: 1px ridge #846109;
|
||||||
|
display: inline-block;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 1rem;
|
||||||
|
max-height: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
background: var(--background-custom-button-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:active{
|
||||||
|
position:relative;
|
||||||
|
top:1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -4,11 +4,11 @@
|
|||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"header header header header header header header"
|
"header header header header header header header"
|
||||||
"action action action action action action action"
|
"action action action action action action action"
|
||||||
"mode separation separation separation separation separation separation"
|
"type separation separation separation separation separation separation"
|
||||||
"mode carac carac carac comp comp resume"
|
"type carac carac carac comp comp resume"
|
||||||
"mode choix choix choix choix choix modifiers"
|
"type choix choix choix choix choix conditions"
|
||||||
"mode resolution resolution resolution resolution resolution modifiers"
|
"type resolution resolution resolution resolution resolution conditions"
|
||||||
"mode chances chances chances chances chances buttons"
|
"type chances chances chances chances chances buttons"
|
||||||
"footer footer footer footer footer footer footer";
|
"footer footer footer footer footer footer footer";
|
||||||
grid-template-columns: 2rem 1rem 1fr 1fr 2fr 2fr 3fr;
|
grid-template-columns: 2rem 1rem 1fr 1fr 2fr 2fr 3fr;
|
||||||
gap: 0.2rem;
|
gap: 0.2rem;
|
||||||
@@ -22,18 +22,18 @@
|
|||||||
roll-choix { grid-area: choix; }
|
roll-choix { grid-area: choix; }
|
||||||
|
|
||||||
roll-table { grid-area: resolution; }
|
roll-table { grid-area: resolution; }
|
||||||
roll-conditions { grid-area: modifiers; }
|
roll-conditions { grid-area: conditions; }
|
||||||
roll-chances { grid-area: chances; }
|
roll-chances { grid-area: chances; }
|
||||||
roll-resume { grid-area: resume; }
|
roll-resume { grid-area: resume; }
|
||||||
roll-buttons { grid-area: buttons; }
|
roll-buttons { grid-area: buttons; }
|
||||||
|
|
||||||
roll-mode {
|
roll-type {
|
||||||
grid-area: mode;
|
grid-area: type;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
roll-conditions roll-section[name="rollmode"],
|
roll-conditions roll-section[name="rollmode"],
|
||||||
roll-mode {
|
roll-type {
|
||||||
button[data-checked="true"] {
|
button[data-checked="true"] {
|
||||||
background-color: var(--color-text-selection-bg);
|
background-color: var(--color-text-selection-bg);
|
||||||
color: var(--color-controls);
|
color: var(--color-controls);
|
||||||
@@ -83,16 +83,23 @@
|
|||||||
gap: 0.2rem;
|
gap: 0.2rem;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
|
|
||||||
|
|
||||||
subline {
|
subline {
|
||||||
grid-area: selection;
|
grid-area: selection;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
margin: 0.1rem 0;
|
||||||
|
.warning {
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--gradient-warning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
roll-part-img {
|
roll-part-img {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
grid-area: img;
|
grid-area: img;
|
||||||
img{
|
img {
|
||||||
border: 0;
|
border: 0;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
max-height: 3rem;
|
max-height: 3rem;
|
||||||
@@ -110,10 +117,22 @@
|
|||||||
subline {
|
subline {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
margin: 0.1rem 0;
|
||||||
div.poesie-extrait{
|
div.poesie-extrait{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
span.status-surprise{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-flow: wrap;
|
||||||
|
img {
|
||||||
|
filter: invert(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,6 +197,11 @@
|
|||||||
margin: 0 0.2rem;
|
margin: 0 0.2rem;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
img.button-effect-img {
|
||||||
|
max-width: 1rem;
|
||||||
|
max-height: 1rem;
|
||||||
|
margin: 0 0.1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
roll-carac select[name="select-carac"] {
|
roll-carac select[name="select-carac"] {
|
||||||
|
@@ -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";
|
||||||
@@ -11,7 +11,6 @@ import { MAINS_DIRECTRICES } from "./actor.js";
|
|||||||
import { RdDBaseActorReveSheet } from "./actor/base-actor-reve-sheet.js";
|
import { RdDBaseActorReveSheet } from "./actor/base-actor-reve-sheet.js";
|
||||||
import { ITEM_TYPES } from "./constants.js";
|
import { ITEM_TYPES } from "./constants.js";
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
import { RdDItemArme } from "./item/arme.js";
|
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { RdDItemBlessure } from "./item/blessure.js";
|
import { RdDItemBlessure } from "./item/blessure.js";
|
||||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||||
@@ -49,7 +48,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
|
|||||||
});
|
});
|
||||||
foundry.utils.mergeObject(formData.calc, {
|
foundry.utils.mergeObject(formData.calc, {
|
||||||
surenc: this.actor.computeMalusSurEncombrement(),
|
surenc: this.actor.computeMalusSurEncombrement(),
|
||||||
surprise: RdDBonus.find(this.actor.getSurprise(false)).descr,
|
surprise: RdDBonus.find(this.actor.getSurprise(false)).label,
|
||||||
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
|
resumeBlessures: this.actor.computeResumeBlessure(this.actor.system.blessures),
|
||||||
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
|
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
|
||||||
surEncombrementMessage: this.actor.isSurenc() ? "Sur-Encombrement!" : "",
|
surEncombrementMessage: this.actor.isSurenc() ? "Sur-Encombrement!" : "",
|
||||||
@@ -175,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())
|
||||||
@@ -209,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 => {
|
||||||
|
@@ -2,6 +2,9 @@
|
|||||||
* class providing the actor and token, and choosing the name and image from the token if available.
|
* class providing the actor and token, and choosing the name and image from the token if available.
|
||||||
*/
|
*/
|
||||||
export class ActorToken {
|
export class ActorToken {
|
||||||
|
static fromTokenActor(token, actor){
|
||||||
|
return token ? ActorToken.fromToken(token) : ActorToken.fromActor(actor)
|
||||||
|
}
|
||||||
|
|
||||||
static fromActorId(actorId, onError = () => undefined) {
|
static fromActorId(actorId, onError = () => undefined) {
|
||||||
actorId = actorId ?? (canvas.tokens.controlled.length > 0
|
actorId = actorId ?? (canvas.tokens.controlled.length > 0
|
||||||
@@ -31,7 +34,7 @@ export class ActorToken {
|
|||||||
|
|
||||||
constructor(token) {
|
constructor(token) {
|
||||||
this.name = token.name ?? token.actor.name
|
this.name = token.name ?? token.actor.name
|
||||||
this.img = token.texture.src ?? token.actor.img
|
this.img = token.actor.isToken && token.texture.src ? token.texture.src : token.actor.img
|
||||||
this.actor = token.actor
|
this.actor = token.actor
|
||||||
this.id = token.actor?.id
|
this.id = token.actor?.id
|
||||||
this.token = token
|
this.token = token
|
||||||
|
282
module/actor.js
@@ -14,12 +14,12 @@ import { STATUSES } from "./settings/status-effects.js";
|
|||||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
|
||||||
import { Draconique } from "./tmr/draconique.js";
|
import { Draconique } from "./tmr/draconique.js";
|
||||||
import { 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";
|
||||||
@@ -31,9 +31,8 @@ import { ITEM_TYPES } from "./constants.js";
|
|||||||
import { RdDBaseActorSang } from "./actor/base-actor-sang.js";
|
import { RdDBaseActorSang } from "./actor/base-actor-sang.js";
|
||||||
import { RdDCoeur } from "./coeur/rdd-coeur.js";
|
import { RdDCoeur } from "./coeur/rdd-coeur.js";
|
||||||
import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js";
|
import { DialogChoixXpCarac } from "./dialog-choix-xp-carac.js";
|
||||||
import { RdDCombatManager } from "./rdd-combat.js";
|
|
||||||
|
|
||||||
import { RdDItemArme } from "./item/arme.js";
|
import { ATTAQUE_TYPE, RdDItemArme } from "./item/arme.js";
|
||||||
import { RdDItemBlessure } from "./item/blessure.js";
|
import { RdDItemBlessure } from "./item/blessure.js";
|
||||||
import { RdDItemTete } from "./item/tete.js";
|
import { RdDItemTete } from "./item/tete.js";
|
||||||
import { RdDItemSort } from "./item-sort.js";
|
import { RdDItemSort } from "./item-sort.js";
|
||||||
@@ -47,7 +46,10 @@ import { PAS_DE_DRACONIC, POSSESSION_SANS_DRACONIC } from "./item/base-items.js"
|
|||||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
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 } from "./settings/options-avancees.js";
|
import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js";
|
||||||
|
import { ROLL_TYPE_MEDITATION } from "./roll/roll-constants.mjs";
|
||||||
|
import { PART_TACHE } from "./roll/roll-part-tache.mjs";
|
||||||
|
import { PART_COMP } from "./roll/roll-part-comp.mjs";
|
||||||
|
|
||||||
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
|
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
|
||||||
|
|
||||||
@@ -99,6 +101,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 != "" }
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -137,12 +141,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
|
||||||
}
|
}
|
||||||
@@ -167,63 +171,64 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
.find(it => true)
|
.find(it => true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
isForceInsuffisante(forceRequise) {
|
||||||
/** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main / lancer */
|
const force = parseInt(this.system.carac.force.value)
|
||||||
listActionsAttaque() {
|
return forceRequise > force
|
||||||
let actions = [
|
|
||||||
this.$prepareAttaqueArme(RdDItemArme.empoignade(this)),
|
|
||||||
this.$prepareAttaqueArme(RdDItemArme.corpsACorps(this)),
|
|
||||||
]
|
|
||||||
|
|
||||||
const armes = this.itemTypes[ITEM_TYPES.arme]
|
|
||||||
.filter(it => RdDItemArme.isAttaque(it))
|
|
||||||
.sort(Misc.ascending(it => it.name));
|
|
||||||
|
|
||||||
for (const arme of armes) {
|
|
||||||
if (arme.system.unemain && arme.system.competence) {
|
|
||||||
actions.push(this.$prepareAttaqueArme(arme, '(1 main)'))
|
|
||||||
}
|
|
||||||
if (arme.system.deuxmains && arme.system.competence) {
|
|
||||||
actions.push(this.$prepareAttaqueArme(arme, '(2 mains)'))
|
|
||||||
}
|
|
||||||
if (arme.system.lancer) {
|
|
||||||
actions.push(this.$prepareAttaqueArme(arme, '(lancer)'))
|
|
||||||
}
|
|
||||||
if (arme.system.tir) {
|
|
||||||
actions.push(this.$prepareAttaqueArme(arme, '(tir)'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return actions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
$prepareAttaqueArme(arme, main) {
|
/** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main / lancer */
|
||||||
const comp = this.getCompetence(RdDActor.$getCompetenceAction(arme, main))
|
listActionsAttaque() {
|
||||||
const caracCode = RdDActor.$getCaracAction(comp, main)
|
const actions = []
|
||||||
const caracValue = this.system.carac[caracCode].value
|
const uniques = []
|
||||||
const dommages = arme.system.dommages.toString()
|
|
||||||
|
|
||||||
// TODO: déplacer sur RdDItemArme
|
const addAttaque = (arme, main = undefined, action = 'attaque') => {
|
||||||
if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) {
|
const dommagesArme = RdDItemArme.valeurMain(arme.system.dommages, main)
|
||||||
ui.notifications.info(`Les dommages de l'arme à 1/2 mains ${arme.name} ne sont pas corrects (ie sous la forme X/Y)`)
|
const forceRequise = RdDItemArme.valeurMain(arme.system.force ?? 0, main)
|
||||||
}
|
const ecaillesEfficacite = arme.system.magique ? arme.system.ecaille_efficacite : 0;
|
||||||
const tableauDommages = dommages.includes("/") ? dommages.split("/") : [dommages, dommages]
|
|
||||||
const dmg = main == '(2 mains)' ? tableauDommages[1] : tableauDommages[0]
|
|
||||||
const niveau = comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(main) ? -8 : -6)
|
|
||||||
const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + (arme.system.magique) ? arme.system.ecaille_efficacite : 0
|
|
||||||
|
|
||||||
return {
|
const comp = this.getCompetence(RdDActor.$getCompetenceAction(arme, main))
|
||||||
name: arme.name + (main ? ' ' + main : ''),
|
const unique = [comp.id, arme.name, dommagesArme, forceRequise, ecaillesEfficacite].join('|');
|
||||||
action: 'attaque',
|
if (uniques.includes(unique)) {
|
||||||
initOnly: false,
|
return
|
||||||
arme: arme,
|
}
|
||||||
comp: comp,
|
uniques.push(unique);
|
||||||
main: main,
|
|
||||||
carac: { key: caracCode, value: caracValue },
|
const caracCode = RdDActor.$getCaracAction(comp, main)
|
||||||
equipe: arme.system.equipe,
|
const caracValue = this.system.carac[caracCode].value
|
||||||
dmg: dmg,
|
|
||||||
initiative: RdDInitiative.calculInitiative(niveau, caracValue, ajustement)
|
const niveau = comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(main) ? -8 : -6)
|
||||||
|
const ajustement = (arme.parent?.getEtatGeneral() ?? 0) + ecaillesEfficacite
|
||||||
|
|
||||||
|
actions.push({
|
||||||
|
label: arme.name + (main ? ' ' + main : ''),
|
||||||
|
action: 'attaque',
|
||||||
|
initOnly: false,
|
||||||
|
arme: arme,
|
||||||
|
comp: comp,
|
||||||
|
main: main,
|
||||||
|
carac: { key: caracCode, value: caracValue },
|
||||||
|
equipe: arme.system.equipe,
|
||||||
|
dommagesArme: dommagesArme,
|
||||||
|
forceRequise: forceRequise,
|
||||||
|
initiative: RdDInitiative.getRollInitiative(caracValue, niveau, ajustement)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.itemTypes[ITEM_TYPES.arme]
|
||||||
|
.filter(it => it.isAttaque())
|
||||||
|
.sort(Misc.ascending(it => it.name))
|
||||||
|
.forEach(arme => {
|
||||||
|
if (arme.system.unemain && arme.system.competence && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.UNE_MAIN) }
|
||||||
|
if (arme.system.deuxmains && arme.system.competence && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.DEUX_MAINS) }
|
||||||
|
if (arme.system.lancer && arme.system.resistance > 0) { addAttaque(arme, ATTAQUE_TYPE.LANCER) }
|
||||||
|
if (arme.system.tir) { addAttaque(arme, ATTAQUE_TYPE.TIR) }
|
||||||
|
})
|
||||||
|
|
||||||
|
addAttaque(RdDItemArme.pugilat(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
||||||
|
addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS, 'empoignade')
|
||||||
|
|
||||||
|
return actions
|
||||||
}
|
}
|
||||||
|
|
||||||
static $getCaracAction(comp, main) {
|
static $getCaracAction(comp, main) {
|
||||||
@@ -239,10 +244,10 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
|
|
||||||
static $getCompetenceAction(arme, main) {
|
static $getCompetenceAction(arme, main) {
|
||||||
switch (main) {
|
switch (main) {
|
||||||
case '(1 main)': return arme.competence1Mains()
|
case ATTAQUE_TYPE.UNE_MAIN: return arme.competence1Mains()
|
||||||
case '(2 mains)': return arme.competence2Mains()
|
case ATTAQUE_TYPE.DEUX_MAINS: return arme.competence2Mains()
|
||||||
case '(lancer)': return arme.system.lancer
|
case ATTAQUE_TYPE.LANCER: return arme.system.lancer
|
||||||
case '(tir)': return arme.system.tir
|
case ATTAQUE_TYPE.TIR: return arme.system.tir
|
||||||
default: return arme.system.competence
|
default: return arme.system.competence
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,7 +512,7 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
'system.sante.fatigue.value': 0,
|
'system.sante.fatigue.value': 0,
|
||||||
'system.compteurs.ethylisme': { value: 1, nb_doses: 0, jet_moral: false }
|
'system.compteurs.ethylisme': { value: 1, nb_doses: 0, jet_moral: false }
|
||||||
})
|
})
|
||||||
await this.removeEffects(e => e.id != STATUSES.StatusDemiReve);
|
await this.removeEffects(e => !e.statuses?.has(STATUSES.StatusDemiReve));
|
||||||
await this.supprimerBlessures(it => true);
|
await this.supprimerBlessures(it => true);
|
||||||
await ChatMessage.create({
|
await ChatMessage.create({
|
||||||
whisper: ChatUtility.getOwners(this),
|
whisper: ChatUtility.getOwners(this),
|
||||||
@@ -1343,7 +1348,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');
|
||||||
@@ -1361,7 +1366,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;
|
||||||
@@ -1923,6 +1928,20 @@ 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 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RollDialog.create(rollData, options)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||||
const competence = this.getCompetence(compName);
|
const competence = this.getCompetence(compName);
|
||||||
await this.openRollDialog({
|
await this.openRollDialog({
|
||||||
@@ -1945,23 +1964,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) }]
|
||||||
@@ -2015,6 +2045,17 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
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)
|
||||||
|
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 = {
|
||||||
@@ -2278,13 +2319,12 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
|
|
||||||
static _getComposantsCaracDerivee(caracName) {
|
static _getComposantsCaracDerivee(caracName) {
|
||||||
switch (Grammar.toLowerCaseNoAccent(caracName)) {
|
switch (Grammar.toLowerCaseNoAccent(caracName)) {
|
||||||
case 'reve-actuel': case 'reve actuel': return ['reve']
|
case CARACS.REVE_ACTUEL: case 'reve actuel': return [CARACS.REVE]
|
||||||
case 'chance-actuelle': case 'chance actuelle': return ['chance']
|
case CARACS.CHANCE_ACTUELLE: case 'chance actuelle': return [CARACS.CHANCE]
|
||||||
case 'vie': return ['constitution']
|
case CARACS.TIR: return [CARACS.DEXTERITE, CARACS.VUE]
|
||||||
case 'tir': return ['vue', 'dexterite']
|
case CARACS.LANCER: return [CARACS.FORCE, CARACS.DEXTERITE, CARACS.VUE]
|
||||||
case 'lancer': return ['force', 'dexterite', 'vue']
|
case CARACS.MELEE: return [CARACS.FORCE, CARACS.AGILITE]
|
||||||
case 'melee': return ['force', 'agilite']
|
case CARACS.DEROBEE: return [CARACS.AGILITE]
|
||||||
case 'derobee': return ['agilite']
|
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -2416,14 +2456,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
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2438,6 +2481,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) {
|
||||||
@@ -2515,29 +2559,27 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async computeArmure(attackerRoll) {
|
async computeArmure(dmg) {
|
||||||
let dmg = (attackerRoll.dmg.dmgArme ?? 0) + (attackerRoll.dmg.dmgActor ?? 0);
|
let baseDmg = (dmg.dmgArme ?? 0) + (dmg.dmgActor ?? 0);
|
||||||
let armeData = attackerRoll.arme;
|
|
||||||
let protection = 0;
|
let protection = 0;
|
||||||
const armures = this.items.filter(it => it.type == "armure" && it.system.equipe);
|
if (dmg.encaisserSpecial != "noarmure") {
|
||||||
for (const armure of armures) {
|
const armures = this.items.filter(it => it.type == "armure" && it.system.equipe)
|
||||||
protection += await RdDDice.rollTotal(armure.system.protection.toString());
|
|
||||||
if (dmg > 0 && attackerRoll.dmg.encaisserSpecial != "noarmure") {
|
for (const armure of armures) {
|
||||||
await armure.deteriorerArmure(dmg)
|
protection += await RdDDice.rollTotal(armure.system.protection.toString());
|
||||||
dmg = 0;
|
if (baseDmg > 0 && dmg.encaisserSpecial != "noarmure") {
|
||||||
|
await armure.deteriorerArmure(baseDmg)
|
||||||
|
baseDmg = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protection -= Math.min(dmg.penetration, protection)
|
||||||
|
protection += this.getProtectionNaturelle();
|
||||||
|
// Gestion des cas particuliers sur la fenêtre d'encaissement
|
||||||
|
if (dmg.encaisserSpecial == "chute") {
|
||||||
|
protection = Math.min(protection, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const penetration = Misc.toInt(armeData?.system.penetration ?? 0);
|
console.log("Final protect", protection, dmg)
|
||||||
protection = Math.max(protection - penetration, 0);
|
|
||||||
protection += this.getProtectionNaturelle();
|
|
||||||
// Gestion des cas particuliers sur la fenêtre d'encaissement
|
|
||||||
if (attackerRoll.dmg.encaisserSpecial == "noarmure") {
|
|
||||||
protection = 0;
|
|
||||||
}
|
|
||||||
if (attackerRoll.dmg.encaisserSpecial == "chute") {
|
|
||||||
protection = Math.min(protection, 2);
|
|
||||||
}
|
|
||||||
console.log("Final protect", protection, attackerRoll);
|
|
||||||
return protection;
|
return protection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2920,7 +2962,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);
|
||||||
}
|
}
|
||||||
@@ -3051,40 +3095,25 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _rollArtV2(oeuvreId, callbackAction = async (actor, rd) => await actor._resultArtV2(rd)) {
|
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}`,
|
title: `Interpretation de ${oeuvre.name} par ${this.name}`,
|
||||||
mode: {
|
type: {
|
||||||
allowed: ["oeuvre"]
|
allowed: ["oeuvre"],
|
||||||
|
current: "oeuvre",
|
||||||
},
|
},
|
||||||
selected: {
|
selected: {
|
||||||
mode: "oeuvre",
|
|
||||||
oeuvre: { key: oeuvre.id },
|
oeuvre: { key: oeuvre.id },
|
||||||
},
|
},
|
||||||
ids: {
|
ids: {
|
||||||
actorId: this.id
|
actorId: this.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await RollDialog.create(rollData, {
|
await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
|
||||||
onRoll: (dialog) => {
|
|
||||||
this._onCloseRollDialog(),
|
|
||||||
dialog.close()
|
|
||||||
},
|
|
||||||
customChatMessage: true,
|
|
||||||
callbacks: [callbackAction]
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _resultArtV2(artData) {
|
|
||||||
const niveau = artData.oeuvre.system.niveau ?? 0;
|
|
||||||
const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau);
|
|
||||||
artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite;
|
|
||||||
|
|
||||||
await RdDRollResult.displayRollData(artData, this.name, `chat-resultat-${artData.art}.hbs`);
|
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
async rollOeuvre(id) {
|
async rollOeuvre(id) {
|
||||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||||
return await this._rollArtV2(id)
|
return await this._rollArtV2(id)
|
||||||
@@ -3170,7 +3199,7 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
async _resultArt(artData) {
|
async _resultArt(artData) {
|
||||||
const niveau = artData.oeuvre.system.niveau ?? 0;
|
const niveau = artData.oeuvre.system.niveau ?? 0;
|
||||||
const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau);
|
const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau);
|
||||||
artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite;
|
artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite
|
||||||
|
|
||||||
await RdDRollResult.displayRollData(artData, this.name, `chat-resultat-${artData.art}.hbs`);
|
await RdDRollResult.displayRollData(artData, this.name, `chat-resultat-${artData.art}.hbs`);
|
||||||
}
|
}
|
||||||
@@ -3191,7 +3220,7 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
async _resultRecetteCuisine(cuisine) {
|
async _resultRecetteCuisine(cuisine) {
|
||||||
const niveauRecette = cuisine.oeuvre.system.niveau ?? 0;
|
const niveauRecette = cuisine.oeuvre.system.niveau ?? 0;
|
||||||
const baseQualite = (cuisine.rolled.isSuccess ? niveauRecette : cuisine.competence.system.niveau);
|
const baseQualite = (cuisine.rolled.isSuccess ? niveauRecette : cuisine.competence.system.niveau);
|
||||||
cuisine.qualiteFinale = Math.min(baseQualite, niveauRecette) + cuisine.rolled.ptQualite;
|
cuisine.qualiteFinale = Math.min(baseQualite, niveauRecette) + cuisine.rolled.ptQualite
|
||||||
cuisine.exotismeFinal = Math.min(Math.min(cuisine.qualiteFinale, cuisine.oeuvre.system.exotisme ?? 0), 0);
|
cuisine.exotismeFinal = Math.min(Math.min(cuisine.qualiteFinale, cuisine.oeuvre.system.exotisme ?? 0), 0);
|
||||||
cuisine.sust = cuisine.oeuvre.system.sust * Math.min(cuisine.proportions, cuisine.proportionsMax ?? cuisine.proportions)
|
cuisine.sust = cuisine.oeuvre.system.sust * Math.min(cuisine.proportions, cuisine.proportionsMax ?? cuisine.proportions)
|
||||||
const platCuisine = {
|
const platCuisine = {
|
||||||
@@ -3249,3 +3278,4 @@ export class RdDActor extends RdDBaseActorSang {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
|
import { ENTITE_INCARNE, renderTemplate, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
|
||||||
import { Grammar } from "../grammar.js";
|
import { 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,12 +11,11 @@ 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 { RdDItemCompetence } from "../item-competence.js";
|
|
||||||
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
|
||||||
import { RdDItemArme } from "../item/arme.js";
|
import { RdDItemArme } from "../item/arme.js";
|
||||||
|
import { RdDItemCompetence } from "../item-competence.js";
|
||||||
|
|
||||||
import { ChatUtility } from "../chat-utility.js";
|
import { ChatUtility } from "../chat-utility.js";
|
||||||
import { DialogValidationEncaissement } from "../dialog-validation-encaissement.js";
|
import { DialogValidationEncaissement } from "../dialog-validation-encaissement.js";
|
||||||
@@ -24,7 +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 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)
|
||||||
@@ -80,7 +84,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
getBonusDegat() { return RdDCarac.getCaracDerivee(this.getEncombrementMax()).plusdom }
|
getBonusDegat() { return RdDCarac.getCaracDerivee(this.getEncombrementMax()).plusdom }
|
||||||
|
|
||||||
getMoralTotal() { return 0 }
|
getMoralTotal() { return 0 }
|
||||||
listeAmoureux() {return []}
|
listeAmoureux() { return [] }
|
||||||
getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) }
|
getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) }
|
||||||
getSConst() { return 0 }
|
getSConst() { return 0 }
|
||||||
|
|
||||||
@@ -113,13 +117,12 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
|
|
||||||
listActions({ isAttaque = false, isEquipe = false }) {
|
listActions({ isAttaque = false, isEquipe = false }) {
|
||||||
return this.itemTypes[ITEM_TYPES.competencecreature]
|
return this.itemTypes[ITEM_TYPES.competencecreature]
|
||||||
.filter(it => RdDItemCompetenceCreature.isAttaque(it))
|
.filter(it => it.isAttaque())
|
||||||
.map(it => RdDItemCompetenceCreature.attaqueCreature(it))
|
.map(it => it.attaqueCreature())
|
||||||
.filter(it => it != undefined);
|
.filter(it => it != undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async computeArmure(dmg) { return this.getProtectionNaturelle() }
|
||||||
async computeArmure(attackerRoll) { return this.getProtectionNaturelle() }
|
|
||||||
async remiseANeuf() { }
|
async remiseANeuf() { }
|
||||||
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { }
|
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { }
|
||||||
|
|
||||||
@@ -191,6 +194,10 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
return RdDItemArme.getArme(armeParadeId ? this.getEmbeddedDocument('Item', armeParadeId) : undefined)
|
return RdDItemArme.getArme(armeParadeId ? this.getEmbeddedDocument('Item', armeParadeId) : undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isForceInsuffisante(forceRequise) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
getDraconicOuPossession() { return POSSESSION_SANS_DRACONIC }
|
getDraconicOuPossession() { return POSSESSION_SANS_DRACONIC }
|
||||||
|
|
||||||
getPossession(possessionId) {
|
getPossession(possessionId) {
|
||||||
@@ -222,8 +229,13 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
isEffectAllowed(effectId) { return false }
|
isEffectAllowed(effectId) { return false }
|
||||||
|
|
||||||
getEffects(filter = e => true) {
|
getEffects(filter = e => true, forceRequise = undefined) {
|
||||||
return this.getEmbeddedCollection("ActiveEffect").filter(filter);
|
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) {
|
getEffectByStatus(statusId) {
|
||||||
@@ -248,7 +260,8 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
|
|
||||||
async removeEffects(filter = e => true) {
|
async removeEffects(filter = e => true) {
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
const ids = this.getEffects(filter).map(it => it.id);
|
const effectsToRemove = this.getEffects(filter);
|
||||||
|
const ids = effectsToRemove.map(it => it.id);
|
||||||
await this.deleteEmbeddedDocuments('ActiveEffect', ids);
|
await this.deleteEmbeddedDocuments('ActiveEffect', ids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,11 +272,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSurprise(isCombat = undefined) {
|
getSurprise(isCombat = undefined) {
|
||||||
return StatusEffects.typeSurprise(
|
return StatusEffects.getSurprise(this.getEffects(), isCombat)
|
||||||
this.getEffects()
|
|
||||||
.map(it => StatusEffects.niveauSurprise(it, isCombat))
|
|
||||||
.reduce(Misc.sum(), 0)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -372,9 +381,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: [PART_COMP], current: PART_COMP },
|
||||||
|
selected: {
|
||||||
|
carac: { key: caracName },
|
||||||
|
comp: options.resistance ? { key: undefined, forced: true } : undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RollDialog.create(rollData, options)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false })
|
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)
|
||||||
@@ -402,9 +424,33 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
async rollCompetenceV2(rollData) {
|
||||||
|
rollData.ids = rollData?.ids ?? {}
|
||||||
|
rollData.type = rollData.type ?? { allowed: DEFAULT_ROLL_TYPES }
|
||||||
|
rollData.ids.actorId = this.id
|
||||||
|
await RollDialog.create(rollData)
|
||||||
|
}
|
||||||
|
|
||||||
async rollCompetence(idOrName, options = { tryTarget: true, arme: undefined }) {
|
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 (competence.type != ITEM_TYPES.competencecreature && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||||
|
const rollData = {
|
||||||
|
selected: {
|
||||||
|
comp: { key: competence.name },
|
||||||
|
diff: { type: DIFF.LIBRE, value: competence.system.default_diffLibre ?? 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.arme) {
|
||||||
|
rollData.selected.attaque = { arme: { id: options.arme.id }, comp: { id: competence.id } }
|
||||||
|
rollData.type = { allowed: ATTAQUE_ROLL_TYPES }
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.rollCompetenceV2(rollData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let rollData = {
|
let rollData = {
|
||||||
carac: this.system.carac,
|
carac: this.system.carac,
|
||||||
competence: competence,
|
competence: competence,
|
||||||
@@ -412,7 +458,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
if (competence.type == ITEM_TYPES.competencecreature) {
|
if (competence.type == ITEM_TYPES.competencecreature) {
|
||||||
const token = RdDUtility.getSelectedToken(this)
|
const token = RdDUtility.getSelectedToken(this)
|
||||||
const arme = RdDItemCompetenceCreature.armeCreature(competence)
|
const arme = MappingCreatureArme.armeCreature(competence)
|
||||||
if (arme && options.tryTarget && Targets.hasTargets()) {
|
if (arme && options.tryTarget && Targets.hasTargets()) {
|
||||||
Targets.selectOneTargetToken(target => {
|
Targets.selectOneTargetToken(target => {
|
||||||
if (arme.action == "possession") {
|
if (arme.action == "possession") {
|
||||||
@@ -422,10 +468,10 @@ 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
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
MappingCreatureArme.setRollDataCreature(rollData)
|
||||||
}
|
}
|
||||||
const dialogLabel = 'Jet ' + Grammar.apostrophe('de', competence.name);
|
const dialogLabel = 'Jet ' + Grammar.apostrophe('de', competence.name);
|
||||||
await this.openRollDialog({
|
await this.openRollDialog({
|
||||||
@@ -444,16 +490,56 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rollAttaque(token) {
|
||||||
|
token = token ?? RdDUtility.getSelectedToken(this)
|
||||||
|
|
||||||
|
if (Targets.hasTargets()) {
|
||||||
|
Targets.selectOneTargetToken(target => {
|
||||||
|
if (Targets.isTargetEntite(target)) {
|
||||||
|
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée!!!!`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
RdDCombat.rddCombatTarget(target, this, token).attaqueV2();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return RdDConfirm.confirmer({
|
||||||
|
settingConfirmer: "confirmer-combat-sans-cible",
|
||||||
|
content: `<p>Voulez vous faire une attaque sans choisir de cible valide?
|
||||||
|
<br>Tous les jets de combats devront être gérés à la main
|
||||||
|
</p>`,
|
||||||
|
title: 'Ne pas utiliser les automatisation de combat',
|
||||||
|
buttonLabel: "Pas d'automatisation",
|
||||||
|
onAction: async () => {
|
||||||
|
this.rollCompetenceV2({
|
||||||
|
ids: {
|
||||||
|
actorId: this.id,
|
||||||
|
actorTokenId: token?.id,
|
||||||
|
},
|
||||||
|
selected: {
|
||||||
|
conditions: { value: 0 }
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
allowed: [ROLL_TYPE_COMP, ROLL_TYPE_ATTAQUE, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE, ROLL_TYPE_JEU],
|
||||||
|
current: ROLL_TYPE_COMP
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** --------------------------------------------
|
/** --------------------------------------------
|
||||||
* @param {*} arme item d'arme/compétence de créature
|
* @param {*} 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
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
rollArme(arme, categorieArme = 'competence', token = undefined) {
|
rollArme(arme, categorieArme = 'competence', token = undefined) {
|
||||||
token = token ?? RdDUtility.getSelectedToken(this)
|
token = token ?? RdDUtility.getSelectedToken(this)
|
||||||
const compToUse = RdDItemArme.getCompetenceArme(arme, categorieArme)
|
const compToUse = RdDItemArme.getCompetenceArme(arme, categorieArme)
|
||||||
if (!RdDItemArme.isUtilisable(arme)) {
|
if (!RdDItemArme.isUtilisable(arme)) {
|
||||||
ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`)
|
ui.notifications.warn(`Arme inutilisable: ${arme.name} non équipée ou avec une résistance de 0 ou moins`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!Targets.hasTargets()) {
|
if (!Targets.hasTargets()) {
|
||||||
@@ -490,29 +576,37 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async encaisser() { await RdDEncaisser.encaisser(this) }
|
async encaisser() { await RdDEncaisser.encaisser(this) }
|
||||||
|
|
||||||
async encaisserDommages(rollData, attacker = undefined, show = undefined, attackerToken = undefined, defenderToken = undefined) {
|
async encaisserDommages(dmg, attacker = undefined, show = undefined, attackerToken = undefined, defenderToken = undefined) {
|
||||||
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
|
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
const armure = await this.computeArmure(rollData);
|
if (!Misc.isOwnerPlayer(this)) {
|
||||||
|
return RdDBaseActor.remoteActorCall({
|
||||||
|
tokenId: attackerToken?.id ?? this.token?.id,
|
||||||
|
actorId: this.id,
|
||||||
|
method: 'encaisserDommages', args: [dmg, attacker, show, attackerToken, defenderToken]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const armure = await this.computeArmure(dmg)
|
||||||
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) {
|
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) {
|
||||||
await this.encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken);
|
await this.encaisserDommagesValidationGR(dmg, armure, show, attackerToken, defenderToken);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const jet = await RdDUtility.jetEncaissement(this, rollData, armure, { showDice: SHOW_DICE });
|
const jet = await RdDUtility.jetEncaissement(this, dmg, armure, { showDice: SHOW_DICE });
|
||||||
await this.$onEncaissement(jet, show, attackerToken, defenderToken)
|
await this.$onEncaissement(jet, show, attackerToken, defenderToken)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken) {
|
async encaisserDommagesValidationGR(dmg, armure, show, attackerToken, defenderToken) {
|
||||||
if (!game.user.isGM) {
|
if (!game.user.isGM) {
|
||||||
RdDBaseActor.remoteActorCall({
|
RdDBaseActor.remoteActorCall({
|
||||||
tokenId: this.token?.id,
|
tokenId: this.token?.id,
|
||||||
actorId: this.id,
|
actorId: this.id,
|
||||||
method: 'encaisserDommagesValidationGR', args: [rollData, armure, show, attackerToken, defenderToken]
|
method: 'encaisserDommagesValidationGR', args: [dmg, armure, show, attackerToken, defenderToken]
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
DialogValidationEncaissement.validerEncaissement(this, rollData, armure,
|
DialogValidationEncaissement.validerEncaissement(this, dmg, armure,
|
||||||
jet => this.$onEncaissement(jet, show, attackerToken, defenderToken));
|
jet => this.$onEncaissement(jet, show, attackerToken, defenderToken));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -549,15 +643,37 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async encaisserRecul(force, dmgArme = 0) {
|
||||||
|
const diffRecul = this.getTaille() - force - dmgArme
|
||||||
|
const rolled = await RdDResolutionTable.roll(10, diffRecul)
|
||||||
|
if (rolled.isSuccess) {
|
||||||
|
return 'encaisse'
|
||||||
|
}
|
||||||
|
if (rolled.isETotal || (await this.rollEquilibre(diffRecul)).isEchec) {
|
||||||
|
await this.setEffect(STATUSES.StatusProne, true)
|
||||||
|
return 'chute'
|
||||||
|
}
|
||||||
|
return 'recul'
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollEquilibre(diff) {
|
||||||
|
// TODO: accrobatie optionnelle sur jet d'équilibre?
|
||||||
|
if (ReglesOptionnelles.isSet('acrobatie-pour-recul')) {
|
||||||
|
diff += Math.max(0, this.getCompetence('acrobatie')?.system.niveau ?? 0)
|
||||||
|
}
|
||||||
|
return await RdDResolutionTable.roll(this.getAgilite(), diff);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
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.isEntite([ENTITE_INCARNE])
|
||||||
|| entite.isEntiteAccordee(this)) {
|
|| entite.isEntiteAccordee(this)) {
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
const rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.getNiveau()));
|
const rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.getNiveau()))
|
||||||
const rollData = {
|
const rollData = {
|
||||||
alias: this.getAlias(),
|
alias: this.getAlias(),
|
||||||
rolled: rolled,
|
rolled: rolled,
|
||||||
@@ -566,11 +682,11 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (rolled.isSuccess) {
|
if (rolled.isSuccess) {
|
||||||
await entite.setEntiteReveAccordee(this);
|
await entite.setEntiteReveAccordee(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.hbs');
|
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.hbs')
|
||||||
await this.appliquerAjoutExperience(rollData, true);
|
await this.appliquerAjoutExperience(rollData, true)
|
||||||
return rolled.isSuccess;
|
return rolled.isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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() {
|
||||||
@@ -161,7 +161,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);
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,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()) {
|
||||||
|
@@ -5,9 +5,9 @@ import { RdDSheetUtility } from "../rdd-sheet-utility.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";
|
||||||
import { RdDItem } from "../item.js";
|
import { RdDItem } from "../item.js";
|
||||||
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
|
||||||
import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js";
|
import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js";
|
||||||
import { ItemAction } from "../item/item-actions.js";
|
import { ItemAction } from "../item/item-actions.js";
|
||||||
|
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
@@ -56,7 +56,8 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
|
|||||||
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 => it.isdommages = RdDItemCompetenceCreature.isDommages(it))
|
.forEach(it => it.isdommages = it.isDommages()
|
||||||
|
)
|
||||||
|
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
@@ -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";
|
||||||
@@ -9,6 +9,8 @@ import { RdDAudio } from "../rdd-audio.js";
|
|||||||
import { RdDConfirm } from "../rdd-confirm.js";
|
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 { STATUSES } from "../settings/status-effects.js";
|
||||||
|
|
||||||
export class RdDBaseActor extends Actor {
|
export class RdDBaseActor extends Actor {
|
||||||
|
|
||||||
@@ -44,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))
|
||||||
}
|
}
|
||||||
@@ -217,6 +221,7 @@ export class RdDBaseActor extends Actor {
|
|||||||
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)) {
|
||||||
@@ -242,7 +247,28 @@ export class RdDBaseActor extends Actor {
|
|||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async onPreUpdateItem(item, change, options, id) { }
|
async onPreUpdateItem(item, change, options, id) { }
|
||||||
async onCreateItem(item, options, id) { }
|
|
||||||
|
async onCreateItem(item, options, id) {
|
||||||
|
switch (item.type) {
|
||||||
|
case ITEM_TYPES.blessure:
|
||||||
|
await this.changeBleedingState()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onUpdateItem(item, options, id) {
|
||||||
|
switch (item.type) {
|
||||||
|
case ITEM_TYPES.blessure:
|
||||||
|
await this.changeBleedingState()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async changeBleedingState() {
|
||||||
|
const bleeding = this.itemTypes[ITEM_TYPES.blessure].find(it => it.isBleeding())
|
||||||
|
await this.setEffect(STATUSES.StatusBleeding, bleeding ? true : false)
|
||||||
|
}
|
||||||
|
|
||||||
async onUpdateActor(update, options, actorId) { }
|
async onUpdateActor(update, options, actorId) { }
|
||||||
async onDeleteItem(item, options, id) {
|
async onDeleteItem(item, options, id) {
|
||||||
if (item.isInventaire()) {
|
if (item.isInventaire()) {
|
||||||
@@ -499,7 +525,8 @@ export class RdDBaseActor extends Actor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async computeEncTotal() {
|
async computeEncTotal() {
|
||||||
if (!this.pack) {
|
if (!this.pack) {
|
||||||
this.encTotal = this.items.map(it => it.getEncTotal()).reduce(Misc.sum(), 0);
|
this.encTotal = this.items.filter(it => RdDItem.getItemTypesInventaire().includes(it.type))
|
||||||
|
.map(it => it.getEncTotal()).reduce(Misc.sum(), 0)
|
||||||
return this.encTotal;
|
return this.encTotal;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -736,7 +763,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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -758,20 +785,24 @@ export class RdDBaseActor extends Actor {
|
|||||||
getCaracInit(competence) { return 0 }
|
getCaracInit(competence) { return 0 }
|
||||||
|
|
||||||
listAttaques() {
|
listAttaques() {
|
||||||
return this.listActions({ isAttaque: true, isEquipe:false })
|
return this.listActions({ isAttaque: true, isEquipe: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
listActions({ isAttaque = false, isEquipe=false }) { return [] }
|
listActions({ isAttaque = false, isEquipe = false }) { return [] }
|
||||||
|
|
||||||
listActionsPossessions() {
|
listActionsPossessions() {
|
||||||
return this.itemTypes[ITEM_TYPES.possession]
|
return this.itemTypes[ITEM_TYPES.possession]
|
||||||
.map(p => {
|
.map(p => {
|
||||||
return {
|
return {
|
||||||
name: p.name,
|
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({})
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
@@ -1,6 +1,4 @@
|
|||||||
import { Grammar } from "../grammar.js";
|
|
||||||
import { ITEM_TYPES } from "../constants.js";
|
import { ITEM_TYPES } from "../constants.js";
|
||||||
import { LIST_CARAC_AUTRES } from "../rdd-carac.js";
|
|
||||||
import { RdDBaseActorSang } from "./base-actor-sang.js";
|
import { RdDBaseActorSang } from "./base-actor-sang.js";
|
||||||
|
|
||||||
export class RdDCreature extends RdDBaseActorSang {
|
export class RdDCreature extends RdDBaseActorSang {
|
||||||
@@ -45,5 +43,4 @@ export class RdDCreature extends RdDBaseActorSang {
|
|||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@ import { SYSTEM_RDD } from "../../constants.js";
|
|||||||
import { Misc } from "../../misc.js";
|
import { Misc } from "../../misc.js";
|
||||||
import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js";
|
import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.js";
|
||||||
import { ExportScriptarium } from "./export-scriptarium.js";
|
import { ExportScriptarium } from "./export-scriptarium.js";
|
||||||
import { CATEGORIES_COMPETENCES, CATEGORIES_DRACONIC, Mapping } from "./mapping.js";
|
import { CATEGORIES_COMPETENCES_BASE, CATEGORIES_DRACONIC, Mapping } from "./mapping.js";
|
||||||
|
|
||||||
export class RdDActorExportSheet extends RdDActorSheet {
|
export class RdDActorExportSheet extends RdDActorSheet {
|
||||||
static init() {
|
static init() {
|
||||||
@@ -44,7 +44,7 @@ export class RdDActorExportSheet extends RdDActorSheet {
|
|||||||
formData.context = Mapping.prepareContext(this.actor)
|
formData.context = Mapping.prepareContext(this.actor)
|
||||||
formData.attaques = this.actor.listActionsAttaque()
|
formData.attaques = this.actor.listActionsAttaque()
|
||||||
formData.export = this.getMappingValues(formData.context, this.actor)
|
formData.export = this.getMappingValues(formData.context, this.actor)
|
||||||
formData.competences = this.getCompetences(CATEGORIES_COMPETENCES)
|
formData.competences = this.getCompetences(CATEGORIES_COMPETENCES_BASE)
|
||||||
formData.draconic = this.getCompetences(CATEGORIES_DRACONIC)
|
formData.draconic = this.getCompetences(CATEGORIES_DRACONIC)
|
||||||
const legeres = this.actor.nbBlessuresLegeres()
|
const legeres = this.actor.nbBlessuresLegeres()
|
||||||
const graves = this.actor.nbBlessuresGraves()
|
const graves = this.actor.nbBlessuresGraves()
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
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 } from "../../constants.js"
|
||||||
@@ -9,7 +9,7 @@ import { RdDBonus } from "../../rdd-bonus.js"
|
|||||||
import { TMRType } from "../../tmr-utility.js"
|
import { TMRType } from "../../tmr-utility.js"
|
||||||
|
|
||||||
|
|
||||||
export const CATEGORIES_COMPETENCES = [
|
export const CATEGORIES_COMPETENCES_BASE = [
|
||||||
"generale",
|
"generale",
|
||||||
"particuliere",
|
"particuliere",
|
||||||
"specialisee",
|
"specialisee",
|
||||||
@@ -88,7 +88,7 @@ const MAPPING_BASE = [
|
|||||||
{ column: "endurance_actuel", rollClass: 'jet-endurance', getter: (actor, context) => actor.system.sante.endurance.value },
|
{ column: "endurance_actuel", rollClass: 'jet-endurance', getter: (actor, context) => actor.system.sante.endurance.value },
|
||||||
{ column: "esquive", getter: (actor, context) => Mapping.getEsquive(context) },
|
{ column: "esquive", getter: (actor, context) => Mapping.getEsquive(context) },
|
||||||
{ column: "esquive_armure", getter: (actor, context) => Mapping.getEsquiveArmure(context) },
|
{ column: "esquive_armure", getter: (actor, context) => Mapping.getEsquiveArmure(context) },
|
||||||
{ column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES) },
|
{ column: "competences", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_COMPETENCES_BASE) },
|
||||||
{ column: "draconic", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_DRACONIC) },
|
{ column: "draconic", getter: (actor, context) => Mapping.getCompetences(actor, CATEGORIES_DRACONIC) },
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -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,
|
||||||
@@ -175,7 +175,7 @@ export class Mapping {
|
|||||||
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 'non-mortel': return `(${dommages})`
|
||||||
case 'empoignade': return '-'
|
case EMPOIGNADE: return '-'
|
||||||
}
|
}
|
||||||
return dommages
|
return dommages
|
||||||
}
|
}
|
||||||
@@ -274,11 +274,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
|
||||||
|
@@ -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";
|
||||||
|
|
||||||
@@ -190,15 +190,19 @@ 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-sender').after(dateHeure)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async onCreateChatMessage(chatMessage, options, id) {
|
static async onCreateChatMessage(chatMessage, options, id) {
|
||||||
if (chatMessage.isAuthor) {
|
if (chatMessage.isAuthor) {
|
||||||
await chatMessage.setFlag(SYSTEM_RDD, 'rdd-timestamp', game.system.rdd.calendrier.getTimestamp());
|
await ChatUtility.setTimestamp(chatMessage)
|
||||||
await chatMessage.update({ content: await RdDTextEditor.enrichHTML(chatMessage.content, undefined, { showLink: false }) })
|
await chatMessage.update({ content: await RdDTextEditor.enrichHTML(chatMessage.content, undefined, { showLink: false }) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async setTimestamp(chatMessage) {
|
||||||
|
await chatMessage.setFlag(SYSTEM_RDD, 'rdd-timestamp', game.system.rdd.calendrier.getTimestamp());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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,17 +9,19 @@ 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",
|
||||||
@@ -30,28 +32,34 @@ export const RDD_CONFIG = {
|
|||||||
"nonincarne": "Non Incarnée",
|
"nonincarne": "Non Incarnée",
|
||||||
"blurette": "Blurette"
|
"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: 'finesse', descr: 'en rapidité', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-rapidite.svg'},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const ACTOR_TYPES = {
|
export const ACTOR_TYPES = {
|
||||||
personnage: 'personnage',
|
personnage: 'personnage',
|
||||||
creature: 'creature',
|
creature: 'creature',
|
||||||
@@ -106,3 +114,4 @@ export const ITEM_TYPES = {
|
|||||||
nombreastral: 'nombreastral',
|
nombreastral: 'nombreastral',
|
||||||
extraitpoetique: 'extraitpoetique',
|
extraitpoetique: 'extraitpoetique',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,18 +7,17 @@ import { RdDUtility } from "./rdd-utility.js";
|
|||||||
*/
|
*/
|
||||||
export class DialogValidationEncaissement extends Dialog {
|
export class DialogValidationEncaissement extends Dialog {
|
||||||
|
|
||||||
static async validerEncaissement(actor, rollData, armure, onEncaisser) {
|
static async validerEncaissement(actor, dmg, armure, onEncaisser) {
|
||||||
const encaissement = await RdDUtility.jetEncaissement(actor, rollData, armure, { showDice: HIDE_DICE });
|
const encaissement = await RdDUtility.jetEncaissement(actor, dmg, armure, { showDice: HIDE_DICE });
|
||||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.hbs', {
|
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.hbs', {
|
||||||
actor: actor,
|
actor: actor,
|
||||||
rollData: rollData,
|
|
||||||
encaissement: encaissement
|
encaissement: encaissement
|
||||||
});
|
});
|
||||||
new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser).render(true);
|
new DialogValidationEncaissement(html, actor, dmg, armure, encaissement, onEncaisser).render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(html, actor, rollData, armure, encaissement, onEncaisser) {
|
constructor(html, actor, dmg, armure, encaissement, onEncaisser) {
|
||||||
// Common conf
|
// Common conf
|
||||||
let buttons = {
|
let buttons = {
|
||||||
"valider": { label: "Valider", callback: html => this.onValider() },
|
"valider": { label: "Valider", callback: html => this.onValider() },
|
||||||
@@ -42,11 +41,11 @@ export class DialogValidationEncaissement extends Dialog {
|
|||||||
super(dialogConf, dialogOptions);
|
super(dialogConf, dialogOptions);
|
||||||
|
|
||||||
this.actor = actor
|
this.actor = actor
|
||||||
this.rollData = rollData;
|
this.dmg = dmg
|
||||||
this.armure = armure;
|
this.armure = armure
|
||||||
this.encaissement = encaissement;
|
this.encaissement = encaissement
|
||||||
this.onEncaisser = onEncaisser;
|
this.onEncaisser = onEncaisser
|
||||||
this.forceDiceResult = {total: encaissement.roll.result };
|
this.forceDiceResult = {total: encaissement.roll.result }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -55,14 +54,14 @@ export class DialogValidationEncaissement extends Dialog {
|
|||||||
this.html = html;
|
this.html = html;
|
||||||
this.html.find('input.encaissement-roll-result').keyup(async event => {
|
this.html.find('input.encaissement-roll-result').keyup(async event => {
|
||||||
this.forceDiceResult.total = event.currentTarget.value;
|
this.forceDiceResult.total = event.currentTarget.value;
|
||||||
this.encaissement = await RdDUtility.jetEncaissement(this.actor, this.rollData, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult});
|
this.encaissement = await RdDUtility.jetEncaissement(this.actor, this.dmg, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult});
|
||||||
this.html.find('label.encaissement-total').text(this.encaissement.total);
|
this.html.find('label.encaissement-total').text(this.encaissement.total);
|
||||||
this.html.find('label.encaissement-blessure').text(this.encaissement.blessures)
|
this.html.find('label.encaissement-blessure').text(this.encaissement.blessures)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async onValider() {
|
async onValider() {
|
||||||
this.encaissement = await RdDUtility.jetEncaissement(this.actor, this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
this.encaissement = await RdDUtility.jetEncaissement(this.actor, this.dmg, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
||||||
this.onEncaisser(this.encaissement)
|
this.onEncaisser(this.encaissement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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,65 @@
|
|||||||
|
export const MAP_PHASE = {
|
||||||
|
possession: { label: "possession", rang: 10 },
|
||||||
|
draconic: { label: "draconic", rang: 9 },
|
||||||
|
tir: { label: "tir", rang: 8 },
|
||||||
|
lancer: { label: "lancer", rang: 7 },
|
||||||
|
arme: { label: "mêlée", rang: 5 },
|
||||||
|
pugilat: { label: "pugilat", rang: 4 },
|
||||||
|
naturelle: { label: "créature", rang: 4 },
|
||||||
|
empoignade: { label: "empoignade", rang: 3 },
|
||||||
|
autre: { label: "autre action", rang: 2 },
|
||||||
|
demi: { label: "demi-surprise", rang: 0 },
|
||||||
|
totale: { label: "surprise totale", rang: -1 },
|
||||||
|
}
|
||||||
|
export const PHASE = Object.values(MAP_PHASE)
|
||||||
|
|
||||||
export class RdDInitiative {
|
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,
|
||||||
|
init: formule.phase.rang + value / 100,
|
||||||
|
label: formule.phase.label
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
import { SANS_COMPETENCE } from "./item/base-items.js";
|
import { CATEGORIES_COMPETENCES, SANS_COMPETENCE } from "./item/base-items.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
|
|
||||||
const competenceTroncs = [["Esquive", "Dague", "Corps à corps"],
|
const competenceTroncs = [["Esquive", "Dague", "Corps à corps"],
|
||||||
@@ -25,16 +26,6 @@ const limitesArchetypes = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
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" }
|
|
||||||
}
|
|
||||||
|
|
||||||
function _buildCumulXP() {
|
function _buildCumulXP() {
|
||||||
let cumulXP = { "-11": 0 };
|
let cumulXP = { "-11": 0 };
|
||||||
@@ -49,7 +40,12 @@ function _buildCumulXP() {
|
|||||||
|
|
||||||
const competence_xp_cumul = _buildCumulXP();
|
const competence_xp_cumul = _buildCumulXP();
|
||||||
|
|
||||||
export class RdDItemCompetence extends Item {
|
export class RdDItemCompetence extends RdDItem {
|
||||||
|
|
||||||
|
static get ITEM_TYPE() { return ITEM_TYPES.competence }
|
||||||
|
|
||||||
|
static get defaultIcon() { return "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp" }
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getLabelCategorie(category) {
|
static getLabelCategorie(category) {
|
||||||
return CATEGORIES_COMPETENCES[category].label;
|
return CATEGORIES_COMPETENCES[category].label;
|
||||||
|
@@ -1,126 +1,74 @@
|
|||||||
|
|
||||||
import { ITEM_TYPES } from "./constants.js";
|
import { ITEM_TYPES } from "./constants.js";
|
||||||
import { Grammar } from "./grammar.js";
|
|
||||||
import { RdDInitiative } from "./initiative.mjs";
|
|
||||||
import { RdDItem } from "./item.js";
|
import { RdDItem } from "./item.js";
|
||||||
|
import { RdDInitiative } from "./initiative.mjs";
|
||||||
export const CATEGORIES_COMPETENCES_CREATURES = {
|
import { RdDItemArme } from "./item/arme.js";
|
||||||
"generale": { base: 0, label: "Générale" },
|
|
||||||
"naturelle": { base: 0, label: "Arme naturelle" },
|
|
||||||
"melee": { base: 0, label: "Mêlée" },
|
|
||||||
"parade": { base: 0, label: "Parade" },
|
|
||||||
"tir": { base: 0, label: "Tir" },
|
|
||||||
"lancer": { base: 0, label: "Lancer" },
|
|
||||||
"possession": { base: 0, label: "Possession" },
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDItemCompetenceCreature extends Item {
|
export class RdDItemCompetenceCreature extends RdDItem {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
static get ITEM_TYPE() { return ITEM_TYPES.competencecreature }
|
||||||
static setRollDataCreature(rollData) {
|
|
||||||
const code = Grammar.toLowerCaseNoAccentNoSpace(rollData.competence.name);
|
|
||||||
const selectedCarac = { code: code, label: rollData.competence.name, value: rollData.competence.system.carac_value };
|
|
||||||
rollData.carac = { [code]: selectedCarac }
|
|
||||||
rollData.competence.system.defaut_carac = code
|
|
||||||
rollData.selectedCarac = selectedCarac
|
|
||||||
rollData.arme = RdDItemCompetenceCreature.armeCreature(rollData.competence);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
static get defaultIcon() { return "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp" }
|
||||||
static armeCreature(item) {
|
|
||||||
const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item)
|
isAttaque() { return this.getCategorieAttaque() != undefined }
|
||||||
|
isParade() { return this.system.iscombat && (this.system.categorie_parade ?? '') != '' }
|
||||||
|
isBouclier() { return this.system.categorie_parade.includes('bouclier') }
|
||||||
|
attaqueCreature() {
|
||||||
|
const categorieAttaque = this.getCategorieAttaque()
|
||||||
if (categorieAttaque != undefined) {
|
if (categorieAttaque != undefined) {
|
||||||
// cloner pour ne pas modifier la compétence
|
const initative = RdDInitiative.getRollInitiative(this.system.carac_value, this.system.niveau);
|
||||||
return foundry.utils.mergeObject(item, {
|
const attaque = {
|
||||||
action: item.isCompetencePossession() ? 'possession' : 'attaque',
|
label: this.name,
|
||||||
system: {
|
action: this.isCompetencePossession() ? 'possession' : 'attaque',
|
||||||
competence: item.name,
|
|
||||||
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
|
|
||||||
niveau: item.system.niveau,
|
|
||||||
initiative: RdDInitiative.calculInitiative(item.system.niveau, item.system.carac_value),
|
|
||||||
equipe: true,
|
|
||||||
resistance: 100,
|
|
||||||
dommagesReels: item.system.dommages,
|
|
||||||
penetration: 0,
|
|
||||||
force: 0,
|
|
||||||
rapide: true,
|
|
||||||
}
|
|
||||||
}, { inplace: false, });
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
static attaqueCreature(comp) {
|
|
||||||
const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(comp)
|
|
||||||
if (categorieAttaque != undefined) {
|
|
||||||
const initative = RdDInitiative.calculInitiative(comp.system.niveau, comp.system.carac_value);
|
|
||||||
return {
|
|
||||||
name: comp.name,
|
|
||||||
action: comp.isCompetencePossession() ? 'possession' : 'attaque',
|
|
||||||
initOnly: false,
|
initOnly: false,
|
||||||
arme: new RdDItem({
|
arme: new RdDItemArme({
|
||||||
name: comp.name,
|
name: this.name,
|
||||||
type: ITEM_TYPES.arme,
|
type: ITEM_TYPES.arme,
|
||||||
img: comp.img,
|
img: this.img,
|
||||||
system: {
|
system: {
|
||||||
competence: comp.name,
|
competence: this.name,
|
||||||
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
|
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
|
||||||
niveau: comp.system.niveau,
|
niveau: this.system.niveau,
|
||||||
initiative: initative,
|
initiative: initative,
|
||||||
|
mortalite: this.system.mortalite,
|
||||||
|
dommages: this.system.dommages,
|
||||||
equipe: true,
|
equipe: true,
|
||||||
resistance: 100,
|
resistance: 100,
|
||||||
dommagesReels: comp.system.dommages,
|
|
||||||
penetration: 0,
|
penetration: 0,
|
||||||
force: 0,
|
force: 0,
|
||||||
rapide: true,
|
rapide: true,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
comp: comp,
|
comp: this,
|
||||||
// main: '',
|
carac: { key: this.name, value: this.system.carac_value },
|
||||||
carac: { key: comp.name, value: comp.system.carac_value },
|
|
||||||
equipe: true,
|
equipe: true,
|
||||||
dmg: comp.system.dommages,
|
mortalite: this.system.mortalite,
|
||||||
|
dmg: this.system.dommages,
|
||||||
initiative: initative
|
initiative: initative
|
||||||
}
|
};
|
||||||
|
return attaque
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
getCategorieAttaque() {
|
||||||
static isAttaque(item) {
|
switch (this.system.categorie) {
|
||||||
return RdDItemCompetenceCreature.getCategorieAttaque(item) != undefined
|
case "melee":
|
||||||
}
|
case "tir":
|
||||||
|
case "lancer":
|
||||||
static getCategorieAttaque(item) {
|
case "naturelle":
|
||||||
if (item.type == ITEM_TYPES.competencecreature) {
|
case "possession":
|
||||||
switch (item.system.categorie) {
|
return this.system.categorie
|
||||||
case "melee":
|
|
||||||
case "tir":
|
|
||||||
case "lancer":
|
|
||||||
case "naturelle":
|
|
||||||
case "possession":
|
|
||||||
return item.system.categorie
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static isDommages(item) {
|
isDommages() {
|
||||||
if (item.type == ITEM_TYPES.competencecreature) {
|
switch (this.system.categorie) {
|
||||||
switch (item.system.categorie) {
|
case "melee":
|
||||||
case "melee":
|
case "tir":
|
||||||
case "tir":
|
case "lancer":
|
||||||
case "lancer":
|
case "naturelle":
|
||||||
case "naturelle":
|
return true
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
static isParade(item) {
|
|
||||||
if (item.type == ITEM_TYPES.competencecreature) {
|
|
||||||
return item.system.categorie_parade || item.system.isparade
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
import { ACTOR_TYPES, ITEM_TYPES } from "./constants.js";
|
import { ACTOR_TYPES, ITEM_TYPES } from "./constants.js";
|
||||||
|
|
||||||
|
import { RdDItem } from "./item.js";
|
||||||
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { RdDItemSort } from "./item-sort.js";
|
import { RdDItemSort } from "./item-sort.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
|
||||||
import { HtmlUtility } from "./html-utility.js";
|
import { HtmlUtility } from "./html-utility.js";
|
||||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { SYSTEM_RDD } from "./constants.js";
|
import { SYSTEM_RDD } from "./constants.js";
|
||||||
@@ -9,8 +11,6 @@ import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
|||||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
import { SystemCompendiums } from "./settings/system-compendiums.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 { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
|
||||||
import { RdDItem } from "./item.js";
|
|
||||||
import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js";
|
import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js";
|
||||||
import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js";
|
import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js";
|
||||||
import { ItemAction } from "./item/item-actions.js";
|
import { ItemAction } from "./item/item-actions.js";
|
||||||
@@ -106,8 +106,8 @@ export class RdDItemSheetV1 extends foundry.appv1.sheets.ItemSheet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.item.type == ITEM_TYPES.competencecreature) {
|
if (this.item.type == ITEM_TYPES.competencecreature) {
|
||||||
formData.isparade = RdDItemCompetenceCreature.isParade(this.item)
|
formData.isparade = this.item.isParade()
|
||||||
formData.isdommages = RdDItemCompetenceCreature.isDommages(this.item)
|
formData.isdommages = this.item.isDommages()
|
||||||
}
|
}
|
||||||
if (this.item.type == ITEM_TYPES.tache ||
|
if (this.item.type == ITEM_TYPES.tache ||
|
||||||
this.item.type == ITEM_TYPES.livre ||
|
this.item.type == ITEM_TYPES.livre ||
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
import { ITEM_TYPES } from "./constants.js";
|
import { ITEM_TYPES, renderTemplate } from "./constants.js";
|
||||||
|
import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES, CATEGORIES_COMPETENCES_CREATURES } from "./item/base-items.js";
|
||||||
|
import { ITEM_ACTIONS, DEFAULT_ACTIONS, COMMON_ACTIONS } from "./item/item-actions.js";
|
||||||
|
|
||||||
import { Grammar } from "./grammar.js";
|
import { Grammar } from "./grammar.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
@@ -7,10 +9,6 @@ import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
|||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||||
import { RdDRaretes } from "./item/raretes.js";
|
import { RdDRaretes } from "./item/raretes.js";
|
||||||
import { CATEGORIES_COMPETENCES } from "./item-competence.js";
|
|
||||||
import { CATEGORIES_COMPETENCES_CREATURES } from "./item-competencecreature.js";
|
|
||||||
import { BASE_CORPS_A_CORPS, BASE_ESQUIVE } from "./item/base-items.js";
|
|
||||||
import { ITEM_ACTIONS, DEFAULT_ACTIONS, COMMON_ACTIONS } from "./item/item-actions.js";
|
|
||||||
|
|
||||||
const typesInventaireMateriel = [
|
const typesInventaireMateriel = [
|
||||||
ITEM_TYPES.arme,
|
ITEM_TYPES.arme,
|
||||||
@@ -186,7 +184,10 @@ export class RdDItem extends Item {
|
|||||||
isMonnaie() { return this.type == ITEM_TYPES.monnaie; }
|
isMonnaie() { return this.type == ITEM_TYPES.monnaie; }
|
||||||
isNourritureBoisson() { return this.type == ITEM_TYPES.nourritureboisson; }
|
isNourritureBoisson() { return this.type == ITEM_TYPES.nourritureboisson; }
|
||||||
isService() { return this.type == ITEM_TYPES.service; }
|
isService() { return this.type == ITEM_TYPES.service; }
|
||||||
|
isAttaque() { return false }
|
||||||
|
isParade() { return false }
|
||||||
|
isBouclier() { return false }
|
||||||
|
getCategorieAttaque() { return undefined }
|
||||||
isCompetence() { return typesObjetsCompetence.includes(this.type) }
|
isCompetence() { return typesObjetsCompetence.includes(this.type) }
|
||||||
isEsquive() {
|
isEsquive() {
|
||||||
return (this.isCompetence()
|
return (this.isCompetence()
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import { ITEM_TYPES } from "../constants.js";
|
import { ITEM_TYPES } from "../constants.js";
|
||||||
import { RdDItem } from "../item.js";
|
import { RdDItem } from "../item.js";
|
||||||
|
|
||||||
import { RdDItemCompetenceCreature } from "../item-competencecreature.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 { Misc } from "../misc.js";
|
||||||
|
|
||||||
const nomCategorieParade = {
|
const nomCategorieParade = {
|
||||||
"sans-armes": "Sans arme",
|
"sans-armes": "Sans arme",
|
||||||
@@ -19,26 +19,56 @@ const nomCategorieParade = {
|
|||||||
"haches": "Haches",
|
"haches": "Haches",
|
||||||
"lances": "Lances",
|
"lances": "Lances",
|
||||||
}
|
}
|
||||||
|
export const ATTAQUE_TYPE = {
|
||||||
|
UNE_MAIN: '(1 main)',
|
||||||
|
DEUX_MAINS: '(2 mains)',
|
||||||
|
CORPS_A_CORPS: '(corps à corps)',
|
||||||
|
COMPETENCE: 'competence',
|
||||||
|
TIR: '(tir)',
|
||||||
|
LANCER: '(lancer)'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CORPS_A_CORPS = 'Corps à corps'
|
||||||
|
export const PUGILAT = 'pugilat'
|
||||||
|
export const EMPOIGNADE = 'empoignade'
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDItemArme extends RdDItem {
|
export class RdDItemArme extends RdDItem {
|
||||||
|
|
||||||
static get ITEM_TYPE() { return ITEM_TYPES.arme }
|
static get ITEM_TYPE() { return ITEM_TYPES.arme }
|
||||||
|
|
||||||
static get defaultIcon() {
|
static get defaultIcon() { return "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp" }
|
||||||
return defaultItemImgArme
|
|
||||||
//return "systems/foundryvtt-reve-de-dragon/icons/armes_armure/epee_sord.webp";
|
penetration() { return parseInt(this.system.penetration ?? 0) }
|
||||||
}
|
|
||||||
|
isParade() { return this.system.resistance > 0 && this.system.categorie_parade }
|
||||||
|
isBouclier() { return RdDItemArme.getCategorieParade(this).includes('bouclier') }
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
static valeurMain(valeurs, main) {
|
||||||
|
valeurs = valeurs?.toString() ?? ""
|
||||||
|
const table = valeurs.includes("/") ? valeurs.split("/") : [valeurs, valeurs]
|
||||||
|
return parseInt(main == ATTAQUE_TYPE.DEUX_MAINS ? table[1] : table[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
static getMainAttaque(competence) {
|
||||||
|
switch (competence.system.categorie) {
|
||||||
|
case 'tir': return ATTAQUE_TYPE.TIR
|
||||||
|
case 'lancer': return ATTAQUE_TYPE.LANCER
|
||||||
|
}
|
||||||
|
if (competence.name.includes('2 main')) {
|
||||||
|
return ATTAQUE_TYPE.DEUX_MAINS
|
||||||
|
}
|
||||||
|
return ATTAQUE_TYPE.UNE_MAIN
|
||||||
|
}
|
||||||
|
|
||||||
static getArme(arme) {
|
static getArme(arme) {
|
||||||
switch (arme ? arme.type : '') {
|
switch (arme ? arme.type : '') {
|
||||||
case ITEM_TYPES.arme: return arme;
|
case ITEM_TYPES.arme: return arme;
|
||||||
case ITEM_TYPES.competencecreature:
|
case ITEM_TYPES.competencecreature:
|
||||||
return RdDItemCompetenceCreature.armeCreature(arme);
|
return MappingCreatureArme.armeCreature(arme);
|
||||||
}
|
}
|
||||||
return RdDItemArme.corpsACorps();
|
return RdDItemArme.pugilat();
|
||||||
}
|
}
|
||||||
|
|
||||||
static getCompetenceArme(arme, maniement) {
|
static getCompetenceArme(arme, maniement) {
|
||||||
@@ -47,11 +77,12 @@ export class RdDItemArme extends RdDItem {
|
|||||||
return arme.name
|
return arme.name
|
||||||
case ITEM_TYPES.arme:
|
case ITEM_TYPES.arme:
|
||||||
switch (maniement) {
|
switch (maniement) {
|
||||||
case 'competence': return arme.system.competence;
|
case ATTAQUE_TYPE.COMPETENCE: return arme.system.competence;
|
||||||
case '(1 main)': return arme.competence1Mains()
|
case ATTAQUE_TYPE.UNE_MAIN: return arme.competence1Mains()
|
||||||
case '(2 mains)': return arme.competence2Mains()
|
case ATTAQUE_TYPE.DEUX_MAINS: return arme.competence2Mains()
|
||||||
case '(tir)': case 'tir': return arme.system.tir
|
case ATTAQUE_TYPE.TIR: case 'tir': return arme.system.tir
|
||||||
case '(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
|
||||||
@@ -88,16 +119,13 @@ export class RdDItemArme extends RdDItem {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getCategorieParade(armeData) {
|
static getCategorieParade(armeData) {
|
||||||
|
if (![ITEM_TYPES.arme, ITEM_TYPES.competencecreature].includes(armeData.type)) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
if (armeData.system.categorie_parade) {
|
if (armeData.system.categorie_parade) {
|
||||||
return armeData.system.categorie_parade
|
return armeData.system.categorie_parade
|
||||||
}
|
}
|
||||||
// pour compatibilité avec des personnages existants
|
// pour compatibilité avec des personnages existants
|
||||||
if (armeData.type == ITEM_TYPES.competencecreature || armeData.system.categorie == 'creature') {
|
|
||||||
return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : '')
|
|
||||||
}
|
|
||||||
if (!armeData.type.match(/arme|competencecreature/)) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
if (armeData.system.competence == undefined) {
|
if (armeData.system.competence == undefined) {
|
||||||
return ITEM_TYPES.competencecreature;
|
return ITEM_TYPES.competencecreature;
|
||||||
}
|
}
|
||||||
@@ -192,7 +220,7 @@ export class RdDItemArme extends RdDItem {
|
|||||||
return Number(arme.system.dommages)
|
return Number(arme.system.dommages)
|
||||||
}
|
}
|
||||||
const tableauDegats = arme.system.dommages.split("/");
|
const tableauDegats = arme.system.dommages.split("/");
|
||||||
return Number(tableauDegats[maniement == '(1 main)' ? 0 : 1])
|
return Number(tableauDegats[maniement == ATTAQUE_TYPE.UNE_MAIN ? 0 : 1])
|
||||||
}
|
}
|
||||||
return Number(arme.system.dommages);
|
return Number(arme.system.dommages);
|
||||||
}
|
}
|
||||||
@@ -201,7 +229,7 @@ export class RdDItemArme extends RdDItem {
|
|||||||
static armeUneOuDeuxMains(arme, aUneMain) {
|
static armeUneOuDeuxMains(arme, aUneMain) {
|
||||||
if (arme && !arme.system.cac) {
|
if (arme && !arme.system.cac) {
|
||||||
arme = foundry.utils.duplicate(arme);
|
arme = foundry.utils.duplicate(arme);
|
||||||
arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? '(1 main)' : '(2 mains)')
|
arme.system.dommagesReels = RdDItemArme.dommagesReels(arme, aUneMain ? ATTAQUE_TYPE.UNE_MAIN : ATTAQUE_TYPE.DEUX_MAINS)
|
||||||
}
|
}
|
||||||
return arme;
|
return arme;
|
||||||
}
|
}
|
||||||
@@ -222,63 +250,42 @@ export class RdDItemArme extends RdDItem {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
static isAttaque(arme) {
|
isAttaque() {
|
||||||
switch (arme.type) {
|
return this.system.resistance > 0 || (this.system.tir != '' && this.system.portee_courte > 0)
|
||||||
case ITEM_TYPES.arme: return arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0)
|
|
||||||
case ITEM_TYPES.competencecreature: return arme.system.iscombat && RdDItemCompetenceCreature.isAttaque(item)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static isParade(arme) {
|
static pugilat(actor) {
|
||||||
switch (arme.type) {
|
return RdDItemArme.$corpsACorps(actor, 'Pugilat', PUGILAT)
|
||||||
case ITEM_TYPES.arme:
|
|
||||||
return arme.system.resistance > 0 && true/* TODO: regarder la categorie d'arme?*/
|
|
||||||
case ITEM_TYPES.competencecreature:
|
|
||||||
return arme.system.iscombat && RdDItemCompetenceCreature.isParade(arme)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static empoignade(actor) {
|
||||||
|
return RdDItemArme.$corpsACorps(actor, 'Empoignade', EMPOIGNADE)
|
||||||
|
}
|
||||||
|
|
||||||
static corpsACorps(actor) {
|
static $corpsACorps(actor, name, cac, system) {
|
||||||
let competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS
|
const competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS
|
||||||
let melee = actor ? actor.system.carac['melee'].value : 0
|
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 == EMPOIGNADE ? EMPOIGNADE : 'non-mortel',
|
||||||
competence: 'Corps à corps',
|
competence: CORPS_A_CORPS,
|
||||||
resistance: 1,
|
resistance: 1,
|
||||||
baseInit: 4,
|
baseInit: cac == 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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -18,3 +18,23 @@ export const SANS_COMPETENCE = {
|
|||||||
img: "systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp"
|
img: "systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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" }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CATEGORIES_COMPETENCES_CREATURES = {
|
||||||
|
"generale": { base: 0, label: "Générale" },
|
||||||
|
"naturelle": { base: 0, label: "Arme naturelle" },
|
||||||
|
"melee": { base: 0, label: "Mêlée" },
|
||||||
|
"parade": { base: 0, label: "Parade" },
|
||||||
|
"tir": { base: 0, label: "Tir" },
|
||||||
|
"lancer": { base: 0, label: "Lancer" },
|
||||||
|
"possession": { base: 0, label: "Possession" },
|
||||||
|
}
|
||||||
|
@@ -209,6 +209,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
|
||||||
}
|
}
|
||||||
|
41
module/item/mapping-creature-arme.mjs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { Grammar } from "../grammar.js";
|
||||||
|
import { RdDInitiative } from "../initiative.mjs";
|
||||||
|
|
||||||
|
export class MappingCreatureArme {
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static setRollDataCreature(rollData) {
|
||||||
|
const code = Grammar.toLowerCaseNoAccentNoSpace(rollData.competence.name);
|
||||||
|
const selectedCarac = { code: code, label: rollData.competence.name, value: rollData.competence.system.carac_value };
|
||||||
|
rollData.carac = { [code]: selectedCarac }
|
||||||
|
rollData.competence.system.defaut_carac = code
|
||||||
|
rollData.selectedCarac = selectedCarac
|
||||||
|
rollData.arme = MappingCreatureArme.armeCreature(rollData.competence);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static armeCreature(item) {
|
||||||
|
const categorieAttaque = item.getCategorieAttaque()
|
||||||
|
if (categorieAttaque != undefined) {
|
||||||
|
// cloner pour ne pas modifier la compétence
|
||||||
|
return foundry.utils.mergeObject(item, {
|
||||||
|
action: item.isCompetencePossession() ? 'possession' : 'attaque',
|
||||||
|
system: {
|
||||||
|
competence: item.name,
|
||||||
|
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
|
||||||
|
niveau: item.system.niveau,
|
||||||
|
initiative: RdDInitiative.getRollInitiative(item.system.carac_value, item.system.niveau),
|
||||||
|
equipe: true,
|
||||||
|
resistance: 100,
|
||||||
|
dommagesReels: item.system.dommages,
|
||||||
|
penetration: 0,
|
||||||
|
force: 0,
|
||||||
|
rapide: true,
|
||||||
|
}
|
||||||
|
}, { inplace: false, });
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -34,6 +34,13 @@ export class Misc {
|
|||||||
return ((n % m) + m) % m;
|
return ((n % m) + m) % m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inRange(value, min, max) {
|
||||||
|
if (min > max) {
|
||||||
|
return Misc.inRange(value, max, min)
|
||||||
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -58,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}`)
|
||||||
: '';
|
: '';
|
||||||
@@ -108,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,21 +1,25 @@
|
|||||||
import { RdDCarac } from "./rdd-carac.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";
|
||||||
|
|
||||||
const conditionsTactiques = [
|
const conditionsTactiques = [
|
||||||
{ type: '', descr: '', dmg: 0, attaque: 0, parade: 0, esquive: true },
|
{ key: '', label: '', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false },
|
||||||
{ type: 'charge', descr: 'Charge', dmg: 2, attaque: 4, parade: -4, esquive: false },
|
{ key: 'normale', label: 'Attaque normale', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: true },
|
||||||
{ type: 'feinte', descr: 'Feinte', dmg: 1, attaque: 1, parade: 0, esquive: true },
|
{ key: 'charge', label: 'Charge', dmg: 2, attaque: 4, parade: -4, esquive: false, isTactique: true },
|
||||||
{ type: 'pret', descr: 'prêt', dmg: 0, attaque: 0, parade: 0, esquive: true },
|
{ key: 'feinte', label: 'Feinte', dmg: 1, attaque: 1, parade: 0, esquive: true, isTactique: true },
|
||||||
{ type: 'demi', descr: 'Demi-surprise', dmg: 1, attaque: 0, parade: 0, esquive: true },
|
{ key: 'pret', label: 'prêt', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false },
|
||||||
{ type: 'totale', descr: 'Surprise totale', dmg: 10, attaque: 6, parade: 0, esquive: true },
|
{ key: 'demi', label: 'Demi-surprise', dmg: 1, attaque: 0, parade: 0, esquive: true, isTactique: false },
|
||||||
|
{ key: 'totale', label: 'Surprise totale', dmg: 10, attaque: 6, parade: 0, esquive: true, isTactique: false },
|
||||||
];
|
];
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDBonus {
|
export class RdDBonus {
|
||||||
|
static get tactiques() {
|
||||||
|
return conditionsTactiques.filter(it => it.isTactique)
|
||||||
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static find(condition) {
|
static find(condition) {
|
||||||
return conditionsTactiques.find(e => e.type == condition) || conditionsTactiques.find(e => e.type == 'pret');
|
return conditionsTactiques.find(e => e.key == condition) || conditionsTactiques[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -32,48 +36,78 @@ export class RdDBonus {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static dmg(rollData, actor, isEntiteIncarnee = false) {
|
static dmg(rollData, actor, isEntiteIncarnee = false) {
|
||||||
const dmgArme = RdDBonus.dmgArme(rollData.arme)
|
const diff = rollData.diffLibre;
|
||||||
|
const dmgArme = RdDBonus.dmgArme(rollData.arme, rollData.arme?.system.dommagesReels)
|
||||||
|
const forceRequise = rollData.arme ? RdDItemArme.valeurMain(rollData.arme.system.force ?? 0, RdDItemArme.getMainAttaque(rollData.competence)) : 0
|
||||||
let dmg = {
|
let dmg = {
|
||||||
total: 0,
|
total: 0,
|
||||||
dmgArme: dmgArme,
|
dmgArme: dmgArme,
|
||||||
|
diff: diff,
|
||||||
|
dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(diff ?? 0) : 0,
|
||||||
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._calculMortalite(rollData, isEntiteIncarnee),
|
||||||
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)
|
||||||
}
|
}
|
||||||
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
|
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante
|
||||||
return dmg;
|
return dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static dmgRollV2(rollData, attaque) {
|
||||||
|
const actor = rollData.active.actor
|
||||||
|
const arme = attaque.arme
|
||||||
|
const dmgArme = RdDBonus.dmgArme(arme, attaque.dommagesArme)
|
||||||
|
const dmg = {
|
||||||
|
total: 0,
|
||||||
|
dmgArme: dmgArme,
|
||||||
|
penetration: arme?.penetration() ?? 0,
|
||||||
|
diff: attaque.diff,
|
||||||
|
dmgTactique: attaque.tactique?.dmg ?? 0,
|
||||||
|
dmgParticuliere: RdDBonus._dmgParticuliere(rollData),
|
||||||
|
dmgSurprise: rollData.opponent?.surprise?.dmg ?? 0,
|
||||||
|
mortalite: RdDBonus.mortalite(attaque.dmg?.mortalite, arme?.system.mortalite, rollData.opponent?.actor?.isEntite()),
|
||||||
|
dmgActor: RdDBonus.bonusDmg(actor, attaque.carac.key, dmgArme, attaque.forceRequise),
|
||||||
|
dmgForceInsuffisante: Math.min(0, actor.getForce() - attaque.forceRequise),
|
||||||
|
dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0
|
||||||
|
}
|
||||||
|
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante + dmg.dmgDiffLibre
|
||||||
|
return dmg
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static description(condition) {
|
static description(condition) {
|
||||||
return RdDBonus.find(condition).descr;
|
return RdDBonus.find(condition).label
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static dmgBonus(condition) {
|
static dmgBonus(condition) {
|
||||||
return RdDBonus.find(condition).dmg;
|
return RdDBonus.find(condition).dmg
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static bonusAttaque(condition) {
|
static bonusAttaque(condition) {
|
||||||
return RdDBonus.find(condition).attaque;
|
return RdDBonus.find(condition).attaque
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _calculMortalite(rollData, isEntiteIncarnee) {
|
static _calculMortalite(rollData, isEntiteIncarnee) {
|
||||||
|
return RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite, isEntiteIncarnee)
|
||||||
|
}
|
||||||
|
|
||||||
|
static mortalite(mortaliteSelect, mortaliteArme, isEntiteIncarnee) {
|
||||||
return isEntiteIncarnee ? "entiteincarnee"
|
return isEntiteIncarnee ? "entiteincarnee"
|
||||||
: rollData.dmg?.mortalite
|
: mortaliteSelect
|
||||||
?? rollData.arme?.system.mortalite
|
?? mortaliteArme
|
||||||
?? "mortel";
|
?? "mortel";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static dmgArme(arme) {
|
static dmgArme(arme, dommagesMain) {
|
||||||
if (arme) {
|
if (arme) {
|
||||||
let dmgBase = arme.system.dommagesReels ?? Number(arme.system.dommages ?? 0);
|
let dmgBase = dommagesMain ?? Number(arme.system.dommages ?? 0);
|
||||||
//Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278)
|
//Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278)
|
||||||
return dmgBase + Math.min(dmgBase, arme.system.magique ? arme.system.ecaille_efficacite : 0);
|
return dmgBase + Math.min(dmgBase, arme.system.magique ? arme.system.ecaille_efficacite : 0);
|
||||||
}
|
}
|
||||||
@@ -87,13 +121,13 @@ export class RdDBonus {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static bonusDmg(actor, categorie, dmgArme) {
|
static bonusDmg(actor, categorie, dmgArme) {
|
||||||
const dmgActor = actor.getBonusDegat()
|
|
||||||
if (categorie == undefined) {
|
if (categorie == undefined) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
const dmgActor = actor.getBonusDegat()
|
||||||
switch (categorie) {
|
switch (categorie) {
|
||||||
case "tir": return 0;
|
case "(tir)": case "tir": return 0
|
||||||
case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
|
case "(lancer)": case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
|
||||||
}
|
}
|
||||||
return dmgActor;
|
return dmgActor;
|
||||||
}
|
}
|
||||||
|
@@ -52,6 +52,15 @@ export const CARACS = {
|
|||||||
EMPATHIE: 'empathie',
|
EMPATHIE: 'empathie',
|
||||||
REVE: 'reve',
|
REVE: 'reve',
|
||||||
CHANCE: 'chance',
|
CHANCE: 'chance',
|
||||||
|
PROTECTION: 'protection',
|
||||||
|
BEAUTE: 'beaute',
|
||||||
|
PERCEPTION: 'perception',
|
||||||
|
MELEE: 'melee',
|
||||||
|
TIR: 'tir',
|
||||||
|
LANCER: 'lancer',
|
||||||
|
DEROBEE: 'derobee',
|
||||||
|
CHANCE_ACTUELLE: 'chance-actuelle',
|
||||||
|
REVE_ACTUEL: 'reve-actuel',
|
||||||
}
|
}
|
||||||
export const LIST_CARAC_PERSONNAGE = {
|
export const LIST_CARAC_PERSONNAGE = {
|
||||||
[CARACS.TAILLE]: { code: CARACS.TAILLE, label: 'Taille', isCarac: true, path: 'system.carac.taille.value' },
|
[CARACS.TAILLE]: { code: CARACS.TAILLE, label: 'Taille', isCarac: true, path: 'system.carac.taille.value' },
|
||||||
@@ -68,21 +77,21 @@ export const LIST_CARAC_PERSONNAGE = {
|
|||||||
[CARACS.EMPATHIE]: { code: CARACS.EMPATHIE, label: 'Empathie', isCarac: true, path: 'system.carac.empathie.value' },
|
[CARACS.EMPATHIE]: { code: CARACS.EMPATHIE, label: 'Empathie', isCarac: true, path: 'system.carac.empathie.value' },
|
||||||
[CARACS.REVE]: { code: CARACS.REVE, label: 'Rêve', isCarac: true, path: 'system.carac.reve.value' },
|
[CARACS.REVE]: { code: CARACS.REVE, label: 'Rêve', isCarac: true, path: 'system.carac.reve.value' },
|
||||||
[CARACS.CHANCE]: { code: CARACS.CHANCE, label: 'Chance', isCarac: true, path: 'system.carac.chance.value' },
|
[CARACS.CHANCE]: { code: CARACS.CHANCE, label: 'Chance', isCarac: true, path: 'system.carac.chance.value' },
|
||||||
'protection': { code: 'protection', label: 'Protection naturelle', isCarac: false, path: 'system.attributs.protection.value' },
|
[CARACS.PROTECTION]: { code: CARACS.PROTECTION, label: 'Protection naturelle', isCarac: false, path: 'system.attributs.protection.value' },
|
||||||
'beaute': { code: 'beaute', label: 'Beauté', isCarac: false, path: 'system.background.beaute.value' }
|
[CARACS.BEAUTE]: { code: CARACS.BEAUTE, label: 'Beauté', isCarac: false, path: 'system.background.beaute.value' }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LIST_CARAC_AUTRES = {
|
export const LIST_CARAC_AUTRES = {
|
||||||
'perception': { code: 'perception', label: 'Perception', path: 'system.carac.perception.value' },
|
[CARACS.PERCEPTION]: { code: 'perception', label: 'Perception', path: 'system.carac.perception.value' },
|
||||||
}
|
}
|
||||||
|
|
||||||
const LIST_CARAC_DERIVEE = {
|
const LIST_CARAC_DERIVEE = {
|
||||||
'melee': { code: "melee", label: 'Mêlée', path: 'system.carac.melee.value' },
|
[CARACS.MELEE]: { code: CARACS.MELEE, label: 'Mêlée', path: 'system.carac.melee.value' },
|
||||||
'tir': { code: "tir", label: 'Tir', path: 'system.carac.tir.value' },
|
[CARACS.TIR]: { code: CARACS.TIR, label: 'Tir', path: 'system.carac.tir.value' },
|
||||||
'lancer': { code: "lancer", label: 'Lancer', path: 'system.carac.lancer.value' },
|
[CARACS.LANCER]: { code: CARACS.LANCER, label: 'Lancer', path: 'system.carac.lancer.value' },
|
||||||
'derobee': { code: "derobee", label: 'Dérobée', path: 'system.carac.derobee.value' },
|
[CARACS.DEROBEE]: { code: CARACS.DEROBEE, label: 'Dérobée', path: 'system.carac.derobee.value' },
|
||||||
'chance-actuelle': { code: "chance-actuelle", label: 'Chance actuelle', path: 'system.carac.lancer.value' },
|
[CARACS.CHANCE_ACTUELLE]: { code: CARACS.CHANCE_ACTUELLE, label: 'Chance actuelle', path: 'system.carac.lancer.value' },
|
||||||
'reve-actuel': { code: "reve-actuel", label: 'Rêve actuel', path: 'system.reve.reve.value' },
|
[CARACS.REVE_ACTUEL]: { code: CARACS.REVE_ACTUEL, label: 'Rêve actuel', path: 'system.reve.reve.value' },
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LIST_CARAC_ROLL = Object.values(LIST_CARAC_PERSONNAGE).filter(it => it.isCarac && it.code != 'taille')
|
export const LIST_CARAC_ROLL = Object.values(LIST_CARAC_PERSONNAGE).filter(it => it.isCarac && it.code != 'taille')
|
||||||
@@ -125,11 +134,11 @@ export class RdDCarac {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isIntellect(caracLabel) {
|
static isIntellect(caracLabel) {
|
||||||
return Grammar.toLowerCaseNoAccent(caracLabel) == 'intellect';
|
return Grammar.toLowerCaseNoAccent(caracLabel) == CARACS.INTELLECT
|
||||||
}
|
}
|
||||||
|
|
||||||
static isVolonte(caracLabel) {
|
static isVolonte(caracLabel) {
|
||||||
return Grammar.toLowerCaseNoAccent(caracLabel) == 'volonte';
|
return Grammar.toLowerCaseNoAccent(caracLabel) == CARACS.VOLONTE
|
||||||
}
|
}
|
||||||
static isChance(caracLabel) {
|
static isChance(caracLabel) {
|
||||||
return Grammar.toLowerCaseNoAccent(caracLabel)?.match(/chance(( |-)?actuelle)?/);
|
return Grammar.toLowerCaseNoAccent(caracLabel)?.match(/chance(( |-)?actuelle)?/);
|
||||||
|
@@ -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 { ENTITE_BLURETTE, 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";
|
||||||
@@ -7,14 +7,19 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
|||||||
import { RdDRoll } from "./rdd-roll.js";
|
import { RdDRoll } from "./rdd-roll.js";
|
||||||
import { RdDRollTables } from "./rdd-rolltables.js";
|
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||||
import { STATUSES } from "./settings/status-effects.js";
|
|
||||||
import { Targets } from "./targets.js";
|
import { Targets } from "./targets.js";
|
||||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||||
import { RdDItemArme } from "./item/arme.js";
|
import { EMPOIGNADE, RdDItemArme } from "./item/arme.js";
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
import { MAP_PHASE, RdDInitiative } from "./initiative.mjs";
|
||||||
import { RdDInitiative } from "./initiative.mjs";
|
import RollDialog from "./roll/roll-dialog.mjs";
|
||||||
|
import { PART_DEFENSE } from "./roll/roll-part-defense.mjs";
|
||||||
|
import { RollDialogAdapter } from "./roll/roll-dialog-adapter.mjs";
|
||||||
|
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs";
|
||||||
|
import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js";
|
||||||
|
import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs";
|
||||||
|
import { RollBasicParts } from "./roll/roll-basic-parts.mjs";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const premierRoundInit = [
|
const premierRoundInit = [
|
||||||
@@ -63,7 +68,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()
|
||||||
}
|
}
|
||||||
@@ -102,14 +107,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
|
||||||
@@ -117,18 +126,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");
|
||||||
@@ -140,10 +148,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();
|
||||||
}
|
}
|
||||||
@@ -155,16 +163,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)`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -176,7 +179,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))
|
||||||
@@ -196,10 +198,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,
|
||||||
|
}])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -216,56 +235,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)
|
||||||
@@ -293,13 +298,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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -368,7 +368,7 @@ export class RdDCombat {
|
|||||||
if (Misc.isOwnerPlayer(defender)) {
|
if (Misc.isOwnerPlayer(defender)) {
|
||||||
let attackerRoll = msg.attackerRoll;
|
let attackerRoll = msg.attackerRoll;
|
||||||
let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined;
|
let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined;
|
||||||
defender.encaisserDommages(attackerRoll, attacker, msg.attackerToken);
|
defender.encaisserDommages(attackerRoll.dmg, attacker, msg.attackerToken);
|
||||||
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(attackerRoll.passeArme);
|
rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||||
}
|
}
|
||||||
@@ -379,8 +379,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.ids) {/* TODO: delete roll V1 */
|
||||||
|
RollDialog.loadRollData(msg.paramChatDefense)
|
||||||
|
rddCombat?._chatMessageDefenseV2(msg.paramChatDefense)
|
||||||
|
} else {
|
||||||
|
rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,15 +403,19 @@ export class RdDCombat {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static registerChatCallbacks(html) {
|
static registerChatCallbacks(html) {
|
||||||
for (let button of [
|
for (let button of [
|
||||||
'.parer-button',
|
'.button-defense',
|
||||||
'.esquiver-button',
|
'.button-parade',
|
||||||
|
'.button-esquive',
|
||||||
|
'.button-encaisser',
|
||||||
'.particuliere-attaque',
|
'.particuliere-attaque',
|
||||||
'.encaisser-button',
|
|
||||||
'.appel-chance-defense',
|
'.appel-chance-defense',
|
||||||
'.appel-destinee-defense',
|
'.appel-destinee-defense',
|
||||||
'.appel-chance-attaque',
|
'.appel-chance-attaque',
|
||||||
'.appel-destinee-attaque',
|
'.appel-destinee-attaque',
|
||||||
'.echec-total-attaque',
|
'.echec-total-attaque',
|
||||||
|
// '.appel-chance',
|
||||||
|
// '.chat-encaissement',
|
||||||
|
// '.resister-recul',
|
||||||
]) {
|
]) {
|
||||||
$(html).on("click", button, event => {
|
$(html).on("click", button, event => {
|
||||||
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(
|
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(
|
||||||
@@ -456,8 +465,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;
|
||||||
@@ -466,9 +475,11 @@ 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 '.parer-button': return this.parade(attackerRoll, armeParadeId);
|
case '.button-defense': return this.defenseV2(attackerRoll);
|
||||||
case '.esquiver-button': return this.esquive(attackerRoll, compId, competence);
|
|
||||||
case '.encaisser-button': return this.encaisser(attackerRoll, defenderRoll);
|
case '.button-parade': return this.parade(attackerRoll, armeParadeId);
|
||||||
|
case '.button-esquive': return this.esquive(attackerRoll, compId, competence);
|
||||||
|
case '.button-encaisser': return this.encaisser(attackerRoll, defenderRoll);
|
||||||
case '.echec-total-attaque': return this._onEchecTotal(attackerRoll);
|
case '.echec-total-attaque': return this._onEchecTotal(attackerRoll);
|
||||||
|
|
||||||
case '.appel-chance-attaque': return this.attacker.rollAppelChance(
|
case '.appel-chance-attaque': return this.attacker.rollAppelChance(
|
||||||
@@ -478,11 +489,9 @@ export class RdDCombat {
|
|||||||
() => this.defenseChanceuse(attackerRoll, defenderRoll),
|
() => this.defenseChanceuse(attackerRoll, defenderRoll),
|
||||||
() => this.afficherOptionsDefense(attackerRoll, defenderRoll, { defenseChance: true }));
|
() => this.afficherOptionsDefense(attackerRoll, defenderRoll, { defenseChance: true }));
|
||||||
case '.appel-destinee-attaque': return this.attacker.appelDestinee(
|
case '.appel-destinee-attaque': return this.attacker.appelDestinee(
|
||||||
() => this.attaqueSignificative(attackerRoll),
|
() => this.attaqueSignificative(attackerRoll));
|
||||||
() => { });
|
|
||||||
case '.appel-destinee-defense': return this.defender.appelDestinee(
|
case '.appel-destinee-defense': return this.defender.appelDestinee(
|
||||||
() => this.defenseDestinee(defenderRoll),
|
() => this.defenseDestinee(defenderRoll));
|
||||||
() => { });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,27 +561,42 @@ export class RdDCombat {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isEchecTotal(rollData) {
|
static isEchecTotal(rollData) {
|
||||||
if (!rollData.attackerRoll && rollData.ajustements.surprise.used) {
|
if (rollData.ids /* roll V2*/) {
|
||||||
return rollData.rolled.isEchec && rollData.rolled.code != 'notSign';
|
// 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
|
||||||
|
return rollData.rolled.isETotal
|
||||||
}
|
}
|
||||||
return rollData.rolled.isETotal;
|
if (rollData.mode == ROLL_TYPE_ATTAQUE && rollData.surprise == 'demi') {
|
||||||
|
// échec normal à l'attaque en demi surprise
|
||||||
|
return rollData.rolled.isEchec && rollData.rolled.code != 'notSign'
|
||||||
|
}
|
||||||
|
return rollData.rolled.isETotal
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isParticuliere(rollData) {
|
static isParticuliere(rollData) {
|
||||||
if (!rollData.attackerRoll && rollData.ajustements.surprise.used) {
|
if (rollData.ids /* roll V2*/) {
|
||||||
return false;
|
return rollData.rolled.isPart
|
||||||
}
|
}
|
||||||
return rollData.rolled.isPart;
|
if (rollData.attackerRoll || !rollData.ajustements.surprise.used) {
|
||||||
|
return rollData.rolled.isPart
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static isReussite(rollData) {
|
static isReussite(rollData) {
|
||||||
switch (rollData.ajustements.surprise.used) {
|
if (rollData.ids /* roll V2*/) {
|
||||||
case 'totale': return false;
|
return rollData.rolled.isSuccess
|
||||||
case 'demi': return rollData.rolled.isSign;
|
|
||||||
}
|
}
|
||||||
return rollData.rolled.isSuccess;
|
if (!rollData.ajustements.surprise.used) {
|
||||||
|
return rollData.rolled.isSuccess
|
||||||
|
}
|
||||||
|
switch (rollData.ajustements.surprise.used) {
|
||||||
|
case 'totale': return false
|
||||||
|
case 'demi': return rollData.rolled.isSign
|
||||||
|
}
|
||||||
|
return rollData.rolled.isSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -642,12 +666,101 @@ 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: (dialog) => {
|
||||||
|
if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
|
||||||
|
dialog.close()
|
||||||
|
},
|
||||||
|
customChatMessage: true,
|
||||||
|
callbacks: [
|
||||||
|
async (roll) => await this.onAttaqueV2(roll),
|
||||||
|
...callbacks
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async onAttaqueV2(attackerRoll) {
|
||||||
|
if (!this.defender || !attackerRoll.rolled.isSuccess || attackerRoll.particulieres?.length > 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!await this.attacker.accorder(this.defender, 'avant-defense')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RollDialog.loadRollData(attackerRoll)
|
||||||
|
|
||||||
|
const surpriseDefender = this.defender.getSurprise(true);
|
||||||
|
const paramChatDefense = {
|
||||||
|
attackerRoll: attackerRoll,
|
||||||
|
isPossession: this.isPossession(attackerRoll),
|
||||||
|
defender: this.defender,
|
||||||
|
attacker: this.attacker,
|
||||||
|
attackerId: this.attackerId,
|
||||||
|
attackerToken: this.attackerToken,
|
||||||
|
defenderToken: this.defenderToken,
|
||||||
|
surprise: surpriseDefender,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Misc.isFirstConnectedGM()) {
|
||||||
|
await this._chatMessageDefenseV2(paramChatDefense);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._socketSendMessageDefense(paramChatDefense, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async _chatMessageDefenseV2(paramDemandeDefense) {
|
||||||
|
const attackerRoll = paramDemandeDefense.attackerRoll;
|
||||||
|
RollBasicParts.loadSurprises(attackerRoll)
|
||||||
|
attackerRoll.passeArme = attackerRoll.passeArme ?? foundry.utils.randomID(16)
|
||||||
|
attackerRoll.dmg = RdDBonus.dmgRollV2(attackerRoll, attackerRoll.current.attaque)
|
||||||
|
// attackerRoll.current.attaque.dmg = attackerRoll.dmg
|
||||||
|
// attaque.dmg = attackerRoll.current.attaque.dmg
|
||||||
|
const attaque = RollDialog.saveParts(attackerRoll)
|
||||||
|
const defense = {
|
||||||
|
attackerRoll: attaque,
|
||||||
|
ids: RollBasicParts.reverseIds(attaque),
|
||||||
|
passeArme: attaque.passeArme ?? foundry.utils.randomID(16)
|
||||||
|
}
|
||||||
|
|
||||||
|
const choixDefense = await ChatMessage.create({
|
||||||
|
// message privé: du défenseur à lui même (et aux GMs)
|
||||||
|
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
|
||||||
|
alias: this.attacker?.getAlias(),
|
||||||
|
whisper: ChatUtility.getOwners(this.defender),
|
||||||
|
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', attackerRoll)
|
||||||
|
});
|
||||||
|
// flag pour garder les jets d'attaque/defense
|
||||||
|
ChatUtility.setMessageData(choixDefense, 'rollData', defense)
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async attaque(competence, arme) {
|
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
|
||||||
}
|
}
|
||||||
@@ -679,6 +792,7 @@ export class RdDCombat {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_prepareAttaque(competence, arme) {
|
_prepareAttaque(competence, arme) {
|
||||||
let rollData = {
|
let rollData = {
|
||||||
|
mode: ROLL_TYPE_ATTAQUE,
|
||||||
alias: this.attacker?.getAlias(),
|
alias: this.attacker?.getAlias(),
|
||||||
passeArme: foundry.utils.randomID(16),
|
passeArme: foundry.utils.randomID(16),
|
||||||
mortalite: arme?.system.mortalite,
|
mortalite: arme?.system.mortalite,
|
||||||
@@ -691,7 +805,7 @@ export class RdDCombat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (this.attacker.isCreatureEntite()) {
|
if (this.attacker.isCreatureEntite()) {
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
MappingCreatureArme.setRollDataCreature(rollData);
|
||||||
}
|
}
|
||||||
else if (arme) {
|
else if (arme) {
|
||||||
// Usual competence
|
// Usual competence
|
||||||
@@ -699,9 +813,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;
|
||||||
}
|
}
|
||||||
@@ -713,9 +827,6 @@ export class RdDCombat {
|
|||||||
if (RdDCombat.isReussite(attackerRoll)) {
|
if (RdDCombat.isReussite(attackerRoll)) {
|
||||||
return await this._onAttaqueNormale(attackerRoll)
|
return await this._onAttaqueNormale(attackerRoll)
|
||||||
}
|
}
|
||||||
// if (RdDCombat.isParticuliere(attackerRoll) && attackerRoll.particuliere == undefined) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
if (RdDCombat.isEchecTotal(attackerRoll)) {
|
if (RdDCombat.isEchecTotal(attackerRoll)) {
|
||||||
return await this._onAttaqueEchecTotal(attackerRoll)
|
return await this._onAttaqueEchecTotal(attackerRoll)
|
||||||
}
|
}
|
||||||
@@ -755,7 +866,7 @@ export class RdDCombat {
|
|||||||
passeArme: rollData.passeArme
|
passeArme: rollData.passeArme
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
ChatUtility.setMessageData(choixParticuliere, 'attacker-roll', rollData);
|
ChatUtility.setMessageData(choixParticuliere, 'rollData', rollData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -786,8 +897,6 @@ export class RdDCombat {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async _sendMessageDefense(attackerRoll, defenderRoll, essaisPrecedents = undefined) {
|
async _sendMessageDefense(attackerRoll, defenderRoll, essaisPrecedents = undefined) {
|
||||||
console.log("RdDCombat._sendMessageDefense", attackerRoll, defenderRoll, essaisPrecedents, " / ", this.attacker, this.target, this.attackerId, attackerRoll.competence.system.categorie);
|
|
||||||
|
|
||||||
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||||
if (essaisPrecedents) {
|
if (essaisPrecedents) {
|
||||||
foundry.utils.mergeObject(attackerRoll.essais, essaisPrecedents, { overwrite: true });
|
foundry.utils.mergeObject(attackerRoll.essais, essaisPrecedents, { overwrite: true });
|
||||||
@@ -833,10 +942,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -850,14 +959,14 @@ export class RdDCombat {
|
|||||||
defenderToken: this.defenderToken,
|
defenderToken: this.defenderToken,
|
||||||
defenderRoll: defenderRoll,
|
defenderRoll: defenderRoll,
|
||||||
paramChatDefense: paramChatDefense,
|
paramChatDefense: paramChatDefense,
|
||||||
rollMode: true
|
rollMode: true,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_filterArmesParade(defender, competence, armeAttaque) {
|
_filterArmesParade(defender, competence, armeAttaque) {
|
||||||
let defenses = defender.items.filter(it => RdDItemArme.isParade(it))
|
let defenses = defender.items.filter(it => it.isParade())
|
||||||
defenses = foundry.utils.duplicate(defenses)
|
defenses = foundry.utils.duplicate(defenses)
|
||||||
defenses.forEach(armeDefense => {
|
defenses.forEach(armeDefense => {
|
||||||
// Ajout du # d'utilisation ce round
|
// Ajout du # d'utilisation ce round
|
||||||
@@ -879,6 +988,7 @@ export class RdDCombat {
|
|||||||
const choixEchecTotal = await ChatMessage.create({
|
const choixEchecTotal = await ChatMessage.create({
|
||||||
whisper: ChatUtility.getOwners(this.attacker),
|
whisper: ChatUtility.getOwners(this.attacker),
|
||||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.hbs', {
|
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.hbs', {
|
||||||
|
rolled: attackerRoll.rolled,
|
||||||
attackerId: this.attackerId,
|
attackerId: this.attackerId,
|
||||||
attacker: this.attacker,
|
attacker: this.attacker,
|
||||||
attackerToken: this.attackerToken,
|
attackerToken: this.attackerToken,
|
||||||
@@ -886,7 +996,7 @@ export class RdDCombat {
|
|||||||
essais: attackerRoll.essais
|
essais: attackerRoll.essais
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
ChatUtility.setMessageData(choixEchecTotal, 'attacker-roll', attackerRoll);
|
ChatUtility.setMessageData(choixEchecTotal, 'rollData', attackerRoll);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -946,9 +1056,44 @@ export class RdDCombat {
|
|||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async defenseV2(attackerRoll) {
|
||||||
|
// this._prepareParade(attackerRoll, arme, competence);
|
||||||
|
RollDialog.loadRollData(attackerRoll)
|
||||||
|
await this.doRollDefense({
|
||||||
|
ids: {
|
||||||
|
actorId: this.defender.id,
|
||||||
|
actorTokenId: this.defenderTokenId,
|
||||||
|
opponentTokenId: this.attackerTokenId,
|
||||||
|
opponentId: this.attackerId,
|
||||||
|
},
|
||||||
|
type: { allowed: [ROLL_TYPE_DEFENSE], current: ROLL_TYPE_DEFENSE },
|
||||||
|
attackerRoll: RollDialogAdapter.mapActionAttaque(attackerRoll),
|
||||||
|
passeArme: attackerRoll.passeArme,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async doRollDefense(rollData, callbacks = []) {
|
||||||
|
await RollDialog.create(rollData, {
|
||||||
|
onRollDone: RollDialog.onRollDoneClose,
|
||||||
|
customChatMessage: true,
|
||||||
|
callbacks: [
|
||||||
|
async (roll) => {
|
||||||
|
this.removeChatMessageActionsPasseArme(roll.passeArme);
|
||||||
|
// defense: esquive / arme de parade / competence de défense
|
||||||
|
if (!RdDCombat.isParticuliere(roll)) {
|
||||||
|
await roll.active.actor.incDecItemUse(roll.current[PART_DEFENSE].defense?.id);
|
||||||
|
}
|
||||||
|
await this._onDefense(roll);
|
||||||
|
},
|
||||||
|
...callbacks
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_prepareParade(attackerRoll, armeParade, competenceParade) {
|
_prepareParade(attackerRoll, armeParade, competenceParade) {
|
||||||
let defenderRoll = {
|
let defenderRoll = {
|
||||||
|
mode: ROLL_TYPE_DEFENSE,
|
||||||
alias: this.defender?.getAlias(),
|
alias: this.defender?.getAlias(),
|
||||||
passeArme: attackerRoll.passeArme,
|
passeArme: attackerRoll.passeArme,
|
||||||
diffLibre: attackerRoll.diffLibre,
|
diffLibre: attackerRoll.diffLibre,
|
||||||
@@ -965,12 +1110,47 @@ export class RdDCombat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (this.defender.isCreatureEntite()) {
|
if (this.defender.isCreatureEntite()) {
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(defenderRoll);
|
MappingCreatureArme.setRollDataCreature(defenderRoll);
|
||||||
}
|
}
|
||||||
|
|
||||||
return defenderRoll;
|
return defenderRoll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _onDefense(rollData) {
|
||||||
|
const isEsquive = rollData.current[PART_DEFENSE].isEsquive
|
||||||
|
const isParade = !isEsquive
|
||||||
|
if (RdDCombat.isReussite(rollData)) {
|
||||||
|
if (isParade) {
|
||||||
|
await this.computeDeteriorationArme(rollData)
|
||||||
|
if (RdDCombat.isParticuliere(rollData)) {
|
||||||
|
await this.infoAttaquantDesarme(rollData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
this.removeChatMessageActionsPasseArme(rollData.passeArme)
|
||||||
|
}
|
||||||
|
|
||||||
|
async infoAttaquantDesarme(rollData) {
|
||||||
|
if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) {
|
||||||
|
// TODO: attaquant doit jouer résistance et peut être désarmé p132
|
||||||
|
ChatUtility.createChatWithRollMode(
|
||||||
|
{ content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` },
|
||||||
|
this.defender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onDefenseNormale(rollData) {
|
||||||
|
console.log("RdDCombat._onDefenseNormale >>>", rollData);
|
||||||
|
await this.computeRecul(rollData);
|
||||||
|
await this.computeDeteriorationArme(rollData);
|
||||||
|
await RdDRollResult.displayRollData(rollData, this.defender, 'chat-resultat-parade.hbs');
|
||||||
|
this.removeChatMessageActionsPasseArme(rollData.passeArme);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async _onParade(defenderRoll) {
|
async _onParade(defenderRoll) {
|
||||||
if (RdDCombat.isReussite(defenderRoll)) {
|
if (RdDCombat.isReussite(defenderRoll)) {
|
||||||
@@ -1042,6 +1222,7 @@ export class RdDCombat {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
_prepareEsquive(attackerRoll, competence) {
|
_prepareEsquive(attackerRoll, competence) {
|
||||||
let rollData = {
|
let rollData = {
|
||||||
|
mode: ROLL_TYPE_DEFENSE,
|
||||||
alias: this.defender.getAlias(),
|
alias: this.defender.getAlias(),
|
||||||
passeArme: attackerRoll.passeArme,
|
passeArme: attackerRoll.passeArme,
|
||||||
diffLibre: attackerRoll.diffLibre,
|
diffLibre: attackerRoll.diffLibre,
|
||||||
@@ -1056,7 +1237,7 @@ export class RdDCombat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (this.defender.isCreatureEntite()) {
|
if (this.defender.isCreatureEntite()) {
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
MappingCreatureArme.setRollDataCreature(rollData);
|
||||||
}
|
}
|
||||||
return rollData;
|
return rollData;
|
||||||
}
|
}
|
||||||
@@ -1105,7 +1286,7 @@ export class RdDCombat {
|
|||||||
// Est-ce une parade normale?
|
// Est-ce une parade normale?
|
||||||
if (defenderRoll.arme && attackerRoll && !defenderRoll.rolled.isPart) {
|
if (defenderRoll.arme && attackerRoll && !defenderRoll.rolled.isPart) {
|
||||||
// Est-ce que l'attaque est une particulière en force ou une charge
|
// Est-ce que l'attaque est une particulière en force ou une charge
|
||||||
if (defenderRoll.needResist || this._isForceOuCharge(attackerRoll)) {
|
if (defenderRoll.needResist || this._isForceOuCharge(attackerRoll, defenderRoll.v2)) {
|
||||||
|
|
||||||
defenderRoll.show = defenderRoll.show || {}
|
defenderRoll.show = defenderRoll.show || {}
|
||||||
|
|
||||||
@@ -1153,7 +1334,7 @@ export class RdDCombat {
|
|||||||
finalLevel: Misc.toInt(defenderRoll.competence.system.niveau) - dmg,
|
finalLevel: Misc.toInt(defenderRoll.competence.system.niveau) - dmg,
|
||||||
showDice: HIDE_DICE
|
showDice: HIDE_DICE
|
||||||
});
|
});
|
||||||
defenderRoll.show.desarme = desarme.rolled.isEchec;
|
defenderRoll.show.desarme = desarme.rolled.isEchec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1161,41 +1342,19 @@ export class RdDCombat {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async computeRecul(defenderRoll) { // Calcul du recul (p. 132)
|
async computeRecul(defenderRoll) { // Calcul du recul (p. 132)
|
||||||
|
if (!ReglesOptionnelles.isUsing('recul')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const attackerRoll = defenderRoll.attackerRoll;
|
const attackerRoll = defenderRoll.attackerRoll;
|
||||||
if (ReglesOptionnelles.isUsing('recul') && this._isForceOuCharge(attackerRoll)) {
|
if (this._isForceOuCharge(attackerRoll, defenderRoll.v2)) {
|
||||||
const impact = this._computeImpactRecul(attackerRoll);
|
defenderRoll.show.recul = this.defender.encaisserRecul(this.attacker.getForce(), attackerRoll.dmg.dmgArme)
|
||||||
const rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impact });
|
|
||||||
if (rollRecul.rolled.isSuccess) {
|
|
||||||
defenderRoll.show.recul = 'encaisse';
|
|
||||||
} else if (rollRecul.rolled.isETotal || this._isReculCauseChute(impact)) {
|
|
||||||
defenderRoll.show.recul = 'chute';
|
|
||||||
await this.defender.setEffect(STATUSES.StatusProne, true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
defenderRoll.show.recul = 'recul';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
_isForceOuCharge(attaque, isRollV2 = false /* TODO: delete roll V1 */) {
|
||||||
async _isReculCauseChute(impact) {
|
return attaque.particuliere == 'force' || 'charge' == (isRollV2 ? attaque.tactique?.key : attaque.tactique)
|
||||||
const agilite = this.defender.getAgilite();
|
|
||||||
const chute = await RdDResolutionTable.rollData({ caracValue: agilite, finalLevel: impact });
|
|
||||||
return chute.rolled.isEchec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_isForceOuCharge(attaque) {
|
|
||||||
return attaque.particuliere == 'force' || attaque.tactique == 'charge';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_computeImpactRecul(attaque) {
|
|
||||||
const taille = this.defender.getTaille();
|
|
||||||
const force = this.attacker.getForce();
|
|
||||||
const dommages = attaque.arme.system.dommagesReels ?? attaque.arme.system.dommages;
|
|
||||||
return taille - (force + dommages);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async encaisser(attackerRoll, defenderRoll) {
|
async encaisser(attackerRoll, defenderRoll) {
|
||||||
@@ -1205,12 +1364,16 @@ export class RdDCombat {
|
|||||||
this._onEchecTotal(defenderRoll);
|
this._onEchecTotal(defenderRoll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.doRollEncaissement(attackerRoll, defenderRoll);
|
||||||
|
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||||
|
}
|
||||||
|
|
||||||
|
async doRollEncaissement(attackerRoll, defenderRoll) {
|
||||||
if (Misc.isOwnerPlayer(this.defender)) {
|
if (Misc.isOwnerPlayer(this.defender)) {
|
||||||
attackerRoll.attackerId = this.attackerId;
|
attackerRoll.attackerId = this.attackerId;
|
||||||
attackerRoll.defenderTokenId = this.defenderToken.id;
|
attackerRoll.defenderTokenId = this.defenderToken.id;
|
||||||
|
|
||||||
await this.computeRecul(defenderRoll);
|
await this.computeRecul(defenderRoll);
|
||||||
await this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show, this.attackerToken, this.defenderToken);
|
await this.defender.encaisserDommages(attackerRoll.dmg, this.attacker, defenderRoll?.show, this.attackerToken, this.defenderToken);
|
||||||
}
|
}
|
||||||
else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas
|
else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas
|
||||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||||
@@ -1221,9 +1384,8 @@ export class RdDCombat {
|
|||||||
attackerToken: this.attackerToken,
|
attackerToken: this.attackerToken,
|
||||||
defenderToken: this.defenderToken
|
defenderToken: this.defenderToken
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -1255,4 +1417,5 @@ export class RdDCombat {
|
|||||||
alias: alias
|
alias: alias
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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)?/;
|
||||||
|
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
/* -------------------------------------------- */
|
|
||||||
import { RdDRoll } from "./rdd-roll.js";
|
|
||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
|
||||||
import { ChatUtility } from "./chat-utility.js";
|
|
||||||
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 { RdDRollResult } from "./rdd-roll-result.js";
|
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||||
|
import { RdDRoll } from "./rdd-roll.js";
|
||||||
|
import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDEmpoignade {
|
export class RdDEmpoignade {
|
||||||
@@ -186,7 +185,7 @@ export class RdDEmpoignade {
|
|||||||
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
|
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
|
||||||
}
|
}
|
||||||
if (attacker.isCreatureEntite()) {
|
if (attacker.isCreatureEntite()) {
|
||||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
MappingCreatureArme.setRollDataCreature(rollData)
|
||||||
}
|
}
|
||||||
if (empoignade.system.pointsemp >= 2) {
|
if (empoignade.system.pointsemp >= 2) {
|
||||||
if (!empoignade.system.ausol) {
|
if (!empoignade.system.ausol) {
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import { RdDItemArme } from "./item/arme.js";
|
import { ATTAQUE_TYPE, EMPOIGNADE, PUGILAT, RdDItemArme } from "./item/arme.js";
|
||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
|
||||||
import { ITEM_TYPES } from "./constants.js";
|
import { ITEM_TYPES } from "./constants.js";
|
||||||
|
|
||||||
export class RdDHotbar {
|
export class RdDHotbar {
|
||||||
@@ -20,14 +19,17 @@ export class RdDHotbar {
|
|||||||
await game.user.assignHotbarMacro(macro, slot);
|
await game.user.assignHotbarMacro(macro, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
static $macroNameSuffix(armeCompetence) {
|
static $macroNameSuffix(maniement) {
|
||||||
switch (armeCompetence) {
|
switch (maniement) {
|
||||||
case '(1 main)': return ' (1 main)';
|
case ATTAQUE_TYPE.UNE_MAIN:
|
||||||
case '(2 mains)': return ' (2 main)';
|
case ATTAQUE_TYPE.DEUX_MAINS:
|
||||||
|
case ATTAQUE_TYPE.LANCER:
|
||||||
|
case ATTAQUE_TYPE.TIR:
|
||||||
|
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 ''
|
||||||
}
|
}
|
||||||
@@ -39,30 +41,30 @@ export class RdDHotbar {
|
|||||||
// Les armes peuvent avoir plusieurs usages
|
// Les armes peuvent avoir plusieurs usages
|
||||||
if (item.system.competence != '') {
|
if (item.system.competence != '') {
|
||||||
if (item.system.unemain) {
|
if (item.system.unemain) {
|
||||||
await this.createItemMacro(item, slot++, '(1 main)')
|
await this.createItemMacro(item, slot++, ATTAQUE_TYPE.UNE_MAIN)
|
||||||
}
|
}
|
||||||
if (item.system.deuxmains) {
|
if (item.system.deuxmains) {
|
||||||
await this.createItemMacro(item, slot++, '(2 mains)')
|
await this.createItemMacro(item, slot++, ATTAQUE_TYPE.DEUX_MAINS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item.system.lancer != '') {
|
if (item.system.lancer != '') {
|
||||||
await this.createItemMacro(item, slot++, 'lancer')
|
await this.createItemMacro(item, slot++, ATTAQUE_TYPE.LANCER)
|
||||||
}
|
}
|
||||||
if (item.system.tir != '') {
|
if (item.system.tir != '') {
|
||||||
await this.createItemMacro(item, slot++, 'lancer')
|
await this.createItemMacro(item, slot++, ATTAQUE_TYPE.TIR)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
case ITEM_TYPES.competencecreature:
|
case ITEM_TYPES.competencecreature:
|
||||||
const categorie = RdDItemCompetenceCreature.getCategorieAttaque(item) ?? 'competence';
|
const categorie = item.getCategorieAttaque() ?? 'competence';
|
||||||
await this.createItemMacro(item, slot, categorie)
|
await this.createItemMacro(item, slot, categorie)
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
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>
|
||||||
@@ -119,15 +121,15 @@ 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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return actor.rollCompetence(item);
|
return actor.rollCompetence(item);
|
||||||
case ITEM_TYPES.competencecreature:
|
case ITEM_TYPES.competencecreature:
|
||||||
return item.system.iscombat && !item.system.isparade
|
return item.system.iscombat
|
||||||
? actor.rollArme(item, categorieArme)
|
? actor.rollArme(item, categorieArme)
|
||||||
: actor.rollCompetence(item);
|
: actor.rollCompetence(item);
|
||||||
|
|
||||||
|
@@ -45,6 +45,8 @@ import * as sheets from "./applications/sheets/_module.mjs"
|
|||||||
import { RdDItemArme } from "./item/arme.js"
|
import { RdDItemArme } from "./item/arme.js"
|
||||||
import { RdDItemArmure } from "./item/armure.js"
|
import { RdDItemArmure } from "./item/armure.js"
|
||||||
import { RdDItemBlessure } from "./item/blessure.js"
|
import { RdDItemBlessure } from "./item/blessure.js"
|
||||||
|
import { RdDItemCompetence } from "./item-competence.js"
|
||||||
|
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
|
||||||
import { RdDItemGemme } from "./item/gemme.js"
|
import { RdDItemGemme } from "./item/gemme.js"
|
||||||
import { RdDItemMaladie } from "./item/maladie.js"
|
import { RdDItemMaladie } from "./item/maladie.js"
|
||||||
import { RdDItemOmbre } from "./item/ombre.js"
|
import { RdDItemOmbre } from "./item/ombre.js"
|
||||||
@@ -86,6 +88,7 @@ import { RdDCombatManager, RdDCombat } from "./rdd-combat.js"
|
|||||||
import { Migrations } from './migrations.js'
|
import { Migrations } from './migrations.js'
|
||||||
|
|
||||||
import RollDialog from "./roll/roll-dialog.mjs"
|
import RollDialog from "./roll/roll-dialog.mjs"
|
||||||
|
import ChatRollResult from "./roll/chat-roll-result.mjs"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RdD system
|
* RdD system
|
||||||
@@ -112,6 +115,8 @@ export class SystemReveDeDragon {
|
|||||||
arme: RdDItemArme,
|
arme: RdDItemArme,
|
||||||
armure: RdDItemArmure,
|
armure: RdDItemArmure,
|
||||||
blessure: RdDItemBlessure,
|
blessure: RdDItemBlessure,
|
||||||
|
competence: RdDItemCompetence,
|
||||||
|
competencecreature: RdDItemCompetenceCreature,
|
||||||
gemme: RdDItemGemme,
|
gemme: RdDItemGemme,
|
||||||
maladie: RdDItemMaladie,
|
maladie: RdDItemMaladie,
|
||||||
ombre: RdDItemOmbre,
|
ombre: RdDItemOmbre,
|
||||||
@@ -292,6 +297,7 @@ export class SystemReveDeDragon {
|
|||||||
TMRRencontres.init()
|
TMRRencontres.init()
|
||||||
ExportScriptarium.init()
|
ExportScriptarium.init()
|
||||||
RollDialog.init()
|
RollDialog.init()
|
||||||
|
ChatRollResult.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
initSettings() {
|
initSettings() {
|
||||||
@@ -346,18 +352,7 @@ export class SystemReveDeDragon {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static async setupAccueil() {
|
|
||||||
let exists = game.scenes.find(j => j.name == "Accueil RdD");
|
|
||||||
if (!exists) {
|
|
||||||
const scenes = await SystemCompendiums.loadCompendium("foundryvtt-reve-de-dragon.scenes-rdd")
|
|
||||||
let newDocuments = scenes.filter(i => i.name == "Accueil RdD");
|
|
||||||
await game.scenes.documentClass.create(newDocuments);
|
|
||||||
game.scenes.find(i => i.name == "Accueil RdD").activate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async onReady() {
|
async onReady() {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* Foundry VTT Initialization */
|
/* Foundry VTT Initialization */
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -376,7 +371,8 @@ export class SystemReveDeDragon {
|
|||||||
StatusEffects.onReady()
|
StatusEffects.onReady()
|
||||||
RdDDice.onReady()
|
RdDDice.onReady()
|
||||||
RollDialog.onReady()
|
RollDialog.onReady()
|
||||||
RdDStatBlockParser.parseStatBlock()
|
ChatRollResult.onReady()
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* Affiche/Init le calendrier */
|
/* Affiche/Init le calendrier */
|
||||||
game.system.rdd.calendrier.display()
|
game.system.rdd.calendrier.display()
|
||||||
@@ -389,7 +385,17 @@ export class SystemReveDeDragon {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemReveDeDragon.setupAccueil()
|
this.setupAccueil()
|
||||||
|
}
|
||||||
|
|
||||||
|
async setupAccueil() {
|
||||||
|
let exists = game.scenes.find(j => j.name == "Accueil RdD");
|
||||||
|
if (!exists) {
|
||||||
|
const scenes = await SystemCompendiums.loadCompendium("foundryvtt-reve-de-dragon.scenes-rdd")
|
||||||
|
let newDocuments = scenes.filter(i => i.name == "Accueil RdD");
|
||||||
|
await game.scenes.documentClass.create(newDocuments);
|
||||||
|
game.scenes.find(i => i.name == "Accueil RdD").activate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@@ -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";
|
||||||
|
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
import { RdDRoll } from "./rdd-roll.js";
|
import { RdDRoll } from "./rdd-roll.js";
|
||||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
|
||||||
import { Targets } from "./targets.js";
|
import { Targets } from "./targets.js";
|
||||||
import { ITEM_TYPES } from "./constants.js";
|
import { ITEM_TYPES } from "./constants.js";
|
||||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||||
import { Grammar } from "./grammar.js";
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* On part du principe qu'une entité démarre tjs
|
/* On part du principe qu'une entité démarre tjs
|
||||||
|
@@ -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";
|
||||||
@@ -66,9 +67,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),
|
||||||
@@ -157,7 +158,7 @@ export class RdDResolutionTable {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static significativeRequise(chances) {
|
static significativeRequise(chances) {
|
||||||
chances.roll = Math.floor(chances.score / 2);
|
chances.roll = Math.min(chances.part + 1, chances.sign)
|
||||||
foundry.utils.mergeObject(chances, reussites.find(x => x.code == 'sign'), { overwrite: true });
|
foundry.utils.mergeObject(chances, reussites.find(x => x.code == 'sign'), { overwrite: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,47 +185,15 @@ export class RdDResolutionTable {
|
|||||||
return Math.max(Math.floor(carac * (diff + 10) / 2), 1);
|
return Math.max(Math.floor(carac * (diff + 10) / 2), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static isEchec(rollData) {
|
|
||||||
switch (rollData.surprise) {
|
|
||||||
case 'demi': return !rollData.rolled.isSign;
|
|
||||||
case 'totale': return true;
|
|
||||||
}
|
|
||||||
return rollData.rolled.isEchec;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static isEchecTotal(rollData) {
|
|
||||||
if (rollData.arme && rollData.surprise == 'demi') {
|
|
||||||
return rollData.rolled.isEchec;
|
|
||||||
}
|
|
||||||
return rollData.rolled.isETotal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static isParticuliere(rollData) {
|
|
||||||
if (rollData.arme && rollData.surprise) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return rollData.rolled.isPart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static isReussite(rollData) {
|
|
||||||
switch (rollData.surprise) {
|
|
||||||
case 'demi': return rollData.rolled.isSign;
|
|
||||||
case 'totale': return false;
|
|
||||||
}
|
|
||||||
return rollData.rolled.isSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
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.code == 'norm') {
|
if (diviseur > 1 && reussite.isSuccess) {
|
||||||
return reussiteInsuffisante;
|
if (chances.norm < roll * diviseur) {
|
||||||
|
return reussiteInsuffisante
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return reussite;
|
return reussite
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -268,7 +237,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_BLURETTE, ENTITE_INCARNE, renderTemplate } from "./constants.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,12 +66,11 @@ export class RdDEncaisser extends Dialog {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
performEncaisser(mortalite) {
|
performEncaisser(mortalite) {
|
||||||
this.actor.encaisserDommages({
|
this.actor.encaisserDommages({
|
||||||
dmg: {
|
total: Number(this.modifier),
|
||||||
total: Number(this.modifier),
|
ajustement: Number(this.modifier),
|
||||||
ajustement: Number(this.modifier),
|
encaisserSpecial: this.encaisserSpecial,
|
||||||
encaisserSpecial: this.encaisserSpecial,
|
mortalite: mortalite,
|
||||||
mortalite: mortalite
|
penetration: 0
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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';
|
||||||
/**
|
/**
|
||||||
@@ -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,7 +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, renderTemplate } from "./constants.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
|
||||||
@@ -22,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) {
|
||||||
@@ -333,10 +334,8 @@ 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 == 'non-mortel');
|
||||||
this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == 'empoignade' ? 'empoignade' : Misc.toSignedString(rollData.dmg.total));
|
this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == EMPOIGNADE ? EMPOIGNADE : Misc.toSignedString(rollData.dmg.total));
|
||||||
this.html.find("label.arme-mortalite").text(rollData.dmg.mortalite);
|
this.html.find("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)
|
||||||
}
|
}
|
||||||
@@ -344,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() });
|
||||||
}
|
}
|
||||||
@@ -508,7 +508,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();
|
||||||
|
@@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -11,7 +11,6 @@ import { RdDItem } from "./item.js";
|
|||||||
import { RdDPossession } from "./rdd-possession.js";
|
import { RdDPossession } from "./rdd-possession.js";
|
||||||
import { RdDNameGen } from "./rdd-namegen.js";
|
import { RdDNameGen } from "./rdd-namegen.js";
|
||||||
import { RdDConfirm } from "./rdd-confirm.js";
|
import { RdDConfirm } from "./rdd-confirm.js";
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
|
||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||||
import { RdDRaretes } from "./item/raretes.js";
|
import { RdDRaretes } from "./item/raretes.js";
|
||||||
@@ -19,10 +18,12 @@ import { RdDEmpoignade } from "./rdd-empoignade.js";
|
|||||||
import { ExperienceLog } from "./actor/experience-log.js";
|
import { ExperienceLog } from "./actor/experience-log.js";
|
||||||
import { RdDCoeur } from "./coeur/rdd-coeur.js";
|
import { RdDCoeur } from "./coeur/rdd-coeur.js";
|
||||||
import { APP_ASTROLOGIE_REFRESH } from "./sommeil/app-astrologie.js";
|
import { APP_ASTROLOGIE_REFRESH } from "./sommeil/app-astrologie.js";
|
||||||
import { ITEM_TYPES, RDD_CONFIG } from "./constants.js";
|
import { ITEM_TYPES, RDD_CONFIG, SYSTEM_RDD } from "./constants.js";
|
||||||
import { RdDBaseActor } from "./actor/base-actor.js";
|
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||||
import { RdDCarac } from "./rdd-carac.js";
|
import { RdDCarac } from "./rdd-carac.js";
|
||||||
import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js";
|
import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js";
|
||||||
|
|
||||||
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { Monnaie } from "./item-monnaie.js";
|
import { Monnaie } from "./item-monnaie.js";
|
||||||
import { ItemAction } from "./item/item-actions.js";
|
import { ItemAction } from "./item/item-actions.js";
|
||||||
|
|
||||||
@@ -271,12 +272,13 @@ export class RdDUtility {
|
|||||||
|
|
||||||
// foundry et options
|
// foundry et options
|
||||||
Handlebars.registerHelper('RDD_CONFIG', path => RDD_CONFIG[path])
|
Handlebars.registerHelper('RDD_CONFIG', path => RDD_CONFIG[path])
|
||||||
|
Handlebars.registerHelper('settings-get', (setting) => game.settings.get(SYSTEM_RDD, setting))
|
||||||
Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
|
Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
|
||||||
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionnelles.isUsing(option));
|
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionnelles.isUsing(option));
|
||||||
|
|
||||||
Handlebars.registerHelper('plusMoins', diff => parseInt(diff) ? (diff > 0 ? '+' : '') + Math.round(diff) : diff)
|
Handlebars.registerHelper('plusMoins', diff => parseInt(diff) ? (diff > 0 ? '+' : '') + Math.round(diff) : diff)
|
||||||
Handlebars.registerHelper('fractionOneN', n => new Handlebars.SafeString(Misc.getFractionOneN(n)))
|
Handlebars.registerHelper('fractionOneN', n => new Handlebars.SafeString(Misc.getFractionOneN(n)))
|
||||||
|
|
||||||
// Handle v12 removal of this helper
|
// Handle v12 removal of this helper
|
||||||
Handlebars.registerHelper('select', function (selected, options) {
|
Handlebars.registerHelper('select', function (selected, options) {
|
||||||
const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected));
|
const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected));
|
||||||
@@ -284,7 +286,7 @@ export class RdDUtility {
|
|||||||
const html = options.fn(this);
|
const html = options.fn(this);
|
||||||
return html.replace(rgx, "$& selected");
|
return html.replace(rgx, "$& selected");
|
||||||
})
|
})
|
||||||
|
|
||||||
// logic
|
// logic
|
||||||
Handlebars.registerHelper('either', (a, b) => a ?? b);
|
Handlebars.registerHelper('either', (a, b) => a ?? b);
|
||||||
// string manipulation
|
// string manipulation
|
||||||
@@ -297,8 +299,10 @@ export class RdDUtility {
|
|||||||
Handlebars.registerHelper('grammar-un', str => Grammar.articleIndetermine(str));
|
Handlebars.registerHelper('grammar-un', str => Grammar.articleIndetermine(str));
|
||||||
Handlebars.registerHelper('grammar-accord', (genre, ...args) => Grammar.accord(genre, args));
|
Handlebars.registerHelper('grammar-accord', (genre, ...args) => Grammar.accord(genre, args));
|
||||||
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 = '';
|
||||||
@@ -344,7 +348,7 @@ export class RdDUtility {
|
|||||||
Handlebars.registerHelper('rarete-getChamp', (rarete, field) => RdDRaretes.getChamp(rarete, field));
|
Handlebars.registerHelper('rarete-getChamp', (rarete, field) => RdDRaretes.getChamp(rarete, field));
|
||||||
Handlebars.registerHelper('item-action-applies', (action, item, options) => ItemAction.applies(action, item, options))
|
Handlebars.registerHelper('item-action-applies', (action, item, options) => ItemAction.applies(action, item, options))
|
||||||
Handlebars.registerHelper('item-action-icon', (action, item) => ItemAction.icon(action, item))
|
Handlebars.registerHelper('item-action-icon', (action, item) => ItemAction.icon(action, item))
|
||||||
Handlebars.registerHelper('item-name', (item) => item.nameDisplay)
|
Handlebars.registerHelper('item-name', (item) => item.nameDisplay)
|
||||||
|
|
||||||
// TMRs
|
// TMRs
|
||||||
Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
|
Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
|
||||||
@@ -609,35 +613,33 @@ export class RdDUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async getLocalisation(type = 'personnage') {
|
static async getLocalisation(type = 'personnage') {
|
||||||
let result = await RdDDice.rollTotal("1d20");
|
const loc = { result: await RdDDice.rollTotal("1d20")};
|
||||||
let txt = ""
|
|
||||||
if (type == 'personnage') {
|
if (type == 'personnage') {
|
||||||
if (result <= 3) txt = "Jambe, genou, pied, jarret";
|
if (loc.result <= 3) loc.txt = "Jambe, genou, pied, jarret";
|
||||||
else if (result <= 7) txt = "Hanche, cuisse, fesse";
|
else if (loc.result <= 7) loc.txt = "Hanche, cuisse, fesse";
|
||||||
else if (result <= 9) txt = "Ventre, reins";
|
else if (loc.result <= 9) loc.txt = "Ventre, reins";
|
||||||
else if (result <= 12) txt = "Poitrine, dos";
|
else if (loc.result <= 12) loc.txt = "Poitrine, dos";
|
||||||
else if (result <= 14) txt = "Avant-bras, main, coude";
|
else if (loc.result <= 14) loc.txt = "Avant-bras, main, coude";
|
||||||
else if (result <= 18) txt = "Epaule, bras, omoplate";
|
else if (loc.result <= 18) loc.txt = "Epaule, bras, omoplate";
|
||||||
else if (result == 19) txt = "Tête";
|
else if (loc.result == 19) loc.txt = "Tête";
|
||||||
else if (result == 20) txt = "Tête (visage)";
|
else if (loc.result == 20) loc.txt = "Tête (visage)";
|
||||||
} else {
|
} else {
|
||||||
if (result <= 7) txt = "Jambes/Pattes";
|
if (loc.result <= 7) loc.txt = "Jambes/Pattes";
|
||||||
else if (result <= 18) txt = "Corps";
|
else if (loc.result <= 18) loc.txt = "Corps";
|
||||||
else if (result <= 20) txt = "Tête";
|
else if (loc.result <= 20) loc.txt = "Tête";
|
||||||
}
|
}
|
||||||
|
return loc
|
||||||
return { result: result, label: txt };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async jetEncaissement(actor, rollData, armure, options = { showDice: HIDE_DICE }) {
|
static async jetEncaissement(actor, dmg, armure, options = { showDice: HIDE_DICE }) {
|
||||||
const diff = Math.abs(rollData.diffLibre);
|
const diff = Math.abs(dmg.diff)
|
||||||
let formula = RdDUtility.formuleEncaissement(diff, options)
|
const formula = RdDUtility.formuleEncaissement(diff, options)
|
||||||
const roll = await RdDDice.roll(formula, options);
|
const roll = await RdDDice.roll(formula, options);
|
||||||
|
|
||||||
RdDUtility.remplaceDeMinParDifficulte(roll, diff, options);
|
RdDUtility.remplaceDeMinParDifficulte(roll, diff, options);
|
||||||
|
|
||||||
return await RdDUtility.prepareEncaissement(actor, rollData, roll, armure);
|
return await RdDUtility.prepareEncaissement(actor, dmg, roll, armure);
|
||||||
}
|
}
|
||||||
|
|
||||||
static remplaceDeMinParDifficulte(roll, diff, options) {
|
static remplaceDeMinParDifficulte(roll, diff, options) {
|
||||||
@@ -660,7 +662,7 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static formuleEncaissement(diff, options) {
|
static formuleEncaissement(diff) {
|
||||||
// Chaque dé fait au minimum la difficulté libre
|
// Chaque dé fait au minimum la difficulté libre
|
||||||
if (ReglesOptionnelles.isUsing('degat-minimum-malus-libre')) {
|
if (ReglesOptionnelles.isUsing('degat-minimum-malus-libre')) {
|
||||||
return `2d10min${diff}`
|
return `2d10min${diff}`
|
||||||
@@ -669,25 +671,22 @@ export class RdDUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async prepareEncaissement(actor, rollData, roll, armure) {
|
static async prepareEncaissement(actor, dmg, roll, armure) {
|
||||||
// La difficulté d'ataque s'ajoute aux dégâts
|
const jetTotal = roll.total + dmg.total - armure
|
||||||
const bonusDegatsDiffLibre = ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(rollData.diffLibre ?? 0) : 0
|
const encaissement = RdDUtility._selectEncaissement(jetTotal, dmg.mortalite);
|
||||||
const jetTotal = roll.total + rollData.dmg.total - armure + bonusDegatsDiffLibre
|
|
||||||
const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite);
|
|
||||||
const over20 = Math.max(jetTotal - 20, 0);
|
const over20 = Math.max(jetTotal - 20, 0);
|
||||||
encaissement.dmg = rollData.dmg
|
encaissement.dmg = dmg
|
||||||
if (ReglesOptionnelles.isUsing('localisation-aleatoire')) {
|
if (ReglesOptionnelles.isUsing('localisation-aleatoire')) {
|
||||||
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(actor.type)
|
encaissement.dmg.loc = dmg.loc ?? await RdDUtility.getLocalisation(actor.type)
|
||||||
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'
|
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
encaissement.dmg.loc = { label: '' }
|
encaissement.dmg.loc = { label: '' }
|
||||||
}
|
}
|
||||||
encaissement.dmg.bonusDegatsDiffLibre = bonusDegatsDiffLibre
|
encaissement.roll = roll
|
||||||
encaissement.roll = roll;
|
encaissement.armure = armure
|
||||||
encaissement.armure = armure;
|
encaissement.penetration = dmg.penetration
|
||||||
encaissement.penetration = rollData.arme?.system.penetration ?? 0;
|
encaissement.total = jetTotal
|
||||||
encaissement.total = jetTotal;
|
|
||||||
encaissement.vie = await RdDUtility._evaluatePerte(encaissement.vie, over20);
|
encaissement.vie = await RdDUtility._evaluatePerte(encaissement.vie, over20);
|
||||||
encaissement.endurance = await RdDUtility._evaluatePerte(encaissement.endurance, over20);
|
encaissement.endurance = await RdDUtility._evaluatePerte(encaissement.endurance, over20);
|
||||||
return encaissement;
|
return encaissement;
|
||||||
|
212
module/roll/chat-roll-result.mjs
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
import { ChatUtility } from "../chat-utility.js"
|
||||||
|
import RollDialog from "./roll-dialog.mjs"
|
||||||
|
import { RdDCarac } from "../rdd-carac.js"
|
||||||
|
import { RdDCombat } from "../rdd-combat.js"
|
||||||
|
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
|
||||||
|
import { RdDResolutionTable } from "../rdd-resolution-table.js"
|
||||||
|
import { RDD_CONFIG, renderTemplate } from "../constants.js"
|
||||||
|
import { EMPOIGNADE } from "../item/arme.js"
|
||||||
|
|
||||||
|
export default class ChatRollResult {
|
||||||
|
static init() {
|
||||||
|
ChatRollResult.instance = new ChatRollResult()
|
||||||
|
|
||||||
|
Hooks.on('renderChatLog', (log, html, chatLog) => ChatRollResult.instance.chatListeners(html))
|
||||||
|
}
|
||||||
|
|
||||||
|
static onReady() {
|
||||||
|
foundry.applications.handlebars.loadTemplates({
|
||||||
|
'partial-appel-chance': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-appel-chance.hbs',
|
||||||
|
'partial-attaque-particuliere': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-attaque-particuliere.hbs',
|
||||||
|
'partial-encaissement': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-encaissement.hbs',
|
||||||
|
'partial-recul-choc': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-recul-choc.hbs',
|
||||||
|
'partial-info-appel-moral': 'systems/foundryvtt-reve-de-dragon/templates/roll/result/partial-info-appel-moral.hbs',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async display(roll) {
|
||||||
|
this.prepareDisplay(roll)
|
||||||
|
|
||||||
|
const chatMessage = await ChatUtility.createChatWithRollMode(
|
||||||
|
{
|
||||||
|
content: await this.buildRollHtml(roll)
|
||||||
|
},
|
||||||
|
roll.active.actor,
|
||||||
|
roll.current?.rollmode?.key
|
||||||
|
)
|
||||||
|
const save = RollDialog.saveParts(roll)
|
||||||
|
ChatUtility.setMessageData(chatMessage, 'rollData', save)
|
||||||
|
return chatMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareDisplay(roll) {
|
||||||
|
roll.done = roll.done ?? {}
|
||||||
|
roll.show = roll.show ?? {}
|
||||||
|
roll.show.chance = this.isAppelChancePossible(roll)
|
||||||
|
roll.show.encaissement = this.isShowEncaissement(roll)
|
||||||
|
roll.show.recul = this.getRecul(roll)
|
||||||
|
//roll.show.particuliere = roll.show.particuliere ?? []
|
||||||
|
}
|
||||||
|
|
||||||
|
isAppelChancePossible(roll) {
|
||||||
|
return roll.active.actor.isPersonnage() &&
|
||||||
|
roll.rolled.isEchec &&
|
||||||
|
RdDCarac.isActionPhysique(roll.current.carac?.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
isShowEncaissement(roll) {
|
||||||
|
switch (roll.type.current) {
|
||||||
|
case ROLL_TYPE_DEFENSE:
|
||||||
|
return roll.rolled.isEchec && roll.attackerRoll?.dmg.mortalite != EMPOIGNADE
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getRecul(roll, defender = roll.active.actor, attacker = roll.opponent?.actor) {
|
||||||
|
switch (roll.type.current) {
|
||||||
|
case ROLL_TYPE_DEFENSE:
|
||||||
|
{
|
||||||
|
const attaque = roll.attackerRoll
|
||||||
|
if (attaque &&
|
||||||
|
(roll.rolled.isEchec || !roll.current.defense.isEsquive) &&
|
||||||
|
(attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key)) {
|
||||||
|
const taille = defender.system.carac.taille.value
|
||||||
|
const impact = attacker.system.carac.force.value + roll.attackerRoll?.dmg.dmgArme
|
||||||
|
return {
|
||||||
|
raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force',
|
||||||
|
taille: taille,
|
||||||
|
impact: impact,
|
||||||
|
chances: RdDResolutionTable.computeChances(10, taille - impact).norm,
|
||||||
|
diff: taille - impact
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ROLL_TYPE_ATTAQUE:
|
||||||
|
{
|
||||||
|
const attaque = roll
|
||||||
|
if (attaque.particuliere == 'force' || 'charge' == attaque.tactique?.key) {
|
||||||
|
return {
|
||||||
|
raison: 'charge' == attaque.tactique?.key ? 'charge' : 'particulière en force',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
async buildRollHtml(roll) {
|
||||||
|
const template = `systems/foundryvtt-reve-de-dragon/templates/roll/result/chat-${roll.type.current}.hbs`
|
||||||
|
return await renderTemplate(template, roll)
|
||||||
|
}
|
||||||
|
|
||||||
|
async chatListeners(html) {
|
||||||
|
$(html).on("click", '.appel-chance', event => this.onClickAppelChance(event))
|
||||||
|
$(html).on("click", '.appel-destinee', event => this.onClickAppelDestinee(event))
|
||||||
|
$(html).on("click", '.encaissement', event => this.onClickEncaissement(event))
|
||||||
|
$(html).on("click", '.resister-recul', event => this.onClickRecul(event))
|
||||||
|
$(html).on("click", '.choix-particuliere', event => this.onClickChoixParticuliere(event))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getCombat(roll) {
|
||||||
|
switch (roll.type.current) {
|
||||||
|
case ROLL_TYPE_DEFENSE:
|
||||||
|
return RdDCombat.rddCombatForAttackerAndDefender(roll.ids.opponentId, roll.ids.opponentTokenId, roll.ids.actorTokenId)
|
||||||
|
case ROLL_TYPE_ATTAQUE:
|
||||||
|
return RdDCombat.rddCombatForAttackerAndDefender(roll.ids.actorId, roll.ids.actorTokenId, roll.ids.opponentId)
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateChatMessage(chatMessage, savedRoll) {
|
||||||
|
ChatUtility.setMessageData(chatMessage, 'rollData', savedRoll)
|
||||||
|
const copy = foundry.utils.duplicate(savedRoll)
|
||||||
|
RollDialog.loadRollData(copy)
|
||||||
|
this.prepareDisplay(copy)
|
||||||
|
chatMessage.update({ content: await this.buildRollHtml(copy) })
|
||||||
|
chatMessage.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickAppelChance(event) {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event)
|
||||||
|
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
|
||||||
|
const actor = game.actors.get(savedRoll.ids.actorId)
|
||||||
|
actor.rollAppelChance(
|
||||||
|
() => this.onAppelChanceSuccess(savedRoll, chatMessage),
|
||||||
|
() => this.onAppelChanceEchec(savedRoll, chatMessage))
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
onAppelChanceSuccess(savedRoll, chatMessage) {
|
||||||
|
const reRoll = foundry.utils.duplicate(savedRoll)
|
||||||
|
reRoll.type.retry = true
|
||||||
|
const callbacks = [r => ChatUtility.removeChatMessageId(chatMessage.id)]
|
||||||
|
// TODO: annuler les effets
|
||||||
|
switch (reRoll.type.current) {
|
||||||
|
case ROLL_TYPE_DEFENSE:
|
||||||
|
this.getCombat(reRoll)?.doRollDefense(reRoll, callbacks)
|
||||||
|
break
|
||||||
|
case ROLL_TYPE_ATTAQUE:
|
||||||
|
// TODO
|
||||||
|
this.getCombat(reRoll)?.doRollAttaque(reRoll, callbacks)
|
||||||
|
break
|
||||||
|
default: {
|
||||||
|
RollDialog.create(reRoll, { callbacks: callbacks })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onAppelChanceEchec(savedRoll, chatMessage) {
|
||||||
|
savedRoll.type.retry = true
|
||||||
|
await this.updateChatMessage(chatMessage, savedRoll)
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickAppelDestinee(event) {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event)
|
||||||
|
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
|
||||||
|
const actor = game.actors.get(savedRoll.ids.actorId)
|
||||||
|
|
||||||
|
actor.appelDestinee(async () => {
|
||||||
|
const reRoll = foundry.utils.duplicate(savedRoll)
|
||||||
|
reRoll.type.retry = true
|
||||||
|
RdDResolutionTable.significativeRequise(reRoll.rolled)
|
||||||
|
await this.updateChatMessage(chatMessage, reRoll)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async onClickEncaissement(event) {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event)
|
||||||
|
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
|
||||||
|
const attaque = savedRoll.attackerRoll
|
||||||
|
const defender = game.actors.get(savedRoll.ids.actorId)
|
||||||
|
const attacker = game.actors.get(savedRoll.ids.opponentId)
|
||||||
|
const defenderToken = savedRoll.ids.actorTokenId ? canvas.tokens.get(savedRoll.ids.actorTokenId) : undefined
|
||||||
|
const attackerToken = savedRoll.ids.opponentTokenId ? canvas.tokens.get(savedRoll.ids.opponentTokenId) : undefined
|
||||||
|
await defender?.encaisserDommages(attaque.dmg, attacker, undefined, attackerToken, defenderToken)
|
||||||
|
|
||||||
|
savedRoll.done.encaissement = true
|
||||||
|
await this.updateChatMessage(chatMessage, savedRoll)
|
||||||
|
}
|
||||||
|
|
||||||
|
async onClickRecul(event) {
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event)
|
||||||
|
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
|
||||||
|
const defender = game.actors.get(savedRoll.ids.actorId)
|
||||||
|
const attacker = game.actors.get(savedRoll.ids.opponentId)
|
||||||
|
savedRoll.done.recul = await defender.encaisserRecul(attacker.getForce(), savedRoll.attackerRoll.dmg.dmgArme)
|
||||||
|
// const reculChoc = this.getReculChoc(savedRoll, defender, attacker)
|
||||||
|
await this.updateChatMessage(chatMessage, savedRoll)
|
||||||
|
}
|
||||||
|
|
||||||
|
async onClickChoixParticuliere(event) {
|
||||||
|
const choix = event.currentTarget.attributes['data-particuliere'].value
|
||||||
|
const chatMessage = ChatUtility.getChatMessage(event)
|
||||||
|
const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
|
||||||
|
savedRoll.particuliere = choix
|
||||||
|
savedRoll.particulieres = [RDD_CONFIG.particuliere[choix]]
|
||||||
|
await this.updateChatMessage(chatMessage, savedRoll)
|
||||||
|
await this.getCombat(savedRoll)?.onAttaqueV2(savedRoll, callbacks)
|
||||||
|
}
|
||||||
|
}
|
@@ -1,32 +1,68 @@
|
|||||||
import { ActorToken } from "../actor-token.mjs"
|
import { ActorToken } from "../actor-token.mjs"
|
||||||
|
import { StatusEffects } from "../settings/status-effects.js"
|
||||||
|
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
|
||||||
|
import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
|
||||||
|
import { PART_DEFENSE } from "./roll-part-defense.mjs"
|
||||||
|
|
||||||
|
|
||||||
export class RollBasicParts {
|
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.$getActor(rollData)
|
||||||
rollData.opponent = RollBasicParts.$getOpponent(rollData)
|
rollData.opponent = RollBasicParts.$getOpponent(rollData)
|
||||||
if (rollData.mode.opposed == undefined) {
|
if (rollData.type.opposed == undefined) {
|
||||||
rollData.mode.opposed = rollData.opponent != null
|
rollData.type.opposed = rollData.opponent != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initFrom(rollData) {
|
static loadSurprises(rollData, type = rollData.type.current) {
|
||||||
|
if (!rollData.type.passif) {
|
||||||
|
RollBasicParts.loadSurprise(rollData.active, RollBasicParts.getForceRequiseActiveActor(rollData, type))
|
||||||
|
RollBasicParts.loadSurprise(rollData.opponent, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static loadSurprise(who, forceRequise) {
|
||||||
|
if (who?.actor) {
|
||||||
|
foundry.utils.mergeObject(who,
|
||||||
|
StatusEffects.getActorEffetSurprise(who.actor, forceRequise),
|
||||||
|
{ overwrite: true, inPlace: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getForceRequiseActiveActor(rollData, type) {
|
||||||
|
switch (type) {
|
||||||
|
case ROLL_TYPE_ATTAQUE: return rollData.current[PART_ATTAQUE].forceRequise
|
||||||
|
case ROLL_TYPE_DEFENSE: return rollData.current[PART_DEFENSE].forceRequise
|
||||||
|
default: return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static initFrom(rollData) {
|
||||||
return {
|
return {
|
||||||
selected: {},
|
selected: {},
|
||||||
mode: {
|
type: rollData.type,
|
||||||
current: rollData.mode.current
|
|
||||||
},
|
|
||||||
ids: {
|
ids: {
|
||||||
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.mode.opposed ? rollData.opponent.id : undefined,
|
opponentId: rollData.type.opposed ? rollData.opponent.id : undefined,
|
||||||
opponentTokenId: rollData.mode.opposed ? rollData.opponent.tokenId : undefined,
|
opponentTokenId: rollData.type.opposed ? rollData.opponent.tokenId : undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static reverseIds(rollData) {
|
||||||
|
return {
|
||||||
|
sceneId: rollData.ids.sceneId,
|
||||||
|
actorId: rollData.ids.opponentId,
|
||||||
|
actorTokenId: rollData.ids.opponentTokenId,
|
||||||
|
opponentId: rollData.ids.actorId,
|
||||||
|
opponentTokenId: rollData.actorTokenId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static $getActor(rollData) {
|
static $getActor(rollData) {
|
||||||
if (rollData.ids.actorTokenId) {
|
if (rollData.ids.actorTokenId) {
|
||||||
return ActorToken.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId)
|
return ActorToken.fromTokenId(rollData.ids.actorTokenId, rollData.ids.sceneId)
|
||||||
|
@@ -1,14 +1,23 @@
|
|||||||
|
|
||||||
export const ROLL_MODE_ATTAQUE = 'attaque'
|
export const ROLL_TYPE_ATTAQUE = 'attaque'
|
||||||
export const ROLL_MODE_COMP = 'comp'
|
export const ROLL_TYPE_COMP = 'comp'
|
||||||
export const ROLL_MODE_DEFENSE = 'defense'
|
export const ROLL_TYPE_DEFENSE = 'defense'
|
||||||
export const ROLL_MODE_JEU = 'jeu'
|
export const ROLL_TYPE_JEU = 'jeu'
|
||||||
export const ROLL_MODE_MEDITATION = 'meditation'
|
export const ROLL_TYPE_MEDITATION = 'meditation'
|
||||||
export const ROLL_MODE_OEUVRE = 'oeuvre'
|
export const ROLL_TYPE_CUISINE = 'cuisine'
|
||||||
export const ROLL_MODE_SORT = 'sort'
|
export const ROLL_TYPE_OEUVRE = 'oeuvre'
|
||||||
export const ROLL_MODE_TACHE = 'tache'
|
export const ROLL_TYPE_SORT = 'sort'
|
||||||
|
export const ROLL_TYPE_TACHE = 'tache'
|
||||||
|
|
||||||
export const DIFF_MODE = {
|
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_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_CUISINE, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE]
|
||||||
|
export const ALL_ROLL_TYPES = [...DEFAULT_ROLL_TYPES, ...COMBAT_ROLL_TYPES, ...DEMIREVE_ROLL_TYPES]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const DIFF = {
|
||||||
LIBRE: 'libre',
|
LIBRE: 'libre',
|
||||||
ATTAQUE: 'attaque',
|
ATTAQUE: 'attaque',
|
||||||
IMPOSEE: 'imposee',
|
IMPOSEE: 'imposee',
|
||||||
@@ -17,12 +26,12 @@ export const DIFF_MODE = {
|
|||||||
AUCUN: 'aucun'
|
AUCUN: 'aucun'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DIFF_MODES = {
|
export const DIFFS = {
|
||||||
[DIFF_MODE.LIBRE]: { key: DIFF_MODE.LIBRE, label: "Difficulté libre", libre: true, visible: true, max: 0 },
|
[DIFF.LIBRE]: { key: DIFF.LIBRE, label: "Difficulté libre", libre: true, visible: true, max: 0 },
|
||||||
[DIFF_MODE.ATTAQUE]: { key: DIFF_MODE.ATTAQUE, label: "Difficulté d'attaque", libre: true, visible: true, max: 0 },
|
[DIFF.ATTAQUE]: { key: DIFF.ATTAQUE, label: "Difficulté d'attaque", libre: true, visible: true, max: 0 },
|
||||||
[DIFF_MODE.IMPOSEE]: { key: DIFF_MODE.IMPOSEE, label: "Diffficulté imposée", libre: false, visible: true, max: 0 },
|
[DIFF.IMPOSEE]: { key: DIFF.IMPOSEE, label: "Diffficulté imposée", libre: false, visible: true, max: 0 },
|
||||||
[DIFF_MODE.DEFENSE]: { key: DIFF_MODE.DEFENSE, label: "Diffficulté défense", libre: false, visible: true, max: 0 },
|
[DIFF.DEFENSE]: { key: DIFF.DEFENSE, label: "Diffficulté défense", libre: false, visible: true, max: 0 },
|
||||||
[DIFF_MODE.DEFAUT]: { key: DIFF_MODE.DEFAUT, label: "Difficulté", libre: true, visible: true, max: 5 },
|
[DIFF.DEFAUT]: { key: DIFF.DEFAUT, label: "Difficulté", libre: true, visible: true, max: 5 },
|
||||||
[DIFF_MODE.AUCUN]: { key: DIFF_MODE.AUCUN, label: "", libre: false, visible: false, max: 0 },
|
[DIFF.AUCUN]: { key: DIFF.AUCUN, label: "", libre: false, visible: false, max: 0 },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,37 +4,45 @@ import { PART_COMP } from "./roll-part-comp.mjs";
|
|||||||
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 { PART_OEUVRE } from "./roll-part-oeuvre.mjs";
|
import { PART_OEUVRE } from "./roll-part-oeuvre.mjs";
|
||||||
|
import { RdDItemArme } from "../item/arme.js";
|
||||||
|
import { RdDBonus } from "../rdd-bonus.js";
|
||||||
|
import { ITEM_TYPES, RDD_CONFIG } from "../constants.js";
|
||||||
|
import { CARACS } from "../rdd-carac.js";
|
||||||
|
import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs";
|
||||||
|
import { PART_ATTAQUE } from "./roll-part-attaque.mjs";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RollDialogAdapter {
|
export class RollDialogAdapter {
|
||||||
|
|
||||||
async rollDice(rollData, rollTitle) {
|
static async rollDice(rollData, rollTitle) {
|
||||||
const chances = this.computeChances({
|
const chances = RollDialogAdapter.computeChances({
|
||||||
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 this.rollChances(rollData, chances)
|
const rolled = await RollDialogAdapter.rollChances(rollData, chances)
|
||||||
this.adjustRollDataForV1(rollData, rolled, rollTitle)
|
RollDialogAdapter.setRollDataRolled(rollData, rolled, rollTitle)
|
||||||
|
RollDialogAdapter.adjustRollDataForV1(rollData)
|
||||||
|
RollDialogAdapter.adjustAttaqueParticuliere(rollData)
|
||||||
|
|
||||||
return rolled
|
return rolled
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
async rollChances(rollData, chances) {
|
static async rollChances(rollData, chances) {
|
||||||
const rolled = await RdDResolutionTable.rollChances(chances, rollData.current.sign, rollData.current.resultat)
|
const rolled = await RdDResolutionTable.rollChances(chances,
|
||||||
|
rollData.current.sign.diviseur,
|
||||||
|
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
|
||||||
@@ -42,13 +50,20 @@ export class RollDialogAdapter {
|
|||||||
return rolled
|
return rolled
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = {}
|
||||||
}
|
}
|
||||||
@@ -57,7 +72,7 @@ export class RollDialogAdapter {
|
|||||||
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.mode.jetResistance
|
rollData.jetResistance = rollData.type.jetResistance
|
||||||
}
|
}
|
||||||
const oeuvreKey = rollData.current.oeuvre?.key
|
const oeuvreKey = rollData.current.oeuvre?.key
|
||||||
if (oeuvreKey) {
|
if (oeuvreKey) {
|
||||||
@@ -71,7 +86,6 @@ export class RollDialogAdapter {
|
|||||||
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 = this.findNiveauNecessaire(carac, rolled.roll)
|
||||||
rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
|
rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
|
||||||
@@ -84,7 +98,62 @@ export class RollDialogAdapter {
|
|||||||
descr: aj.diff == undefined ? aj.label : undefined
|
descr: aj.diff == undefined ? aj.label : undefined
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
rollData.show.title = rollTitle
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static adjustAttaqueParticuliere(rollData) {
|
||||||
|
if (rollData.type.current != ROLL_TYPE_ATTAQUE || !rollData.rolled.isPart) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const attaque = rollData.current.attaque;
|
||||||
|
const choix = []
|
||||||
|
const isEmpoignade = attaque.dmg.mortalite == 'empoignade';
|
||||||
|
const isCharge = attaque.tactique == 'charge'
|
||||||
|
/* TODO: cas de créatures faisant des lancers, Glou, Glipzouk */
|
||||||
|
const isMeleeDiffNegative = (attaque.comp.type == ITEM_TYPES.competencecreature || rollData.current.carac.key == CARACS.MELEE)
|
||||||
|
&& rollData.current.diff.value < 0
|
||||||
|
|
||||||
|
// force toujours, sauf empoignade
|
||||||
|
if (!isEmpoignade) {
|
||||||
|
choix.push(RDD_CONFIG.particuliere.force)
|
||||||
|
}
|
||||||
|
|
||||||
|
// finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
|
||||||
|
if (!isCharge && (isEmpoignade || isMeleeDiffNegative)) {
|
||||||
|
choix.push(RDD_CONFIG.particuliere.finesse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rapidité seulement en mêlée, si l'arme le permet, et si la difficulté libre est de -1 minimum
|
||||||
|
if (!isCharge && !isEmpoignade && isMeleeDiffNegative && attaque.arme.system.rapide) {
|
||||||
|
choix.push(RDD_CONFIG.particuliere.rapidite)
|
||||||
|
}
|
||||||
|
if (choix.length == 1) {
|
||||||
|
rollData.particuliere = choix[0].key
|
||||||
|
}
|
||||||
|
rollData.particulieres = choix
|
||||||
|
}
|
||||||
|
|
||||||
|
static mapActionAttaque(attackerRoll) {
|
||||||
|
if (attackerRoll.ids) {
|
||||||
|
return attackerRoll.current[PART_ATTAQUE]
|
||||||
|
}
|
||||||
|
const label = attackerRoll.alias + ' ' + attackerRoll.arme.name;
|
||||||
|
return {
|
||||||
|
// correspond à l'attaque de RollPartAttaque (dans rollDta.current.attaque)
|
||||||
|
label: label,
|
||||||
|
// correspond aux actions d'attaques dans RdDActor.listActionsAttaque
|
||||||
|
name: label,
|
||||||
|
// action: 'attaque',
|
||||||
|
arme: attackerRoll.arme,
|
||||||
|
comp: attackerRoll.competence,
|
||||||
|
main: RdDItemArme.getMainAttaque(attackerRoll.competence),
|
||||||
|
equipe: attackerRoll.arme.system.equipe,
|
||||||
|
// carac: { key: caracCode, value: caracValue },
|
||||||
|
// dommagesArme: dommagesArme,
|
||||||
|
diff: attackerRoll.diffLibre,
|
||||||
|
particuliere: attackerRoll.particuliere,
|
||||||
|
tactique: RdDBonus.find(attackerRoll.tactique),
|
||||||
|
dmg: attackerRoll.dmg,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +1,18 @@
|
|||||||
import { Misc } from "../misc.js";
|
import { Misc } from "../misc.js";
|
||||||
import { RollModeComp } from "./roll-mode-comp.mjs";
|
import { RollTypeComp } from "./roll-type-comp.mjs";
|
||||||
import { RollModeTache } from "./roll-mode-tache.mjs";
|
import { RollTypeTache } from "./roll-type-tache.mjs";
|
||||||
import { RollModeAttaque } from "./roll-mode-attaque.mjs";
|
import { RollTypeAttaque } from "./roll-type-attaque.mjs";
|
||||||
import { RollModeDefense } from "./roll-mode-defense.mjs";
|
import { RollTypeDefense } from "./roll-type-defense.mjs";
|
||||||
import { RollModeMeditation } from "./roll-mode-meditation.mjs";
|
import { RollTypeMeditation } from "./roll-type-meditation.mjs";
|
||||||
import { RollModeSort } from "./roll-mode-sort.mjs";
|
import { RollTypeSort } from "./roll-type-sort.mjs";
|
||||||
import { RollModeOeuvre } from "./roll-mode-oeuvre.mjs";
|
import { RollTypeOeuvre } from "./roll-type-oeuvre.mjs";
|
||||||
import { RollModeJeu } from "./roll-mode-jeu.mjs";
|
import { RollTypeJeu } from "./roll-type-jeu.mjs";
|
||||||
|
|
||||||
import { RollPartAction } from "./roll-part-action.mjs";
|
import { RollPartAction } from "./roll-part-action.mjs";
|
||||||
import { RollPartActor } from "./roll-part-actor.mjs";
|
import { RollPartActor } from "./roll-part-actor.mjs";
|
||||||
import { RollPartAppelMoral } from "./roll-part-appelmoral.mjs";
|
import { RollPartAppelMoral } from "./roll-part-appelmoral.mjs";
|
||||||
import { RollPartAstrologique } from "./roll-part-astrologique.mjs";
|
import { RollPartAstrologique } from "./roll-part-astrologique.mjs";
|
||||||
import { RollPartCarac } from "./roll-part-carac.mjs";
|
import { PART_CARAC, RollPartCarac } from "./roll-part-carac.mjs";
|
||||||
import { RollPartCoeur } from "./roll-part-coeur.mjs";
|
import { RollPartCoeur } from "./roll-part-coeur.mjs";
|
||||||
import { PART_COMP, RollPartComp } from "./roll-part-comp.mjs";
|
import { PART_COMP, RollPartComp } from "./roll-part-comp.mjs";
|
||||||
import { RollPartConditions } from "./roll-part-conditions.mjs";
|
import { RollPartConditions } from "./roll-part-conditions.mjs";
|
||||||
@@ -25,7 +25,7 @@ import { RollPartMeditation } from "./roll-part-meditation.mjs";
|
|||||||
import { RollPartMoral } from "./roll-part-moral.mjs";
|
import { RollPartMoral } from "./roll-part-moral.mjs";
|
||||||
import { RollPartOpponent } from "./roll-part-opponent.mjs";
|
import { RollPartOpponent } from "./roll-part-opponent.mjs";
|
||||||
import { RollPartSurEnc } from "./roll-part-surenc.mjs";
|
import { RollPartSurEnc } from "./roll-part-surenc.mjs";
|
||||||
import { RollPartTricher } from "./roll-part-tricher.mjs";
|
import { PART_TRICHER, RollPartTricher } from "./roll-part-tricher.mjs";
|
||||||
import { RollPartTache } from "./roll-part-tache.mjs";
|
import { RollPartTache } from "./roll-part-tache.mjs";
|
||||||
import { RollPartOeuvre } from "./roll-part-oeuvre.mjs";
|
import { RollPartOeuvre } from "./roll-part-oeuvre.mjs";
|
||||||
import { RollPartSort } from "./roll-part-sort.mjs";
|
import { RollPartSort } from "./roll-part-sort.mjs";
|
||||||
@@ -37,27 +37,30 @@ import { RollPartAttaque } from "./roll-part-attaque.mjs";
|
|||||||
import { RollPartDefense } from "./roll-part-defense.mjs";
|
import { RollPartDefense } from "./roll-part-defense.mjs";
|
||||||
import { RollDialogAdapter } from "./roll-dialog-adapter.mjs";
|
import { RollDialogAdapter } from "./roll-dialog-adapter.mjs";
|
||||||
import { ROLLDIALOG_SECTION } from "./roll-part.mjs";
|
import { ROLLDIALOG_SECTION } from "./roll-part.mjs";
|
||||||
import { ROLL_MODE_COMP } from "./roll-constants.mjs";
|
import { ROLL_TYPE_COMP } from "./roll-constants.mjs";
|
||||||
|
import ChatRollResult from "./chat-roll-result.mjs";
|
||||||
|
import { renderTemplate } from "../constants.js";
|
||||||
|
import { RollTypeCuisine } from "./roll-type-cuisine.mjs";
|
||||||
|
import { RollPartCuisine } from "./roll-part-cuisine.mjs";
|
||||||
|
import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js";
|
||||||
|
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
|
||||||
const doNothing = (dialog) => { }
|
|
||||||
|
|
||||||
const ROLL_MODE_TABS = [
|
const ALL_ROLL_TYPES = [
|
||||||
new RollModeComp(),
|
new RollTypeComp(),
|
||||||
new RollModeTache(),
|
new RollTypeTache(),
|
||||||
new RollModeAttaque(),
|
new RollTypeAttaque(),
|
||||||
new RollModeDefense(),
|
new RollTypeDefense(),
|
||||||
// new RollModeParade??
|
new RollTypeSort(),
|
||||||
// new RollModeEsquive??
|
new RollTypeMeditation(),
|
||||||
// new RollModeResistance ??
|
new RollTypeCuisine(),
|
||||||
new RollModeSort(),
|
new RollTypeOeuvre(),
|
||||||
new RollModeMeditation(),
|
new RollTypeJeu(),
|
||||||
new RollModeOeuvre(),
|
// new RollTypeResistance ??
|
||||||
new RollModeJeu(),
|
// new RollTypeFixedCarac ??
|
||||||
]
|
]
|
||||||
|
|
||||||
const BASIC_PARTS = new RollBasicParts()
|
|
||||||
|
|
||||||
const ROLL_PARTS = [
|
const ROLL_PARTS = [
|
||||||
new RollPartActor(),
|
new RollPartActor(),
|
||||||
new RollPartAction(),
|
new RollPartAction(),
|
||||||
@@ -71,6 +74,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(),
|
||||||
|
|
||||||
@@ -95,7 +99,7 @@ const ROLL_PARTS = [
|
|||||||
* @extends {Dialog}
|
* @extends {Dialog}
|
||||||
* # Principes
|
* # Principes
|
||||||
* - une seule fenêtre de dialogue (classe RollDialog)
|
* - une seule fenêtre de dialogue (classe RollDialog)
|
||||||
* - plusieurs modes de fonctionnement (classe RollMode)
|
* - plusieurs "types"s de fonctionnement (classe RollType)
|
||||||
* - gestion uniforme des modificateurs (classe RollPart)
|
* - gestion uniforme des modificateurs (classe RollPart)
|
||||||
* - un objet rollData contient les informations liées à un jet de dés
|
* - un objet rollData contient les informations liées à un jet de dés
|
||||||
* - un rollData doit pouvoir être "réduit" pour fournir les informations significatives
|
* - un rollData doit pouvoir être "réduit" pour fournir les informations significatives
|
||||||
@@ -106,15 +110,15 @@ const ROLL_PARTS = [
|
|||||||
* - TODO: une classe de base RollChatMessage gerera les messages correspondant aux résultats du dés
|
* - TODO: une classe de base RollChatMessage gerera les messages correspondant aux résultats du dés
|
||||||
* - TODO: réfléchir aux messages supplémentaires gérés par RdDCombat ?
|
* - TODO: réfléchir aux messages supplémentaires gérés par RdDCombat ?
|
||||||
*
|
*
|
||||||
* ## Modes de fonctionnement - RollMode
|
* ## Types de fonctionnement - RollType
|
||||||
*
|
*
|
||||||
* Un mode de fonctionnement (RollMode) détermine quelles parties (RollPart) de la
|
* Un type de fonctionnement (RollType) détermine quelles parties (RollPart) de la
|
||||||
* fenêtre RollDialog sont actives, mais aussi quels sont les effets du jet.
|
* fenêtre RollDialog sont actives, mais aussi quels sont les effets du jet.
|
||||||
*
|
*
|
||||||
* - chaque mode de fonctionnement peut impacter les RollPart utilisés, les données
|
* - chaque type de fonctionnement peut impacter les RollPart utilisés, les données
|
||||||
* attendues et ajoutées au rollData.
|
* attendues et ajoutées au rollData.
|
||||||
* - chaque mode de fonctionnement peut définir le template de ChatMessage correspondant
|
* - chaque type de fonctionnement peut définir le template de ChatMessage correspondant
|
||||||
* - Le mode de fonctionnement détermine aussi quelles sont les effets du jet:
|
* - Le type de fonctionnement détermine aussi quelles sont les effets du jet:
|
||||||
* - quelle ChatMessage afficher dans le tchat?
|
* - quelle ChatMessage afficher dans le tchat?
|
||||||
* - en cas d'attaque/de défense, quelles sont les suites à donner?
|
* - en cas d'attaque/de défense, quelles sont les suites à donner?
|
||||||
* - en cas de lancement de sort, réduire les points de rêve
|
* - en cas de lancement de sort, réduire les points de rêve
|
||||||
@@ -168,6 +172,14 @@ const ROLL_PARTS = [
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2)
|
export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
{
|
{
|
||||||
|
static onRollDoneDoNothing(dialog) {
|
||||||
|
dialog.render()
|
||||||
|
}
|
||||||
|
static onRollDoneClose(dialog) {
|
||||||
|
if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
|
||||||
|
dialog.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static init() {
|
static init() {
|
||||||
}
|
}
|
||||||
@@ -176,18 +188,25 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
|
|
||||||
foundry.applications.handlebars.loadTemplates({
|
foundry.applications.handlebars.loadTemplates({
|
||||||
'roll-section': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-section.hbs',
|
'roll-section': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-section.hbs',
|
||||||
'roll-mode': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-mode.hbs',
|
'roll-type': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-type.hbs',
|
||||||
'roll-table': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-table.hbs',
|
'roll-table': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-table.hbs',
|
||||||
'roll-ajustements': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-ajustements.hbs',
|
'roll-ajustements': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-ajustements.hbs',
|
||||||
'roll-chances': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-chances.hbs',
|
'roll-chances': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-chances.hbs',
|
||||||
'roll-button': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-button.hbs',
|
'roll-button': 'systems/foundryvtt-reve-de-dragon/templates/roll/roll-button.hbs',
|
||||||
})
|
})
|
||||||
|
|
||||||
foundry.applications.handlebars.loadTemplates(ROLL_MODE_TABS.map(m => m.template))
|
ChatRollResult.onReady()
|
||||||
|
|
||||||
|
foundry.applications.handlebars.loadTemplates(ALL_ROLL_TYPES.map(m => m.template))
|
||||||
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())
|
||||||
|
|
||||||
Handlebars.registerHelper('roll-centered-array', (base, show) => RollDialog.centeredArray(base, show))
|
Handlebars.registerHelper('roll-centered-array', (base, show) => {
|
||||||
|
show = Math.abs(show)
|
||||||
|
const start = base - show
|
||||||
|
return [...Array(2 * show + 1).keys()].map(it => start + it)
|
||||||
|
})
|
||||||
|
|
||||||
Handlebars.registerHelper('roll-list-item-value', (list, key, path = undefined) => {
|
Handlebars.registerHelper('roll-list-item-value', (list, key, path = undefined) => {
|
||||||
const selected = list.find(p => p.key == key)
|
const selected = list.find(p => p.key == key)
|
||||||
if (selected && path && path != '') {
|
if (selected && path && path != '') {
|
||||||
@@ -195,6 +214,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
}
|
}
|
||||||
return selected
|
return selected
|
||||||
})
|
})
|
||||||
|
|
||||||
Handlebars.registerHelper('roll-part-context', (rollData, code) => {
|
Handlebars.registerHelper('roll-part-context', (rollData, code) => {
|
||||||
const rollPart = ROLL_PARTS.find(it => it.code == code)
|
const rollPart = ROLL_PARTS.find(it => it.code == code)
|
||||||
if (rollPart == undefined) {
|
if (rollPart == undefined) {
|
||||||
@@ -211,11 +231,6 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static centeredArray(base, show) {
|
|
||||||
show = Math.abs(show)
|
|
||||||
const start = base - show
|
|
||||||
return [...Array(2 * show + 1).keys()].map(it => start + it)
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(rollData, rollOptions = {}) {
|
static async create(rollData, rollOptions = {}) {
|
||||||
const rollDialog = new RollDialog(rollData, rollOptions)
|
const rollDialog = new RollDialog(rollData, rollOptions)
|
||||||
@@ -246,74 +261,91 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
// rien pour l'instant
|
// rien pour l'instant
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(rollData, rollOptions) {
|
|
||||||
super()
|
|
||||||
this.rollData = rollData
|
|
||||||
// const callbacks = this.rollOptions.callbacks.map(c =>
|
|
||||||
// r => r.activve.actor Promise.all(this.rollOptions.callbacks.map(async callback => await callback(rollData.active.actor, rollData)))
|
|
||||||
// )
|
|
||||||
this.rollOptions = {
|
|
||||||
callbacks: [
|
|
||||||
async (actor, r) => await actor.appliquerAjoutExperience(r),
|
|
||||||
async (actor, r) => await actor.appliquerAppelMoral(r),
|
|
||||||
...(rollOptions.callbacks ?? [])
|
|
||||||
],
|
|
||||||
customChatMessage: rollOptions.customChatMessage,
|
|
||||||
onRoll: rollOptions.onRoll ?? doNothing
|
|
||||||
}
|
|
||||||
this.$loadParts()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** pre-configure les paramètres des différentes parties de la fenêtre (par exemple, prépare les listes de caractéristiques/compétences */
|
/** pre-configure les paramètres des différentes parties de la fenêtre (par exemple, prépare les listes de caractéristiques/compétences */
|
||||||
$loadParts() {
|
static $prepareRollData(rollData) {
|
||||||
const rollData = this.rollData;
|
|
||||||
const loadedMode = rollData.mode?.current
|
|
||||||
rollData.current = rollData.current ?? {}
|
rollData.current = rollData.current ?? {}
|
||||||
rollData.selected = rollData.selected ?? {}
|
rollData.selected = rollData.selected ?? {}
|
||||||
rollData.mode = rollData.mode ?? {}
|
rollData.type = rollData.type ?? {}
|
||||||
rollData.mode.retry = rollData.mode.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 allowed = rollData.type.retry && potential
|
||||||
|
? [potential]
|
||||||
|
: (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code) ?? [ROLL_TYPE_COMP])
|
||||||
|
const rollType = allowed.find(c => c == rollData.type.current) ?? allowed[0]
|
||||||
|
|
||||||
|
rollData.type.allowed = allowed
|
||||||
|
rollData.type.current = rollType
|
||||||
|
ALL_ROLL_TYPES.find(m => m.code == rollType).setRollDataType(rollData)
|
||||||
|
|
||||||
|
rollData.refs = foundry.utils.mergeObject(rollData.refs ?? {}, Object.fromEntries(ROLL_PARTS.map(p => [p.code, {}])));
|
||||||
|
rollData.options = rollData.options ?? { rollMode: game.settings.get("core", "rollMode") }
|
||||||
|
|
||||||
rollData.mode.allowed = rollData.mode.retry ? [loadedMode] : rollData.mode.allowed ?? ROLL_MODE_TABS.map(m => m.code)
|
|
||||||
rollData.mode.current = loadedMode ?? ROLL_MODE_TABS.find(m => m.isAllowed(rollData) && m.visible(rollData))?.code ?? ROLL_MODE_COMP
|
|
||||||
this.getSelectedMode().setRollDataMode(rollData)
|
|
||||||
|
|
||||||
rollData.refs = this.$prepareRefs(rollData)
|
|
||||||
rollData.options = rollData.options ?? { showDice: true, rollMode: game.settings.get("core", "rollMode") }
|
|
||||||
|
|
||||||
ROLL_PARTS.forEach(p => p.initialize(rollData))
|
ROLL_PARTS.forEach(p => p.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.loadRefs(rollData)
|
p.restore(rollData)
|
||||||
p.prepareContext(rollData)
|
p.loadRefs(rollData)
|
||||||
})
|
p.prepareContext(rollData)
|
||||||
this.selectMode();
|
})
|
||||||
}
|
return rollData
|
||||||
|
|
||||||
selectMode() {
|
|
||||||
this.rollData.mode.label = this.getSelectedMode().title(this.rollData)
|
|
||||||
this.getSelectedMode().setRollDataMode(this.rollData)
|
|
||||||
this.getSelectedMode().onSelect(this.rollData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$prepareRefs(rollData) {
|
static saveParts(rollData) {
|
||||||
return foundry.utils.mergeObject(rollData.refs ?? {}, Object.fromEntries(ROLL_PARTS.map(p => [p.code, {}])));
|
const target = RollBasicParts.initFrom(rollData)
|
||||||
}
|
ROLL_PARTS.filter(p => p.isActive(rollData))
|
||||||
|
.forEach(p => p.storeClean(rollData, target))
|
||||||
$saveParts() {
|
target.attackerRoll = rollData.attackerRoll
|
||||||
const target = BASIC_PARTS.initFrom(this.rollData)
|
target.rolled = rollData.rolled
|
||||||
ROLL_PARTS.filter(p => p.isActive(this.rollData))
|
target.result = rollData.result
|
||||||
.forEach(p => p.store(this.rollData, target))
|
target.done = rollData.done ?? {}
|
||||||
|
target.dmg = rollData.dmg
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
getActiveParts() {
|
constructor(rollData, rollOptions) {
|
||||||
return ROLL_PARTS.filter(p => p.isActive(this.rollData))
|
super()
|
||||||
|
|
||||||
|
this.rollData = RollDialog.$prepareRollData(rollData)
|
||||||
|
this.rollOptions = {
|
||||||
|
callbacks: [
|
||||||
|
async r => await r.active.actor.appliquerAjoutExperience(r),
|
||||||
|
async r => await r.active.actor.appliquerAppelMoral(r),
|
||||||
|
...(rollOptions.callbacks ?? [])
|
||||||
|
],
|
||||||
|
customChatMessage: rollOptions.customChatMessage,
|
||||||
|
onRollDone: rollOptions.onRollDone ?? RollDialog.onRollDoneDoNothing
|
||||||
|
}
|
||||||
|
this.chatRollResult = new ChatRollResult();
|
||||||
|
this.selectType()
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
selectType() {
|
||||||
return this.rollData.title ?? `Jet de dés de ${this.rollData.active.actor.name}`
|
const selectedType = this.getSelectedType();
|
||||||
|
this.rollData.type.label = selectedType.title(this.rollData)
|
||||||
|
selectedType.setRollDataType(this.rollData)
|
||||||
|
selectedType.onSelect(this.rollData)
|
||||||
|
|
||||||
|
ROLL_PARTS.find(it => it.code == PART_CARAC).filterCaracs(this.rollData)
|
||||||
|
ROLL_PARTS.find(it => it.code == PART_COMP).filterComps(this.rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static getActiveParts(rollData) {
|
||||||
|
return ROLL_PARTS.filter(p => p.isActive(rollData))
|
||||||
|
}
|
||||||
|
|
||||||
|
rollTitle(rollData) {
|
||||||
|
const title = rollData.label ?? ROLL_PARTS
|
||||||
|
.filter(it => it.section == ROLLDIALOG_SECTION.ACTION)
|
||||||
|
.filter(it => it.isActive(rollData))
|
||||||
|
.map(it => it.title(rollData))
|
||||||
|
.reduce(Misc.joining(' '));
|
||||||
|
if (this.rollOptions.title) {
|
||||||
|
return `${this.rollOptions.title} ${title}`
|
||||||
|
}
|
||||||
|
return title
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onRender(context, options) {
|
async _onRender(context, options) {
|
||||||
@@ -325,54 +357,54 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
this.roll()
|
this.roll()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const buttonsMode = this.element.querySelectorAll(`button[name="roll-mode"]`)
|
const buttonsType = this.element.querySelectorAll(`button[name="roll-type"]`)
|
||||||
buttonsMode?.forEach(it => it.addEventListener(
|
buttonsType?.forEach(it => it.addEventListener(
|
||||||
"click", e => {
|
"click", e => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
this.rollData.mode.current = e.currentTarget.dataset.mode
|
this.rollData.type.current = e.currentTarget.dataset.type
|
||||||
this.selectMode()
|
this.selectType()
|
||||||
this.render()
|
this.render()
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
||||||
Promise.all(
|
Promise.all(
|
||||||
this.getActiveParts().map(async p => await p._onRender(this, context, options))
|
RollDialog.getActiveParts(this.rollData).map(async p => await p._onRender(this, context, options))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getAjustements() {
|
static getAjustements(rollData) {
|
||||||
return this.getActiveParts()
|
return RollDialog.getActiveParts(rollData)
|
||||||
.map(p => p.getAjustements(this.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.diff == undefined ? 1 : b.diff == 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() {
|
||||||
const rollData = this.rollData
|
const rollData = this.rollData
|
||||||
|
|
||||||
const modes = ROLL_MODE_TABS.filter(m => m.isAllowed(rollData) && m.visible(rollData))
|
const types = ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData))
|
||||||
.map(m => m.toModeData(rollData))
|
.map(m => m.toTypeData(rollData))
|
||||||
this.setModeTitle()
|
RollBasicParts.loadSurprises(rollData, this.getSelectedType().code)
|
||||||
|
rollData.type.label = this.getSelectedType()?.title(rollData)
|
||||||
const visibleRollParts = this.getActiveParts()
|
//TOCHECK: set type.label ?
|
||||||
visibleRollParts.forEach(p => p.setExternalFilter(visibleRollParts, rollData))
|
const visibleRollParts = RollDialog.getActiveParts(rollData)
|
||||||
|
visibleRollParts.forEach(p => p.applyExternalImpacts(visibleRollParts, rollData))
|
||||||
|
|
||||||
this.setSpecialComp(visibleRollParts);
|
this.setSpecialComp(visibleRollParts);
|
||||||
|
|
||||||
visibleRollParts.forEach(p => p.prepareContext(rollData))
|
visibleRollParts.forEach(p => p.prepareContext(rollData))
|
||||||
|
|
||||||
this.calculAjustements()
|
RollDialog.calculAjustements(rollData)
|
||||||
|
|
||||||
const templates = this.getActiveParts().map(p => p.toTemplateData())
|
const templates = RollDialog.getActiveParts(rollData).map(p => p.toTemplateData())
|
||||||
const context = await super._prepareContext()
|
const context = await super._prepareContext()
|
||||||
return foundry.utils.mergeObject(
|
return foundry.utils.mergeObject(
|
||||||
{
|
{
|
||||||
modes: modes,
|
types: types,
|
||||||
templates: templates,
|
templates: templates,
|
||||||
rollData: rollData,
|
rollData: rollData,
|
||||||
}, context)
|
}, context)
|
||||||
@@ -382,58 +414,54 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
|||||||
const specialComp = visibleRollParts.map(p => p.getSpecialComp(this.rollData))
|
const specialComp = visibleRollParts.map(p => p.getSpecialComp(this.rollData))
|
||||||
.reduce((a, b) => a.concat(b))
|
.reduce((a, b) => a.concat(b))
|
||||||
if (specialComp.length > 0) {
|
if (specialComp.length > 0) {
|
||||||
const rollPartComp = this.getActiveParts()
|
const rollPartComp = RollDialog.getActiveParts(this.rollData)
|
||||||
.find(it => it.code == PART_COMP);
|
.find(it => it.code == PART_COMP);
|
||||||
rollPartComp?.setSpecialComp(this.rollData, specialComp)
|
rollPartComp?.setSpecialComp(this.rollData, specialComp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
calculAjustements() {
|
static calculAjustements(rollData) {
|
||||||
this.rollData.ajustements = this.getAjustements()
|
rollData.ajustements = RollDialog.getAjustements(rollData)
|
||||||
this.rollData.ajustements.forEach(it => it.isDiff = it.diff != undefined)
|
rollData.ajustements.forEach(it => it.isDiff = it.diff != undefined)
|
||||||
this.rollData.current.totaldiff = this.rollData.ajustements
|
rollData.current.totaldiff = rollData.ajustements
|
||||||
.map(adj => adj.diff)
|
.map(adj => adj.diff)
|
||||||
.filter(d => d != undefined)
|
.filter(d => d != undefined)
|
||||||
.reduce(Misc.sum(), 0)
|
.reduce(Misc.sum(), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
setModeTitle() {
|
getSelectedType() {
|
||||||
this.rollData.mode.label = this.getSelectedMode()?.title(this.rollData)
|
return ALL_ROLL_TYPES.find(m => m.code == this.rollData.type.current)
|
||||||
}
|
|
||||||
|
|
||||||
getSelectedMode() {
|
|
||||||
return ROLL_MODE_TABS.find(m => m.code == this.rollData.mode.current)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async roll() {
|
async roll() {
|
||||||
this.calculAjustements()
|
|
||||||
const rollData = this.rollData
|
const roll = RollDialog.saveParts(this.rollData)
|
||||||
console.info('Roll parts:', this.$saveParts())
|
const selectedRollType = this.getSelectedType(roll);
|
||||||
const rolled = await this.$rollDice(rollData)
|
RollDialog.loadRollData(roll)
|
||||||
rollData.rolled = rolled
|
roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1
|
||||||
Promise.all(this.rollOptions.callbacks.map(async callback => await callback(rollData.active.actor, rollData)))
|
roll.choix = {}
|
||||||
if (!this.rollOptions.customChatMessage) {
|
roll.rolled = await RollDialogAdapter.rollDice(roll, this.rollTitle(roll))
|
||||||
rollData.active.actor.$onRollCompetence(this.rollData)
|
roll.result = selectedRollType.getResult(roll)
|
||||||
}
|
|
||||||
this.rollOptions.onRoll(this)
|
console.info('RollDialog.roll:', roll)
|
||||||
|
const callbacks = [
|
||||||
|
...this.rollOptions.callbacks,
|
||||||
|
...selectedRollType.callbacks(this.rollOptions),
|
||||||
|
]
|
||||||
|
await Promise.all(callbacks.map(async callback => await callback(roll)))
|
||||||
|
await this.chatRollResult.display(roll)
|
||||||
|
this.rollOptions.onRollDone(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static loadRollData(roll) {
|
||||||
async defaultCallback(rollData, rolled) {
|
RollDialog.$prepareRollData(roll)
|
||||||
await rollData.active.actor.appliquerAjoutExperience(rollData)
|
RollDialog.calculAjustements(roll)
|
||||||
await rollData.active.actor.appliquerAppelMoral(rollData)
|
roll.v2 = true
|
||||||
}
|
}
|
||||||
|
|
||||||
async $rollDice(rollData) {
|
async defaultCallback(roll, rolled) {
|
||||||
const adapter = new RollDialogAdapter(ROLL_PARTS);
|
await roll.active.actor.appliquerAjoutExperience(roll)
|
||||||
return await adapter.rollDice(rollData, this.rollTitle(rollData));
|
await roll.active.actor.appliquerAppelMoral(roll)
|
||||||
}
|
}
|
||||||
|
|
||||||
rollTitle(rollData) {
|
|
||||||
return ROLL_PARTS
|
|
||||||
.filter(it => it.section == ROLLDIALOG_SECTION.ACTION)
|
|
||||||
.filter(it => it.isActive(rollData))
|
|
||||||
.map(it => it.title(rollData))
|
|
||||||
.reduce(Misc.joining(' '))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
import { DIFF_MODE, ROLL_MODE_ATTAQUE } from "./roll-constants.mjs"
|
|
||||||
import { RollMode } from "./roll-mode.mjs"
|
|
||||||
|
|
||||||
export class RollModeAttaque extends RollMode {
|
|
||||||
get code() { return ROLL_MODE_ATTAQUE }
|
|
||||||
get name() { return `Attaquer` }
|
|
||||||
|
|
||||||
title(rollData) { return `attaque` }
|
|
||||||
|
|
||||||
onSelect(rollData) {
|
|
||||||
this.setDiffMode(rollData, DIFF_MODE.ATTAQUE)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
import { ROLL_MODE_COMP } from "./roll-constants.mjs"
|
|
||||||
import { RollMode } from "./roll-mode.mjs"
|
|
||||||
|
|
||||||
export class RollModeComp extends RollMode {
|
|
||||||
get code() { return ROLL_MODE_COMP }
|
|
||||||
get name() { return `Jet de caractéristique / compétence` }
|
|
||||||
|
|
||||||
title(rollData) { return `fait un jet ${rollData.mode.opposed ? ' contre ' : ''}` }
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
import { DIFF_MODE, ROLL_MODE_DEFENSE } from "./roll-constants.mjs"
|
|
||||||
import { RollMode } from "./roll-mode.mjs"
|
|
||||||
|
|
||||||
export class RollModeDefense extends RollMode {
|
|
||||||
get code() { return ROLL_MODE_DEFENSE }
|
|
||||||
get name() { return `Se défendre` }
|
|
||||||
|
|
||||||
title(rollData) { return `se défend${rollData.attacker ? ' de' : ''}` }
|
|
||||||
|
|
||||||
getOpponent(rollData) {
|
|
||||||
return rollData.attacker
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelect(rollData) {
|
|
||||||
this.setDiffMode(rollData, DIFF_MODE.DEFENSE)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
import { DIFF_MODE, ROLL_MODE_MEDITATION } from "./roll-constants.mjs"
|
|
||||||
import { PART_MEDITATION } from "./roll-part-meditation.mjs"
|
|
||||||
import { RollMode } from "./roll-mode.mjs"
|
|
||||||
|
|
||||||
export class RollModeMeditation extends RollMode {
|
|
||||||
get code() { return ROLL_MODE_MEDITATION }
|
|
||||||
get name() { return `Méditation draconique` }
|
|
||||||
|
|
||||||
visible(rollData) { return rollData.active.actor.isHautRevant() }
|
|
||||||
title(rollData) {
|
|
||||||
const current = rollData.current[PART_MEDITATION]
|
|
||||||
const theme = current?.meditation.system.theme
|
|
||||||
return theme ? 'médite sur ' + theme : 'médite'
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelect(rollData) {
|
|
||||||
this.setDiffMode(rollData, DIFF_MODE.AUCUN)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
import { DIFF_MODE, ROLL_MODE_OEUVRE } from "./roll-constants.mjs"
|
|
||||||
import { PART_OEUVRE } from "./roll-part-oeuvre.mjs"
|
|
||||||
import { RollMode } from "./roll-mode.mjs"
|
|
||||||
|
|
||||||
export class RollModeOeuvre extends RollMode {
|
|
||||||
get code() { return ROLL_MODE_OEUVRE }
|
|
||||||
get name() { return `Interpréter une oeuvre` }
|
|
||||||
|
|
||||||
visible(rollData) { return rollData.active.actor.isPersonnage() }
|
|
||||||
title(rollData) {
|
|
||||||
const current = rollData.current[PART_OEUVRE]
|
|
||||||
return `${current.art.action} ${current.label}`
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelect(rollData) {
|
|
||||||
this.setDiffMode(rollData, DIFF_MODE.AUCUN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@@ -1,15 +0,0 @@
|
|||||||
import { DIFF_MODE, ROLL_MODE_SORT } from "./roll-constants.mjs"
|
|
||||||
import { RollMode } from "./roll-mode.mjs"
|
|
||||||
import { PART_SORT } from "./roll-part-sort.mjs"
|
|
||||||
|
|
||||||
export class RollModeSort extends RollMode {
|
|
||||||
get code() { return ROLL_MODE_SORT }
|
|
||||||
get name() { return `lancer un sort` }
|
|
||||||
|
|
||||||
visible(rollData) { return rollData.active.actor.isHautRevant() }
|
|
||||||
title(rollData) { return `lance le sort:` }
|
|
||||||
|
|
||||||
onSelect(rollData) {
|
|
||||||
this.setDiffMode(rollData, DIFF_MODE.AUCUN)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
import { DIFF_MODE, ROLL_MODE_TACHE } from "./roll-constants.mjs"
|
|
||||||
import { PART_TACHE } from "./roll-part-tache.mjs"
|
|
||||||
import { RollMode } from "./roll-mode.mjs"
|
|
||||||
|
|
||||||
export class RollModeTache extends RollMode {
|
|
||||||
get code() { return ROLL_MODE_TACHE }
|
|
||||||
get name() { return `Travailler à une tâche` }
|
|
||||||
|
|
||||||
visible(rollData) { return rollData.active.actor.isPersonnage() }
|
|
||||||
title(rollData) {
|
|
||||||
const current = rollData.current[PART_TACHE]
|
|
||||||
const tache = current?.tache
|
|
||||||
return `travaille à sa tâche: ${tache.name ?? ''}`
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelect(rollData) {
|
|
||||||
this.setDiffMode(rollData, DIFF_MODE.AUCUN)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,54 +0,0 @@
|
|||||||
import { DIFF_MODE } from "./roll-constants.mjs"
|
|
||||||
import { PART_DIFF } from "./roll-part-diff.mjs"
|
|
||||||
|
|
||||||
const DEFAULT_DIFF_MODES = [DIFF_MODE.LIBRE, DIFF_MODE.IMPOSEE, DIFF_MODE.DEFAUT]
|
|
||||||
|
|
||||||
export class RollMode {
|
|
||||||
|
|
||||||
onReady() { }
|
|
||||||
|
|
||||||
get code() { throw new Error(`Pas de code défini pour ${this}`) }
|
|
||||||
get name() { return this.code }
|
|
||||||
get icon() { return `systems/foundryvtt-reve-de-dragon/assets/actions/${this.code}.svg` }
|
|
||||||
|
|
||||||
toModeData(rollData) {
|
|
||||||
return { code: this.code, name: this.name, icon: this.icon, section: 'mode', template: this.template, selected: this.isSelected(rollData) }
|
|
||||||
}
|
|
||||||
|
|
||||||
isAllowed(rollData) { return rollData.mode.allowed == undefined || rollData.mode.allowed.includes(this.code) }
|
|
||||||
visible(rollData) { return true }
|
|
||||||
|
|
||||||
title(rollData) { return this.code }
|
|
||||||
isSelected(rollData) { return rollData.mode.current == this.code }
|
|
||||||
|
|
||||||
setRollDataMode(rollData) {
|
|
||||||
rollData.mode.opposed = rollData.opponent != undefined
|
|
||||||
rollData.mode.resistance = false /** TODO */
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelect(rollData) {
|
|
||||||
const mode = [
|
|
||||||
rollData.current[PART_DIFF].mode,
|
|
||||||
this.modeFromOpponents(rollData),
|
|
||||||
rollData.selected[PART_DIFF].mode].find(m => DEFAULT_DIFF_MODES.includes(m))
|
|
||||||
|
|
||||||
this.setDiffMode(rollData, mode ??
|
|
||||||
DIFF_MODE.DEFAUT)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
modeFromOpponents(rollData) {
|
|
||||||
if (rollData.mode.opposed) {
|
|
||||||
if (rollData.mode.resistance) {
|
|
||||||
return DIFF_MODE.IMPOSEE
|
|
||||||
}
|
|
||||||
return DIFF_MODE.LIBRE
|
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
setDiffMode(rollData, mode) {
|
|
||||||
rollData.current[PART_DIFF].mode = mode
|
|
||||||
this.setRollDataMode(rollData)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -8,12 +8,12 @@ export class RollPartAction extends RollPart {
|
|||||||
get section() { return ROLLDIALOG_SECTION.ACTION }
|
get section() { return ROLLDIALOG_SECTION.ACTION }
|
||||||
|
|
||||||
title(rollData) {
|
title(rollData) {
|
||||||
return rollData.mode.label
|
return rollData.type.label
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareContext(rollData) {
|
prepareContext(rollData) {
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
current.verb = rollData.mode.label
|
current.verb = rollData.type.label
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,7 @@ export class RollPartAppelMoral extends RollPartCheckbox {
|
|||||||
}
|
}
|
||||||
return '<i class="fa-regular fa-face-meh"></i>'
|
return '<i class="fa-regular fa-face-meh"></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
getCheckboxLabel(rollData) { return "Appel au moral" }
|
getCheckboxLabel(rollData) { return "Appel au moral" }
|
||||||
getCheckboxValue(rollData) { return 1 }
|
getCheckboxValue(rollData) { return 1 }
|
||||||
}
|
}
|
||||||
|
@@ -10,10 +10,8 @@ export class RollPartAstrologique extends RollPartCheckbox {
|
|||||||
get useCheckboxTemplate() { return false }
|
get useCheckboxTemplate() { return false }
|
||||||
|
|
||||||
visible(rollData) {
|
visible(rollData) {
|
||||||
return this.$isUsingAstrologie() && (
|
return this.$isUsingAstrologie()
|
||||||
this.isJetChance(rollData)
|
&& (this.isJetChance(rollData) || this.isLancementRituel(rollData))
|
||||||
|| this.isLancementRituel(rollData)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isLancementRituel(rollData) {
|
isLancementRituel(rollData) {
|
||||||
|
@@ -1,66 +1,131 @@
|
|||||||
import { Grammar } from "../grammar.js"
|
import { RdDBonus } from "../rdd-bonus.js"
|
||||||
import { ROLL_MODE_ATTAQUE } from "./roll-constants.mjs"
|
import { DIFF, ROLL_TYPE_ATTAQUE } 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"
|
||||||
|
import { PART_DIFF } from "./roll-part-diff.mjs"
|
||||||
import { RollPartSelect } from "./roll-part-select.mjs"
|
import { RollPartSelect } from "./roll-part-select.mjs"
|
||||||
import { ROLLDIALOG_SECTION, RollPart } 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)
|
||||||
|
|
||||||
export class RollPartAttaque extends RollPartSelect {
|
export class RollPartAttaque extends RollPartSelect {
|
||||||
|
|
||||||
get code() { return PART_ATTAQUE }
|
get code() { return PART_ATTAQUE }
|
||||||
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
||||||
|
|
||||||
visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_ATTAQUE) }
|
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_ATTAQUE) }
|
||||||
|
|
||||||
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.attaques = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor))
|
||||||
if (refs.attaques.length>0){
|
refs.tactiques = TACTIQUES
|
||||||
this.$selectAttaque(rollData)
|
if (refs.attaques.length > 0) {
|
||||||
|
const attaque = this.findAttaque(refs.attaques, this.getSaved(rollData))
|
||||||
|
this.$selectAttaque(rollData, attaque?.key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
store(rollData, targetData) {
|
||||||
|
super.store(rollData, targetData)
|
||||||
|
this.getSaved(targetData).dmg = this.getCurrent(rollData).dmg
|
||||||
|
}
|
||||||
|
|
||||||
|
restore(rollData) {
|
||||||
|
const saved = this.getSaved(rollData)
|
||||||
|
super.restore(rollData)
|
||||||
|
if (saved.dmg) {
|
||||||
|
this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findAttaque(attaques, saved) {
|
||||||
|
return attaques.find(at => at.arme.id == saved?.arme?.id &&
|
||||||
|
at.comp.id == saved?.comp?.id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
choices(refs) { return refs.attaques }
|
choices(refs) { return refs.attaques }
|
||||||
|
|
||||||
static $extractAttaque(action, actor) {
|
static $extractAttaque(attaque, actor) {
|
||||||
return {
|
// const extracted = foundry.utils.mergeObject({
|
||||||
key: `${action.action}::${action.arme.id}::${action.comp.id}`,
|
// key: `${attaque.action}::${attaque.label}`,
|
||||||
label: action.name,
|
// tactique: TACTIQUES[0]
|
||||||
action: action,
|
// },
|
||||||
arme: action.arme,
|
// attaque
|
||||||
comp: action.comp,
|
// )
|
||||||
}
|
// return extracted
|
||||||
|
// extracted.initialDiff = attaque.comp?.system.default_diffLibre ?? 0
|
||||||
|
attaque.key = `${attaque.action}::${attaque.label}`
|
||||||
|
attaque.tactique = TACTIQUES[0]
|
||||||
|
attaque.initialDiff = attaque.comp?.system.default_diffLibre ?? 0
|
||||||
|
return attaque
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepareContext(rollData) {
|
||||||
|
const current = this.getCurrent(rollData)
|
||||||
|
current.dmg = RdDBonus.dmgRollV2(rollData, current)
|
||||||
|
}
|
||||||
|
|
||||||
|
getAjustements(rollData) {
|
||||||
|
const current = this.getCurrent(rollData)
|
||||||
|
const ajustements = []
|
||||||
|
if (current.tactique) {
|
||||||
|
ajustements.push({ label: current.tactique.label, diff: current.tactique.attaque })
|
||||||
|
}
|
||||||
|
if (rollData.opponent?.surprise) {
|
||||||
|
ajustements.push({ label: rollData.opponent.surprise.label, diff: rollData.opponent.surprise.attaque })
|
||||||
|
}
|
||||||
|
return ajustements
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$selectAttaque(rollData, key) {
|
$selectAttaque(rollData, key) {
|
||||||
this.selectByKey(rollData, key, 0)
|
this.selectByKey(rollData, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onRender(rollDialog, context, options) {
|
async _onRender(rollDialog, context, options) {
|
||||||
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 checkMortalite = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="check-mortalite"]`)
|
||||||
|
const current = this.getCurrent(rollDialog.rollData)
|
||||||
|
|
||||||
selectAttaque.addEventListener("change", e => {
|
selectAttaque.addEventListener("change", e => {
|
||||||
const selectOptions = e.currentTarget.options
|
const selectOptions = e.currentTarget.options
|
||||||
const index = selectOptions.selectedIndex
|
const index = selectOptions.selectedIndex
|
||||||
this.$selectAttaque(rollDialog.rollData, selectOptions[index]?.value)
|
this.$selectAttaque(rollDialog.rollData, selectOptions[index]?.value)
|
||||||
rollDialog.setModeTitle()
|
rollDialog.render()
|
||||||
|
})
|
||||||
|
|
||||||
|
selectTactique.addEventListener("change", e => {
|
||||||
|
const selectOptions = e.currentTarget.options
|
||||||
|
const index = selectOptions.selectedIndex
|
||||||
|
current.tactique = RdDBonus.find(selectOptions[index]?.value)
|
||||||
|
rollDialog.render()
|
||||||
|
})
|
||||||
|
|
||||||
|
checkMortalite?.addEventListener("change", e => {
|
||||||
|
current.dmg.mortalite = (e.currentTarget.checked ? 'mortel' : 'non-mortel')
|
||||||
rollDialog.render()
|
rollDialog.render()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getExternalPartsFilter(partCode, rollData) {
|
impactOtherPart(part, rollData) {
|
||||||
if (this.visible(rollData)) {
|
if (this.visible(rollData)) {
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
switch (partCode) {
|
switch (part.code) {
|
||||||
case PART_CARAC: return p => Grammar.equalsInsensitive(current.action.carac.key, p.key)
|
case PART_CARAC: return part.filterCaracs(rollData, [current.carac.key])
|
||||||
case PART_COMP: return p => p.label == current.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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -36,9 +36,14 @@ export class RollPartCarac extends RollPartSelect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setFilter(rollData, filter) {
|
filterCaracs(rollData, allowed = []) {
|
||||||
|
allowed = allowed.filter(it => it != undefined)
|
||||||
const refs = this.getRefs(rollData)
|
const refs = this.getRefs(rollData)
|
||||||
refs.caracs = refs.all.filter(filter)
|
refs.caracs = allowed.length > 0
|
||||||
|
// ? refs.all.filter(it => allowed.includes(Grammar.toLowerCaseNoAccent(it.key)))
|
||||||
|
? refs.all.filter(it => allowed.includes(it.key))
|
||||||
|
: refs.all
|
||||||
|
this.$selectCarac(rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareContext(rollData) {
|
prepareContext(rollData) {
|
||||||
|
@@ -18,8 +18,8 @@ export class RollPartCheckbox extends RollPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadRefs(rollData) {
|
loadRefs(rollData) {
|
||||||
const current = this.getCurrent(rollData)
|
const refs = this.getRefs(rollData)
|
||||||
current.label = this.getCheckboxLabel(rollData)
|
refs.label = this.getCheckboxLabel(rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareContext(rollData) {
|
prepareContext(rollData) {
|
||||||
@@ -28,9 +28,7 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +41,7 @@ export class RollPartCheckbox extends RollPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCheckboxLabelAjustement(rollData) {
|
getCheckboxLabelAjustement(rollData) {
|
||||||
return `${this.getCheckboxIcon(rollData)} ${this.getCurrent(rollData).label}`
|
return `${this.getCheckboxIcon(rollData)} ${this.getRefs(rollData).label}`
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onRender(rollDialog, context, options) {
|
async _onRender(rollDialog, context, options) {
|
||||||
|
@@ -17,7 +17,14 @@ export class RollPartComp extends RollPartSelect {
|
|||||||
|
|
||||||
loadRefs(rollData) {
|
loadRefs(rollData) {
|
||||||
const refs = this.getRefs(rollData)
|
const refs = this.getRefs(rollData)
|
||||||
|
const selected = this.getSelected(rollData)
|
||||||
refs.all = this.$getActorComps(rollData)
|
refs.all = this.$getActorComps(rollData)
|
||||||
|
.filter(comp => !selected.forced ||
|
||||||
|
(selected.key ?
|
||||||
|
Grammar.includesLowerCaseNoAccent(comp.name, selected.key)
|
||||||
|
: comp.key == '')
|
||||||
|
)
|
||||||
|
|
||||||
refs.comps = refs.all
|
refs.comps = refs.all
|
||||||
this.$selectComp(rollData)
|
this.$selectComp(rollData)
|
||||||
}
|
}
|
||||||
@@ -45,9 +52,13 @@ export class RollPartComp extends RollPartSelect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setFilter(rollData, filter) {
|
filterComps(rollData, allowed = []) {
|
||||||
|
allowed = allowed.filter(it => it != undefined)
|
||||||
const refs = this.getRefs(rollData)
|
const refs = this.getRefs(rollData)
|
||||||
refs.comps = refs.all.filter(filter)
|
refs.comps = allowed.length > 0
|
||||||
|
? refs.all.filter(it => allowed.includes(it.label))
|
||||||
|
: refs.all
|
||||||
|
this.$selectComp(rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareContext(rollData) {
|
prepareContext(rollData) {
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { SYSTEM_RDD } from "../constants.js";
|
import { SYSTEM_RDD } from "../constants.js";
|
||||||
|
import { Misc } from "../misc.js";
|
||||||
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs";
|
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs";
|
||||||
|
|
||||||
const CONDITIONS = "conditions"
|
const CONDITIONS = "conditions"
|
||||||
@@ -50,7 +51,7 @@ export class RollPartConditions extends RollPart {
|
|||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
current.min = game.settings.get(SYSTEM_RDD, this.settingMin())
|
current.min = game.settings.get(SYSTEM_RDD, this.settingMin())
|
||||||
current.max = game.settings.get(SYSTEM_RDD, this.settingMax())
|
current.max = game.settings.get(SYSTEM_RDD, this.settingMax())
|
||||||
current.value = current.value ?? 0
|
current.value = Misc.inRange(current.value ?? 0, current.min, current.max)
|
||||||
}
|
}
|
||||||
|
|
||||||
getAjustements(rollData) {
|
getAjustements(rollData) {
|
||||||
@@ -63,12 +64,13 @@ export class RollPartConditions extends RollPart {
|
|||||||
|
|
||||||
async _onRender(rollDialog, context, options) {
|
async _onRender(rollDialog, context, options) {
|
||||||
const input = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`)
|
const input = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`)
|
||||||
|
|
||||||
input?.addEventListener("change", e => {
|
input?.addEventListener("input", e => this.onInputChange(e, rollDialog))
|
||||||
const current = this.getCurrent(rollDialog.rollData)
|
}
|
||||||
current.value = parseInt(e.currentTarget.value)
|
|
||||||
rollDialog.render()
|
onInputChange(event, rollDialog) {
|
||||||
})
|
this.getCurrent(rollDialog.rollData).value = parseInt(event.currentTarget.value)
|
||||||
|
rollDialog.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
76
module/roll/roll-part-cuisine.mjs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
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) }
|
||||||
|
|
||||||
|
loadRefs(rollData) {
|
||||||
|
const refs = this.getRefs(rollData)
|
||||||
|
refs.recettes = rollData.active.actor.items
|
||||||
|
.filter(it => it.type == ITEM_TYPES.recettecuisine)
|
||||||
|
.map(it => RollPartCuisine.$extractRecette(it, rollData.active.actor))
|
||||||
|
if (refs.recettes.length > 0) {
|
||||||
|
this.$selectRecette(rollData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
choices(refs) { return refs.recettes }
|
||||||
|
|
||||||
|
static $extractRecette(recette, actor) {
|
||||||
|
return {
|
||||||
|
key: recette.id,
|
||||||
|
label: recette.name,
|
||||||
|
caracs: RollPartCuisine.getCaracs(recette),
|
||||||
|
qualite: recette.system.niveau,
|
||||||
|
value: -recette.system.niveau,
|
||||||
|
recette: recette,
|
||||||
|
comp: actor.getCompetence('Cuisine')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static getCaracs(recette){
|
||||||
|
// TODO: permettre différentes caractéristiques pour la cuisine?
|
||||||
|
return [CARACS.ODORATGOUT, CARACS.EMPATHIE, CARACS.DEXTERITE]
|
||||||
|
}
|
||||||
|
|
||||||
|
$selectRecette(rollData, key) {
|
||||||
|
this.selectByKey(rollData, key, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onRender(rollDialog, context, options) {
|
||||||
|
const selectRecette = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-recette"]`)
|
||||||
|
|
||||||
|
selectRecette.addEventListener("change", e => {
|
||||||
|
const selectOptions = e.currentTarget.options
|
||||||
|
const index = selectOptions.selectedIndex
|
||||||
|
this.$selectRecette(rollDialog.rollData, selectOptions[index]?.value)
|
||||||
|
rollDialog.render()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impactOtherPart(part, rollData) {
|
||||||
|
if (this.visible(rollData)) {
|
||||||
|
const current = this.getCurrent(rollData)
|
||||||
|
switch (part.code) {
|
||||||
|
case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
|
||||||
|
case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,17 +1,132 @@
|
|||||||
import { ROLL_MODE_DEFENSE } from "./roll-constants.mjs"
|
import { ITEM_TYPES } from "../constants.js"
|
||||||
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
|
import { Grammar } from "../grammar.js"
|
||||||
|
import { ATTAQUE_TYPE, RdDItemArme } from "../item/arme.js"
|
||||||
|
import { RdDBonus } from "../rdd-bonus.js"
|
||||||
|
import { CARACS } from "../rdd-carac.js"
|
||||||
|
import { StatusEffects } from "../settings/status-effects.js"
|
||||||
|
import { DIFF, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
|
||||||
|
import { PART_CARAC } from "./roll-part-carac.mjs"
|
||||||
|
import { PART_COMP } from "./roll-part-comp.mjs"
|
||||||
|
import { PART_DIFF } from "./roll-part-diff.mjs"
|
||||||
|
import { RollPartSelect } from "./roll-part-select.mjs"
|
||||||
|
import { PART_SIGN } from "./roll-part-sign.mjs"
|
||||||
|
import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
|
||||||
|
|
||||||
export const PART_DEFENSE = 'defense'
|
export const PART_DEFENSE = 'defense'
|
||||||
|
|
||||||
export class RollPartDefense extends RollPart {
|
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 }
|
||||||
visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_DEFENSE) }
|
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_DEFENSE) }
|
||||||
|
|
||||||
|
static getDiffAttaque(attackerRoll) {
|
||||||
|
// TODO: rollDataV2?
|
||||||
|
return attackerRoll.diffLibre;
|
||||||
|
}
|
||||||
|
|
||||||
loadRefs(rollData) {
|
loadRefs(rollData) {
|
||||||
const refs = this.getRefs(rollData)
|
const refs = this.getRefs(rollData)
|
||||||
refs.defenses =[]
|
const attackerRoll = rollData.attackerRoll
|
||||||
|
const defenseur = rollData.active.actor
|
||||||
|
refs.isDistance = [ATTAQUE_TYPE.TIR, ATTAQUE_TYPE.LANCER].find(it => it == attackerRoll?.main)
|
||||||
|
const esquives = refs.isDistance == ATTAQUE_TYPE.TIR ? [] : defenseur.getCompetencesEsquive()
|
||||||
|
.map(it => RollPartDefense.$extractEsquive(it, defenseur))
|
||||||
|
|
||||||
|
const parades = defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier()))
|
||||||
|
.map(it => RollPartDefense.$extractParade(it, attackerRoll?.arme, defenseur))
|
||||||
|
|
||||||
|
refs.defenses = [...esquives, ...parades].filter(it => it != undefined)
|
||||||
|
this.$selectDefense(rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static $extractEsquive(esquive, defenseur) {
|
||||||
|
return {
|
||||||
|
key: esquive.id,
|
||||||
|
label: esquive.name,
|
||||||
|
img: esquive.img,
|
||||||
|
// TODO: carac pour créatures
|
||||||
|
carac: defenseur.isPersonnage() ? CARACS.DEROBEE : esquive.name,
|
||||||
|
verb: "esquive",
|
||||||
|
comp: esquive,
|
||||||
|
isEsquive: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static $extractParade(armeDefense, armeAttaque, defenseur) {
|
||||||
|
const comp = (ITEM_TYPES.competencecreature == armeDefense.type)
|
||||||
|
? armeDefense
|
||||||
|
: defenseur.getCompetence(armeDefense.system.competence)
|
||||||
|
return {
|
||||||
|
key: armeDefense.id,
|
||||||
|
label: 'Parade ' + armeDefense.name,
|
||||||
|
img: armeDefense.img,
|
||||||
|
// TODO: carac pour créatures
|
||||||
|
carac: defenseur.isPersonnage() ? CARACS.MELEE : comp.name,
|
||||||
|
verb: "pare",
|
||||||
|
comp: comp,
|
||||||
|
arme: armeDefense,
|
||||||
|
forceRequise: armeDefense ? RdDItemArme.valeurMain(armeDefense.system.force ?? 0, RdDItemArme.getMainAttaque(comp)) : 0,
|
||||||
|
typeParade: armeAttaque ? RdDItemArme.defenseArmeParade(armeDefense, armeAttaque) : 'norm',
|
||||||
|
isEsquive: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareContext(rollData) {
|
||||||
|
// current.dmg = this.$dmgRollV2(rollData, current)
|
||||||
|
}
|
||||||
|
|
||||||
|
getAjustements(rollData) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
choices(refs) { return refs.defenses }
|
||||||
|
|
||||||
|
$selectDefense(rollData, key) {
|
||||||
|
this.selectByKey(rollData, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
async _onRender(rollDialog, context, options) {
|
||||||
|
const selectDefense = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-defense"]`)
|
||||||
|
|
||||||
|
selectDefense.addEventListener("change", e => {
|
||||||
|
const selectOptions = e.currentTarget.options
|
||||||
|
const index = selectOptions.selectedIndex
|
||||||
|
this.$selectDefense(rollDialog.rollData, selectOptions[index]?.value)
|
||||||
|
rollDialog.render()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impactOtherPart(part, rollData) {
|
||||||
|
if (this.visible(rollData)) {
|
||||||
|
const current = this.getCurrent(rollData)
|
||||||
|
switch (part.code) {
|
||||||
|
case PART_CARAC: return part.filterCaracs(rollData, [current.carac])
|
||||||
|
case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
|
||||||
|
case PART_DIFF: return part.setDiff(rollData, this.getDiffDefense(rollData))
|
||||||
|
case PART_SIGN: return part.setArmeDisparate(rollData, this.isArmeDisparate(rollData))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
isArmeDisparate(rollData) {
|
||||||
|
const armeDefense = this.getCurrent(rollData).arme
|
||||||
|
if (armeDefense) {
|
||||||
|
const armeAttaque = rollData.attackerRoll?.arme
|
||||||
|
return RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) == 'sign'
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
getDiffDefense(rollData) {
|
||||||
|
const refs = this.getRefs(rollData)
|
||||||
|
if (refs.isDistance || !rollData.attackerRoll) {
|
||||||
|
// TODO: Déterminer la difficulté de parade
|
||||||
|
return { diff: 0, type: DIFF.LIBRE }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return { diff: rollData.attackerRoll.diff ?? 0, type: DIFF.DEFENSE }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
import { DIFF_MODE, DIFF_MODES, ROLL_MODE_MEDITATION, ROLL_MODE_OEUVRE, ROLL_MODE_SORT, ROLL_MODE_TACHE } from "./roll-constants.mjs";
|
import { DIFF, DIFFS, 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";
|
||||||
|
|
||||||
export const PART_DIFF = "diff"
|
export const PART_DIFF = "diff"
|
||||||
|
|
||||||
const EXCLUDED_ROLL_MODES = [ROLL_MODE_TACHE, ROLL_MODE_MEDITATION, ROLL_MODE_SORT, ROLL_MODE_OEUVRE]
|
const EXCLUDED_ROLL_TYPES = [ROLL_TYPE_TACHE, ROLL_TYPE_MEDITATION, ROLL_TYPE_SORT, ROLL_TYPE_OEUVRE]
|
||||||
|
|
||||||
export class RollPartDiff extends RollPart {
|
export class RollPartDiff extends RollPart {
|
||||||
|
|
||||||
@@ -14,42 +15,48 @@ export class RollPartDiff extends RollPart {
|
|||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
const saved = this.getSaved(rollData)
|
const saved = this.getSaved(rollData)
|
||||||
current.value = saved?.value ?? current.value ?? 0
|
current.value = saved?.value ?? current.value ?? 0
|
||||||
current.mode = saved?.mode ?? current.mode
|
current.type = saved?.type ?? current.type
|
||||||
}
|
}
|
||||||
|
|
||||||
store(rollData, targetData) {
|
store(rollData, targetData) {
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
this.setSaved(targetData, {
|
this.setSaved(targetData, {
|
||||||
value: current.value,
|
value: current.value,
|
||||||
mode: current.mode
|
type: current.type
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
visible(rollData) {
|
visible(rollData) {
|
||||||
if (EXCLUDED_ROLL_MODES.includes(rollData.mode.current)) {
|
if (EXCLUDED_ROLL_TYPES.includes(rollData.type.current)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
/* TODO: affiner les cas où afficher ou non. devrait s'afficher pour les jets basiques (même si pas d'opposant sélectionné)*/
|
/* TODO: affiner les cas où afficher ou non. devrait s'afficher pour les jets basiques (même si pas d'opposant sélectionné)*/
|
||||||
return Object.values(DIFF_MODE).includes(current.mode)
|
return Object.values(DIFF).includes(current.type)
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareContext(rollData) {
|
prepareContext(rollData) {
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
const diffMode = DIFF_MODES[current.mode] ?? DIFF_MODES[DIFF_MODE.AUCUN]
|
const diffType = DIFFS[current.type] ?? DIFFS[DIFF.AUCUN]
|
||||||
foundry.utils.mergeObject(current,
|
foundry.utils.mergeObject(current,
|
||||||
{
|
{
|
||||||
mode: diffMode.key,
|
type: diffType.key,
|
||||||
label: diffMode?.label ?? '',
|
label: diffType?.label ?? '',
|
||||||
value: current.value ?? 0,
|
disabled: !diffType.libre,
|
||||||
disabled: !diffMode.libre,
|
value: Misc.inRange(current.value ?? 0, -10, diffType.max),
|
||||||
min: -10,
|
min: -10,
|
||||||
max: diffMode.max
|
max: diffType.max
|
||||||
},
|
},
|
||||||
{ inplace: true }
|
{ inplace: true }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDiff(rollData, diff) {
|
||||||
|
const current = this.getCurrent(rollData)
|
||||||
|
current.value = diff.diff
|
||||||
|
current.type = diff.type
|
||||||
|
}
|
||||||
|
|
||||||
getAjustements(rollData) {
|
getAjustements(rollData) {
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
return [{
|
return [{
|
||||||
@@ -61,10 +68,12 @@ export class RollPartDiff extends RollPart {
|
|||||||
async _onRender(rollDialog, context, options) {
|
async _onRender(rollDialog, context, options) {
|
||||||
const input = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`)
|
const input = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${this.code}"]`)
|
||||||
|
|
||||||
input?.addEventListener("change", e => {
|
input?.addEventListener("input", e => this.onInputChange(e, rollDialog))
|
||||||
this.getCurrent(rollDialog.rollData).value = parseInt(e.currentTarget.value)
|
}
|
||||||
rollDialog.render()
|
|
||||||
})
|
onInputChange(event, rollDialog) {
|
||||||
|
this.getCurrent(rollDialog.rollData).value = parseInt(event.currentTarget.value)
|
||||||
|
rollDialog.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
import { Grammar } from "../grammar.js"
|
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_MODE_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 } from "./roll-part-comp.mjs"
|
||||||
import { RollPartSelect } from "./roll-part-select.mjs"
|
import { RollPartSelect } from "./roll-part-select.mjs"
|
||||||
@@ -17,7 +17,7 @@ export class RollPartJeu extends RollPartSelect {
|
|||||||
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
||||||
|
|
||||||
isValid(rollData) { return rollData.active.actor.isPersonnage() }
|
isValid(rollData) { return rollData.active.actor.isPersonnage() }
|
||||||
visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_JEU) }
|
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_JEU) }
|
||||||
|
|
||||||
loadRefs(rollData) {
|
loadRefs(rollData) {
|
||||||
const refs = this.getRefs(rollData)
|
const refs = this.getRefs(rollData)
|
||||||
@@ -68,8 +68,8 @@ export class RollPartJeu extends RollPartSelect {
|
|||||||
|
|
||||||
prepareContext(rollData) {
|
prepareContext(rollData) {
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
if (rollData.mode.current == ROLL_MODE_JEU && current) {
|
if (rollData.type.current == ROLL_TYPE_JEU && current) {
|
||||||
rollData.mode.opposed = true
|
rollData.type.opposed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,17 +86,16 @@ export class RollPartJeu extends RollPartSelect {
|
|||||||
const selectOptions = e.currentTarget.options
|
const selectOptions = e.currentTarget.options
|
||||||
const index = selectOptions.selectedIndex
|
const index = selectOptions.selectedIndex
|
||||||
this.$selectJeu(rollDialog.rollData, selectOptions[index]?.value)
|
this.$selectJeu(rollDialog.rollData, selectOptions[index]?.value)
|
||||||
rollDialog.setModeTitle()
|
|
||||||
rollDialog.render()
|
rollDialog.render()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getExternalPartsFilter(partCode, rollData) {
|
impactOtherPart(part, rollData) {
|
||||||
if (this.visible(rollData)) {
|
if (this.visible(rollData)) {
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
switch (partCode) {
|
switch (part.code) {
|
||||||
case PART_CARAC: return p => current.caracs?.includes(Grammar.toLowerCaseNoAccent(p.key))
|
case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
|
||||||
case PART_COMP: return p => p.label == current.comp?.name
|
case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import { ITEM_TYPES } from "../constants.js"
|
import { ITEM_TYPES } from "../constants.js"
|
||||||
import { Grammar } from "../grammar.js"
|
import { Grammar } from "../grammar.js"
|
||||||
import { RdDCarac } from "../rdd-carac.js"
|
import { CARACS, RdDCarac } 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_MODE_MEDITATION } from "./roll-constants.mjs"
|
import { ROLL_TYPE_MEDITATION } 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"
|
||||||
import { RollPartSelect } from "./roll-part-select.mjs"
|
import { RollPartSelect } from "./roll-part-select.mjs"
|
||||||
@@ -11,26 +11,41 @@ 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.isRollMode(rollData, ROLL_MODE_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,
|
refs.meditations = rollData.active.actor.itemTypes[ITEM_TYPES.meditation]
|
||||||
{
|
.map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor))
|
||||||
meditations: rollData.active.actor.itemTypes[ITEM_TYPES.meditation]
|
|
||||||
.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 +63,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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,13 +81,18 @@ export class RollPartMeditation extends RollPartSelect {
|
|||||||
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"]`)
|
||||||
@@ -86,13 +101,9 @@ export class RollPartMeditation extends RollPartSelect {
|
|||||||
const index = selectOptions.selectedIndex
|
const index = selectOptions.selectedIndex
|
||||||
this.$selectMeditation(rollDialog.rollData, selectOptions[index]?.value)
|
this.$selectMeditation(rollDialog.rollData, selectOptions[index]?.value)
|
||||||
rollDialog.render()
|
rollDialog.render()
|
||||||
rollDialog.setModeTitle()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
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) {
|
||||||
@@ -104,12 +115,12 @@ export class RollPartMeditation extends RollPartSelect {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getExternalPartsFilter(partCode, rollData) {
|
impactOtherPart(part, rollData) {
|
||||||
if (this.visible(rollData)) {
|
if (this.visible(rollData)) {
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
switch (partCode) {
|
switch (part.code) {
|
||||||
case PART_CARAC: return p => RdDCarac.isIntellect(p.key)
|
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.INTELLECT])
|
||||||
case PART_COMP: return p => p.label == current.comp?.name
|
case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import { ITEM_TYPES } from "../constants.js"
|
import { ITEM_TYPES } from "../constants.js"
|
||||||
import { Grammar } from "../grammar.js"
|
|
||||||
import { Misc } from "../misc.js"
|
import { Misc } from "../misc.js"
|
||||||
import { CARACS } from "../rdd-carac.js"
|
import { CARACS } from "../rdd-carac.js"
|
||||||
import { ROLL_MODE_OEUVRE } from "./roll-constants.mjs"
|
import { ROLL_TYPE_OEUVRE } 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"
|
||||||
import { RollPartSelect } from "./roll-part-select.mjs"
|
import { RollPartSelect } from "./roll-part-select.mjs"
|
||||||
@@ -12,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 => {
|
||||||
@@ -21,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 {
|
||||||
@@ -38,20 +36,20 @@ export class RollPartOeuvre extends RollPartSelect {
|
|||||||
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
||||||
|
|
||||||
isValid(rollData) { return rollData.active.actor.isPersonnage() }
|
isValid(rollData) { return rollData.active.actor.isPersonnage() }
|
||||||
visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_OEUVRE) }
|
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_OEUVRE) }
|
||||||
|
|
||||||
loadRefs(rollData) {
|
loadRefs(rollData) {
|
||||||
const refs = this.getRefs(rollData)
|
const refs = this.getRefs(rollData)
|
||||||
refs.oeuvres = rollData.active.actor.items
|
refs.oeuvres = rollData.active.actor.items
|
||||||
.filter(it => it.isOeuvre() && RollPartOeuvre.getArt(it))
|
.filter(it => it.isOeuvre() && RollPartOeuvre.getArt(it))
|
||||||
.map(it => RollPartOeuvre.$extractOeuvre(it, rollData.active.actor))
|
.map(it => RollPartOeuvre.$extractOeuvre(it, rollData.active.actor))
|
||||||
if (refs.oeuvres.length > 0) {
|
if (refs.oeuvres.length > 0) {
|
||||||
this.$selectOeuvre(rollData)
|
this.$selectOeuvre(rollData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
choices(refs) { return refs.oeuvres }
|
choices(refs) { return refs.oeuvres }
|
||||||
|
|
||||||
static $extractOeuvre(oeuvre, actor) {
|
static $extractOeuvre(oeuvre, actor) {
|
||||||
const art = RollPartOeuvre.getArt(oeuvre)
|
const art = RollPartOeuvre.getArt(oeuvre)
|
||||||
return {
|
return {
|
||||||
@@ -59,12 +57,13 @@ export class RollPartOeuvre extends RollPartSelect {
|
|||||||
label: oeuvre.name,
|
label: oeuvre.name,
|
||||||
art: art,
|
art: art,
|
||||||
caracs: art.caracs(oeuvre),
|
caracs: art.caracs(oeuvre),
|
||||||
|
qualite: oeuvre.system.niveau,
|
||||||
value: -oeuvre.system.niveau,
|
value: -oeuvre.system.niveau,
|
||||||
oeuvre: oeuvre,
|
oeuvre: oeuvre,
|
||||||
comp: actor.getCompetence(art.competence(oeuvre))
|
comp: actor.getCompetence(art.competence(oeuvre))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getArt(oeuvre) {
|
static getArt(oeuvre) {
|
||||||
return ARTS.find(it => it.type == oeuvre.type)
|
return ARTS.find(it => it.type == oeuvre.type)
|
||||||
}
|
}
|
||||||
@@ -80,17 +79,16 @@ export class RollPartOeuvre extends RollPartSelect {
|
|||||||
const selectOptions = e.currentTarget.options
|
const selectOptions = e.currentTarget.options
|
||||||
const index = selectOptions.selectedIndex
|
const index = selectOptions.selectedIndex
|
||||||
this.$selectOeuvre(rollDialog.rollData, selectOptions[index]?.value)
|
this.$selectOeuvre(rollDialog.rollData, selectOptions[index]?.value)
|
||||||
rollDialog.setModeTitle()
|
|
||||||
rollDialog.render()
|
rollDialog.render()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getExternalPartsFilter(partCode, rollData) {
|
impactOtherPart(part, rollData) {
|
||||||
if (this.visible(rollData)) {
|
if (this.visible(rollData)) {
|
||||||
const current = this.getCurrent(rollData)
|
const current = this.getCurrent(rollData)
|
||||||
switch (partCode) {
|
switch (part.code) {
|
||||||
case PART_CARAC: return p => current.caracs?.includes(Grammar.toLowerCaseNoAccent(p.key))
|
case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
|
||||||
case PART_COMP: return p => p.label == current.comp?.name
|
case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
|
@@ -7,6 +7,6 @@ export class RollPartOpponent extends RollPart {
|
|||||||
get code() { return OPPONENT }
|
get code() { return OPPONENT }
|
||||||
get section() { return ROLLDIALOG_SECTION.ACTION }
|
get section() { return ROLLDIALOG_SECTION.ACTION }
|
||||||
|
|
||||||
visible(rollData) { return rollData.mode.opposed }
|
visible(rollData) { return rollData.type.opposed }
|
||||||
title(rollData) { return rollData.opponent?.name ?? '' }
|
title(rollData) { return rollData.opponent?.name ?? '' }
|
||||||
}
|
}
|
||||||
|