Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82f870db05 | ||
|
|
878efab321 | ||
|
|
659ddbd0a4 | ||
|
|
22b9e11021 | ||
|
|
02ec8880fc | ||
|
|
521cf50b7b | ||
|
|
1cc6fab3a9 | ||
|
|
7baccbabb9 | ||
|
|
d9b24b0f97 | ||
|
|
d504a0e131 | ||
|
|
09ca86a7fd | ||
|
|
5b68837023 | ||
|
|
7452c54c04 | ||
|
|
af1976b9d8 | ||
|
|
9fe45ce99f | ||
|
|
852964e77b | ||
|
|
b87dea1661 | ||
|
|
d2835c7472 | ||
|
|
f3c58424e5 | ||
|
|
c600eb3965 | ||
|
|
4a7848cb04 | ||
|
|
0d62b60e38 | ||
|
|
9b91850731 | ||
|
|
05c7a91f93 | ||
|
|
f83fdb3b8f | ||
|
|
020ff4b014 | ||
|
|
b3c7453823 | ||
|
|
18d003aa5d | ||
|
|
0b90badb5e | ||
|
|
290b5029d1 | ||
|
|
a7e4aea52d | ||
|
|
755d15509e | ||
|
|
02cea84ebb | ||
|
|
c47fc4f5b6 | ||
|
|
147e49f2cb | ||
|
|
7f4f942d50 | ||
|
|
8f4df1af56 | ||
|
|
77f2de2c5f | ||
|
|
e5e271e424 | ||
|
|
43ecca8be1 | ||
|
|
e21f7e398a | ||
|
|
e16f89743a | ||
|
|
a6c593c100 | ||
|
|
cd8e190082 | ||
|
|
f2106763c1 | ||
|
|
5da5cb0314 | ||
|
|
6d7f66569a | ||
|
|
3e8963b20b | ||
|
|
2cf5b06da8 | ||
|
|
68c01fc930 | ||
|
|
3bc1c4871b | ||
|
|
3d732e9a8a | ||
|
|
35f226af5c | ||
|
|
126a0701d8 | ||
|
|
edf920b340 | ||
|
|
293af5ab83 | ||
|
|
1bf9e330f4 | ||
|
|
33dc58138c | ||
|
|
fa6769fcd7 | ||
|
|
47c4478303 | ||
|
|
52065fd6f6 | ||
|
|
6886f19921 | ||
|
|
10a89cc268 | ||
|
|
6a987086f8 | ||
|
|
54f470d531 | ||
|
|
37af0dd4f1 | ||
|
|
d46b039a63 | ||
|
|
7370b633db | ||
|
|
d0ba1ebf99 | ||
|
|
053bc23d12 | ||
|
|
1360992daa | ||
|
|
878645491d | ||
|
|
edfaf203f7 | ||
|
|
3480b64d75 | ||
|
|
17e10d3be9 | ||
|
|
bbcd6ad363 | ||
|
|
faca73b0a1 | ||
|
|
a7e14736e4 | ||
|
|
2741fc3fbf | ||
|
|
160f10a639 | ||
|
|
d26ab59c51 | ||
|
|
1f330c734e | ||
|
|
74515d28f4 | ||
|
|
c84af21c7e | ||
|
|
0730bdf240 | ||
|
|
607eedc6d2 |
@@ -6,71 +6,70 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: localhost
|
||||
steps:
|
||||
- run: echo "💡 The ${{ gitea.repository }} repository will cloned to the runner."
|
||||
- run: echo "💡 The ${{ gitea.repository }} repository will cloned to the runner."
|
||||
|
||||
#- uses: actions/checkout@v3
|
||||
- uses: RouxAntoine/checkout@v3.5.4
|
||||
with:
|
||||
ref: 'v13'
|
||||
- name: Add NODE/NPM bin directory to PATH
|
||||
shell: bash
|
||||
run: echo "/opt/alt/alt-nodejs20/root/usr/bin/" >> $GITHUB_PATH
|
||||
|
||||
# get part of the tag after the `v`
|
||||
- name: Extract tag version number
|
||||
id: get_version
|
||||
uses: battila7/get-version-action@v2
|
||||
- uses: RouxAntoine/checkout@v3.5.4
|
||||
with:
|
||||
ref: "v13"
|
||||
|
||||
# Substitute the Manifest and Download URLs in the module.json
|
||||
- name: Substitute Manifest and Download Links For Versioned Ones
|
||||
id: sub_manifest_link_version
|
||||
uses: microsoft/variable-substitution@v1
|
||||
with:
|
||||
files: 'system.json'
|
||||
env:
|
||||
version: ${{steps.get_version.outputs.version-without-v}}
|
||||
url: https://www.uberwald.me/gitea/${{gitea.repository}}
|
||||
manifest: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/system.json
|
||||
download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/rddsystem.zip
|
||||
# get part of the tag after the `v`
|
||||
- name: Extract tag version number
|
||||
id: get_version
|
||||
uses: battila7/get-version-action@v2
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '18' # Use the node version your project requires
|
||||
# Substitute the Manifest and Download URLs in the module.json
|
||||
- name: Substitute Manifest and Download Links For Versioned Ones
|
||||
id: sub_manifest_link_version
|
||||
uses: microsoft/variable-substitution@v1
|
||||
with:
|
||||
files: "system.json"
|
||||
env:
|
||||
version: ${{steps.get_version.outputs.version-without-v}}
|
||||
url: https://gitea.scriptarium.org/${{gitea.repository}}
|
||||
manifest: https://gitea.scriptarium.org/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/system.json
|
||||
download: https://gitea.scriptarium.org/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/rddsystem.zip
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: "18" # Use the node version your project requires
|
||||
|
||||
- name: Build the compendiums
|
||||
run: node ./tools/packCompendiumsToDist.mjs
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
# Create a zip file with all files required by the module to add to the release
|
||||
- run: |
|
||||
apt update -y
|
||||
apt install -y zip
|
||||
- name: Build the compendiums
|
||||
run: node ./tools/packCompendiumsToDist.mjs
|
||||
|
||||
- run: zip -r ./rddsystem.zip system.json template.json README.md LICENSE.txt assets/ css/ fonts/ icons lang/ module/ packs/ pic/ sounds/ styles/ templates/
|
||||
- name: Create ZIP file
|
||||
run: zip -r ./rddsystem.zip system.json template.json README.md LICENSE.txt assets/ css/ fonts/ icons lang/ module/ packs/ pic/ sounds/ styles/ templates/
|
||||
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '>=1.20.1'
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ">=1.20.1"
|
||||
|
||||
- name: Use Go Action
|
||||
id: use-go-action
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: |-
|
||||
./rddsystem.zip
|
||||
system.json
|
||||
api_key: '${{secrets.ALLOW_PUSH_RELEASE}}'
|
||||
- name: Use Go Action
|
||||
id: use-go-action
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: |-
|
||||
./rddsystem.zip
|
||||
system.json
|
||||
api_key: "${{secrets.RDD_PUBLISH_RELEASE}}"
|
||||
|
||||
- name: Publish to Foundry server
|
||||
uses: djlechuck/foundryvtt-publish-package-action@v1
|
||||
with:
|
||||
token: ${{ secrets.FOUNDRYVTT_RELEASE_TOKEN }}
|
||||
id: 'foundryvtt-reve-de-dragon'
|
||||
version: ${{github.event.release.tag_name}}
|
||||
manifest: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/system.json'
|
||||
notes: 'https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v13/changelog.md'
|
||||
compatibility-minimum: '13'
|
||||
compatibility-verified: '13'
|
||||
- name: Publish to Foundry server
|
||||
uses: djlechuck/foundryvtt-publish-package-action@v1
|
||||
with:
|
||||
token: ${{ secrets.RDD_PUBLISH_RELEASE_FOUNDRY }}
|
||||
id: "foundryvtt-reve-de-dragon"
|
||||
version: ${{github.event.release.tag_name}}
|
||||
manifest: "https://gitea.scriptarium.org/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/system.json"
|
||||
notes: "https://gitea.scriptarium.org/Scriptarium/foundryvtt-reve-de-dragon/raw/branch/v13/changelog.md"
|
||||
compatibility-minimum: "13"
|
||||
compatibility-verified: "13"
|
||||
|
||||
@@ -12,8 +12,8 @@ Pseudo : LeRatierBretonnien
|
||||
|
||||
Mainteneur/Développeur : LeRatierBretonnien
|
||||
Développeur : VincentVk
|
||||
Tests, Compendiums, Données: Fred, Fab, Grendel
|
||||
Styles/CSS : Mandar
|
||||
Tests, Compendiums, Données: Fred, Fab, Grendel, LeRatierBretonnien, VincentVk
|
||||
Styles/CSS : Mandar, VincentVk
|
||||
|
||||
# Mentions Légales
|
||||
|
||||
@@ -23,6 +23,9 @@ 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.
|
||||
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.
|
||||
|
||||
# Licences
|
||||
- L'export pdf utilise la librairie [pdf-lib](https://pdf-lib.js.org/) sous licence [MIT](pdf-lib-LICENSE.md)
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><defs><linearGradient x1="0" x2="1" y1="1" y2="0" id="lorc-shattered-sword-gradient-4"><stop offset="0%" stop-color="#4a4a4a" stop-opacity="1"></stop><stop offset="100%" stop-color="#c9c9c9" stop-opacity="1"></stop></linearGradient><radialGradient id="lorc-shattered-sword-gradient-5"><stop offset="0%" stop-color="#9013fe" stop-opacity="1"></stop><stop offset="100%" stop-color="#85562c" stop-opacity="1"></stop></radialGradient><radialGradient id="lorc-shattered-sword-gradient-7"><stop offset="0%" stop-color="#9013fe" stop-opacity="1"></stop><stop offset="100%" stop-color="#85562c" stop-opacity="1"></stop></radialGradient></defs><g class="" transform="translate(1,-2)" style=""><path d="m496.223 16.818-48.475 44.205 48.475 4.575v-48.78zm-41.55 1.22-68.91 11.28-7.04 65.547 75.95-76.828zM352.26 77.907l-87.887 50.3 15.447 41.026 82.662-16.87-10.222-74.456zm64.34 25.022-32.967 67.443 24.842 70.684 54.314-134.19-46.19-3.937zm-271.362 72.808c-10.02.155-20.714 3.165-30.79 9.057 4.143 8.863 3.382 18.708-2.776 24.873-6.158 6.165-15.993 6.927-24.846 2.78-12.923 22.167-11.88 47.34 2.485 61.73l29.84-29.87c58.655 42.87 109.37 92.94 150.57 151.24l-36.19 36.23 6.61-6.604c14.283 14.298 39.192 15.42 61.23 2.732-4.88-9.197-4.366-19.74 2.107-26.22 6.47-6.478 17-6.993 26.185-2.112 12.66-22.062 11.54-47-2.732-61.3l-28.248 28.28c-57.035-42.41-107.91-92.665-151.426-150.386l35.455-35.492-6.61 6.603c-7.834-7.843-18.863-11.726-30.862-11.542zm108.45 4.512c-17.61 17.41-39.674 39.21-62.22 61.375a728.952 728.952 0 0 0 27.407 30.094l59.063-59.126-24.25-32.344zm78.28 32.688L297 219.968l-65 65.063a728.12 728.12 0 0 0 35 32.376c22.02-23.134 43.764-46.41 64.97-69.406v-35.063zM173.47 313.25c-31.146 40.858-67.877 74.323-108.905 101.875 4.13 13.708 16.394 26.374 30.624 30.563 29.466-41.26 61.113-79.902 100.97-109.97a637.777 637.777 0 0 0-22.688-22.468zM44.5 410.28l-20.844 20.845c7.133 24.65 27.843 44.912 53.72 53.438l19.28-19.313c-26.948-4.28-48.314-26.91-51.875-52.938l-.28-2.03z" fill="#fff" fill-opacity="1" transform="translate(51.2, 51.2) scale(0.8, 0.8) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,0)" style=""><path d="m329.5 29.12-8.1 11.4L359 67.16l8.1-11.44zm-88 5.04 24.2 45.36 1.8 1.29 14.8-40.36zm57.6 12.63-16.4 44.8 40.7 28.81 35.3-31.54c-.9-.58-1.9-1.19-2.8-1.84zM59.83 48.56l10.84 45.83 29.63 2.6 2.7-29.63zM470.9 75.41c-5.6 4.71-12.2 8.59-19.5 11.74 5 46.45-14.7 83.45-45.2 109.75-26.5 22.9-60.9 38.4-95 47.9-2.5 4.8-5 9.2-7.4 13.1 41.5 5.4 93.2-21.2 129.2-60 19.8-21.3 34.8-45.9 41.1-69.2 5.2-19.4 4.7-37.42-3.2-53.29zm-351.3 8.71-3 32.48-32.35-2.9 226.55 271 20-16.7 15.3-12.8zM434 93.09c-4.2 1-8.5 2-12.8 2.7-14.9 2.5-30.1 3.1-43.5.3l-41 36.61c4 7 5 15.7 4.5 24.5-.6 12.6-4.3 26.7-9.3 40.9-3 8.3-6.3 16.6-9.9 24.6 26.9-9.2 52.6-22.3 72.5-39.4 26.2-22.8 42.5-51.6 39.5-90.21zM274 107.4l-51.2 72.2 30.6 36.5 58.2-82.1zM173.8 248.8 34.53 445.2l37.53 26.6L204.3 285.3zm233 79.2L273.3 439.5l19.2 23.1L426 351zm-18.3 77.9-35.3 29.4 39.7 47.6 35.3-29.4z" fill="#fff" fill-opacity="1"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -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 |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,0)" style=""><path d="M243.512 23.29c-27.105 18.337-53.533 32.92-82.274 45.337-2.843 17.364-3.948 34.497-4.05 51.584 28.913 15.41 56.096 32.85 83.33 49.634l7.045 4.344-3.432 7.482c-12.12 26.572-24.33 47.087-46.245 70.3l-5.184 5.512-6.46-3.904c-32.974-19.974-74.472-38.724-113.373-53.95l6.826-17.374c36.79 14.4 75.11 32.32 108.153 51.504 15.396-17.198 25.326-33.354 34.713-52.89-43.44-26.91-86.13-53.51-134.69-70.632-23.012 20.357-37.705 45.243-51.942 70.74 8.324 25.495 6.596 53.376-6.596 77.46 48.58-.593 97.994 2.23 150.666 10.26l5.658.837 1.787 5.44c8.85 26.46 11.79 54.41 8.325 83.588l-.987 8.432-8.466-.187c-40.508-.864-80.175-2.138-118.17.234 1.634 15.94-2.31 30.972-7.724 45.025 13.427 28.54 27.38 55.8 48.29 79.39 41.27-19.05 73.564-31.288 115.93-42.85-3.407-13.72-6.918-26.36-11.097-33.62-5.122-8.9-10.207-13.057-17.85-15.256-15.284-4.4-44.533 2.293-92.894 19.454l-6.243-17.594c48.907-17.354 79.702-26.894 104.283-19.82 9.133 2.628 16.884 8.004 23.066 15.46 14.487-7.627 28.415-16.79 42.053-26.996 12.34-45.92 37.29-81.42 66.626-112.107-7.226-13.52-13.208-27.204-20.563-40.613l-3.394-6.168 5-4.965c23.275-23.13 47.34-40.157 71.87-52.487l8.395 16.716c-20.952 10.53-41.503 25.913-61.795 45.152 12.41 23.91 22.263 45.5 39.457 64.826 37.488-27.124 74.943-51.39 116.84-74.938-13.96-30.473-31.345-58.357-56.286-79.462-32.2 13.38-62.527 17.39-92.61 12.29-14.223 13.25-30.094 22.23-48.756 23.337-29.017 1.722-60.74-15.74-99.174-57.672l6.858-6.295.017-.028.006.006 6.88-6.314c36.702 40.043 63.74 52.87 84.32 51.65 18.514-1.1 35.03-14.95 51.684-35.406-28.827-31.81-64.174-59.94-97.822-84.465zM39.324 277.884c-6.06.022-12.104.098-18.142.223 1.673 26.288 5.512 51.288 14.052 73.732 45.88-5.82 93.308-4.96 141.15-3.87 1.518-21.27-.253-41.69-6.058-61.212-45.528-6.565-88.59-9.03-131.002-8.873z" fill="#fff" fill-opacity="1"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -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 |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><defs><linearGradient x1="0" x2="1" y1="1" y2="0" id="delapouite-sparkles-gradient-4"><stop offset="0%" stop-color="#4a4a4a" stop-opacity="1"></stop><stop offset="100%" stop-color="#c9c9c9" stop-opacity="1"></stop></linearGradient><radialGradient id="delapouite-sparkles-gradient-5"><stop offset="0%" stop-color="#9013fe" stop-opacity="1"></stop><stop offset="100%" stop-color="#85562c" stop-opacity="1"></stop></radialGradient><radialGradient id="delapouite-sparkles-gradient-7"><stop offset="0%" stop-color="#9013fe" stop-opacity="1"></stop><stop offset="100%" stop-color="#85562c" stop-opacity="1"></stop></radialGradient></defs><g class="" transform="translate(1,-2)" style=""><path d="M237.4 20.73c-6.1 42.1-26.8 64.2-63.9 64 31.6 4.5 63.8 8 63.9 64.07-.6-46.1 24.5-63.07 64.1-64.07-38-1.5-64.9-16.3-64.1-64zm127.8 11.58c-9.1 14.25-20.8 21.29-38.9 10.28 14.9 11.79 18.6 24.76 10.2 38.97 8.9-11.18 17.5-22.73 39-10.27-17.8-10.06-18.8-23.57-10.3-38.98zM59.68 41.69c-2.7 18.8-12 28.6-28.5 28.5 14.1 2 28.4 3.6 28.5 28.52-.3-20.5 10.9-28.12 28.5-28.52-16.9-.7-28.9-7.3-28.5-28.5zM431 66.28c-2.7 18.8-12 28.6-28.5 28.5 14.1 2 28.4 3.6 28.5 28.52-.3-20.5 10.9-28.12 28.5-28.52-16.9-.7-28.9-7.3-28.5-28.5zM120.3 116.4c-15.8 53.7-47.76 48-79.35 43.4C76.6 170 90.3 197.1 84.28 239.2c12.66-46 42.62-52.6 79.42-43.4-37.6-12.1-56.9-35.4-43.4-79.4zm187 5c-8.8 61.6-39.3 94-93.6 93.7 46.2 6.5 93.6 11.7 93.6 93.7-.8-67.3 35.9-92.2 93.8-93.7-55.5-2.2-94.9-23.9-93.8-93.7zm136.8 38.3c-13.1 21.6-29.5 28.8-49.7 20.1 16.3 9.7 33 19.1 20.1 49.6 10.3-25.2 27.9-28.7 49.7-20-20.3-9.7-31.6-23.9-20.1-49.7zM50.7 243.2c9.16 16.7 7.63 30.1-5.61 40 12.46-6.9 24.85-14.3 39.91 5.6-12.57-16.2-8.2-29 5.61-40-13.92 9.7-27.47 11.6-39.91-5.6zm137.2.3c11.4 26.8-.5 41.3-21.7 50.9 22.7-8.5 40.8-4.5 50.9 21.7-12.7-31.8 4.8-41.2 21.7-50.9-21 8.5-37.8.9-50.9-21.7zm228 12.6c-26.6 64.7-68.7 91.7-127.8 76.4 48.6 19.8 98.8 38.5 76.4 127.9 17.5-73.7 64.4-90.7 127.9-76.5-59.9-17.5-96.9-52-76.5-127.8zM99.94 295.5c15.66 57.8.86 98.1-47.32 118.5 43.46-11.8 87.38-25.2 118.68 47.4-26.4-59.3-3.4-95.4 47.3-118.8-50 19.2-93.1 15-118.66-47.1zm169.36 61c-21.8 20.6-43 23.6-63.2 7.3 15.5 16.3 31.6 32.4 7.2 63.3 19.8-25.6 41.2-24.1 63.3-7.3-20.2-17.4-28.6-37.5-7.3-63.3zM443.2 404c-2.7 18.8-12 28.6-28.5 28.5 14.1 2 28.4 3.6 28.5 28.5-.3-20.5 10.9-28.1 28.5-28.5-16.9-.7-28.9-7.3-28.5-28.5zm-169.7 36c-2.7 18.8-12 28.6-28.5 28.5 14.1 2 28.4 3.6 28.5 28.5-.3-20.5 10.9-28.1 28.5-28.5-16.9-.7-28.9-7.3-28.5-28.5z" fill="#fff" transform="translate(51.2, 51.2) scale(0.8, 0.8) rotate(0, 256, 256) skewX(0) skewY(0)" fill-opacity="1"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 448 434"
|
||||
version="1.1"
|
||||
id="svg6"
|
||||
sodipodi:docname="surenc.svg"
|
||||
width="448"
|
||||
height="434"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2054"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="1.4355469"
|
||||
inkscape:cx="224"
|
||||
inkscape:cy="210"
|
||||
inkscape:window-x="-11"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg6" />
|
||||
<g
|
||||
class=""
|
||||
id="g4"
|
||||
transform="translate(-32,-46)">
|
||||
<path
|
||||
d="m 256,46 c -45.074,0 -82,36.926 -82,82 0,25.812 12.123,48.936 30.938,64 H 128 L 32,480 H 480 L 384,192 H 307.062 C 325.877,176.936 338,153.812 338,128 338,82.926 301.074,46 256,46 Z m 0,36 c 25.618,0 46,20.382 46,46 0,25.618 -20.382,46 -46,46 -25.618,0 -46,-20.382 -46,-46 0,-25.618 20.382,-46 46,-46 z m -82.215,202.95 h 23.5 v 33.263 l 33.873,-33.264 h 27.283 l -43.883,43.15 48.4,47.974 H 233.54 l -36.255,-35.888 v 35.888 h -23.5 z m 119.934,21.24 c 4.76,0 8.952,0.934 12.573,2.806 3.62,1.872 6.938,4.82 9.95,8.85 v -10.13 h 21.972 v 61.462 c 0,10.986 -3.48,19.368 -10.438,25.146 -6.917,5.82 -16.968,8.727 -30.152,8.727 -4.272,0 -8.4,-0.325 -12.39,-0.976 a 77.367,77.367 0 0 1 -12.024,-2.99 v -17.03 c 3.826,2.198 7.57,3.826 11.23,4.884 3.664,1.098 7.347,1.648 11.05,1.648 7.162,0 12.41,-1.566 15.746,-4.7 3.337,-3.132 5.006,-8.035 5.006,-14.708 v -4.7 c -3.01,3.986 -6.328,6.916 -9.95,8.788 -3.62,1.87 -7.813,2.808 -12.573,2.808 -8.343,0 -15.238,-3.275 -20.69,-9.826 -5.453,-6.592 -8.18,-14.974 -8.18,-25.146 0,-10.214 2.727,-18.576 8.18,-25.086 5.452,-6.55 12.347,-9.827 20.69,-9.827 z m 8.118,15.746 c -4.517,0 -8.038,1.67 -10.56,5.005 -2.523,3.338 -3.784,8.058 -3.784,14.162 0,6.266 1.22,11.026 3.662,14.28 2.442,3.215 6.003,4.823 10.682,4.823 4.557,0 8.096,-1.67 10.62,-5.006 2.522,-3.337 3.784,-8.036 3.784,-14.098 0,-6.104 -1.262,-10.824 -3.785,-14.16 -2.523,-3.337 -6.062,-5.006 -10.62,-5.006 z"
|
||||
fill="#ffffff"
|
||||
fill-opacity="1"
|
||||
id="path2" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 256px; width: 256px;"><g class="" transform="translate(0,0)" style=""><path d="M221.313 16a23.682 23.695 0 0 0-23.688 23.688v106.406a23.682 23.695 0 0 0 2.156 9.72 23.682 23.695 0 0 0 3.157 13.81l41.75 71.626-79 55.438 6.094-48.625a23.682 23.695 0 0 0-8.186-20.97l-66.28-81.937a23.682 23.695 0 0 0-33.314-3.5l-9.188 7.438a23.682 23.695 0 0 0-3.53 33.344l59.78 73.906-11.25 89.937a23.682 23.695 0 0 0 12.47 23.876l37.468 53.47a23.695 23.682 1.57 0 0 2.344 2.812 23.682 23.695 0 0 0 13.594 20.062L262 491.53a23.682 23.695 0 0 0 9.97 2.22 23.682 23.695 0 0 0 23.53-2.063l87.156-60.937a23.682 23.695 0 0 0 5.844-33l-6.78-9.688a23.682 23.695 0 0 0-32.97-5.875l-72.406 50.657-59.063-27.625 120.595-84.626a23.695 23.682 1.57 0 0 5.53-5.5 23.682 23.695 0 0 0 14.626-13.594l37.22-91.53 87.813-44.845a23.694 23.682 1.18 0 0 10.312-31.875L488 122.687a23.694 23.682 1.18 0 0-31.875-10.343l-94.688 48.375a23.694 23.682 1.18 0 0-9.843 9.436 23.682 23.695 0 0 0-8.344 10.47l-27.375 67.31-5.22-7.436a23.682 23.695 0 0 0-3-8.844l-50.81-87.094V39.688A23.682 23.695 0 0 0 233.154 16h-11.843zM77.75 376A59.994 60 0 0 0 16 436a59.994 60 0 1 0 120 0 59.994 60 0 0 0-58.25-60z" fill="#fff" fill-opacity="1"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -0,0 +1,110 @@
|
||||
<?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 378.00079 384.97681"
|
||||
version="1.1"
|
||||
id="svg23"
|
||||
sodipodi:docname="resistance.svg"
|
||||
width="378.00079"
|
||||
height="384.97681"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
|
||||
<metadata
|
||||
id="metadata27">
|
||||
<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="1875"
|
||||
inkscape:window-height="1352"
|
||||
id="namedview25"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="1.4355469"
|
||||
inkscape:cx="186.7504"
|
||||
inkscape:cy="196.1768"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg23" />
|
||||
<defs
|
||||
id="defs17">
|
||||
<linearGradient
|
||||
x1="0"
|
||||
x2="1"
|
||||
y1="1"
|
||||
y2="0"
|
||||
id="lorc-aura-gradient-4">
|
||||
<stop
|
||||
offset="0%"
|
||||
stop-color="#4a4a4a"
|
||||
stop-opacity="1"
|
||||
id="stop2" />
|
||||
<stop
|
||||
offset="100%"
|
||||
stop-color="#c9c9c9"
|
||||
stop-opacity="1"
|
||||
id="stop4" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="lorc-aura-gradient-5">
|
||||
<stop
|
||||
offset="0%"
|
||||
stop-color="#9013fe"
|
||||
stop-opacity="1"
|
||||
id="stop7" />
|
||||
<stop
|
||||
offset="100%"
|
||||
stop-color="#85562c"
|
||||
stop-opacity="1"
|
||||
id="stop9" />
|
||||
</radialGradient>
|
||||
<radialGradient
|
||||
id="lorc-aura-gradient-7">
|
||||
<stop
|
||||
offset="0%"
|
||||
stop-color="#9013fe"
|
||||
stop-opacity="1"
|
||||
id="stop12" />
|
||||
<stop
|
||||
offset="100%"
|
||||
stop-color="#85562c"
|
||||
stop-opacity="1"
|
||||
id="stop14" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g
|
||||
class=""
|
||||
transform="translate(-68.2496,-61.8232)"
|
||||
id="g21">
|
||||
<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="#ffffff"
|
||||
fill-opacity="1"
|
||||
transform="matrix(0.8,0,0,0.8,51.2,51.2)"
|
||||
id="path19" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
@@ -1,5 +1,156 @@
|
||||
# 13.0
|
||||
|
||||
## 13.0.19 - L'introspection d'Illysis
|
||||
|
||||
- Ajout d'un bouton pour les jets de résistance sous rêve actuel
|
||||
- Fenêtre de jet v2
|
||||
- restrictions au propriétaire du personnage
|
||||
- ouverture de la fenêtre de jets
|
||||
- appel à la chance
|
||||
- appel à la destinée
|
||||
- fermeture par défaut selon le type de jets:
|
||||
- jets d'attaque
|
||||
- jets de défense
|
||||
- jets imposés par un choix d'action
|
||||
- lancer de sorts
|
||||
- jets suite à appel à la chance
|
||||
- gestion des écailles d'efficacité sur les armes
|
||||
- permettre de faire une attaque même si l'initiative n'est pas faite
|
||||
- les messages de défense s'affichent correctement avec plusieurs joueurs
|
||||
- les particulières en force/rapidité sont correctement affichées dans le tchat
|
||||
- l'expérience sur jet de résistance est limitée à 1 point
|
||||
|
||||
## 13.0.18 - Le reflet d'Illysis
|
||||
|
||||
- Mise à jour de la feuille de personnage pdf template (avec police correcte)
|
||||
- Ajout d'une icône "écurie" pour les services des commerces & auberges
|
||||
- Suppression de message d'erreur sur compétence
|
||||
manquante à l'ouverture des acteurs d'invocation
|
||||
|
||||
## 13.0.17 - Le chant d'Illysis
|
||||
|
||||
- Corrections CSS
|
||||
- Migration Uberwald -> Scriptarium
|
||||
|
||||
## 13.0.16 - La paix d'Illysis
|
||||
|
||||
- Export de personnages sous forme de feuille de personnage pdf
|
||||
- Correction d'un problème à l'ouverture de personnages saisis dans d'anciennes versions
|
||||
- Fenêtre de jet v2
|
||||
- on peut faire des jets en dehors des combats
|
||||
|
||||
## 13.0.15 - Les pièces d'Illysis
|
||||
|
||||
- On peut de nouveau acheter dans les commerces
|
||||
- Corrections V13
|
||||
- Les textes sur fond "parchemin" ne sont plus affichés en blanc
|
||||
|
||||
## 13.0.14 - Le familier d'Illysis
|
||||
|
||||
- Les réussites particulières en demi-surprise sont de simples réussites
|
||||
- Les images des scènes par défaut sont corrigées
|
||||
- Ajout d'une image de status "sur-encombré"
|
||||
- Correction V13
|
||||
- couleur lisible dans les sommaires des journaux et des compendiums
|
||||
- Amélioration des entités:
|
||||
- l'attaquant ne sait plus que c'est une entité de cauchemar (surprise!)
|
||||
- l'encaissement indique une blessure dans le tchat... même si ce n'est que de l'endurance
|
||||
- les blurettes suivent les règles des entités de cauchemar (p322)
|
||||
- Nouvelle fenêtre de jets de dés
|
||||
- attaque/défense des créatures
|
||||
- les attaques/parades avec une arme trop lourde se font en demi-surprise
|
||||
- les demandes de défense disparaîssent une fois prises en compte
|
||||
- empoignade
|
||||
- l'empoignade est possible avec une initiative d'empoignade, ou en cours d'empoignade
|
||||
- seule la dague, le pugilat et la dague sont possibles en cours d'empoignade
|
||||
- jet de Dextérité/Dague pour utiliser la dague en cours d'empoignade (p136)
|
||||
- attaquer avec une arme un empoigneur donne un +4 si pas d'empoignade (p134)
|
||||
- la différence de taille donne un bonus/malus en cours d'empoignade (p135)
|
||||
- les dommages de l'empoignade ajoutent/enlèvent un point d'empoignade
|
||||
- le statut d'empoignade est affiché sur les tokens
|
||||
- les défenses contre une empoignade sont corrigées
|
||||
|
||||
## 13.0.13 - L'épanouissement d'Illysis
|
||||
|
||||
- Fix d'erreur au chargement de templates RollDialog
|
||||
- Nouvelle fenêtre de jets de dés
|
||||
- Fix: affichage des points de tâche
|
||||
- Fix: affichage des ajustements cohérent
|
||||
- L'ouverture depuis les caractéristiques permet plusieurs types de jets
|
||||
- On peut créer ou modifier les tâches dans la fenêtre de jets de tâches
|
||||
- attaque/défense
|
||||
- les maladresses sont affichées dans le résultat du jet
|
||||
- le message au défenseur s'affiche correctement
|
||||
- la difficulté d'attaque s'applique à la défense
|
||||
- on peut choisir les particulières en rapidité
|
||||
|
||||
## 13.0.12 - La méditation d'Illysis
|
||||
|
||||
- les signes draconiques éphémères de 1 round sont supprimés à la descente des TMRs
|
||||
- Générateur de description
|
||||
- correction des termes pour les couleurs des yeux/cheveux
|
||||
- ajout de boutons pour forcer le sexe masculin/féminin
|
||||
- Nouvelle fenêtre de jets de dés
|
||||
- les méditations proposent un bouton pour monter dans les TMRs
|
||||
- fenêtre de lancer de sorts
|
||||
- Correction: les compétences de jeux ne remplacent plus les compétences en dehors des jets de jeu
|
||||
- gestion des maladresses d'attaque et défense
|
||||
|
||||
## 13.0.11 - Le gambit d'Illysis
|
||||
|
||||
- Nouvelle fenêtre de jets de dés
|
||||
- jeux
|
||||
- cuisine et préparation de nourriture
|
||||
|
||||
## 13.0.10 - Les papilles d'Illysis
|
||||
|
||||
- Ajout d'un statut "saignement" en cas de blessure grave ou critique sans premiers soins
|
||||
|
||||
- Nouvelle fenêtre de jets de dés
|
||||
- jets de méditation
|
||||
- jets de tâches
|
||||
- jets de caractéristiques
|
||||
- jets de compétences
|
||||
- Boutons d'initiative et d'attaque V2
|
||||
- fenêtre d'attaque
|
||||
- choix des armes
|
||||
- gestion des particulières
|
||||
- message au défenseur
|
||||
- gestion des demi-surprises (attaquant/défenseur)
|
||||
- gestion des tactiques (attaquant/défenseur)
|
||||
- en cours nouvelle fenêtre de jets
|
||||
- jets de compétence avec messages
|
||||
- jets de cuisine séparés avec messages (pour gérer plus tard les spécificités: fabricatioon de plats)
|
||||
- gestion des empoignades
|
||||
|
||||
- Technique: suppression de warnings foundry sur renderTemplate
|
||||
|
||||
## 13.0.9 - Le combat d'Illysis
|
||||
- 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
|
||||
|
||||
- Fix Foundry V13
|
||||
|
||||
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 8.3 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"TYPES": {
|
||||
"Actor": {
|
||||
"Actor": {
|
||||
"personnage": "Personnage",
|
||||
"creature": "Créature",
|
||||
"entite": "Entité de cauchemar",
|
||||
@@ -66,6 +66,8 @@
|
||||
"StatusRestrained": "Immobilisé",
|
||||
"StatusComma": "Comma",
|
||||
"StatusDead": "Mort",
|
||||
"StatusDemiReve": "Demi-rêve"
|
||||
"StatusDemiReve": "Demi-rêve",
|
||||
"StatusSurEnc": "Sur-encombrement",
|
||||
"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-violet: linear-gradient(150deg, rgba(100, 45, 124, 0.6), rgba(216, 157, 192, 0.3), rgba(177, 157, 216, 0.5), rgba(107, 62, 121, 0.3), rgba(100, 45, 124, 0.6));
|
||||
--gradient-purple-black: linear-gradient(150deg, rgba(0, 0, 0, 0.7), rgba(100, 45, 124, 0.4), rgba(82, 17, 131, 0.3),rgba(100, 45, 124, 0.4), rgba(0, 0, 0, 0.7));
|
||||
--gradient-warning: linear-gradient(150deg,
|
||||
hsla(32, 100%, 50%, 0.3),
|
||||
hsla(52, 60%, 50%, 0.1),
|
||||
hsla(32, 60%, 50%, 0.1),
|
||||
hsla(32, 100%, 50%, 0.3));
|
||||
--gradient-silver-light: linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2));
|
||||
--gradient-daylight: conic-gradient(
|
||||
from 0deg,
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
.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 {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
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:
|
||||
"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"
|
||||
"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;
|
||||
gap: 0.2rem;
|
||||
@@ -22,18 +22,18 @@
|
||||
roll-choix { grid-area: choix; }
|
||||
|
||||
roll-table { grid-area: resolution; }
|
||||
roll-conditions { grid-area: modifiers; }
|
||||
roll-conditions { grid-area: conditions; }
|
||||
roll-chances { grid-area: chances; }
|
||||
roll-resume { grid-area: resume; }
|
||||
roll-buttons { grid-area: buttons; }
|
||||
|
||||
roll-mode {
|
||||
grid-area: mode;
|
||||
roll-type {
|
||||
grid-area: type;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
roll-conditions roll-section[name="rollmode"],
|
||||
roll-mode {
|
||||
roll-type {
|
||||
button[data-checked="true"] {
|
||||
background-color: var(--color-text-selection-bg);
|
||||
color: var(--color-controls);
|
||||
@@ -83,16 +83,23 @@
|
||||
gap: 0.2rem;
|
||||
align-items: start;
|
||||
|
||||
|
||||
subline {
|
||||
grid-area: selection;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 0.1rem 0;
|
||||
.warning {
|
||||
border-radius: 0.5rem;
|
||||
background: var(--gradient-warning);
|
||||
}
|
||||
}
|
||||
|
||||
roll-part-img {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-area: img;
|
||||
img{
|
||||
img {
|
||||
border: 0;
|
||||
padding: 1px;
|
||||
max-height: 3rem;
|
||||
@@ -110,9 +117,22 @@
|
||||
subline {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 0.1rem 0;
|
||||
div.poesie-extrait{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: normal;
|
||||
}
|
||||
span.status-surprise{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-flow: wrap;
|
||||
img {
|
||||
filter: invert(0.8);
|
||||
}
|
||||
}
|
||||
label {
|
||||
align-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,8 +142,13 @@
|
||||
display: flow;
|
||||
width: 2.5rem;
|
||||
text-align: right;
|
||||
margin: 0 0.2rem 0 0.5rem;
|
||||
margin: 0 0.2rem;
|
||||
padding: 0 0.2rem;
|
||||
border: 1px solid ;
|
||||
border-radius: 0.2rem ;
|
||||
background: hsla(0, 0%, 0%, 0.2);
|
||||
height: 1.5rem;
|
||||
background: hsla(0, 0%, 0%, 0.2);
|
||||
}
|
||||
|
||||
roll-action {
|
||||
@@ -135,6 +160,9 @@
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
|
||||
roll-section[name="resistance"] {
|
||||
align-items: flex-end;
|
||||
}
|
||||
roll-section {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -149,6 +177,12 @@
|
||||
margin: 0 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
img.flag-resistance {
|
||||
max-width: 1.5rem;
|
||||
max-height: 1.5rem;
|
||||
text-align: right;
|
||||
filter: invert(0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,31 +212,40 @@
|
||||
margin: 0 0.2rem;
|
||||
padding: 0;
|
||||
}
|
||||
img.button-effect-img {
|
||||
max-width: 1rem;
|
||||
max-height: 1rem;
|
||||
margin: 0 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
roll-carac select[name="select-carac"] {
|
||||
max-width: 6rem;
|
||||
|
||||
}
|
||||
min-width: 6.5rem;
|
||||
max-width: 8rem;
|
||||
}
|
||||
roll-comp select[name="select-comp"] {
|
||||
min-width: 8rem;
|
||||
max-width: 11rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
max-width: 10rem;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
roll-conditions roll-section[name="coeur"] select[name="coeur"] {
|
||||
max-width: 4rem;
|
||||
}
|
||||
|
||||
roll-conditions roll-section[name="tricher"] img {
|
||||
/* image de d100 */
|
||||
max-width: 2.5rem;
|
||||
max-height: 2.5rem;
|
||||
roll-conditions roll-section img {
|
||||
max-width: 1rem;
|
||||
max-height: 1rem;
|
||||
gap: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
filter: invert(0.8);
|
||||
}
|
||||
roll-conditions roll-section[name="tricher"] img {
|
||||
/* image de d100 */
|
||||
max-width: 2.5rem;
|
||||
max-height: 2.5rem;
|
||||
}
|
||||
|
||||
roll-buttons {
|
||||
display: flex;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
min-height: 100px; // Hauteur minimale pour la description
|
||||
background: var(--rdd-bg-input-alt); // Une couleur de fond alternative
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
color: var(--rdd-color-text-primary);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
background: var(--fieldset-background);
|
||||
color: var(--rdd-color-text-primary);
|
||||
margin-bottom: 4px;
|
||||
border-radius: 6px;
|
||||
border-radius: 0.5rem;
|
||||
border-color: var(--rdd-color-text-primary);
|
||||
border-width: 2px;
|
||||
}
|
||||
@@ -64,7 +64,7 @@
|
||||
--rdd-color-text-input
|
||||
); // Assurez-vous que cette variable existe
|
||||
padding: 2px 2px; // Augmentation du padding vertical
|
||||
border-radius: 3px;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SYSTEM_RDD } from "../constants.js";
|
||||
import { renderTemplate, SYSTEM_RDD } from "../constants.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
|
||||
const DETAIL_VENTE = 'detailVente';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "../constants.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
import { ChatVente } from "./chat-vente.js";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "../constants.js";
|
||||
import { HtmlUtility } from "../html-utility.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
import { ChatVente } from "./chat-vente.js";
|
||||
|
||||
@@ -3,7 +3,7 @@ import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDBonus } from "./rdd-bonus.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDCombatManager } from "./rdd-combat.js";
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
import { CARACS, RdDCarac } from "./rdd-carac.js";
|
||||
import { DialogSplitItem } from "./dialog-split-item.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
import { RdDSheetUtility } from "./rdd-sheet-utility.js";
|
||||
@@ -11,7 +11,6 @@ import { MAINS_DIRECTRICES } from "./actor.js";
|
||||
import { RdDBaseActorReveSheet } from "./actor/base-actor-reve-sheet.js";
|
||||
import { ITEM_TYPES } from "./constants.js";
|
||||
import { RdDItem } from "./item.js";
|
||||
import { RdDItemArme } from "./item/arme.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { RdDItemBlessure } from "./item/blessure.js";
|
||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||
@@ -49,7 +48,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
|
||||
});
|
||||
foundry.utils.mergeObject(formData.calc, {
|
||||
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),
|
||||
caracTotal: RdDCarac.computeTotal(this.actor.system.carac, this.actor.system.beaute),
|
||||
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) } })
|
||||
});
|
||||
|
||||
this.html.find('.roll-chance-actuelle').click(async event => await this.actor.rollCarac('chance-actuelle'))
|
||||
this.html.find('.roll-chance-actuelle').click(async event => await this.actor.rollCarac(CARACS.CHANCE_ACTUELLE))
|
||||
this.html.find('.button-appel-chance').click(async event => await this.actor.rollAppelChance())
|
||||
|
||||
this.html.find('[name="jet-astrologie"]').click(async event => await this.actor.astrologieNombresAstraux())
|
||||
@@ -209,7 +208,8 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
|
||||
}
|
||||
|
||||
// Points de reve actuel
|
||||
this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollCarac('reve-actuel', { resistance: true }))
|
||||
this.html.find('.roll-reve-actuel').click(async event => await this.actor.rollReveActuel({ resistance: false }))
|
||||
this.html.find('.button-reve-resistance').click(async event => await this.actor.rollReveActuel({ diff: -8, resistance: true }))
|
||||
this.html.find('.action-empoignade').click(async event => await RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor)))
|
||||
|
||||
this.html.find('.roll-arme').click(async event => {
|
||||
@@ -343,7 +343,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async createEmptyTache() {
|
||||
await this.actor.createItem('tache', 'Nouvelle tache');
|
||||
await this.actor.createItem(ITEM_TYPES.tache, 'Nouvelle tache')
|
||||
}
|
||||
|
||||
_getActionCombat(event) {
|
||||
@@ -376,14 +376,6 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
_updateObject(event, formData) {
|
||||
// Update the Actor
|
||||
return this.actor.update(formData);
|
||||
}
|
||||
|
||||
async splitItem(item) {
|
||||
const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split));
|
||||
dialog.render(true);
|
||||
|
||||
@@ -14,12 +14,12 @@ import { STATUSES } from "./settings/status-effects.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
import { EffetsDraconiques } from "./tmr/effets-draconiques.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 { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js";
|
||||
import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||
import { RollDataAjustements } from "./rolldata-ajustements-v1.js";
|
||||
import { RdDPossession } from "./rdd-possession.js";
|
||||
import { ACTOR_TYPES, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { ACTOR_TYPES, renderTemplate, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { RdDConfirm } from "./rdd-confirm.js";
|
||||
import { DialogRepos } from "./sommeil/dialog-repos.js";
|
||||
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||
@@ -31,9 +31,8 @@ import { ITEM_TYPES } from "./constants.js";
|
||||
import { RdDBaseActorSang } from "./actor/base-actor-sang.js";
|
||||
import { RdDCoeur } from "./coeur/rdd-coeur.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 { RdDItemTete } from "./item/tete.js";
|
||||
import { RdDItemSort } from "./item-sort.js";
|
||||
@@ -47,7 +46,12 @@ import { PAS_DE_DRACONIC, POSSESSION_SANS_DRACONIC } from "./item/base-items.js"
|
||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
import { RdDInitiative } from "./initiative.mjs";
|
||||
import RollDialog from "./roll/roll-dialog.mjs";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js";
|
||||
import { ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_SORT } from "./roll/roll-constants.mjs";
|
||||
import { PART_TACHE } from "./roll/roll-part-tache.mjs";
|
||||
import { PART_COMP } from "./roll/roll-part-comp.mjs";
|
||||
import { PART_OEUVRE } from "./roll/roll-part-oeuvre.mjs";
|
||||
import { PART_CUISINE } from "./roll/roll-part-cuisine.mjs";
|
||||
|
||||
export const MAINS_DIRECTRICES = ['Droitier', 'Gaucher', 'Ambidextre']
|
||||
|
||||
@@ -99,6 +103,8 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
|
||||
isPersonnage() { return true }
|
||||
isFeminin() { return this.system.sexe.length > 0 && this.system.sexe.charAt(0).toLowerCase() == 'f' }
|
||||
|
||||
isHautRevant() { return this.system.attributs.hautrevant.value != "" }
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -137,12 +143,12 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
|
||||
listActions({ isAttaque = false, isEquipe = false }) {
|
||||
// Recupération des armes
|
||||
// Recupération des attaques
|
||||
const actions = this.listActionsAttaque()
|
||||
.filter(it => !isEquipe || it.arme.system.equipe)
|
||||
|
||||
if (!isAttaque && this.system.attributs.hautrevant.value) {
|
||||
actions.push({ name: "Draconic", action: 'haut-reve', initOnly: true })
|
||||
actions.push({ label: "Draconic", action: 'haut-reve', initOnly: true })
|
||||
}
|
||||
return actions
|
||||
}
|
||||
@@ -159,71 +165,71 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getDemiReve() { return this.system.reve.tmrpos.coord }
|
||||
getDraconicList() { return this.itemTypes[ITEM_TYPES.competence].filter(it => it.system.categorie == 'draconic') }
|
||||
getBestDraconic() { return foundry.utils.duplicate([...this.getDraconicList(), PAS_DE_DRACONIC].sort(Misc.descending(it => it.system.niveau)).find(it => true)) }
|
||||
getDraconics() { return this.itemTypes[ITEM_TYPES.competence].filter(it => it.system.categorie == 'draconic') }
|
||||
getBestDraconic() { return foundry.utils.duplicate([...this.getDraconics(), PAS_DE_DRACONIC].sort(Misc.descending(it => it.system.niveau)).find(it => true)) }
|
||||
getDraconicOuPossession() {
|
||||
return [...this.getDraconicList().filter(it => it.system.niveau >= 0), POSSESSION_SANS_DRACONIC]
|
||||
return [...this.getDraconics().filter(it => it.system.niveau >= 0), POSSESSION_SANS_DRACONIC]
|
||||
.sort(Misc.descending(it => it.system.niveau))
|
||||
.find(it => true)
|
||||
}
|
||||
|
||||
isForceInsuffisante(forceRequise) {
|
||||
const force = parseInt(this.system.carac.force.value)
|
||||
return forceRequise > force
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** Retourne une liste triée d'actions d'armes avec le split arme1 main / arme 2 main / lancer */
|
||||
listActionsAttaque() {
|
||||
let actions = [
|
||||
this.$prepareAttaqueArme(RdDItemArme.empoignade(this)),
|
||||
this.$prepareAttaqueArme(RdDItemArme.corpsACorps(this)),
|
||||
]
|
||||
const actions = []
|
||||
const uniques = []
|
||||
|
||||
const armes = this.itemTypes[ITEM_TYPES.arme]
|
||||
.filter(it => RdDItemArme.isAttaque(it))
|
||||
.sort(Misc.ascending(it => it.name));
|
||||
const addAttaque = (arme, main = undefined) => {
|
||||
const dommages = RdDItemArme.valeurMain(arme.system.dommages, main)
|
||||
const forceRequise = RdDItemArme.valeurMain(arme.system.force ?? 0, main)
|
||||
const ecaillesEfficacite = arme.system.magique ? arme.system.ecaille_efficacite : 0;
|
||||
|
||||
for (const arme of armes) {
|
||||
if (arme.system.unemain && arme.system.competence) {
|
||||
actions.push(this.$prepareAttaqueArme(arme, '(1 main)'))
|
||||
const comp = this.getCompetence(arme.getCompetenceAction(main), { onMessage: message => { console.info(message) } })
|
||||
if (!comp) {
|
||||
return
|
||||
}
|
||||
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)'))
|
||||
const unique = [comp.id, arme.name, dommages, forceRequise, ecaillesEfficacite].join('|');
|
||||
if (uniques.includes(unique)) {
|
||||
return
|
||||
}
|
||||
uniques.push(unique);
|
||||
|
||||
const caracCode = RdDActor.$getCaracAction(comp, main)
|
||||
const caracValue = this.system.carac[caracCode].value
|
||||
|
||||
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,
|
||||
dommages: dommages,
|
||||
forceRequise: forceRequise,
|
||||
initiative: RdDInitiative.getRollInitiative(caracValue, niveau, ajustement)
|
||||
})
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
$prepareAttaqueArme(arme, main) {
|
||||
const comp = this.getCompetence(RdDActor.$getCompetenceAction(arme, main))
|
||||
const caracCode = RdDActor.$getCaracAction(comp, main)
|
||||
const caracValue = this.system.carac[caracCode].value
|
||||
const dommages = arme.system.dommages.toString()
|
||||
addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
||||
|
||||
// TODO: déplacer sur RdDItemArme
|
||||
if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) {
|
||||
ui.notifications.info(`Les dommages de l'arme à 1/2 mains ${arme.name} ne sont pas corrects (ie sous la forme X/Y)`)
|
||||
}
|
||||
const tableauDommages = dommages.includes("/") ? dommages.split("/") : [dommages, dommages]
|
||||
const 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
|
||||
this.itemTypes[ITEM_TYPES.arme]
|
||||
.filter(it => it.isAttaque())
|
||||
.sort(Misc.ascending(it => it.name))
|
||||
.forEach(arme => arme.getTypeAttaques().forEach(t => addAttaque(arme, t)))
|
||||
|
||||
return {
|
||||
name: arme.name + (main ? ' ' + main : ''),
|
||||
action: 'attaque',
|
||||
initOnly: false,
|
||||
arme: arme,
|
||||
comp: comp,
|
||||
main: main,
|
||||
carac: { key: caracCode, value: caracValue },
|
||||
equipe: arme.system.equipe,
|
||||
dmg: dmg,
|
||||
initiative: RdDInitiative.calculInitiative(niveau, caracValue, ajustement)
|
||||
}
|
||||
addAttaque(RdDItemArme.pugilat(this), ATTAQUE_TYPE.CORPS_A_CORPS)
|
||||
|
||||
return actions
|
||||
}
|
||||
|
||||
static $getCaracAction(comp, main) {
|
||||
@@ -237,16 +243,6 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
}
|
||||
|
||||
static $getCompetenceAction(arme, main) {
|
||||
switch (main) {
|
||||
case '(1 main)': return arme.competence1Mains()
|
||||
case '(2 mains)': return arme.competence2Mains()
|
||||
case '(lancer)': return arme.system.lancer
|
||||
case '(tir)': return arme.system.tir
|
||||
default: return arme.system.competence
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async $perteReveEnchantementsChateauDormants() {
|
||||
const toUpdate = this.items.filter(it => [ITEM_TYPES.potion, ITEM_TYPES.gemme].includes(it.type))
|
||||
@@ -507,7 +503,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
'system.sante.fatigue.value': 0,
|
||||
'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 ChatMessage.create({
|
||||
whisper: ChatUtility.getOwners(this),
|
||||
@@ -698,11 +694,12 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async combattreReveDeDragon(force) {
|
||||
const rencontre = await game.system.rdd.rencontresTMR.getReveDeDragon(force);
|
||||
let rollData = {
|
||||
actor: this,
|
||||
competence: this.getDraconicOuPossession(),
|
||||
canClose: false,
|
||||
rencontre: await game.system.rdd.rencontresTMR.getReveDeDragon(force),
|
||||
rencontre: rencontre,
|
||||
tmr: true,
|
||||
use: { libre: false, conditions: false },
|
||||
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } }
|
||||
@@ -733,12 +730,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async sortMisEnReserve(sort, draconic, coord, ptreve) {
|
||||
await this.createEmbeddedDocuments("Item", [{
|
||||
type: ITEM_TYPES.sortreserve,
|
||||
name: sort.name,
|
||||
img: sort.img,
|
||||
system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' }
|
||||
}],
|
||||
await this.createEmbeddedDocuments("Item", [RdDItemSort.prepareSortEnReserve(sort, draconic, ptreve, coord)],
|
||||
{ renderSheet: false });
|
||||
this.tmrApp.updateTokens();
|
||||
}
|
||||
@@ -752,20 +744,18 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
let updates = {};
|
||||
if (caracName == LIST_CARAC_PERSONNAGE.reve.code) {
|
||||
if (to > Misc.toInt(this.system.reve.seuil.value)) {
|
||||
updates[`system.reve.seuil.value`] = to; // SFA : Direct and packed changes
|
||||
//this.setPointsDeSeuil(to);
|
||||
updates[`system.reve.seuil.value`] = to
|
||||
}
|
||||
}
|
||||
if (caracName == LIST_CARAC_PERSONNAGE.chance.code) {
|
||||
if (to > Misc.toInt(this.system.compteurs.chance.value)) {
|
||||
updates[`system.compteurs.chance.value`] = to; // SFA : Direct and packed changes
|
||||
//this.setPointsDeChance(to);
|
||||
updates[`system.compteurs.chance.value`] = to
|
||||
}
|
||||
}
|
||||
let selectedCarac = this.findCaracByName(caracName);
|
||||
const from = selectedCarac.value
|
||||
updates[`system.carac.${caracName}.value`] = to;
|
||||
await this.update(updates);
|
||||
await this.update(updates, { noHook: true });
|
||||
await ExperienceLog.add(this, XP_TOPIC.CARAC, from, to, caracName);
|
||||
}
|
||||
|
||||
@@ -1343,7 +1333,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
async _apprecierCuisine(item, seForcer) {
|
||||
const surmonteExotisme = await this._surmonterExotisme(item, seForcer);
|
||||
if (surmonteExotisme) {
|
||||
await this.apprecier('gout', 'cuisine', item.system.qualite, item.system.boisson ? "apprécie la boisson" : "apprécie le plat");
|
||||
await this.apprecier(CARACS.ODORATGOUT, 'cuisine', item.system.qualite, item.system.boisson ? "apprécie la boisson" : "apprécie le plat");
|
||||
}
|
||||
else if (seForcer) {
|
||||
await this.jetDeMoral('malheureux');
|
||||
@@ -1361,7 +1351,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
if (exotisme < 0 || qualite < 0) {
|
||||
const competence = qualite > 0 ? 'cuisine' : undefined
|
||||
const difficulte = Math.min(exotisme, qualite)
|
||||
const rolled = await this.doRollCaracCompetence('volonte', competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
|
||||
const rolled = await this.doRollCaracCompetence(CARACS.VOLONTE, competence, difficulte, { title: `tente de surmonter l'exotisme de ${item.name}` })
|
||||
return rolled.isSuccess
|
||||
}
|
||||
return true;
|
||||
@@ -1646,7 +1636,8 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
return
|
||||
}
|
||||
hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM)
|
||||
let xpData = await this._appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence, rollData.jetResistance);
|
||||
let xpData = await this._appliquerExperience(rollData.rolled, rollData.selectedCarac.label, rollData.competence,
|
||||
rollData.v2 ? rollData.type.resistance : rollData.jetResistance);
|
||||
if (xpData.length) {
|
||||
const content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-gain-xp.hbs`, {
|
||||
actor: this,
|
||||
@@ -1683,7 +1674,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
computeDraconicAndSortIndex(sortList) {
|
||||
let draconicList = this.getDraconicList();
|
||||
let draconicList = this.getDraconics();
|
||||
for (let sort of sortList) {
|
||||
let draconicsSort = RdDItemSort.getDraconicsSort(draconicList, sort).map(it => it.name);
|
||||
for (let index = 0; index < draconicList.length && sort.system.listIndex == undefined; index++) {
|
||||
@@ -1704,15 +1695,18 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
ui.notifications.error("Une queue ou un souffle vous empèche de lancer de sort!")
|
||||
return
|
||||
}
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
return await this.rollUnSortV2();
|
||||
}
|
||||
// Duplication car les pts de reve sont modifiés dans le sort!
|
||||
let sorts = foundry.utils.duplicate(this.itemTypes[ITEM_TYPES.sort].filter(it => RdDItemSort.isSortOnCoord(it, coord)))
|
||||
if (sorts.length == 0) {
|
||||
ui.notifications.info(`Aucun sort disponible en ${TMRUtility.getTMR(coord).label} !`);
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
const draconicList = this.computeDraconicAndSortIndex(sorts);
|
||||
const reve = foundry.utils.duplicate(this.system.carac.reve);
|
||||
const draconicList = this.computeDraconicAndSortIndex(sorts)
|
||||
const reve = foundry.utils.duplicate(this.system.carac.reve)
|
||||
|
||||
const dialog = await this.openRollDialog({
|
||||
name: 'lancer-un-sort',
|
||||
@@ -1735,6 +1729,27 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
this.tmrApp?.setTMRPendingAction(dialog);
|
||||
}
|
||||
|
||||
async rollUnSortV2() {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: { allowed: [ROLL_TYPE_SORT], current: ROLL_TYPE_SORT }
|
||||
};
|
||||
const dialog = await RollDialog.create(rollData, {
|
||||
callbacks: [roll => {
|
||||
this.tmrApp?.restoreTMRAfterAction();
|
||||
if (roll.closeTMR) {
|
||||
this.tmrApp?.close();
|
||||
this.tmrApp = undefined;
|
||||
}
|
||||
}],
|
||||
onRollDone: RollDialog.onRollDoneClose,
|
||||
onClose: () => {
|
||||
this.tmrApp?.restoreTMRAfterAction();
|
||||
}
|
||||
});
|
||||
this.tmrApp?.setTMRPendingAction(dialog);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isMauvaiseRencontre() { // Gestion queue/souffle 'Mauvaise Rencontre en Perpective'
|
||||
let addMsg = "";
|
||||
@@ -1806,11 +1821,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
else {
|
||||
console.log('lancement de sort', rollData.selectedSort)
|
||||
const precedents = rollData.selectedSort.system.lancements ?? []
|
||||
const lancements = [...precedents, {
|
||||
timestamp: game.system.rdd.calendrier.getTimestamp(),
|
||||
reve: rollData.selectedSort.system.ptreve_reel
|
||||
}]
|
||||
const lancements = RdDItemSort.prepareSortAddLancement(rollData.selectedSort, rollData.selectedSort.system.ptreve_reel)
|
||||
await this.updateEmbeddedDocuments('Item',
|
||||
[{ _id: rollData.selectedSort._id, 'system.lancements': lancements }]
|
||||
)
|
||||
@@ -1923,6 +1934,20 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
|
||||
async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
|
||||
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: { allowed: [PART_COMP], current: PART_COMP },
|
||||
selected: {
|
||||
carac: { key: caracName },
|
||||
comp: { key: compName, forced: options.forced },
|
||||
diff: { value: diff ?? 0 }
|
||||
}
|
||||
}
|
||||
return await RollDialog.create(rollData)
|
||||
}
|
||||
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
const competence = this.getCompetence(compName);
|
||||
await this.openRollDialog({
|
||||
@@ -1945,23 +1970,33 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollTache(id, options = {}) {
|
||||
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
const tacheData = this.getTache(id)
|
||||
const compData = this.getCompetence(tacheData.system.competence)
|
||||
compData.system.defaut_carac = tacheData.system.carac; // Patch !
|
||||
const tache = this.getTache(id)
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
selected: { tache: { key: tache.id, forced: options.forced } },
|
||||
type: { allowed: [PART_TACHE], current: PART_TACHE }
|
||||
}
|
||||
return await RollDialog.create(rollData)
|
||||
}
|
||||
|
||||
const compData = this.getCompetence(tache.system.competence)
|
||||
compData.system.defaut_carac = tache.system.carac; // Patch !
|
||||
|
||||
await this.openRollDialog({
|
||||
name: 'jet-competence',
|
||||
label: 'Jet de Tâche ' + tacheData.name,
|
||||
label: 'Jet de Tâche ' + tache.name,
|
||||
template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.hbs',
|
||||
rollData: {
|
||||
competence: compData,
|
||||
tache: tacheData,
|
||||
diffLibre: tacheData.system.difficulte,
|
||||
tache: tache,
|
||||
diffLibre: tache.system.difficulte,
|
||||
diffConditions: 0,
|
||||
use: { libre: false, conditions: true },
|
||||
carac: {
|
||||
[tacheData.system.carac]: foundry.utils.duplicate(this.system.carac[tacheData.system.carac])
|
||||
[tache.system.carac]: foundry.utils.duplicate(this.system.carac[tache.system.carac])
|
||||
}
|
||||
},
|
||||
callbacks: [{ action: r => this._tacheResult(r, options) }]
|
||||
@@ -1995,9 +2030,18 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollJeu(id) {
|
||||
const oeuvre = this.getJeu(id);
|
||||
const jeu = this.getJeu(id);
|
||||
|
||||
const listCarac = oeuvre.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim());
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
selected: { jeu: { key: jeu.id } },
|
||||
type: { allowed: [ROLL_TYPE_JEU], current: ROLL_TYPE_JEU }
|
||||
}
|
||||
return await RollDialog.create(rollData)
|
||||
}
|
||||
|
||||
const listCarac = jeu.system.caraccomp.toLowerCase().split(/[.,:\/-]/).map(it => it.trim());
|
||||
const carac = listCarac.length > 0 ? listCarac[0] : 'chance'
|
||||
const artData = {
|
||||
art: 'jeu', verbe: 'Jeu',
|
||||
@@ -2007,14 +2051,24 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
};
|
||||
listCarac.forEach(c => artData.forceCarac[c] = this.system.carac[c]);
|
||||
artData.competence.system.niveauReel = artData.competence.system.niveau;
|
||||
artData.competence.system.niveau = Math.max(artData.competence.system.niveau, oeuvre.system.base);
|
||||
await this._rollArtV1(artData, carac, oeuvre);
|
||||
artData.competence.system.niveau = Math.max(artData.competence.system.niveau, jeu.system.base);
|
||||
await this._rollArtV1(artData, carac, jeu);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollMeditation(id) {
|
||||
const meditation = foundry.utils.duplicate(this.getMeditation(id));
|
||||
|
||||
if (meditation && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
selected: { meditation: { key: id } },
|
||||
type: { allowed: [ROLL_TYPE_MEDITATION], current: ROLL_TYPE_MEDITATION }
|
||||
}
|
||||
return await RollDialog.create(rollData)
|
||||
}
|
||||
|
||||
const competence = foundry.utils.duplicate(this.getCompetence(meditation.system.competence));
|
||||
competence.system.defaut_carac = "intellect"; // Meditation = toujours avec intellect
|
||||
let meditationData = {
|
||||
@@ -2054,7 +2108,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
/* -------------------------------------------- */
|
||||
_getSignesDraconiques(coord) {
|
||||
const type = TMRUtility.getTMRType(coord);
|
||||
return this.itemTypes["signedraconique"].filter(it => it.system.typesTMR.includes(type));
|
||||
return this.itemTypes[ITEM_TYPES.signedraconique].filter(it => it.system.typesTMR.includes(type));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -2066,18 +2120,19 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
async rollLireSigneDraconique(coord) {
|
||||
if (!this.isHautRevant()) {
|
||||
ui.notifications.info("Seul un haut rêvant peut lire un signe draconique!");
|
||||
return;
|
||||
return
|
||||
}
|
||||
let signes = this._getSignesDraconiques(coord);
|
||||
let signes = this._getSignesDraconiques(coord)
|
||||
if (signes.length == 0) {
|
||||
ui.notifications.info(`Aucun signe draconiques en ${coord} !`);
|
||||
return;
|
||||
ui.notifications.info(`Aucun signe draconiques en ${coord} !`)
|
||||
return
|
||||
}
|
||||
let draconicList = this.getDraconicList()
|
||||
|
||||
let draconicList = this.getDraconics()
|
||||
.map(draconic => {
|
||||
let draconicLecture = foundry.utils.duplicate(draconic);
|
||||
draconicLecture.system.defaut_carac = "intellect";
|
||||
return draconicLecture;
|
||||
let draconicLecture = foundry.utils.duplicate(draconic)
|
||||
draconicLecture.system.defaut_carac = "intellect"
|
||||
return draconicLecture
|
||||
});
|
||||
|
||||
const intellect = this.system.carac.intellect;
|
||||
@@ -2210,7 +2265,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
const xpCompetence = competence ? xp - xpCarac : 0;
|
||||
if (jetResistance) {
|
||||
const message = `Jet de résistance ${jetResistance}, l'expérience est limitée à 1`;
|
||||
const message = `Jet de résistance, l'expérience est limitée à 1`;
|
||||
ui.notifications.info(message);
|
||||
console.log(message)
|
||||
// max 1 xp sur jets de résistance
|
||||
@@ -2278,13 +2333,12 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
|
||||
static _getComposantsCaracDerivee(caracName) {
|
||||
switch (Grammar.toLowerCaseNoAccent(caracName)) {
|
||||
case 'reve-actuel': case 'reve actuel': return ['reve']
|
||||
case 'chance-actuelle': case 'chance actuelle': return ['chance']
|
||||
case 'vie': return ['constitution']
|
||||
case 'tir': return ['vue', 'dexterite']
|
||||
case 'lancer': return ['force', 'dexterite', 'vue']
|
||||
case 'melee': return ['force', 'agilite']
|
||||
case 'derobee': return ['agilite']
|
||||
case CARACS.REVE_ACTUEL: case 'reve actuel': return [CARACS.REVE]
|
||||
case CARACS.CHANCE_ACTUELLE: case 'chance actuelle': return [CARACS.CHANCE]
|
||||
case CARACS.TIR: return [CARACS.DEXTERITE, CARACS.VUE]
|
||||
case CARACS.LANCER: return [CARACS.FORCE, CARACS.DEXTERITE, CARACS.VUE]
|
||||
case CARACS.MELEE: return [CARACS.FORCE, CARACS.AGILITE]
|
||||
case CARACS.DEROBEE: return [CARACS.AGILITE]
|
||||
}
|
||||
return []
|
||||
}
|
||||
@@ -2352,14 +2406,15 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
if (this.tmrApp) {
|
||||
ui.notifications.warn("Vous êtes déja dans les TMR....")
|
||||
this.tmrApp.forceTMRDisplay()
|
||||
return
|
||||
return false
|
||||
}
|
||||
if (mode != 'visu' && this.isDemiReve()) {
|
||||
ui.notifications.warn("Les personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation")
|
||||
ui.notifications.warn("Le personnage est déjà dans les Terres Médianes, elles s'affichent en visualisation")
|
||||
mode = "visu"; // bascule le mode en visu automatiquement
|
||||
}
|
||||
if (mode == 'visu') {
|
||||
await this._doDisplayTMR(mode)
|
||||
return false
|
||||
}
|
||||
else {
|
||||
const rencontre = this.getRencontreTMREnAttente();
|
||||
@@ -2372,6 +2427,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
buttonLabel: 'Monter dans les TMR',
|
||||
onAction: async () => await this._doDisplayTMR(mode)
|
||||
})
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2394,7 +2450,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
let tmrFormData = {
|
||||
mode: mode,
|
||||
fatigue: RdDUtility.calculFatigueHtml(fatigue, endurance),
|
||||
draconic: this.getDraconicList(),
|
||||
draconic: this.getDraconics(),
|
||||
sort: this.itemTypes['sort'],
|
||||
signes: this.itemTypes['signedraconique'],
|
||||
caracReve: parseInt(this.system.carac.reve.value),
|
||||
@@ -2409,6 +2465,29 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
await this.tmrApp.onDeplacement()
|
||||
}
|
||||
|
||||
async quitterTMR(message, viewOnly, cumulFatigue) {
|
||||
if (this.tmrApp) {
|
||||
this.tmrApp = undefined
|
||||
const appliquerFatigue = ReglesOptionnelles.isUsing("appliquer-fatigue");
|
||||
await this.santeIncDec(
|
||||
appliquerFatigue ? "fatigue" : "endurance",
|
||||
(appliquerFatigue ? 1 : -1) * cumulFatigue)
|
||||
if (!viewOnly) {
|
||||
await this.supprimerSignesDraconiques(it => it.system.ephemere && it.system.duree == '1 round', { render: false })
|
||||
await this.setEffect(STATUSES.StatusDemiReve, false)
|
||||
ChatUtility.tellToUserAndGM(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async supprimerSignesDraconiques(filter = it => true, options = { render: true }) {
|
||||
const signes = this.itemTypes[ITEM_TYPES.signedraconique].filter(filter)
|
||||
if (signes.length > 0) {
|
||||
this.deleteEmbeddedDocuments("Item", signes.map(item => item.id), options)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollSoins(blesse, blessureId) {
|
||||
const blessure = blesse.blessuresASoigner().find(it => it.id == blessureId);
|
||||
@@ -2416,14 +2495,17 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
if (!blessure.system.premierssoins.done) {
|
||||
const tache = await this.getTacheBlessure(blesse, blessure);
|
||||
return await this.rollTache(tache.id, {
|
||||
onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r)
|
||||
onRollAutomate: async r => blesse.onRollTachePremiersSoins(blessureId, r),
|
||||
title: 'Premiers soins',
|
||||
forced: true
|
||||
});
|
||||
}
|
||||
if (!blessure.system.soinscomplets.done) {
|
||||
else if (!blessure.system.soinscomplets.done) {
|
||||
const diff = blessure.system.difficulte + (blessure.system.premierssoins.bonus ?? 0);
|
||||
return await this.rollCaracCompetence("dexterite", "Chirurgie", diff, {
|
||||
return await this.rollCaracCompetence(CARACS.DEXTERITE, "Chirurgie", diff, {
|
||||
title: "Soins complets",
|
||||
onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r)
|
||||
onRollAutomate: r => blesse.onRollSoinsComplets(blessureId, r),
|
||||
forced: true
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2438,6 +2520,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
})
|
||||
}
|
||||
const blessure = this.getItem(blessureId, 'blessure')
|
||||
|
||||
if (blessure && !blessure.system.premierssoins.done) {
|
||||
const tache = rollData.tache;
|
||||
if (rollData.rolled.isETotal) {
|
||||
@@ -2508,36 +2591,34 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
if (item?.isEquipable()) {
|
||||
const isEquipe = !item.system.equipe;
|
||||
await item.update({ "system.equipe": isEquipe });
|
||||
this.computeEncTotal();
|
||||
this.computeEncTotal()
|
||||
if (isEquipe)
|
||||
this.verifierForceMin(item);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async computeArmure(attackerRoll) {
|
||||
let dmg = (attackerRoll.dmg.dmgArme ?? 0) + (attackerRoll.dmg.dmgActor ?? 0);
|
||||
let armeData = attackerRoll.arme;
|
||||
async computeArmure(dmg) {
|
||||
let baseDmg = (dmg.dmgArme ?? 0) + (dmg.dmgActor ?? 0);
|
||||
let protection = 0;
|
||||
const armures = this.items.filter(it => it.type == "armure" && it.system.equipe);
|
||||
for (const armure of armures) {
|
||||
protection += await RdDDice.rollTotal(armure.system.protection.toString());
|
||||
if (dmg > 0 && attackerRoll.dmg.encaisserSpecial != "noarmure") {
|
||||
await armure.deteriorerArmure(dmg)
|
||||
dmg = 0;
|
||||
if (dmg.encaisserSpecial != "noarmure") {
|
||||
const armures = this.items.filter(it => it.type == "armure" && it.system.equipe)
|
||||
|
||||
for (const armure of armures) {
|
||||
protection += await RdDDice.rollTotal(armure.system.protection.toString());
|
||||
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);
|
||||
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);
|
||||
console.log("Final protect", protection, dmg)
|
||||
return protection;
|
||||
}
|
||||
|
||||
@@ -2901,6 +2982,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
if (updatedEndurance && options.diff) {
|
||||
await this.setEffect(STATUSES.StatusUnconscious, updatedEndurance.value == 0)
|
||||
}
|
||||
await super.onUpdateActor(update, options, actorId)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -2920,7 +3002,9 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
break
|
||||
case ITEM_TYPES.race:
|
||||
await this.onCreateOwnedRace(item, options, id)
|
||||
break
|
||||
}
|
||||
await super.onCreateItem(item, options, id)
|
||||
await item.onCreateItemTemporel(this);
|
||||
await item.onCreateDecoupeComestible(this);
|
||||
}
|
||||
@@ -2941,9 +3025,12 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
break
|
||||
case ITEM_TYPES.empoignade:
|
||||
await RdDEmpoignade.deleteLinkedEmpoignade(this.id, item)
|
||||
// TODO: check remaining emp.
|
||||
await this.setEffect(STATUSES.StatusGrappled, false)
|
||||
await this.setEffect(STATUSES.StatusGrappling, false)
|
||||
break
|
||||
}
|
||||
super.onDeleteItem(item, options, id)
|
||||
await super.onDeleteItem(item, options, id)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -3051,40 +3138,17 @@ 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 rollData = {
|
||||
title: `Interpretation de ${oeuvre.name} par ${this.name}`,
|
||||
mode: {
|
||||
allowed: ["oeuvre"]
|
||||
},
|
||||
selected: {
|
||||
mode: "oeuvre",
|
||||
oeuvre: { key: oeuvre.id },
|
||||
},
|
||||
ids: {
|
||||
actorId: this.id
|
||||
}
|
||||
ids: { actorId: this.id },
|
||||
selected: { oeuvre: { key: oeuvre.id } },
|
||||
type: { allowed: [PART_OEUVRE], current: PART_OEUVRE, },
|
||||
}
|
||||
await RollDialog.create(rollData, {
|
||||
onRoll: (dialog) => {
|
||||
this._onCloseRollDialog(),
|
||||
dialog.close()
|
||||
},
|
||||
customChatMessage: true,
|
||||
callbacks: [callbackAction]
|
||||
})
|
||||
return await RollDialog.create(rollData)
|
||||
}
|
||||
|
||||
async _resultArtV2(artData) {
|
||||
const niveau = artData.oeuvre.system.niveau ?? 0;
|
||||
const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau);
|
||||
artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite;
|
||||
|
||||
await RdDRollResult.displayRollData(artData, this.name, `chat-resultat-${artData.art}.hbs`);
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
|
||||
async rollOeuvre(id) {
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
return await this._rollArtV2(id)
|
||||
@@ -3170,28 +3234,39 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
async _resultArt(artData) {
|
||||
const niveau = artData.oeuvre.system.niveau ?? 0;
|
||||
const baseQualite = (artData.rolled.isSuccess ? niveau : artData.competence.system.niveau);
|
||||
artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite;
|
||||
artData.qualiteFinale = Math.min(baseQualite, niveau) + artData.rolled.ptQualite
|
||||
|
||||
await RdDRollResult.displayRollData(artData, this.name, `chat-resultat-${artData.art}.hbs`);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollRecetteCuisine(id) {
|
||||
const oeuvre = this.getRecetteCuisine(id);
|
||||
const recette = this.getRecetteCuisine(id);
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: { allowed: [PART_CUISINE], current: PART_CUISINE },
|
||||
selected: {
|
||||
cuisine: { key: recette.id }
|
||||
}
|
||||
}
|
||||
return await RollDialog.create(rollData)
|
||||
}
|
||||
|
||||
const artData = {
|
||||
verbe: 'Cuisiner',
|
||||
compName: 'cuisine',
|
||||
proportions: 1,
|
||||
ajouterEquipement: false
|
||||
};
|
||||
await this._rollArtV1(artData, 'odoratgout', oeuvre, r => this._resultRecetteCuisine(r));
|
||||
await this._rollArtV1(artData, 'odoratgout', recette, r => this._resultRecetteCuisine(r));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _resultRecetteCuisine(cuisine) {
|
||||
const niveauRecette = cuisine.oeuvre.system.niveau ?? 0;
|
||||
const baseQualite = (cuisine.rolled.isSuccess ? niveauRecette : cuisine.competence.system.niveau);
|
||||
cuisine.qualiteFinale = Math.min(baseQualite, niveauRecette) + cuisine.rolled.ptQualite;
|
||||
cuisine.qualiteFinale = Math.min(baseQualite, niveauRecette) + cuisine.rolled.ptQualite
|
||||
cuisine.exotismeFinal = Math.min(Math.min(cuisine.qualiteFinale, cuisine.oeuvre.system.exotisme ?? 0), 0);
|
||||
cuisine.sust = cuisine.oeuvre.system.sust * Math.min(cuisine.proportions, cuisine.proportionsMax ?? cuisine.proportions)
|
||||
const platCuisine = {
|
||||
@@ -3217,6 +3292,17 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
|
||||
async preparerNourriture(item) {
|
||||
if (item.getUtilisationCuisine() == 'brut' && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: { allowed: [PART_CUISINE], current: PART_CUISINE },
|
||||
selected: {
|
||||
cuisine: { key: item.id }
|
||||
}
|
||||
}
|
||||
return await RollDialog.create(rollData)
|
||||
}
|
||||
|
||||
if (item.getUtilisationCuisine() == 'brut') {
|
||||
const nourriture = {
|
||||
name: 'Plat de ' + item.name,
|
||||
@@ -3227,7 +3313,7 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
exotisme: item.system.exotisme,
|
||||
ingredients: item.name
|
||||
}
|
||||
};
|
||||
}
|
||||
const artData = {
|
||||
verbe: 'Préparer',
|
||||
compName: 'cuisine',
|
||||
@@ -3249,3 +3335,4 @@ export class RdDActor extends RdDBaseActorSang {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,13 +56,15 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet {
|
||||
if (this.options.vueDetaillee) {
|
||||
// On carac change
|
||||
this.html.find('.carac-value').change(async event => {
|
||||
let caracName = event.currentTarget.name.replace(".value", "").replace("system.carac.", "")
|
||||
await this.actor.updateCarac(caracName, parseInt(event.target.value))
|
||||
});
|
||||
if (event.currentTarget.name.includes("carac.")) {
|
||||
let caracName = event.currentTarget.name.replace("carac.", "")
|
||||
await this.actor.updateCarac(caracName, parseInt(event.currentTarget.value))
|
||||
}
|
||||
})
|
||||
// On competence change
|
||||
this.html.find('.competence-value').change(async event => {
|
||||
let compName = event.currentTarget.attributes.compname.value
|
||||
await this.actor.updateCompetence(compName, parseInt(event.target.value))
|
||||
await this.actor.updateCompetence(compName, parseInt(event.currentTarget.value))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ENTITE_INCARNE, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
|
||||
import { renderTemplate, SHOW_DICE, SYSTEM_RDD } from "../constants.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDResolutionTable } from "../rdd-resolution-table.js";
|
||||
@@ -11,12 +11,11 @@ import { ITEM_TYPES } from "../constants.js";
|
||||
import { StatusEffects, STATUSES } from "../settings/status-effects.js";
|
||||
import { Targets } from "../targets.js";
|
||||
import { RdDConfirm } from "../rdd-confirm.js";
|
||||
import { RdDCarac } from "../rdd-carac.js";
|
||||
import { CARACS, RdDCarac } from "../rdd-carac.js";
|
||||
import { RdDRollResult } from "../rdd-roll-result.js";
|
||||
|
||||
import { RdDItemCompetence } from "../item-competence.js";
|
||||
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
||||
import { RdDItemArme } from "../item/arme.js";
|
||||
import { RdDItemCompetence } from "../item-competence.js";
|
||||
|
||||
import { ChatUtility } from "../chat-utility.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 { RdDPossession } from "../rdd-possession.js";
|
||||
import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, POSSESSION_SANS_DRACONIC } from "../item/base-items.js";
|
||||
import { RollDataAjustements } from "../rolldata-ajustements.js";
|
||||
import { RollDataAjustements } from "../rolldata-ajustements-v1.js";
|
||||
import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs";
|
||||
import RollDialog from "../roll/roll-dialog.mjs";
|
||||
import { ATTAQUE_ROLL_TYPES, DEFAULT_ROLL_TYPES, DIFF, DIFFS, 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)
|
||||
@@ -80,12 +84,11 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
getBonusDegat() { return RdDCarac.getCaracDerivee(this.getEncombrementMax()).plusdom }
|
||||
|
||||
getMoralTotal() { return 0 }
|
||||
listeAmoureux() {return []}
|
||||
listeAmoureux() { return [] }
|
||||
getProtectionNaturelle() { return Number(this.system.attributs?.protection?.value ?? 0) }
|
||||
getSConst() { return 0 }
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isSurenc() { return false }
|
||||
computeMalusSurEncombrement() { return 0 }
|
||||
|
||||
ajustementAstrologique() { return 0 }
|
||||
@@ -113,16 +116,17 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
|
||||
listActions({ isAttaque = false, isEquipe = false }) {
|
||||
return this.itemTypes[ITEM_TYPES.competencecreature]
|
||||
.filter(it => RdDItemCompetenceCreature.isAttaque(it))
|
||||
.map(it => RdDItemCompetenceCreature.attaqueCreature(it))
|
||||
.filter(it => it.isAttaque())
|
||||
.map(it => it.attaqueCreature())
|
||||
.filter(it => it != undefined);
|
||||
}
|
||||
|
||||
|
||||
async computeArmure(attackerRoll) { return this.getProtectionNaturelle() }
|
||||
async computeArmure(dmg) { return this.getProtectionNaturelle() }
|
||||
async remiseANeuf() { }
|
||||
async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { }
|
||||
|
||||
computeResumeBlessure() { }
|
||||
countBlessures(filter = it => !it.isContusion()) { return 0 }
|
||||
async santeIncDec(name, inc, isCritique = false) { }
|
||||
|
||||
async finDeRound(options = { terminer: false }) {
|
||||
@@ -173,10 +177,11 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
}
|
||||
|
||||
getCompetences(name = undefined, options = { onMessage: message => { } }) {
|
||||
const all = [...this.itemTypes[ITEM_TYPES.competence], ...this.itemTypes[ITEM_TYPES.competencecreature]]
|
||||
if (name == undefined) {
|
||||
return this.itemTypes[ITEM_TYPES.competence]
|
||||
return all
|
||||
}
|
||||
return RdDItemCompetence.findCompetences(this.itemTypes[ITEM_TYPES.competence], name, options)
|
||||
return RdDItemCompetence.findCompetences(all, name, options)
|
||||
}
|
||||
|
||||
getCompetenceCorpsACorps(options = { onMessage: message => { } }) {
|
||||
@@ -191,11 +196,16 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
return RdDItemArme.getArme(armeParadeId ? this.getEmbeddedDocument('Item', armeParadeId) : undefined)
|
||||
}
|
||||
|
||||
isForceInsuffisante(forceRequise) {
|
||||
return false
|
||||
}
|
||||
|
||||
getDraconicOuPossession() { return POSSESSION_SANS_DRACONIC }
|
||||
|
||||
getPossession(possessionId) {
|
||||
return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId);
|
||||
}
|
||||
|
||||
getEmpoignades() {
|
||||
return this.itemTypes[ITEM_TYPES.empoignade];
|
||||
}
|
||||
@@ -219,51 +229,13 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isEffectAllowed(effectId) { return false }
|
||||
|
||||
getEffects(filter = e => true) {
|
||||
return this.getEmbeddedCollection("ActiveEffect").filter(filter);
|
||||
}
|
||||
|
||||
getEffectByStatus(statusId) {
|
||||
return this.getEffects().find(it => it.statuses.has(statusId));
|
||||
}
|
||||
|
||||
async setEffect(statusId, status) {
|
||||
if (this.isEffectAllowed(statusId)) {
|
||||
const effect = this.getEffectByStatus(statusId);
|
||||
if (!status && effect) {
|
||||
await this.deleteEmbeddedDocuments('ActiveEffect', [effect.id]);
|
||||
}
|
||||
if (status && !effect) {
|
||||
await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.prepareActiveEffect(statusId)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async removeEffect(id) {
|
||||
this.removeEffects(it => it.id == id)
|
||||
}
|
||||
|
||||
async removeEffects(filter = e => true) {
|
||||
if (game.user.isGM) {
|
||||
const ids = this.getEffects(filter).map(it => it.id);
|
||||
await this.deleteEmbeddedDocuments('ActiveEffect', ids);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isDemiReve() {
|
||||
return this.getEffectByStatus(STATUSES.StatusDemiReve) != undefined
|
||||
return this.getEffectsByStatus(STATUSES.StatusDemiReve).length > 0
|
||||
}
|
||||
|
||||
getSurprise(isCombat = undefined) {
|
||||
return StatusEffects.typeSurprise(
|
||||
this.getEffects()
|
||||
.map(it => StatusEffects.niveauSurprise(it, isCombat))
|
||||
.reduce(Misc.sum(), 0)
|
||||
)
|
||||
getSurprise(isCombat = undefined, forceRequise = undefined) {
|
||||
return StatusEffects.getSurprise(this.getEffects(e => true, isCombat, forceRequise), isCombat)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -300,6 +272,21 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
|
||||
async rollCaracCompetence(caracName, compName, diff, options = { title: "" }) {
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const competence = this.getCompetence(compName);
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: { allowed: DEFAULT_ROLL_TYPES, current: PART_COMP },
|
||||
selected: {
|
||||
carac: { key: caracName },
|
||||
comp: { key: competence.name },
|
||||
diff: { value: diff }
|
||||
}
|
||||
}
|
||||
return await RollDialog.create(rollData, options)
|
||||
}
|
||||
|
||||
const competence = this.getCompetence(compName);
|
||||
await this.openRollDialog({
|
||||
name: 'jet-competence',
|
||||
@@ -371,10 +358,47 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
})
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async rollReveActuel({ diff = 0, resistance = false }) {
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: {
|
||||
allowed: [PART_COMP],
|
||||
current: PART_COMP,
|
||||
resistance: resistance
|
||||
},
|
||||
selected: {
|
||||
carac: { key: CARACS.REVE_ACTUEL, forced: true },
|
||||
comp: resistance ? { key: undefined, forced: true } : undefined,
|
||||
diff: { type: DIFF.DEFAUT, value: diff }
|
||||
}
|
||||
}
|
||||
return await RollDialog.create(rollData)
|
||||
}
|
||||
return this.rollCarac(CARACS.REVE_ACTUEL, { diff, resistance })
|
||||
}
|
||||
|
||||
async rollCarac(caracName, options = {}) {
|
||||
if (Grammar.equalsInsensitive(caracName, 'taille')) {
|
||||
if (Grammar.equalsInsensitive(caracName, CARACS.TAILLE)) {
|
||||
return
|
||||
}
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: {
|
||||
allowed: options.resistance ? [PART_COMP] : DEFAULT_ROLL_TYPES,
|
||||
current: PART_COMP,
|
||||
resistance: options.resistance
|
||||
},
|
||||
selected: {
|
||||
carac: { key: caracName },
|
||||
comp: options.resistance ? { key: undefined, forced: true } : undefined,
|
||||
diff: { type: DIFF.DEFAUT, value: options.diff ?? 0 }
|
||||
}
|
||||
}
|
||||
return await RollDialog.create(rollData, options)
|
||||
}
|
||||
|
||||
foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false })
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
let selectedCarac = this.getCaracByName(caracName)
|
||||
@@ -401,10 +425,24 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-general.hbs');
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollCompetence(idOrName, options = { tryTarget: true, arme: undefined }) {
|
||||
RdDEmpoignade.checkEmpoignadeEnCours(this)
|
||||
|
||||
const competence = this.getCompetence(idOrName);
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id },
|
||||
type: { allowed: options.arme ? ATTAQUE_ROLL_TYPES : DEFAULT_ROLL_TYPES },
|
||||
selected: {
|
||||
carac: competence.type == ITEM_TYPES.competencecreature ? { key: competence.name } : undefined,
|
||||
comp: { key: competence.name },
|
||||
diff: { type: options.arme ? DIFF.ATTAQUE : DIFF.LIBRE, value: competence.system.default_diffLibre ?? 0 },
|
||||
attaque: options.arme ? { arme: { key: options.arme.id } } : undefined
|
||||
}
|
||||
}
|
||||
return await RollDialog.create(rollData)
|
||||
}
|
||||
|
||||
let rollData = {
|
||||
carac: this.system.carac,
|
||||
competence: competence,
|
||||
@@ -412,7 +450,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
}
|
||||
if (competence.type == ITEM_TYPES.competencecreature) {
|
||||
const token = RdDUtility.getSelectedToken(this)
|
||||
const arme = RdDItemCompetenceCreature.armeCreature(competence)
|
||||
const arme = MappingCreatureArme.armeCreature(competence)
|
||||
if (arme && options.tryTarget && Targets.hasTargets()) {
|
||||
Targets.selectOneTargetToken(target => {
|
||||
if (arme.action == "possession") {
|
||||
@@ -422,10 +460,10 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme)
|
||||
}
|
||||
});
|
||||
return;
|
||||
return
|
||||
}
|
||||
// Transformer la competence de créature
|
||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||
MappingCreatureArme.setRollDataCreature(rollData)
|
||||
}
|
||||
const dialogLabel = 'Jet ' + Grammar.apostrophe('de', competence.name);
|
||||
await this.openRollDialog({
|
||||
@@ -444,16 +482,50 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
}
|
||||
}
|
||||
|
||||
rollAttaque(token) {
|
||||
token = token ?? RdDUtility.getSelectedToken(this)
|
||||
|
||||
if (Targets.hasTargets()) {
|
||||
Targets.selectOneTargetToken(target => {
|
||||
if (Targets.isTargetEntite(target)) {
|
||||
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée!!!!`)
|
||||
return
|
||||
}
|
||||
|
||||
RdDCombat.rddCombatTarget(target, this, token).attaqueV2();
|
||||
})
|
||||
}
|
||||
else {
|
||||
return RdDConfirm.confirmer({
|
||||
settingConfirmer: "confirmer-combat-sans-cible",
|
||||
content: `<p>Voulez vous faire une attaque sans choisir de cible valide?
|
||||
<br>Tous les jets de combats devront être gérés à la main
|
||||
</p>`,
|
||||
title: 'Ne pas utiliser les automatisation de combat',
|
||||
buttonLabel: "Pas d'automatisation",
|
||||
onAction: async () => {
|
||||
const rollData = {
|
||||
ids: { actorId: this.id, actorTokenId: token?.id, },
|
||||
type: {
|
||||
allowed: [ROLL_TYPE_ATTAQUE], current: ROLL_TYPE_ATTAQUE
|
||||
}
|
||||
};
|
||||
return await RollDialog.create(rollData, { onRollDone: RollDialog.onRollDoneClose })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/** --------------------------------------------
|
||||
* @param {*} arme item d'arme/compétence de créature
|
||||
* @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
rollArme(arme, categorieArme = 'competence', token = undefined) {
|
||||
token = token ?? RdDUtility.getSelectedToken(this)
|
||||
const compToUse = RdDItemArme.getCompetenceArme(arme, categorieArme)
|
||||
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
|
||||
}
|
||||
if (!Targets.hasTargets()) {
|
||||
@@ -490,29 +562,37 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
/* -------------------------------------------- */
|
||||
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')) {
|
||||
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')) {
|
||||
await this.encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken);
|
||||
await this.encaisserDommagesValidationGR(dmg, armure, show, attackerToken, defenderToken);
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
async encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken) {
|
||||
async encaisserDommagesValidationGR(dmg, armure, show, attackerToken, defenderToken) {
|
||||
if (!game.user.isGM) {
|
||||
RdDBaseActor.remoteActorCall({
|
||||
tokenId: this.token?.id,
|
||||
actorId: this.id,
|
||||
method: 'encaisserDommagesValidationGR', args: [rollData, armure, show, attackerToken, defenderToken]
|
||||
method: 'encaisserDommagesValidationGR', args: [dmg, armure, show, attackerToken, defenderToken]
|
||||
})
|
||||
} else {
|
||||
DialogValidationEncaissement.validerEncaissement(this, rollData, armure,
|
||||
DialogValidationEncaissement.validerEncaissement(this, dmg, armure,
|
||||
jet => this.$onEncaissement(jet, show, attackerToken, defenderToken));
|
||||
}
|
||||
}
|
||||
@@ -549,15 +629,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') {
|
||||
if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar")
|
||||
|| entite == undefined
|
||||
|| !entite.isEntite([ENTITE_INCARNE])
|
||||
|| !entite.isEntiteIncarnee()
|
||||
|| 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 = {
|
||||
alias: this.getAlias(),
|
||||
rolled: rolled,
|
||||
@@ -566,11 +668,11 @@ export class RdDBaseActorReve extends RdDBaseActor {
|
||||
};
|
||||
|
||||
if (rolled.isSuccess) {
|
||||
await entite.setEntiteReveAccordee(this);
|
||||
await entite.setEntiteReveAccordee(this)
|
||||
}
|
||||
|
||||
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.hbs');
|
||||
await this.appliquerAjoutExperience(rollData, true);
|
||||
await RdDRollResult.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.hbs')
|
||||
await this.appliquerAjoutExperience(rollData, true)
|
||||
return rolled.isSuccess;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,17 +34,17 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||
|
||||
getFatigueActuelle() {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
return Math.max(0, Math.min(this.getFatigueMax(), Misc.toInt(this.system.sante.fatigue?.value)))
|
||||
return Math.max(0, Math.min(this.getFatigueMax(), Misc.toInt(this.system.sante.fatigue?.value)))
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
isCumulFatigueCauseSommeil(cumulFatigue){
|
||||
isCumulFatigueCauseSommeil(cumulFatigue) {
|
||||
return ReglesOptionnelles.isUsing("appliquer-fatigue")
|
||||
? (this.getFatigueRestante() <= cumulFatigue)
|
||||
: (this.getEnduranceActuelle() <= cumulFatigue)
|
||||
? (this.getFatigueRestante() <= cumulFatigue)
|
||||
: (this.getEnduranceActuelle() <= cumulFatigue)
|
||||
}
|
||||
getFatigueRestante() {return this.getFatigueMax() - this.getFatigueActuelle() }
|
||||
getFatigueRestante() { return this.getFatigueMax() - this.getFatigueActuelle() }
|
||||
getFatigueMin() { return this.system.sante.endurance.max - this.system.sante.endurance.value }
|
||||
|
||||
malusFatigue() {
|
||||
@@ -116,6 +116,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||
blessure: blessure
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async santeIncDec(name, inc, isCritique = false) {
|
||||
if (name == 'fatigue' && !ReglesOptionnelles.isUsing("appliquer-fatigue")) {
|
||||
@@ -161,7 +162,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||
if (ReglesOptionnelles.isUsing("appliquer-fatigue") && sante.fatigue && fatigue > 0) {
|
||||
sante.fatigue.value = Math.max(sante.fatigue.value + fatigue, this.getFatigueMin());
|
||||
}
|
||||
await this.update({ "system.sante": sante })
|
||||
await this.update({ "system.sante": sante }, { render: true })
|
||||
if (this.isDead()) {
|
||||
await this.setEffect(STATUSES.StatusComma, true);
|
||||
}
|
||||
@@ -179,6 +180,28 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||
return Math.max(0, Math.min(maxEndVie, maxEndGraves, maxEndCritiques));
|
||||
}
|
||||
|
||||
async onCreateItem(item, options, id) {
|
||||
switch (item.type) {
|
||||
case ITEM_TYPES.blessure:
|
||||
await this.changeBleedingState()
|
||||
break
|
||||
}
|
||||
await super.onCreateItem(item, options, id)
|
||||
}
|
||||
|
||||
async onUpdateItem(item, options, id) {
|
||||
switch (item.type) {
|
||||
case ITEM_TYPES.blessure:
|
||||
await this.changeBleedingState()
|
||||
break
|
||||
}
|
||||
await super.onUpdateItem(item, options, id)
|
||||
}
|
||||
|
||||
async changeBleedingState() {
|
||||
const bleeding = this.itemTypes[ITEM_TYPES.blessure].find(it => it.isBleeding())
|
||||
await this.setEffect(STATUSES.StatusBleeding, bleeding ? true : false)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async ajouterBlessure(encaissement, attackerToken = undefined) {
|
||||
@@ -195,7 +218,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||
const endActuelle = this.getEnduranceActuelle();
|
||||
const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken);
|
||||
if (blessure.isCritique()) {
|
||||
encaissement.endurance = endActuelle;
|
||||
encaissement.endurance = endActuelle
|
||||
}
|
||||
|
||||
if (blessure.isMort()) {
|
||||
@@ -292,7 +315,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve {
|
||||
}
|
||||
|
||||
isSonne() {
|
||||
return this.getEffectByStatus(STATUSES.StatusStunned)
|
||||
return this.getEffectsByStatus(STATUSES.StatusStunned).length > 0
|
||||
}
|
||||
|
||||
isEffectAllowed(effectId) { return true }
|
||||
|
||||
@@ -5,9 +5,9 @@ import { RdDSheetUtility } from "../rdd-sheet-utility.js";
|
||||
import { Monnaie } from "../item-monnaie.js";
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
import { RdDItem } from "../item.js";
|
||||
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
||||
import { RdDTextEditor } from "../apps/rdd-text-roll-editor.js";
|
||||
import { ItemAction } from "../item/item-actions.js";
|
||||
import { RdDItemCompetenceCreature } from "../item-competencecreature.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
@@ -49,14 +49,14 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
formData.calc = {
|
||||
fortune: Monnaie.toSolsDeniers(this.actor.getFortune()),
|
||||
prixTotalEquipement: this.actor.computePrixTotalEquipement(),
|
||||
encTotal: await this.actor.computeEncTotal(),
|
||||
encTotal: this.actor.getEncTotal(),
|
||||
}
|
||||
|
||||
this.objetVersConteneur = RdDUtility.buildArbreDeConteneurs(formData.conteneurs, formData.inventaires);
|
||||
this._appliquerRechercheObjets(formData.conteneurs, formData.inventaires);
|
||||
formData.conteneurs = RdDUtility.conteneursRacine(formData.conteneurs);
|
||||
formData.competences.filter(it => it.type == ITEM_TYPES.competencecreature)
|
||||
.forEach(it => it.isdommages = RdDItemCompetenceCreature.isDommages(it))
|
||||
.forEach(it => it.isdommages = it.isDommages())
|
||||
|
||||
return formData;
|
||||
}
|
||||
@@ -229,14 +229,6 @@ export class RdDBaseActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
_updateObject(event, formData) {
|
||||
// Update the Actor
|
||||
return this.actor.update(formData);
|
||||
}
|
||||
|
||||
async splitItem(item) {
|
||||
const dialog = await DialogSplitItem.create(item, (item, split) => this._onSplitItem(item, split));
|
||||
dialog.render(true);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ChatVente } from "../achat-vente/chat-vente.js";
|
||||
import { ChatUtility } from "../chat-utility.js";
|
||||
import { SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { renderTemplate, SYSTEM_SOCKET_ID } from "../constants.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { Monnaie } from "../item-monnaie.js";
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
@@ -9,6 +9,8 @@ import { RdDAudio } from "../rdd-audio.js";
|
||||
import { RdDConfirm } from "../rdd-confirm.js";
|
||||
import { RdDUtility } from "../rdd-utility.js";
|
||||
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
||||
import { RdDItem } from "../item.js";
|
||||
import { StatusEffects, STATUSES } from "../settings/status-effects.js";
|
||||
|
||||
export class RdDBaseActor extends Actor {
|
||||
|
||||
@@ -44,8 +46,10 @@ export class RdDBaseActor extends Actor {
|
||||
}
|
||||
|
||||
static init() {
|
||||
Handlebars.registerHelper('actor-isFeminin', actor => actor.isFeminin())
|
||||
Hooks.on("preUpdateItem", (item, change, options, id) => Misc.documentIfResponsible(item.parent)?.onPreUpdateItem(item, change, options, id))
|
||||
Hooks.on("createItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onCreateItem(item, options, id))
|
||||
Hooks.on("updateItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onUpdateItem(item, options, id))
|
||||
Hooks.on("deleteItem", (item, options, id) => Misc.documentIfResponsible(item.parent)?.onDeleteItem(item, options, id))
|
||||
Hooks.on("updateActor", (actor, change, options, actorId) => Misc.documentIfResponsible(actor)?.onUpdateActor(change, options, actorId))
|
||||
}
|
||||
@@ -211,12 +215,15 @@ export class RdDBaseActor extends Actor {
|
||||
return game.users.players.find(player => player.active && player.character?.id == this.id);
|
||||
}
|
||||
|
||||
isCreatureEntite() { return this.isCreature() || this.isEntite() }
|
||||
isCreatureOuEntite() { return this.isCreature() || this.isEntite() }
|
||||
isCreature() { return false }
|
||||
isEntite(typeentite = []) { return false }
|
||||
isEntite() { return false }
|
||||
isEntiteIncarnee() { return false }
|
||||
isEntiteNonIncarnee() { return false }
|
||||
isHautRevant() { return false }
|
||||
isVehicule() { return false }
|
||||
isPersonnage() { return false }
|
||||
isFeminin() { return false }
|
||||
getItem(id, type = undefined) {
|
||||
const item = this.items.get(id);
|
||||
if (type == undefined || (item?.type == type)) {
|
||||
@@ -236,20 +243,87 @@ export class RdDBaseActor extends Actor {
|
||||
|
||||
getMonnaie(id) { return this.findItemLike(id, 'monnaie'); }
|
||||
getEncombrementMax() { return 0 }
|
||||
isSurenc() { return false }
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isEffectAllowed(effectId) { return false }
|
||||
|
||||
getEffects(filter = e => true, forceRequise = undefined) {
|
||||
const effects = this.getEmbeddedCollection("ActiveEffect")
|
||||
const selected = effects.filter(filter)
|
||||
if (forceRequise && this.isForceInsuffisante(forceRequise)) {
|
||||
selected.push(StatusEffects.prepareActiveEffect(STATUSES.StatusForceWeak))
|
||||
}
|
||||
return selected
|
||||
}
|
||||
|
||||
getEffectsByStatus(effectId) {
|
||||
return this.getEffects().filter(it => it.statuses.has(effectId))
|
||||
}
|
||||
|
||||
async setEffect(effectId, status) {
|
||||
if (this.isEffectAllowed(effectId)) {
|
||||
const effects = this.getEffectsByStatus(effectId)
|
||||
if (!status && effects.length > 0) {
|
||||
await this.deleteEmbeddedDocuments('ActiveEffect', effects.map(it => it.id), { render: true })
|
||||
}
|
||||
if (status && effects.length == 0) {
|
||||
await this.createEmbeddedDocuments("ActiveEffect", [StatusEffects.prepareActiveEffect(effectId)], { render: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async removeEffect(id) {
|
||||
this.removeEffects(it => it.id == id)
|
||||
}
|
||||
|
||||
async removeEffects(filter = e => true) {
|
||||
if (game.user.isGM) {
|
||||
const effectsToRemove = this.getEffects(filter)
|
||||
if (this.canRemoveEffect(effectsToRemove)) {
|
||||
const ids = effectsToRemove.map(it => it.id)
|
||||
await this.deleteEmbeddedDocuments('ActiveEffect', ids)
|
||||
}
|
||||
}
|
||||
}
|
||||
canRemoveEffect(effect) {
|
||||
if (effect.statuses.has(STATUSES.StatusSurEnc)) {
|
||||
return !this.isSurenc()
|
||||
}
|
||||
if (effect.statuses.has(STATUSES.StatusDemiReve)) {
|
||||
return !this.tmrApp
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async updateCarac(caracName, to) {
|
||||
}
|
||||
|
||||
async onUpdateActor(change, options, actorId) {
|
||||
const updatedCarac = change?.system?.carac
|
||||
if (updatedCarac && (updatedCarac.force || updatedCarac.reve || updatedCarac.taille)) {
|
||||
console.log(' onUpdateActor', change, options, actorId)
|
||||
await this.setEffect(STATUSES.StatusSurEnc, this.isSurenc())
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onPreUpdateItem(item, change, options, id) { }
|
||||
async onCreateItem(item, options, id) { }
|
||||
async onUpdateActor(update, options, actorId) { }
|
||||
|
||||
async onCreateItem(item, options, id) {
|
||||
}
|
||||
|
||||
async onUpdateItem(item, options, id) {
|
||||
}
|
||||
|
||||
async onDeleteItem(item, options, id) {
|
||||
if (item.isInventaire()) {
|
||||
await this._removeItemFromConteneur(item)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async _removeItemFromConteneur(item) {
|
||||
const updates = this.items.filter(it => it.isConteneur() && it.system.contenu.includes(item.id))
|
||||
.map(conteneur => {
|
||||
@@ -498,15 +572,22 @@ export class RdDBaseActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async computeEncTotal() {
|
||||
if (!this.pack) {
|
||||
this.encTotal = this.items.map(it => it.getEncTotal()).reduce(Misc.sum(), 0);
|
||||
return this.encTotal;
|
||||
if (this.pack) {
|
||||
this.encTotal = 0
|
||||
}
|
||||
else {
|
||||
const wasSurenc = this.isSurenc()
|
||||
this.encTotal = this.items.filter(it => RdDItem.getItemTypesInventaire().includes(it.type))
|
||||
.map(it => it.getEncTotal()).reduce(Misc.sum(), 0)
|
||||
const isSurenc = this.isSurenc()
|
||||
if (isSurenc != wasSurenc) {
|
||||
await this.setEffect(STATUSES.StatusSurEnc, isSurenc)
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
getEncTotal() {
|
||||
return Math.floor(this.encTotal ?? 0);
|
||||
return Math.floor(this.encTotal ?? 0)
|
||||
}
|
||||
|
||||
async createItem(type, name = undefined) {
|
||||
@@ -557,7 +638,7 @@ export class RdDBaseActor extends Actor {
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.computeEncTotal();
|
||||
await this.computeEncTotal()
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -736,7 +817,7 @@ export class RdDBaseActor extends Actor {
|
||||
name: this.getAlias(),
|
||||
system: { description: this.system.description }
|
||||
}
|
||||
foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.hbs', chatData)
|
||||
renderTemplate('systems/foundryvtt-reve-de-dragon/templates/post-actor.hbs', chatData)
|
||||
.then(html => ChatMessage.create(RdDUtility.chatDataSetup(html, modeOverride)));
|
||||
}
|
||||
|
||||
@@ -758,20 +839,24 @@ export class RdDBaseActor extends Actor {
|
||||
getCaracInit(competence) { return 0 }
|
||||
|
||||
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() {
|
||||
return this.itemTypes[ITEM_TYPES.possession]
|
||||
.map(p => {
|
||||
return {
|
||||
name: p.name,
|
||||
label: p.name,
|
||||
action: 'possession',
|
||||
possessionid: p.system.possessionid,
|
||||
}
|
||||
})
|
||||
}
|
||||
listActionsCombat() {
|
||||
const possessions = this.listActionsPossessions()
|
||||
return possessions.length > 0 ? possessions : this.listActions({})
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
import { LIST_CARAC_AUTRES } from "../rdd-carac.js";
|
||||
import { RdDBaseActorSang } from "./base-actor-sang.js";
|
||||
|
||||
export class RdDCreature extends RdDBaseActorSang {
|
||||
@@ -45,5 +43,4 @@ export class RdDCreature extends RdDBaseActorSang {
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet {
|
||||
this.html.find('.resonance-add').click(async event =>
|
||||
await DialogSelect.select({
|
||||
label: "Choisir un acteur à accorder",
|
||||
list: game.actors.filter(it => it.isPersonnage() && it.prototypeToken.actorLink)
|
||||
list: game.actors.filter(it => true)
|
||||
},
|
||||
it => this.resonanceAdd(it.id))
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js";
|
||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js";
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
import { RdDItemBlessure } from "../item/blessure.js";
|
||||
import { Misc } from "../misc.js";
|
||||
import { RdDCarac } from "../rdd-carac.js";
|
||||
import { RdDEncaisser } from "../rdd-roll-encaisser.js";
|
||||
@@ -16,11 +17,10 @@ export class RdDEntite extends RdDBaseActorReve {
|
||||
return item.type == ITEM_TYPES.competencecreature
|
||||
}
|
||||
|
||||
isEntite(typeentite = []) {
|
||||
return (typeentite.length == 0 || typeentite.includes(this.system.definition.typeentite));
|
||||
}
|
||||
|
||||
isNonIncarnee() { return this.isEntite([ENTITE_NONINCARNE]) }
|
||||
isEntite() { return true }
|
||||
isEntiteNonIncarnee() { return this.system.definition.typeentite == ENTITE_NONINCARNE }
|
||||
isEntiteIncarnee() { return [ENTITE_INCARNE, ENTITE_BLURETTE].includes(this.system.definition.typeentite) }
|
||||
isEntiteBlurette() { return this.system.definition.typeentite !== ENTITE_BLURETTE }
|
||||
|
||||
getReveActuel() {
|
||||
return Misc.toInt(this.system.carac.reve?.value)
|
||||
@@ -49,20 +49,20 @@ export class RdDEntite extends RdDBaseActorReve {
|
||||
}
|
||||
|
||||
async remiseANeuf() {
|
||||
await this.removeEffects(e => true);
|
||||
if (!this.isNonIncarnee()) {
|
||||
if (!this.isEntiteNonIncarnee()) {
|
||||
await this.update({
|
||||
'system.sante.endurance.value': this.system.sante.endurance.max
|
||||
});
|
||||
}
|
||||
await this.removeEffects(e => true)
|
||||
}
|
||||
|
||||
isDead() {
|
||||
return this.isNonIncarnee() ? false : this.system.sante.endurance.value <= 0
|
||||
return this.isEntiteNonIncarnee() ? false : this.system.sante.endurance.value <= 0
|
||||
}
|
||||
|
||||
async santeIncDec(name, inc, isCritique = false) {
|
||||
if (name == 'endurance' && !this.isNonIncarnee()) {
|
||||
if (name == 'endurance' && !this.isEntiteNonIncarnee()) {
|
||||
const oldValue = this.system.sante.endurance.value;
|
||||
const endurance = Math.max(0,
|
||||
Math.min(oldValue + inc,
|
||||
@@ -78,7 +78,7 @@ export class RdDEntite extends RdDBaseActorReve {
|
||||
}
|
||||
|
||||
async encaisser() {
|
||||
if (this.isNonIncarnee()) {
|
||||
if (this.isEntiteNonIncarnee()) {
|
||||
return
|
||||
}
|
||||
await RdDEncaisser.encaisser(this)
|
||||
@@ -89,15 +89,19 @@ export class RdDEntite extends RdDBaseActorReve {
|
||||
}
|
||||
|
||||
async onAppliquerJetEncaissement(encaissement, attackerToken) {
|
||||
if (this.isEntiteNonIncarnee()) {
|
||||
return
|
||||
}
|
||||
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance);
|
||||
foundry.utils.mergeObject(encaissement, {
|
||||
resteEndurance: perteEndurance.newValue,
|
||||
endurance: perteEndurance.perte
|
||||
});
|
||||
endurance: perteEndurance.perte,
|
||||
blessure: RdDItemBlessure.prepareBlessure(encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken)
|
||||
})
|
||||
}
|
||||
|
||||
isEntiteAccordee(attacker) {
|
||||
if (this.isEntite([ENTITE_INCARNE])) {
|
||||
if (this.isEntiteIncarnee()) {
|
||||
let resonnance = this.system.sante.resonnance
|
||||
return (resonnance.actors.find(it => it == attacker.id))
|
||||
}
|
||||
@@ -106,7 +110,7 @@ export class RdDEntite extends RdDBaseActorReve {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async setEntiteReveAccordee(actor) {
|
||||
if (this.isEntite([ENTITE_INCARNE])) {
|
||||
if (this.isEntiteIncarnee()) {
|
||||
if (this.system.sante.resonnance.actors.find(it => it == actor.id)) {
|
||||
// déjà accordé
|
||||
return
|
||||
|
||||
@@ -29,7 +29,7 @@ export class ExperienceLog {
|
||||
};
|
||||
console.log('ExperienceLog.add', newXpLog)
|
||||
const newExperienceLog = (actor.system.experiencelog ?? []).concat([newXpLog]);
|
||||
await actor.update({ [`system.experiencelog`]: newExperienceLog });
|
||||
await actor.update({ [`system.experiencelog`]: newExperienceLog }, { noHook: true });
|
||||
}
|
||||
|
||||
static labelTopic(topic) {
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
import { ACTOR_TYPES, ITEM_TYPES } from "../../constants.js"
|
||||
import { Grammar } from "../../grammar.js"
|
||||
import { RdDItemArme } from "../../item/arme.js"
|
||||
import { CATEGORIES_COMPETENCE_COMBAT } from "../../item/base-items.js"
|
||||
import { Misc } from "../../misc.js"
|
||||
import { RdDTimestamp } from "../../time/rdd-timestamp.js"
|
||||
import { PDFDocument } from "./pdf-lib/pdf-lib.esm.js"
|
||||
|
||||
|
||||
|
||||
const copyProperty = (actor, path) => foundry.utils.getProperty(actor, path)
|
||||
|
||||
// const findItem = (actor, itemType, itemName) => actor.itemTypes[itemType].find(it => Grammar.equalsInsensitive(formCompName(it.name), formCompName(itemName)))
|
||||
// const findItemPos = (actor, itemType, pos) => actor.itemTypes[itemType].length <= pos ? actor.itemTypes[itemType][pos] : length
|
||||
// const findProperty = (it, path) => it ? foundry.utils.getProperty(it, path) : undefined
|
||||
|
||||
// const findItemProperty = (actor, itemType, itemName, path) => findProperty(findItem(actor, itemType, itemName), path)
|
||||
// const findItemPosProperty = (actor, itemType, pos, path) => findProperty(findItemPos(actor, itemType, pos), path)
|
||||
|
||||
// const findArmeProperty = (actor, pos, path) => findProperty(findItemPos(actor, ITEM_TYPES.arme, pos), path)
|
||||
// const findSortProperty = (actor, pos, path) => findProperty(findItemPos(actor, ITEM_TYPES.sort, pos), path)
|
||||
|
||||
// const itemFormPath = (type, pos, property) => `${type}s.${pos}.${property}`
|
||||
|
||||
|
||||
const ACTOR_TO_FORM_MAPPING = [
|
||||
{ path: 'name' },
|
||||
{ path: 'system.carac.taille.value' },
|
||||
{ path: 'system.carac.apparence.value' },
|
||||
{ path: 'system.carac.apparence.xp' },
|
||||
{ path: 'system.carac.constitution.value' },
|
||||
{ path: 'system.carac.constitution.xp' },
|
||||
{ path: 'system.carac.force.value' },
|
||||
{ path: 'system.carac.force.value' },
|
||||
{ path: 'system.carac.force.xp' },
|
||||
{ path: 'system.carac.agilite.value' },
|
||||
{ path: 'system.carac.agilite.xp' },
|
||||
{ path: 'system.carac.dexterite.value' },
|
||||
{ path: 'system.carac.dexterite.xp' },
|
||||
{ path: 'system.carac.vue.value' },
|
||||
{ path: 'system.carac.vue.xp' },
|
||||
{ path: 'system.carac.ouie.value' },
|
||||
{ path: 'system.carac.ouie.xp' },
|
||||
{ path: 'system.carac.odoratgout.value' },
|
||||
{ path: 'system.carac.odoratgout.xp' },
|
||||
{ path: 'system.carac.volonte.value' },
|
||||
{ path: 'system.carac.volonte.xp' },
|
||||
{ path: 'system.carac.empathie.value' },
|
||||
{ path: 'system.carac.empathie.xp' },
|
||||
{ path: 'system.carac.intellect.value' },
|
||||
{ path: 'system.carac.intellect.xp' },
|
||||
{ path: 'system.carac.reve.value' },
|
||||
{ path: 'system.carac.reve.xp' },
|
||||
{ path: 'system.carac.chance.value' },
|
||||
{ path: 'system.carac.chance.xp' },
|
||||
|
||||
{ path: 'system.age' },
|
||||
{ path: 'system.sexe' },
|
||||
{ path: 'system.taille' },
|
||||
{ path: 'system.poids' },
|
||||
{ path: 'system.cheveux' },
|
||||
{ path: 'system.yeux' },
|
||||
{ path: 'system.beaute' },
|
||||
{ path: 'system.main' },
|
||||
{ path: 'system.heure' },
|
||||
{ path: 'computed.hn.heure', getter: actor => (RdDTimestamp.definition(actor.system.heure)?.heure ?? 0) + 1 },
|
||||
{ path: 'computed.hn.label', getter: actor => RdDTimestamp.definition(actor.system.heure)?.avecArticle },
|
||||
|
||||
{ path: 'system.carac.melee.value' },
|
||||
{ path: 'system.carac.tir.value' },
|
||||
{ path: 'system.carac.lancer.value' },
|
||||
{ path: 'system.carac.derobee.value' },
|
||||
{ path: 'system.sante.vie.value' },
|
||||
{ path: 'system.sante.endurance.value' },
|
||||
|
||||
{ path: 'system.attributs.sust.value' },
|
||||
{ path: 'system.attributs.sconst.value' },
|
||||
{ path: 'system.attributs.encombrement.value' },
|
||||
{ path: 'system.attributs.plusdom.value', getter: actor => Misc.toSignedString(actor.system.attributs.plusdom.value) },
|
||||
|
||||
// , getter: actor => actor.get
|
||||
]
|
||||
|
||||
export default class ExportPdf {
|
||||
|
||||
static init() {
|
||||
Hooks.on("getActorContextOptions", (actorDirectory, menus) => { ExportPdf.onActorDirectoryMenu(actorDirectory, menus) })
|
||||
}
|
||||
|
||||
static onActorDirectoryMenu(actorDirectory, menus) {
|
||||
menus.push({
|
||||
name: 'Export PDF',
|
||||
icon: '<i class="fa-regular fa-file-pdf"></i>',
|
||||
condition: target => actorDirectory.id == 'actors' && ExportPdf.$isActorPersonnage(this.$getActor(target)),
|
||||
callback: async target => await ExportPdf.exportActor(target)
|
||||
})
|
||||
}
|
||||
|
||||
static $getActor(target) {
|
||||
const entryId = $(target).closest(".directory-item")?.data("entryId")
|
||||
return game.actors.get(entryId)
|
||||
}
|
||||
|
||||
static $isActorPersonnage(actor) {
|
||||
return actor?.type == ACTOR_TYPES.personnage
|
||||
}
|
||||
|
||||
static async exportActor(target) {
|
||||
const actor = ExportPdf.$getActor(target)
|
||||
if (!ExportPdf.$isActorPersonnage(actor)) {
|
||||
ui.notifications.error("Pas de personnage sélectionné")
|
||||
return
|
||||
}
|
||||
const templatePdf = '/systems/foundryvtt-reve-de-dragon/assets/feuille-personnage.pdf';
|
||||
|
||||
const pdfBytes = await fetch(templatePdf).then(res => res.arrayBuffer())
|
||||
const pdfDoc = await PDFDocument.load(pdfBytes)
|
||||
|
||||
const exporter = new ExportPdf(actor, pdfDoc)
|
||||
exporter.generateFeuillePersonnage()
|
||||
}
|
||||
|
||||
constructor(actor, pdfDoc) {
|
||||
this.pdfDoc = pdfDoc
|
||||
this.form = this.pdfDoc.getForm()
|
||||
this.actor = actor
|
||||
this.allComps = this.actor.itemTypes[ITEM_TYPES.competence]
|
||||
this.comps = this.allComps
|
||||
.filter(it => !it.isNiveauBase())
|
||||
.sort(Misc.ascending(it => it.name))
|
||||
|
||||
this.compsNonArmes = this.comps.filter(it => !ExportPdf.isCompCombat(it))
|
||||
this.compsArmes = this.comps.filter(it => ExportPdf.isCompCombat(it))
|
||||
this.addedComps = new Set([])
|
||||
}
|
||||
|
||||
static isCompCombat(comp) {
|
||||
return CATEGORIES_COMPETENCE_COMBAT.includes(comp.system.categorie) && !Grammar.includesLowerCaseNoAccent(comp.name, "corps à corps") && !Grammar.includesLowerCaseNoAccent(comp.name, "esquive")
|
||||
}
|
||||
|
||||
async generateFeuillePersonnage() {
|
||||
|
||||
this.$exportActorFields()
|
||||
this.$exportCompetences()
|
||||
this.$exportArchetype()
|
||||
this.$exportArmes()
|
||||
this.$exportSorts()
|
||||
|
||||
const pdfBytes = await this.pdfDoc.save();
|
||||
const filename = `rdd-${this.actor.name.slugify()}.pdf`;
|
||||
foundry.utils.saveDataToFile(pdfBytes, "application/pdf", filename);
|
||||
}
|
||||
|
||||
$exportActorFields() {
|
||||
ACTOR_TO_FORM_MAPPING.forEach(async (mapping) => {
|
||||
const path = mapping.path
|
||||
const value = mapping.getter ? mapping.getter(this.actor) : copyProperty(this.actor, path)
|
||||
this.$setFormValue(path, value)
|
||||
})
|
||||
}
|
||||
|
||||
$exportCompetences() {
|
||||
this.compsNonArmes
|
||||
.filter(it => !this.addedComps.has(it.id))
|
||||
.forEach(comp => {
|
||||
const formCompName = Grammar.toLowerCaseNoAccent(comp.name.replaceAll(/(\s|-|\')/g, '_'))
|
||||
this.$setFormCompetence(formCompName, comp)
|
||||
})
|
||||
const musique = this.compsNonArmes.filter(it => Grammar.includesLowerCaseNoAccent(it.name, 'musique'))
|
||||
.sort(Misc.descending(it => it.system.niveau))
|
||||
.filter(it => !this.addedComps.has(it.id))
|
||||
.find(it => true)
|
||||
if (musique) {
|
||||
this.$setFormCompetence('musique', musique)
|
||||
}
|
||||
}
|
||||
|
||||
$exportArchetype() {
|
||||
this.allComps.sort(Misc.ascending(it => it.system.niveau_archetype))
|
||||
.forEach(comp => {
|
||||
let formCompName = Grammar.toLowerCaseNoAccent(comp.name.replaceAll(/(\s|-|\')/g, '_'))
|
||||
if (formCompName.includes('musique')) {
|
||||
formCompName = 'musique'
|
||||
}
|
||||
this.$setFormValue(`competences.${formCompName}.niveau_archetype`, comp.system.niveau_archetype)
|
||||
})
|
||||
}
|
||||
|
||||
$setFormCompetenceArchetype(formCompName, comp, baseFormName = 'competences') {
|
||||
}
|
||||
|
||||
$exportArmes() {
|
||||
const uniques = new Set([])
|
||||
const armes = this.actor.itemTypes[ITEM_TYPES.arme].map(arme => arme.getTypeAttaques()
|
||||
.map(main => {
|
||||
const compName = arme.getCompetenceAction(main)
|
||||
const dommages = RdDItemArme.valeurMain(arme.system.dommages, main)
|
||||
const forceRequise = RdDItemArme.valeurMain(arme.system.force ?? 0, main)
|
||||
const comp = this.compsArmes.find(it => Grammar.equalsInsensitive(it.name, compName)) ?? this.actor.findItemLike(compName, ITEM_TYPES.competence)
|
||||
const unique = [comp.id, arme.name, dommages, forceRequise].join('|');
|
||||
if (uniques.has(unique)) {
|
||||
return undefined
|
||||
}
|
||||
uniques.add(unique)
|
||||
return { arme: arme, comp: comp, main: main }
|
||||
}))
|
||||
.reduce((a, b) => a.concat(b))
|
||||
.filter(it => it != undefined && !it.comp.isNiveauBase())
|
||||
.sort(Misc.descending(it => it.comp.niveau))
|
||||
|
||||
for (let pos = 0; pos < armes.length; pos++) {
|
||||
const it = armes[pos]
|
||||
this.$setFormArmeCompetence(pos, it.comp, it.arme, it.main, it.main)
|
||||
}
|
||||
|
||||
// TODO: list comps without weapons
|
||||
// TODO: list other comps not in the standard list -- use an instance of ExportPdf to hold state/built list
|
||||
const otherComps = this.comps.filter(it => !this.addedComps.has(it.id))
|
||||
for (let pos = 0; pos < otherComps.length; pos++) {
|
||||
const comp = otherComps[pos]
|
||||
this.$setFormCompetence(pos, comp, 'competences')
|
||||
this.$setFormValue(`competences.${pos}.name`, comp.name)
|
||||
}
|
||||
}
|
||||
|
||||
$setFormCompetence(formCompName, comp, baseFormName = 'competences') {
|
||||
|
||||
if (this.form.getFieldMaybe(`${baseFormName}.${formCompName}.niveau`)) {
|
||||
this.addedComps.add(comp.id)
|
||||
}
|
||||
if (comp.system.niveau != comp.system.base) {
|
||||
this.$setFormValue(`${baseFormName}.${formCompName}.niveau`, comp.system.niveau)
|
||||
}
|
||||
if (comp.system.xp > 0) {
|
||||
this.$setFormValue(`${baseFormName}.${formCompName}.xp`, comp.system.xp)
|
||||
}
|
||||
if (comp.system.xp_sort > 0) {
|
||||
this.$setFormValue(`${baseFormName}.${formCompName}.xp_sort`, comp.system.xp_sort)
|
||||
}
|
||||
if (CATEGORIES_COMPETENCE_COMBAT.includes(comp.system.categorie)) {
|
||||
this.$setFormValue(`${baseFormName}.${formCompName}.init`, comp.getBaseInit())
|
||||
}
|
||||
}
|
||||
|
||||
$setFormArmeCompetence(pos, comp, arme, main) {
|
||||
this.$setFormCompetence(pos, comp, 'armes')
|
||||
this.$setFormValue(`armes.${pos}.name`, arme.name)
|
||||
this.$setFormValue(`armes.${pos}.main`, main)
|
||||
this.$setFormValue(`armes.${pos}.plusdom`, RdDItemArme.valeurMain(arme.system.dommages, main))
|
||||
}
|
||||
|
||||
$exportSorts() {
|
||||
const sorts = this.actor.itemTypes[ITEM_TYPES.sort].sort(Misc.ascending(s => ExportPdf.$orderDraconic(s) + s.name))
|
||||
|
||||
for (let pos = 0; pos < sorts.length; pos++) {
|
||||
const sort = sorts[pos]
|
||||
this.$setFormSort(pos, sort)
|
||||
}
|
||||
}
|
||||
|
||||
$setFormSort(pos, sort) {
|
||||
this.$setFormValue(`sorts.${pos}.name`, sort.name)
|
||||
this.$setFormValue(`sorts.${pos}.voie`, sort.system.draconic)
|
||||
this.$setFormValue(`sorts.${pos}.tmr`, sort.system.caseTMRSpeciale ?? sort.system.caseTMR)
|
||||
this.$setFormValue(`sorts.${pos}.diff`, sort.system.difficulte)
|
||||
this.$setFormValue(`sorts.${pos}.reve`, sort.system.ptreve)
|
||||
this.$setFormValue(`sorts.${pos}.bonuscase`, sort.system.bonuscase)
|
||||
}
|
||||
|
||||
static $orderDraconic(s) {
|
||||
switch (s.system.draconic.substring(0, 1)) {
|
||||
case 'O': return 1
|
||||
case 'H': return 2
|
||||
case 'N': return 3
|
||||
case 'T': return 4
|
||||
}
|
||||
return 5
|
||||
}
|
||||
|
||||
$setFormValue(path, value) {
|
||||
const hasField = this.form.getFieldMaybe(path)
|
||||
if (hasField && value != undefined) {
|
||||
const field = this.form.getTextField(path)
|
||||
field.setText(value.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { SYSTEM_RDD } from "../../constants.js";
|
||||
import { Misc } from "../../misc.js";
|
||||
import { EXPORT_CSV_SCRIPTARIUM, OptionsAvancees } from "../../settings/options-avancees.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 {
|
||||
static init() {
|
||||
@@ -44,7 +44,7 @@ export class RdDActorExportSheet extends RdDActorSheet {
|
||||
formData.context = Mapping.prepareContext(this.actor)
|
||||
formData.attaques = this.actor.listActionsAttaque()
|
||||
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)
|
||||
const legeres = this.actor.nbBlessuresLegeres()
|
||||
const graves = this.actor.nbBlessuresGraves()
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { Grammar } from "../../grammar.js"
|
||||
import { RdDItemArme } from "../../item/arme.js"
|
||||
import { EMPOIGNADE, RdDItemArme } from "../../item/arme.js"
|
||||
import { RdDItemCompetence } from "../../item-competence.js"
|
||||
import { RdDItemSort } from "../../item-sort.js"
|
||||
import { ITEM_TYPES } from "../../constants.js"
|
||||
import { ITEM_TYPES, RDD_CONFIG } from "../../constants.js"
|
||||
import { Misc } from "../../misc.js"
|
||||
import { RdDTimestamp } from "../../time/rdd-timestamp.js"
|
||||
import { RdDBonus } from "../../rdd-bonus.js"
|
||||
import { TMRType } from "../../tmr-utility.js"
|
||||
|
||||
|
||||
export const CATEGORIES_COMPETENCES = [
|
||||
export const CATEGORIES_COMPETENCES_BASE = [
|
||||
"generale",
|
||||
"particuliere",
|
||||
"specialisee",
|
||||
@@ -88,7 +88,7 @@ const MAPPING_BASE = [
|
||||
{ column: "endurance_actuel", rollClass: 'jet-endurance', getter: (actor, context) => actor.system.sante.endurance.value },
|
||||
{ column: "esquive", getter: (actor, context) => Mapping.getEsquive(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) },
|
||||
]
|
||||
|
||||
@@ -141,7 +141,7 @@ export class Mapping {
|
||||
|
||||
static prepareArmes(actor) {
|
||||
const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme)
|
||||
armes.push(RdDItemArme.corpsACorps(actor));
|
||||
armes.push(RdDItemArme.pugilat(actor));
|
||||
armes.push(RdDItemArme.empoignade(actor));
|
||||
return armes.map(arme => [
|
||||
arme.system.unemain ? Mapping.prepareArme(actor, arme, '(1 main)') : undefined,
|
||||
@@ -160,7 +160,7 @@ export class Mapping {
|
||||
return undefined
|
||||
}
|
||||
const categorie = Mapping.complementCategorie(arme, maniement)
|
||||
const dommages = Mapping.dommagesArme(actor, arme, maniement)
|
||||
const dommages = Mapping.dommages(actor, arme, maniement)
|
||||
return {
|
||||
name: arme.name + categorie,
|
||||
niveau: Misc.toSignedString(competence.system.niveau),
|
||||
@@ -170,12 +170,13 @@ export class Mapping {
|
||||
arme: arme
|
||||
}
|
||||
}
|
||||
static dommagesArme(actor, arme, maniement) {
|
||||
|
||||
static dommages(actor, arme, maniement) {
|
||||
const dmgArme = RdDItemArme.dommagesReels(arme, maniement)
|
||||
const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme))
|
||||
switch (arme.system.mortalite) {
|
||||
case 'non-mortel': return `(${dommages})`
|
||||
case 'empoignade': return '-'
|
||||
case RDD_CONFIG.encaissement.nonmortel: return `(${dommages})`
|
||||
case RDD_CONFIG.encaissement.empoignade: return '-'
|
||||
}
|
||||
return dommages
|
||||
}
|
||||
@@ -274,11 +275,10 @@ export class Mapping {
|
||||
}
|
||||
|
||||
static getDescription(actor) {
|
||||
const sexe = actor.system.sexe
|
||||
const sexeFeminin = sexe.length > 0 && sexe.charAt(0).toLowerCase() == 'f' ? 'Née' : 'Né'
|
||||
const naissance = actor.isFeminin() ? 'née' : 'né'
|
||||
const race = ['', 'humain'].includes(Grammar.toLowerCaseNoAccent(actor.system.race)) ? '' : (actor.system.race + ' ')
|
||||
const heure = actor.system.heure
|
||||
const hn = `${sexeFeminin} à l'heure ${RdDTimestamp.definition(heure).avecArticle}`
|
||||
const hn = `${naissance} à l'heure ${RdDTimestamp.definition(heure).avecArticle}`
|
||||
const age = (actor.system.age && actor.system.age >0) ? `${actor.system.age} ans` : undefined
|
||||
const taille = actor.system.taille
|
||||
const poids = actor.system.poids
|
||||
|
||||
@@ -20,14 +20,15 @@ const PATHS = [
|
||||
const RANDOM_VALUES = {
|
||||
'system.sexe': { 'masculin': 1, 'féminin': 1 },
|
||||
'system.main': { 'droitier': 51, 'gaucher': 15, 'ambidextre': 6 },
|
||||
'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains clair': 5, 'blonds': 4, 'blonds très clair': 1, 'roux carotte': 1, 'roux cuivré': 3 },
|
||||
'system.yeux': { 'noirs': 2, 'noisettes': 3, 'bruns vert': 4, 'verts': 3, 'bleus clair': 3, 'bleus gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 },
|
||||
'system.cheveux': { 'noirs': 2, 'bruns': 5, 'châtains': 3, 'châtain clair': 5, 'blonds': 4, 'blond platine': 1, 'roux carotte': 1, 'roux cuivré': 3, 'chauve': 1 },
|
||||
'system.yeux': { 'noirs': 2, 'noisette': 3, 'brun-vert': 4, 'verts': 3, 'bleu clair': 3, 'bleu gris': 2, 'gris': 1, 'mauves': 1, 'indigos': 1 },
|
||||
}
|
||||
|
||||
export class AppPersonnageAleatoire extends FormApplication {
|
||||
static preloadHandlebars() {
|
||||
foundry.applications.handlebars.loadTemplates([
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/random/champ-aleatoire.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/actor/random/sexe-aleatoire.hbs',
|
||||
])
|
||||
}
|
||||
|
||||
@@ -49,14 +50,14 @@ export class AppPersonnageAleatoire extends FormApplication {
|
||||
this.current = foundry.utils.duplicate(actor)
|
||||
this.checked = {
|
||||
'name': false,
|
||||
'system.sexe': true,
|
||||
'system.age': true,
|
||||
'system.taille': true,
|
||||
'system.poids': true,
|
||||
'system.main': true,
|
||||
'system.heure': true,
|
||||
'system.cheveux': true,
|
||||
'system.yeux': true
|
||||
'system.sexe': (this.actor.system.sexe ?? '') == '',
|
||||
'system.age': this.actor.system.age == 0,
|
||||
'system.taille': (this.actor.system.taille ?? '') == '',
|
||||
'system.poids': (this.actor.system.poids ?? '') == '',
|
||||
'system.main': (this.actor.system.main ?? '') == '',
|
||||
'system.heure': (this.actor.system.heure ?? '') == '',
|
||||
'system.cheveux': (this.actor.system.cheveux ?? '') == '',
|
||||
'system.yeux': (this.actor.system.yeux ?? '') == '',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +77,8 @@ export class AppPersonnageAleatoire extends FormApplication {
|
||||
this.html.find("button.button-apply").click(async event => await this.onApply())
|
||||
this.html.find("input.current-value").change(async event => await this.onChange(event))
|
||||
this.html.find("div.random-field[data-path='system.heure'] select.current-value").change(async event => await this.onChange(event))
|
||||
this.html.find('a[data-action="sexe-masculin"]').click(async event => await this.onSexe('masculin'))
|
||||
this.html.find('a[data-action="sexe-feminin"]').click(async event => await this.onSexe('féminin'))
|
||||
this.html.find("a.random").click(async event => await this.onRandom(event))
|
||||
this.html.find("a.reset").click(async event => await this.onReset(event))
|
||||
this.html.find("a.randomize-selected").click(async event => await this.onRandomizeSelected())
|
||||
@@ -96,6 +99,10 @@ export class AppPersonnageAleatoire extends FormApplication {
|
||||
const fields = this.html.find(selector).parents("div.random-field:first")
|
||||
return fields[0].attributes['data-path'].value
|
||||
}
|
||||
async onSexe(sexe) {
|
||||
this.current['system.sexe'] = sexe
|
||||
this.render()
|
||||
}
|
||||
|
||||
async onChange(event) {
|
||||
const path = this.getPath(event.currentTarget)
|
||||
@@ -180,8 +187,9 @@ export class AppPersonnageAleatoire extends FormApplication {
|
||||
const variation = Math.floor((caracTaille.poidsMax - caracTaille.poidsMin + base / 5) / 2)
|
||||
const total = await RdDDice.rollTotal(`2d${variation} + ${base}`)
|
||||
const cm = total % 100
|
||||
const dm = cm < 10 ? '0' : ''
|
||||
const m = (total - cm) / 100
|
||||
return `${m}m${cm}`
|
||||
return `${m}m${dm}${cm}`
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "../../constants.js";
|
||||
|
||||
export class TextRollManager {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Misc } from "./misc.js";
|
||||
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js";
|
||||
|
||||
@@ -106,6 +106,25 @@ export class ChatUtility {
|
||||
return await ChatMessage.create(messageData)
|
||||
}
|
||||
|
||||
static tellToUser(message) {
|
||||
ChatMessage.create({ content: message, user: game.user.id, whisper: [game.user.id] });
|
||||
}
|
||||
|
||||
static tellToGM(message) {
|
||||
ChatMessage.create({
|
||||
user: game.user.id,
|
||||
content: message,
|
||||
whisper: ChatUtility.getGMs()
|
||||
});
|
||||
}
|
||||
|
||||
static tellToUserAndGM(message) {
|
||||
ChatMessage.create({
|
||||
user: game.user.id,
|
||||
content: message,
|
||||
whisper: ChatUtility.getUserAndGMs()
|
||||
})
|
||||
}
|
||||
static getOwners(document) {
|
||||
return document ? game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) : [game.user]
|
||||
}
|
||||
@@ -190,15 +209,19 @@ export class ChatUtility {
|
||||
if (rddTimestamp) {
|
||||
const timestamp = new RdDTimestamp(rddTimestamp);
|
||||
const timestampData = timestamp.toCalendrier();
|
||||
const dateHeure = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData);
|
||||
$(html).find('header.message-header .message-sender').after(dateHeure)
|
||||
const dateHeure = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData);
|
||||
$(html).find('header.message-header .message-timestamp').after(dateHeure)
|
||||
}
|
||||
}
|
||||
|
||||
static async onCreateChatMessage(chatMessage, options, id) {
|
||||
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 }) })
|
||||
}
|
||||
}
|
||||
|
||||
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 { ChatUtility } from "../chat-utility.js";
|
||||
import { renderTemplate } from "../constants.js";
|
||||
|
||||
const INFO_COEUR = 'info-coeur';
|
||||
|
||||
|
||||
@@ -9,47 +9,69 @@ export const ENTITE_INCARNE = 'incarne'
|
||||
export const ENTITE_NONINCARNE = 'nonincarne'
|
||||
export const ENTITE_BLURETTE = 'blurette'
|
||||
|
||||
export const renderTemplate = foundry.applications.handlebars.renderTemplate
|
||||
|
||||
export const RDD_CONFIG = {
|
||||
niveauEthylisme : [
|
||||
{value: "1", label: "Aucun"},
|
||||
{value: "0", label: "Eméché (0)"},
|
||||
{value: "-1", label: "Gris (-1)"},
|
||||
{value: "-2", label: "Pinté (-2)"},
|
||||
{value: "-3", label: "Pas Frais (-3)"},
|
||||
{value: "-4", label: "Ivre (-4)"},
|
||||
{value: "-5", label: "Bu (-5)"},
|
||||
{value: "-6", label: "Complètement fait (-6)"},
|
||||
{value: "-7", label: "Ivre mort (-7)"}
|
||||
niveauEthylisme: [
|
||||
{ value: '1', label: 'Aucun' },
|
||||
{ value: '0', label: 'Eméché (0)' },
|
||||
{ value: '-1', label: 'Gris (-1)' },
|
||||
{ value: '-2', label: 'Pinté (-2)' },
|
||||
{ value: '-3', label: 'Pas Frais (-3)' },
|
||||
{ value: '-4', label: 'Ivre (-4)' },
|
||||
{ value: '-5', label: 'Bu (-5)' },
|
||||
{ value: '-6', label: 'Complètement fait (-6)' },
|
||||
{ value: '-7', label: 'Ivre mort (-7)' }
|
||||
],
|
||||
categorieEntite: {
|
||||
"cauchemar": "Cauchemar",
|
||||
"reve": "Rêve"
|
||||
'cauchemar': 'Cauchemar',
|
||||
'reve': 'Rêve'
|
||||
},
|
||||
typeEntite: {
|
||||
"incarne": "Incarnée",
|
||||
"nonincarne": "Non Incarnée",
|
||||
"blurette": "Blurette"
|
||||
[ENTITE_INCARNE]: 'Incarnée',
|
||||
[ENTITE_NONINCARNE]: 'Non Incarnée',
|
||||
[ENTITE_BLURETTE]: 'Blurette'
|
||||
},
|
||||
heuresRdD : [
|
||||
{value : "vaisseau", label: "Vaisseau", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd01.webp"},
|
||||
{value : "sirene", label: "Sirène", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd02.webp"},
|
||||
{value : "faucon", label: "Faucon", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd03.webp"},
|
||||
{value : "couronne", label: "Couronne", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd04.webp"},
|
||||
{value : "dragon", label: "Dragon", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd05.webp"},
|
||||
{value : "epees", label: "Epées", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd06.webp"},
|
||||
{value : "lyre", label: "Lyre", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd07.webp"},
|
||||
{value : "serpent", label: "Serpent", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd08.webp"},
|
||||
{value : "poissonacrobate", label: "Poisson Acrobate", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd09.webp"},
|
||||
{value : "araignee", label: "Araignée", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd10.webp"},
|
||||
{value : "roseau", label: "Roseau", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd11.webp"},
|
||||
{value : "chateaudormant", label: "Chateau Dormant", img: "modules/foundryvtt-reve-de-dragon/icons/heures/hd12.webp"}
|
||||
heuresRdD: [
|
||||
{ value: 'vaisseau', label: 'Vaisseau', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd01.webp' },
|
||||
{ value: 'sirene', label: 'Sirène', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd02.webp' },
|
||||
{ value: 'faucon', label: 'Faucon', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd03.webp' },
|
||||
{ value: 'couronne', label: 'Couronne', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd04.webp' },
|
||||
{ value: 'dragon', label: 'Dragon', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd05.webp' },
|
||||
{ value: 'epees', label: 'Epées', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd06.webp' },
|
||||
{ value: 'lyre', label: 'Lyre', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd07.webp' },
|
||||
{ value: 'serpent', label: 'Serpent', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd08.webp' },
|
||||
{ value: 'poissonacrobate', label: 'Poisson Acrobate', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd09.webp' },
|
||||
{ value: 'araignee', label: 'Araignée', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd10.webp' },
|
||||
{ value: 'roseau', label: 'Roseau', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd11.webp' },
|
||||
{ value: 'chateaudormant', label: 'Chateau Dormant', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.webp' }
|
||||
],
|
||||
raretes: [
|
||||
{value: "Commune", label: "Commune"},
|
||||
{value: "Frequente", label: "Fréquente"},
|
||||
{value: "Rare", label: "Rare"},
|
||||
{value: "Rarissime", label: "Rarissime"}
|
||||
]
|
||||
{ value: 'Commune', label: 'Commune' },
|
||||
{ value: 'Frequente', label: 'Fréquente' },
|
||||
{ value: 'Rare', label: 'Rare' },
|
||||
{ value: 'Rarissime', label: 'Rarissime' }
|
||||
],
|
||||
particuliere: {
|
||||
force: { key: 'force', descr: 'en force', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-force.svg' },
|
||||
finesse: { key: 'finesse', descr: 'en finesse', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-finesse.svg' },
|
||||
rapidite: { key: 'rapidite', descr: 'en rapidité', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-rapidite.svg' },
|
||||
},
|
||||
icons: {
|
||||
armesDisparates: 'systems/foundryvtt-reve-de-dragon/assets/actions/armes-disparates.svg',
|
||||
demiReve: 'systems/foundryvtt-reve-de-dragon/assets/actions/sort.svg',
|
||||
empoignade: 'systems/foundryvtt-reve-de-dragon/assets/actions/empoignade.svg',
|
||||
forceWeak: 'systems/foundryvtt-reve-de-dragon/assets/actions/weak.svg',
|
||||
surenc: 'systems/foundryvtt-reve-de-dragon/assets/actions/surenc.svg',
|
||||
magique: 'systems/foundryvtt-reve-de-dragon/assets/actions/magique.svg',
|
||||
armebrisee: 'systems/foundryvtt-reve-de-dragon/assets/actions/arme-brisee.svg',
|
||||
},
|
||||
encaissement: {
|
||||
mortel: 'mortel',
|
||||
nonmortel: 'non-mortel',
|
||||
entiteincarnee: 'entiteincarnee',
|
||||
empoignade: 'empoignade'
|
||||
}
|
||||
}
|
||||
|
||||
export const ACTOR_TYPES = {
|
||||
@@ -106,3 +128,4 @@ export const ITEM_TYPES = {
|
||||
nombreastral: 'nombreastral',
|
||||
extraitpoetique: 'extraitpoetique',
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js"
|
||||
|
||||
export class DialogChoixXpCarac extends Dialog {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SYSTEM_RDD } from "./constants.js";
|
||||
import { renderTemplate, SYSTEM_RDD } from "./constants.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { RdDItemSigneDraconique } from "./item/signedraconique.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
export class DialogConsommer extends Dialog {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js"
|
||||
|
||||
export class DialogSelect extends Dialog {
|
||||
static extractIdNameImg(it) { return { id: it.id, name: it.name, img: it.img } }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Misc } from "./misc.js";
|
||||
import { renderTemplate } from "./constants.js";
|
||||
|
||||
export class DialogSplitItem extends Dialog {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { HIDE_DICE, SHOW_DICE } from "./constants.js";
|
||||
import { HIDE_DICE, renderTemplate, SHOW_DICE } from "./constants.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
|
||||
/**
|
||||
@@ -7,18 +7,17 @@ import { RdDUtility } from "./rdd-utility.js";
|
||||
*/
|
||||
export class DialogValidationEncaissement extends Dialog {
|
||||
|
||||
static async validerEncaissement(actor, rollData, armure, onEncaisser) {
|
||||
const encaissement = await RdDUtility.jetEncaissement(actor, rollData, armure, { showDice: HIDE_DICE });
|
||||
static async validerEncaissement(actor, dmg, armure, onEncaisser) {
|
||||
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', {
|
||||
actor: actor,
|
||||
rollData: rollData,
|
||||
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
|
||||
let buttons = {
|
||||
"valider": { label: "Valider", callback: html => this.onValider() },
|
||||
@@ -42,11 +41,11 @@ export class DialogValidationEncaissement extends Dialog {
|
||||
super(dialogConf, dialogOptions);
|
||||
|
||||
this.actor = actor
|
||||
this.rollData = rollData;
|
||||
this.armure = armure;
|
||||
this.encaissement = encaissement;
|
||||
this.onEncaisser = onEncaisser;
|
||||
this.forceDiceResult = {total: encaissement.roll.result };
|
||||
this.dmg = dmg
|
||||
this.armure = armure
|
||||
this.encaissement = encaissement
|
||||
this.onEncaisser = onEncaisser
|
||||
this.forceDiceResult = {total: encaissement.roll.result }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -55,14 +54,14 @@ export class DialogValidationEncaissement extends Dialog {
|
||||
this.html = html;
|
||||
this.html.find('input.encaissement-roll-result').keyup(async event => {
|
||||
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-blessure').text(this.encaissement.blessures)
|
||||
});
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ITEM_TYPES } from "../constants.js"
|
||||
import { ITEM_TYPES, renderTemplate } from "../constants.js"
|
||||
import { RdDItemSort } from "../item-sort.js"
|
||||
import { Misc } from "../misc.js"
|
||||
|
||||
|
||||
@@ -1,7 +1,66 @@
|
||||
export const MAP_PHASE = {
|
||||
possession: { label: "possession", rang: 10 },
|
||||
draconic: { label: "draconic", rang: 9 },
|
||||
tir: { label: "tir", rang: 8 },
|
||||
lancer: { label: "lancer", rang: 7 },
|
||||
arme: { label: "mêlée", rang: 5 },
|
||||
pugilat: { label: "pugilat", rang: 4 },
|
||||
naturelle: { label: "créature", rang: 4 },
|
||||
empoignade: { label: "empoignade", rang: 3 },
|
||||
autre: { label: "autre action", rang: 2 },
|
||||
demi: { label: "demi-surprise", rang: 0 },
|
||||
totale: { label: "surprise totale", rang: -1 },
|
||||
}
|
||||
export const PHASE = Object.values(MAP_PHASE)
|
||||
|
||||
export class RdDInitiative {
|
||||
|
||||
static calculInitiative(niveau, caracValue, bonus = 0) {
|
||||
let base = niveau + Math.floor(caracValue / 2) + bonus;
|
||||
return "1d6" + (base >= 0 ? "+" : "") + base;
|
||||
static getRollInitiative(caracValue, niveau, bonus = 0) {
|
||||
const base = RdDInitiative.ajustementInitiative(caracValue, niveau, bonus)
|
||||
return "1d6" + (base >= 0 ? "+" : "") + base
|
||||
}
|
||||
|
||||
static ajustementInitiative(caracValue, niveau, bonus = 0) {
|
||||
return niveau + Math.floor(caracValue / 2) + bonus
|
||||
}
|
||||
|
||||
static formule(phase, carac, niveau, bonusMalus = 0) {
|
||||
const ajustement = RdDInitiative.ajustementInitiative(carac, niveau, bonusMalus)
|
||||
return { phase, ajustement }
|
||||
}
|
||||
|
||||
static phaseArme(categorie, arme) {
|
||||
switch (categorie) {
|
||||
case "tir":
|
||||
case "lancer":
|
||||
return MAP_PHASE[categorie]
|
||||
default:
|
||||
switch (arme.system.cac) {
|
||||
case "empoignade":
|
||||
case "pugilat":
|
||||
case "naturelle":
|
||||
return MAP_PHASE[arme.system.cac]
|
||||
default:
|
||||
return MAP_PHASE['arme']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static phase(keyOrRang) {
|
||||
return MAP_PHASE[keyOrRang] ?? PHASE.find(it => it.rang == keyOrRang) ?? MAP_PHASE.autre
|
||||
}
|
||||
|
||||
static async roll(formule) {
|
||||
const sign = formule.ajustement >= 0 ? "+" : ""
|
||||
const roll = new Roll(`1d6 + ${sign} + ${formule.ajustement}`)
|
||||
await roll.evaluate()
|
||||
const value = Math.max(roll.total, 0)
|
||||
return {
|
||||
roll: roll,
|
||||
value: value,
|
||||
rang: formule.phase.rang,
|
||||
init: formule.phase.rang + value / 100,
|
||||
label: formule.phase.label
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { RdDInitiative } from "./initiative.mjs";
|
||||
import { RdDItem } from "./item.js";
|
||||
import { SANS_COMPETENCE } from "./item/base-items.js";
|
||||
import { CATEGORIES_COMPETENCE_COMBAT, CATEGORIES_COMPETENCES, SANS_COMPETENCE } from "./item/base-items.js";
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
const competenceTroncs = [["Esquive", "Dague", "Corps à corps"],
|
||||
@@ -25,16 +27,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() {
|
||||
let cumulXP = { "-11": 0 };
|
||||
@@ -49,7 +41,36 @@ function _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" }
|
||||
|
||||
isNiveauBase() {
|
||||
return this.system.niveau == this.system.base && this.system.xp == 0
|
||||
}
|
||||
|
||||
getBaseInit() {
|
||||
const carac = this.getInitCarac()
|
||||
if (carac == undefined) {
|
||||
return undefined
|
||||
}
|
||||
return RdDInitiative.ajustementInitiative(carac.value, this.system.niveau)
|
||||
}
|
||||
|
||||
getInitCarac() {
|
||||
if (!this.actor) {
|
||||
return undefined
|
||||
}
|
||||
switch (this.system.categorie) {
|
||||
case CATEGORIES_COMPETENCES.melee.key: return this.actor.system.carac.melee
|
||||
case CATEGORIES_COMPETENCES.tir.key: return this.actor.system.carac.tir
|
||||
case CATEGORIES_COMPETENCES.lancer.key: return this.actor.system.carac.lancer
|
||||
case CATEGORIES_COMPETENCES.draconic.key: return this.actor.system.carac.reve
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static getLabelCategorie(category) {
|
||||
return CATEGORIES_COMPETENCES[category].label;
|
||||
|
||||
@@ -1,126 +1,76 @@
|
||||
|
||||
import { ITEM_TYPES } from "./constants.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { RdDInitiative } from "./initiative.mjs";
|
||||
import { RdDItem } from "./item.js";
|
||||
|
||||
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" },
|
||||
}
|
||||
import { RdDInitiative } from "./initiative.mjs";
|
||||
import { RdDItemArme } from "./item/arme.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDItemCompetenceCreature extends Item {
|
||||
export class RdDItemCompetenceCreature extends RdDItem {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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 ITEM_TYPE() { return ITEM_TYPES.competencecreature }
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static armeCreature(item) {
|
||||
const categorieAttaque = RdDItemCompetenceCreature.getCategorieAttaque(item)
|
||||
static get defaultIcon() { return "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp" }
|
||||
|
||||
isAttaque() { return this.getCategorieAttaque() != undefined }
|
||||
isParade() { return this.system.iscombat && (this.system.categorie_parade ?? '') != '' }
|
||||
isBouclier() { return this.system.categorie_parade.includes('bouclier') }
|
||||
attaqueCreature() {
|
||||
const categorieAttaque = this.getCategorieAttaque()
|
||||
if (categorieAttaque != undefined) {
|
||||
// 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.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',
|
||||
const initative = RdDInitiative.getRollInitiative(this.system.carac_value, this.system.niveau);
|
||||
const attaque = {
|
||||
label: this.name,
|
||||
action: this.isCompetencePossession() ? 'possession' : 'attaque',
|
||||
initOnly: false,
|
||||
arme: new RdDItem({
|
||||
name: comp.name,
|
||||
arme: new RdDItemArme({
|
||||
name: this.name,
|
||||
type: ITEM_TYPES.arme,
|
||||
img: comp.img,
|
||||
img: this.img,
|
||||
system: {
|
||||
competence: comp.name,
|
||||
competence: this.name,
|
||||
cac: categorieAttaque == "naturelle" ? "naturelle" : "",
|
||||
niveau: comp.system.niveau,
|
||||
niveau: this.system.niveau,
|
||||
initiative: initative,
|
||||
mortalite: this.system.mortalite,
|
||||
dommages: this.system.dommages,
|
||||
forceRequise: 0,
|
||||
equipe: true,
|
||||
resistance: 100,
|
||||
dommagesReels: comp.system.dommages,
|
||||
penetration: 0,
|
||||
force: 0,
|
||||
rapide: true,
|
||||
}
|
||||
}),
|
||||
comp: comp,
|
||||
// main: '',
|
||||
carac: { key: comp.name, value: comp.system.carac_value },
|
||||
comp: this,
|
||||
carac: { key: this.name, value: this.system.carac_value },
|
||||
equipe: true,
|
||||
dmg: comp.system.dommages,
|
||||
mortalite: this.system.mortalite,
|
||||
dommages: this.system.dommages,
|
||||
//dmg: this.system.dommages,
|
||||
initiative: initative
|
||||
}
|
||||
};
|
||||
return attaque
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isAttaque(item) {
|
||||
return RdDItemCompetenceCreature.getCategorieAttaque(item) != undefined
|
||||
}
|
||||
|
||||
static getCategorieAttaque(item) {
|
||||
if (item.type == ITEM_TYPES.competencecreature) {
|
||||
switch (item.system.categorie) {
|
||||
case "melee":
|
||||
case "tir":
|
||||
case "lancer":
|
||||
case "naturelle":
|
||||
case "possession":
|
||||
return item.system.categorie
|
||||
}
|
||||
getCategorieAttaque() {
|
||||
switch (this.system.categorie) {
|
||||
case "melee":
|
||||
case "tir":
|
||||
case "lancer":
|
||||
case "naturelle":
|
||||
case "possession":
|
||||
return this.system.categorie
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
static isDommages(item) {
|
||||
if (item.type == ITEM_TYPES.competencecreature) {
|
||||
switch (item.system.categorie) {
|
||||
case "melee":
|
||||
case "tir":
|
||||
case "lancer":
|
||||
case "naturelle":
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
static isParade(item) {
|
||||
if (item.type == ITEM_TYPES.competencecreature) {
|
||||
return item.system.categorie_parade || item.system.isparade
|
||||
isDommages() {
|
||||
switch (this.system.categorie) {
|
||||
case "melee":
|
||||
case "tir":
|
||||
case "lancer":
|
||||
case "naturelle":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
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 { RdDUtility } from "./rdd-utility.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { HtmlUtility } from "./html-utility.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.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 { Misc } from "./misc.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 { RdDTextEditor } from "./apps/rdd-text-roll-editor.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) {
|
||||
formData.isparade = RdDItemCompetenceCreature.isParade(this.item)
|
||||
formData.isdommages = RdDItemCompetenceCreature.isDommages(this.item)
|
||||
formData.isparade = this.item.isParade()
|
||||
formData.isdommages = this.item.isDommages()
|
||||
}
|
||||
if (this.item.type == ITEM_TYPES.tache ||
|
||||
this.item.type == ITEM_TYPES.livre ||
|
||||
@@ -260,7 +260,7 @@ export class RdDItemSheetV1 extends foundry.appv1.sheets.ItemSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
_updateObject(event, formData) {
|
||||
async _updateObject(event, formData) {
|
||||
switch (this.item.type) {
|
||||
case ITEM_TYPES.sort:
|
||||
formData['system.bonuscase'] = RdDItemSort.bonuscasesToString(RdDItemSheetV1._listCaseTmr(
|
||||
@@ -273,8 +273,7 @@ export class RdDItemSheetV1 extends foundry.appv1.sheets.ItemSheet {
|
||||
formData['system.niveau'] = formData['system.niveau'] ?? formData['system.base']
|
||||
break
|
||||
}
|
||||
|
||||
return this.item.update(formData)
|
||||
return await super._updateObject(event, formData)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
@@ -62,7 +62,7 @@ export class RdDItemSort extends Item {
|
||||
|
||||
|
||||
static diffReve(sort) { return RdDItemSort.toVar((sort.system.difficulte.match(/\-?(\d)+/) ? 'R' : 'R ') + sort.system.difficulte) }
|
||||
static coutReve(sort) { return RdDItemSort.toVar((sort.system.ptreve.match(/(\d)+\+?/) ? 'r' : 'r ') + sort.system.ptreve) }
|
||||
static coutReve(sort) { return RdDItemSort.toVar((Number.isInteger(sort.system.ptreve || sort.system.ptreve.match(/(\d)+\+?/)) ? 'r' : 'r ') + sort.system.ptreve) }
|
||||
static getDraconicsSort(competencesDraconic, sort) {
|
||||
// se baser sur la voie du sort?
|
||||
switch (Grammar.toLowerCaseNoAccent(sort.name)) {
|
||||
@@ -148,10 +148,17 @@ export class RdDItemSort extends Item {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static incrementBonusCase(actor, sort, coord) {
|
||||
let bonuscase = RdDItemSort.calculBonuscase(sort, coord)
|
||||
|
||||
actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'system.bonuscase': bonuscase }]);
|
||||
}
|
||||
|
||||
|
||||
static calculBonuscase(sort, coord) {
|
||||
if (TMRUtility.isFleuve(coord)) {
|
||||
coord = FLEUVE_COORD;
|
||||
coord = FLEUVE_COORD
|
||||
}
|
||||
let list = RdDItemSort.stringToBonuscases(sort.system.bonuscase);
|
||||
let list = RdDItemSort.stringToBonuscases(sort.system.bonuscase)
|
||||
const existing = list.find(it => it.case == coord)
|
||||
const bonus = Number(existing?.bonus ?? 0) + 1
|
||||
if (existing) {
|
||||
@@ -160,11 +167,9 @@ export class RdDItemSort extends Item {
|
||||
else {
|
||||
list.push({ case: coord, bonus: 1 })
|
||||
}
|
||||
|
||||
actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'system.bonuscase': RdDItemSort.bonuscasesToString(list) }]);
|
||||
return RdDItemSort.bonuscasesToString(list)
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getCaseBonus(sort, coord) {
|
||||
const search = TMRUtility.isFleuve(coord)
|
||||
@@ -189,4 +194,22 @@ export class RdDItemSort extends Item {
|
||||
.map(it => it.split(':'))
|
||||
.map(it => { return { case: it[0], bonus: it[1] } });
|
||||
}
|
||||
|
||||
static prepareSortEnReserve(sort, draconic, ptreve, coord) {
|
||||
return {
|
||||
type: ITEM_TYPES.sortreserve,
|
||||
name: sort.name,
|
||||
img: sort.img,
|
||||
system: { sortid: sort._id, draconic: (draconic?.name ?? sort.system.draconic), ptreve: ptreve, coord: coord, heurecible: 'Vaisseau' }
|
||||
};
|
||||
}
|
||||
|
||||
static prepareSortAddLancement(sort, reveSort) {
|
||||
const precedents = sort.system.lancements ?? []
|
||||
const lancements = [...precedents, {
|
||||
timestamp: game.system.rdd.calendrier.getTimestamp(),
|
||||
reve: reveSort
|
||||
}]
|
||||
return lancements
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import { ITEM_TYPES } from "./constants.js";
|
||||
import { ITEM_TYPES, RDD_CONFIG, renderTemplate } from "./constants.js";
|
||||
import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES, CATEGORIES_COMPETENCES_CREATURES } from "./item/base-items.js";
|
||||
import { ITEM_ACTIONS, DEFAULT_ACTIONS, COMMON_ACTIONS } from "./item/item-actions.js";
|
||||
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
@@ -7,10 +9,6 @@ import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { SystemCompendiums } from "./settings/system-compendiums.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 = [
|
||||
ITEM_TYPES.arme,
|
||||
@@ -186,7 +184,10 @@ export class RdDItem extends Item {
|
||||
isMonnaie() { return this.type == ITEM_TYPES.monnaie; }
|
||||
isNourritureBoisson() { return this.type == ITEM_TYPES.nourritureboisson; }
|
||||
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) }
|
||||
isEsquive() {
|
||||
return (this.isCompetence()
|
||||
@@ -628,7 +629,7 @@ export class RdDItem extends Item {
|
||||
_armeChatData() {
|
||||
return [
|
||||
`<b>Compétence</b>: ${this.system.competence}`,
|
||||
`<b>Dommages</b>: ${this.system.dommages} ${this.system.mortalite == 'non-mortel' ? '(Non mortel)' : ''}`,
|
||||
`<b>Dommages</b>: ${this.system.dommages} ${this.system.mortalite == RDD_CONFIG.encaissement.nonmortel ? '(Non mortel)' : ''}`,
|
||||
`<b>Force minimum</b>: ${this.system.force}`,
|
||||
`<b>Resistance</b>: ${this.system.resistance}`,
|
||||
...this._inventaireTemplateChatData()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ITEM_TYPES } from "../constants.js";
|
||||
import { ITEM_TYPES, RDD_CONFIG } from "../constants.js";
|
||||
import { RdDItem } from "../item.js";
|
||||
|
||||
import { RdDItemCompetenceCreature } from "../item-competencecreature.js"
|
||||
import { BASE_CORPS_A_CORPS } from "./base-items.js";
|
||||
import { Grammar } from "../grammar.js";
|
||||
import { RdDInitiative } from "../initiative.mjs";
|
||||
import { MappingCreatureArme } from "./mapping-creature-arme.mjs";
|
||||
import { Misc } from "../misc.js";
|
||||
|
||||
const nomCategorieParade = {
|
||||
"sans-armes": "Sans arme",
|
||||
@@ -19,26 +19,67 @@ const nomCategorieParade = {
|
||||
"haches": "Haches",
|
||||
"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 ATTAQUE_TYPE_MELEE = [ATTAQUE_TYPE.UNE_MAIN, ATTAQUE_TYPE.DEUX_MAINS, ATTAQUE_TYPE.CORPS_A_CORPS]
|
||||
|
||||
export const CORPS_A_CORPS = 'Corps à corps'
|
||||
export const PUGILAT = 'pugilat'
|
||||
export const EMPOIGNADE = RDD_CONFIG.encaissement.empoignade
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDItemArme extends RdDItem {
|
||||
|
||||
static get ITEM_TYPE() { return ITEM_TYPES.arme }
|
||||
|
||||
static get defaultIcon() {
|
||||
return defaultItemImgArme
|
||||
//return "systems/foundryvtt-reve-de-dragon/icons/armes_armure/epee_sord.webp";
|
||||
static get defaultIcon() { return "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.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') }
|
||||
|
||||
|
||||
getCompetenceAction(main) {
|
||||
switch (main) {
|
||||
case ATTAQUE_TYPE.UNE_MAIN: return this.competence1Mains()
|
||||
case ATTAQUE_TYPE.DEUX_MAINS: return this.competence2Mains()
|
||||
case ATTAQUE_TYPE.LANCER: return this.system.lancer
|
||||
case ATTAQUE_TYPE.TIR: return this.system.tir
|
||||
default: return this.system.competence
|
||||
}
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
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) {
|
||||
switch (arme ? arme.type : '') {
|
||||
case ITEM_TYPES.arme: return arme;
|
||||
case ITEM_TYPES.competencecreature:
|
||||
return RdDItemCompetenceCreature.armeCreature(arme);
|
||||
return MappingCreatureArme.armeCreature(arme);
|
||||
}
|
||||
return RdDItemArme.corpsACorps();
|
||||
return RdDItemArme.pugilat();
|
||||
}
|
||||
|
||||
static getCompetenceArme(arme, maniement) {
|
||||
@@ -47,16 +88,26 @@ export class RdDItemArme extends RdDItem {
|
||||
return arme.name
|
||||
case ITEM_TYPES.arme:
|
||||
switch (maniement) {
|
||||
case 'competence': return arme.system.competence;
|
||||
case '(1 main)': return arme.competence1Mains()
|
||||
case '(2 mains)': return arme.competence2Mains()
|
||||
case '(tir)': case 'tir': return arme.system.tir
|
||||
case '(lancer)': case 'lancer': return arme.system.lancer;
|
||||
case ATTAQUE_TYPE.COMPETENCE: return arme.system.competence
|
||||
case ATTAQUE_TYPE.UNE_MAIN: return arme.competence1Mains()
|
||||
case ATTAQUE_TYPE.DEUX_MAINS: return arme.competence2Mains()
|
||||
case ATTAQUE_TYPE.TIR: case 'tir': return arme.system.tir
|
||||
case ATTAQUE_TYPE.LANCER: case 'lancer': return arme.system.lancer
|
||||
case ATTAQUE_TYPE.CORPS_A_CORPS: return CORPS_A_CORPS
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
getTypeAttaques() {
|
||||
return [
|
||||
...(this.system.unemain && this.system.competence && this.system.resistance > 0) ? [ATTAQUE_TYPE.UNE_MAIN] : [],
|
||||
...(this.system.deuxmains && this.system.competence && this.system.resistance > 0) ? [ATTAQUE_TYPE.DEUX_MAINS] : [],
|
||||
...(this.system.lancer && this.system.resistance > 0) ? [ATTAQUE_TYPE.LANCER] : [],
|
||||
...(this.system.tir) ? [ATTAQUE_TYPE.TIR] : [],
|
||||
]
|
||||
}
|
||||
|
||||
static computeNiveauArmes(armes, competences) {
|
||||
for (const arme of armes) {
|
||||
arme.system.niveau = RdDItemArme.niveauCompetenceArme(arme, competences);
|
||||
@@ -88,16 +139,13 @@ export class RdDItemArme extends RdDItem {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getCategorieParade(armeData) {
|
||||
if (![ITEM_TYPES.arme, ITEM_TYPES.competencecreature].includes(armeData.type)) {
|
||||
return ''
|
||||
}
|
||||
if (armeData.system.categorie_parade) {
|
||||
return armeData.system.categorie_parade
|
||||
}
|
||||
// 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) {
|
||||
return ITEM_TYPES.competencecreature;
|
||||
}
|
||||
@@ -192,7 +240,7 @@ export class RdDItemArme extends RdDItem {
|
||||
return Number(arme.system.dommages)
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -201,7 +249,7 @@ export class RdDItemArme extends RdDItem {
|
||||
static armeUneOuDeuxMains(arme, aUneMain) {
|
||||
if (arme && !arme.system.cac) {
|
||||
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;
|
||||
}
|
||||
@@ -222,63 +270,50 @@ export class RdDItemArme extends RdDItem {
|
||||
return false
|
||||
}
|
||||
|
||||
static isAttaque(arme) {
|
||||
switch (arme.type) {
|
||||
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
|
||||
isAttaque() {
|
||||
return this.system.resistance > 0 || (this.system.tir != '' && this.system.portee_courte > 0)
|
||||
}
|
||||
|
||||
static isParade(arme) {
|
||||
switch (arme.type) {
|
||||
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
|
||||
isEmpoignade() {
|
||||
return this.system.mortalite == RDD_CONFIG.encaissement.empoignade
|
||||
}
|
||||
|
||||
isUtilisableEmpoigne() {
|
||||
return this.system.baseInit == 3 || this.system.baseInit == 4 || this.system.competence == "Dague"
|
||||
}
|
||||
|
||||
static corpsACorps(actor) {
|
||||
let competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS
|
||||
let melee = actor ? actor.system.carac['melee'].value : 0
|
||||
static pugilat(actor) {
|
||||
return RdDItemArme.$corpsACorps(actor, 'Pugilat', PUGILAT)
|
||||
}
|
||||
|
||||
static empoignade(actor) {
|
||||
return RdDItemArme.$corpsACorps(actor, 'Empoignade', RDD_CONFIG.encaissement.empoignade)
|
||||
}
|
||||
|
||||
static $corpsACorps(actor, name, cac) {
|
||||
const competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS
|
||||
const melee = actor ? actor.system.carac['melee'].value : 0
|
||||
return new RdDItemArme({
|
||||
_id: competence.id,
|
||||
name: 'Corps à corps',
|
||||
_id: Misc.fakeId(cac),
|
||||
name: name,
|
||||
type: ITEM_TYPES.arme,
|
||||
img: competence.img,
|
||||
system: {
|
||||
initiative: RdDInitiative.calculInitiative(competence.system.niveau, melee),
|
||||
initiative: RdDInitiative.getRollInitiative(melee, competence.system.niveau),
|
||||
equipe: true,
|
||||
rapide: true,
|
||||
force: 0,
|
||||
dommages: "0",
|
||||
dommagesReels: 0,
|
||||
mortalite: 'non-mortel',
|
||||
competence: 'Corps à corps',
|
||||
mortalite: cac == RDD_CONFIG.encaissement.empoignade ? RDD_CONFIG.encaissement.empoignade : RDD_CONFIG.encaissement.nonmortel,
|
||||
competence: CORPS_A_CORPS,
|
||||
resistance: 1,
|
||||
baseInit: 4,
|
||||
cac: 'pugilat',
|
||||
baseInit: cac == RDD_CONFIG.encaissement.empoignade ? 3 : 4,
|
||||
cac: cac,
|
||||
deuxmains: true,
|
||||
categorie_parade: 'sans-armes'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static mainsNues(actor) {
|
||||
const mainsNues = RdDItemArme.corpsACorps(actor)
|
||||
mainsNues.name = 'Mains nues'
|
||||
return mainsNues;
|
||||
}
|
||||
|
||||
static empoignade(actor) {
|
||||
const empoignade = RdDItemArme.corpsACorps(actor)
|
||||
empoignade.name = 'Empoignade'
|
||||
empoignade.system.cac = 'empoignade'
|
||||
empoignade.system.baseInit = 3
|
||||
empoignade.system.mortalite = 'empoignade'
|
||||
return empoignade
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,28 @@ export const SANS_COMPETENCE = {
|
||||
description: "",
|
||||
descriptionmj: "",
|
||||
defaut_carac: "",
|
||||
},
|
||||
},
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/templates/icone_parchement_vierge.webp"
|
||||
}
|
||||
}
|
||||
|
||||
export const CATEGORIES_COMPETENCES = {
|
||||
generale: { key: 'generale', base: -4, label: "Générales" },
|
||||
particuliere: { key: 'particuliere', base: -8, label: "Particulières" },
|
||||
specialisee: { key: 'specialisee', base: -11, label: "Spécialisées" },
|
||||
connaissance: { key: 'connaissance', base: -11, label: "Connaissances" },
|
||||
draconic: { key: 'draconic', base: -11, label: "Draconic" },
|
||||
melee: { key: 'melee', base: -6, label: "Mêlée" },
|
||||
tir: { key: 'tir', base: -8, label: "Tir" },
|
||||
lancer: { key: 'lancer', base: -8, label: "Lancer" }
|
||||
}
|
||||
export const CATEGORIES_COMPETENCE_COMBAT = [CATEGORIES_COMPETENCES.melee, CATEGORIES_COMPETENCES.tir, CATEGORIES_COMPETENCES.lancer].map(it => it.key)
|
||||
|
||||
export const CATEGORIES_COMPETENCES_CREATURES = {
|
||||
generale: { key: 'generale', base: 0, label: "Générale" },
|
||||
naturelle: { key: 'naturelle', base: 0, label: "Arme naturelle" },
|
||||
melee: { key: 'melee', base: 0, label: "Mêlée" },
|
||||
parade: { key: 'parade', base: 0, label: "Parade" },
|
||||
tir: { key: 'tir', base: 0, label: "Tir" },
|
||||
lancer: { key: 'lancer', base: 0, label: "Lancer" },
|
||||
possession: { key: 'possession', base: 0, label: "Possession" },
|
||||
}
|
||||
|
||||
@@ -71,21 +71,25 @@ export class RdDItemBlessure extends RdDItem {
|
||||
return 0
|
||||
}
|
||||
|
||||
static async createBlessure(actor, gravite, localisation = '', attackerToken) {
|
||||
const definition = RdDItemBlessure.getDefinition(gravite)
|
||||
const blessure = {
|
||||
static async createBlessure(actor, gravite, localisation = '', attackerToken = undefined) {
|
||||
const blessure = RdDItemBlessure.prepareBlessure(gravite, localisation, attackerToken);
|
||||
const blessures = await actor.createEmbeddedDocuments('Item', [blessure])
|
||||
return blessures[0]
|
||||
}
|
||||
|
||||
static prepareBlessure(gravite, localisation, attackerToken) {
|
||||
const definition = RdDItemBlessure.getDefinition(gravite);
|
||||
return {
|
||||
name: definition.label,
|
||||
type: 'blessure',
|
||||
img: definition.icon,
|
||||
system: {
|
||||
gravite: gravite,
|
||||
difficulte: - gravite,
|
||||
difficulte: -gravite,
|
||||
localisation: localisation,
|
||||
origine: attackerToken?.name ?? ""
|
||||
}
|
||||
}
|
||||
const blessures = await actor.createEmbeddedDocuments('Item', [blessure])
|
||||
return blessures[0]
|
||||
}
|
||||
|
||||
static async createTacheSoinBlessure(actor, gravite) {
|
||||
@@ -209,6 +213,9 @@ export class RdDItemBlessure extends RdDItem {
|
||||
isCritique() {
|
||||
return this.system.gravite > 4 && this.system.gravite <= 6
|
||||
}
|
||||
isBleeding() {
|
||||
return this.system.gravite > 2 && !this.system.premierssoins.done
|
||||
}
|
||||
isMort() {
|
||||
return this.system.gravite > 6
|
||||
}
|
||||
|
||||
@@ -12,12 +12,13 @@ const _SPACEHOLDER = { placeholder: true }
|
||||
|
||||
const _VENDRE = {
|
||||
code: 'item-vendre', label: 'Vendre ou donner', icon: it => 'fa-solid fa-comments-dollar',
|
||||
filter: it => Misc.toInt(it.system.quantite) > 0,
|
||||
filter: it => Misc.toInt(it.system.quantite) > 0 || it.parent?.type == ACTOR_TYPES.commerce,
|
||||
action: (item, actor) => item.proposerVente()
|
||||
}
|
||||
const _ACHETER = {
|
||||
code: 'item-acheter', label: 'Acheter', icon: it => 'fa-regular fa-coins',
|
||||
filter: it => Misc.toInt(it.system.quantite) > 0 && it.parent?.type == ACTOR_TYPES.commerce,
|
||||
filter: it => it.parent?.type == ACTOR_TYPES.commerce,
|
||||
allowLimited: true,
|
||||
action: (item, actor) => actor.vente(item)
|
||||
}
|
||||
const _MONTRER = {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,8 +6,8 @@ const tableEffets = [
|
||||
{ code: "passeur", resultat: "succes", description: "Déplacer le demi-rêve à (force) cases", method: EffetsRencontre.passeur},
|
||||
{ code: "reve+f", resultat: "succes", description: "Gain de (force) points de rêve" , method: EffetsRencontre.reve_plus_force},
|
||||
{ code: "teleport", resultat: "succes", description: "Déplacer le demi-rêve (même type)", method: EffetsRencontre.teleportation_typecase },
|
||||
{ code: "part+tete", resultat: "succes", description: "Tête de dragon sur réussite particulière", method: EffetsRencontre.rdd_part_tete },
|
||||
{ code: "part+xp", resultat: "succes", description: "Expérience sur réussite particulière", method: EffetsRencontre.experience_particuliere },
|
||||
{ code: "part+tete", resultat: "succes", description: "Tête de dragon sur particulière", method: EffetsRencontre.rdd_part_tete },
|
||||
{ code: "part+xp", resultat: "succes", description: "Expérience sur particulière", method: EffetsRencontre.experience_particuliere },
|
||||
{ code: "seuil", resultat: "succes", description: "Récupération de seuil de rêve", method: EffetsRencontre.regain_seuil },
|
||||
|
||||
{ code: "reve-1", resultat: "echec", description: "Perte de 1 point de rêve", method: EffetsRencontre.reve_moins_1 },
|
||||
@@ -19,7 +19,7 @@ const tableEffets = [
|
||||
{ code: "aleatoire", resultat: "echec", description: "Déplacement aléatoire", method: EffetsRencontre.deplacement_aleatoire },
|
||||
{ code: "sort-aleatoire", resultat: "echec", description: "Déclenche un sort en réserve aléatoire", method: EffetsRencontre.sort_aleatoire },
|
||||
{ code: "rompu", resultat: "echec", description: "Demi-rêve interrompu", method: EffetsRencontre.demireve_rompu },
|
||||
{ code: "echec-queue", resultat: "echec", description: "Queue(s) de dragon sur échec", method: EffetsRencontre.rdd_echec_queue },
|
||||
{ code: "echec-queue", resultat: "echec", description: "Queue(s) de dragon", method: EffetsRencontre.rdd_echec_queue },
|
||||
|
||||
{ code: "reve+1", resultat: "succes", description: "Gain de 1 point de rêve", method: EffetsRencontre.reve_plus_1 },
|
||||
{ code: "vie-f", resultat: "echec", description: "Perte de (force) points de vie", method: EffetsRencontre.vie_moins_force },
|
||||
|
||||
@@ -34,6 +34,13 @@ export class Misc {
|
||||
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() {
|
||||
return (a, b) => Number(a) + Number(b);
|
||||
}
|
||||
@@ -58,6 +65,10 @@ export class Misc {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static fakeId(base) {
|
||||
return (base + foundry.utils.randomID(16)).substring(0, 16)
|
||||
}
|
||||
|
||||
static typeName(type, subType) {
|
||||
return subType ? game.i18n.localize(`TYPES.${type}.${subType}`)
|
||||
: '';
|
||||
@@ -108,6 +119,10 @@ export class Misc {
|
||||
list.forEach(it => addToObj(obj, it))
|
||||
return obj;
|
||||
}
|
||||
static indexed(list, index = 'index') {
|
||||
let i = 0;
|
||||
return list.map(it => { it[index] = i++; return it })
|
||||
}
|
||||
|
||||
static concat(lists) {
|
||||
return lists.reduce((a, b) => a.concat(b), []);
|
||||
@@ -214,6 +229,14 @@ export class Misc {
|
||||
return undefined
|
||||
}
|
||||
|
||||
static async doIfOwner(document, action, orElse = async it => { ui.notifications.warn(`Vous n'avez pas le droit d'agir pour ${it.name}`) }) {
|
||||
if (Misc.isOwnerPlayer(document)) {
|
||||
return await action(document)
|
||||
} else {
|
||||
return await orElse(document)
|
||||
}
|
||||
}
|
||||
|
||||
static isOwnerPlayer(document) {
|
||||
return document.testUserPermission && document.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
|
||||
}
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
import { RdDCarac } from "./rdd-carac.js";
|
||||
import { RDD_CONFIG } from "./constants.js";
|
||||
import { RdDItemArme } from "./item/arme.js";
|
||||
import { RdDPossession } from "./rdd-possession.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
|
||||
const conditionsTactiques = [
|
||||
{ type: '', descr: '', dmg: 0, attaque: 0, parade: 0, esquive: true },
|
||||
{ type: 'charge', descr: 'Charge', dmg: 2, attaque: 4, parade: -4, esquive: false },
|
||||
{ type: 'feinte', descr: 'Feinte', dmg: 1, attaque: 1, parade: 0, esquive: true },
|
||||
{ type: 'pret', descr: 'prêt', dmg: 0, attaque: 0, parade: 0, esquive: true },
|
||||
{ type: 'demi', descr: 'Demi-surprise', dmg: 1, attaque: 0, parade: 0, esquive: true },
|
||||
{ type: 'totale', descr: 'Surprise totale', dmg: 10, attaque: 6, parade: 0, esquive: true },
|
||||
{ key: '', label: '', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false },
|
||||
{ key: 'normale', label: 'Attaque normale', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: true },
|
||||
{ key: 'charge', label: 'Charge', dmg: 2, attaque: 4, parade: -4, esquive: false, isTactique: true },
|
||||
{ key: 'feinte', label: 'Feinte', dmg: 1, attaque: 1, parade: 0, esquive: true, isTactique: true },
|
||||
{ key: 'pret', label: 'prêt', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false },
|
||||
{ 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 {
|
||||
|
||||
static get tactiques() {
|
||||
return conditionsTactiques.filter(it => it.isTactique)
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
@@ -31,49 +36,73 @@ export class RdDBonus {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static dmg(rollData, actor, isEntiteIncarnee = false) {
|
||||
const dmgArme = RdDBonus.dmgArme(rollData.arme)
|
||||
static dmg(rollData, actor) {
|
||||
const diff = rollData.diffLibre;
|
||||
const dmgArme = RdDBonus.dmgArme(rollData.arme, rollData.arme?.system.dommagesReels)
|
||||
const forceRequise = rollData.arme ? RdDItemArme.valeurMain(rollData.arme.system.force ?? 0, RdDItemArme.getMainAttaque(rollData.competence)) : 0
|
||||
let dmg = {
|
||||
total: 0,
|
||||
dmgArme: dmgArme,
|
||||
diff: diff,
|
||||
dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(diff ?? 0) : 0,
|
||||
penetration: RdDBonus._peneration(rollData),
|
||||
dmgTactique: RdDBonus.dmgBonus(rollData.tactique),
|
||||
dmgParticuliere: RdDBonus._dmgParticuliere(rollData),
|
||||
dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used),
|
||||
mortalite: RdDBonus._calculMortalite(rollData, isEntiteIncarnee),
|
||||
dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme)
|
||||
dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris?.used),
|
||||
mortalite: RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite),
|
||||
dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme),
|
||||
dmgForceInsuffisante: Math.min(0, actor.getForce() - forceRequise)
|
||||
}
|
||||
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
|
||||
return dmg;
|
||||
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante
|
||||
return dmg
|
||||
}
|
||||
|
||||
static dmgRollV2(rollData, attaque) {
|
||||
const actor = rollData.active.actor
|
||||
const arme = attaque.arme
|
||||
const dmgArme = RdDBonus.dmgArme(arme, attaque.dommages)
|
||||
const dmg = {
|
||||
total: 0,
|
||||
dmgArme: dmgArme,
|
||||
penetration: arme?.system.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),
|
||||
dmgActor: RdDBonus.bonusDmg(actor, attaque.carac.key, dmgArme, attaque.forceRequise),
|
||||
dmgForceInsuffisante: Math.min(0, actor.getForce() - (attaque.forceRequise ?? 0)),
|
||||
dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0
|
||||
}
|
||||
dmg.isEmpoignade = dmg.mortalite == RDD_CONFIG.encaissement.empoignade
|
||||
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante + dmg.dmgDiffLibre
|
||||
return dmg
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static description(condition) {
|
||||
return RdDBonus.find(condition).descr;
|
||||
return RdDBonus.find(condition).label
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static dmgBonus(condition) {
|
||||
return RdDBonus.find(condition).dmg;
|
||||
return RdDBonus.find(condition).dmg
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static bonusAttaque(condition) {
|
||||
return RdDBonus.find(condition).attaque;
|
||||
return RdDBonus.find(condition).attaque
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _calculMortalite(rollData, isEntiteIncarnee) {
|
||||
return isEntiteIncarnee ? "entiteincarnee"
|
||||
: rollData.dmg?.mortalite
|
||||
?? rollData.arme?.system.mortalite
|
||||
?? "mortel";
|
||||
static mortalite(mortaliteSelect, mortaliteArme) {
|
||||
return mortaliteSelect ?? mortaliteArme ?? RDD_CONFIG.encaissement.mortel
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static dmgArme(arme) {
|
||||
static dmgArme(arme, dommages) {
|
||||
if (arme) {
|
||||
let dmgBase = arme.system.dommagesReels ?? Number(arme.system.dommages ?? 0);
|
||||
let dmgBase = dommages ?? Number(arme.system.dommages ?? 0);
|
||||
//Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278)
|
||||
return dmgBase + Math.min(dmgBase, arme.system.magique ? arme.system.ecaille_efficacite : 0);
|
||||
}
|
||||
@@ -87,13 +116,13 @@ export class RdDBonus {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static bonusDmg(actor, categorie, dmgArme) {
|
||||
const dmgActor = actor.getBonusDegat()
|
||||
if (categorie == undefined) {
|
||||
return 0
|
||||
}
|
||||
const dmgActor = actor.getBonusDegat()
|
||||
switch (categorie) {
|
||||
case "tir": return 0;
|
||||
case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
|
||||
case "(tir)": case "tir": return 0
|
||||
case "(lancer)": case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
|
||||
}
|
||||
return dmgActor;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,15 @@ export const CARACS = {
|
||||
EMPATHIE: 'empathie',
|
||||
REVE: 'reve',
|
||||
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 = {
|
||||
[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.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' },
|
||||
'protection': { code: 'protection', label: 'Protection naturelle', isCarac: false, path: 'system.attributs.protection.value' },
|
||||
'beaute': { code: 'beaute', label: 'Beauté', isCarac: false, path: 'system.background.beaute.value' }
|
||||
[CARACS.PROTECTION]: { code: CARACS.PROTECTION, label: 'Protection naturelle', isCarac: false, path: 'system.attributs.protection.value' },
|
||||
[CARACS.BEAUTE]: { code: CARACS.BEAUTE, label: 'Beauté', isCarac: false, path: 'system.background.beaute.value' }
|
||||
}
|
||||
|
||||
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 = {
|
||||
'melee': { code: "melee", label: 'Mêlée', path: 'system.carac.melee.value' },
|
||||
'tir': { code: "tir", label: 'Tir', path: 'system.carac.tir.value' },
|
||||
'lancer': { code: "lancer", label: 'Lancer', path: 'system.carac.lancer.value' },
|
||||
'derobee': { code: "derobee", label: 'Dérobée', path: 'system.carac.derobee.value' },
|
||||
'chance-actuelle': { code: "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.MELEE]: { code: CARACS.MELEE, label: 'Mêlée', path: 'system.carac.melee.value' },
|
||||
[CARACS.TIR]: { code: CARACS.TIR, label: 'Tir', path: 'system.carac.tir.value' },
|
||||
[CARACS.LANCER]: { code: CARACS.LANCER, label: 'Lancer', path: 'system.carac.lancer.value' },
|
||||
[CARACS.DEROBEE]: { code: CARACS.DEROBEE, label: 'Dérobée', path: 'system.carac.derobee.value' },
|
||||
[CARACS.CHANCE_ACTUELLE]: { code: CARACS.CHANCE_ACTUELLE, label: 'Chance actuelle', path: 'system.carac.lancer.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')
|
||||
@@ -125,11 +134,11 @@ export class RdDCarac {
|
||||
}
|
||||
|
||||
static isIntellect(caracLabel) {
|
||||
return Grammar.toLowerCaseNoAccent(caracLabel) == 'intellect';
|
||||
return Grammar.toLowerCaseNoAccent(caracLabel) == CARACS.INTELLECT
|
||||
}
|
||||
|
||||
static isVolonte(caracLabel) {
|
||||
return Grammar.toLowerCaseNoAccent(caracLabel) == 'volonte';
|
||||
return Grammar.toLowerCaseNoAccent(caracLabel) == CARACS.VOLONTE
|
||||
}
|
||||
static isChance(caracLabel) {
|
||||
return Grammar.toLowerCaseNoAccent(caracLabel)?.match(/chance(( |-)?actuelle)?/);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { ENTITE_BLURETTE, HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { HIDE_DICE, renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDBonus } from "./rdd-bonus.js";
|
||||
@@ -7,14 +7,18 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { RdDRoll } from "./rdd-roll.js";
|
||||
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
import { STATUSES } from "./settings/status-effects.js";
|
||||
import { Targets } from "./targets.js";
|
||||
import { RdDEmpoignade } from "./rdd-empoignade.js";
|
||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
import { RdDItemArme } from "./item/arme.js";
|
||||
import { EMPOIGNADE, RdDItemArme } from "./item/arme.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||
import { RdDInitiative } from "./initiative.mjs";
|
||||
import { MAP_PHASE, RdDInitiative } from "./initiative.mjs";
|
||||
import RollDialog from "./roll/roll-dialog.mjs";
|
||||
import { PART_DEFENSE } from "./roll/roll-part-defense.mjs";
|
||||
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs";
|
||||
import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js";
|
||||
import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs";
|
||||
import { RollBasicParts } from "./roll/roll-basic-parts.mjs";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const premierRoundInit = [
|
||||
@@ -52,6 +56,12 @@ export class RdDCombatManager extends Combat {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static getCombatant(actorId, tokenId) {
|
||||
return game.combat?.combatants.find(it => it.actor.id == actorId &&
|
||||
it.token.id == tokenId
|
||||
)
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async nextRound() {
|
||||
await this.finDeRound();
|
||||
@@ -63,7 +73,7 @@ export class RdDCombatManager extends Combat {
|
||||
if (Misc.isFirstConnectedGM()) {
|
||||
await this.finDeRound({ terminer: true })
|
||||
ChatUtility.removeChatMessageContaining(`<div data-combatid="${this.id}" data-combatmessage="actor-turn-summary">`)
|
||||
game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined)
|
||||
game.messages.filter(m => ChatUtility.getMessageData(m, 'rollData') != undefined && ChatUtility.getMessageData(m, 'rollData') != undefined)
|
||||
.forEach(it => it.delete())
|
||||
RdDEmpoignade.deleteAllEmpoignades()
|
||||
}
|
||||
@@ -102,14 +112,18 @@ export class RdDCombatManager extends Combat {
|
||||
return combatant.actor
|
||||
}
|
||||
|
||||
static calculAjustementInit(actor, arme) {
|
||||
const efficacite = (arme?.system.magique) ? arme.system.ecaille_efficacite : 0
|
||||
const etatGeneral = actor.getEtatGeneral() ?? 0
|
||||
return efficacite + etatGeneral
|
||||
|
||||
static bonusArme(arme) {
|
||||
return (arme?.system.magique) ? arme.system.ecaille_efficacite : 0
|
||||
}
|
||||
|
||||
/************************************************************************************/
|
||||
static etatGeneral(actor) {
|
||||
return actor.getEtatGeneral() ?? 0;
|
||||
}
|
||||
|
||||
|
||||
/** ***********************************************************************************
|
||||
* @override lance l'initiative de plusieurs combattants (tous/ous les PNJs) en une fois
|
||||
*/
|
||||
async rollInitiative(ids, messageOptions = {}) {
|
||||
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, messageOptions)
|
||||
ids = typeof ids === "string" ? [ids] : ids
|
||||
@@ -117,18 +131,17 @@ export class RdDCombatManager extends Combat {
|
||||
return this
|
||||
}
|
||||
|
||||
async rollInitRdD(id, formula, messageOptions = {}) {
|
||||
async rollInitRdD(id, formule, messageOptions = {}) {
|
||||
const combatant = this.combatants.get(id);
|
||||
const actor = RdDCombatManager.getActorCombatant(combatant)
|
||||
if (actor) {
|
||||
const rollFormula = formula ?? RdDCombatManager.getFirstInitRollFormula(actor)
|
||||
const roll = combatant.getInitiativeRoll(rollFormula);
|
||||
if (!roll.total) {
|
||||
await roll.evaluate();
|
||||
}
|
||||
const total = Math.max(roll.total, 0.00);
|
||||
console.log("Compute init for", rollFormula, roll, total, combatant);
|
||||
await this.updateEmbeddedDocuments("Combatant", [{ _id: combatant._id || combatant.id, initiative: total }]);
|
||||
formule = formule ?? RdDCombatManager.getFirstInitRollFormula(actor)
|
||||
const init = await RdDInitiative.roll(formule)
|
||||
|
||||
await this.updateEmbeddedDocuments("Combatant", [{
|
||||
_id: combatant._id || combatant.id,
|
||||
initiative: init.init, 'system.init': init
|
||||
}])
|
||||
|
||||
// Send a chat message
|
||||
let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode");
|
||||
@@ -140,10 +153,10 @@ export class RdDCombatManager extends Combat {
|
||||
alias: combatant.token?.name,
|
||||
sound: CONFIG.sounds.dice,
|
||||
},
|
||||
flavor: `${combatant.token?.name} a fait son jet d'Initiative (${messageOptions.info})<br>`
|
||||
flavor: `${combatant.token?.name} a une initiatyive de ${init.value} : ${messageOptions.info}<br>`
|
||||
},
|
||||
messageOptions);
|
||||
roll.toMessage(messageData, { rollMode, create: true });
|
||||
init.roll.toMessage(messageData, { rollMode, create: true });
|
||||
|
||||
RdDCombatManager.processPremierRoundInit();
|
||||
}
|
||||
@@ -155,16 +168,11 @@ export class RdDCombatManager extends Combat {
|
||||
if (actions.length > 0) {
|
||||
const action = actions[0]
|
||||
const init = RdDCombatManager.getInitData(actor, action)
|
||||
const ajustement = RdDCombatManager.calculAjustementInit(actor, action)
|
||||
return RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
|
||||
const ajustement = RdDCombatManager.bonusArme(action.arme) + RdDCombatManager.etatGeneral(actor)
|
||||
return RdDInitiative.formule(init.phase, init.carac, init.niveau, ajustement);
|
||||
}
|
||||
|
||||
let ajustement = RdDCombatManager.calculAjustementInit(actor, undefined);
|
||||
return RdDCombatManager.formuleInitiative(2, 10, 0, ajustement);
|
||||
}
|
||||
|
||||
static formuleInitiative(rang, carac, niveau, bonusMalus) {
|
||||
return `${rang} +( (${RdDInitiative.calculInitiative(niveau, carac, bonusMalus)} )/100)`;
|
||||
return RdDInitiative.formule(MAP_PHASE['autre'], 10, 0, actor.getEtatGeneral() ?? 0);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -176,7 +184,6 @@ export class RdDCombatManager extends Combat {
|
||||
for (let combatant of game.combat.combatants) {
|
||||
if (combatant.initiativeData?.arme?.type == "arme") {
|
||||
// TODO: get init data premier round
|
||||
const initiativeData = combatant.initiativeData;
|
||||
const action = combatant.initiativeData.arme;
|
||||
const fromArme = Grammar.toLowerCaseNoAccentNoSpace(action.system.initpremierround)
|
||||
const initData = premierRoundInit.find(it => fromArme.includes(initData.pattern))
|
||||
@@ -196,10 +203,27 @@ export class RdDCombatManager extends Combat {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static incDecInit(combatantId, incDecValue) {
|
||||
const combatant = game.combat.combatants.get(combatantId);
|
||||
let initValue = combatant.initiative + incDecValue;
|
||||
game.combat.setInitiative(combatantId, initValue);
|
||||
|
||||
static applyInitiativeCommand(combatantId, command, commandValue) {
|
||||
switch (command) {
|
||||
case 'delta': return RdDCombatManager.incDecInit(combatantId, commandValue);
|
||||
case 'autre': return RdDCombatManager.rollInitiativeAction(combatantId,
|
||||
{ name: "Autre action", action: 'autre', system: { initOnly: true, competence: "Autre action" } });
|
||||
}
|
||||
}
|
||||
|
||||
static async incDecInit(combatantId, incDecValue) {
|
||||
const combatant = game.combat.combatants.get(combatantId)
|
||||
if (combatant?.initiative && incDecValue != 0) {
|
||||
const value = combatant.system.init.value + incDecValue
|
||||
const newInit = combatant.initiative + incDecValue / 100;
|
||||
await game.combat.updateEmbeddedDocuments("Combatant", [{
|
||||
_id: combatantId,
|
||||
initiative: newInit,
|
||||
'system.init.value': value,
|
||||
'system.init.init': newInit,
|
||||
}])
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -216,56 +240,42 @@ export class RdDCombatManager extends Combat {
|
||||
}
|
||||
}
|
||||
options = [
|
||||
{ name: "Incrémenter initiative", condition: true, icon: '<i class="fa-solid fa-plus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +0.01); } },
|
||||
{ name: "Décrémenter initiative", condition: true, icon: '<i class="fa-solid fa-minus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -0.01); } }
|
||||
{ name: "Incrémenter initiative", condition: true, icon: '<i class="fa-solid fa-plus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), +1); } },
|
||||
{ name: "Décrémenter initiative", condition: true, icon: '<i class="fa-solid fa-minus"></i>', callback: target => { RdDCombatManager.incDecInit(target.data('combatant-id'), -1); } }
|
||||
].concat(options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async rollInitiativeAction(combatantId, action) {
|
||||
const combatant = game.combat.combatants.get(combatantId)
|
||||
const actor = RdDCombatManager.getActorCombatant(combatant)
|
||||
if (actor == undefined) { return [] }
|
||||
|
||||
combatant.initiativeData = { arme: action } // pour reclasser l'init au round 0
|
||||
if (actor == undefined) { return }
|
||||
|
||||
const init = RdDCombatManager.getInitData(actor, action)
|
||||
const ajustement = RdDCombatManager.calculAjustementInit(actor, action.arme)
|
||||
const rollFormula = RdDCombatManager.formuleInitiative(init.offset, init.carac, init.niveau, ajustement);
|
||||
const ajustement = RdDCombatManager.bonusArme(actor, action.arme) + RdDCombatManager.etatGeneral(actor)
|
||||
const formule = RdDInitiative.formule(init.phase, init.carac, init.niveau, ajustement);
|
||||
|
||||
await game.combat.rollInitRdD(combatantId, rollFormula, init);
|
||||
combatant.initiativeData
|
||||
await game.combat.rollInitRdD(combatantId, formule, init);
|
||||
combatant.initiativeData = { action, formule } // pour reclasser l'init au round 0
|
||||
}
|
||||
|
||||
static getInitData(actor, action) {
|
||||
if (actor.getSurprise() == "totale") { return { offset: -1, info: "Surprise Totale", carac: 0, niveau: 0 } }
|
||||
if (actor.getSurprise() == "demi") { return { offset: 0, info: "Demi Surprise", carac: 0, niveau: 0 } }
|
||||
if (action.action == 'autre') { return { offset: 2, info: "Autre Action", carac: 0, niveau: 0 } }
|
||||
if (action.action == 'possession') { return { offset: 10, info: "Possession", carac: actor.getReveActuel(), niveau: 0 } }
|
||||
if (action.action == 'haut-reve') { return { offset: 9, info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } }
|
||||
if (actor.getSurprise() == "totale") { return { phase: MAP_PHASE['totale'], info: "Surprise Totale", carac: 0, niveau: 0 } }
|
||||
if (actor.getSurprise() == "demi") { return { phase: MAP_PHASE['demi'], info: "Demi Surprise", carac: 0, niveau: 0 } }
|
||||
if (action.action == 'autre') { return { phase: MAP_PHASE['autre'], info: "Autre Action", carac: 0, niveau: 0 } }
|
||||
if (action.action == 'possession') { return { phase: MAP_PHASE['possession'], info: "Possession", carac: actor.getReveActuel(), niveau: 0 } }
|
||||
if (action.action == 'haut-reve') { return { phase: MAP_PHASE['draconic'], info: "Draconic", carac: actor.getReveActuel(), niveau: 0 } }
|
||||
|
||||
const comp = action.comp
|
||||
return {
|
||||
offset: RdDCombatManager.initOffset(comp?.system.categorie, action.arme),
|
||||
info: action.name + " / " + comp.name,
|
||||
phase: RdDInitiative.phaseArme(comp?.system.categorie, action.arme),
|
||||
info: action.label,
|
||||
carac: actor.getCaracInit(comp),
|
||||
niveau: comp?.system.niveau ?? (['(lancer)', '(tir)'].includes(action.main) ? -8 : -6)
|
||||
}
|
||||
}
|
||||
|
||||
static initOffset(categorie, arme) {
|
||||
switch (categorie) {
|
||||
case "tir": return 8
|
||||
case "lancer": return 7
|
||||
default:
|
||||
switch (arme.system.cac) {
|
||||
case "empoignade": return 3
|
||||
case "pugilat": return 4
|
||||
case "naturelle": return 4
|
||||
default: return 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static displayInitiativeMenu(html, combatantId) {
|
||||
const combatant = game.combat.combatants.get(combatantId)
|
||||
@@ -293,13 +303,8 @@ export class RdDCombatManager extends Combat {
|
||||
? possessions
|
||||
: actor.listActions({ isEquipe: true })
|
||||
|
||||
for (let index = 0; index < actions.length; index++) {
|
||||
actions[index].index = index
|
||||
}
|
||||
return actions
|
||||
return Misc.indexed(actions)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -310,6 +315,7 @@ export class RdDCombat {
|
||||
switch (sockmsg.msg) {
|
||||
case "msg_encaisser": return RdDCombat.onMsgEncaisser(sockmsg.data);
|
||||
case "msg_defense": return RdDCombat.onMsgDefense(sockmsg.data);
|
||||
case "msg_defense_v2": return RdDCombat.onMsgDefenseV2(sockmsg.data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,13 +368,26 @@ export class RdDCombat {
|
||||
return new RdDCombat(attacker, attackerTokenId, defender, defenderTokenId, target)
|
||||
}
|
||||
|
||||
static rddCombatForAttackV2(attackerRoll) {
|
||||
const defenderRoll = RollBasicParts.prepareDefense(attackerRoll)
|
||||
return RdDCombat.rddCombatForDefenseV2(defenderRoll)
|
||||
}
|
||||
|
||||
static rddCombatForDefenseV2(defenderRoll) {
|
||||
let defenderToken = canvas.tokens.get(defenderRoll.active.tokenId)
|
||||
if (defenderToken) {
|
||||
return RdDCombat.rddCombatForAttackerAndDefender(defenderRoll.opponent.id, defenderRoll.opponent.tokenId, defenderRoll.active.tokenId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static onMsgEncaisser(msg) {
|
||||
let defender = canvas.tokens.get(msg.defenderToken.id).actor;
|
||||
if (Misc.isOwnerPlayer(defender)) {
|
||||
let attackerRoll = msg.attackerRoll;
|
||||
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);
|
||||
rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||
}
|
||||
@@ -379,8 +398,13 @@ export class RdDCombat {
|
||||
let defenderToken = canvas.tokens.get(msg.defenderToken.id)
|
||||
if (defenderToken && Misc.isFirstConnectedGM()) {
|
||||
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id)
|
||||
rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme)
|
||||
rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll)
|
||||
rddCombat?.removeChatMessageActionsPasseArme(msg.paramChatDefense.attackerRoll.passeArme)
|
||||
if (msg.defenderRoll.v2) {/* TODO: delete roll V1 */
|
||||
RollDialog.loadRollData(msg.paramChatDefense)
|
||||
rddCombat?._chatMessageDefenseV2(msg.paramChatDefense)
|
||||
} else {
|
||||
rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,15 +422,18 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
static registerChatCallbacks(html) {
|
||||
for (let button of [
|
||||
'.parer-button',
|
||||
'.esquiver-button',
|
||||
'.button-parade',
|
||||
'.button-esquive',
|
||||
'.button-encaisser',
|
||||
'.particuliere-attaque',
|
||||
'.encaisser-button',
|
||||
'.appel-chance-defense',
|
||||
'.appel-destinee-defense',
|
||||
'.appel-chance-attaque',
|
||||
'.appel-destinee-attaque',
|
||||
'.echec-total-attaque',
|
||||
// '.appel-chance',
|
||||
// '.chat-encaissement',
|
||||
// '.resister-recul',
|
||||
]) {
|
||||
$(html).on("click", button, event => {
|
||||
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(
|
||||
@@ -456,8 +483,8 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
async onEvent(button, event) {
|
||||
const chatMessage = ChatUtility.getChatMessage(event);
|
||||
const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll');
|
||||
const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll');
|
||||
const defenderRoll = ChatUtility.getMessageData(chatMessage, 'rollData');
|
||||
const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'rollData');
|
||||
console.log('RdDCombat', attackerRoll, defenderRoll);
|
||||
|
||||
const armeParadeId = event.currentTarget.attributes['data-armeid']?.value;
|
||||
@@ -466,9 +493,9 @@ export class RdDCombat {
|
||||
|
||||
switch (button) {
|
||||
case '.particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value);
|
||||
case '.parer-button': return this.parade(attackerRoll, armeParadeId);
|
||||
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 '.appel-chance-attaque': return this.attacker.rollAppelChance(
|
||||
@@ -478,11 +505,9 @@ export class RdDCombat {
|
||||
() => this.defenseChanceuse(attackerRoll, defenderRoll),
|
||||
() => this.afficherOptionsDefense(attackerRoll, defenderRoll, { defenseChance: true }));
|
||||
case '.appel-destinee-attaque': return this.attacker.appelDestinee(
|
||||
() => this.attaqueSignificative(attackerRoll),
|
||||
() => { });
|
||||
() => this.attaqueSignificative(attackerRoll));
|
||||
case '.appel-destinee-defense': return this.defender.appelDestinee(
|
||||
() => this.defenseDestinee(defenderRoll),
|
||||
() => { });
|
||||
() => this.defenseDestinee(defenderRoll));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,33 +577,48 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isEchecTotal(rollData) {
|
||||
if (!rollData.attackerRoll && rollData.ajustements.surprise.used) {
|
||||
return rollData.rolled.isEchec && rollData.rolled.code != 'notSign';
|
||||
if (rollData.v2 /* roll V2*/) {
|
||||
// TODO: en cas de demi-surprise à l'attaque, tout échec est un echec total.
|
||||
// TODO: en cas de demi-surprise 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) {
|
||||
if (!rollData.attackerRoll && rollData.ajustements.surprise.used) {
|
||||
return false;
|
||||
if (rollData.v2 /* roll V2*/) {
|
||||
return rollData.rolled.isPart
|
||||
}
|
||||
return rollData.rolled.isPart;
|
||||
if (rollData.attackerRoll || !rollData.ajustements.surprise.used) {
|
||||
return rollData.rolled.isPart
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isReussite(rollData) {
|
||||
switch (rollData.ajustements.surprise.used) {
|
||||
case 'totale': return false;
|
||||
case 'demi': return rollData.rolled.isSign;
|
||||
if (rollData.v2 /* roll V2*/) {
|
||||
return rollData.rolled.isSuccess
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async proposerAjustementTirLancer(rollData) {
|
||||
if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) {
|
||||
if (this.defender.isEntite([ENTITE_BLURETTE])) {
|
||||
if (this.defender.isEntiteBlurette()) {
|
||||
ChatMessage.create({
|
||||
content: `<strong>La cible est une blurette, l'arme à distance sera perdue dans le blurêve`,
|
||||
whisper: ChatUtility.getGMs()
|
||||
@@ -642,12 +682,110 @@ export class RdDCombat {
|
||||
return { msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3 };
|
||||
}
|
||||
|
||||
|
||||
async attaqueV2() {
|
||||
if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
|
||||
return
|
||||
}
|
||||
await this.doRollAttaque({
|
||||
ids: {
|
||||
actorId: this.attackerId,
|
||||
actorTokenId: this.attackerTokenId,
|
||||
opponentId: this.defender.id,
|
||||
opponentTokenId: this.defenderTokenId,
|
||||
},
|
||||
type: { allowed: ['attaque'], current: 'attaque' },
|
||||
passeArme: foundry.utils.randomID(16),
|
||||
})
|
||||
}
|
||||
|
||||
async doRollAttaque(rollData, callbacks = []) {
|
||||
// TODO V2 await this.proposerAjustementTirLancer(rollData)
|
||||
return await RollDialog.create(rollData, {
|
||||
onRollDone: RollDialog.onRollDoneClose,
|
||||
callbacks: [
|
||||
async (roll) => await this.onAttaqueV2(roll),
|
||||
...callbacks
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
async onAttaqueV2(attackerRoll) {
|
||||
if (!this.defender || !attackerRoll.rolled.isSuccess || attackerRoll.particulieres?.length > 1) {
|
||||
return
|
||||
}
|
||||
if (!await this.attacker.accorder(this.defender, 'avant-defense')) {
|
||||
return;
|
||||
}
|
||||
|
||||
RollDialog.loadRollData(attackerRoll)
|
||||
|
||||
const surpriseDefender = this.defender.getSurprise(true);
|
||||
const paramChatDefense = {
|
||||
attackerRoll: attackerRoll,
|
||||
isPossession: this.isPossession(attackerRoll),
|
||||
defender: this.defender,
|
||||
attacker: this.attacker,
|
||||
attackerId: this.attackerId,
|
||||
attackerToken: this.attackerToken,
|
||||
defenderToken: this.defenderToken,
|
||||
surprise: surpriseDefender,
|
||||
}
|
||||
|
||||
if (Misc.isFirstConnectedGM()) {
|
||||
await this._chatMessageDefenseV2(paramChatDefense);
|
||||
}
|
||||
else {
|
||||
this._socketSendMessageDefenseV2(paramChatDefense);
|
||||
}
|
||||
}
|
||||
|
||||
_socketSendMessageDefenseV2(paramChatDefense) {
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_defense_v2", data: {paramChatDefense} })
|
||||
}
|
||||
|
||||
static async onMsgDefenseV2(msg) {
|
||||
if (Misc.isFirstConnectedGM()) {
|
||||
const paramChatDefense = msg.paramChatDefense
|
||||
RollBasicParts.restore(paramChatDefense.attackerRoll)
|
||||
const rddCombat = RdDCombat.rddCombatForAttackV2(paramChatDefense.attackerRoll)
|
||||
rddCombat?.removeChatMessageActionsPasseArme(paramChatDefense.attackerRoll.passeArme)
|
||||
await rddCombat?._chatMessageDefenseV2(paramChatDefense)
|
||||
}
|
||||
}
|
||||
|
||||
async _chatMessageDefenseV2(paramDemandeDefense) {
|
||||
const attackerRoll = paramDemandeDefense.attackerRoll;
|
||||
RollBasicParts.loadSurprises(attackerRoll)
|
||||
attackerRoll.dmg = RdDBonus.dmgRollV2(attackerRoll, attackerRoll.current.attaque)
|
||||
|
||||
const defenseData = RollBasicParts.prepareDefense(attackerRoll)
|
||||
|
||||
const choixDefense = await ChatMessage.create({
|
||||
// message privé: du défenseur à lui même (et aux GMs)
|
||||
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
|
||||
alias: this.attacker?.getAlias(),
|
||||
whisper: ChatUtility.getOwners(this.defender),
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', defenseData)
|
||||
});
|
||||
// flag pour garder les jets d'attaque/defense
|
||||
ChatUtility.setMessageData(choixDefense, 'demande-defense', true)
|
||||
ChatUtility.setMessageData(choixDefense, 'rollData', {
|
||||
ids: defenseData.ids,
|
||||
attackerRoll: RollDialog.saveParts(attackerRoll),
|
||||
passeArme: defenseData.passeArme
|
||||
})
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async attaque(competence, arme) {
|
||||
if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
|
||||
return
|
||||
}
|
||||
if (arme.system.cac == 'empoignade') {
|
||||
if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) {
|
||||
return this.attacker.rollCompetence(competence.name, { arme: arme })
|
||||
}
|
||||
if (arme.system.cac == EMPOIGNADE) {
|
||||
RdDEmpoignade.onAttaqueEmpoignade(this.attacker, this.defender)
|
||||
return
|
||||
}
|
||||
@@ -679,6 +817,7 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
_prepareAttaque(competence, arme) {
|
||||
let rollData = {
|
||||
mode: ROLL_TYPE_ATTAQUE,
|
||||
alias: this.attacker?.getAlias(),
|
||||
passeArme: foundry.utils.randomID(16),
|
||||
mortalite: arme?.system.mortalite,
|
||||
@@ -690,8 +829,8 @@ export class RdDCombat {
|
||||
essais: {}
|
||||
};
|
||||
|
||||
if (this.attacker.isCreatureEntite()) {
|
||||
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
||||
if (this.attacker.isCreatureOuEntite()) {
|
||||
MappingCreatureArme.setRollDataCreature(rollData);
|
||||
}
|
||||
else if (arme) {
|
||||
// Usual competence
|
||||
@@ -699,9 +838,9 @@ export class RdDCombat {
|
||||
}
|
||||
else {
|
||||
// sans armes: à mains nues
|
||||
rollData.arme = RdDItemArme.corpsACorps(this.attacker)
|
||||
rollData.arme = RdDItemArme.pugilat(this.attacker)
|
||||
rollData.arme.system.niveau = competence.system.niveau
|
||||
rollData.arme.system.initiative = RdDInitiative.calculInitiative(competence.system.niveau, this.attacker.system.carac['melee'].value);
|
||||
rollData.arme.system.initiative = RdDInitiative.getRollInitiative(this.attacker.system.carac['melee'].value, competence.system.niveau);
|
||||
}
|
||||
return rollData;
|
||||
}
|
||||
@@ -713,9 +852,6 @@ export class RdDCombat {
|
||||
if (RdDCombat.isReussite(attackerRoll)) {
|
||||
return await this._onAttaqueNormale(attackerRoll)
|
||||
}
|
||||
// if (RdDCombat.isParticuliere(attackerRoll) && attackerRoll.particuliere == undefined) {
|
||||
// return
|
||||
// }
|
||||
if (RdDCombat.isEchecTotal(attackerRoll)) {
|
||||
return await this._onAttaqueEchecTotal(attackerRoll)
|
||||
}
|
||||
@@ -755,14 +891,14 @@ export class RdDCombat {
|
||||
passeArme: rollData.passeArme
|
||||
})
|
||||
});
|
||||
ChatUtility.setMessageData(choixParticuliere, 'attacker-roll', rollData);
|
||||
ChatUtility.setMessageData(choixParticuliere, 'rollData', rollData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _onAttaqueNormale(attackerRoll) {
|
||||
console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll);
|
||||
|
||||
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite());
|
||||
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker);
|
||||
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
|
||||
attackerRoll.show = {
|
||||
cible: this.defender?.getAlias() ?? 'la cible',
|
||||
@@ -781,13 +917,14 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
isPossession(attackerRoll) {
|
||||
return attackerRoll.selectedCarac.label.toLowerCase() == 'possession';
|
||||
const carac = attackerRoll.v2
|
||||
? attackerRoll.current.carac?.label
|
||||
: attackerRoll.selectedCarac.label
|
||||
return carac?.toLowerCase() == 'possession';
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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);
|
||||
if (essaisPrecedents) {
|
||||
foundry.utils.mergeObject(attackerRoll.essais, essaisPrecedents, { overwrite: true });
|
||||
@@ -833,10 +970,10 @@ export class RdDCombat {
|
||||
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
|
||||
alias: this.attacker?.getAlias(),
|
||||
whisper: ChatUtility.getOwners(this.defender),
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.hbs', paramDemandeDefense),
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense-v1.hbs', paramDemandeDefense),
|
||||
});
|
||||
// flag pour garder les jets d'attaque/defense
|
||||
ChatUtility.setMessageData(choixDefense, 'defender-roll', defenderRoll);
|
||||
ChatUtility.setMessageData(choixDefense, 'rollData', defenderRoll);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -850,14 +987,14 @@ export class RdDCombat {
|
||||
defenderToken: this.defenderToken,
|
||||
defenderRoll: defenderRoll,
|
||||
paramChatDefense: paramChatDefense,
|
||||
rollMode: true
|
||||
rollMode: true,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_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.forEach(armeDefense => {
|
||||
// Ajout du # d'utilisation ce round
|
||||
@@ -879,6 +1016,7 @@ export class RdDCombat {
|
||||
const choixEchecTotal = await ChatMessage.create({
|
||||
whisper: ChatUtility.getOwners(this.attacker),
|
||||
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.hbs', {
|
||||
rolled: attackerRoll.rolled,
|
||||
attackerId: this.attackerId,
|
||||
attacker: this.attacker,
|
||||
attackerToken: this.attackerToken,
|
||||
@@ -886,7 +1024,7 @@ export class RdDCombat {
|
||||
essais: attackerRoll.essais
|
||||
})
|
||||
});
|
||||
ChatUtility.setMessageData(choixEchecTotal, 'attacker-roll', attackerRoll);
|
||||
ChatUtility.setMessageData(choixEchecTotal, 'rollData', attackerRoll);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -946,9 +1084,43 @@ export class RdDCombat {
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
async defenseV2(attackerRoll, callbacks = []) {
|
||||
// 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: attackerRoll,
|
||||
passeArme: attackerRoll.passeArme,
|
||||
}, callbacks)
|
||||
}
|
||||
|
||||
async doRollDefense(rollData, callbacks = []) {
|
||||
return await RollDialog.create(rollData, {
|
||||
onRollDone: RollDialog.onRollDoneClose,
|
||||
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) {
|
||||
let defenderRoll = {
|
||||
mode: ROLL_TYPE_DEFENSE,
|
||||
alias: this.defender?.getAlias(),
|
||||
passeArme: attackerRoll.passeArme,
|
||||
diffLibre: attackerRoll.diffLibre,
|
||||
@@ -964,13 +1136,48 @@ export class RdDCombat {
|
||||
show: {}
|
||||
};
|
||||
|
||||
if (this.defender.isCreatureEntite()) {
|
||||
RdDItemCompetenceCreature.setRollDataCreature(defenderRoll);
|
||||
if (this.defender.isCreatureOuEntite()) {
|
||||
MappingCreatureArme.setRollDataCreature(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) {
|
||||
if (RdDCombat.isReussite(defenderRoll)) {
|
||||
@@ -1042,6 +1249,7 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
_prepareEsquive(attackerRoll, competence) {
|
||||
let rollData = {
|
||||
mode: ROLL_TYPE_DEFENSE,
|
||||
alias: this.defender.getAlias(),
|
||||
passeArme: attackerRoll.passeArme,
|
||||
diffLibre: attackerRoll.diffLibre,
|
||||
@@ -1055,8 +1263,8 @@ export class RdDCombat {
|
||||
show: {}
|
||||
};
|
||||
|
||||
if (this.defender.isCreatureEntite()) {
|
||||
RdDItemCompetenceCreature.setRollDataCreature(rollData);
|
||||
if (this.defender.isCreatureOuEntite()) {
|
||||
MappingCreatureArme.setRollDataCreature(rollData);
|
||||
}
|
||||
return rollData;
|
||||
}
|
||||
@@ -1105,7 +1313,7 @@ export class RdDCombat {
|
||||
// Est-ce une parade normale?
|
||||
if (defenderRoll.arme && attackerRoll && !defenderRoll.rolled.isPart) {
|
||||
// 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 || {}
|
||||
|
||||
@@ -1153,7 +1361,7 @@ export class RdDCombat {
|
||||
finalLevel: Misc.toInt(defenderRoll.competence.system.niveau) - dmg,
|
||||
showDice: HIDE_DICE
|
||||
});
|
||||
defenderRoll.show.desarme = desarme.rolled.isEchec;
|
||||
defenderRoll.show.desarme = desarme.rolled.isEchec
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1161,41 +1369,19 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async computeRecul(defenderRoll) { // Calcul du recul (p. 132)
|
||||
if (!ReglesOptionnelles.isUsing('recul')) {
|
||||
return
|
||||
}
|
||||
const attackerRoll = defenderRoll.attackerRoll;
|
||||
if (ReglesOptionnelles.isUsing('recul') && this._isForceOuCharge(attackerRoll)) {
|
||||
const impact = this._computeImpactRecul(attackerRoll);
|
||||
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';
|
||||
}
|
||||
if (this._isForceOuCharge(attackerRoll, defenderRoll.v2)) {
|
||||
defenderRoll.show.recul = this.defender.encaisserRecul(this.attacker.getForce(), attackerRoll.dmg.dmgArme)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _isReculCauseChute(impact) {
|
||||
const agilite = this.defender.getAgilite();
|
||||
const chute = await RdDResolutionTable.rollData({ caracValue: agilite, finalLevel: impact });
|
||||
return chute.rolled.isEchec;
|
||||
_isForceOuCharge(attaque, isRollV2 = false /* TODO: delete roll V1 */) {
|
||||
return attaque.particuliere == 'force' || 'charge' == (isRollV2 ? attaque.tactique?.key : attaque.tactique)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_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) {
|
||||
@@ -1205,12 +1391,16 @@ export class RdDCombat {
|
||||
this._onEchecTotal(defenderRoll);
|
||||
}
|
||||
|
||||
await this.doRollEncaissement(attackerRoll, defenderRoll);
|
||||
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||
}
|
||||
|
||||
async doRollEncaissement(attackerRoll, defenderRoll) {
|
||||
if (Misc.isOwnerPlayer(this.defender)) {
|
||||
attackerRoll.attackerId = this.attackerId;
|
||||
attackerRoll.defenderTokenId = this.defenderToken.id;
|
||||
|
||||
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
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
@@ -1221,9 +1411,8 @@ export class RdDCombat {
|
||||
attackerToken: this.attackerToken,
|
||||
defenderToken: this.defenderToken
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -1255,4 +1444,5 @@ export class RdDCombat {
|
||||
alias: alias
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import { TMRUtility } from "./tmr-utility.js";
|
||||
import { DialogFatigueVoyage } from "./voyage/dialog-fatigue-voyage.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
import { renderTemplate } from "./constants.js";
|
||||
|
||||
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
|
||||
|
||||
@@ -460,12 +461,7 @@ export class RdDCommands {
|
||||
|
||||
async supprimerSignesDraconiquesEphemeres() {
|
||||
if (game.user.isGM) {
|
||||
game.actors.forEach(actor => {
|
||||
const ephemeres = actor.items.filter(item => item.type = 'signedraconique' && item.system.ephemere);
|
||||
if (ephemeres.length > 0) {
|
||||
actor.deleteEmbeddedDocuments("Item", ephemeres.map(item => item.id));
|
||||
}
|
||||
});
|
||||
game.actors.forEach(actor => actor.supprimerSignesDraconiques(it => it.system.ephemere))
|
||||
}
|
||||
else {
|
||||
ui.notifications.warn("Seul le MJ est autorisé à utiliser la commande /signe");
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/* -------------------------------------------- */
|
||||
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 { ITEM_TYPES } from "./constants.js";
|
||||
import { ITEM_TYPES, renderTemplate } from "./constants.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
import { RdDRoll } from "./rdd-roll.js";
|
||||
import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs";
|
||||
import { MAP_PHASE } from "./initiative.mjs";
|
||||
import { RdDCombatManager } from "./rdd-combat.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDEmpoignade {
|
||||
@@ -13,6 +14,49 @@ export class RdDEmpoignade {
|
||||
static init() {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isCombatantEmpoignade(actorId, tokenId) {
|
||||
const combatant = RdDCombatManager.getCombatant(actorId, tokenId)
|
||||
return MAP_PHASE.empoignade.rang == combatant?.system.init?.rang
|
||||
}
|
||||
|
||||
static async ajustementEmpoignade(attacker, defender, adjust = 1) {
|
||||
const empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||
const empId = empoignade?.system.empoignadeid ?? foundry.utils.randomID(16)
|
||||
if (empoignade) {
|
||||
if (empoignade.system.empoigneurid == defender.id) {
|
||||
adjust = - adjust
|
||||
}
|
||||
empoignade.system.pointsemp += adjust
|
||||
await RdDEmpoignade.$updateEtatEmpoignade(empoignade, attacker, defender)
|
||||
}
|
||||
else {
|
||||
await RdDEmpoignade.$createEtatEmpoignade({
|
||||
name: `Empoignade de ${attacker.name} sur ${defender.name}`,
|
||||
type: ITEM_TYPES.empoignade,
|
||||
system: {
|
||||
description: "",
|
||||
empoignadeid: empId,
|
||||
empoigneurid: attacker.id,
|
||||
empoigneid: defender.id,
|
||||
pointsemp: adjust,
|
||||
empoigneurname: attacker.name,
|
||||
empoignename: defender.name
|
||||
}
|
||||
}, attacker, defender)
|
||||
}
|
||||
const result = RdDEmpoignade.getEmpoignadeById(defender, empId);
|
||||
const defGrappled = result.system.pointsemp == (result.system.empoigneid == defender.id ? 2 : -2)
|
||||
const attGrappled = result.system.pointsemp == (result.system.empoigneurid == attacker.id ? -2 : 2)
|
||||
const grappling = Math.abs(result.system.pointsemp) > 0
|
||||
await defender.setEffect(STATUSES.StatusGrappling, grappling && !defGrappled)
|
||||
await attacker.setEffect(STATUSES.StatusGrappling, grappling && !attGrappled)
|
||||
await defender.setEffect(STATUSES.StatusGrappled, defGrappled)
|
||||
await attacker.setEffect(STATUSES.StatusGrappled, attGrappled)
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static registerChatCallbacks(html) {
|
||||
$(html).on("click", '.defense-empoignade-cac', event => {
|
||||
@@ -185,8 +229,8 @@ export class RdDEmpoignade {
|
||||
selectedCarac: attacker.system.carac.melee,
|
||||
malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender)
|
||||
}
|
||||
if (attacker.isCreatureEntite()) {
|
||||
RdDItemCompetenceCreature.setRollDataCreature(rollData)
|
||||
if (attacker.isCreatureOuEntite()) {
|
||||
MappingCreatureArme.setRollDataCreature(rollData)
|
||||
}
|
||||
if (empoignade.system.pointsemp >= 2) {
|
||||
if (!empoignade.system.ausol) {
|
||||
@@ -238,10 +282,7 @@ export class RdDEmpoignade {
|
||||
|
||||
|
||||
if (rollData.rolled.isSuccess && isNouvelle) {
|
||||
const objectEmpoignade = rollData.empoignade.toObject();
|
||||
// Creer l'empoignade sur attaquant/defenseur
|
||||
attacker.creerObjetParMJ(objectEmpoignade);
|
||||
defender.creerObjetParMJ(objectEmpoignade);
|
||||
RdDEmpoignade.$createEtatEmpoignade(rollData.empoignade)
|
||||
}
|
||||
|
||||
rollData.empoignade.isSuccess = rollData.rolled.isSuccess;
|
||||
@@ -260,7 +301,7 @@ export class RdDEmpoignade {
|
||||
return
|
||||
}
|
||||
|
||||
let empoignade = this.getEmpoignade(attacker, defender)
|
||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||
|
||||
if (!empoignade) {
|
||||
ui.notifications.warn("Une erreur s'est produite : Aucune empoignade trouvée !!")
|
||||
@@ -318,18 +359,33 @@ export class RdDEmpoignade {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $updateEtatEmpoignade(empoignade) {
|
||||
console.log("UPDATE Empoignade", empoignade)
|
||||
static async $createEtatEmpoignade(empoignade) {
|
||||
console.log("CREATE Empoignade", empoignade)
|
||||
|
||||
let defender = game.actors.get(empoignade.system.empoigneid)
|
||||
let emp = RdDEmpoignade.getEmpoignadeById(defender, empoignade.system.empoignadeid)
|
||||
let update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol }
|
||||
await defender.updateEmbeddedDocuments('Item', [update])
|
||||
|
||||
let attacker = game.actors.get(empoignade.system.empoigneurid)
|
||||
emp = RdDEmpoignade.getEmpoignadeById(attacker, empoignade.system.empoignadeid)
|
||||
update = { _id: emp._id, "system.pointsemp": empoignade.system.pointsemp, "system.ausol": empoignade.system.ausol }
|
||||
await attacker.updateEmbeddedDocuments('Item', [update])
|
||||
|
||||
// Creer l'empoignade sur attaquant/defenseur
|
||||
await attacker.creerObjetParMJ(empoignade)
|
||||
await defender.creerObjetParMJ(empoignade)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async $updateEtatEmpoignade(empoignade, attacker, defender) {
|
||||
console.log("UPDATE Empoignade", empoignade)
|
||||
const belligerants = [
|
||||
attacker ?? game.actors.get(empoignade.system.empoigneurid),
|
||||
defender ?? game.actors.get(empoignade.system.empoigneid)]
|
||||
|
||||
await Promise.all(
|
||||
belligerants.map(async belligerant => {
|
||||
const emp = RdDEmpoignade.getEmpoignadeById(belligerant, empoignade.system.empoignadeid)
|
||||
return await belligerant.updateEmbeddedDocuments('Item', [{
|
||||
_id: emp._id,
|
||||
"system.pointsemp": empoignade.system.pointsemp,
|
||||
"system.ausol": empoignade.system.ausol
|
||||
}])
|
||||
}))
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -348,7 +404,7 @@ export class RdDEmpoignade {
|
||||
if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) {
|
||||
return
|
||||
}
|
||||
let empoignade = this.getEmpoignade(attacker, defender)
|
||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||
|
||||
empoignade.system.ausol = true
|
||||
await this.$updateEtatEmpoignade(empoignade)
|
||||
@@ -367,7 +423,7 @@ export class RdDEmpoignade {
|
||||
if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) {
|
||||
return
|
||||
}
|
||||
let empoignade = this.getEmpoignade(attacker, defender)
|
||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||
|
||||
await defender.setEffect(STATUSES.StatusProne, true);
|
||||
await this.$deleteEmpoignade(empoignade)
|
||||
@@ -383,7 +439,7 @@ export class RdDEmpoignade {
|
||||
if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) {
|
||||
return
|
||||
}
|
||||
let empoignade = this.getEmpoignade(attacker, defender)
|
||||
let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender)
|
||||
|
||||
//console.log("Perte d'endurance :!!!", perteMode)
|
||||
let endValue = defender.system.sante.endurance.value
|
||||
@@ -424,9 +480,17 @@ export class RdDEmpoignade {
|
||||
/* -------------------------------------------- */
|
||||
static async createEmpoignade(attacker, defender) {
|
||||
return await Item.create({
|
||||
name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name,
|
||||
type: 'empoignade',
|
||||
system: { description: "", empoignadeid: foundry.utils.randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name }
|
||||
name: "Empoignade de " + attacker.name + ' sur ' + defender.name,
|
||||
type: ITEM_TYPES.empoignade,
|
||||
system: {
|
||||
description: "",
|
||||
empoignadeid: foundry.utils.randomID(16),
|
||||
empoigneurid: attacker.id,
|
||||
empoigneid: defender.id,
|
||||
pointsemp: 0,
|
||||
empoigneurname: attacker.name,
|
||||
empoignename: defender.name
|
||||
}
|
||||
},
|
||||
{
|
||||
temporary: true
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { RdDItemArme } from "./item/arme.js";
|
||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||
import { ATTAQUE_TYPE, EMPOIGNADE, PUGILAT, RdDItemArme } from "./item/arme.js";
|
||||
import { ITEM_TYPES } from "./constants.js";
|
||||
|
||||
export class RdDHotbar {
|
||||
@@ -20,14 +19,17 @@ export class RdDHotbar {
|
||||
await game.user.assignHotbarMacro(macro, slot);
|
||||
}
|
||||
|
||||
static $macroNameSuffix(armeCompetence) {
|
||||
switch (armeCompetence) {
|
||||
case '(1 main)': return ' (1 main)';
|
||||
case '(2 mains)': return ' (2 main)';
|
||||
static $macroNameSuffix(maniement) {
|
||||
switch (maniement) {
|
||||
case ATTAQUE_TYPE.UNE_MAIN:
|
||||
case ATTAQUE_TYPE.DEUX_MAINS:
|
||||
case ATTAQUE_TYPE.LANCER:
|
||||
case ATTAQUE_TYPE.TIR:
|
||||
return ' ' + maniement
|
||||
case 'tir': return ' (tir)';
|
||||
case 'lancer': return ' (lancer)';
|
||||
case 'pugilat': return ' (pugilat)';
|
||||
case 'empoignade': return ' (empoignade)';
|
||||
case PUGILAT: return ' (pugilat)';
|
||||
case EMPOIGNADE: return ' (empoignade)';
|
||||
}
|
||||
return ''
|
||||
}
|
||||
@@ -39,30 +41,30 @@ export class RdDHotbar {
|
||||
// Les armes peuvent avoir plusieurs usages
|
||||
if (item.system.competence != '') {
|
||||
if (item.system.unemain) {
|
||||
await this.createItemMacro(item, slot++, '(1 main)')
|
||||
await this.createItemMacro(item, slot++, ATTAQUE_TYPE.UNE_MAIN)
|
||||
}
|
||||
if (item.system.deuxmains) {
|
||||
await this.createItemMacro(item, slot++, '(2 mains)')
|
||||
await this.createItemMacro(item, slot++, ATTAQUE_TYPE.DEUX_MAINS)
|
||||
}
|
||||
}
|
||||
if (item.system.lancer != '') {
|
||||
await this.createItemMacro(item, slot++, 'lancer')
|
||||
await this.createItemMacro(item, slot++, ATTAQUE_TYPE.LANCER)
|
||||
}
|
||||
if (item.system.tir != '') {
|
||||
await this.createItemMacro(item, slot++, 'lancer')
|
||||
await this.createItemMacro(item, slot++, ATTAQUE_TYPE.TIR)
|
||||
}
|
||||
}
|
||||
return
|
||||
case ITEM_TYPES.competencecreature:
|
||||
const categorie = RdDItemCompetenceCreature.getCategorieAttaque(item) ?? 'competence';
|
||||
const categorie = item.getCategorieAttaque() ?? 'competence';
|
||||
await this.createItemMacro(item, slot, categorie)
|
||||
return
|
||||
default:
|
||||
case ITEM_TYPES.competence:
|
||||
await this.createItemMacro(item, slot++, 'competence')
|
||||
if (item.isCorpsACorps()) {
|
||||
await this.createItemMacro(item, slot++, 'pugilat')
|
||||
await this.createItemMacro(item, slot++, 'empoignade')
|
||||
await this.createItemMacro(item, slot++, PUGILAT)
|
||||
await this.createItemMacro(item, slot++, EMPOIGNADE)
|
||||
}
|
||||
else if (item.isCompetenceArme()) {
|
||||
ui.notifications.info(`${item.name} est une compétence d'arme, la macro n'est pas liée à un arme.<br>
|
||||
@@ -119,15 +121,15 @@ export class RdDHotbar {
|
||||
case ITEM_TYPES.competence:
|
||||
if (item.isCorpsACorps()) {
|
||||
switch (categorieArme) {
|
||||
case 'pugilat':
|
||||
return actor.rollArme(RdDItemArme.corpsACorps(actor));
|
||||
case 'empoignade':
|
||||
case PUGILAT:
|
||||
return actor.rollArme(RdDItemArme.pugilat(actor));
|
||||
case EMPOIGNADE:
|
||||
return actor.rollArme(RdDItemArme.empoignade(actor));
|
||||
}
|
||||
}
|
||||
return actor.rollCompetence(item);
|
||||
case ITEM_TYPES.competencecreature:
|
||||
return item.system.iscombat && !item.system.isparade
|
||||
return item.system.iscombat
|
||||
? actor.rollArme(item, categorieArme)
|
||||
: actor.rollCompetence(item);
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ import * as sheets from "./applications/sheets/_module.mjs"
|
||||
import { RdDItemArme } from "./item/arme.js"
|
||||
import { RdDItemArmure } from "./item/armure.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 { RdDItemMaladie } from "./item/maladie.js"
|
||||
import { RdDItemOmbre } from "./item/ombre.js"
|
||||
@@ -86,6 +88,8 @@ import { RdDCombatManager, RdDCombat } from "./rdd-combat.js"
|
||||
import { Migrations } from './migrations.js'
|
||||
|
||||
import RollDialog from "./roll/roll-dialog.mjs"
|
||||
import ChatRollResult from "./roll/chat-roll-result.mjs"
|
||||
import ExportPdf from "./actor/export-pdf/export-pdf.mjs"
|
||||
|
||||
/**
|
||||
* RdD system
|
||||
@@ -112,6 +116,8 @@ export class SystemReveDeDragon {
|
||||
arme: RdDItemArme,
|
||||
armure: RdDItemArmure,
|
||||
blessure: RdDItemBlessure,
|
||||
competence: RdDItemCompetence,
|
||||
competencecreature: RdDItemCompetenceCreature,
|
||||
gemme: RdDItemGemme,
|
||||
maladie: RdDItemMaladie,
|
||||
ombre: RdDItemOmbre,
|
||||
@@ -291,7 +297,9 @@ export class SystemReveDeDragon {
|
||||
RdDPossession.init()
|
||||
TMRRencontres.init()
|
||||
ExportScriptarium.init()
|
||||
ExportPdf.init()
|
||||
RollDialog.init()
|
||||
ChatRollResult.init()
|
||||
}
|
||||
|
||||
initSettings() {
|
||||
@@ -346,18 +354,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() {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
/* -------------------------------------------- */
|
||||
@@ -376,7 +373,8 @@ export class SystemReveDeDragon {
|
||||
StatusEffects.onReady()
|
||||
RdDDice.onReady()
|
||||
RollDialog.onReady()
|
||||
RdDStatBlockParser.parseStatBlock()
|
||||
ChatRollResult.onReady()
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Affiche/Init le calendrier */
|
||||
game.system.rdd.calendrier.display()
|
||||
@@ -389,7 +387,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 { renderTemplate } from "./constants.js"
|
||||
|
||||
const vents = [
|
||||
{ min: 0, max: 0, valeur: 'Calme' },
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { RdDBaseActor } from "./actor/base-actor.js";
|
||||
import { ChatUtility } from "./chat-utility.js";
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { RdDRoll } from "./rdd-roll.js";
|
||||
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
|
||||
import { Targets } from "./targets.js";
|
||||
import { ITEM_TYPES } from "./constants.js";
|
||||
import { RdDRollResult } from "./rdd-roll-result.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* On part du principe qu'une entité démarre tjs
|
||||
@@ -97,7 +95,7 @@ export class RdDPossession {
|
||||
|
||||
static selectCompetenceDraconicOuPossession(rollData, rollingActor) {
|
||||
rollData.competence = rollingActor.getDraconicOuPossession();
|
||||
if (rollingActor.isCreatureEntite()) {
|
||||
if (rollingActor.isCreatureOuEntite()) {
|
||||
const carac = rollingActor.system.carac
|
||||
rollData.carac = carac
|
||||
rollData.competence.system.defaut_carac = 'reve'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { renderTemplate } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
import { RdDDice } from "./rdd-dice.js";
|
||||
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
|
||||
@@ -15,17 +16,20 @@ const levelDown = [
|
||||
];
|
||||
const levelImpossible = { score: 0, norm: 0, sign: 0, part: 0, epart: 0, etotal: 1 };
|
||||
|
||||
const reussiteNormale = { code: "norm", isPart: false, isSign: false, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 1, ptQualite: 0, quality: "Réussite normale", condition: (target, roll) => (roll > target.sign && roll <= target.norm) };
|
||||
const reussiteSignificative = { code: "sign", isPart: false, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 2, ptQualite: 1, quality: "Réussite significative", condition: (target, roll) => (roll > target.part && roll <= target.sign) };
|
||||
const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false }
|
||||
|
||||
const reussites = [
|
||||
{ code: "etotal", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: -4, ptQualite: -6, quality: "Echec total", condition: (target, roll) => roll >= target.etotal && roll <= 100 },
|
||||
{ code: "epart", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: false, ptTache: -2, ptQualite: -4, quality: "Echec particulier", condition: (target, roll) => (roll >= target.epart && roll < target.etotal) },
|
||||
{ code: "echec", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Echec normal", condition: (target, roll) => (roll > target.norm && roll < target.etotal) },
|
||||
{ code: "norm", isPart: false, isSign: false, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 1, ptQualite: 0, quality: "Réussite normale", condition: (target, roll) => (roll > target.sign && roll <= target.norm) },
|
||||
{ code: "sign", isPart: false, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 2, ptQualite: 1, quality: "Réussite significative", condition: (target, roll) => (roll > target.part && roll <= target.sign) },
|
||||
reussiteNormale,
|
||||
reussiteSignificative,
|
||||
{ code: "part", isPart: true, isSign: true, isSuccess: true, isEchec: false, isEPart: false, isETotal: false, ptTache: 3, ptQualite: 2, quality: "Réussite Particulière!", condition: (target, roll) => (roll > 0 && roll <= target.part) },
|
||||
{ code: "error", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: true, isETotal: true, ptTache: 0, ptQualite: 0, quality: "Jet de dés invalide", condition: (target, roll) => (roll <= 0 || roll > 100) }
|
||||
];
|
||||
|
||||
const reussiteInsuffisante = { code: "notSign", isPart: false, isSign: false, isSuccess: false, isEchec: true, isEPart: false, isETotal: false, ptTache: 0, ptQualite: -2, quality: "Réussite insuffisante", condition: (target, roll) => false }
|
||||
/* -------------------------------------------- */
|
||||
const CARAC_MAXIMUM_RESOLUTION = 40;
|
||||
/* -------------------------------------------- */
|
||||
@@ -66,9 +70,9 @@ export class RdDResolutionTable {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _computeCell(niveau, percentage) {
|
||||
static _computeCell(level, percentage) {
|
||||
return {
|
||||
niveau: niveau,
|
||||
level: level,
|
||||
score: percentage,
|
||||
norm: Math.min(99, percentage),
|
||||
sign: this._reussiteSignificative(percentage),
|
||||
@@ -155,9 +159,14 @@ export class RdDResolutionTable {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static replaceParticuliereDemiSurprise(chances) {
|
||||
foundry.utils.mergeObject(chances, reussites.find(x => x.code == 'part'), { overwrite: true });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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 });
|
||||
}
|
||||
|
||||
@@ -184,47 +193,16 @@ export class RdDResolutionTable {
|
||||
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) {
|
||||
const reussite = reussites.find(x => x.condition(chances, roll));
|
||||
if (diviseur > 1 && reussite.code == 'norm') {
|
||||
return reussiteInsuffisante;
|
||||
const reussite = reussites.find(x => x.condition(chances, roll))
|
||||
if (diviseur > 1 && reussite.isSuccess) {
|
||||
if (chances.norm < roll * diviseur) {
|
||||
return reussiteInsuffisante
|
||||
}
|
||||
return reussiteSignificative
|
||||
}
|
||||
return reussite;
|
||||
return reussite
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@@ -268,7 +246,7 @@ export class RdDResolutionTable {
|
||||
maxCarac = Math.min(maxCarac, minCarac + 20);
|
||||
minLevel = Math.max(minLevel, -10);
|
||||
maxLevel = Math.max(Math.min(maxLevel, 30), minLevel + colonnes);
|
||||
return await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', {
|
||||
return await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/resolution-table.hbs', {
|
||||
carac: carac,
|
||||
difficulte: level,
|
||||
min: minLevel,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ENTITE_BLURETTE, ENTITE_INCARNE } from "./constants.js";
|
||||
import { ENTITE_NONINCARNE, RDD_CONFIG, renderTemplate } from "./constants.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
|
||||
/**
|
||||
@@ -16,34 +16,29 @@ export class RdDEncaisser extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(html, actor) {
|
||||
let dialogConf = {
|
||||
if (actor.isEntiteNonIncarnee([ENTITE_NONINCARNE])) {
|
||||
throw `${actor.name} est une entité non incarnée et ne peut pas subnir de dommages`
|
||||
}
|
||||
|
||||
const dialogConf = {
|
||||
title: "Jet d'Encaissement",
|
||||
content: html,
|
||||
}
|
||||
|
||||
if (!actor.isEntite()) {
|
||||
dialogConf.default = "mortel";
|
||||
dialogConf.buttons = {
|
||||
"mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") },
|
||||
"non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") },
|
||||
"sonne": { label: "Sonné", callback: html => this.actor.setSonne() },
|
||||
};
|
||||
}
|
||||
else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])) {
|
||||
dialogConf.default = "entiteincarnee"
|
||||
dialogConf.buttons = {
|
||||
"entiteincarnee": { label: "Entité incarnée", callback: html => this.performEncaisser("entiteincarnee") }
|
||||
default: RDD_CONFIG.encaissement.mortel,
|
||||
buttons: {
|
||||
[RDD_CONFIG.encaissement.mortel]: { label: "Mortel", callback: html => this.performEncaisser(RDD_CONFIG.encaissement.mortel) },
|
||||
}
|
||||
}
|
||||
|
||||
let dialogOptions = {
|
||||
classes: ["rdd-roll-dialog"],
|
||||
width: 320,
|
||||
height: 'fit-content'
|
||||
if (!actor.isEntite()) {
|
||||
dialogConf.buttons[RDD_CONFIG.encaissement.nonmortel] = { label: "Non-mortel", callback: html => this.performEncaisser(RDD_CONFIG.encaissement.nonmortel) }
|
||||
dialogConf.buttons["sonne"] = { label: "Sonné", callback: html => this.actor.setSonne() }
|
||||
}
|
||||
|
||||
// Select proper roll dialog template and stuff
|
||||
super(dialogConf, dialogOptions);
|
||||
super(dialogConf, {
|
||||
classes: ["rdd-roll-dialog"],
|
||||
width: 320,
|
||||
height: 'fit-content'
|
||||
});
|
||||
|
||||
this.actor = actor;
|
||||
this.modifier = 0;
|
||||
@@ -66,12 +61,11 @@ export class RdDEncaisser extends Dialog {
|
||||
/* -------------------------------------------- */
|
||||
performEncaisser(mortalite) {
|
||||
this.actor.encaisserDommages({
|
||||
dmg: {
|
||||
total: Number(this.modifier),
|
||||
ajustement: Number(this.modifier),
|
||||
encaisserSpecial: this.encaisserSpecial,
|
||||
mortalite: mortalite
|
||||
}
|
||||
total: Number(this.modifier),
|
||||
ajustement: Number(this.modifier),
|
||||
encaisserSpecial: this.encaisserSpecial,
|
||||
mortalite: mortalite,
|
||||
penetration: 0
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||