Compare commits
205 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf13b986d4 | ||
|
|
f8364888f2 | ||
|
|
e2579e12f8 | ||
|
|
2c2c4cc83f | ||
|
|
dbeb511bdc | ||
|
|
ec6378092f | ||
|
|
d479ef7559 | ||
|
|
c466e0e539 | ||
|
|
cfaed0d230 | ||
|
|
8aff8b0fda | ||
|
|
6b80f3530d | ||
|
|
002438398b | ||
|
|
af4f0f60a4 | ||
|
|
6198146c6c | ||
|
|
484c7a375c | ||
|
|
2df7d2243f | ||
|
|
10449acf37 | ||
|
|
c6a7f86926 | ||
|
|
48ceade1d1 | ||
|
|
6d41a33b0c | ||
|
|
c3bb67ad7c | ||
|
|
2737c46ffe | ||
|
|
7e5fc036aa | ||
|
|
aa41635f88 | ||
|
|
050fecd4f6 | ||
|
|
44eaec2d38 | ||
|
|
8c83d304b7 | ||
| 118dcfb71c | |||
|
|
1598081e3b | ||
|
|
a8c94ee16f | ||
|
|
ca0d3eb970 | ||
|
|
f2c169c077 | ||
|
|
fde3881653 | ||
|
|
f15f3a4456 | ||
|
|
3ace1df5a2 | ||
|
|
92652262f3 | ||
|
|
c5c5a71587 | ||
|
|
878d278303 | ||
|
|
1d148d39db | ||
|
|
4efa89915a | ||
|
|
1c372415f4 | ||
|
|
1558468526 | ||
|
|
e0e4a7b68a | ||
|
|
a0f17fc4f5 | ||
|
|
14827195fe | ||
|
|
f4d7ea59f3 | ||
|
|
0ac7f07081 | ||
|
|
a1e9c565af | ||
|
|
d8b676535f | ||
|
|
96b24d6445 | ||
|
|
81a3e822a8 | ||
|
|
24d31aad30 | ||
|
|
e0a3b4985b | ||
|
|
566faf61d2 | ||
|
|
9f6a8e5e73 | ||
|
|
d5429b7b34 | ||
|
|
1c2ced321b | ||
|
|
82452f4f7c | ||
|
|
dd5a980f4e | ||
|
|
ad2da03f1e | ||
|
|
de672642d2 | ||
|
|
97ac56dadc | ||
|
|
fc065a5234 | ||
|
|
5a0484190e | ||
|
|
3a5a3ecc38 | ||
|
|
e54857023b | ||
|
|
9a99f6fc35 | ||
|
|
23fc2cb474 | ||
|
|
194eba779d | ||
|
|
df316c68f3 | ||
|
|
be31e98dea | ||
|
|
0f28e23b5c | ||
|
|
3d8d041915 | ||
|
|
19666a4e05 | ||
|
|
eadaa53c75 | ||
|
|
5c5a1a8b56 | ||
|
|
f4014e9c35 | ||
|
|
4c11a21d09 | ||
|
|
71c091e04a | ||
| c03cd1dcd7 | |||
|
|
fe4abd073f | ||
|
|
c7bafee6b6 | ||
|
|
36976e5123 | ||
|
|
6504e33fad | ||
|
|
97af3801c4 | ||
|
|
34eae97b47 | ||
|
|
337370bbfe | ||
|
|
60797ab1e2 | ||
|
|
ec07fcfd39 | ||
|
|
acbcb6c9b2 | ||
|
|
649381cfdd | ||
|
|
b19d248bc8 | ||
|
|
022a63f12f | ||
|
|
8c9d8125f2 | ||
|
|
8ef9bd2550 | ||
|
|
07517658e7 | ||
|
|
1ba6cd0617 | ||
|
|
96f5b17785 | ||
|
|
b3e699bc32 | ||
|
|
55a64afe02 | ||
|
|
18cdc2addc | ||
|
|
0605542d62 | ||
|
|
bad95f8c18 | ||
|
|
6a355e63c0 | ||
|
|
a383225b8c | ||
|
|
d64ed37953 | ||
|
|
68b53601d6 | ||
|
|
3b4e2405c1 | ||
|
|
df38113533 | ||
|
|
6db5818184 | ||
|
|
25a1e7e574 | ||
|
|
80995da0aa | ||
|
|
aa5c6d5aba | ||
|
|
cf109a6ed1 | ||
|
|
83d0bad21f | ||
|
|
310ac07c88 | ||
|
|
d69790ce89 | ||
|
|
0304af3695 | ||
|
|
59b64f57db | ||
|
|
23ec5fe0d3 | ||
|
|
30ed81cafa | ||
|
|
33ccb01a6f | ||
|
|
62554d1622 | ||
|
|
0c1149a21c | ||
|
|
cd98e66484 | ||
|
|
745824f6cc | ||
|
|
7549cd2b05 | ||
|
|
82f1499c3d | ||
|
|
992ae094b2 | ||
|
|
6d14d70f3e | ||
|
|
5e2fb95c73 | ||
|
|
27c30b7eef | ||
|
|
d131e2faaa | ||
|
|
47183da268 | ||
|
|
c716f0dbbd | ||
|
|
3c412dde32 | ||
|
|
5fe854a0f3 | ||
|
|
aab71df1fc | ||
|
|
b6ca477be7 | ||
|
|
8a51a75233 | ||
|
|
4e3a588c57 | ||
|
|
470f5b6225 | ||
|
|
46e7d674d3 | ||
|
|
afbb9bbe02 | ||
|
|
79b0431ead | ||
|
|
364ebd06f2 | ||
|
|
54d047d240 | ||
|
|
d100af3198 | ||
|
|
3981e95ff0 | ||
|
|
609b5820ba | ||
|
|
c525c1390b | ||
|
|
e6e392d7e5 | ||
|
|
42bd07707d | ||
|
|
daaa459012 | ||
|
|
cd6554289b | ||
|
|
5f09f92790 | ||
|
|
2065596686 | ||
|
|
c1ee1a9ef8 | ||
|
|
7516e7b42b | ||
|
|
0e8d1615a7 | ||
|
|
753d72b4e0 | ||
|
|
6d2d02b077 | ||
|
|
d74416c620 | ||
|
|
b123bea62c | ||
|
|
fb4026dcce | ||
|
|
19588bb137 | ||
|
|
bbd96d3b45 | ||
|
|
b4509555f3 | ||
|
|
1ca9958c52 | ||
|
|
c1fa5b3d9b | ||
|
|
34c7dbed87 | ||
|
|
bb542b8545 | ||
|
|
a0f8566104 | ||
|
|
696717aa1c | ||
|
|
8971f25b9d | ||
|
|
411ddca927 | ||
|
|
1a102074d5 | ||
|
|
29a1e0eacf | ||
|
|
2a7d485ab4 | ||
|
|
a9e926c6b4 | ||
|
|
1177ed36aa | ||
|
|
931b6a96d0 | ||
|
|
0770f32ef5 | ||
|
|
30fee77c8e | ||
|
|
cad3cdd5f1 | ||
|
|
914b6e5862 | ||
|
|
1002b1387c | ||
|
|
4544516c5c | ||
|
|
1c737b3dc4 | ||
|
|
990a7c1bed | ||
|
|
10c118d846 | ||
|
|
8786e4781d | ||
|
|
bfc8a343b5 | ||
|
|
11f01aed8d | ||
|
|
8ea1c82de8 | ||
|
|
7067615da7 | ||
|
|
2f8ec1b79c | ||
|
|
83039c6144 | ||
|
|
23dd021df6 | ||
|
|
acd4d35da0 | ||
|
|
e284529a45 | ||
|
|
6fbb480f83 | ||
|
|
68362def85 | ||
|
|
60cfd0f1bb | ||
|
|
f5a6c30248 |
1
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
packs/** binary
|
||||||
1
.github/workflows/draft-release.yml
vendored
|
|
@ -35,6 +35,7 @@ jobs:
|
||||||
|
|
||||||
# Compile the stuff that needs to be compiled
|
# Compile the stuff that needs to be compiled
|
||||||
- run: npm run build
|
- run: npm run build
|
||||||
|
- run: node scripts/buildCompendia.mjs
|
||||||
|
|
||||||
- name: Move system.json to a temp file
|
- name: Move system.json to a temp file
|
||||||
id: manifest-move
|
id: manifest-move
|
||||||
|
|
|
||||||
15
.gitignore
vendored
|
|
@ -2,4 +2,17 @@ node_modules/
|
||||||
*.tmp
|
*.tmp
|
||||||
*.bak.*
|
*.bak.*
|
||||||
references.txt
|
references.txt
|
||||||
.styles/
|
references/
|
||||||
|
/.*/
|
||||||
|
!/.vscode/
|
||||||
|
!/.github/
|
||||||
|
/*.ref.*
|
||||||
|
*.lock
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
# Ignore all of the binaries and stuff that gets built for Foundry from the raw
|
||||||
|
# JSON data because it's annoying seeing it in my git changes when it isn't actually
|
||||||
|
# needed.
|
||||||
|
/packs/**/*
|
||||||
|
!/packs/**/*/
|
||||||
|
!/packs/**/*.json
|
||||||
27
.vscode/components.html-data.json
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"version": 1.1,
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"name": "dd-incrementer",
|
||||||
|
"description": "A number input that allows more flexible increase/decrease buttons",
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "value", "description": "The initial value to put in the input" },
|
||||||
|
{ "name": "name", "description": "The form name to use when this input is used to submit data" },
|
||||||
|
{ "name": "min", "description": "The minimum value that this input can contain" },
|
||||||
|
{ "name": "max", "description": "The maximum value that this input can contain" },
|
||||||
|
{ "name": "smallStep", "description": "The value that the input is changed by when clicking a delta button or using the up/down arrow key" },
|
||||||
|
{ "name": "largeStep", "description": "The value that the input is changed by when clicking a delta button with control held or using the page up/ page down arrow key" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dd-icon",
|
||||||
|
"description": "Loads an icon asynchronously, caching the result for future uses",
|
||||||
|
"attributes": [
|
||||||
|
{ "name": "name", "description": "The name of the icon, this is relative to the assets folder of the dotdungeon system" },
|
||||||
|
{ "name": "path", "description": "The full path of the icon, this will only be used if `name` isn't provided or fails to fetch." }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalAttributes": [],
|
||||||
|
"valueSets": []
|
||||||
|
}
|
||||||
16
.vscode/settings.json
vendored
|
|
@ -1,11 +1,19 @@
|
||||||
{
|
{
|
||||||
"files.autoSave": "onWindowChange",
|
"files.autoSave": "onWindowChange",
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"[javascript]": {
|
|
||||||
"editor.tabSize": 4
|
|
||||||
},
|
|
||||||
"[yaml,yml]": {
|
"[yaml,yml]": {
|
||||||
"editor.insertSpaces": true,
|
"editor.insertSpaces": true,
|
||||||
"editor.tabSize": 2
|
"editor.tabSize": 2
|
||||||
}
|
},
|
||||||
|
"git.branchProtection": [],
|
||||||
|
"files.exclude": {
|
||||||
|
"dotdungeon.lock": true,
|
||||||
|
".styles": true,
|
||||||
|
"node_modules": true,
|
||||||
|
"packs": true,
|
||||||
|
".gitattributes": true,
|
||||||
|
},
|
||||||
|
"html.customData": [
|
||||||
|
"./.vscode/components.html-data.json"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<svg width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
|
||||||
<path d="m82.137 50.016c-0.003907 2.6133-1.1172 5.1055-3.0664 6.8477l-44.16 40.445c-1.8984 1.75-4.3867 2.7227-6.9688 2.7266-1.4727 0-2.9297-0.30859-4.2773-0.90234-3.5078-1.4531-5.7969-4.875-5.8008-8.668v-80.93c0.019531-3.7812 2.3047-7.1875 5.8008-8.6367 3.7734-1.6836 8.1836-0.98047 11.246 1.793l44.172 40.457c1.9492 1.75 3.0625 4.25 3.0547 6.8672z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 484 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
|
||||||
<path d="M 61.24 9 L 42.776 9 C 21.393 9 4.095 26.336 4.095 47.679 C 2.013 74.103 34.856 91.236 48.486 97.153 C 51.236 98.362 54.278 96.319 54.278 93.319 L 54.278 84.775 C 54.278 82.482 56.154 80.606 58.447 80.606 L 61.197 80.606 C 80.995 80.606 97 64.561 97 44.804 C 97 25.046 80.954 9 61.197 9 L 61.24 9 Z M 32.854 54.389 C 29.813 54.389 27.354 51.93 27.354 48.888 C 27.354 45.844 29.813 43.388 32.854 43.388 C 35.899 43.388 38.358 45.844 38.358 48.888 C 38.358 51.93 35.899 54.389 32.854 54.389 Z M 50.527 54.389 C 47.486 54.389 45.025 51.93 45.025 48.888 C 45.025 45.844 47.486 43.388 50.527 43.388 C 53.571 43.388 56.03 45.844 56.03 48.888 C 56.03 51.93 53.571 54.389 50.527 54.389 Z M 68.202 54.389 C 65.158 54.389 62.697 51.93 62.697 48.888 C 62.697 45.844 65.158 43.388 68.202 43.388 C 71.242 43.388 73.703 45.844 73.703 48.888 C 73.703 51.93 71.242 54.389 68.202 54.389 Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 975 B |
|
|
@ -1,3 +0,0 @@
|
||||||
<svg width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="m96.293 83.457c3.543 3.5469 3.543 9.2891 0 12.836-3.5469 3.543-9.2891 3.543-12.836 0l-31.992-31.992c-0.80859-0.8125-2.1211-0.8125-2.9297 0l-31.992 31.992c-3.5469 3.543-9.2891 3.543-12.836 0-3.543-3.5469-3.543-9.2891 0-12.836l31.992-31.988c0.8125-0.8125 0.8125-2.125 0-2.9336l-31.992-31.992c-3.543-3.5469-3.543-9.2891 0-12.836 3.5469-3.543 9.2891-3.543 12.836 0l31.992 31.996c0.80859 0.80859 2.1211 0.80859 2.9297 0l31.992-31.996c3.5469-3.543 9.2891-3.543 12.836 0 3.543 3.5469 3.543 9.2891 0 12.836l-31.992 31.992c-0.8125 0.80859-0.8125 2.1211 0 2.9336z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 678 B |
|
|
@ -1,3 +1 @@
|
||||||
<svg width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M52.348 11.457a3.021 3.021 0 0 0-3.84 0l-36.53 30.484a3.005 3.005 0 0 0-1.079 2.3v10.95c0 .879.39 1.719 1.059 2.289l36.535 31.043a3.01 3.01 0 0 0 3.883 0L89.118 57.48a3.02 3.02 0 0 0 1.058-2.29l-.004-10.94c0-.89-.398-1.739-1.078-2.309zm31.824 39.934-15.445-3.93-10.316-23.188L84.184 45.66zm-33.73 3.52-12.258-6.29 12.258-27.496L62.7 48.621zm-16.508-1.723 13.508 6.93v19.636L20.266 56.668zm19.504 6.93 13.508-6.93 13.797 3.52-27.305 23.065zM42.442 24.343 32.145 47.45 16.899 51.34v-5.68z"/></svg>
|
||||||
<path d="m52.348 11.457c-1.1094-0.91797-2.7305-0.91797-3.8398 0l-36.531 30.484c-0.67969 0.57031-1.0781 1.4102-1.0781 2.3008v10.949c0 0.87891 0.39062 1.7188 1.0586 2.2891l36.535 31.043c0.55859 0.48047 1.25 0.71094 1.9414 0.71094s1.3789-0.23828 1.9414-0.71094l36.742-31.043c0.66797-0.57031 1.0586-1.4102 1.0586-2.2891l-0.003906-10.941c0-0.89062-0.39844-1.7383-1.0781-2.3086zm31.824 39.934-15.445-3.9297-10.316-23.188 25.773 21.387zm-33.73 3.5195-12.258-6.2891 12.258-27.496 12.258 27.496zm-16.508-1.7227 13.508 6.9297v19.637l-27.176-23.086zm19.504 6.9297 13.508-6.9297 13.797 3.5195-27.305 23.066zm-10.996-35.773-10.297 23.105-15.246 3.8906v-5.6797z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 763 B After Width: | Height: | Size: 566 B |
|
|
@ -1,3 +1 @@
|
||||||
<svg width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M85.484 37.672 73.066 20.574a3.024 3.024 0 0 0-1.5-1.09l-20.098-6.527c-.602-.2-1.25-.2-1.852 0l-20.098 6.527c-.601.2-1.128.578-1.5 1.09L15.596 37.672a2.998 2.998 0 0 0-.57 1.758v21.125c0 .629.2 1.25.57 1.758L28.014 79.41c.371.511.899.89 1.5 1.09l20.098 6.527a2.988 2.988 0 0 0 1.86 0L71.57 80.5a3.024 3.024 0 0 0 1.5-1.09l12.414-17.093c.37-.512.57-1.13.57-1.758V39.434c0-.633-.203-1.25-.57-1.762zm-7.059.492-9.34 4.008L53.54 30.875v-10.93l15.238 4.95zM59.59 63.957H41.491l-5.59-17.207L50.54 36.113 65.176 46.75zM32.292 24.895l15.238-4.949v10.938L31.991 42.173l-9.34-4.008zM21.026 59.59V43.992l8.918 3.828 6.008 18.484-5.347 6.457zm29.512 21.445-14.969-4.86 5.149-6.218h19.625l5.148 6.219zm19.938-8.27L65.13 66.31l6.007-18.484 8.919-3.828v15.598z"/></svg>
|
||||||
<path d="m85.484 37.672-12.418-17.098c-0.37109-0.51172-0.89844-0.89062-1.5-1.0898l-20.098-6.5273c-0.60156-0.19922-1.25-0.19922-1.8516 0l-20.098 6.5273c-0.60156 0.19922-1.1289 0.57812-1.5 1.0898l-12.422 17.098c-0.37109 0.51172-0.57031 1.1289-0.57031 1.7578v21.125c0 0.62891 0.19922 1.25 0.57031 1.7578l12.418 17.098c0.37109 0.51172 0.89844 0.89062 1.5 1.0898l20.098 6.5273c0.30078 0.10156 0.60938 0.14844 0.92969 0.14844 0.32031 0 0.62891-0.050781 0.92969-0.14844l20.098-6.5273c0.60156-0.19922 1.1289-0.57812 1.5-1.0898l12.414-17.094c0.37109-0.51172 0.57031-1.1289 0.57031-1.7578v-21.125c0-0.63281-0.20313-1.25-0.57031-1.7617zm-7.0586 0.49219-9.3398 4.0078-15.547-11.297v-10.93l15.238 4.9492zm-18.836 25.793h-18.098l-5.5898-17.207 14.637-10.637 14.637 10.637zm-27.297-39.062 15.238-4.9492v10.938l-15.539 11.289-9.3398-4.0078zm-11.266 34.695v-15.598l8.918 3.8281 6.0078 18.484-5.3477 6.457zm29.512 21.445-14.969-4.8594 5.1484-6.2188h19.625l5.1484 6.2188zm19.938-8.2695-5.3477-6.457 6.0078-18.484 8.918-3.8281v15.598z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 825 B |
|
|
@ -1,3 +1 @@
|
||||||
<svg width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M82.172 32.355c-.02-.148-.031-.3-.07-.441-.04-.13-.102-.239-.149-.372-.039-.109-.07-.218-.129-.32-.011-.012-.02-.02-.02-.031-.07-.11-.16-.211-.237-.32-.079-.102-.149-.211-.239-.301-.078-.078-.18-.14-.27-.211-.109-.09-.218-.192-.35-.262a.113.113 0 0 1-.04-.031L51.356 13.87a2.985 2.985 0 0 0-3 .059L19.68 31.227c-.02.011-.031.03-.05.039-.122.07-.22.171-.329.261-.09.078-.191.149-.281.239-.078.09-.148.199-.219.289-.078.109-.172.218-.23.34a.113.113 0 0 1-.032.039c-.05.101-.07.199-.101.3-.05.13-.11.25-.14.391s-.04.281-.051.418c-.012.101-.04.2-.04.309l.63 33.484c.019 1.07.609 2.05 1.55 2.57L49.72 86.113c.45.25.95.37 1.45.37.538 0 1.07-.14 1.55-.429L81.403 68.77a2.994 2.994 0 0 0 1.45-2.629l-.63-33.484c0-.101-.039-.203-.05-.3zM60.246 60.007l-8.879 15.816-9.469-15.477zm-18.926-6.2 8.879-15.815 9.469 15.477zm-5.36-2.706-9.437-14.605 18.258-1.11zm29.306.027-9.758-15.945 18.617.418zM53.05 29.124l-.09-7.488 14.129 7.808zm-6 .11-13.828.84 13.746-8.29zM32.08 56.148l-7.34 5.34-.327-17.196zm3.29 5.019 9.386 15.348-17.336-9.578zm31.105-.012 7.707 4.961-15.848 9.547zm2.96-5.238 6.989-12.258.32 16.965z"/></svg>
|
||||||
<path d="m82.172 32.355c-0.019531-0.14844-0.03125-0.30078-0.070313-0.44141-0.039062-0.12891-0.10156-0.23828-0.14844-0.37109-0.039063-0.10938-0.070313-0.21875-0.12891-0.32031-0.011719-0.011718-0.019531-0.019531-0.019531-0.03125-0.070313-0.10938-0.16016-0.21094-0.23828-0.32031-0.078125-0.10156-0.14844-0.21094-0.23828-0.30078-0.078125-0.078124-0.17969-0.14062-0.26953-0.21094-0.10938-0.089844-0.21875-0.19141-0.35156-0.26172-0.019531-0.011718-0.03125-0.019531-0.039062-0.03125l-29.312-16.195c-0.94141-0.51953-2.0781-0.5-3 0.058594l-28.676 17.297c-0.019532 0.011719-0.03125 0.03125-0.050782 0.039063-0.12109 0.070313-0.21875 0.17188-0.32812 0.26172-0.089843 0.078125-0.19141 0.14844-0.28125 0.23828-0.078125 0.089844-0.14844 0.19922-0.21875 0.28906-0.078125 0.10937-0.17188 0.21875-0.23047 0.33984-0.011718 0.019531-0.019531 0.03125-0.03125 0.039063-0.050781 0.10156-0.070312 0.19922-0.10156 0.30078-0.050781 0.12891-0.10938 0.25-0.14062 0.39062s-0.039063 0.28125-0.050781 0.41797c-0.011719 0.10156-0.039063 0.19922-0.039063 0.30859l0.62891 33.484c0.019531 1.0703 0.60937 2.0508 1.5508 2.5703l29.332 16.207c0.44922 0.25 0.94922 0.37109 1.4492 0.37109 0.53906 0 1.0703-0.14062 1.5508-0.42969l28.684-17.285c0.91797-0.55078 1.4688-1.5508 1.4492-2.6289l-0.62891-33.484c0-0.10156-0.039062-0.20312-0.050781-0.30078zm-21.926 27.652-8.8789 15.816-9.4688-15.477zm-18.926-6.1992 8.8789-15.816 9.4688 15.477zm-5.3594-2.707-9.4375-14.605 18.258-1.1094zm29.305 0.027344-9.7578-15.945 18.617 0.41797zm-12.215-22.004-0.089843-7.4883 14.129 7.8086zm-6 0.10938-13.828 0.83984 13.746-8.2891zm-14.969 26.914-7.3398 5.3398-0.32813-17.195zm3.2891 5.0195 9.3867 15.348-17.336-9.5781zm31.105-0.011719 7.707 4.9609-15.848 9.5469zm2.9609-5.2383 6.9883-12.258 0.32031 16.965z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.2 KiB |
|
|
@ -1,3 +1 @@
|
||||||
<svg width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M52.91 11.938a3.005 3.005 0 0 0-4.758 0L10.38 60.887a2.993 2.993 0 0 0-.578 2.371c.149.828.649 1.57 1.371 2.008l37.781 23.516a3.028 3.028 0 0 0 3.18 0l37.78-23.516a3.02 3.02 0 0 0 1.372-2.008 3.03 3.03 0 0 0-.578-2.371zm-5.371 10.629v58.277L17.156 61.926zm6 58.266V22.567L83.922 61.93z"/></svg>
|
||||||
<path d="m52.91 11.938c-0.57031-0.73828-1.4492-1.168-2.3789-1.168s-1.8086 0.42969-2.3789 1.168l-37.773 48.949c-0.51953 0.66797-0.73047 1.5312-0.57812 2.3711 0.14844 0.82813 0.64844 1.5703 1.3711 2.0078l37.781 23.516c0.48828 0.30078 1.0391 0.44922 1.5898 0.44922s1.1016-0.14844 1.5898-0.44922l37.781-23.516c0.71875-0.44922 1.2188-1.1797 1.3711-2.0078 0.14844-0.82812-0.058594-1.6914-0.57812-2.3711zm-5.3711 10.629v58.277l-30.383-18.918zm6 58.266v-58.266l30.383 39.363z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 583 B After Width: | Height: | Size: 365 B |
|
|
@ -1,3 +1 @@
|
||||||
<svg width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M83.664 28.203 51.711 14.676c-.75-.32-1.59-.32-2.34 0L17.418 28.203a3.006 3.006 0 0 0-1.828 2.738v37.622c0 1.191.711 2.27 1.8 2.75l31.954 13.996c.379.172.789.25 1.2.25.41 0 .82-.078 1.198-.25l31.953-13.996a3.012 3.012 0 0 0 1.801-2.75l-.004-37.598v-.02a3 3 0 0 0-1.828-2.742zm-33.125-7.508 24.375 10.316-24.375 10.68-24.375-10.676zm-28.965 14.86L47.539 46.92v31.055l-25.965-11.37zm31.965 42.417v-31.05l25.953-11.368V66.61z"/></svg>
|
||||||
<path d="m83.664 28.203-31.953-13.527c-0.75-0.32031-1.5898-0.32031-2.3398 0l-31.953 13.527c-1.1016 0.46875-1.8203 1.5508-1.8281 2.7383v0.019532 37.602c0 1.1914 0.71094 2.2695 1.8008 2.75l31.953 13.996c0.37891 0.17188 0.78906 0.25 1.1992 0.25 0.41016 0 0.82031-0.078125 1.1992-0.25l31.953-13.996c1.0898-0.48047 1.8008-1.5586 1.8008-2.75l-0.003906-37.598v-0.019532c-0.007813-1.1914-0.71875-2.2695-1.8281-2.7422zm-33.125-7.5078 24.375 10.316-24.375 10.68-24.375-10.676zm-28.965 14.859 25.965 11.367v31.055l-25.965-11.371zm31.965 42.418v-31.051l25.953-11.367v31.055z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 678 B After Width: | Height: | Size: 502 B |
|
|
@ -1,3 +1 @@
|
||||||
<svg width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M80.785 31.625 52.738 14.676a3.004 3.004 0 0 0-3-.059l-28.691 15.81a2.999 2.999 0 0 0-1.55 2.57l-.65 32.762a3.013 3.013 0 0 0 1.45 2.629L48.34 85.333c.48.289 1.012.43 1.55.43.5 0 1-.122 1.45-.372l28.695-15.816a2.999 2.999 0 0 0 1.55-2.57l.65-32.762a2.98 2.98 0 0 0-1.45-2.617zm-4.969 23.793L58.66 25.254l17.535 10.598zm-2.41 7.91-45.199-.449 22.566-39.363zM42.863 25.254 25.035 56.348l.43-21.504zm7.086 54.04L32.785 68.925l35.352.352z"/></svg>
|
||||||
<path d="m80.785 31.625-28.047-16.949c-0.91797-0.55078-2.0586-0.57812-3-0.058593l-28.691 15.809c-0.94141 0.51953-1.5312 1.5-1.5508 2.5703l-0.64844 32.762c-0.019531 1.0703 0.53125 2.0703 1.4492 2.6289l28.043 16.945c0.48047 0.28906 1.0117 0.42969 1.5508 0.42969 0.5 0 1-0.12109 1.4492-0.37109l28.695-15.816c0.94141-0.51953 1.5312-1.5 1.5508-2.5703l0.64844-32.762c0.019531-1.0703-0.53125-2.0703-1.4492-2.6172zm-4.9688 23.793-17.156-30.164 17.535 10.598zm-2.4102 7.9102-45.199-0.44922 22.566-39.363zm-30.543-38.074-17.828 31.094 0.42969-21.504zm7.0859 54.039-17.164-10.367 35.352 0.35156z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 700 B After Width: | Height: | Size: 514 B |
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg fill="currentColor" width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g>
|
|
||||||
<path d="m67.5 12.801c-3.1992-3.1992-8.3984-3.1992-11.602 0l-38.797 38.801c-2.3008 2.3008-2.3008 6.1016 0 8.3984l21.5 21.5c2.3008 2.3008 6.1016 2.3008 8.3984 0l38.801-38.801c3.1992-3.1992 3.1992-8.3984 0-11.602z"/>
|
|
||||||
<path d="m18.602 88.102h0.19922l10.301-0.30078c3.1016-0.10156 4.6016-3.8984 2.3984-6.1016l-14.699-14.699c-2.1992-2.1992-6-0.69922-6.1016 2.3984l-0.30078 10.301c-0.10156 2.3008 0.80078 4.5 2.3984 6.1016 1.5039 1.5 3.6016 2.3008 5.8047 2.3008z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 645 B |
|
|
@ -1,6 +0,0 @@
|
||||||
<svg width="100%" height="100%" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
|
||||||
<g>
|
|
||||||
<path d="m82.199 25.301h-64.398c-1.3008 0-2.3008 1.1016-2.1992 2.3984l7.5 62.398c0.5 4.1992 4.1016 7.3984 8.3984 7.3984h37c4.3008 0 7.8984-3.1992 8.3984-7.3984l7.5-62.398c0.10156-1.3008-0.89844-2.3984-2.1992-2.3984zm-45.301 57.699h-0.19922c-1.1992 0-2.1992-0.89844-2.3008-2.1016l-4.1016-38.699c-0.10156-1.3008 0.80078-2.3984 2.1016-2.5 1.3008-0.10156 2.3984 0.80078 2.5 2.1016l4.1016 38.699c0.10156 1.3008-0.80078 2.3984-2.1016 2.5zm15.402-2.3008c0 1.3008-1 2.3008-2.3008 2.3008s-2.3008-1-2.3008-2.3008v-38.699c0-1.3008 1-2.3008 2.3008-2.3008s2.3008 1 2.3008 2.3008zm13.301 0.30078c-0.10156 1.1992-1.1016 2.1016-2.3008 2.1016h-0.19922c-1.3008-0.10156-2.1992-1.3008-2.1016-2.5l4.1016-38.699c0.10156-1.3008 1.3008-2.1992 2.5-2.1016 1.3008 0.10156 2.1992 1.3008 2.1016 2.5z"/>
|
|
||||||
<path d="m86.602 10.801h-19.301l-4.6016-6.3984c-0.80078-1.1992-2.1992-1.8984-3.6992-1.8984l-18-0.003906c-1.5 0-2.8008 0.69922-3.6992 1.8984l-4.6016 6.3984-19.301 0.003906c-2.3984 0-4.3008 1.8984-4.3008 4.3008 0 2.3984 1.8984 4.3008 4.3008 4.3008h73.199c2.3984 0 4.3008-1.8984 4.3008-4.3008 0-2.4023-1.8984-4.3008-4.2969-4.3008z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
|
@ -1,8 +0,0 @@
|
||||||
<svg height="100%" width="100%" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g transform="matrix(1.0666639804840088, 0, 0, 1.0666639804840088, -4.5322370529174805, -4.2468461990356445)">
|
|
||||||
<path d="m16.086 76.617c0 1.3672 1.1133 2.4805 2.4805 2.4805h49.793c1.3672 0 2.4805-1.1133 2.4805-2.4805v-66.324c0-1.3672-1.1133-2.4805-2.4805-2.4805h-35.352v12.695c0 2.2812-1.8555 4.1328-4.1367 4.1328l-12.785 0.003906zm7.6328-48.016h39.492c0.45703 0 0.82812 0.36719 0.82812 0.82813 0 0.46094-0.36719 0.82812-0.82812 0.82812h-39.492c-0.45703 0-0.82812-0.36719-0.82812-0.82812 0-0.46094 0.37109-0.82813 0.82812-0.82813zm0 10.609h39.492c0.45703 0 0.82812 0.36719 0.82812 0.82812 0 0.46094-0.36719 0.82813-0.82812 0.82813h-39.492c-0.45703 0-0.82812-0.36719-0.82812-0.82813 0-0.45703 0.37109-0.82812 0.82812-0.82812zm0 10.617h39.492c0.45703 0 0.82812 0.36719 0.82812 0.82812s-0.36719 0.82812-0.82812 0.82812h-39.492c-0.45703 0-0.82812-0.36719-0.82812-0.82812s0.37109-0.82812 0.82812-0.82812zm0 10.613h39.492c0.45703 0 0.82812 0.36719 0.82812 0.82812 0 0.46094-0.36719 0.82812-0.82812 0.82812h-39.492c-0.45703 0-0.82812-0.36719-0.82812-0.82812 0-0.46094 0.37109-0.82812 0.82812-0.82812z"/>
|
|
||||||
<path d="m74.898 14.355h-2.3984v62.258c0 2.2812-1.8555 4.1328-4.1328 4.1328h-45.746v2.4102c0 1.3672 1.1133 2.4805 2.4805 2.4805h49.793c1.3672 0 2.4805-1.1133 2.4805-2.4805l0.003906-66.32c0-1.3633-1.1133-2.4805-2.4805-2.4805z"/>
|
|
||||||
<path d="m31.352 20.508v-11.531l-14.09 14.016h11.609c1.3711 0 2.4805-1.1172 2.4805-2.4844z"/>
|
|
||||||
<path d="m29.16 87.297v2.4102c0 1.3672 1.1133 2.4805 2.4805 2.4805h49.793c1.3672 0 2.4805-1.1133 2.4805-2.4805v-66.324c0-1.3672-1.1133-2.4805-2.4805-2.4805h-2.3984v62.258c0 2.2812-1.8555 4.1328-4.1328 4.1328h-45.742z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB |
|
|
@ -1,11 +1,15 @@
|
||||||
|
Disclaimer:
|
||||||
|
All icons included in this repo have been scaled and optimized as needed.
|
||||||
|
|
||||||
Amer Alamer
|
Amer Alamer
|
||||||
caret-right.svg (https://thenounproject.com/icon/arrow-caret-right-1143917/)
|
ui/caret/right.svg (https://thenounproject.com/icon/arrow-caret-right-1143917/)
|
||||||
|
ui/caret/down.svg (https://thenounproject.com/icon/arrow-caret-down-1143911/)
|
||||||
|
|
||||||
Alice Design:
|
Alice Design:
|
||||||
garbage-bin.svg (https://thenounproject.com/icon/garbage-2025492/)
|
ui/garbage-bin.svg (https://thenounproject.com/icon/garbage-2025492/)
|
||||||
|
|
||||||
zapesicon:
|
zapesicon:
|
||||||
chat-bubble.svg (https://thenounproject.com/icon/chat-6423186/)
|
ui/chat-bubble.svg (https://thenounproject.com/icon/chat-6423186/)
|
||||||
|
|
||||||
Fritz Duggan:
|
Fritz Duggan:
|
||||||
dice/d4.svg (https://thenounproject.com/icon/d4-4570604/)
|
dice/d4.svg (https://thenounproject.com/icon/d4-4570604/)
|
||||||
|
|
@ -16,18 +20,19 @@ Fritz Duggan:
|
||||||
dice/d20.svg (https://thenounproject.com/icon/d20-4570607/)
|
dice/d20.svg (https://thenounproject.com/icon/d20-4570607/)
|
||||||
|
|
||||||
Landan Lloyd:
|
Landan Lloyd:
|
||||||
create.svg (https://thenounproject.com/icon/create-1447560/)
|
ui/plus.svg (https://thenounproject.com/icon/create-1447560/)
|
||||||
|
|
||||||
|
Bismillah
|
||||||
|
ui/minus.svg (https://thenounproject.com/icon/minus-1727966/)
|
||||||
|
|
||||||
Rokhman Kharis:
|
Rokhman Kharis:
|
||||||
close.svg (https://thenounproject.com/icon/close-4996834/)
|
ui/close.svg (https://thenounproject.com/icon/close-4996834/)
|
||||||
|
|
||||||
Athok:
|
Athok:
|
||||||
sheet.svg (https://thenounproject.com/icon/sheet-5939348/)
|
ui/sheet.svg (https://thenounproject.com/icon/sheet-5939348/)
|
||||||
|
|
||||||
Icon Depot:
|
Icon Depot:
|
||||||
edit.svg (https://thenounproject.com/icon/edit-1489252/)
|
ui/pencil.svg (https://thenounproject.com/icon/edit-1489252/)
|
||||||
|
|
||||||
Oliver Akins:
|
Muhammad Ahsanu Nadia:
|
||||||
chat-bubble.svg : Scaling
|
ui/help.svg (https://thenounproject.com/icon/help-6778522/)
|
||||||
create.svg : Scaling, Optimization
|
|
||||||
sheet.svg : Scaling
|
|
||||||
|
|
|
||||||
1
assets/ui/caret/down.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 100 100"><path d="M50.016 82.137a9.195 9.195 0 0 1-6.844-3.066L2.692 34.91a10.286 10.286 0 0 1-2.691-6.97c0-1.472.304-2.929.898-4.276a9.404 9.404 0 0 1 8.637-5.801h80.93a9.404 9.404 0 0 1 8.637 5.8A10.424 10.424 0 0 1 97.31 34.91L56.853 79.082a9.201 9.201 0 0 1-6.836 3.055z"/></svg>
|
||||||
|
After Width: | Height: | Size: 356 B |
1
assets/ui/caret/right.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 100 100"><path d="M82.137 50.016a9.203 9.203 0 0 1-3.066 6.848L34.91 97.309a10.306 10.306 0 0 1-6.97 2.726c-1.472 0-2.929-.308-4.276-.902a9.396 9.396 0 0 1-5.801-8.668V9.535a9.404 9.404 0 0 1 5.8-8.637A10.424 10.424 0 0 1 34.91 2.691l44.172 40.457a9.198 9.198 0 0 1 3.055 6.867z"/></svg>
|
||||||
|
After Width: | Height: | Size: 360 B |
1
assets/ui/chat-bubble.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 100 100"><path d="M61.24 9H42.776C21.393 9 4.095 26.336 4.095 47.679 2.013 74.103 34.856 91.236 48.486 97.153c2.75 1.209 5.792-.834 5.792-3.834v-8.544a4.181 4.181 0 0 1 4.169-4.169h2.75C80.995 80.606 97 64.561 97 44.804 97 25.046 80.954 9 61.197 9h.043ZM32.854 54.389a5.496 5.496 0 0 1-5.5-5.501c0-3.044 2.459-5.5 5.5-5.5a5.495 5.495 0 0 1 5.504 5.5 5.497 5.497 0 0 1-5.504 5.501Zm17.673 0a5.498 5.498 0 0 1-5.502-5.501c0-3.044 2.461-5.5 5.502-5.5a5.494 5.494 0 0 1 5.503 5.5 5.496 5.496 0 0 1-5.503 5.501Zm17.675 0a5.498 5.498 0 0 1-5.505-5.501c0-3.044 2.461-5.5 5.505-5.5a5.495 5.495 0 0 1 5.501 5.5 5.497 5.497 0 0 1-5.501 5.501Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 714 B |
1
assets/ui/close.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M96.293 83.457a9.08 9.08 0 0 1 0 12.836 9.08 9.08 0 0 1-12.836 0L51.465 64.301a2.065 2.065 0 0 0-2.93 0L16.543 96.293a9.08 9.08 0 0 1-12.836 0 9.08 9.08 0 0 1 0-12.836L35.7 51.469a2.07 2.07 0 0 0 0-2.934L3.707 16.543a9.08 9.08 0 0 1 0-12.836 9.08 9.08 0 0 1 12.836 0l31.992 31.996a2.072 2.072 0 0 0 2.93 0L83.457 3.707a9.08 9.08 0 0 1 12.836 0 9.08 9.08 0 0 1 0 12.836L64.301 48.535a2.07 2.07 0 0 0 0 2.934z"/></svg>
|
||||||
|
After Width: | Height: | Size: 487 B |
1
assets/ui/garbage-bin.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 100 100"><path d="M82.199 25.301H17.801c-1.3 0-2.3 1.102-2.2 2.398l7.5 62.398c.5 4.2 4.102 7.399 8.4 7.399h37c4.3 0 7.898-3.2 8.398-7.399l7.5-62.398a2.204 2.204 0 0 0-2.2-2.398zM36.898 83h-.2c-1.198 0-2.198-.898-2.3-2.102L30.296 42.2c-.101-1.3.801-2.398 2.102-2.5 1.3-.101 2.398.801 2.5 2.102L39 80.5c.101 1.3-.801 2.398-2.102 2.5zM52.3 80.7c0 1.3-1 2.3-2.3 2.3s-2.302-1-2.302-2.3V42c0-1.3 1-2.3 2.301-2.3s2.301 1 2.301 2.3zm13.301.3a2.296 2.296 0 0 1-2.3 2.102h-.2c-1.3-.102-2.2-1.301-2.102-2.5l4.102-38.7c.102-1.3 1.3-2.199 2.5-2.101 1.3.102 2.2 1.3 2.102 2.5zM86.602 10.801H67.301l-4.602-6.398C61.9 3.203 60.5 2.504 59 2.504L41 2.5c-1.5 0-2.8.7-3.699 1.899l-4.602 6.398-19.3.004a4.269 4.269 0 0 0-4.301 4.3c0 2.4 1.898 4.302 4.3 4.302h73.2c2.398 0 4.3-1.899 4.3-4.301S89 10.8 86.601 10.8z"/></svg>
|
||||||
|
After Width: | Height: | Size: 873 B |
1
assets/ui/help.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M50 9.375a40.635 40.635 0 0 0-28.727 11.898 40.63 40.63 0 0 0 0 57.454 40.63 40.63 0 0 0 57.454 0A40.63 40.63 0 0 0 90.625 50a40.658 40.658 0 0 0-11.914-28.711A40.66 40.66 0 0 0 50 9.375zm0 75a34.39 34.39 0 0 1-24.309-10.066 34.386 34.386 0 0 1 0-48.618 34.386 34.386 0 0 1 48.618 0A34.386 34.386 0 0 1 84.375 50a34.407 34.407 0 0 1-10.082 24.293A34.41 34.41 0 0 1 50 84.375z"/><path d="M50 25a15.641 15.641 0 0 0-15.625 15.625v3.125a3.124 3.124 0 1 0 6.25 0v-3.125c0-5.176 4.2-9.375 9.375-9.375s9.375 4.2 9.375 9.375v.457a6.217 6.217 0 0 1-3.438 5.59l-2.136 1.066a12.432 12.432 0 0 0-6.926 11.18v6.707a3.124 3.124 0 1 0 6.25 0v-6.707a6.223 6.223 0 0 1 3.453-5.59l2.137-1.066a12.434 12.434 0 0 0 6.91-11.18v-.457A15.641 15.641 0 0 0 50 25zM53.125 75c0 4.168-6.25 4.168-6.25 0s6.25-4.168 6.25 0"/></svg>
|
||||||
|
After Width: | Height: | Size: 873 B |
1
assets/ui/minus.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 100 100"><path fill-rule="evenodd" d="M12.633 38.727h74.734c6.258 0 11.336 6.227 11.336 11.273 0 6.227-5.074 11.273-11.336 11.273H12.633C6.375 61.273 1.297 55.046 1.297 50c0-6.227 5.074-11.273 11.336-11.273z"/></svg>
|
||||||
|
After Width: | Height: | Size: 289 B |
1
assets/ui/pencil.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 100 100"><path d="M67.5 12.801c-3.2-3.2-8.398-3.2-11.602 0L17.101 51.602c-2.3 2.3-2.3 6.102 0 8.398l21.5 21.5c2.3 2.301 6.102 2.301 8.398 0L85.8 42.7c3.2-3.2 3.2-8.399 0-11.603zM18.602 88.102h.2l10.3-.3c3.102-.102 4.602-3.9 2.399-6.102L16.8 67c-2.199-2.199-6-.699-6.101 2.399L10.4 79.7c-.102 2.3.8 4.5 2.398 6.102 1.504 1.5 3.601 2.3 5.804 2.3z"/></svg>
|
||||||
|
After Width: | Height: | Size: 426 B |
|
Before Width: | Height: | Size: 536 B After Width: | Height: | Size: 536 B |
1
assets/ui/sheet.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M12.626 77.478a2.65 2.65 0 0 0 2.646 2.646h53.112a2.65 2.65 0 0 0 2.646-2.646V6.732a2.65 2.65 0 0 0-2.646-2.646H30.676v13.542a4.414 4.414 0 0 1-4.413 4.408l-13.637.004zm8.142-51.217h42.124c.488 0 .884.391.884.883a.878.878 0 0 1-.884.883H20.768a.881.881 0 0 1-.884-.883c0-.492.396-.883.884-.883zm0 11.316h42.124c.488 0 .884.392.884.883a.878.878 0 0 1-.884.884H20.768a.884.884 0 0 1 0-1.767zm0 11.325h42.124c.488 0 .884.391.884.883s-.392.883-.884.883H20.768c-.488 0-.884-.391-.884-.883s.396-.883.884-.883zm0 11.32h42.124c.488 0 .884.392.884.884a.878.878 0 0 1-.884.883H20.768a.881.881 0 0 1-.884-.883c0-.492.396-.884.884-.884z"/><path d="M75.359 11.065H72.8v66.408a4.413 4.413 0 0 1-4.408 4.409H19.597v2.57a2.65 2.65 0 0 0 2.645 2.647h53.113A2.65 2.65 0 0 0 78 84.453l.004-70.741a2.652 2.652 0 0 0-2.646-2.646zM28.91 17.628v-12.3L13.88 20.28h12.383a2.65 2.65 0 0 0 2.646-2.65z"/><path d="M26.572 88.87v2.57a2.65 2.65 0 0 0 2.646 2.646H82.33a2.65 2.65 0 0 0 2.646-2.645V20.695a2.65 2.65 0 0 0-2.646-2.646h-2.558v66.409a4.413 4.413 0 0 1-4.409 4.408H26.572z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
9
augments.d.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
interface Actor {
|
||||||
|
/** The system-specific data */
|
||||||
|
system: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
/** The system-specific data */
|
||||||
|
system: any;
|
||||||
|
};
|
||||||
7
jsconfig.json
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": [
|
||||||
|
"./augments.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
129
langs/en-ca.2.json
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
{
|
||||||
|
"dotdungeon": {
|
||||||
|
"stat": {
|
||||||
|
"build": "Build",
|
||||||
|
"meta": "Meta",
|
||||||
|
"presence": "Presence",
|
||||||
|
"hands": "Hands",
|
||||||
|
"tilt": "Tilt",
|
||||||
|
"rng": "RNG"
|
||||||
|
},
|
||||||
|
"skills": {
|
||||||
|
"defense": "Defense",
|
||||||
|
"magic": "Magic",
|
||||||
|
"melee": "Melee",
|
||||||
|
"platforming": "Platforming",
|
||||||
|
"strength": "Strength",
|
||||||
|
"alchemy": "Alchemy",
|
||||||
|
"arcanum": "Arcanum",
|
||||||
|
"dreams": "Dreams",
|
||||||
|
"lore": "Lore",
|
||||||
|
"navigation": "Navigation",
|
||||||
|
"animal_handling": "Animal Handling",
|
||||||
|
"perception": "Perception",
|
||||||
|
"sneak": "Sneak",
|
||||||
|
"speech": "Speech",
|
||||||
|
"vibes": "Vibes",
|
||||||
|
"accuracy": "Accuracy",
|
||||||
|
"crafting": "Crafting",
|
||||||
|
"engineering": "Engineering",
|
||||||
|
"explosives": "Explosives",
|
||||||
|
"piloting": "Piloting"
|
||||||
|
},
|
||||||
|
"trainingLevel": {
|
||||||
|
"untrained": "Untrained",
|
||||||
|
"trained": "Trained",
|
||||||
|
"expert": "Expert",
|
||||||
|
"locked": "Locked"
|
||||||
|
},
|
||||||
|
"die": {
|
||||||
|
"d4": "d4",
|
||||||
|
"d6": "d6",
|
||||||
|
"d8": "d8",
|
||||||
|
"d10": "d10",
|
||||||
|
"d12": "d12",
|
||||||
|
"d20": "d20"
|
||||||
|
},
|
||||||
|
"sheet": {
|
||||||
|
"actor": {
|
||||||
|
"v2": {
|
||||||
|
"stat-not-chosen": "Select a dice to see the {name} skills",
|
||||||
|
"skill-roll-locked": "@dotdungeon.trainingLevel.locked",
|
||||||
|
"toggle-item-information": "Toggle the item's extra information visibility",
|
||||||
|
"create-item": "Create @TYPES.Item.{type}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"item": {
|
||||||
|
"untyped": {
|
||||||
|
"quantity": "Quantity",
|
||||||
|
"usage": "Usage Cost",
|
||||||
|
"rarity": "Tier",
|
||||||
|
"no-description": "This item hasn't been described yet..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rarity": {
|
||||||
|
"simple": "Simple",
|
||||||
|
"greater": "Greater",
|
||||||
|
"rare": "Rare",
|
||||||
|
"legendary": "Legendary"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"unknown": "@dotdungeon.common.empty",
|
||||||
|
"inventory": "Inventory",
|
||||||
|
"equipped": "Equipped",
|
||||||
|
"storage": "Storage"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"name": "(Unnamed @TYPES.{document}.{type})"
|
||||||
|
},
|
||||||
|
"common": {
|
||||||
|
"send-to-chat": "Send to Chat",
|
||||||
|
"edit": "Edit",
|
||||||
|
"delete": "Delete",
|
||||||
|
"reset": "Reset",
|
||||||
|
"empty": "---",
|
||||||
|
"help": "Help",
|
||||||
|
"gm": "Server",
|
||||||
|
"view-larger": "View Larger"
|
||||||
|
},
|
||||||
|
"sheet-names": {
|
||||||
|
"*DataSheet": "Data Sheet"
|
||||||
|
},
|
||||||
|
"help-tooltips": {
|
||||||
|
"calculated-capacity": {
|
||||||
|
"title": "What is Calculated Capacity?",
|
||||||
|
"content": "<p>The calculated capacity is how much space in your inventory that the item will take up, the way it is calculated is determined by the item. Usually the main thing that affects the capacity is the item's quantity, but this can be turned off by the @dotdungeon.common.gm, which means that no matter the quantity it will only use up one capacity. The @dotdungeon.common.gm can also entirely disable capacity usage which will make the used capacity always be zero.</p>"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"ActiveEffect": {
|
||||||
|
"title": "Delete Effect",
|
||||||
|
"content": "<p>Are you sure you would like to delete the active effect: {name}</p>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TYPES": {
|
||||||
|
"Actor": {
|
||||||
|
"player": "Player",
|
||||||
|
"sync": "Sync"
|
||||||
|
},
|
||||||
|
"Item": {
|
||||||
|
"aspect": "Aspect",
|
||||||
|
"weapon": "Weapon",
|
||||||
|
"armour": "Armour",
|
||||||
|
"equipment": "Equipment",
|
||||||
|
"foil": "Foil",
|
||||||
|
"pet": "Pet",
|
||||||
|
"structure": "Structure",
|
||||||
|
"service": "Service",
|
||||||
|
"material": "Materials",
|
||||||
|
"legendaryItem": "Legendary Item",
|
||||||
|
"spell": "Spell",
|
||||||
|
"untyped": "Custom"
|
||||||
|
},
|
||||||
|
"ActiveEffect": {
|
||||||
|
"base": "Effect"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -78,13 +78,17 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sheet-names": {
|
"sheet-names": {
|
||||||
"PlayerSheet": "PC/PUG Sheet",
|
"PlayerSheet": {
|
||||||
|
"MVP": "MVP PC Sheet",
|
||||||
|
"v2": "PC Sheet"
|
||||||
|
},
|
||||||
"SyncSheet": {
|
"SyncSheet": {
|
||||||
"basic": "Theme: Basic"
|
"basic": "Theme: Basic"
|
||||||
},
|
},
|
||||||
"AspectSheet": "Aspect Sheet",
|
"AspectSheet": "Aspect Sheet",
|
||||||
"SpellSheet": "Spell Sheet",
|
"SpellSheet": "Spell Sheet",
|
||||||
"PetSheet": "Pet Sheet"
|
"PetSheet": "Pet Sheet",
|
||||||
|
"UntypedItemSheet": "Custom Item"
|
||||||
},
|
},
|
||||||
"actor": {
|
"actor": {
|
||||||
"pc": {
|
"pc": {
|
||||||
|
|
@ -253,6 +257,9 @@
|
||||||
},
|
},
|
||||||
"warn": {
|
"warn": {
|
||||||
"negative-aspect-limit": "The Aspect limit must be 0 or greater"
|
"negative-aspect-limit": "The Aspect limit must be 0 or greater"
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"increased-item-quantity": "Increased the item quantity for: {name}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dialogs": {
|
"dialogs": {
|
||||||
|
|
@ -273,6 +280,12 @@
|
||||||
"title": "You want to kill your pet?!",
|
"title": "You want to kill your pet?!",
|
||||||
"content": "Are you sure you would like to kill the pet: {name}<br /><br />This action cannot be undone."
|
"content": "Are you sure you would like to kill the pet: {name}<br /><br />This action cannot be undone."
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"untyped": {
|
||||||
|
"delete": {
|
||||||
|
"title": "Confirm Item Deletion",
|
||||||
|
"content": "Are you sure you would like to delete the item: {name}<br /><br />This action cannot be undone."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keyword": {
|
"keyword": {
|
||||||
|
|
@ -316,6 +329,9 @@
|
||||||
},
|
},
|
||||||
"pet": {
|
"pet": {
|
||||||
"name": "(Unnamed Pet)"
|
"name": "(Unnamed Pet)"
|
||||||
|
},
|
||||||
|
"untyped": {
|
||||||
|
"name": "Unknown Item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
125
module/components/icon.mjs
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
import { StyledShadowElement } from "./mixins/Styles.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attributes:
|
||||||
|
@property {string} name - The name of the icon, takes precedence over the path
|
||||||
|
@property {string} path - The path of the icon file
|
||||||
|
*/
|
||||||
|
export class DotDungeonIcon extends StyledShadowElement(HTMLElement) {
|
||||||
|
static elementName = `dd-icon`;
|
||||||
|
static formAssociated = false;
|
||||||
|
|
||||||
|
/* Stuff for the mixin to use */
|
||||||
|
static _stylePath = `v3/components/icon.css`;
|
||||||
|
|
||||||
|
|
||||||
|
static _cache = new Map();
|
||||||
|
#container;
|
||||||
|
/** @type {null | string} */
|
||||||
|
_name;
|
||||||
|
/** @type {null | string} */
|
||||||
|
_path;
|
||||||
|
|
||||||
|
/* Stored IDs for all of the hooks that are in this component */
|
||||||
|
#svgHmr;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
// this._shadow = this.attachShadow({ mode: `open`, delegatesFocus: true });
|
||||||
|
|
||||||
|
this.#container = document.createElement(`div`);
|
||||||
|
this._shadow.appendChild(this.#container);
|
||||||
|
};
|
||||||
|
|
||||||
|
_mounted = false;
|
||||||
|
async connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
if (this._mounted) return;
|
||||||
|
|
||||||
|
this._name = this.getAttribute(`name`);
|
||||||
|
this._path = this.getAttribute(`path`);
|
||||||
|
|
||||||
|
/*
|
||||||
|
This converts all of the double-dash prefixed properties on the element to
|
||||||
|
CSS variables so that they don't all need to be provided by doing style=""
|
||||||
|
*/
|
||||||
|
for (const attrVar of this.attributes) {
|
||||||
|
if (attrVar.name?.startsWith(`var:`)) {
|
||||||
|
const prop = attrVar.name.replace(`var:`, ``);
|
||||||
|
this.style.setProperty(`--` + prop, attrVar.value);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Try to retrieve the icon if it isn't present, try the path then default to
|
||||||
|
the slot content, as then we can have a default per-icon usage
|
||||||
|
*/
|
||||||
|
let content;
|
||||||
|
if (this._name) {
|
||||||
|
content = await this.#getIcon(`./systems/dotdungeon/assets/${this._name}.svg`);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this._path && !content) {
|
||||||
|
content = await this.#getIcon(this._path);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (content) {
|
||||||
|
this.#container.appendChild(content.cloneNode(true));
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is so that when we get an HMR event from Foundry we can appropriately
|
||||||
|
handle it using our logic to update the component and the icon cache.
|
||||||
|
*/
|
||||||
|
if (game.settings.get(`dotdungeon`, `devMode`)) {
|
||||||
|
this.#svgHmr = Hooks.on(`dd-hmr:svg`, (iconName, data) => {
|
||||||
|
if (this._name === iconName || this._path?.endsWith(data.path)) {
|
||||||
|
const svg = this.#parseSVG(data.content);
|
||||||
|
this.constructor._cache.set(iconName, svg);
|
||||||
|
this.#container.replaceChildren(svg.cloneNode(true));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this._mounted = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
if (!this._mounted) return;
|
||||||
|
|
||||||
|
Hooks.off(`dd-hmr:svg`, this.#svgHmr);
|
||||||
|
|
||||||
|
this._mounted = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
async #getIcon(path) {
|
||||||
|
// Cache hit!
|
||||||
|
if (this.constructor._cache.has(path)) {
|
||||||
|
console.debug(`.dungeon | Icon ${path} cache hit`);
|
||||||
|
return this.constructor._cache.get(path);
|
||||||
|
};
|
||||||
|
|
||||||
|
const r = await fetch(path);
|
||||||
|
switch (r.status) {
|
||||||
|
case 200:
|
||||||
|
case 201:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`.dungeon | Failed to fetch icon: ${path}`);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
console.debug(`.dungeon | Adding icon ${path} to the cache`);
|
||||||
|
const svg = this.#parseSVG(await r.text());
|
||||||
|
this.constructor._cache.set(path, svg);
|
||||||
|
return svg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Takes an SVG string and returns it as a DOM node */
|
||||||
|
#parseSVG(content) {
|
||||||
|
const temp = document.createElement(`div`);
|
||||||
|
temp.innerHTML = content;
|
||||||
|
return temp.querySelector(`svg`);
|
||||||
|
};
|
||||||
|
};
|
||||||
149
module/components/incrementer.mjs
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
import { DotDungeonIcon } from "./icon.mjs";
|
||||||
|
import { StyledShadowElement } from "./mixins/Styles.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
Attributes:
|
||||||
|
@property {string} name - The path to the value to update
|
||||||
|
@property {number} value - The actual value of the input
|
||||||
|
@property {number} min - The minimum value of the input
|
||||||
|
@property {number} max - The maximum value of the input
|
||||||
|
@property {number?} smallStep - The step size used for the buttons and arrow keys
|
||||||
|
@property {number?} largeStep - The step size used for the buttons + Ctrl and page up / down
|
||||||
|
|
||||||
|
Styling:
|
||||||
|
- `--height`: Controls the height of the element + the width of the buttons (default: 1.25rem)
|
||||||
|
- `--width`: Controls the width of the number input (default 50px)
|
||||||
|
*/
|
||||||
|
export class DotDungeonIncrementer extends StyledShadowElement(HTMLElement) {
|
||||||
|
static elementName = `dd-incrementer`;
|
||||||
|
static formAssociated = true;
|
||||||
|
|
||||||
|
static _stylePath = `v3/components/incrementer.css`;
|
||||||
|
|
||||||
|
_internals;
|
||||||
|
#input;
|
||||||
|
|
||||||
|
_min;
|
||||||
|
_max;
|
||||||
|
_smallStep;
|
||||||
|
_largeStep;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Form internals
|
||||||
|
this._internals = this.attachInternals();
|
||||||
|
this._internals.role = `spinbutton`;
|
||||||
|
};
|
||||||
|
|
||||||
|
get form() {
|
||||||
|
return this._internals.form;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this.getAttribute(`name`);
|
||||||
|
}
|
||||||
|
set name(value) {
|
||||||
|
this.setAttribute(`name`, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
get value() {
|
||||||
|
return this.getAttribute(`value`);
|
||||||
|
};
|
||||||
|
set value(value) {
|
||||||
|
this.setAttribute(`value`, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
get type() {
|
||||||
|
return `number`;
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this.replaceChildren();
|
||||||
|
|
||||||
|
// Attribute parsing / registration
|
||||||
|
const value = this.getAttribute(`value`);
|
||||||
|
this._min = parseInt(this.getAttribute(`min`) ?? 0);
|
||||||
|
this._max = parseInt(this.getAttribute(`max`) ?? 0);
|
||||||
|
this._smallStep = parseInt(this.getAttribute(`smallStep`) ?? 1);
|
||||||
|
this._largeStep = parseInt(this.getAttribute(`largeStep`) ?? 5);
|
||||||
|
|
||||||
|
this._internals.ariaValueMin = this._min;
|
||||||
|
this._internals.ariaValueMax = this._max;
|
||||||
|
|
||||||
|
const container = document.createElement(`div`);
|
||||||
|
|
||||||
|
// The input that the user can see / modify
|
||||||
|
const input = document.createElement(`input`);
|
||||||
|
this.#input = input;
|
||||||
|
input.type = `number`;
|
||||||
|
input.ariaHidden = true;
|
||||||
|
input.min = this.getAttribute(`min`);
|
||||||
|
input.max = this.getAttribute(`max`);
|
||||||
|
input.addEventListener(`change`, this.#updateValue.bind(this));
|
||||||
|
input.value = value;
|
||||||
|
|
||||||
|
// plus button
|
||||||
|
const increment = document.createElement(DotDungeonIcon.elementName);
|
||||||
|
increment.setAttribute(`name`, `ui/plus`);
|
||||||
|
increment.setAttribute(`var:size`, `0.75rem`);
|
||||||
|
increment.setAttribute(`var:fill`, `currentColor`);
|
||||||
|
increment.ariaHidden = true;
|
||||||
|
increment.classList.value = `increment`;
|
||||||
|
increment.addEventListener(`mousedown`, this.#increment.bind(this));
|
||||||
|
|
||||||
|
// minus button
|
||||||
|
const decrement = document.createElement(DotDungeonIcon.elementName);
|
||||||
|
decrement.setAttribute(`name`, `ui/minus`);
|
||||||
|
decrement.setAttribute(`var:size`, `0.75rem`);
|
||||||
|
decrement.setAttribute(`var:fill`, `currentColor`);
|
||||||
|
decrement.ariaHidden = true;
|
||||||
|
decrement.classList.value = `decrement`;
|
||||||
|
decrement.addEventListener(`mousedown`, this.#decrement.bind(this));
|
||||||
|
|
||||||
|
// Construct the DOM
|
||||||
|
container.appendChild(decrement);
|
||||||
|
container.appendChild(input);
|
||||||
|
container.appendChild(increment);
|
||||||
|
this._shadow.appendChild(container);
|
||||||
|
|
||||||
|
/*
|
||||||
|
This converts all of the namespace prefixed properties on the element to
|
||||||
|
CSS variables so that they don't all need to be provided by doing style=""
|
||||||
|
*/
|
||||||
|
for (const attrVar of this.attributes) {
|
||||||
|
if (attrVar.name?.startsWith(`var:`)) {
|
||||||
|
const prop = attrVar.name.replace(`var:`, ``);
|
||||||
|
this.style.setProperty(`--` + prop, attrVar.value);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#updateValue() {
|
||||||
|
let value = parseInt(this.#input.value);
|
||||||
|
if (this.getAttribute(`min`)) value = Math.max(this._min, value);
|
||||||
|
if (this.getAttribute(`max`)) value = Math.min(this._max, value);
|
||||||
|
this.#input.value = value;
|
||||||
|
this.value = value;
|
||||||
|
this.dispatchEvent(new Event(`change`, { bubbles: true }));
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @param {Event} $e */
|
||||||
|
#increment($e) {
|
||||||
|
$e.preventDefault();
|
||||||
|
let value = parseInt(this.#input.value);
|
||||||
|
value += $e.ctrlKey ? this._largeStep : this._smallStep;
|
||||||
|
this.#input.value = value;
|
||||||
|
this.#updateValue();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @param {Event} $e */
|
||||||
|
#decrement($e) {
|
||||||
|
$e.preventDefault();
|
||||||
|
let value = parseInt(this.#input.value);
|
||||||
|
value -= $e.ctrlKey ? this._largeStep : this._smallStep;
|
||||||
|
this.#input.value = value;
|
||||||
|
this.#updateValue();
|
||||||
|
};
|
||||||
|
};
|
||||||
23
module/components/index.mjs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { DotDungeonIncrementer } from "./incrementer.mjs";
|
||||||
|
import { DotDungeonIcon } from "./icon.mjs";
|
||||||
|
|
||||||
|
const components = [
|
||||||
|
DotDungeonIcon,
|
||||||
|
DotDungeonIncrementer,
|
||||||
|
];
|
||||||
|
|
||||||
|
export function registerCustomComponents() {
|
||||||
|
(CONFIG.CACHE ??= {}).componentListeners ??= [];
|
||||||
|
for (const component of components) {
|
||||||
|
if (!window.customElements.get(component.elementName)) {
|
||||||
|
console.debug(`.dungeon | Registering component "${component.elementName}"`);
|
||||||
|
window.customElements.define(
|
||||||
|
component.elementName,
|
||||||
|
component
|
||||||
|
);
|
||||||
|
if (component.formAssociated) {
|
||||||
|
CONFIG.CACHE.componentListeners.push(component.elementName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
80
module/components/mixins/Styles.mjs
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} Base
|
||||||
|
*/
|
||||||
|
export function StyledShadowElement(Base) {
|
||||||
|
return class extends Base {
|
||||||
|
/**
|
||||||
|
* The path to the CSS that is loaded
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
static _stylePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The stringified CSS to use
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
static _styles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The HTML element of the stylesheet
|
||||||
|
* @type {HTMLStyleElement}
|
||||||
|
*/
|
||||||
|
_style;
|
||||||
|
|
||||||
|
/** @type {ShadowRoot} */
|
||||||
|
_shadow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hook ID for this element's CSS hot reload
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
#cssHmr;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this._shadow = this.attachShadow({ mode: `open` });
|
||||||
|
this._style = document.createElement(`style`);
|
||||||
|
this._shadow.appendChild(this._style);
|
||||||
|
};
|
||||||
|
|
||||||
|
#mounted = false;
|
||||||
|
connectedCallback() {
|
||||||
|
if (this.#mounted) return;
|
||||||
|
|
||||||
|
this._getStyles();
|
||||||
|
|
||||||
|
if (game.settings.get(`dotdungeon`, `devMode`)) {
|
||||||
|
this.#cssHmr = Hooks.on(`dd-hmr:css`, (data) => {
|
||||||
|
if (data.path.endsWith(this.constructor._stylePath)) {
|
||||||
|
this._style.innerHTML = data.content;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.#mounted = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
if (!this.#mounted) return;
|
||||||
|
if (this.#cssHmr != null) {
|
||||||
|
Hooks.off(`dd-hmr:css`, this.#cssHmr);
|
||||||
|
this.#cssHmr = null;
|
||||||
|
};
|
||||||
|
this.#mounted = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
_getStyles() {
|
||||||
|
if (this.constructor._styles) {
|
||||||
|
this._style.innerHTML = this.constructor._styles;
|
||||||
|
} else {
|
||||||
|
fetch(`./systems/dotdungeon/.styles/${this.constructor._stylePath}`)
|
||||||
|
.then(r => r.text())
|
||||||
|
.then(t => {
|
||||||
|
this.constructor._styles = t;
|
||||||
|
this._style.innerHTML = t;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1,35 +1,71 @@
|
||||||
const statDice = [ `d4`, `d6`, `d8`, `d10`, `d12`, `d20` ];
|
export const statDice = [ `d4`, `d6`, `d8`, `d10`, `d12`, `d20` ];
|
||||||
|
|
||||||
const trainingLevels = [``, `locked`, `+2`, `+4`];
|
export const trainingLevels = [
|
||||||
|
{ key: "locked", label: "dotdungeon.trainingLevel.locked", value: -1 },
|
||||||
|
{ key: "untrained", label: "dotdungeon.trainingLevel.untrained", value: 0 },
|
||||||
|
{ key: "trained", label: "dotdungeon.trainingLevel.trained", value: 2 },
|
||||||
|
{ key: "expert", label: "dotdungeon.trainingLevel.expert", value: 4 },
|
||||||
|
];
|
||||||
|
|
||||||
const damageTypes = [ `slashing`, `piercing`, `smashing`, `gun`, `neon`, `shadow`, `solar` ];
|
export const damageTypes = [ `slashing`, `piercing`, `smashing`, `gun`, `neon`, `shadow`, `solar` ];
|
||||||
|
|
||||||
const ammoTypes = [`quivers`, `mags`, `cells`];
|
export const ammoTypes = [`quivers`, `mags`, `cells`];
|
||||||
|
|
||||||
const stats = [ `build`, `meta`, `presence`, `hands`, `tilt`, `rng` ];
|
export const stats = [ `build`, `meta`, `presence`, `hands`, `tilt`, `rng` ];
|
||||||
|
|
||||||
const buildSkills = [ `defense`, `magic`, `melee`, `platforming`, `strength`, ];
|
export const buildSkills = [ `defense`, `magic`, `melee`, `platforming`, `strength`, ];
|
||||||
const metaSkills = [ `alchemy`, `arcanum`, `dreams`, `lore`, `navigation`, ];
|
export const metaSkills = [ `alchemy`, `arcanum`, `dreams`, `lore`, `navigation`, ];
|
||||||
const presenceSkills = [ `animal_handling`, `perception`, `sneak`, `speech`, `vibes`, ];
|
export const presenceSkills = [ `animal_handling`, `perception`, `sneak`, `speech`, `vibes`, ];
|
||||||
const handsSkills = [ `accuracy`, `crafting`, `engineering`, `explosives`, `piloting`, ];
|
export const handsSkills = [ `accuracy`, `crafting`, `engineering`, `explosives`, `piloting`, ];
|
||||||
|
|
||||||
const allSkills = [
|
export const allSkills = [
|
||||||
...buildSkills,
|
...buildSkills,
|
||||||
...metaSkills,
|
...metaSkills,
|
||||||
...presenceSkills,
|
...presenceSkills,
|
||||||
...handsSkills,
|
...handsSkills,
|
||||||
];
|
];
|
||||||
|
|
||||||
const skills = {
|
export const skills = {
|
||||||
build: buildSkills,
|
build: buildSkills,
|
||||||
meta: metaSkills,
|
meta: metaSkills,
|
||||||
presence: presenceSkills,
|
presence: presenceSkills,
|
||||||
hands: handsSkills,
|
hands: handsSkills,
|
||||||
};
|
};
|
||||||
|
|
||||||
const itemTiers = [
|
export const defaultItemTier = `simple`;
|
||||||
`simple`, `greater`,
|
export const itemTiers = [
|
||||||
`rare`, `legendary`
|
{ value: `simple`, label: `dotdungeon.rarity.simple` },
|
||||||
|
{ value: `greater`, label: `dotdungeon.rarity.greater` },
|
||||||
|
{ value: `rare`, label: `dotdungeon.rarity.rare` },
|
||||||
|
{ value: `legendary`, label: `dotdungeon.rarity.legendary` },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const syncMilestones = [
|
||||||
|
{ value: 20, andReturn: true },
|
||||||
|
{ value: 40, andReturn: false },
|
||||||
|
{ value: 60, andReturn: true },
|
||||||
|
{ value: 80, andReturn: false },
|
||||||
|
{ value: 100, andReturn: true },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const syncDice = `1d20`;
|
||||||
|
|
||||||
|
export const localizerConfig = {
|
||||||
|
subKeyPattern: /@(?<key>[a-zA-Z\.]+)/gm,
|
||||||
|
maxDepth: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const itemFilters = [
|
||||||
|
`material`,
|
||||||
|
`untyped`,
|
||||||
|
`aspect`,
|
||||||
|
`weapon`,
|
||||||
|
`armour`,
|
||||||
|
`equipment`,
|
||||||
|
`foil`,
|
||||||
|
`pet`,
|
||||||
|
`structure`,
|
||||||
|
`service`,
|
||||||
];
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -44,5 +80,10 @@ export default {
|
||||||
handsSkills,
|
handsSkills,
|
||||||
allSkills,
|
allSkills,
|
||||||
skills,
|
skills,
|
||||||
|
defaultItemTier,
|
||||||
itemTiers,
|
itemTiers,
|
||||||
|
syncMilestones,
|
||||||
|
syncDice,
|
||||||
|
localizerConfig,
|
||||||
|
itemFilters,
|
||||||
};
|
};
|
||||||
|
|
@ -12,7 +12,7 @@ export class DiceList extends GenericDialog {
|
||||||
};
|
};
|
||||||
|
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
const opts = mergeObject({
|
const opts = foundry.utils.mergeObject({
|
||||||
...super.defaultOptions,
|
...super.defaultOptions,
|
||||||
template: `systems/dotdungeon/templates/dialogs/diceList.hbs`,
|
template: `systems/dotdungeon/templates/dialogs/diceList.hbs`,
|
||||||
width: 275,
|
width: 275,
|
||||||
|
|
@ -27,10 +27,19 @@ export class DiceList extends GenericDialog {
|
||||||
async getData() {
|
async getData() {
|
||||||
const ctx = await super.getData();
|
const ctx = await super.getData();
|
||||||
ctx.dice = this.dice;
|
ctx.dice = this.dice;
|
||||||
console.debug(`DiceList context`, ctx);
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
if (!this.isEditable) return;
|
||||||
|
console.debug(`.dungeon | DiceList adding event listeners`);
|
||||||
|
|
||||||
|
html.find(`[data-die-update]`)
|
||||||
|
.on(`change`, this.updateDieInMemoryOnly.bind(this))
|
||||||
|
};
|
||||||
|
|
||||||
async _updateObject(_event, formData) {
|
async _updateObject(_event, formData) {
|
||||||
const newDice = this.dice.map(d => {
|
const newDice = this.dice.map(d => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -42,6 +51,19 @@ export class DiceList extends GenericDialog {
|
||||||
await this.actor.update({ "system.dice": newDice });
|
await this.actor.update({ "system.dice": newDice });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
updateDieInMemoryOnly($e) {
|
||||||
|
const target = $e.currentTarget;
|
||||||
|
const data = target.dataset;
|
||||||
|
const value = target.value;
|
||||||
|
const [ dieId, field ] = data.dieUpdate.split(`.`);
|
||||||
|
for (const die of this.dice) {
|
||||||
|
if (die.id === dieId) {
|
||||||
|
die[field] = value;
|
||||||
|
return
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
addDie() {
|
addDie() {
|
||||||
this.dice.push({
|
this.dice.push({
|
||||||
count: 1,
|
count: 1,
|
||||||
|
|
|
||||||
7
module/documents/ActiveEffect/GenericActiveEffect.mjs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
export class DotDungeonActiveEffect extends ActiveEffect {
|
||||||
|
|
||||||
|
// Invert the logic of the disabled property so it's easier to modify via
|
||||||
|
// embedded controls
|
||||||
|
get enabled() { return !this.disabled };
|
||||||
|
set enabled(newValue) { this.disabled = !newValue };
|
||||||
|
};
|
||||||
42
module/documents/ActiveEffect/_proxy.mjs
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { DotDungeonActiveEffect } from "./GenericActiveEffect.mjs";
|
||||||
|
|
||||||
|
const classes = {};
|
||||||
|
|
||||||
|
const defaultClass = DotDungeonActiveEffect;
|
||||||
|
|
||||||
|
export const ActiveEffectProxy = new Proxy(function () {}, {
|
||||||
|
construct(target, args) {
|
||||||
|
const [data] = args;
|
||||||
|
|
||||||
|
if (!classes.hasOwnProperty(data.type)) {
|
||||||
|
return new defaultClass(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new classes[data.type](...args);
|
||||||
|
},
|
||||||
|
get(target, prop, receiver) {
|
||||||
|
|
||||||
|
if (["create", "createDocuments"].includes(prop)) {
|
||||||
|
return function (data, options) {
|
||||||
|
if (data.constructor === Array) {
|
||||||
|
return data.map(i => ActiveEffectProxy.create(i, options))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!classes.hasOwnProperty(data.type)) {
|
||||||
|
return defaultClass.create(data, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes[data.type].create(data, options);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (prop == Symbol.hasInstance) {
|
||||||
|
return function (instance) {
|
||||||
|
if (instance instanceof defaultClass) return true;
|
||||||
|
return Object.values(classes).some(i => instance instanceof i);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return defaultClass[prop];
|
||||||
|
},
|
||||||
|
});
|
||||||
49
module/documents/Actor/GenericActor.mjs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
export class DotDungeonActor extends Actor {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Using this to take a "snapshot" of the system data prior to applying AE's so
|
||||||
|
that the inputs can still have the non-modified value in them, while we still
|
||||||
|
provide all that data to AE's without needing to disable any inputs.
|
||||||
|
*/
|
||||||
|
prepareEmbeddedDocuments() {
|
||||||
|
this.preAE = foundry.utils.deepClone(this.system);
|
||||||
|
super.prepareEmbeddedDocuments();
|
||||||
|
};
|
||||||
|
|
||||||
|
async createEmbeddedItem(defaults, opts = {}) {
|
||||||
|
let items = await this.createEmbeddedDocuments(`Item`, defaults);
|
||||||
|
if (!Array.isArray(items)) items = items ? [items] : [];
|
||||||
|
if (items.length == 0) {
|
||||||
|
throw new Error(`Failed to create any items`);
|
||||||
|
};
|
||||||
|
this.sheet.render();
|
||||||
|
if (
|
||||||
|
game.settings.get(`dotdungeon`, `openEmbeddedOnCreate`)
|
||||||
|
&& !opts.overrideSheetOpen
|
||||||
|
) {
|
||||||
|
for (const item of items) {
|
||||||
|
item.sheet.render(true);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
async preItemEmbed(item) {
|
||||||
|
|
||||||
|
// Increases the quantity of already present items if they match via source
|
||||||
|
let embedded = this.itemTypes[item.type].find(i => {
|
||||||
|
return i.getFlag(`core`, `sourceId`) === `Item.${item.id}`
|
||||||
|
});
|
||||||
|
if (embedded) {
|
||||||
|
await embedded.update({"system.quantity": embedded.system.quantity + 1});
|
||||||
|
ui.notifications.info(
|
||||||
|
game.i18n.format(
|
||||||
|
`dotdungeon.notification.info.increased-item-quantity`,
|
||||||
|
{ name: embedded.name, quantity: embedded.system.quantity }
|
||||||
|
),
|
||||||
|
{ console: false }
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
import PlayerActor from "./Player.mjs";
|
|
||||||
import MobActor from "./Mob.mjs";
|
|
||||||
|
|
||||||
/** @extends {Actor} */
|
|
||||||
export class ActorHandler extends Actor {
|
|
||||||
proxyTargets = {
|
|
||||||
player: PlayerActor,
|
|
||||||
mob: MobActor,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(data, ctx) {
|
|
||||||
super(data, ctx);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @type {class|undefined} */
|
|
||||||
get fn() {
|
|
||||||
return this.proxyTargets[this.type];
|
|
||||||
};
|
|
||||||
|
|
||||||
async proxyFunction(funcName, ...args) {
|
|
||||||
if (!this.fn?.[funcName]) return;
|
|
||||||
return await this.fn?.[funcName].bind(this)(...args);
|
|
||||||
};
|
|
||||||
|
|
||||||
async openEmbeddedSheet($event) {
|
|
||||||
if (this.fn?.openEmbeddedSheet) {
|
|
||||||
this.fn.openEmbeddedSheet.bind(this)($event);
|
|
||||||
} else {
|
|
||||||
const data = $event.target.dataset;
|
|
||||||
let item = await fromUuid(data.embeddedEdit);
|
|
||||||
item?.sheet.render(true);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
async genericEmbeddedUpdate($event) {
|
|
||||||
if (this.fn?.genericEmbeddedUpdate) {
|
|
||||||
return this.fn.genericEmbeddedUpdate.bind(this)($event);
|
|
||||||
};
|
|
||||||
const target = $event.delegateTarget;
|
|
||||||
const data = target.dataset;
|
|
||||||
const item = await fromUuid(data.embeddedId);
|
|
||||||
|
|
||||||
let value = target.value;
|
|
||||||
switch (target.type) {
|
|
||||||
case "checkbox": value = target.checked; break;
|
|
||||||
};
|
|
||||||
|
|
||||||
await item?.update({ [data.embeddedUpdate]: value });
|
|
||||||
};
|
|
||||||
|
|
||||||
async genericEmbeddedDelete($event) {
|
|
||||||
if (!this.fn?.genericEmbeddedDelete) return;
|
|
||||||
this.fn.genericEmbeddedDelete.bind(this)($event);
|
|
||||||
};
|
|
||||||
|
|
||||||
async genericEmbeddedCreate($event) {
|
|
||||||
const data = $event.currentTarget.dataset;
|
|
||||||
if (!this.fn?.[`createCustom${data.embeddedCreate}`]) return;
|
|
||||||
this.fn?.[`createCustom${data.embeddedCreate}`].bind(this)($event);
|
|
||||||
};
|
|
||||||
|
|
||||||
async genericSendToChat($event) {
|
|
||||||
const data = $event.currentTarget.dataset;
|
|
||||||
const type = data.messageType;
|
|
||||||
console.log(data)
|
|
||||||
if (this.fn?.[`send${type}ToChat`]) {
|
|
||||||
return await this.fn?.[`send${type}ToChat`].bind(this)($event);
|
|
||||||
};
|
|
||||||
if (!data.messageContent) {
|
|
||||||
console.warn(`.dungeon | Tried to send a chat message with no content`);
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let message = await ChatMessage.create({
|
|
||||||
content: data.messageContent,
|
|
||||||
flavor: data.messageFlavor,
|
|
||||||
speaker: { actor: this.actor }
|
|
||||||
});
|
|
||||||
message.render();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ItemHandler} item
|
|
||||||
* @returns {boolean} true to allow the document to be embedded
|
|
||||||
*/
|
|
||||||
async preItemEmbed(item) {
|
|
||||||
let type = item.type[0].toUpperCase() + item.type.slice(1);
|
|
||||||
if (this.fn?.[`pre${type}Embed`]) {
|
|
||||||
return await this.fn?.[`pre${type}Embed`].bind(this)(item);
|
|
||||||
};
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
@ -1 +1,10 @@
|
||||||
export default {};
|
import { DotDungeonActor } from "./GenericActor.mjs";
|
||||||
|
|
||||||
|
export class Mob extends DotDungeonActor {
|
||||||
|
getRollData() {
|
||||||
|
const data = {
|
||||||
|
initiative: this.system.initiative ?? 0,
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,116 +1,51 @@
|
||||||
import { ItemHandler } from "../Item/Handler.mjs";
|
import { DotDungeonActor } from "./GenericActor.mjs";
|
||||||
|
|
||||||
/** @this {Actor} */
|
export class Player extends DotDungeonActor {
|
||||||
async function genericEmbeddedDelete($event) {
|
|
||||||
let data = $event.currentTarget.dataset;
|
|
||||||
let item = await fromUuid(data.embeddedId);
|
|
||||||
|
|
||||||
if (!item) {
|
applyActiveEffects() {
|
||||||
ui.notifications.error(
|
super.applyActiveEffects();
|
||||||
`dotdungeon.notification.error.item-not-found`,
|
|
||||||
{ console: false }
|
/*
|
||||||
|
These are the (groups of) fields that ActiveEffects may modify safely and
|
||||||
|
remain editable in the sheet. This needs to be done because of default
|
||||||
|
Foundry behaviour that otherwise prevents these fields from being edited.
|
||||||
|
The deletes must use optional chaining otherwise they can cause issues
|
||||||
|
during the document preparation lifecycle as an actor with no AE's affecting
|
||||||
|
anything in one of these areas will result in these paths being undefined.
|
||||||
|
*/
|
||||||
|
delete this.overrides.system?.stats;
|
||||||
|
delete this.overrides.system?.skills;
|
||||||
|
};
|
||||||
|
|
||||||
|
async createCustomPet() {
|
||||||
|
const body = new URLSearchParams({
|
||||||
|
number: 1,
|
||||||
|
animal: `Cat`,
|
||||||
|
"X-Requested-With": "fetch"
|
||||||
|
});
|
||||||
|
const r = await fetch(
|
||||||
|
`https://randommer.io/pet-names`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body
|
||||||
|
}
|
||||||
);
|
);
|
||||||
return;
|
await this.createEmbeddedItem([{
|
||||||
|
type: `pet`,
|
||||||
|
name: (await r.json())[0] ?? game.i18n.localize(`dotdungeon.defaults.pet.name`),
|
||||||
|
}]);
|
||||||
};
|
};
|
||||||
|
|
||||||
Dialog.confirm({
|
get atAspectLimit() {
|
||||||
title: game.i18n.format(
|
let limit = game.settings.get(`dotdungeon`, `aspectLimit`);
|
||||||
`dotdungeon.dialogs.${item.type}.delete.title`,
|
return this.itemTypes.aspect.length >= limit;
|
||||||
item
|
|
||||||
),
|
|
||||||
content: game.i18n.format(
|
|
||||||
`dotdungeon.dialogs.${item.type}.delete.content`,
|
|
||||||
item
|
|
||||||
),
|
|
||||||
yes: () => {
|
|
||||||
item.delete();
|
|
||||||
},
|
|
||||||
defaultYes: false,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @this {Actor} */
|
|
||||||
async function createCustomItem(defaults, opts = {}) {
|
|
||||||
let items = await this.createEmbeddedDocuments(`Item`, defaults);
|
|
||||||
if (items.length == 0) {
|
|
||||||
throw new Error();
|
|
||||||
};
|
};
|
||||||
this.sheet.render();
|
|
||||||
if (
|
getRollData() {
|
||||||
game.settings.get(`dotdungeon`, `openEmbeddedOnCreate`)
|
const data = {
|
||||||
&& !opts.overrideSheetOpen
|
initiative: this.system.stats.hands ?? 0,
|
||||||
) {
|
stats: this.system.stats,
|
||||||
for (const item of items) {
|
|
||||||
item.sheet.render(true);
|
|
||||||
};
|
};
|
||||||
|
return data;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @this {Actor} */
|
|
||||||
async function createCustomAspect() {
|
|
||||||
await createCustomItem.bind(this)([{
|
|
||||||
type: `aspect`,
|
|
||||||
name: game.i18n.format(`dotdungeon.defaults.aspect.name`),
|
|
||||||
}]);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @this {Actor} */
|
|
||||||
async function createCustomSpell() {
|
|
||||||
await createCustomItem.bind(this)([{
|
|
||||||
type: `spell`,
|
|
||||||
name: game.i18n.format(`dotdungeon.defaults.spell.name`),
|
|
||||||
}]);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @this {Actor} */
|
|
||||||
async function createCustomPet() {
|
|
||||||
const body = new URLSearchParams({
|
|
||||||
number: 1,
|
|
||||||
animal: `Cat`,
|
|
||||||
"X-Requested-With": "fetch"
|
|
||||||
})
|
|
||||||
const r = await fetch(
|
|
||||||
`https://randommer.io/pet-names`,
|
|
||||||
{
|
|
||||||
method: "POST",
|
|
||||||
body
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await createCustomItem.bind(this)([{
|
|
||||||
type: `pet`,
|
|
||||||
name: (await r.json())[0] ?? game.i18n.localize(`dotdungeon.defaults.pet.name`),
|
|
||||||
}]);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @this {Actor} */
|
|
||||||
async function atAspectLimit() {
|
|
||||||
let limit = game.settings.get(`dotdungeon`, `aspectLimit`);
|
|
||||||
return this.itemTypes.aspect.length >= limit;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ItemHandler} item
|
|
||||||
* @this {Actor}
|
|
||||||
*/
|
|
||||||
async function preAspectEmbed(item) {
|
|
||||||
if (await atAspectLimit.bind(this)()) {
|
|
||||||
ui.notifications.error(
|
|
||||||
game.i18n.format(
|
|
||||||
`dotdungeon.notification.error.aspect-limit-reached`,
|
|
||||||
{ limit: game.settings.get(`dotdungeon`, `aspectLimit`) }
|
|
||||||
),
|
|
||||||
{ console: false }
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
atAspectLimit,
|
|
||||||
createCustomItem,
|
|
||||||
createCustomAspect,
|
|
||||||
createCustomSpell,
|
|
||||||
createCustomPet,
|
|
||||||
genericEmbeddedDelete,
|
|
||||||
preAspectEmbed,
|
|
||||||
};
|
|
||||||
56
module/documents/Actor/Sync.mjs
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { DotDungeonActor } from "./GenericActor.mjs";
|
||||||
|
import { syncMilestones } from "../../config.mjs";
|
||||||
|
|
||||||
|
export class Sync extends DotDungeonActor {
|
||||||
|
async useRestDie() {
|
||||||
|
let addToSync = await (new Roll(syncDice)).evaluate();
|
||||||
|
await addToSync.toMessage({
|
||||||
|
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
|
||||||
|
flavor: `Sync Restoration`,
|
||||||
|
});
|
||||||
|
this.update({
|
||||||
|
"system.rest_dice": this.system.rest_dice - 1,
|
||||||
|
"system.value": this.system.value + addToSync.total,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async _preUpdate(data, options) {
|
||||||
|
if (options.diff) {
|
||||||
|
if (data.system?.value != null) {
|
||||||
|
let currentSync = this.system.value;
|
||||||
|
let newSync = data.system.value;
|
||||||
|
|
||||||
|
let minSync = Math.min(currentSync, newSync);
|
||||||
|
let maxSync = Math.max(currentSync, newSync);
|
||||||
|
let milestones = syncMilestones.filter(
|
||||||
|
m => minSync < m.value && m.value <= maxSync
|
||||||
|
);
|
||||||
|
|
||||||
|
if (milestones.length > 0) data.system.rest_dice ??= this.system.rest_dice;
|
||||||
|
|
||||||
|
for (const milestone of milestones) {
|
||||||
|
// Damage
|
||||||
|
if (newSync < currentSync) {
|
||||||
|
if (!this.system.milestones_hit.has(milestone.value)) {
|
||||||
|
data.system.rest_dice += 1;
|
||||||
|
this.system.milestones_hit.add(milestone.value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Healing
|
||||||
|
else if (newSync > currentSync) {
|
||||||
|
if (
|
||||||
|
this.system.milestones_hit.has(milestone.value)
|
||||||
|
&& milestone.andReturn
|
||||||
|
&& milestone.value <= newSync
|
||||||
|
) {
|
||||||
|
this.system.milestones_hit.delete(milestone.value);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
data.system.milestones_hit = [ ...this.system.milestones_hit ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
49
module/documents/Actor/_proxy.mjs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { DotDungeonActor } from "./GenericActor.mjs";
|
||||||
|
import { Player } from "./Player.mjs";
|
||||||
|
import { Sync } from "./Sync.mjs";
|
||||||
|
import { Mob } from "./Mob.mjs";
|
||||||
|
|
||||||
|
const classes = {
|
||||||
|
player: Player,
|
||||||
|
mob: Mob,
|
||||||
|
sync: Sync,
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultClass = DotDungeonActor;
|
||||||
|
|
||||||
|
export const ActorProxy = new Proxy(function () {}, {
|
||||||
|
construct(target, args) {
|
||||||
|
const [data] = args;
|
||||||
|
|
||||||
|
if (!classes.hasOwnProperty(data.type)) {
|
||||||
|
return new defaultClass(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new classes[data.type](...args);
|
||||||
|
},
|
||||||
|
get(target, prop, receiver) {
|
||||||
|
|
||||||
|
if (["create", "createDocuments"].includes(prop)) {
|
||||||
|
return function (data, options) {
|
||||||
|
if (data.constructor === Array) {
|
||||||
|
return data.map(i => ActorProxy.create(i, options))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!classes.hasOwnProperty(data.type)) {
|
||||||
|
return defaultClass.create(data, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes[data.type].create(data, options);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (prop == Symbol.hasInstance) {
|
||||||
|
return function (instance) {
|
||||||
|
if (instance instanceof defaultClass) return true;
|
||||||
|
return Object.values(classes).some(i => instance instanceof i);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return defaultClass[prop];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -1,10 +1,42 @@
|
||||||
/** @this {ItemHandler} */
|
import { DotDungeonItem } from "./GenericItem.mjs";
|
||||||
async function _preCreate(_data, _options, _user) {
|
|
||||||
if (this.isEmbedded) {
|
const secondsInAMinute = 60;
|
||||||
return await this.actor?.preItemEmbed(this);
|
const secondsInAnHour = 60 * secondsInAMinute;
|
||||||
|
|
||||||
|
export class Aspect extends DotDungeonItem {
|
||||||
|
async _preCreate() {
|
||||||
|
if (this.isEmbedded) {
|
||||||
|
if (this.actor.atAspectLimit) {
|
||||||
|
ui.notifications.error(
|
||||||
|
game.i18n.format(
|
||||||
|
`dotdungeon.notification.error.aspect-limit-reached`,
|
||||||
|
{ limit: game.settings.get(`dotdungeon`, `aspectLimit`) }
|
||||||
|
),
|
||||||
|
{ console: false }
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return await this.actor?.preItemEmbed(this);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
get friendlyDuration() {
|
||||||
|
let friendly = ``;
|
||||||
|
let duration = this.system.deactivateAfter;
|
||||||
|
if (duration >= secondsInAnHour) {
|
||||||
|
let hours = Math.floor(duration / secondsInAnHour);
|
||||||
|
friendly += `${hours}h`;
|
||||||
|
duration -= hours * secondsInAnHour;
|
||||||
|
};
|
||||||
|
if (duration >= secondsInAMinute) {
|
||||||
|
let minutes = Math.floor(duration / secondsInAMinute);
|
||||||
|
friendly += `${minutes}m`;
|
||||||
|
duration -= minutes * secondsInAMinute;
|
||||||
|
};
|
||||||
|
if (duration > 0) {
|
||||||
|
friendly += `${duration}s`;
|
||||||
|
};
|
||||||
|
return friendly;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
|
||||||
_preCreate,
|
|
||||||
};
|
|
||||||
24
module/documents/Item/GenericItem.mjs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
export class DotDungeonItem extends Item {
|
||||||
|
async _preCreate() {
|
||||||
|
if (this.isEmbedded) {
|
||||||
|
return await this.actor?.preItemEmbed(this);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
get usedCapacity() {
|
||||||
|
if (!this.system.uses_inventory_slot) return 0;
|
||||||
|
if (!this.system.quantity_affects_used_capacity) {
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
return this.system.quantity;
|
||||||
|
};
|
||||||
|
|
||||||
|
get availableLocations() {
|
||||||
|
return [
|
||||||
|
{ value: null, label: `dotdungeon.location.unknown` },
|
||||||
|
{ value: `inventory`, label: `dotdungeon.location.inventory` },
|
||||||
|
{ value: `equipped`, label: `dotdungeon.location.equipped` },
|
||||||
|
{ value: `storage`, label: `dotdungeon.location.storage` },
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
import AspectItem from "./Aspect.mjs";
|
|
||||||
import SpellItem from "./Spell.mjs";
|
|
||||||
|
|
||||||
/** @extends {Item} */
|
|
||||||
export class ItemHandler extends Item {
|
|
||||||
proxyTargets = {
|
|
||||||
aspect: AspectItem,
|
|
||||||
spell: SpellItem,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(data, ctx) {
|
|
||||||
super(data, ctx);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @type {class|undefined} */
|
|
||||||
get fn() {
|
|
||||||
return this.proxyTargets[this.type];
|
|
||||||
};
|
|
||||||
|
|
||||||
async proxyFunction(funcName, ...args) {
|
|
||||||
if (!this.fn?.[funcName]) return;
|
|
||||||
return await this.fn?.[funcName].bind(this)(...args);
|
|
||||||
};
|
|
||||||
|
|
||||||
async _preCreate(...args) {
|
|
||||||
if (!this.fn?._preCreate) return;
|
|
||||||
return this.fn?._preCreate.bind(this)(...args);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
15
module/documents/Item/Material.mjs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { DotDungeonItem } from "./GenericItem.mjs";
|
||||||
|
|
||||||
|
export class Material extends DotDungeonItem {
|
||||||
|
get usedCapacity() {
|
||||||
|
let affects = game.settings.get(`dotdungeon`, `materialsAffectCapacity`);
|
||||||
|
return affects ? super.usedCapacity : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
get availableLocations() {
|
||||||
|
return [
|
||||||
|
{ value: null, label: `dotdungeon.location.unknown` },
|
||||||
|
{ value: `inventory`, label: `dotdungeon.location.inventory` },
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export default {};
|
|
||||||
47
module/documents/Item/_proxy.mjs
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { DotDungeonItem } from "./GenericItem.mjs";
|
||||||
|
import { Aspect } from "./Aspect.mjs";
|
||||||
|
import { Material } from "./Material.mjs";
|
||||||
|
|
||||||
|
const classes = {
|
||||||
|
aspect: Aspect,
|
||||||
|
material: Material,
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultClass = DotDungeonItem;
|
||||||
|
|
||||||
|
export const ItemProxy = new Proxy(function () {}, {
|
||||||
|
construct(target, args) {
|
||||||
|
const [data] = args;
|
||||||
|
|
||||||
|
if (!classes.hasOwnProperty(data.type)) {
|
||||||
|
return new defaultClass(...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new classes[data.type](...args);
|
||||||
|
},
|
||||||
|
get(target, prop, receiver) {
|
||||||
|
|
||||||
|
if (["create", "createDocuments"].includes(prop)) {
|
||||||
|
return function (data, options) {
|
||||||
|
if (data.constructor === Array) {
|
||||||
|
return data.map(i => ItemProxy.create(i, options))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!classes.hasOwnProperty(data.type)) {
|
||||||
|
return defaultClass.create(data, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes[data.type].create(data, options);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (prop == Symbol.hasInstance) {
|
||||||
|
return function (instance) {
|
||||||
|
if (instance instanceof defaultClass) return true;
|
||||||
|
return Object.values(classes).some(i => instance instanceof i);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return defaultClass[prop];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
// Data Models
|
// Data Models
|
||||||
|
import { DescribedItemData } from "./models/Item/DescribedItemData.mjs";
|
||||||
|
import { CommonItemData } from "./models/Item/CommonItemData.mjs";
|
||||||
|
import { WeaponItemData } from "./models/Item/Weapon.mjs";
|
||||||
import { AspectItemData } from "./models/Item/Aspect.mjs";
|
import { AspectItemData } from "./models/Item/Aspect.mjs";
|
||||||
import { SpellItemData } from "./models/Item/Spell.mjs";
|
import { SpellItemData } from "./models/Item/Spell.mjs";
|
||||||
import { PlayerData } from "./models/Actor/Player.mjs";
|
import { PlayerData } from "./models/Actor/Player.mjs";
|
||||||
|
|
@ -7,16 +10,21 @@ import { SyncData } from "./models/Actor/Sync.mjs";
|
||||||
import { MobData } from "./models/Actor/Mob.mjs";
|
import { MobData } from "./models/Actor/Mob.mjs";
|
||||||
|
|
||||||
// Main Documents
|
// Main Documents
|
||||||
import { ActorHandler } from "./documents/Actor/Handler.mjs";
|
import { ActiveEffectProxy } from "./documents/ActiveEffect/_proxy.mjs";
|
||||||
import { ItemHandler } from "./documents/Item/Handler.mjs";
|
import { ActorProxy } from "./documents/Actor/_proxy.mjs";
|
||||||
|
import { ItemProxy } from "./documents/Item/_proxy.mjs";
|
||||||
|
|
||||||
// Character Sheets
|
// Item Sheets
|
||||||
import { SpellSheet } from "./sheets/SpellSheet.mjs";
|
import { UntypedItemSheet } from "./sheets/Items/UntypedItemSheet.mjs";
|
||||||
import { AspectSheet } from "./sheets/AspectSheet.mjs";
|
import { AspectSheet } from "./sheets/Items/AspectSheet.mjs";
|
||||||
import { PlayerSheet } from "./sheets/PlayerSheet.mjs";
|
import { SpellSheet } from "./sheets/Items/SpellSheet.mjs";
|
||||||
|
import { PetSheet } from "./sheets/Items/PetSheet.mjs";
|
||||||
|
|
||||||
|
// Actor Sheets
|
||||||
import { BasicSyncSheet } from "./sheets/SyncVariations/BasicSyncSheet.mjs";
|
import { BasicSyncSheet } from "./sheets/SyncVariations/BasicSyncSheet.mjs";
|
||||||
|
import { PlayerSheetv2 } from "./sheets/Actors/PC/PlayerSheetV2.mjs";
|
||||||
|
import { MVPPCSheet } from "./sheets/MVPPCSheet.mjs";
|
||||||
import { MobSheet } from "./sheets/MobSheet.mjs";
|
import { MobSheet } from "./sheets/MobSheet.mjs";
|
||||||
import { PetSheet } from "./sheets/PetSheet.mjs";
|
|
||||||
|
|
||||||
// Utility imports
|
// Utility imports
|
||||||
import * as hbs from "./handlebars.mjs";
|
import * as hbs from "./handlebars.mjs";
|
||||||
|
|
@ -25,31 +33,44 @@ import * as hbs from "./handlebars.mjs";
|
||||||
import "./hooks/hotReload.mjs";
|
import "./hooks/hotReload.mjs";
|
||||||
|
|
||||||
// Misc Imports
|
// Misc Imports
|
||||||
|
import { registerCustomComponents } from "./components/index.mjs";
|
||||||
import loadSettings from "./settings/index.mjs";
|
import loadSettings from "./settings/index.mjs";
|
||||||
|
import { devInit } from "./hooks/devInit.mjs";
|
||||||
import DOTDUNGEON from "./config.mjs";
|
import DOTDUNGEON from "./config.mjs";
|
||||||
|
|
||||||
|
|
||||||
Hooks.once(`init`, async () => {
|
Hooks.once(`init`, async () => {
|
||||||
console.debug(`.dungeon | Initializing`);
|
console.debug(`.dungeon | Initializing`);
|
||||||
|
CONFIG.ActiveEffect.legacyTransferral = false;
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
CONFIG.Actor.dataModels.player = PlayerData;
|
CONFIG.Actor.dataModels.player = PlayerData;
|
||||||
CONFIG.Actor.dataModels.sync = SyncData;
|
CONFIG.Actor.dataModels.sync = SyncData;
|
||||||
CONFIG.Actor.dataModels.mob = MobData;
|
CONFIG.Actor.dataModels.mob = MobData;
|
||||||
|
CONFIG.Item.dataModels.untyped = DescribedItemData;
|
||||||
|
CONFIG.Item.dataModels.material = CommonItemData;
|
||||||
|
CONFIG.Item.dataModels.foil = DescribedItemData;
|
||||||
|
CONFIG.Item.dataModels.weapon = WeaponItemData;
|
||||||
CONFIG.Item.dataModels.aspect = AspectItemData;
|
CONFIG.Item.dataModels.aspect = AspectItemData;
|
||||||
CONFIG.Item.dataModels.spell = SpellItemData;
|
CONFIG.Item.dataModels.spell = SpellItemData;
|
||||||
CONFIG.Item.dataModels.pet = PetItemData;
|
CONFIG.Item.dataModels.pet = PetItemData;
|
||||||
CONFIG.Actor.documentClass = ActorHandler;
|
CONFIG.Actor.documentClass = ActorProxy;
|
||||||
CONFIG.Item.documentClass = ItemHandler;
|
CONFIG.Item.documentClass = ItemProxy;
|
||||||
|
CONFIG.ActiveEffect.documentClass = ActiveEffectProxy;
|
||||||
|
|
||||||
CONFIG.DOTDUNGEON = DOTDUNGEON;
|
CONFIG.DOTDUNGEON = DOTDUNGEON;
|
||||||
|
|
||||||
// Actors.unregisterSheet("core", ActorSheet);
|
|
||||||
Actors.registerSheet("dotdungeon", PlayerSheet, {
|
Actors.registerSheet("dotdungeon", MVPPCSheet, {
|
||||||
makeDefault: true,
|
makeDefault: true,
|
||||||
types: ["player"],
|
types: ["player"],
|
||||||
label: "dotdungeon.sheet-names.PlayerSheet"
|
label: "dotdungeon.sheet-names.PlayerSheet.MVP"
|
||||||
|
});
|
||||||
|
Actors.registerSheet("dotdungeon", PlayerSheetv2, {
|
||||||
|
makeDefault: false,
|
||||||
|
types: ["player"],
|
||||||
|
label: "dotdungeon.sheet-names.PlayerSheet.v2"
|
||||||
});
|
});
|
||||||
Actors.registerSheet("dotdungeon", MobSheet, {
|
Actors.registerSheet("dotdungeon", MobSheet, {
|
||||||
makeDefault: true,
|
makeDefault: true,
|
||||||
|
|
@ -62,6 +83,13 @@ Hooks.once(`init`, async () => {
|
||||||
label: "dotdungeon.sheet-names.SyncSheet.basic"
|
label: "dotdungeon.sheet-names.SyncSheet.basic"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Items.registerSheet("dotdungeon", UntypedItemSheet, {
|
||||||
|
makeDefault: true,
|
||||||
|
label: "dotdungeon.sheet-names.UntypedItemSheet",
|
||||||
|
});
|
||||||
|
Items.unregisterSheet("dotdungeon", UntypedItemSheet, {
|
||||||
|
types: ["aspect"],
|
||||||
|
});
|
||||||
Items.registerSheet("dotdungeon", AspectSheet, {
|
Items.registerSheet("dotdungeon", AspectSheet, {
|
||||||
makeDefault: true,
|
makeDefault: true,
|
||||||
types: ["aspect"],
|
types: ["aspect"],
|
||||||
|
|
@ -75,15 +103,16 @@ Hooks.once(`init`, async () => {
|
||||||
Items.registerSheet("dotdungeon", PetSheet, {
|
Items.registerSheet("dotdungeon", PetSheet, {
|
||||||
makeDefault: true,
|
makeDefault: true,
|
||||||
types: ["pet"],
|
types: ["pet"],
|
||||||
lable: "dotdungeon.sheet-names.PetSheet"
|
label: "dotdungeon.sheet-names.PetSheet"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (true || game.settings.get(`dotdungeon`, `devMode`)) {
|
||||||
|
devInit();
|
||||||
|
};
|
||||||
|
|
||||||
hbs.registerHandlebarsHelpers();
|
hbs.registerHandlebarsHelpers();
|
||||||
hbs.preloadHandlebarsTemplates();
|
hbs.preloadHandlebarsTemplates();
|
||||||
|
registerCustomComponents();
|
||||||
CONFIG.CACHE = {};
|
|
||||||
CONFIG.CACHE.icons = await hbs.preloadIcons();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -93,9 +122,9 @@ Hooks.once(`ready`, () => {
|
||||||
let defaultTab = game.settings.get(`dotdungeon`, `defaultTab`);
|
let defaultTab = game.settings.get(`dotdungeon`, `defaultTab`);
|
||||||
if (defaultTab) {
|
if (defaultTab) {
|
||||||
if (!ui.sidebar?.tabs?.[defaultTab]) {
|
if (!ui.sidebar?.tabs?.[defaultTab]) {
|
||||||
console.error(`Couldn't find a sidebar tab with ID:`, defaultTab);
|
console.error(`.dungeon | Couldn't find a sidebar tab with ID:`, defaultTab);
|
||||||
} else {
|
} else {
|
||||||
console.debug(`Switching sidebar tab to:`, defaultTab);
|
console.debug(`.dungeon | Switching sidebar tab to:`, defaultTab);
|
||||||
ui.sidebar.tabs[defaultTab].activate();
|
ui.sidebar.tabs[defaultTab].activate();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export const partials = [
|
||||||
`partials/panel.hbs`,
|
`partials/panel.hbs`,
|
||||||
`items/aspect.hbs`,
|
`items/aspect.hbs`,
|
||||||
|
|
||||||
// All of the partials for the PC sheet panels
|
// All of the partials for the PC MVP sheet panels
|
||||||
`actors/char-sheet-mvp/panels/aspect.pc.hbs`,
|
`actors/char-sheet-mvp/panels/aspect.pc.hbs`,
|
||||||
`actors/char-sheet-mvp/panels/backpack.pc.hbs`,
|
`actors/char-sheet-mvp/panels/backpack.pc.hbs`,
|
||||||
`actors/char-sheet-mvp/panels/mounts.pc.hbs`,
|
`actors/char-sheet-mvp/panels/mounts.pc.hbs`,
|
||||||
|
|
@ -18,27 +18,32 @@ export const partials = [
|
||||||
`actors/char-sheet-mvp/panels/pets.pc.hbs`,
|
`actors/char-sheet-mvp/panels/pets.pc.hbs`,
|
||||||
`actors/char-sheet-mvp/panels/sync.pc.hbs`,
|
`actors/char-sheet-mvp/panels/sync.pc.hbs`,
|
||||||
`actors/char-sheet-mvp/panels/weapons.pc.hbs`,
|
`actors/char-sheet-mvp/panels/weapons.pc.hbs`,
|
||||||
|
|
||||||
|
// The v2 PC sheet partials
|
||||||
|
`actors/char-sheet/v2/partials/stats.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/effects.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/inventory/inventory.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/inventory/player.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/inventory/item-list.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/inventory/storage.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/inventory/items/material.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/inventory/items/untyped.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/inventory/items/aspect.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/inventory/items/weapon.v2.pc.hbs`,
|
||||||
|
`actors/char-sheet/v2/partials/inventory/items/pet.v2.pc.hbs`,
|
||||||
|
|
||||||
|
// The v2 Untyped sheet partials
|
||||||
|
`items/untyped/v2/tabs/general.v2.untyped.hbs`,
|
||||||
|
`items/untyped/v2/tabs/details.v2.untyped.hbs`,
|
||||||
|
`items/untyped/v2/tabs/effects.v2.untyped.hbs`,
|
||||||
|
`items/untyped/v2/tabs/settings.v2.untyped.hbs`,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const icons = [
|
export const preAliasedPartials = {
|
||||||
`caret-right.svg`,
|
"dotdungeon.pc.v2.foil": "actors/char-sheet/v2/partials/inventory/items/untyped.v2.pc.hbs",
|
||||||
`garbage-bin.svg`,
|
};
|
||||||
`chat-bubble.svg`,
|
|
||||||
`dice/d4.svg`,
|
|
||||||
`dice/d6.svg`,
|
|
||||||
`dice/d8.svg`,
|
|
||||||
`dice/d10.svg`,
|
|
||||||
`dice/d12.svg`,
|
|
||||||
`dice/d20.svg`,
|
|
||||||
`create.svg`,
|
|
||||||
`close.svg`,
|
|
||||||
`edit.svg`,
|
|
||||||
`sheet.svg`,
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
export async function registerHandlebarsHelpers() {
|
export async function registerHandlebarsHelpers() {
|
||||||
console.log(Handlebars)
|
|
||||||
Handlebars.registerHelper(helpers);
|
Handlebars.registerHelper(helpers);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -48,6 +53,10 @@ export async function preloadHandlebarsTemplates() {
|
||||||
|
|
||||||
const paths = {};
|
const paths = {};
|
||||||
|
|
||||||
|
for (const alias in preAliasedPartials) {
|
||||||
|
paths[alias] = `${pathPrefix}${preAliasedPartials[alias]}`;
|
||||||
|
};
|
||||||
|
|
||||||
for ( const partial of partials ) {
|
for ( const partial of partials ) {
|
||||||
console.debug(`Loading partial: ${partial}`);
|
console.debug(`Loading partial: ${partial}`);
|
||||||
const path = `${pathPrefix}${partial}`;
|
const path = `${pathPrefix}${partial}`;
|
||||||
|
|
@ -69,38 +78,3 @@ export async function preloadHandlebarsTemplates() {
|
||||||
console.groupEnd();
|
console.groupEnd();
|
||||||
return loadTemplates(paths);
|
return loadTemplates(paths);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads all of the icons that are needed in the handlebars templating to make
|
|
||||||
* the sheet look nicer.
|
|
||||||
*
|
|
||||||
* @returns An object containing icon names to the corresponding HTML data for
|
|
||||||
* displaying the icon
|
|
||||||
*/
|
|
||||||
export async function preloadIcons() {
|
|
||||||
const pathPrefix = `systems/dotdungeon/assets/`
|
|
||||||
const parsedIcons = {};
|
|
||||||
|
|
||||||
for (const icon of icons) {
|
|
||||||
const iconName = icon.split(`/`).slice(-1)[0].slice(0, -4);
|
|
||||||
if (icon.endsWith(`.svg`)) {
|
|
||||||
try {
|
|
||||||
const response = await fetchWithTimeout(`${pathPrefix}${icon}`);
|
|
||||||
if (response.status !== 200) { continue };
|
|
||||||
const svgData = await response.text();
|
|
||||||
parsedIcons[iconName] = svgData;
|
|
||||||
} catch {
|
|
||||||
console.error(`.dungeon | Failed to fetch/parse icon: ${icon}`);
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (icon.endsWith(`.png`)) {
|
|
||||||
parsedIcons[iconName] = `<img alt="" src="${pathPrefix}${icon}">`;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.warn(`.dungeon | Icon "${icon}" failed to be handled by a loader`)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return parsedIcons;
|
|
||||||
};
|
|
||||||
|
|
@ -2,20 +2,24 @@ import { schemaOptions } from "./schemaOptions.mjs";
|
||||||
import { createArray } from "./createArray.mjs";
|
import { createArray } from "./createArray.mjs";
|
||||||
import { detailsExpanded } from "./detailsExpanded.mjs";
|
import { detailsExpanded } from "./detailsExpanded.mjs";
|
||||||
import { objectValue } from "./objectValue.mjs";
|
import { objectValue } from "./objectValue.mjs";
|
||||||
import { toFriendlyDuration } from "./toFriendlyDuration.mjs";
|
import { handlebarsLocalizer, localizer } from "../utils/localizer.mjs";
|
||||||
|
import { options } from "./options.mjs";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
// Complex helpers
|
// Complex helpers
|
||||||
"dd-schemaOptions": schemaOptions,
|
"dd-schemaOptions": schemaOptions,
|
||||||
"dd-array": createArray,
|
"dd-array": createArray,
|
||||||
"dd-toFriendlyDuration": toFriendlyDuration,
|
|
||||||
"dd-objectValue": objectValue,
|
"dd-objectValue": objectValue,
|
||||||
"dd-expanded": detailsExpanded,
|
"dd-expanded": detailsExpanded,
|
||||||
|
"dd-i18n": handlebarsLocalizer,
|
||||||
|
"dd-options": options,
|
||||||
|
|
||||||
// Simple helpers
|
// Simple helpers
|
||||||
"dd-stringify": v => JSON.stringify(v, null, ` `),
|
"dd-stringify": v => JSON.stringify(v, null, ` `),
|
||||||
"dd-empty": v => v.length == 0,
|
"dd-empty": v => v.length == 0,
|
||||||
|
"dd-set-has": (s, k) => s.has(k),
|
||||||
|
"dd-empty-state": (v) => v ?? localizer(`dotdungeon.common.empty`),
|
||||||
|
|
||||||
// Logic helpers
|
// Logic helpers
|
||||||
"eq": (a, b) => a == b,
|
"eq": (a, b) => a == b,
|
||||||
|
|
|
||||||
35
module/helpers/options.mjs
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { localizer } from "../utils/localizer.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} Option
|
||||||
|
* @property {string} [label]
|
||||||
|
* @property {string|number} value
|
||||||
|
* @property {boolean} [disabled]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string | number} selected
|
||||||
|
* @param {Array<Option | string>} opts
|
||||||
|
*/
|
||||||
|
export function options(selected, opts, meta) {
|
||||||
|
const { localize = false } = meta.hash;
|
||||||
|
selected = Handlebars.escapeExpression(selected);
|
||||||
|
const htmlOptions = [];
|
||||||
|
|
||||||
|
for (let opt of opts) {
|
||||||
|
if (foundry.utils.getType(opt) === "string") {
|
||||||
|
opt = { label: opt, value: opt };
|
||||||
|
};
|
||||||
|
opt.value = Handlebars.escapeExpression(opt.value);
|
||||||
|
htmlOptions.push(
|
||||||
|
`<option
|
||||||
|
value="${opt.value}"
|
||||||
|
${selected === opt.value ? "selected" : ""}
|
||||||
|
${opt.disabled ? "disabled" : ""}
|
||||||
|
>
|
||||||
|
${localize ? localizer(opt.label) : opt.label}
|
||||||
|
</option>`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
return htmlOptions.join(`\n`);
|
||||||
|
};
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
const secondsInAMinute = 60;
|
|
||||||
const secondsInAnHour = 60 * secondsInAMinute;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a duration into a more human-friendly format
|
|
||||||
* @param {number} duration The length of time in seconds
|
|
||||||
* @returns The human-friendly time string
|
|
||||||
*/
|
|
||||||
export function toFriendlyDuration(duration) {
|
|
||||||
let friendly = ``;
|
|
||||||
if (duration >= secondsInAnHour) {
|
|
||||||
let hours = Math.floor(duration / secondsInAnHour);
|
|
||||||
friendly += `${hours}h`;
|
|
||||||
duration -= hours * secondsInAnHour;
|
|
||||||
};
|
|
||||||
if (duration >= secondsInAMinute) {
|
|
||||||
let minutes = Math.floor(duration / secondsInAMinute);
|
|
||||||
friendly += `${minutes}m`;
|
|
||||||
duration -= minutes * secondsInAMinute;
|
|
||||||
};
|
|
||||||
if (duration > 0) {
|
|
||||||
friendly += `${duration}s`;
|
|
||||||
};
|
|
||||||
return friendly;
|
|
||||||
};
|
|
||||||
27
module/hooks/devInit.mjs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
Initialization of dev-specific features for the init hook, this is primarily
|
||||||
|
used to register all of the data sheets of various entity types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { GroupDataSheet } from "../sheets/Datasheets/GroupDataSheet.mjs";
|
||||||
|
import { UntypedDataSheet } from "../sheets/Datasheets/UntypedDataSheet.mjs";
|
||||||
|
|
||||||
|
export function devInit() {
|
||||||
|
Items.registerSheet(
|
||||||
|
`dotdungeon`,
|
||||||
|
UntypedDataSheet,
|
||||||
|
{
|
||||||
|
types: [`untyped`, `foil`],
|
||||||
|
label: `dotdungeon.sheet-names.*DataSheet`,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Actors.registerSheet(
|
||||||
|
`dotdungeon`,
|
||||||
|
GroupDataSheet,
|
||||||
|
{
|
||||||
|
types: [`sync`],
|
||||||
|
label: `dotdungeon.sheet-names.*DataSheet`,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -3,8 +3,8 @@ import * as hbs from "../handlebars.mjs";
|
||||||
const loaders = {
|
const loaders = {
|
||||||
svg(data) {
|
svg(data) {
|
||||||
const iconName = data.path.split(`/`).slice(-1)[0].slice(0, -4);
|
const iconName = data.path.split(`/`).slice(-1)[0].slice(0, -4);
|
||||||
console.log(`.dungeon | hot-reloading icon: ${iconName}`);
|
console.debug(`.dungeon | hot-reloading icon: ${iconName}`);
|
||||||
CONFIG.CACHE.icons[iconName] = data.content;
|
Hooks.call(`dd-hmr:svg`, iconName, data);
|
||||||
},
|
},
|
||||||
hbs(data) {
|
hbs(data) {
|
||||||
if (!hbs.partials.some(p => data.path.endsWith(p))) {
|
if (!hbs.partials.some(p => data.path.endsWith(p))) {
|
||||||
|
|
@ -33,6 +33,12 @@ const loaders = {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
js() {window.location.reload()},
|
||||||
|
mjs() {window.location.reload()},
|
||||||
|
css(data) {
|
||||||
|
console.debug(`.dungeon | Hot-reloading CSS: ${data.path}`);
|
||||||
|
Hooks.call(`dd-hmr:css`, data);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Hooks.on(`hotReload`, async (data) => {
|
Hooks.on(`hotReload`, async (data) => {
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ export class MobData extends foundry.abstract.TypeDataModel {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Called during create, read, and update
|
||||||
static migrateData(source) {
|
static migrateData(source) {
|
||||||
console.log(`migrateData data`, source);
|
return source;
|
||||||
source.dice = [];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { MappingField } from "../fields/MappingField.mjs";
|
import DOTDUNGEON from "../../config.mjs";
|
||||||
|
|
||||||
function diceChoiceField() {
|
function diceChoiceField() {
|
||||||
return new foundry.data.fields.StringField({
|
return new foundry.data.fields.StringField({
|
||||||
|
|
@ -6,33 +6,17 @@ function diceChoiceField() {
|
||||||
blank: true,
|
blank: true,
|
||||||
trim: true,
|
trim: true,
|
||||||
options() {
|
options() {
|
||||||
return CONFIG.DOTDUNGEON.statDice;
|
return DOTDUNGEON.statDice;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function trainingLevelField() {
|
function trainingLevelField() {
|
||||||
return new foundry.data.fields.StringField({
|
return new foundry.data.fields.NumberField({
|
||||||
initial: ``,
|
initial: 0,
|
||||||
blank: true,
|
min: -1,
|
||||||
trim: true,
|
integer: true,
|
||||||
options: CONFIG.DOTDUNGEON.trainingLevels,
|
options: Object.values(DOTDUNGEON.trainingLevels),
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function weaponDamageTypeField() {
|
|
||||||
return new foundry.data.fields.StringField({
|
|
||||||
initial: ``,
|
|
||||||
blank: true,
|
|
||||||
options: [ ``, ...CONFIG.DOTDUNGEON.damageTypes ],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function ammoTypeField() {
|
|
||||||
return new foundry.data.fields.StringField({
|
|
||||||
initial: ``,
|
|
||||||
blank: true,
|
|
||||||
options: [ ``, ...CONFIG.DOTDUNGEON.ammoTypes ],
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -40,6 +24,14 @@ export class PlayerData extends foundry.abstract.TypeDataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return {
|
return {
|
||||||
|
/*
|
||||||
|
These are special data properties that will be used by ActiveEffects
|
||||||
|
to modify certain limits within the actor, allowing for neat hacks
|
||||||
|
that change these
|
||||||
|
*/
|
||||||
|
weapon_slots: new fields.NumberField({ initial: 2 }),
|
||||||
|
inventory_slots: new fields.NumberField({ initial: 0 }),
|
||||||
|
|
||||||
bytes: new fields.NumberField({
|
bytes: new fields.NumberField({
|
||||||
initial: 0,
|
initial: 0,
|
||||||
min: 0,
|
min: 0,
|
||||||
|
|
@ -83,67 +75,18 @@ export class PlayerData extends foundry.abstract.TypeDataModel {
|
||||||
piloting: trainingLevelField(),
|
piloting: trainingLevelField(),
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
aspect: new fields.SchemaField({
|
// ! Delete
|
||||||
name: new fields.StringField({ blank: true, trim: true }),
|
|
||||||
description: new fields.StringField({ blank: true, trim: true }),
|
|
||||||
deactivateAfter: new fields.NumberField({ min: 0, integer: true}),
|
|
||||||
used: new fields.BooleanField(),
|
|
||||||
}),
|
|
||||||
roles: new fields.SchemaField({
|
roles: new fields.SchemaField({
|
||||||
r1: new fields.StringField({ blank: true, trim: true }),
|
r1: new fields.StringField({ blank: true, trim: true }),
|
||||||
r2: new fields.StringField({ blank: true, trim: true }),
|
r2: new fields.StringField({ blank: true, trim: true }),
|
||||||
r3: new fields.StringField({ blank: true, trim: true }),
|
r3: new fields.StringField({ blank: true, trim: true }),
|
||||||
r4: new fields.StringField({ blank: true, trim: true }),
|
r4: new fields.StringField({ blank: true, trim: true }),
|
||||||
}),
|
}),
|
||||||
weapon: new fields.SchemaField({
|
|
||||||
mainHand: new fields.SchemaField({
|
|
||||||
name: new fields.StringField({ blank: true, trim: true }),
|
|
||||||
damage: weaponDamageTypeField(),
|
|
||||||
ranged: new fields.BooleanField({ initial: false }),
|
|
||||||
scope: new fields.BooleanField({ initial: false }),
|
|
||||||
ammo: ammoTypeField(),
|
|
||||||
}),
|
|
||||||
offHand: new fields.SchemaField({
|
|
||||||
name: new fields.StringField({ blank: true, trim: true }),
|
|
||||||
damage: weaponDamageTypeField(),
|
|
||||||
ranged: new fields.BooleanField({ initial: false }),
|
|
||||||
scope: new fields.BooleanField({ initial: false }),
|
|
||||||
ammo: ammoTypeField(),
|
|
||||||
}),
|
|
||||||
ammo: new fields.SchemaField({
|
|
||||||
quivers: new fields.NumberField({ min: 0, max: 10, integer: true }),
|
|
||||||
mags: new fields.NumberField({ min: 0, max: 10, integer: true }),
|
|
||||||
cells: new fields.NumberField({ min: 0, max: 10, integer: true }),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
supplies: new fields.NumberField({
|
supplies: new fields.NumberField({
|
||||||
initial: 0,
|
initial: 0,
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 5,
|
|
||||||
integer: true
|
integer: true
|
||||||
}),
|
}),
|
||||||
materials: new fields.NumberField({
|
|
||||||
initial: 0,
|
|
||||||
min: 0,
|
|
||||||
max: 5,
|
|
||||||
integer: true
|
|
||||||
}),
|
|
||||||
pet: new fields.SchemaField({
|
|
||||||
name: new fields.StringField(),
|
|
||||||
info: new fields.StringField(),
|
|
||||||
}),
|
|
||||||
transport: new fields.SchemaField({
|
|
||||||
name: new fields.StringField(),
|
|
||||||
upkeep: new fields.NumberField({ min: 0, integer: true }),
|
|
||||||
info: new fields.StringField(),
|
|
||||||
}),
|
|
||||||
spells: new MappingField(
|
|
||||||
new fields.SchemaField({
|
|
||||||
name: new fields.StringField({ initial: ``, blank: true, trim: true }),
|
|
||||||
cost: new fields.NumberField({ initial: 0, min: 0 }),
|
|
||||||
info: new fields.StringField({ initial: ``, blank: true, trim: true }),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
respawns: new fields.SchemaField({
|
respawns: new fields.SchemaField({
|
||||||
r1: new fields.BooleanField(),
|
r1: new fields.BooleanField(),
|
||||||
r2: new fields.BooleanField(),
|
r2: new fields.BooleanField(),
|
||||||
|
|
@ -154,7 +97,6 @@ export class PlayerData extends foundry.abstract.TypeDataModel {
|
||||||
integer: true,
|
integer: true,
|
||||||
initial: 0,
|
initial: 0,
|
||||||
}),
|
}),
|
||||||
inventoryString: new fields.StringField({ blank: true, trim: true }),
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -3,10 +3,18 @@ export class SyncData extends foundry.abstract.TypeDataModel {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return {
|
return {
|
||||||
value: new fields.NumberField({
|
value: new fields.NumberField({
|
||||||
required: true,
|
|
||||||
integer: true,
|
integer: true,
|
||||||
initial: 100,
|
initial: 100,
|
||||||
}),
|
}),
|
||||||
|
rest_dice: new fields.NumberField({
|
||||||
|
integer: true,
|
||||||
|
initial: 0,
|
||||||
|
min: 0,
|
||||||
|
}),
|
||||||
|
milestones_hit: new fields.SetField(
|
||||||
|
new fields.NumberField({ integer: true, }),
|
||||||
|
{ initial: [] },
|
||||||
|
),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -1,11 +1,19 @@
|
||||||
export class AspectItemData extends foundry.abstract.TypeDataModel {
|
import { DescribedItemData } from "./DescribedItemData.mjs";
|
||||||
|
|
||||||
|
export class AspectItemData extends DescribedItemData {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return {
|
const parentSchema = super.defineSchema();
|
||||||
|
|
||||||
|
// Purge fields that I don't want in this schema
|
||||||
|
delete parentSchema.quantity;
|
||||||
|
delete parentSchema.quantity_affects_used_capacity;
|
||||||
|
delete parentSchema.usage_cost;
|
||||||
|
|
||||||
|
return foundry.utils.mergeObject(parentSchema, {
|
||||||
used: new fields.BooleanField({ initial: false }),
|
used: new fields.BooleanField({ initial: false }),
|
||||||
/** The number of seconds that the effect of the aspect stays */
|
/** The number of seconds that the effect of the aspect stays */
|
||||||
deactivateAfter: new fields.NumberField({ nullable: true }),
|
deactivateAfter: new fields.NumberField({ nullable: true }),
|
||||||
info: new fields.HTMLField({ nullable: true, blank: false, trim: true }),
|
});
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -4,18 +4,46 @@ export class CommonItemData extends foundry.abstract.TypeDataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return {
|
return {
|
||||||
|
quantity: new fields.NumberField({
|
||||||
|
initial: 1,
|
||||||
|
min: 0,
|
||||||
|
nullable: false,
|
||||||
|
integer: true,
|
||||||
|
}),
|
||||||
|
uses_inventory_slot: new fields.BooleanField({
|
||||||
|
initial: true,
|
||||||
|
nullable: false,
|
||||||
|
}),
|
||||||
|
quantity_affects_used_capacity: new fields.BooleanField({
|
||||||
|
initial: true,
|
||||||
|
nullable: false,
|
||||||
|
}),
|
||||||
buy: new fields.NumberField({
|
buy: new fields.NumberField({
|
||||||
initial: null,
|
initial: null,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
integer: true,
|
||||||
}),
|
}),
|
||||||
usage_cost: new fields.NumberField({
|
usage_cost: new fields.NumberField({
|
||||||
initial: null,
|
initial: null,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
integer: true,
|
||||||
}),
|
}),
|
||||||
tier: new fields.StringField({
|
tier: new fields.StringField({
|
||||||
initial: `simple`,
|
initial: DOTDUNGEON.defaultItemTier,
|
||||||
|
nullable: false,
|
||||||
|
choices: DOTDUNGEON.itemTiers.map(tier => tier.value),
|
||||||
|
}),
|
||||||
|
/*
|
||||||
|
If this property is set to true, the item will be shown in the combat tab
|
||||||
|
list of items. This is shown whether or not the item is marked as "equipped".
|
||||||
|
*/
|
||||||
|
combat_relevant: new fields.BooleanField({
|
||||||
|
initial: false,
|
||||||
|
nullable: false,
|
||||||
|
}),
|
||||||
|
location: new fields.StringField({
|
||||||
|
initial: "",
|
||||||
nullable: false,
|
nullable: false,
|
||||||
choices: DOTDUNGEON.itemTiers,
|
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { CommonItemData } from "./CommonItemData.mjs";
|
||||||
export class DescribedItemData extends CommonItemData {
|
export class DescribedItemData extends CommonItemData {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return mergeObject(super.defineSchema(), {
|
return foundry.utils.mergeObject(super.defineSchema(), {
|
||||||
description: new fields.StringField({
|
description: new fields.StringField({
|
||||||
initial: ``,
|
initial: ``,
|
||||||
blank: true,
|
blank: true,
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,6 @@ import { DescribedItemData } from "./DescribedItemData.mjs";
|
||||||
export class EquipmentItemData extends DescribedItemData {
|
export class EquipmentItemData extends DescribedItemData {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return mergeObject(super.defineSchema(), {
|
return foundry.utils.mergeObject(super.defineSchema(), {});
|
||||||
extra_inventory: new fields.NumberField({
|
|
||||||
initial: null,
|
|
||||||
nullable: true,
|
|
||||||
required: false,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,13 @@ import { DescribedItemData } from "./DescribedItemData.mjs";
|
||||||
export class PetItemData extends DescribedItemData {
|
export class PetItemData extends DescribedItemData {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return mergeObject(super.defineSchema(), {
|
const parentSchema = super.defineSchema();
|
||||||
|
|
||||||
|
delete parentSchema.quantity;
|
||||||
|
delete parentSchema.quantity_affects_used_capacity;
|
||||||
|
delete parentSchema.usage_cost;
|
||||||
|
|
||||||
|
return foundry.utils.mergeObject(parentSchema, {
|
||||||
upkeep: new fields.NumberField({ initial: null, nullable: true }),
|
upkeep: new fields.NumberField({ initial: null, nullable: true }),
|
||||||
pokeballd: new fields.BooleanField({ initial: true }),
|
pokeballd: new fields.BooleanField({ initial: true }),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import DOTDUNGEON from "../../config.mjs";
|
||||||
export class SpellItemData extends DescribedItemData {
|
export class SpellItemData extends DescribedItemData {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return mergeObject(super.defineSchema(), {
|
return foundry.utils.mergeObject(super.defineSchema(), {
|
||||||
skill: new fields.StringField({
|
skill: new fields.StringField({
|
||||||
initial: ``,
|
initial: ``,
|
||||||
blank: true,
|
blank: true,
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import { DescribedItemData } from "./DescribedItemData.mjs";
|
|
||||||
|
|
||||||
export class TransportationItemData extends DescribedItemData {
|
|
||||||
static defineSchema() {
|
|
||||||
const fields = foundry.data.fields;
|
|
||||||
return mergeObject(super.defineSchema(), {
|
|
||||||
single_trip: new fields.NumberField({
|
|
||||||
initial: null,
|
|
||||||
nullable: true,
|
|
||||||
}),
|
|
||||||
upkeep: new fields.NumberField({
|
|
||||||
initial: null,
|
|
||||||
nullable: true,
|
|
||||||
}),
|
|
||||||
can_be_in_inventory: new fields.BooleanField({
|
|
||||||
initial: false,
|
|
||||||
}),
|
|
||||||
inventory_slots: new fields.NumberField({
|
|
||||||
initial: 0,
|
|
||||||
min: 0,
|
|
||||||
}),
|
|
||||||
logon_bonus: new fields.NumberField({
|
|
||||||
initial: null,
|
|
||||||
nullable: true,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
24
module/models/Item/Weapon.mjs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { DescribedItemData } from "./DescribedItemData.mjs";
|
||||||
|
import DOTDUNGEON from "../../config.mjs";
|
||||||
|
|
||||||
|
export class WeaponItemData extends DescribedItemData {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return foundry.utils.mergeObject(super.defineSchema(), {
|
||||||
|
damage: new fields.StringField({
|
||||||
|
initial: null,
|
||||||
|
nullable: true,
|
||||||
|
blank: true,
|
||||||
|
options: DOTDUNGEON.damageTypes,
|
||||||
|
}),
|
||||||
|
ranged: new fields.BooleanField({ initial: false, }),
|
||||||
|
scoped: new fields.BooleanField({ initial: false, }),
|
||||||
|
ammo: new fields.StringField({
|
||||||
|
initial: null,
|
||||||
|
nullable: true,
|
||||||
|
blank: true,
|
||||||
|
options: DOTDUNGEON.ammoTypes,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -129,4 +129,4 @@ export class MappingField extends foundry.data.fields.ObjectField {
|
||||||
path.shift();
|
path.shift();
|
||||||
return this.model._getField(path);
|
return this.model._getField(path);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { DescribedItemData } from "./DescribedItemData.mjs";
|
||||||
export class TemplateData extends DescribedItemData {
|
export class TemplateData extends DescribedItemData {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return mergeObject(super.defineSchema(), {
|
return foundry.utils.mergeObject(super.defineSchema(), {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,16 @@ export default function() {
|
||||||
requiresReload: false,
|
requiresReload: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
game.settings.register(`dotdungeon`, `materialsAffectCapacity`, {
|
||||||
|
name: `dotdungeon.settings.materialsAffectCapacity.name`,
|
||||||
|
hint: `dotdungeon.settings.materialsAffectCapacity.description`,
|
||||||
|
scope: `world`,
|
||||||
|
config: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
requiresReload: false,
|
||||||
|
});
|
||||||
|
|
||||||
game.settings.register(`dotdungeon`, `resourcesOrSupplies`, {
|
game.settings.register(`dotdungeon`, `resourcesOrSupplies`, {
|
||||||
name: `dotdungeon.settings.resourcesOrSupplies.name`,
|
name: `dotdungeon.settings.resourcesOrSupplies.name`,
|
||||||
hint: `dotdungeon.settings.resourcesOrSupplies.description`,
|
hint: `dotdungeon.settings.resourcesOrSupplies.description`,
|
||||||
|
|
|
||||||
172
module/sheets/Actors/PC/PlayerSheetV2.mjs
Normal file
|
|
@ -0,0 +1,172 @@
|
||||||
|
import { GenericActorSheet } from "../../GenericActorSheet.mjs";
|
||||||
|
import DOTDUNGEON from "../../../config.mjs";
|
||||||
|
import { localizer } from "../../../utils/localizer.mjs";
|
||||||
|
import { modifierToString } from "../../../utils/modifierToString.mjs";
|
||||||
|
import { GenericContextMenu } from "../../../utils/GenericContextMenu.mjs";
|
||||||
|
|
||||||
|
export class PlayerSheetv2 extends GenericActorSheet {
|
||||||
|
static get defaultOptions() {
|
||||||
|
let opts = foundry.utils.mergeObject(
|
||||||
|
super.defaultOptions,
|
||||||
|
{
|
||||||
|
template: `systems/dotdungeon/templates/actors/char-sheet/v2/sheet.hbs`,
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
group: `page`,
|
||||||
|
navSelector: `nav.page`,
|
||||||
|
contentSelector: `.page-content`,
|
||||||
|
initial: `inventory`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: `inventory`,
|
||||||
|
navSelector: `nav.inventory`,
|
||||||
|
contentSelector: `.tab[data-tab="inventory"]`,
|
||||||
|
initial: `player`,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
opts.classes.push(`style-v3`);
|
||||||
|
return opts;
|
||||||
|
};
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
if (this.document.isEmbedded) return;
|
||||||
|
if (!this.isEditable) return;
|
||||||
|
console.debug(`.dungeon | Adding event listeners for Actor: ${this.id}`);
|
||||||
|
|
||||||
|
html.find(`.create-ae`).on(`click`, async ($e) => {
|
||||||
|
console.debug(`Creating an ActiveEffect?`);
|
||||||
|
const ae = this.actor.createEmbeddedDocuments(`ActiveEffect`, [{name: "Default AE"}]);
|
||||||
|
ae.sheet.render(true);
|
||||||
|
});
|
||||||
|
html.find(`[data-filter-toggle]`).on(`change`, ($e) => {
|
||||||
|
const target = $e.delegateTarget;
|
||||||
|
const filter = target.dataset.filterToggle;
|
||||||
|
this.toggleItemFilter(filter);
|
||||||
|
this._renderInner();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Make materials be able to be edited/deleted
|
||||||
|
new GenericContextMenu(html, `.material`, [
|
||||||
|
{
|
||||||
|
name: localizer(`dotdungeon.common.edit`),
|
||||||
|
callback: (html) => {
|
||||||
|
const data = html[0].dataset;
|
||||||
|
this.openEmbeddedSheet.bind(this)(data.embeddedId);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: localizer(`dotdungeon.common.delete`),
|
||||||
|
callback: (html) => {
|
||||||
|
const data = html[0].dataset;
|
||||||
|
this.genericEmbeddedDelete.bind(this)(data.embeddedId);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const ctx = await super.getData();
|
||||||
|
/** @type {ActorHandler} */
|
||||||
|
const actor = this.actor;
|
||||||
|
|
||||||
|
ctx.preAE = actor.preAE;
|
||||||
|
ctx.system = actor.system;
|
||||||
|
ctx.flags = actor.flags;
|
||||||
|
ctx.items = this.actor.itemTypes;
|
||||||
|
|
||||||
|
ctx.computed = {
|
||||||
|
canChangeGroup: ctx.settings.playersCanChangeGroup || ctx.isGM,
|
||||||
|
canAddAspect: !this.actor.atAspectLimit,
|
||||||
|
stats: this.#statData,
|
||||||
|
itemFilters: this.#itemFilters,
|
||||||
|
noItemTypesVisible: this._itemTypesHidden.size === DOTDUNGEON.itemFilters.length,
|
||||||
|
capacity: this.#inventoryCapacity,
|
||||||
|
};
|
||||||
|
console.log(ctx)
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
get #statData() {
|
||||||
|
const stats = [];
|
||||||
|
const usedDice = new Set(Object.values(this.actor.system.stats));
|
||||||
|
for (const statName in this.actor.system.stats) {
|
||||||
|
const stat = {
|
||||||
|
key: statName,
|
||||||
|
name: localizer(`dotdungeon.stat.${statName}`),
|
||||||
|
original: this.actor.preAE.stats[statName],
|
||||||
|
value: this.actor.system.stats[statName],
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Determine what dice are available to the user in the dropdown
|
||||||
|
selector. Disables all dice options that are selected, but not used
|
||||||
|
by this stat.
|
||||||
|
*/
|
||||||
|
stat.dieOptions = [
|
||||||
|
{ label: `---`, value: `` },
|
||||||
|
...DOTDUNGEON.statDice.map(die => {
|
||||||
|
return {
|
||||||
|
value: die,
|
||||||
|
label: localizer(`dotdungeon.die.${die}`, { stat: statName }),
|
||||||
|
disabled: usedDice.has(die) && this.actor.preAE.stats[statName] !== die,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculating the data needed in order to display all of the skills
|
||||||
|
for this character.
|
||||||
|
*/
|
||||||
|
stat.skills = [];
|
||||||
|
for (const skill in this.actor.system.skills[statName]) {
|
||||||
|
const value = this.actor.system.skills[statName][skill];
|
||||||
|
stat.skills.push({
|
||||||
|
key: skill,
|
||||||
|
name: game.i18n.format(`dotdungeon.skills.${skill}`),
|
||||||
|
value,
|
||||||
|
original: this.actor.preAE.skills[statName][skill],
|
||||||
|
formula: `1` + stat.value + modifierToString(value, { spaces: true }),
|
||||||
|
rollDisabled: this.actor.preAE.skills[statName][skill] === -1,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
stats.push(stat);
|
||||||
|
};
|
||||||
|
return stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
_itemTypesHidden = new Set([`armour`, `equipment`, `structure`, `service`]);
|
||||||
|
toggleItemFilter(filterName) {
|
||||||
|
if (this._itemTypesHidden.has(filterName)) {
|
||||||
|
this._itemTypesHidden.delete(filterName);
|
||||||
|
} else {
|
||||||
|
this._itemTypesHidden.add(filterName);
|
||||||
|
};
|
||||||
|
this.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
get #itemFilters() {
|
||||||
|
const types = DOTDUNGEON.itemFilters;
|
||||||
|
const filters = {};
|
||||||
|
for (const type of types) {
|
||||||
|
filters[type] = {
|
||||||
|
label: localizer(`TYPES.Item.${type}`),
|
||||||
|
active: !this._itemTypesHidden.has(type),
|
||||||
|
createLabel: localizer(`dotdungeon.sheet.actor.v2.create-item`, {type}),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return filters;
|
||||||
|
};
|
||||||
|
|
||||||
|
get #inventoryCapacity() {
|
||||||
|
return {
|
||||||
|
used: this.actor.items
|
||||||
|
.reduce((sum, i) => sum + i.usedCapacity, 0),
|
||||||
|
max: this.actor.system.inventory_slots,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
31
module/sheets/Datasheets/GroupDataSheet.mjs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
export class GroupDataSheet extends ActorSheet {
|
||||||
|
static get defaultOptions() {
|
||||||
|
let opts = foundry.utils.mergeObject(
|
||||||
|
super.defaultOptions,
|
||||||
|
{
|
||||||
|
template: `systems/dotdungeon/templates/datasheets/actor/group.hbs`,
|
||||||
|
width: 200,
|
||||||
|
height: 275
|
||||||
|
},
|
||||||
|
);
|
||||||
|
opts.classes.push(`dotdungeon`, `style-v3`);
|
||||||
|
return opts;
|
||||||
|
};
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const ctx = {};
|
||||||
|
|
||||||
|
ctx.actor = this.actor;
|
||||||
|
ctx.system = this.actor.system;
|
||||||
|
|
||||||
|
ctx.computed = {
|
||||||
|
milestones_hit_viewable: [...this.actor.system.milestones_hit.values()].join(`, `)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.meta = {
|
||||||
|
idp: this.actor.uuid,
|
||||||
|
};
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
|
};
|
||||||
27
module/sheets/Datasheets/UntypedDataSheet.mjs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
export class UntypedDataSheet extends ItemSheet {
|
||||||
|
static get defaultOptions() {
|
||||||
|
let opts = foundry.utils.mergeObject(
|
||||||
|
super.defaultOptions,
|
||||||
|
{
|
||||||
|
template: `systems/dotdungeon/templates/datasheets/untyped.hbs`,
|
||||||
|
width: 650,
|
||||||
|
height: 700
|
||||||
|
},
|
||||||
|
);
|
||||||
|
opts.classes.push(`dotdungeon`, `style-v3`);
|
||||||
|
return opts;
|
||||||
|
};
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const ctx = {};
|
||||||
|
|
||||||
|
ctx.item = this.item;
|
||||||
|
ctx.system = this.item.system;
|
||||||
|
|
||||||
|
ctx.meta = {
|
||||||
|
idp: this.item.uuid,
|
||||||
|
};
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1,6 +1,18 @@
|
||||||
|
import { localizer } from "../utils/localizer.mjs";
|
||||||
import DOTDUNGEON from "../config.mjs";
|
import DOTDUNGEON from "../config.mjs";
|
||||||
|
|
||||||
export class GenericActorSheet extends ActorSheet {
|
export class GenericActorSheet extends ActorSheet {
|
||||||
|
static get defaultOptions() {
|
||||||
|
let opts = foundry.utils.mergeObject(
|
||||||
|
super.defaultOptions,
|
||||||
|
{
|
||||||
|
scrollY: [`.scrollable`],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
opts.classes.push(`dotdungeon`);
|
||||||
|
return opts;
|
||||||
|
};
|
||||||
|
|
||||||
_expanded = new Set();
|
_expanded = new Set();
|
||||||
|
|
||||||
#propogatedSettings = [
|
#propogatedSettings = [
|
||||||
|
|
@ -28,7 +40,7 @@ export class GenericActorSheet extends ActorSheet {
|
||||||
|
|
||||||
ctx.actor = this.actor;
|
ctx.actor = this.actor;
|
||||||
ctx.config = DOTDUNGEON;
|
ctx.config = DOTDUNGEON;
|
||||||
ctx.icons = CONFIG.CACHE.icons;
|
ctx.icons = {};
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
|
|
@ -40,18 +52,45 @@ export class GenericActorSheet extends ActorSheet {
|
||||||
if (!this.isEditable) return;
|
if (!this.isEditable) return;
|
||||||
console.debug(`.dungeon | Generic sheet adding listeners`);
|
console.debug(`.dungeon | Generic sheet adding listeners`);
|
||||||
|
|
||||||
html.find(`summary`).on(`click`, this._handleSummaryToggle.bind(this));
|
/*
|
||||||
|
Custom element event listeners because Foundry doesn't listen to them by
|
||||||
|
default.
|
||||||
|
*/
|
||||||
|
html.find(
|
||||||
|
CONFIG.CACHE.componentListeners.map(n => `${n}[name]`).join(`,`)
|
||||||
|
).on(`change`, () => this._onChangeInput.bind(this));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Utility event listeners that apply
|
||||||
|
*/
|
||||||
|
html.find(`[data-collapse-id]`).on(`click`, this._handleSummaryToggle.bind(this));
|
||||||
html.find(`[data-roll-formula]`).on(`click`, this._handleRoll.bind(this));
|
html.find(`[data-roll-formula]`).on(`click`, this._handleRoll.bind(this));
|
||||||
html.find(`[data-embedded-update]`)
|
html.find(`[data-embedded-update-on="change"]`)
|
||||||
.on(`change`, this.actor.genericEmbeddedUpdate.bind(this.actor));
|
.on(`change`, this.genericEmbeddedUpdate.bind(this));
|
||||||
|
html.find(`[data-embedded-update-on="blur"]`)
|
||||||
|
.on(`blur`, this.genericEmbeddedUpdate.bind(this));
|
||||||
html.find(`[data-embedded-delete]`)
|
html.find(`[data-embedded-delete]`)
|
||||||
.on(`click`, this.actor.genericEmbeddedDelete.bind(this.actor));
|
.on(`click`, ($e) => {
|
||||||
|
const id = $e.currentTarget.dataset.embeddedDelete;
|
||||||
|
this.genericEmbeddedDelete.bind(this)(id);
|
||||||
|
});
|
||||||
html.find(`[data-embedded-create]`)
|
html.find(`[data-embedded-create]`)
|
||||||
.on(`click`, this.actor.genericEmbeddedCreate.bind(this.actor));
|
.on(`click`, this.genericEmbeddedCreate.bind(this));
|
||||||
html.find(`[data-message-type]`)
|
html.find(`[data-message-type]`)
|
||||||
.on(`click`, this.actor.genericSendToChat.bind(this.actor));
|
.on(`click`, this.genericSendToChat.bind(this));
|
||||||
html.find(`[data-embedded-edit]`)
|
html.find(`[data-embedded-edit]`)
|
||||||
.on(`click`, this.actor.openEmbeddedSheet.bind(this.actor));
|
.on(`click`, ($e) => {
|
||||||
|
const id = $e.currentTarget.dataset.embeddedEdit;
|
||||||
|
this.openEmbeddedSheet.bind(this)(id);
|
||||||
|
})
|
||||||
|
html.find(`button[data-increment]`)
|
||||||
|
.on(`click`, this._incrementValue.bind(this));
|
||||||
|
html.find(`button[data-decrement]`)
|
||||||
|
.on(`click`, this._decrementValue.bind(this));
|
||||||
|
html.find(`button[data-embedded-increment]`)
|
||||||
|
.on(`click`, this.genericEmbeddedIncrement.bind(this));
|
||||||
|
html.find(`button[data-embedded-decrement]`)
|
||||||
|
.on(`click`, this.genericEmbeddedDecrement.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
async _handleRoll($e) {
|
async _handleRoll($e) {
|
||||||
|
|
@ -71,21 +110,139 @@ export class GenericActorSheet extends ActorSheet {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleSummaryToggle($e) {
|
async _incrementValue($e) {
|
||||||
let data = $e.currentTarget.dataset;
|
const target = $e.currentTarget;
|
||||||
let open = $e.currentTarget.parentNode.open;
|
const data = target.dataset;
|
||||||
console.debug(`.dungeon | Collapse ID: ${data.collapseId} (open: ${open})`);
|
const value = getProperty(this.actor, data.increment);
|
||||||
|
if (typeof value != "number") {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
this.actor.update({ [data.increment]: value + 1 });
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
async _decrementValue($e) {
|
||||||
This seeming inversion of logic is due to the fact that this handler
|
const target = $e.currentTarget;
|
||||||
gets called before the element is updated to include/reflect the
|
const data = target.dataset;
|
||||||
change, so if the parentNode doesn't actually have it, then we're
|
const value = getProperty(this.actor, data.decrement);
|
||||||
opening it and vice-versa.
|
if (typeof value != "number") {
|
||||||
*/
|
return;
|
||||||
if (!open) {
|
};
|
||||||
|
this.actor.update({ [data.decrement]: value - 1 });
|
||||||
|
};
|
||||||
|
|
||||||
|
async _handleSummaryToggle($e) {
|
||||||
|
$e.stopPropagation();
|
||||||
|
let target = $e.currentTarget;
|
||||||
|
let parent = target.closest(`.collapse`);
|
||||||
|
let data = target.dataset;
|
||||||
|
console.debug(`.dungeon | Collapse ID: ${data.collapseId}`);
|
||||||
|
|
||||||
|
if (!this._expanded.has(data.collapseId)) {
|
||||||
this._expanded.add(data.collapseId);
|
this._expanded.add(data.collapseId);
|
||||||
|
parent.setAttribute(`open`, ``);
|
||||||
} else {
|
} else {
|
||||||
this._expanded.delete(data.collapseId);
|
this._expanded.delete(data.collapseId);
|
||||||
|
parent.removeAttribute(`open`, ``);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async openEmbeddedSheet(item_id) {
|
||||||
|
let item = await fromUuid(item_id);
|
||||||
|
item?.sheet.render(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
async genericEmbeddedCreate($event) {
|
||||||
|
const data = $event.currentTarget.dataset;
|
||||||
|
if (!this[`createCustom${data.embeddedCreate}`]) {
|
||||||
|
this.actor.createEmbeddedItem({
|
||||||
|
type: data.embeddedCreate,
|
||||||
|
name: localizer(
|
||||||
|
`dotdungeon.default.name`,
|
||||||
|
{ document: `Item`, type: data.embeddedCreate }
|
||||||
|
),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this[`createCustom${data.embeddedCreate}`]($event);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
async genericEmbeddedUpdate($event) {
|
||||||
|
const target = $event.currentTarget;
|
||||||
|
const data = target.dataset;
|
||||||
|
const item = await fromUuid(data.embeddedId);
|
||||||
|
|
||||||
|
let value = target.value;
|
||||||
|
switch (target.type) {
|
||||||
|
case "checkbox": value = target.checked; break;
|
||||||
|
};
|
||||||
|
|
||||||
|
await item?.update({ [data.embeddedUpdate]: value });
|
||||||
|
};
|
||||||
|
|
||||||
|
async genericEmbeddedIncrement($event) {
|
||||||
|
const target = $event.currentTarget;
|
||||||
|
const data = target.dataset;
|
||||||
|
const item = await fromUuid(data.embeddedId);
|
||||||
|
const value = getProperty(item, data.embeddedIncrement);
|
||||||
|
if (typeof value != "number") {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
await item?.update({ [data.embeddedIncrement]: value + 1 });
|
||||||
|
};
|
||||||
|
|
||||||
|
async genericEmbeddedDecrement($event) {
|
||||||
|
const target = $event.currentTarget;
|
||||||
|
const data = target.dataset;
|
||||||
|
const item = await fromUuid(data.embeddedId);
|
||||||
|
const value = getProperty(item, data.embeddedDecrement);
|
||||||
|
if (typeof value != "number") {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
await item?.update({ [data.embeddedDecrement]: value - 1 });
|
||||||
|
};
|
||||||
|
|
||||||
|
async genericEmbeddedDelete(item_uuid) {
|
||||||
|
let item = await fromUuid(item_uuid);
|
||||||
|
|
||||||
|
if (!item) {
|
||||||
|
ui.notifications.error(
|
||||||
|
`dotdungeon.notification.error.item-not-found`,
|
||||||
|
{ console: false }
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
Dialog.confirm({
|
||||||
|
title: game.i18n.format(
|
||||||
|
`dotdungeon.dialogs.${item.type}.delete.title`,
|
||||||
|
item
|
||||||
|
),
|
||||||
|
content: game.i18n.format(
|
||||||
|
`dotdungeon.dialogs.${item.type}.delete.content`,
|
||||||
|
item
|
||||||
|
),
|
||||||
|
yes: () => {
|
||||||
|
item.delete();
|
||||||
|
},
|
||||||
|
defaultYes: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async genericSendToChat($event) {
|
||||||
|
const data = $event.currentTarget.dataset;
|
||||||
|
const type = data.messageType;
|
||||||
|
if (this[`send${type}ToChat`]) {
|
||||||
|
return await this[`send${type}ToChat`]($event);
|
||||||
|
};
|
||||||
|
if (!data.messageContent) {
|
||||||
|
console.warn(`.dungeon | Tried to send a chat message with no content`);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let message = await ChatMessage.create({
|
||||||
|
content: data.messageContent,
|
||||||
|
flavor: data.messageFlavor,
|
||||||
|
speaker: { actor: this.actor },
|
||||||
|
});
|
||||||
|
message.render();
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
import DOTDUNGEON from "../config.mjs";
|
|
||||||
|
|
||||||
export class GenericItemSheet extends ItemSheet {
|
|
||||||
_expanded = new Set();
|
|
||||||
|
|
||||||
#propogatedSettings = [
|
|
||||||
`devMode`,
|
|
||||||
`showAvatarOnSheet`,
|
|
||||||
`playersCanChangeGroup`,
|
|
||||||
`resourcesOrSupplies`,
|
|
||||||
];
|
|
||||||
|
|
||||||
activateListeners(html) {
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
if (!this.isEditable) return;
|
|
||||||
console.debug(`.dungeon | Adding event listeners for Generic Item: ${this.id}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
async getData() {
|
|
||||||
const ctx = {};
|
|
||||||
|
|
||||||
// Send all of the settings that sheets need into their context
|
|
||||||
ctx.settings = {};
|
|
||||||
for (const setting of this.#propogatedSettings) {
|
|
||||||
ctx.settings[setting] = game.settings.get(`dotdungeon`, setting);
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.isGM = game.users.current.hasRole(CONST.USER_ROLES.ASSISTANT);
|
|
||||||
|
|
||||||
ctx.meta = {
|
|
||||||
expanded: this._expanded,
|
|
||||||
idp: this.item.uuid,
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.config = DOTDUNGEON;
|
|
||||||
ctx.icons = CONFIG.CACHE.icons;
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { GenericItemSheet } from "./GenericItemSheet.mjs";
|
||||||
|
|
||||||
export class AspectSheet extends GenericItemSheet {
|
export class AspectSheet extends GenericItemSheet {
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
let opts = mergeObject(
|
let opts = foundry.utils.mergeObject(
|
||||||
super.defaultOptions,
|
super.defaultOptions,
|
||||||
{
|
{
|
||||||
template: `systems/dotdungeon/templates/items/aspect.hbs`,
|
template: `systems/dotdungeon/templates/items/aspect.hbs`,
|
||||||
|
|
@ -22,14 +22,7 @@ export class AspectSheet extends GenericItemSheet {
|
||||||
};
|
};
|
||||||
|
|
||||||
async getData() {
|
async getData() {
|
||||||
const ctx = {};
|
const ctx = await super.getData();
|
||||||
const item = this.item;
|
|
||||||
|
|
||||||
ctx.item = item;
|
|
||||||
ctx.system = item.system;
|
|
||||||
ctx.flags = item.flags;
|
|
||||||
|
|
||||||
console.log(item.uuid, `context:`, ctx);
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
86
module/sheets/Items/GenericItemSheet.mjs
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
import { DialogManager } from "../../utils/DialogManager.mjs";
|
||||||
|
import DOTDUNGEON from "../../config.mjs";
|
||||||
|
|
||||||
|
export class GenericItemSheet extends ItemSheet {
|
||||||
|
_expanded = new Set();
|
||||||
|
|
||||||
|
#propogatedSettings = [
|
||||||
|
`devMode`,
|
||||||
|
`showAvatarOnSheet`,
|
||||||
|
`playersCanChangeGroup`,
|
||||||
|
`resourcesOrSupplies`,
|
||||||
|
];
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const ctx = {};
|
||||||
|
|
||||||
|
// Send all of the settings that sheets need into their context
|
||||||
|
ctx.settings = {};
|
||||||
|
for (const setting of this.#propogatedSettings) {
|
||||||
|
ctx.settings[setting] = game.settings.get(`dotdungeon`, setting);
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.isGM = game.users.current.hasRole(CONST.USER_ROLES.ASSISTANT);
|
||||||
|
|
||||||
|
ctx.meta = {
|
||||||
|
expanded: this._expanded,
|
||||||
|
idp: this.item.uuid,
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.item = this.item;
|
||||||
|
ctx.system = this.item.system;
|
||||||
|
ctx.flags = this.item.flags;
|
||||||
|
ctx.effects = this.item.effects;
|
||||||
|
|
||||||
|
ctx.config = DOTDUNGEON;
|
||||||
|
ctx.icons = {};
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
if (!this.isEditable) return;
|
||||||
|
console.debug(`.dungeon | Adding event listeners for Generic Item: ${this.id}`);
|
||||||
|
html.find(`button[data-increment]`)
|
||||||
|
.on(`click`, this._incrementValue.bind(this));
|
||||||
|
html.find(`button[data-decrement]`)
|
||||||
|
.on(`click`, this._decrementValue.bind(this));
|
||||||
|
|
||||||
|
|
||||||
|
html.find(`[data-help-id]`)
|
||||||
|
.on(`click`, this._helpPopup.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
async _incrementValue($e) {
|
||||||
|
const target = $e.currentTarget;
|
||||||
|
const data = target.dataset;
|
||||||
|
const value = getProperty(this.actor, data.increment);
|
||||||
|
if (typeof value != "number") {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
this.actor.update({ [data.increment]: value + 1 });
|
||||||
|
};
|
||||||
|
|
||||||
|
async _decrementValue($e) {
|
||||||
|
const target = $e.currentTarget;
|
||||||
|
const data = target.dataset;
|
||||||
|
const value = getProperty(this.actor, data.decrement);
|
||||||
|
if (typeof value != "number") {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
this.actor.update({ [data.decrement]: value - 1 });
|
||||||
|
};
|
||||||
|
|
||||||
|
async _helpPopup($e) {
|
||||||
|
const target = $e.currentTarget;
|
||||||
|
const data = target.dataset;
|
||||||
|
if (!data.helpId) return;
|
||||||
|
DialogManager.helpDialog(
|
||||||
|
data.helpId,
|
||||||
|
data.helpContent,
|
||||||
|
data.helpTitle
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -2,7 +2,7 @@ import { GenericItemSheet } from "./GenericItemSheet.mjs";
|
||||||
|
|
||||||
export class PetSheet extends GenericItemSheet {
|
export class PetSheet extends GenericItemSheet {
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
let opts = mergeObject(
|
let opts = foundry.utils.mergeObject(
|
||||||
super.defaultOptions,
|
super.defaultOptions,
|
||||||
{
|
{
|
||||||
template: `systems/dotdungeon/templates/items/pet.hbs`,
|
template: `systems/dotdungeon/templates/items/pet.hbs`,
|
||||||
|
|
@ -23,10 +23,6 @@ export class PetSheet extends GenericItemSheet {
|
||||||
|
|
||||||
async getData() {
|
async getData() {
|
||||||
const ctx = await super.getData();
|
const ctx = await super.getData();
|
||||||
|
|
||||||
ctx.item = this.item;
|
|
||||||
ctx.system = this.item.system;
|
|
||||||
ctx.flags = this.item.flags;
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -2,7 +2,7 @@ import { GenericItemSheet } from "./GenericItemSheet.mjs";
|
||||||
|
|
||||||
export class SpellSheet extends GenericItemSheet {
|
export class SpellSheet extends GenericItemSheet {
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
let opts = mergeObject(
|
let opts = foundry.utils.mergeObject(
|
||||||
super.defaultOptions,
|
super.defaultOptions,
|
||||||
{
|
{
|
||||||
template: `systems/dotdungeon/templates/items/spell.hbs`,
|
template: `systems/dotdungeon/templates/items/spell.hbs`,
|
||||||
|
|
@ -23,10 +23,6 @@ export class SpellSheet extends GenericItemSheet {
|
||||||
|
|
||||||
async getData() {
|
async getData() {
|
||||||
const ctx = await super.getData();
|
const ctx = await super.getData();
|
||||||
|
|
||||||
ctx.item = this.item;
|
|
||||||
ctx.system = this.item.system;
|
|
||||||
ctx.flags = this.item.flags;
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
116
module/sheets/Items/UntypedItemSheet.mjs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
import { GenericContextMenu } from "../../utils/GenericContextMenu.mjs";
|
||||||
|
import { DialogManager } from "../../utils/DialogManager.mjs";
|
||||||
|
import { GenericItemSheet } from "./GenericItemSheet.mjs";
|
||||||
|
import { localizer } from "../../utils/localizer.mjs";
|
||||||
|
|
||||||
|
export class UntypedItemSheet extends GenericItemSheet {
|
||||||
|
static get defaultOptions() {
|
||||||
|
let opts = foundry.utils.mergeObject(
|
||||||
|
super.defaultOptions,
|
||||||
|
{
|
||||||
|
template: `systems/dotdungeon/templates/items/untyped/v2/index.hbs`,
|
||||||
|
width: 300,
|
||||||
|
height: 340,
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
group: `page`,
|
||||||
|
navSelector: `nav.page`,
|
||||||
|
contentSelector: `.page-content`,
|
||||||
|
initial: `general`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
opts.classes.push(`dotdungeon`, `style-v3`);
|
||||||
|
return opts;
|
||||||
|
};
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
new GenericContextMenu(html, `.photo.panel`, [
|
||||||
|
{
|
||||||
|
name: localizer(`dotdungeon.common.view-larger`),
|
||||||
|
callback: () => {
|
||||||
|
(new ImagePopout(this.item.img)).render(true);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: localizer(`dotdungeon.common.edit`),
|
||||||
|
condition: () => this.isEditable,
|
||||||
|
callback: () => {
|
||||||
|
const fp = new FilePicker({
|
||||||
|
callback: (path) => {
|
||||||
|
this.item.update({"img": path});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
fp.render(true);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: localizer(`dotdungeon.common.reset`),
|
||||||
|
condition: () => this.isEditable,
|
||||||
|
callback: () => {
|
||||||
|
console.log(`.dungeon | Reset Item Image`)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!this.isEditable) return;
|
||||||
|
console.debug(`.dungeon | Adding event listeners for Untyped Item: ${this.item.id}`);
|
||||||
|
|
||||||
|
html.find(`.create-ae`).on(`click`, async () => {
|
||||||
|
await this.item.createEmbeddedDocuments(
|
||||||
|
`ActiveEffect`,
|
||||||
|
[{name: localizer(`dotdungeon.default.name`, { document: `ActiveEffect`, type: `base` })}],
|
||||||
|
{ renderSheet: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
new GenericContextMenu(html, `.effect.panel`, [
|
||||||
|
{
|
||||||
|
name: localizer(`dotdungeon.common.edit`),
|
||||||
|
callback: async (html) => {
|
||||||
|
(await fromUuid(html.closest(`.effect`)[0].dataset.embeddedId))?.sheet.render(true);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: localizer(`dotdungeon.common.delete`),
|
||||||
|
callback: async (html) => {
|
||||||
|
const target = html.closest(`.effect`)[0];
|
||||||
|
const data = target.dataset;
|
||||||
|
const id = data.embeddedId;
|
||||||
|
const doc = await fromUuid(id);
|
||||||
|
DialogManager.createOrFocus(
|
||||||
|
`${doc.uuid}-delete`,
|
||||||
|
{
|
||||||
|
title: localizer(`dotdungeon.delete.ActiveEffect.title`, doc),
|
||||||
|
content: localizer(`dotdungeon.delete.ActiveEffect.content`, doc),
|
||||||
|
buttons: {
|
||||||
|
yes: {
|
||||||
|
label: localizer(`Yes`),
|
||||||
|
callback() {
|
||||||
|
doc.delete();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
no: {
|
||||||
|
label: localizer(`No`),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
async getData() {
|
||||||
|
const ctx = await super.getData();
|
||||||
|
|
||||||
|
ctx.meta.showSettingsTab = ctx.isGM || this.item.isOwned;
|
||||||
|
ctx.meta.isEmbedded = this.item.isOwned;
|
||||||
|
ctx.meta.isEditable = this.isEditable;
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
import { ActorHandler } from "../documents/Actor/Handler.mjs";
|
|
||||||
import { GenericActorSheet } from "./GenericActorSheet.mjs";
|
import { GenericActorSheet } from "./GenericActorSheet.mjs";
|
||||||
|
|
||||||
export class PlayerSheet extends GenericActorSheet {
|
export class MVPPCSheet extends GenericActorSheet {
|
||||||
|
|
||||||
/** @override {ActorHandler} actor */
|
/** @override {ActorHandler} actor */
|
||||||
|
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
let opts = mergeObject(
|
let opts = foundry.utils.mergeObject(
|
||||||
super.defaultOptions,
|
super.defaultOptions,
|
||||||
{
|
{
|
||||||
template: `systems/dotdungeon/templates/actors/char-sheet-mvp/sheet.hbs`
|
template: `systems/dotdungeon/templates/actors/char-sheet-mvp/sheet.hbs`
|
||||||
|
|
@ -35,10 +34,9 @@ export class PlayerSheet extends GenericActorSheet {
|
||||||
|
|
||||||
ctx.computed = {
|
ctx.computed = {
|
||||||
canChangeGroup: ctx.settings.playersCanChangeGroup || ctx.isGM,
|
canChangeGroup: ctx.settings.playersCanChangeGroup || ctx.isGM,
|
||||||
canAddAspect: !await actor.proxyFunction.bind(actor)(`atAspectLimit`),
|
canAddAspect: !this.actor.atAspectLimit,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(actor.uuid, `context:`, ctx)
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import { ActorHandler } from "../documents/Actor/Handler.mjs";
|
|
||||||
import { GenericActorSheet } from "./GenericActorSheet.mjs";
|
import { GenericActorSheet } from "./GenericActorSheet.mjs";
|
||||||
import { DiceList } from "../dialogs/DiceList.mjs";
|
import { DiceList } from "../dialogs/DiceList.mjs";
|
||||||
|
|
||||||
export class MobSheet extends GenericActorSheet {
|
export class MobSheet extends GenericActorSheet {
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
let opts = mergeObject(
|
let opts = foundry.utils.mergeObject(
|
||||||
super.defaultOptions,
|
super.defaultOptions,
|
||||||
{
|
{
|
||||||
template: `systems/dotdungeon/templates/actors/mobs/main.hbs`,
|
template: `systems/dotdungeon/templates/actors/mobs/main.hbs`,
|
||||||
|
|
@ -43,7 +42,6 @@ export class MobSheet extends GenericActorSheet {
|
||||||
|
|
||||||
// Compute rolls here
|
// Compute rolls here
|
||||||
|
|
||||||
console.log(actor.uuid, `context:`, ctx)
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -2,11 +2,11 @@ import { GenericActorSheet } from "../GenericActorSheet.mjs";
|
||||||
|
|
||||||
export class AbstractSyncSheet extends GenericActorSheet {
|
export class AbstractSyncSheet extends GenericActorSheet {
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
let opts = mergeObject(
|
let opts = foundry.utils.mergeObject(
|
||||||
super.defaultOptions,
|
super.defaultOptions,
|
||||||
{
|
{
|
||||||
width: 200,
|
width: 200,
|
||||||
height: 200,
|
height: 275,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
opts.classes.push(
|
opts.classes.push(
|
||||||
|
|
@ -22,11 +22,12 @@ export class AbstractSyncSheet extends GenericActorSheet {
|
||||||
|
|
||||||
ctx.system = actor.system;
|
ctx.system = actor.system;
|
||||||
ctx.flags = actor.flags;
|
ctx.flags = actor.flags;
|
||||||
|
|
||||||
console.groupCollapsed(`SyncSheet.getData`);
|
|
||||||
console.log(`ctx`, ctx);
|
|
||||||
console.log(`actor`, actor);
|
|
||||||
console.groupEnd();
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
html.find(`.use-rest-die`)
|
||||||
|
.on(`click`, this.actor.useRestDie.bind(this.actor));
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
export function reloadWindows(type = null) {
|
|
||||||
if (!type) {
|
|
||||||
for (const window of globalThis.ui.windows) {
|
|
||||||
window.render(true);
|
|
||||||
};
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
for (const window of globalThis.ui.windows) {
|
|
||||||
if (window instanceof type) {
|
|
||||||
window.render(true);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
83
module/utils/DialogManager.mjs
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { localizer } from "./localizer.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility class that allows managing Dialogs that are created for various
|
||||||
|
* purposes such as deleting items, help popups, etc. This is a singleton class
|
||||||
|
* that upon instantiating after the first time will just return the first instance
|
||||||
|
*/
|
||||||
|
export class DialogManager {
|
||||||
|
|
||||||
|
/** @type {Map<string, Dialog>} */
|
||||||
|
static #dialogs = new Map();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Focuses a dialog if it already exists, or creates a new one and renders it.
|
||||||
|
*
|
||||||
|
* @param {string} dialogId The ID to associate with the dialog, should be unique
|
||||||
|
* @param {object} data The data to pass to the Dialog constructor
|
||||||
|
* @param {DialogOptions} opts The options to pass to the Dialog constructor
|
||||||
|
* @returns {Dialog} The Dialog instance
|
||||||
|
*/
|
||||||
|
static async createOrFocus(dialogId, data, opts = {}) {
|
||||||
|
if (DialogManager.#dialogs.has(dialogId)) {
|
||||||
|
const dialog = DialogManager.#dialogs.get(dialogId);
|
||||||
|
dialog.bringToTop();
|
||||||
|
return dialog;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
This makes sure that if I provide a close function as a part of the data,
|
||||||
|
that the dialog still gets removed from the set once it's closed, otherwise
|
||||||
|
it could lead to dangling references that I don't care to keep. Or if I don't
|
||||||
|
provide the close function, it just sets the function as there isn't anything
|
||||||
|
extra that's needed to be called.
|
||||||
|
*/
|
||||||
|
if (data?.close) {
|
||||||
|
const provided = data.close;
|
||||||
|
data.close = () => {
|
||||||
|
DialogManager.#dialogs.delete(dialogId);
|
||||||
|
provided();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data.close = () => DialogManager.#dialogs.delete(dialogId);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create the Dialog with the modified data
|
||||||
|
const dialog = new Dialog(data, opts);
|
||||||
|
DialogManager.#dialogs.set(dialogId, dialog);
|
||||||
|
dialog.render(true);
|
||||||
|
return dialog;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes a dialog if it is rendered
|
||||||
|
*
|
||||||
|
* @param {string} dialogId The ID of the dialog to close
|
||||||
|
*/
|
||||||
|
static async close(dialogId) {
|
||||||
|
const dialog = DialogManager.#dialogs.get(dialogId);
|
||||||
|
dialog?.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
static async helpDialog(
|
||||||
|
helpId,
|
||||||
|
helpContent,
|
||||||
|
helpTitle = `dotdungeon.common.help`,
|
||||||
|
localizationData = {},
|
||||||
|
) {
|
||||||
|
DialogManager.createOrFocus(
|
||||||
|
helpId,
|
||||||
|
{
|
||||||
|
title: localizer(helpTitle, localizationData),
|
||||||
|
content: localizer(helpContent, localizationData),
|
||||||
|
buttons: {},
|
||||||
|
},
|
||||||
|
{ resizable: true, }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
static get size() {
|
||||||
|
return DialogManager.#dialogs.size;
|
||||||
|
}
|
||||||
|
};
|
||||||
6
module/utils/GenericContextMenu.mjs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
export class GenericContextMenu extends ContextMenu {
|
||||||
|
constructor(element, selector, menuItems, opts = {}) {
|
||||||
|
super(element, selector, menuItems, opts);
|
||||||
|
this.menuItems.forEach(i => i.icon ??= ``);
|
||||||
|
};
|
||||||
|
};
|
||||||
37
module/utils/localizer.mjs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { localizerConfig } from "../config.mjs";
|
||||||
|
|
||||||
|
export function handlebarsLocalizer(key, ...args) {
|
||||||
|
let data = args[0]
|
||||||
|
if (args.length === 1) data = args[0].hash;
|
||||||
|
if (key instanceof Handlebars.SafeString) key = key.toString();
|
||||||
|
const localized = localizer(key, data);
|
||||||
|
return localized;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function localizer(key, args = {}, depth = 0) {
|
||||||
|
/** @type {string} */
|
||||||
|
let localized = game.i18n.format(key, args);
|
||||||
|
const subkeys = localized.matchAll(localizerConfig.subKeyPattern);
|
||||||
|
|
||||||
|
// Short-cut to help prevent infinite recursion
|
||||||
|
if (depth > localizerConfig.maxDepth) {
|
||||||
|
return localized;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Helps prevent recursion on the same key so that we aren't doing excess work.
|
||||||
|
*/
|
||||||
|
const localizedSubkeys = new Map();
|
||||||
|
for (const match of subkeys) {
|
||||||
|
const subkey = match.groups.key;
|
||||||
|
if (localizedSubkeys.has(subkey)) continue;
|
||||||
|
localizedSubkeys.set(subkey, localizer(subkey, args, depth + 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
return localized.replace(
|
||||||
|
localizerConfig.subKeyPattern,
|
||||||
|
(_fullMatch, subkey) => {
|
||||||
|
return localizedSubkeys.get(subkey);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
18
module/utils/modifierToString.mjs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
* Takes in an integer and converts it into a string format that can be used in
|
||||||
|
* roll formulas or for displaying to the user.
|
||||||
|
*
|
||||||
|
* @param {number} mod The modifier to stringify
|
||||||
|
* @param {object} opts
|
||||||
|
* @param {boolean} opts.spaces Puts spaces on either side of the operand
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export function modifierToString(mod, opts = {}) {
|
||||||
|
if (mod == 0) return ``;
|
||||||
|
|
||||||
|
let value = [``, `+`, mod]
|
||||||
|
if (mod < 0) {
|
||||||
|
value = [``, `-`, Math.abs(mod)]
|
||||||
|
};
|
||||||
|
return value.join(opts.spaces ? ` ` : ``);
|
||||||
|
};
|
||||||
80
new-pc-sheet.md
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
## Tabs:
|
||||||
|
- Main
|
||||||
|
- Stats
|
||||||
|
- Skills
|
||||||
|
- Inventory
|
||||||
|
- Player
|
||||||
|
- Containers
|
||||||
|
- Inventory (divided into category of items)
|
||||||
|
- This is the items that the player will have "on them"
|
||||||
|
- Storage (divided into category of items)
|
||||||
|
- This is all of the items that the players owns and has put into storage *somewhere*
|
||||||
|
- Transportation
|
||||||
|
- Combat
|
||||||
|
- Easy skill buttons:
|
||||||
|
- Melee
|
||||||
|
- Accuracy
|
||||||
|
- Weapons
|
||||||
|
- Sync / Respawns
|
||||||
|
- Info
|
||||||
|
- Account name
|
||||||
|
- PFP
|
||||||
|
- Group name
|
||||||
|
- Aspects
|
||||||
|
- Roles
|
||||||
|
- Spells
|
||||||
|
|
||||||
|
======
|
||||||
|
|
||||||
|
## Requirements:
|
||||||
|
|
||||||
|
Stats:
|
||||||
|
- Needs to list all 6 of the primary stats
|
||||||
|
- Needs to have a dropdown for to select a die
|
||||||
|
- Nice to have: disables dice that have been selected in other stats
|
||||||
|
- Needs to have a button to roll the stat (when a die is selected)
|
||||||
|
- Foundry v12: ActiveEffect - Die needs to be able to be affected by ActiveEffects
|
||||||
|
|
||||||
|
Skills:
|
||||||
|
- Each of the 25 skills needs to be grouped under a header of what stat it's
|
||||||
|
associated with
|
||||||
|
- Each skill must have a dropdown to indicate training level (null, trained,
|
||||||
|
expert, locked)
|
||||||
|
- Every skill must have a button to roll the dice that is labelled with the
|
||||||
|
correct formula for that skill (or "Locked" if the skill is locked)
|
||||||
|
- ActiveEffect - Increase Modifier
|
||||||
|
- Foundry v12: ActiveEffect - Increase Training Level
|
||||||
|
|
||||||
|
Combat:
|
||||||
|
- Two weapon slots for the equipped weapon(s)
|
||||||
|
- A single armor slot
|
||||||
|
- Quick-access to the Melee / Accuracy skills
|
||||||
|
|
||||||
|
Inventory:
|
||||||
|
- Needs three sub-tabs:
|
||||||
|
- Player
|
||||||
|
- Storage
|
||||||
|
- Transportation
|
||||||
|
- Player Subtab:
|
||||||
|
- Needs to have a section for container items, and indicating how many slots
|
||||||
|
each one has.
|
||||||
|
- List all of the items that the player has with the "inventory" location
|
||||||
|
- Show the total number of items the player on their character and how many
|
||||||
|
total slots are available
|
||||||
|
- Needs some way to move items to a different storage area (embedded-only
|
||||||
|
item sheet field maybe)
|
||||||
|
- Storage Subtab:
|
||||||
|
- List all of the items that the player has marked as in-storage
|
||||||
|
- Transportation:
|
||||||
|
- This is currently just a placeholder tab, no functionality needed other
|
||||||
|
than existing
|
||||||
|
|
||||||
|
Spells:
|
||||||
|
- Lists all spells on a page (sortable by: alphabetical, cost, etc.)
|
||||||
|
|
||||||
|
Info:
|
||||||
|
- Needs a place to edit the actor's name
|
||||||
|
- Needs a place to edit the actor's image
|
||||||
|
- Needs a place to edit the group name (if enabled by the GM, or is the GM)
|
||||||
|
- Needs a place to see and manage all equipped aspects
|
||||||
|
- Needs a place to see and manage all equipped roles
|
||||||
714
package-lock.json
generated
|
|
@ -5,10 +5,32 @@
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@foundryvtt/foundryvtt-cli": "^1.0.2",
|
||||||
"@league-of-foundry-developers/foundry-vtt-types": "^9.280.0",
|
"@league-of-foundry-developers/foundry-vtt-types": "^9.280.0",
|
||||||
"sass": "^1.69.5"
|
"sass": "^1.69.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@foundryvtt/foundryvtt-cli": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@foundryvtt/foundryvtt-cli/-/foundryvtt-cli-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-pERML7ViBiqwP11NS1kci0Q38t4h557F/Mj+DjYmmgumMJIZqDsVv2XU3bwOJS7+6yzbUmUc2/jRD6EIx+U/fw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^5.2.0",
|
||||||
|
"classic-level": "^1.2.0",
|
||||||
|
"esm": "^3.2.25",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"mkdirp": "^3.0.0",
|
||||||
|
"nedb-promises": "^6.2.1",
|
||||||
|
"yargs": "^17.7.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"fvtt": "fvtt.mjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">17.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@league-of-foundry-developers/foundry-vtt-types": {
|
"node_modules/@league-of-foundry-developers/foundry-vtt-types": {
|
||||||
"version": "9.280.0",
|
"version": "9.280.0",
|
||||||
"resolved": "https://registry.npmjs.org/@league-of-foundry-developers/foundry-vtt-types/-/foundry-vtt-types-9.280.0.tgz",
|
"resolved": "https://registry.npmjs.org/@league-of-foundry-developers/foundry-vtt-types/-/foundry-vtt-types-9.280.0.tgz",
|
||||||
|
|
@ -2152,6 +2174,23 @@
|
||||||
"@pixi/settings": "6.5.10"
|
"@pixi/settings": "6.5.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@seald-io/binary-search-tree": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-qv3jnwoakeax2razYaMsGI/luWdliBLHTdC6jU55hQt1hcFqzauH/HsBollQ7IR4ySTtYhT+xyHoijpA16C+tA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@seald-io/nedb": {
|
||||||
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@seald-io/nedb/-/nedb-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-CUNcMio7QUHTA+sIJ/DC5JzVNNsHe743TPmC4H5Gij9zDLMbmrCT2li3eVB72/gF63BPS8pWEZrjlAMRKA8FDw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@seald-io/binary-search-tree": "^1.0.3",
|
||||||
|
"localforage": "^1.9.0",
|
||||||
|
"util": "^0.12.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@socket.io/component-emitter": {
|
"node_modules/@socket.io/component-emitter": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz",
|
||||||
|
|
@ -2175,9 +2214,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.10.6",
|
"version": "20.11.16",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz",
|
||||||
"integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==",
|
"integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
|
|
@ -2205,6 +2244,48 @@
|
||||||
"integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==",
|
"integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/abstract-level": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-eUP/6pbXBkMbXFdx4IH2fVgvB7M0JvR7/lIL33zcs0IBcwjdzSSl31TOJsaCzmKSSDF9h8QYSOJux4Nd4YJqFg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"catering": "^2.1.0",
|
||||||
|
"is-buffer": "^2.0.5",
|
||||||
|
"level-supports": "^4.0.0",
|
||||||
|
"level-transcoder": "^1.0.1",
|
||||||
|
"module-error": "^1.0.1",
|
||||||
|
"queue-microtask": "^1.2.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-regex": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/anymatch": {
|
"node_modules/anymatch": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||||
|
|
@ -2218,12 +2299,50 @@
|
||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/available-typed-arrays": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/backo2": {
|
"node_modules/backo2": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
|
||||||
"integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==",
|
"integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/base64-js": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
|
|
@ -2245,20 +2364,69 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/buffer": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/call-bind": {
|
"node_modules/call-bind": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz",
|
||||||
"integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
|
"integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
"function-bind": "^1.1.2",
|
"function-bind": "^1.1.2",
|
||||||
"get-intrinsic": "^1.2.1",
|
"get-intrinsic": "^1.2.3",
|
||||||
"set-function-length": "^1.1.1"
|
"set-function-length": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/catering": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chalk": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "3.5.3",
|
"version": "3.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
|
|
@ -2286,6 +2454,55 @@
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/classic-level": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-qGx/KJl3bvtOHrGau2WklEZuXhS3zme+jf+fsu6Ej7W7IP/C49v7KNlWIsT1jZu0YnfzSIYDGcEWpCa1wKGWXQ==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"abstract-level": "^1.0.2",
|
||||||
|
"catering": "^2.1.0",
|
||||||
|
"module-error": "^1.0.1",
|
||||||
|
"napi-macros": "^2.2.2",
|
||||||
|
"node-gyp-build": "^4.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"string-width": "^4.2.0",
|
||||||
|
"strip-ansi": "^6.0.1",
|
||||||
|
"wrap-ansi": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
|
|
@ -2304,14 +2521,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/define-data-property": {
|
"node_modules/define-data-property": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz",
|
||||||
"integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
|
"integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"get-intrinsic": "^1.2.1",
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.2",
|
||||||
"gopd": "^1.0.1",
|
"gopd": "^1.0.1",
|
||||||
"has-property-descriptors": "^1.0.0"
|
"has-property-descriptors": "^1.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
|
|
@ -2323,6 +2541,12 @@
|
||||||
"integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==",
|
"integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/engine.io-client": {
|
"node_modules/engine.io-client": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.0.3.tgz",
|
||||||
|
|
@ -2349,12 +2573,39 @@
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/es-errors": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/es6-promise-polyfill": {
|
"node_modules/es6-promise-polyfill": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/es6-promise-polyfill/-/es6-promise-polyfill-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/es6-promise-polyfill/-/es6-promise-polyfill-1.2.0.tgz",
|
||||||
"integrity": "sha512-HHb0vydCpoclpd0ySPkRXMmBw80MRt1wM4RBJBlXkux97K7gleabZdsR0gvE1nNPM9mgOZIBTzjjXiPxf4lIqQ==",
|
"integrity": "sha512-HHb0vydCpoclpd0ySPkRXMmBw80MRt1wM4RBJBlXkux97K7gleabZdsR0gvE1nNPM9mgOZIBTzjjXiPxf4lIqQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/escalade": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/esm": {
|
||||||
|
"version": "3.2.25",
|
||||||
|
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
|
||||||
|
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eventemitter3": {
|
"node_modules/eventemitter3": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
|
||||||
|
|
@ -2373,6 +2624,15 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/for-each": {
|
||||||
|
"version": "0.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||||
|
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-callable": "^1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
|
|
@ -2396,17 +2656,30 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-caller-file": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "6.* || 8.* || >= 10.*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-intrinsic": {
|
"node_modules/get-intrinsic": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||||
"integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
|
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
"function-bind": "^1.1.2",
|
"function-bind": "^1.1.2",
|
||||||
"has-proto": "^1.0.1",
|
"has-proto": "^1.0.1",
|
||||||
"has-symbols": "^1.0.3",
|
"has-symbols": "^1.0.3",
|
||||||
"hasown": "^2.0.0"
|
"hasown": "^2.0.0"
|
||||||
},
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
|
|
@ -2498,6 +2771,21 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/has-tostringtag": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"has-symbols": "^1.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/hasown": {
|
"node_modules/hasown": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
|
||||||
|
|
@ -2510,12 +2798,60 @@
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ieee754": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/immediate": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||||
|
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/immutable": {
|
"node_modules/immutable": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
|
||||||
"integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==",
|
"integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/is-arguments": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind": "^1.0.2",
|
||||||
|
"has-tostringtag": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-binary-path": {
|
"node_modules/is-binary-path": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||||
|
|
@ -2528,6 +2864,41 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-buffer": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-callable": {
|
||||||
|
"version": "1.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
||||||
|
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-extglob": {
|
"node_modules/is-extglob": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
|
@ -2537,6 +2908,30 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-fullwidth-code-point": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-generator-function": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"has-tostringtag": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-glob": {
|
"node_modules/is-glob": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
|
@ -2558,12 +2953,79 @@
|
||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-typed-array": {
|
||||||
|
"version": "1.1.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
|
||||||
|
"integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"which-typed-array": "^1.1.14"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ismobilejs": {
|
"node_modules/ismobilejs": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz",
|
||||||
"integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==",
|
"integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/js-yaml": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/level-supports": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/level-transcoder": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"module-error": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lie": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"immediate": "~3.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/localforage": {
|
||||||
|
"version": "1.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
|
||||||
|
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"lie": "3.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mini-signals": {
|
"node_modules/mini-signals": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/mini-signals/-/mini-signals-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/mini-signals/-/mini-signals-1.2.0.tgz",
|
||||||
|
|
@ -2579,18 +3041,68 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mkdirp": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"mkdirp": "dist/cjs/src/bin.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/module-error": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/napi-macros": {
|
||||||
|
"version": "2.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz",
|
||||||
|
"integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/nedb-promises": {
|
||||||
|
"version": "6.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/nedb-promises/-/nedb-promises-6.2.3.tgz",
|
||||||
|
"integrity": "sha512-enq0IjNyBz9Qy9W/QPCcLGh/QORGBjXbIeZeWvIjO3OMLyAvlKT3hiJubP2BKEiFniUlR3L01o18ktqgn5jxqA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@seald-io/nedb": "^4.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/neo-async": {
|
"node_modules/neo-async": {
|
||||||
"version": "2.6.2",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
||||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/node-gyp-build": {
|
||||||
|
"version": "4.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz",
|
||||||
|
"integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"node-gyp-build": "bin.js",
|
||||||
|
"node-gyp-build-optional": "optional.js",
|
||||||
|
"node-gyp-build-test": "build-test.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/normalize-path": {
|
"node_modules/normalize-path": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
|
@ -2833,6 +3345,26 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/queue-microtask": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/readdirp": {
|
"node_modules/readdirp": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
|
|
@ -2845,6 +3377,15 @@
|
||||||
"node": ">=8.10.0"
|
"node": ">=8.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/require-directory": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/resource-loader": {
|
"node_modules/resource-loader": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/resource-loader/-/resource-loader-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/resource-loader/-/resource-loader-3.0.1.tgz",
|
||||||
|
|
@ -2873,29 +3414,35 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/set-function-length": {
|
"node_modules/set-function-length": {
|
||||||
"version": "1.1.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
|
||||||
"integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
|
"integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"define-data-property": "^1.1.1",
|
"define-data-property": "^1.1.2",
|
||||||
"get-intrinsic": "^1.2.1",
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"get-intrinsic": "^1.2.3",
|
||||||
"gopd": "^1.0.1",
|
"gopd": "^1.0.1",
|
||||||
"has-property-descriptors": "^1.0.0"
|
"has-property-descriptors": "^1.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/side-channel": {
|
"node_modules/side-channel": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
|
||||||
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
|
"integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind": "^1.0.0",
|
"call-bind": "^1.0.6",
|
||||||
"get-intrinsic": "^1.0.2",
|
"es-errors": "^1.3.0",
|
||||||
"object-inspect": "^1.9.0"
|
"get-intrinsic": "^1.2.4",
|
||||||
|
"object-inspect": "^1.13.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
|
@ -2949,6 +3496,32 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/string-width": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strip-ansi": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tinymce": {
|
"node_modules/tinymce": {
|
||||||
"version": "5.10.1",
|
"version": "5.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.10.1.tgz",
|
||||||
|
|
@ -2996,12 +3569,61 @@
|
||||||
"qs": "^6.11.2"
|
"qs": "^6.11.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/util": {
|
||||||
|
"version": "0.12.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
|
||||||
|
"integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"is-arguments": "^1.0.4",
|
||||||
|
"is-generator-function": "^1.0.7",
|
||||||
|
"is-typed-array": "^1.1.3",
|
||||||
|
"which-typed-array": "^1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/which-typed-array": {
|
||||||
|
"version": "1.1.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz",
|
||||||
|
"integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"available-typed-arrays": "^1.0.6",
|
||||||
|
"call-bind": "^1.0.5",
|
||||||
|
"for-each": "^0.3.3",
|
||||||
|
"gopd": "^1.0.1",
|
||||||
|
"has-tostringtag": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/wordwrap": {
|
"node_modules/wordwrap": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||||
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
|
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/wrap-ansi": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.0.0",
|
||||||
|
"string-width": "^4.1.0",
|
||||||
|
"strip-ansi": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.2.3",
|
"version": "8.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
|
||||||
|
|
@ -3032,6 +3654,42 @@
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/y18n": {
|
||||||
|
"version": "5.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs": {
|
||||||
|
"version": "17.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||||
|
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"cliui": "^8.0.1",
|
||||||
|
"escalade": "^3.1.1",
|
||||||
|
"get-caller-file": "^2.0.5",
|
||||||
|
"require-directory": "^2.1.1",
|
||||||
|
"string-width": "^4.2.3",
|
||||||
|
"y18n": "^5.0.5",
|
||||||
|
"yargs-parser": "^21.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs-parser": {
|
||||||
|
"version": "21.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||||
|
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/yeast": {
|
"node_modules/yeast": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
"build": "sass --embed-source-map --no-error-css styles/:.styles/"
|
"build": "sass --embed-source-map --no-error-css styles/:.styles/"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@foundryvtt/foundryvtt-cli": "^1.0.2",
|
||||||
"@league-of-foundry-developers/foundry-vtt-types": "^9.280.0",
|
"@league-of-foundry-developers/foundry-vtt-types": "^9.280.0",
|
||||||
"sass": "^1.69.5"
|
"sass": "^1.69.5"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "Tutorial Dungeon",
|
||||||
|
"img": null,
|
||||||
|
"caption": "",
|
||||||
|
"sort": 0,
|
||||||
|
"description": "",
|
||||||
|
"actors": [],
|
||||||
|
"combats": [],
|
||||||
|
"items": [],
|
||||||
|
"journal": [],
|
||||||
|
"scenes": [],
|
||||||
|
"tables": [],
|
||||||
|
"macros": [],
|
||||||
|
"cards": [],
|
||||||
|
"playlists": [],
|
||||||
|
"folders": [],
|
||||||
|
"_id": "P4I3A3FYvW0Yedqm",
|
||||||
|
"folder": null,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1708052903525,
|
||||||
|
"modifiedTime": 1708052903525,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!adventures!P4I3A3FYvW0Yedqm"
|
||||||
|
}
|
||||||
105
packs/beastiary/_source/Arya_oCHOQYCQEI1zk5zO.json
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
{
|
||||||
|
"name": "Arya",
|
||||||
|
"type": "mob",
|
||||||
|
"_id": "oCHOQYCQEI1zk5zO",
|
||||||
|
"img": "icons/svg/mystery-man.svg",
|
||||||
|
"system": {
|
||||||
|
"bonus": 4,
|
||||||
|
"initiative": null,
|
||||||
|
"morale": 20,
|
||||||
|
"drops": "Arya's Cloak",
|
||||||
|
"stunts": "Arya's Shroud - On her initiative, Arya drags a player into her shroud, a foggy one-on-one arena. They leave at the beginning of Arya's next turn if she chooses a new victim.",
|
||||||
|
"immune": "Solar, Shadow, Neon",
|
||||||
|
"weak": "Gun",
|
||||||
|
"bytes": 0,
|
||||||
|
"description": "The Queen of the Wode. A gargantuan fox who converses with her all-seeing children (the Palims) through hidden strings of code. If you find her, perform a /bow and offer anything of value. She can guide you where you need to go.",
|
||||||
|
"dice": [
|
||||||
|
{
|
||||||
|
"count": 3,
|
||||||
|
"sides": 6,
|
||||||
|
"repeat": 5
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"prototypeToken": {
|
||||||
|
"name": "Arya",
|
||||||
|
"displayName": 0,
|
||||||
|
"actorLink": false,
|
||||||
|
"appendNumber": false,
|
||||||
|
"prependAdjective": false,
|
||||||
|
"texture": {
|
||||||
|
"src": "icons/svg/mystery-man.svg",
|
||||||
|
"scaleX": 1,
|
||||||
|
"scaleY": 1,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"rotation": 0
|
||||||
|
},
|
||||||
|
"width": 1,
|
||||||
|
"height": 1,
|
||||||
|
"lockRotation": false,
|
||||||
|
"rotation": 0,
|
||||||
|
"alpha": 1,
|
||||||
|
"disposition": -1,
|
||||||
|
"displayBars": 0,
|
||||||
|
"bar1": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"bar2": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"alpha": 0.5,
|
||||||
|
"angle": 360,
|
||||||
|
"bright": 0,
|
||||||
|
"coloration": 1,
|
||||||
|
"dim": 0,
|
||||||
|
"attenuation": 0.5,
|
||||||
|
"luminosity": 0.5,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0,
|
||||||
|
"shadows": 0,
|
||||||
|
"animation": {
|
||||||
|
"type": null,
|
||||||
|
"speed": 5,
|
||||||
|
"intensity": 5,
|
||||||
|
"reverse": false
|
||||||
|
},
|
||||||
|
"darkness": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sight": {
|
||||||
|
"enabled": false,
|
||||||
|
"range": 0,
|
||||||
|
"angle": 360,
|
||||||
|
"visionMode": "basic",
|
||||||
|
"attenuation": 0.1,
|
||||||
|
"brightness": 0,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0
|
||||||
|
},
|
||||||
|
"detectionModes": [],
|
||||||
|
"flags": {},
|
||||||
|
"randomImg": false
|
||||||
|
},
|
||||||
|
"items": [],
|
||||||
|
"effects": [],
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"ownership": {
|
||||||
|
"default": 0,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1708052549670,
|
||||||
|
"modifiedTime": 1708052728103,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!actors!oCHOQYCQEI1zk5zO"
|
||||||
|
}
|
||||||
110
packs/beastiary/_source/Dragon_TxMsleI1qG86zj6B.json
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
{
|
||||||
|
"name": "Dragon",
|
||||||
|
"type": "mob",
|
||||||
|
"_id": "TxMsleI1qG86zj6B",
|
||||||
|
"img": "icons/svg/mystery-man.svg",
|
||||||
|
"system": {
|
||||||
|
"bonus": 6,
|
||||||
|
"initiative": 20,
|
||||||
|
"morale": 2,
|
||||||
|
"drops": "Dragon Materials",
|
||||||
|
"stunts": "Breath Weapon: At the end of the round, the Dragon breathes its fire onto the battlefield, forcing everyone to make a contest against its current dice.",
|
||||||
|
"immune": "Piercing, Slashing, Smashing",
|
||||||
|
"weak": "Gun, Neon",
|
||||||
|
"bytes": 0,
|
||||||
|
"description": "Children of Annwn that explode from her body and conquer the hex of their birth. Stylized after the lung Dragons",
|
||||||
|
"dice": [
|
||||||
|
{
|
||||||
|
"count": 3,
|
||||||
|
"sides": 6,
|
||||||
|
"repeat": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"count": 2,
|
||||||
|
"sides": 6,
|
||||||
|
"repeat": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"prototypeToken": {
|
||||||
|
"name": "Dragon",
|
||||||
|
"displayName": 0,
|
||||||
|
"actorLink": false,
|
||||||
|
"appendNumber": false,
|
||||||
|
"prependAdjective": false,
|
||||||
|
"texture": {
|
||||||
|
"src": "icons/svg/mystery-man.svg",
|
||||||
|
"scaleX": 1,
|
||||||
|
"scaleY": 1,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"rotation": 0
|
||||||
|
},
|
||||||
|
"width": 1,
|
||||||
|
"height": 1,
|
||||||
|
"lockRotation": false,
|
||||||
|
"rotation": 0,
|
||||||
|
"alpha": 1,
|
||||||
|
"disposition": -1,
|
||||||
|
"displayBars": 0,
|
||||||
|
"bar1": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"bar2": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"alpha": 0.5,
|
||||||
|
"angle": 360,
|
||||||
|
"bright": 0,
|
||||||
|
"coloration": 1,
|
||||||
|
"dim": 0,
|
||||||
|
"attenuation": 0.5,
|
||||||
|
"luminosity": 0.5,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0,
|
||||||
|
"shadows": 0,
|
||||||
|
"animation": {
|
||||||
|
"type": null,
|
||||||
|
"speed": 5,
|
||||||
|
"intensity": 5,
|
||||||
|
"reverse": false
|
||||||
|
},
|
||||||
|
"darkness": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sight": {
|
||||||
|
"enabled": false,
|
||||||
|
"range": 0,
|
||||||
|
"angle": 360,
|
||||||
|
"visionMode": "basic",
|
||||||
|
"attenuation": 0.1,
|
||||||
|
"brightness": 0,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0
|
||||||
|
},
|
||||||
|
"detectionModes": [],
|
||||||
|
"flags": {},
|
||||||
|
"randomImg": false
|
||||||
|
},
|
||||||
|
"items": [],
|
||||||
|
"effects": [],
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"ownership": {
|
||||||
|
"default": 0,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1707676733262,
|
||||||
|
"modifiedTime": 1707676892258,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!actors!TxMsleI1qG86zj6B"
|
||||||
|
}
|
||||||
21
packs/rules/_source/Exploration_RT4uYaDJYd2RkDaA.json
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "Exploration",
|
||||||
|
"_id": "RT4uYaDJYd2RkDaA",
|
||||||
|
"pages": [],
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"ownership": {
|
||||||
|
"default": 0,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1708054253372,
|
||||||
|
"modifiedTime": 1708054253372,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal!RT4uYaDJYd2RkDaA"
|
||||||
|
}
|
||||||
94
packs/rules/_source/Inventory_y7CfRycKl5A8SpnH.json
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
{
|
||||||
|
"name": "Inventory",
|
||||||
|
"_id": "y7CfRycKl5A8SpnH",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"sort": 100000,
|
||||||
|
"name": "Bytes",
|
||||||
|
"type": "text",
|
||||||
|
"_id": "3uVI4u2ByT8Tt6jq",
|
||||||
|
"title": {
|
||||||
|
"show": true,
|
||||||
|
"level": 1
|
||||||
|
},
|
||||||
|
"image": {},
|
||||||
|
"text": {
|
||||||
|
"format": 1,
|
||||||
|
"content": "<p>Bytes are the currency of .dungeon. They can only be gained by interacting with the game: travelling to far away places, fighting mobs, exploring randomly generated structures, and taking on quests. They are used for everything from buying gear, to casting spells, and uncovering secrets in the world.</p><p></p><h2>Gaining Bytes</h2><p>A character gains 1 Byte (1b) per day as long as they log in and play. Traveling into a new hex for the first time also nets 1b. Defeating an encounter without taking Sync damage will gain the party an additional 1b each.</p><p></p><h2>The Hidden World of Bytes</h2><p>Last year, players discovered that an entire region of the map was unlocked once they accumulated enough Bytes, leading to speculation that the developers have hidden other things behind Bytes. Secret doors have been found in the tutorial dungeon. Some mobs are hidden until a certain number of Bytes are acquired. There are many secrets we've yet to uncover.</p>",
|
||||||
|
"markdown": ""
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"controls": true,
|
||||||
|
"volume": 0.5
|
||||||
|
},
|
||||||
|
"src": null,
|
||||||
|
"system": {},
|
||||||
|
"ownership": {
|
||||||
|
"default": -1,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1708053617428,
|
||||||
|
"modifiedTime": 1708058964191,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal.pages!y7CfRycKl5A8SpnH.3uVI4u2ByT8Tt6jq"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sort": 200000,
|
||||||
|
"name": "Resources/Supplies",
|
||||||
|
"type": "text",
|
||||||
|
"_id": "u0e8iLKCdCbdBkRG",
|
||||||
|
"title": {
|
||||||
|
"show": true,
|
||||||
|
"level": 1
|
||||||
|
},
|
||||||
|
"image": {},
|
||||||
|
"text": {
|
||||||
|
"format": 1,
|
||||||
|
"content": "<p><strong>Note:</strong> The wiki uses the terms \"Resources\" and \"Supplies\" interchangeably, they are functionally equivalent in every way.</p>",
|
||||||
|
"markdown": ""
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"controls": true,
|
||||||
|
"volume": 0.5
|
||||||
|
},
|
||||||
|
"src": null,
|
||||||
|
"system": {},
|
||||||
|
"ownership": {
|
||||||
|
"default": -1,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1708053891257,
|
||||||
|
"modifiedTime": 1708060045044,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal.pages!y7CfRycKl5A8SpnH.u0e8iLKCdCbdBkRG"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"ownership": {
|
||||||
|
"default": 0,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1708053607510,
|
||||||
|
"modifiedTime": 1708060045044,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal!y7CfRycKl5A8SpnH"
|
||||||
|
}
|
||||||
232
packs/rules/_source/Stats___Skills_PZlkwX6W6TXpvl5C.json
Normal file
|
|
@ -0,0 +1,232 @@
|
||||||
|
{
|
||||||
|
"name": "Stats & Skills",
|
||||||
|
"_id": "PZlkwX6W6TXpvl5C",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"sort": 100000,
|
||||||
|
"name": "Skills",
|
||||||
|
"type": "text",
|
||||||
|
"_id": "tf71tBEsorEzwg5D",
|
||||||
|
"title": {
|
||||||
|
"show": true,
|
||||||
|
"level": 1
|
||||||
|
},
|
||||||
|
"image": {},
|
||||||
|
"text": {
|
||||||
|
"format": 1,
|
||||||
|
"content": "<p>Skills are in-game abilities that dictate how good your Avatar is at accomplishing tasks. Choose three skills to gain training in, alongside the one skill gifted by your job. <em>Training</em> in a skill means you get +2 to rolls when using it. <em>Expertise</em> in a skill means you get +4 to rolls when using it.</p><p>Skills are categorized by which Stat they fall under. Add your bonus to Contests where the Skill is applicable, rolling your Stat Dice and adding the Skill to the result.</p><p></p><h2>Skill Training</h2><p>To learn a new skill, PCs must find someone who can teach it to them. This requires a payment of 20 Bytes and a week of downtime. To gain Expertise in a skill, the player and the Server Host must agree to a challenge. Failure to accomplish the challenge locks you out of the skill into another challenge is agreed upon. If the challenge is accomplished the player gains Expertise in the skill.</p><p></p><h2>Detailed Skill Breakdowns</h2><ul><li><p>@UUID[.hcU7kvIyJEyQfjZI]{Build Skills}</p></li><li><p>@UUID[.eEKc5g8nyJo4gzcA]{Meta Skills}</p></li><li><p>@UUID[.Bv7FKq69XgfNgq0G]{Presence Skills}</p></li><li><p>@UUID[.YjSClMTdT8psEy3k]{Hands Skills}</p></li></ul>"
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"controls": true,
|
||||||
|
"volume": 0.5
|
||||||
|
},
|
||||||
|
"src": null,
|
||||||
|
"system": {},
|
||||||
|
"ownership": {
|
||||||
|
"default": -1,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1707675426941,
|
||||||
|
"modifiedTime": 1707676418844,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal.pages!PZlkwX6W6TXpvl5C.tf71tBEsorEzwg5D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sort": 200000,
|
||||||
|
"name": "Build Skills",
|
||||||
|
"type": "text",
|
||||||
|
"_id": "hcU7kvIyJEyQfjZI",
|
||||||
|
"title": {
|
||||||
|
"show": true,
|
||||||
|
"level": 2
|
||||||
|
},
|
||||||
|
"image": {},
|
||||||
|
"text": {
|
||||||
|
"format": 1,
|
||||||
|
"content": "<h2>Defense</h2><p>Instead of armor, characters have a base defense that acts as damage reduction. Training in defense gives you 1dr, and Expertise gives you 2dr. Some clothes and armour may offer more damage reduction.</p><p></p><h2>Magic</h2><p>Training in magic lets you cast spells. Without training, you might be able to read the spells but their magic is lost on you. Expertise allows you to identify who cast a particular spell and detect magic in the area.</p><p></p><h2>Melee</h2><p>Training in melee allows you to use big melee weapons. Expertise allows you a unique \"stance\" with your weapon of choice. Whether you're swinging a sword or a punch, add your training when making attacks against against opponents.</p><p></p><h2>Platforming</h2><p>Acrobatic leaps, climbing, and navigating dangerous terrain. Training in platforming gives you tighter control over your Avatar's movements. Expertise gives you a double jump.</p><p></p><h2>Strength</h2><p>Knocking this over, pushing things out of the way, and general, hand-made destruction. Training in strength makes objects weigh less to your character. Expertise lets you throw large objects.</p>"
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"controls": true,
|
||||||
|
"volume": 0.5
|
||||||
|
},
|
||||||
|
"src": null,
|
||||||
|
"system": {},
|
||||||
|
"ownership": {
|
||||||
|
"default": -1,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1707675453145,
|
||||||
|
"modifiedTime": 1707675622437,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal.pages!PZlkwX6W6TXpvl5C.hcU7kvIyJEyQfjZI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sort": 300000,
|
||||||
|
"name": "Meta Skills",
|
||||||
|
"type": "text",
|
||||||
|
"_id": "eEKc5g8nyJo4gzcA",
|
||||||
|
"title": {
|
||||||
|
"show": true,
|
||||||
|
"level": 2
|
||||||
|
},
|
||||||
|
"image": {},
|
||||||
|
"text": {
|
||||||
|
"format": 1,
|
||||||
|
"content": "<h2>Alchemy</h2><p>Creating and identifying foils. Training in alchemy allows your character to craft lesser foils out of Materials. Expertise lets you craft greater foils.</p><p></p><h2>Arcanum</h2><p>The knowledge and training to use magic items and sci-fi tech. Training in arcanum allows you to use neon weapons. Expertise gives you basic information about magic items that are within your line of sight.</p><p></p><h2>Dreams</h2><p>Considered a hidden skill of the game, because it's not clearly defined on the wiki. [Call to action! The .dungeon wiki is open for contributors who know more about this skill]</p><section class=\"secret\" id=\"secret-p8sDnaGF4dVcH8aS\"><p>Training in dreams allows you to make pacts with the pantheon of .dungeon. Expertise in it allows you to open yourself to the world of Annwn and receive messages from it. Often cryptic or prophetic.</p></section><p></p><h2>Lore</h2><p>Training in lore means the game expands descriptive text. Expertise means the game might butt in to give you information, even when you didn't ask for it.</p><p></p><h2>Navigation</h2><p>Training in navigation improves your HUD radar and quest markers. Expertise gives you active hints to help you search and travel.</p>"
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"controls": true,
|
||||||
|
"volume": 0.5
|
||||||
|
},
|
||||||
|
"src": null,
|
||||||
|
"system": {},
|
||||||
|
"ownership": {
|
||||||
|
"default": -1,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1707675480467,
|
||||||
|
"modifiedTime": 1707675613151,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal.pages!PZlkwX6W6TXpvl5C.eEKc5g8nyJo4gzcA"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sort": 400000,
|
||||||
|
"name": "Presence Skills",
|
||||||
|
"type": "text",
|
||||||
|
"_id": "Bv7FKq69XgfNgq0G",
|
||||||
|
"title": {
|
||||||
|
"show": true,
|
||||||
|
"level": 2
|
||||||
|
},
|
||||||
|
"image": {},
|
||||||
|
"text": {
|
||||||
|
"format": 1,
|
||||||
|
"content": "<h2>Animal Handling</h2><p>Training in animal handling allows you to take on animals (and some monsters) as pets. Expertise in animal handling lets you reroll animal reactions to you, and take on a mount.</p><p></p><h2>Perception</h2><p>Training in perception improves colours, sounds, and smells to enhance your senses. Expertise in perception does this even more and also adds faint outlines to things of interest. The invisible hands of the game like you.</p><p></p><h2>Sneak</h2><p>Training in sneak reduces the ambient and active sounds of your Avatar. Expertise makes you completely silent while crouched.</p><p></p><h2>Speech</h2><p>Training in speech improves NPC reactions to you. Expertise in speech rerolls reaction rolls even in dangerous situations.</p><p></p><h2>Vibes</h2><p>Training in vibes improves the haptic feedback of your VR rig, giving you subtle signals when things are off. Expertise improves this even more and makes NPCs more readable.</p>"
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"controls": true,
|
||||||
|
"volume": 0.5
|
||||||
|
},
|
||||||
|
"src": null,
|
||||||
|
"system": {},
|
||||||
|
"ownership": {
|
||||||
|
"default": -1,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1707675495034,
|
||||||
|
"modifiedTime": 1707675630479,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal.pages!PZlkwX6W6TXpvl5C.Bv7FKq69XgfNgq0G"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sort": 500000,
|
||||||
|
"name": "Hands Skills",
|
||||||
|
"type": "text",
|
||||||
|
"_id": "YjSClMTdT8psEy3k",
|
||||||
|
"title": {
|
||||||
|
"show": true,
|
||||||
|
"level": 2
|
||||||
|
},
|
||||||
|
"image": {},
|
||||||
|
"text": {
|
||||||
|
"format": 1,
|
||||||
|
"content": "<h2>Accuracy</h2><p>Training in accuracy reduces arrow and bullet drop and other things that affect trajectory of ranged attacks. Expertise subtly slows aiming down to give you greater control.</p><p></p><h2>Crafting</h2><p>Training in crafting allows you to create lesser versions of items as long as you have the supplies. Expertise allows you to create greater versions.</p><p></p><h2>Engineering</h2><p>Training in engineering aids you in repairing vehicles and other machinery in the world. Expertise aids you further by reducing repair costs.</p><p></p><h2>Explosives</h2><p>Training in explosives allows you more wiggle room for failure while using them in combat and aids you in building and disarming explosives. Expertise allows you to disarm explosives without destroying them.</p><p></p><h2>Piloting</h2><p>Training in piloting improves vehicle responsiveness and makes them easier to control. Expertise allows for a semi-auto-pilot so you can take on simple tasks while also piloting.</p>"
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"controls": true,
|
||||||
|
"volume": 0.5
|
||||||
|
},
|
||||||
|
"src": null,
|
||||||
|
"system": {},
|
||||||
|
"ownership": {
|
||||||
|
"default": -1,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1707675529083,
|
||||||
|
"modifiedTime": 1707675636786,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal.pages!PZlkwX6W6TXpvl5C.YjSClMTdT8psEy3k"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sort": 0,
|
||||||
|
"name": "Stats",
|
||||||
|
"type": "text",
|
||||||
|
"_id": "tv9jEZflqkGgQ1Az",
|
||||||
|
"title": {
|
||||||
|
"show": true,
|
||||||
|
"level": 1
|
||||||
|
},
|
||||||
|
"image": {},
|
||||||
|
"text": {
|
||||||
|
"format": 1,
|
||||||
|
"content": "<h2>Build</h2><p>System mastery, character optimization, the crunch of the game.</p><p></p><h2>Meta</h2><p>Knowledge of the game, its setting, and its development.</p><p></p><h2>Presence</h2><p>Your senses, charisma, and immersion in the virtual world.</p><p></p><h2>Hands</h2><p>Your reaction time, hand-eye coordination, and precision.</p><p></p><h2>Tilt</h2><p>Tilt is how you keep your cool when the virtual world is unfair. Other RPGs call this a \"save\" or a \"saving throw\". Whenever your character would take on a status effect, roll your Tilt dice, <strong>getting a 4 or higher is a success, avoiding the status.</strong></p><p></p><h2>RNG</h2><p>RNG is also known as \"luck\" in other RPGs, RNG rolls are done for random events, loot drops, and other acts of chance the Server needs to account for. You can also roll RNG against an NPC to see if they are nearby.</p>"
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"controls": true,
|
||||||
|
"volume": 0.5
|
||||||
|
},
|
||||||
|
"src": null,
|
||||||
|
"system": {},
|
||||||
|
"ownership": {
|
||||||
|
"default": -1,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1707675599891,
|
||||||
|
"modifiedTime": 1707675641462,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal.pages!PZlkwX6W6TXpvl5C.tv9jEZflqkGgQ1Az"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"ownership": {
|
||||||
|
"default": 0,
|
||||||
|
"SXF6LgHA8oYfOhCm": 3
|
||||||
|
},
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "dotdungeon",
|
||||||
|
"systemVersion": "0.0.5",
|
||||||
|
"coreVersion": "11.315",
|
||||||
|
"createdTime": 1707675420080,
|
||||||
|
"modifiedTime": 1707676418844,
|
||||||
|
"lastModifiedBy": "SXF6LgHA8oYfOhCm"
|
||||||
|
},
|
||||||
|
"_key": "!journal!PZlkwX6W6TXpvl5C"
|
||||||
|
}
|
||||||