intelligent-system-design-language 0.3.21 → 0.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/langium-language-designer.md +38 -38
- package/.claude/agents/typescript-vscode-expert.md +29 -29
- package/.claude/agents/ui-ux-designer.md +36 -36
- package/.claude/settings.local.json +33 -33
- package/.idea/inspectionProfiles/Project_Default.xml +6 -6
- package/.idea/isdl.iml +13 -13
- package/.idea/modules.xml +8 -8
- package/.idea/vcs.xml +6 -6
- package/.idea/watcherTasks.xml +3 -3
- package/.vscodeignore +18 -18
- package/LICENSE +673 -673
- package/README.md +86 -86
- package/bin/cli.js +4 -4
- package/bin/lsp.js +8 -8
- package/out/_backgrounds.scss +91 -91
- package/out/_handlebars.scss +497 -497
- package/out/_isdlStyles.scss +1444 -1381
- package/out/_vuetifyOverrides.scss +425 -425
- package/out/_vuetifyStyles.scss +31957 -31957
- package/out/cli/components/_backgrounds.scss +91 -91
- package/out/cli/components/_handlebars.scss +497 -497
- package/out/cli/components/_isdlStyles.scss +1444 -1381
- package/out/cli/components/_vuetifyOverrides.scss +425 -425
- package/out/cli/components/_vuetifyStyles.scss +31957 -31957
- package/out/cli/components/active-effect-sheet-generator.js +453 -453
- package/out/cli/components/chat-card-generator.js +654 -651
- package/out/cli/components/chat-card-generator.js.map +1 -1
- package/out/cli/components/css-generator.js +4 -4
- package/out/cli/components/damage-roll-generator.js +160 -160
- package/out/cli/components/datamodel-generator.js +264 -257
- package/out/cli/components/datamodel-generator.js.map +1 -1
- package/out/cli/components/derived-data-generator.js +923 -923
- package/out/cli/components/hotbar-drop-hook-generator.js +82 -82
- package/out/cli/components/init-hook-generator.js +495 -495
- package/out/cli/components/language-generator.js +1 -1
- package/out/cli/components/language-generator.js.map +1 -1
- package/out/cli/components/measured-template-preview.js +221 -221
- package/out/cli/components/method-generator.js +979 -887
- package/out/cli/components/method-generator.js.map +1 -1
- package/out/cli/components/ready-hook-generator.js +404 -404
- package/out/cli/components/token-generator.js +116 -116
- package/out/cli/components/vue/base-components/vue-attribute.js +138 -138
- package/out/cli/components/vue/base-components/vue-boolean.js +64 -64
- package/out/cli/components/vue/base-components/vue-calculator.js +93 -93
- package/out/cli/components/vue/base-components/vue-damage-application.js +356 -356
- package/out/cli/components/vue/base-components/vue-damage-bonuses.js +165 -165
- package/out/cli/components/vue/base-components/vue-damage-resistances.js +196 -196
- package/out/cli/components/vue/base-components/vue-damage-track.js +121 -121
- package/out/cli/components/vue/base-components/vue-date-time.js +42 -42
- package/out/cli/components/vue/base-components/vue-dice.js +98 -98
- package/out/cli/components/vue/base-components/vue-die.js +73 -73
- package/out/cli/components/vue/base-components/vue-document-choice.js +149 -149
- package/out/cli/components/vue/base-components/vue-document-choices.js +179 -179
- package/out/cli/components/vue/base-components/vue-document-link.js +60 -60
- package/out/cli/components/vue/base-components/vue-extended-choice.js +88 -88
- package/out/cli/components/vue/base-components/vue-inventory.js +519 -519
- package/out/cli/components/vue/base-components/vue-macro-choice.js +138 -138
- package/out/cli/components/vue/base-components/vue-measured-template.js +530 -530
- package/out/cli/components/vue/base-components/vue-money.js +483 -483
- package/out/cli/components/vue/base-components/vue-number.js +174 -174
- package/out/cli/components/vue/base-components/vue-paperdoll.js +43 -43
- package/out/cli/components/vue/base-components/vue-parent-property-reference.js +76 -76
- package/out/cli/components/vue/base-components/vue-prosemirror.js +18 -18
- package/out/cli/components/vue/base-components/vue-resource.js +136 -136
- package/out/cli/components/vue/base-components/vue-roll-visualizer.js +286 -109
- package/out/cli/components/vue/base-components/vue-roll-visualizer.js.map +1 -1
- package/out/cli/components/vue/base-components/vue-self-property-reference.js +62 -62
- package/out/cli/components/vue/base-components/vue-string-choice.js +98 -98
- package/out/cli/components/vue/base-components/vue-string-choices.js +203 -203
- package/out/cli/components/vue/base-components/vue-string.js +60 -60
- package/out/cli/components/vue/base-components/vue-text-field.js +53 -53
- package/out/cli/components/vue/base-components/vue-tracker.js +431 -431
- package/out/cli/components/vue/vue-action-component-generator.js +64 -64
- package/out/cli/components/vue/vue-active-effect-sheet-generator.js +856 -856
- package/out/cli/components/vue/vue-datatable-sheet-class-generator.js +292 -292
- package/out/cli/components/vue/vue-datatable2-component-generator.js +824 -824
- package/out/cli/components/vue/vue-document-creation-app.js +121 -121
- package/out/cli/components/vue/vue-document-creation-sheet.js +94 -94
- package/out/cli/components/vue/vue-generator.js +40 -40
- package/out/cli/components/vue/vue-mixin.js +296 -296
- package/out/cli/components/vue/vue-pinned-datatable-component-generator.js +260 -260
- package/out/cli/components/vue/vue-prompt-generator.js +91 -76
- package/out/cli/components/vue/vue-prompt-generator.js.map +1 -1
- package/out/cli/components/vue/vue-prompt-sheet-class-generator.js +317 -317
- package/out/cli/components/vue/vue-sheet-application-generator.js +1177 -1167
- package/out/cli/components/vue/vue-sheet-application-generator.js.map +1 -1
- package/out/cli/components/vue/vue-sheet-class-generator.js +510 -510
- package/out/cli/generator.js +438 -433
- package/out/cli/generator.js.map +1 -1
- package/out/extension/github/githubAuthProvider.js +71 -29
- package/out/extension/github/githubAuthProvider.js.map +1 -1
- package/out/extension/github/githubGistManager.js +4 -3
- package/out/extension/github/githubGistManager.js.map +1 -1
- package/out/extension/github/githubManager.js +40 -38
- package/out/extension/github/githubManager.js.map +1 -1
- package/out/extension/github/githubQuickActions.js +120 -120
- package/out/extension/github/system-workflow.yml +47 -47
- package/out/extension/main.cjs +909 -532
- package/out/extension/main.cjs.map +3 -3
- package/out/extension/package.json +419 -419
- package/out/language/generated/ast.js +51 -2
- package/out/language/generated/ast.js.map +1 -1
- package/out/language/generated/grammar.js +14240 -13991
- package/out/language/generated/grammar.js.map +1 -1
- package/out/language/intelligent-system-design-language-validator.js +32 -2
- package/out/language/intelligent-system-design-language-validator.js.map +1 -1
- package/out/language/isdl-scope-provider.js +14 -1
- package/out/language/isdl-scope-provider.js.map +1 -1
- package/out/language/main.cjs +913 -569
- package/out/language/main.cjs.map +3 -3
- package/out/package.json +419 -419
- package/out/progressbar.min.js +6 -6
- package/out/styles.scss +762 -747
- package/out/test/validating/diagnostics.test.js +40 -0
- package/out/test/validating/diagnostics.test.js.map +1 -1
- package/package.json +419 -419
package/out/cli/generator.js
CHANGED
|
@@ -108,76 +108,76 @@ function generateSystemJson(entry, id, destination) {
|
|
|
108
108
|
const generatedFilePath = path.join(destination, `system.json`);
|
|
109
109
|
// Get the version of the extension
|
|
110
110
|
const extensionVersion = getExtensionVersion();
|
|
111
|
-
const fileNode = expandToNode `
|
|
112
|
-
{
|
|
113
|
-
"id": "${id}",
|
|
114
|
-
"title": "${(_a = entry.config.body.find(x => isConfigExpression(x) && x.type == "label")) === null || _a === void 0 ? void 0 : _a.value}",
|
|
115
|
-
"description": "${(_b = entry.config.body.find(x => isConfigExpression(x) && x.type == "description")) === null || _b === void 0 ? void 0 : _b.value}",
|
|
116
|
-
"version": "This is auto replaced",
|
|
117
|
-
"compatibility": {
|
|
118
|
-
"minimum": 12,
|
|
119
|
-
"verified": 14
|
|
120
|
-
},
|
|
121
|
-
"authors": [
|
|
122
|
-
{
|
|
123
|
-
"name": "${(_c = entry.config.body.find(x => isConfigExpression(x) && x.type == "author")) === null || _c === void 0 ? void 0 : _c.value}"
|
|
124
|
-
}
|
|
125
|
-
],
|
|
126
|
-
"scripts": [
|
|
127
|
-
],
|
|
128
|
-
"esmodules": [
|
|
129
|
-
"system/${id}-main.mjs",
|
|
130
|
-
"system/${id}-custom.mjs"
|
|
131
|
-
],
|
|
132
|
-
"styles": [
|
|
133
|
-
"css/materialdesignicons.min.css",
|
|
134
|
-
"css/${id}.css",
|
|
135
|
-
"css/${id}-custom.css"
|
|
136
|
-
],
|
|
137
|
-
"license": "LICENSE",
|
|
138
|
-
"readme": "README.md",
|
|
139
|
-
"socket": true,
|
|
140
|
-
"languages": [
|
|
141
|
-
{
|
|
142
|
-
"lang": "en",
|
|
143
|
-
"name": "English",
|
|
144
|
-
"path": "lang/en.json"
|
|
145
|
-
}
|
|
146
|
-
],
|
|
147
|
-
"flags": {
|
|
148
|
-
"hotReload": {
|
|
149
|
-
"extensions": ["css", "hbs", "json", "mjs"],
|
|
150
|
-
"paths": ["css", "system", "lang", "system", "system.json"]
|
|
151
|
-
},
|
|
152
|
-
"isdl-version": "${extensionVersion}"
|
|
153
|
-
},
|
|
154
|
-
"media": [
|
|
155
|
-
{
|
|
156
|
-
"type": "setup",
|
|
157
|
-
"url": "systems/${id}/img/isdl.png",
|
|
158
|
-
"thumbnail": "systems/${id}/img/isdl.png"
|
|
159
|
-
}
|
|
160
|
-
],
|
|
161
|
-
"relationships": {
|
|
162
|
-
"recommends": [
|
|
163
|
-
{
|
|
164
|
-
"id": "intelligent-filepicker",
|
|
165
|
-
"type": "module",
|
|
166
|
-
"manifest": "https://github.com/cswendrowski/intelligent-filepicker/releases/latest/download/module.json",
|
|
167
|
-
"reason": "Makes it much faster to pick out Icons for your Documents"
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
"id": "ric",
|
|
171
|
-
"type": "module",
|
|
172
|
-
"manifest": "https://github.com/GamerFlix/ric/releases/latest/download/module.json",
|
|
173
|
-
"reason": "Adds an UI for managing invalid Documents, such as when fields change to become required but were not filled in"
|
|
174
|
-
}
|
|
175
|
-
]
|
|
176
|
-
},
|
|
177
|
-
"url": "This is auto replaced",
|
|
178
|
-
"manifest": "This is auto replaced",
|
|
179
|
-
"download": "This is auto replaced"
|
|
180
|
-
}
|
|
111
|
+
const fileNode = expandToNode `
|
|
112
|
+
{
|
|
113
|
+
"id": "${id}",
|
|
114
|
+
"title": "${(_a = entry.config.body.find(x => isConfigExpression(x) && x.type == "label")) === null || _a === void 0 ? void 0 : _a.value}",
|
|
115
|
+
"description": "${(_b = entry.config.body.find(x => isConfigExpression(x) && x.type == "description")) === null || _b === void 0 ? void 0 : _b.value}",
|
|
116
|
+
"version": "This is auto replaced",
|
|
117
|
+
"compatibility": {
|
|
118
|
+
"minimum": 12,
|
|
119
|
+
"verified": 14
|
|
120
|
+
},
|
|
121
|
+
"authors": [
|
|
122
|
+
{
|
|
123
|
+
"name": "${(_c = entry.config.body.find(x => isConfigExpression(x) && x.type == "author")) === null || _c === void 0 ? void 0 : _c.value}"
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"scripts": [
|
|
127
|
+
],
|
|
128
|
+
"esmodules": [
|
|
129
|
+
"system/${id}-main.mjs",
|
|
130
|
+
"system/${id}-custom.mjs"
|
|
131
|
+
],
|
|
132
|
+
"styles": [
|
|
133
|
+
"css/materialdesignicons.min.css",
|
|
134
|
+
"css/${id}.css",
|
|
135
|
+
"css/${id}-custom.css"
|
|
136
|
+
],
|
|
137
|
+
"license": "LICENSE",
|
|
138
|
+
"readme": "README.md",
|
|
139
|
+
"socket": true,
|
|
140
|
+
"languages": [
|
|
141
|
+
{
|
|
142
|
+
"lang": "en",
|
|
143
|
+
"name": "English",
|
|
144
|
+
"path": "lang/en.json"
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"flags": {
|
|
148
|
+
"hotReload": {
|
|
149
|
+
"extensions": ["css", "hbs", "json", "mjs"],
|
|
150
|
+
"paths": ["css", "system", "lang", "system", "system.json"]
|
|
151
|
+
},
|
|
152
|
+
"isdl-version": "${extensionVersion}"
|
|
153
|
+
},
|
|
154
|
+
"media": [
|
|
155
|
+
{
|
|
156
|
+
"type": "setup",
|
|
157
|
+
"url": "systems/${id}/img/isdl.png",
|
|
158
|
+
"thumbnail": "systems/${id}/img/isdl.png"
|
|
159
|
+
}
|
|
160
|
+
],
|
|
161
|
+
"relationships": {
|
|
162
|
+
"recommends": [
|
|
163
|
+
{
|
|
164
|
+
"id": "intelligent-filepicker",
|
|
165
|
+
"type": "module",
|
|
166
|
+
"manifest": "https://github.com/cswendrowski/intelligent-filepicker/releases/latest/download/module.json",
|
|
167
|
+
"reason": "Makes it much faster to pick out Icons for your Documents"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"id": "ric",
|
|
171
|
+
"type": "module",
|
|
172
|
+
"manifest": "https://github.com/GamerFlix/ric/releases/latest/download/module.json",
|
|
173
|
+
"reason": "Adds an UI for managing invalid Documents, such as when fields change to become required but were not filled in"
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
"url": "This is auto replaced",
|
|
178
|
+
"manifest": "This is auto replaced",
|
|
179
|
+
"download": "This is auto replaced"
|
|
180
|
+
}
|
|
181
181
|
`.appendNewLineIfNotEmpty();
|
|
182
182
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
183
183
|
}
|
|
@@ -197,21 +197,21 @@ function generateTemplateJson(entry, id, destination) {
|
|
|
197
197
|
}
|
|
198
198
|
function generateEntryMjs(entry, id, destination) {
|
|
199
199
|
const generatedFilePath = path.join(destination, "system", `${id}-main.mjs`);
|
|
200
|
-
const fileNode = expandToNode `
|
|
201
|
-
import {init} from "./hooks/init.mjs";
|
|
202
|
-
import {ready} from "./hooks/ready.mjs";
|
|
203
|
-
import {renderChatLog} from "./hooks/render-chat-log.mjs";
|
|
204
|
-
import {renderSettings} from "./hooks/render-settings.mjs";
|
|
205
|
-
import {hotReload} from "./hooks/hot-reload.mjs";
|
|
206
|
-
import {hotbarDrop} from "./hooks/hotbar-drop.mjs";
|
|
207
|
-
|
|
208
|
-
Hooks.once("init", init);
|
|
209
|
-
Hooks.once("ready", ready);
|
|
210
|
-
Hooks.on("devModeReady", ({registerPackageDebugFlag}) => registerPackageDebugFlag("${id}"));
|
|
211
|
-
Hooks.on("renderChatMessage", renderChatLog);
|
|
212
|
-
Hooks.on("renderSettings", renderSettings);
|
|
213
|
-
Hooks.on("hotReload", hotReload);
|
|
214
|
-
Hooks.on("hotbarDrop", hotbarDrop);
|
|
200
|
+
const fileNode = expandToNode `
|
|
201
|
+
import {init} from "./hooks/init.mjs";
|
|
202
|
+
import {ready} from "./hooks/ready.mjs";
|
|
203
|
+
import {renderChatLog} from "./hooks/render-chat-log.mjs";
|
|
204
|
+
import {renderSettings} from "./hooks/render-settings.mjs";
|
|
205
|
+
import {hotReload} from "./hooks/hot-reload.mjs";
|
|
206
|
+
import {hotbarDrop} from "./hooks/hotbar-drop.mjs";
|
|
207
|
+
|
|
208
|
+
Hooks.once("init", init);
|
|
209
|
+
Hooks.once("ready", ready);
|
|
210
|
+
Hooks.on("devModeReady", ({registerPackageDebugFlag}) => registerPackageDebugFlag("${id}"));
|
|
211
|
+
Hooks.on("renderChatMessage", renderChatLog);
|
|
212
|
+
Hooks.on("renderSettings", renderSettings);
|
|
213
|
+
Hooks.on("hotReload", hotReload);
|
|
214
|
+
Hooks.on("hotbarDrop", hotbarDrop);
|
|
215
215
|
`.appendNewLineIfNotEmpty();
|
|
216
216
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
217
217
|
}
|
|
@@ -221,10 +221,10 @@ function generateCustomEntryMjs(entry, id, destination) {
|
|
|
221
221
|
if (fs.existsSync(generatedFilePath)) {
|
|
222
222
|
return;
|
|
223
223
|
}
|
|
224
|
-
const fileNode = expandToNode `
|
|
225
|
-
// Write your custom code and hooks here. This file will not be overwritten by the generator.
|
|
226
|
-
|
|
227
|
-
Hooks.once("init", () => {});
|
|
224
|
+
const fileNode = expandToNode `
|
|
225
|
+
// Write your custom code and hooks here. This file will not be overwritten by the generator.
|
|
226
|
+
|
|
227
|
+
Hooks.once("init", () => {});
|
|
228
228
|
`.appendNewLineIfNotEmpty();
|
|
229
229
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
230
230
|
}
|
|
@@ -234,35 +234,35 @@ function generateHotReloadHookMjs(entry, id, destination) {
|
|
|
234
234
|
if (!fs.existsSync(generatedFileDir)) {
|
|
235
235
|
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
236
236
|
}
|
|
237
|
-
const fileNode = expandToNode `
|
|
238
|
-
export function hotReload(context) {
|
|
239
|
-
const reloadFileTypes = ["mjs", "json"];
|
|
240
|
-
if (!reloadFileTypes.includes(context.extension)) return;
|
|
241
|
-
|
|
242
|
-
if (context.extension === "json") {
|
|
243
|
-
if (!context.path.endsWith("system.json")) return;
|
|
244
|
-
ui.notifications.warn("The system configuration has been updated. Please reload your world to apply changes.", { permanent: true });
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
ui.notifications.info("Reloading page to apply script changes", { permanent: true });
|
|
248
|
-
|
|
249
|
-
const lastState = {
|
|
250
|
-
openWindows: []
|
|
251
|
-
};
|
|
252
|
-
for (const window of Object.values(ui.windows)) {
|
|
253
|
-
if (!window.object) continue;
|
|
254
|
-
const uuid = window.object.uuid;
|
|
255
|
-
lastState.openWindows.push({
|
|
256
|
-
uuid: uuid,
|
|
257
|
-
position: window.position
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
game.settings.set("${id}", "hotReloadLastState", lastState).then(() =>
|
|
261
|
-
{
|
|
262
|
-
// Reload the page
|
|
263
|
-
window.location.reload(true);
|
|
264
|
-
});
|
|
265
|
-
}
|
|
237
|
+
const fileNode = expandToNode `
|
|
238
|
+
export function hotReload(context) {
|
|
239
|
+
const reloadFileTypes = ["mjs", "json"];
|
|
240
|
+
if (!reloadFileTypes.includes(context.extension)) return;
|
|
241
|
+
|
|
242
|
+
if (context.extension === "json") {
|
|
243
|
+
if (!context.path.endsWith("system.json")) return;
|
|
244
|
+
ui.notifications.warn("The system configuration has been updated. Please reload your world to apply changes.", { permanent: true });
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
ui.notifications.info("Reloading page to apply script changes", { permanent: true });
|
|
248
|
+
|
|
249
|
+
const lastState = {
|
|
250
|
+
openWindows: []
|
|
251
|
+
};
|
|
252
|
+
for (const window of Object.values(ui.windows)) {
|
|
253
|
+
if (!window.object) continue;
|
|
254
|
+
const uuid = window.object.uuid;
|
|
255
|
+
lastState.openWindows.push({
|
|
256
|
+
uuid: uuid,
|
|
257
|
+
position: window.position
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
game.settings.set("${id}", "hotReloadLastState", lastState).then(() =>
|
|
261
|
+
{
|
|
262
|
+
// Reload the page
|
|
263
|
+
window.location.reload(true);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
266
|
`.appendNewLineIfNotEmpty();
|
|
267
267
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
268
268
|
}
|
|
@@ -272,12 +272,12 @@ function generateRenderChatLogHookMjs(entry, id, destination) {
|
|
|
272
272
|
if (!fs.existsSync(generatedFileDir)) {
|
|
273
273
|
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
274
274
|
}
|
|
275
|
-
const fileNode = expandToNode `
|
|
276
|
-
import ${entry.config.name}ChatCard from "../documents/chat-card.mjs";
|
|
277
|
-
|
|
278
|
-
export function renderChatLog(app, html, data) {
|
|
279
|
-
${entry.config.name}ChatCard.activateListeners(html);
|
|
280
|
-
}
|
|
275
|
+
const fileNode = expandToNode `
|
|
276
|
+
import ${entry.config.name}ChatCard from "../documents/chat-card.mjs";
|
|
277
|
+
|
|
278
|
+
export function renderChatLog(app, html, data) {
|
|
279
|
+
${entry.config.name}ChatCard.activateListeners(html);
|
|
280
|
+
}
|
|
281
281
|
`.appendNewLineIfNotEmpty();
|
|
282
282
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
283
283
|
}
|
|
@@ -287,33 +287,33 @@ function generateRenderSettingsHookMjs(entry, id, destination) {
|
|
|
287
287
|
if (!fs.existsSync(generatedFileDir)) {
|
|
288
288
|
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
289
289
|
}
|
|
290
|
-
const fileNode = expandToNode `
|
|
291
|
-
// Adds an "ISDL" version row to the Foundry Settings sidebar, next to the
|
|
292
|
-
// system info, showing which version of ISDL generated this system.
|
|
293
|
-
export function renderSettings(app, html) {
|
|
294
|
-
const root = html instanceof HTMLElement ? html : html?.[0];
|
|
295
|
-
if (!root) return;
|
|
296
|
-
|
|
297
|
-
const info = root.querySelector("section.info");
|
|
298
|
-
if (!info || info.querySelector(".isdl-version")) return;
|
|
299
|
-
|
|
300
|
-
const version = game.system.flags?.["isdl-version"] ?? "unknown";
|
|
301
|
-
|
|
302
|
-
const row = document.createElement("div");
|
|
303
|
-
row.classList.add("isdl-version");
|
|
304
|
-
const label = document.createElement("span");
|
|
305
|
-
label.classList.add("label");
|
|
306
|
-
label.textContent = "ISDL";
|
|
307
|
-
const value = document.createElement("span");
|
|
308
|
-
value.classList.add("value");
|
|
309
|
-
value.textContent = version;
|
|
310
|
-
row.append(label, value);
|
|
311
|
-
|
|
312
|
-
// Place it right after the system row when present, else append.
|
|
313
|
-
const systemRow = info.querySelector(".system");
|
|
314
|
-
if (systemRow) systemRow.after(row);
|
|
315
|
-
else info.appendChild(row);
|
|
316
|
-
}
|
|
290
|
+
const fileNode = expandToNode `
|
|
291
|
+
// Adds an "ISDL" version row to the Foundry Settings sidebar, next to the
|
|
292
|
+
// system info, showing which version of ISDL generated this system.
|
|
293
|
+
export function renderSettings(app, html) {
|
|
294
|
+
const root = html instanceof HTMLElement ? html : html?.[0];
|
|
295
|
+
if (!root) return;
|
|
296
|
+
|
|
297
|
+
const info = root.querySelector("section.info");
|
|
298
|
+
if (!info || info.querySelector(".isdl-version")) return;
|
|
299
|
+
|
|
300
|
+
const version = game.system.flags?.["isdl-version"] ?? "unknown";
|
|
301
|
+
|
|
302
|
+
const row = document.createElement("div");
|
|
303
|
+
row.classList.add("isdl-version");
|
|
304
|
+
const label = document.createElement("span");
|
|
305
|
+
label.classList.add("label");
|
|
306
|
+
label.textContent = "ISDL";
|
|
307
|
+
const value = document.createElement("span");
|
|
308
|
+
value.classList.add("value");
|
|
309
|
+
value.textContent = version;
|
|
310
|
+
row.append(label, value);
|
|
311
|
+
|
|
312
|
+
// Place it right after the system row when present, else append.
|
|
313
|
+
const systemRow = info.querySelector(".system");
|
|
314
|
+
if (systemRow) systemRow.after(row);
|
|
315
|
+
else info.appendChild(row);
|
|
316
|
+
}
|
|
317
317
|
`.appendNewLineIfNotEmpty();
|
|
318
318
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
319
319
|
}
|
|
@@ -323,263 +323,268 @@ function generateExtendedRoll(entry, id, destination) {
|
|
|
323
323
|
if (!fs.existsSync(generatedFileDir)) {
|
|
324
324
|
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
325
325
|
}
|
|
326
|
-
const fileNode = expandToNode `
|
|
327
|
-
export default class ${entry.config.name}Roll extends Roll {
|
|
328
|
-
async getTooltip() {
|
|
329
|
-
const parts = [];
|
|
330
|
-
|
|
331
|
-
for ( const term of this.terms ) {
|
|
332
|
-
if ( foundry.utils.isSubclass(term.constructor, foundry.dice.terms.DiceTerm) ) {
|
|
333
|
-
parts.push(term.getTooltipData());
|
|
334
|
-
}
|
|
335
|
-
else if ( foundry.utils.isSubclass(term.constructor, foundry.dice.terms.NumericTerm) ) {
|
|
336
|
-
parts.push({
|
|
337
|
-
formula: term.flavor,
|
|
338
|
-
total: term.total,
|
|
339
|
-
faces: null,
|
|
340
|
-
flavor: "",
|
|
341
|
-
rolls: []
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
return renderTemplate(this.constructor.TOOLTIP_TEMPLATE, { parts });
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/* -------------------------------------------- */
|
|
350
|
-
|
|
351
|
-
get cleanFormula() {
|
|
352
|
-
// Replace flavor terms such as 5[STR] with just the flavor text
|
|
353
|
-
let cleanFormula = this._formula;
|
|
354
|
-
for ( const term of this.terms ) {
|
|
355
|
-
if ( term.formula && term.flavor ) {
|
|
356
|
-
cleanFormula = cleanFormula.replace(term.formula, term.flavor);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// If there are still parts of the formula such as 5[STR] then replace them with just the flavor text
|
|
361
|
-
const rgx = new RegExp(/(\\d+)\\[(.*?)\\]/g);
|
|
362
|
-
cleanFormula = cleanFormula.replace(rgx, "$2");
|
|
363
|
-
|
|
364
|
-
return cleanFormula;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
326
|
+
const fileNode = expandToNode `
|
|
327
|
+
export default class ${entry.config.name}Roll extends Roll {
|
|
328
|
+
async getTooltip() {
|
|
329
|
+
const parts = [];
|
|
330
|
+
|
|
331
|
+
for ( const term of this.terms ) {
|
|
332
|
+
if ( foundry.utils.isSubclass(term.constructor, foundry.dice.terms.DiceTerm) ) {
|
|
333
|
+
parts.push(term.getTooltipData());
|
|
334
|
+
}
|
|
335
|
+
else if ( foundry.utils.isSubclass(term.constructor, foundry.dice.terms.NumericTerm) ) {
|
|
336
|
+
parts.push({
|
|
337
|
+
formula: term.flavor,
|
|
338
|
+
total: term.total,
|
|
339
|
+
faces: null,
|
|
340
|
+
flavor: "",
|
|
341
|
+
rolls: []
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return renderTemplate(this.constructor.TOOLTIP_TEMPLATE, { parts });
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/* -------------------------------------------- */
|
|
350
|
+
|
|
351
|
+
get cleanFormula() {
|
|
352
|
+
// Replace flavor terms such as 5[STR] with just the flavor text
|
|
353
|
+
let cleanFormula = this._formula;
|
|
354
|
+
for ( const term of this.terms ) {
|
|
355
|
+
if ( term.formula && term.flavor ) {
|
|
356
|
+
cleanFormula = cleanFormula.replace(term.formula, term.flavor);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// If there are still parts of the formula such as 5[STR] then replace them with just the flavor text
|
|
361
|
+
const rgx = new RegExp(/(\\d+)\\[(.*?)\\]/g);
|
|
362
|
+
cleanFormula = cleanFormula.replace(rgx, "$2");
|
|
363
|
+
|
|
364
|
+
return cleanFormula;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
367
|
`.appendNewLineIfNotEmpty();
|
|
368
368
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
369
369
|
}
|
|
370
370
|
function generateContextMenu2(entry, id, destination) {
|
|
371
371
|
const generatedFilePath = path.join(destination, "system", "contextMenu2.js");
|
|
372
|
-
const fileNode = expandToNode `
|
|
373
|
-
export class ContextMenu2 {
|
|
374
|
-
constructor(element, selector, menuItems, {eventName="contextmenu"}={}) {
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* The target HTMLElement being selected
|
|
378
|
-
* @type {HTMLElement}
|
|
379
|
-
*/
|
|
380
|
-
this.element = element;
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* The target CSS selector which activates the menu
|
|
384
|
-
* @type {String}
|
|
385
|
-
*/
|
|
386
|
-
this.selector = selector || element.attr("id");
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* An interaction event name which activates the menu
|
|
390
|
-
* @type {String}
|
|
391
|
-
*/
|
|
392
|
-
this.eventName = eventName;
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* The array of menu items being rendered
|
|
396
|
-
* @type {Array}
|
|
397
|
-
*/
|
|
398
|
-
this.menuItems = menuItems;
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* Track which direction the menu is expanded in
|
|
402
|
-
* @type {Boolean}
|
|
403
|
-
*/
|
|
404
|
-
this._expandUp = false;
|
|
405
|
-
|
|
406
|
-
// Bind to the current element
|
|
407
|
-
this.bind();
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
/* -------------------------------------------- */
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* A convenience accessor to the context menu HTML object
|
|
414
|
-
* @return {*|jQuery.fn.init|jQuery|HTMLElement}
|
|
415
|
-
*/
|
|
416
|
-
get menu() {
|
|
417
|
-
return $("#context-menu2");
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
/* -------------------------------------------- */
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Attach a ContextMenu instance to an HTML selector
|
|
424
|
-
*/
|
|
425
|
-
bind() {
|
|
426
|
-
this.element.on(this.eventName, this.selector, event => {
|
|
427
|
-
event.preventDefault();
|
|
428
|
-
event.stopPropagation();
|
|
429
|
-
let parent = $(event.currentTarget)
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
//
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
this.render(parent);
|
|
443
|
-
ui.context = this;
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
menu.
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
let
|
|
485
|
-
|
|
486
|
-
html.append(
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
let
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
button.
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
li.
|
|
519
|
-
|
|
520
|
-
e.
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
*
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
const
|
|
552
|
-
|
|
553
|
-
//
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
372
|
+
const fileNode = expandToNode `
|
|
373
|
+
export class ContextMenu2 {
|
|
374
|
+
constructor(element, selector, menuItems, {eventName="contextmenu"}={}) {
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* The target HTMLElement being selected
|
|
378
|
+
* @type {HTMLElement}
|
|
379
|
+
*/
|
|
380
|
+
this.element = element;
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* The target CSS selector which activates the menu
|
|
384
|
+
* @type {String}
|
|
385
|
+
*/
|
|
386
|
+
this.selector = selector || element.attr("id");
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* An interaction event name which activates the menu
|
|
390
|
+
* @type {String}
|
|
391
|
+
*/
|
|
392
|
+
this.eventName = eventName;
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* The array of menu items being rendered
|
|
396
|
+
* @type {Array}
|
|
397
|
+
*/
|
|
398
|
+
this.menuItems = menuItems;
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Track which direction the menu is expanded in
|
|
402
|
+
* @type {Boolean}
|
|
403
|
+
*/
|
|
404
|
+
this._expandUp = false;
|
|
405
|
+
|
|
406
|
+
// Bind to the current element
|
|
407
|
+
this.bind();
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* -------------------------------------------- */
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* A convenience accessor to the context menu HTML object
|
|
414
|
+
* @return {*|jQuery.fn.init|jQuery|HTMLElement}
|
|
415
|
+
*/
|
|
416
|
+
get menu() {
|
|
417
|
+
return $("#context-menu2");
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* -------------------------------------------- */
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Attach a ContextMenu instance to an HTML selector
|
|
424
|
+
*/
|
|
425
|
+
bind() {
|
|
426
|
+
this.element.on(this.eventName, this.selector, event => {
|
|
427
|
+
event.preventDefault();
|
|
428
|
+
event.stopPropagation();
|
|
429
|
+
let parent = $(event.currentTarget);
|
|
430
|
+
|
|
431
|
+
if (this.selector == ".message") return;
|
|
432
|
+
|
|
433
|
+
// Remove existing context UI
|
|
434
|
+
$('.context').removeClass("context");
|
|
435
|
+
|
|
436
|
+
// The menu mounts on <body> (not inside the target), so a fresh right-click can't
|
|
437
|
+
// rely on DOM containment to toggle. Tear down any open menu immediately to avoid
|
|
438
|
+
// duplicates/animation races, then open a fresh one anchored to this target.
|
|
439
|
+
$("#context-menu2").stop(true, true).remove();
|
|
440
|
+
if ( ui.context ) delete ui.context;
|
|
441
|
+
|
|
442
|
+
this.render(parent);
|
|
443
|
+
ui.context = this;
|
|
444
|
+
})
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/* -------------------------------------------- */
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Animate closing the menu by sliding up and removing from the DOM
|
|
451
|
+
*/
|
|
452
|
+
async close() {
|
|
453
|
+
let menu = this.menu;
|
|
454
|
+
await this._animateClose(menu);
|
|
455
|
+
menu.remove();
|
|
456
|
+
$('.context').removeClass("context");
|
|
457
|
+
delete ui.context;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/* -------------------------------------------- */
|
|
461
|
+
|
|
462
|
+
async _animateOpen(menu) {
|
|
463
|
+
menu.hide();
|
|
464
|
+
return new Promise(resolve => menu.slideDown(200, resolve));
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/* -------------------------------------------- */
|
|
468
|
+
|
|
469
|
+
async _animateClose(menu) {
|
|
470
|
+
return new Promise(resolve => menu.slideUp(200, resolve));
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/* -------------------------------------------- */
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Render the Context Menu by iterating over the menuItems it contains
|
|
477
|
+
* Check the visibility of each menu item, and only render ones which are allowed by the item's logical condition
|
|
478
|
+
* Attach a click handler to each item which is rendered
|
|
479
|
+
* @param target
|
|
480
|
+
*/
|
|
481
|
+
render(target) {
|
|
482
|
+
// Always a fresh node -- bind() removed any prior menu, so appending h2/items here
|
|
483
|
+
// can't accumulate onto a reused element.
|
|
484
|
+
let html = $('<nav id="context-menu2" data-mod="1"></nav>');
|
|
485
|
+
let ol = $('<ol class="context-items"></ol>');
|
|
486
|
+
html.append($(\`<h2>\${game.i18n.localize('CONTEXT.ApplyChanges')}</h2>\`));
|
|
487
|
+
html.append(ol);
|
|
488
|
+
|
|
489
|
+
// Determine if user-selected targets are allowed.
|
|
490
|
+
const allowTargeting = game.settings.get('${id}', 'allowTargetDamageApplication');
|
|
491
|
+
let targetType = game.settings.get('${id}', 'userTargetDamageApplicationType');
|
|
492
|
+
if (!allowTargeting && targetType !== 'selected') {
|
|
493
|
+
game.settings.set('${id}', 'userTargetDamageApplicationType', 'selected');
|
|
494
|
+
targetType = 'selected';
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// Add default target type.
|
|
498
|
+
html[0].dataset.target = targetType;
|
|
499
|
+
|
|
500
|
+
// Build menu items
|
|
501
|
+
for (let item of this.menuItems) {
|
|
502
|
+
|
|
503
|
+
// Determine menu item visibility (display unless false)
|
|
504
|
+
let display = true;
|
|
505
|
+
if ( item.condition !== undefined ) {
|
|
506
|
+
display = ( item.condition instanceof Function ) ? item.condition(target) : item.condition;
|
|
507
|
+
}
|
|
508
|
+
if ( !display ) continue;
|
|
509
|
+
|
|
510
|
+
// Construct and add the menu item
|
|
511
|
+
let name = game.i18n.localize(item.name);
|
|
512
|
+
let li = $(\`<li class="context-item \${item?.id ?? ''}">\${item.icon}\${name}</li>\`);
|
|
513
|
+
// If this is the target buttons option, set one of them to active.
|
|
514
|
+
if (name.includes('data-target="targeted"')) {
|
|
515
|
+
const button = li.find(\`[data-target="\${targetType}"]\`);
|
|
516
|
+
button.addClass('active');
|
|
517
|
+
}
|
|
518
|
+
li.children("i").addClass("fa-fw");
|
|
519
|
+
li.click(e => {
|
|
520
|
+
e.preventDefault();
|
|
521
|
+
e.stopPropagation();
|
|
522
|
+
item.callback(target, e);
|
|
523
|
+
// If this was a target button, prevent closing the context menu.
|
|
524
|
+
if (!item?.preventClose) {
|
|
525
|
+
this.close();
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
ol.append(li);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// Bail out if there are no children
|
|
532
|
+
if ( ol.children().length === 0 ) return;
|
|
533
|
+
|
|
534
|
+
// Append to target
|
|
535
|
+
this._setPosition(html, target);
|
|
536
|
+
|
|
537
|
+
// Deactivate global tooltip
|
|
538
|
+
game.tooltip.deactivate();
|
|
539
|
+
|
|
540
|
+
// Animate open the menu
|
|
541
|
+
return this._animateOpen(html);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/* -------------------------------------------- */
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Set the position of the context menu, taking into consideration whether the menu should expand upward or downward
|
|
548
|
+
* @private
|
|
549
|
+
*/
|
|
550
|
+
_setPosition(html, target) {
|
|
551
|
+
const targetRect = target[0].getBoundingClientRect();
|
|
552
|
+
|
|
553
|
+
// Mount on <body> with fixed positioning so the menu escapes the chat log's overflow
|
|
554
|
+
// clipping (#chat-log is overflow-x:hidden / overflow-y:auto) and any transformed sheet
|
|
555
|
+
// ancestor. We then place it explicitly in viewport coordinates.
|
|
556
|
+
html.css("visibility", "hidden");
|
|
557
|
+
document.body.appendChild(html[0]);
|
|
558
|
+
const contextRect = html[0].getBoundingClientRect();
|
|
559
|
+
|
|
560
|
+
// Expand upward only when there isn't room below the target but there is above it.
|
|
561
|
+
const roomBelow = window.innerHeight - targetRect.bottom;
|
|
562
|
+
this._expandUp = (roomBelow < contextRect.height) && (targetRect.top > contextRect.height);
|
|
563
|
+
const top = this._expandUp
|
|
564
|
+
? targetRect.top - contextRect.height - 2
|
|
565
|
+
: targetRect.bottom + 2;
|
|
566
|
+
|
|
567
|
+
// Align to the target's left edge, clamped to stay within the viewport.
|
|
568
|
+
let left = targetRect.left;
|
|
569
|
+
const maxLeft = window.innerWidth - contextRect.width - 4;
|
|
570
|
+
if (left > maxLeft) left = maxLeft;
|
|
571
|
+
if (left < 4) left = 4;
|
|
572
|
+
|
|
573
|
+
// Display the menu
|
|
574
|
+
html.css({ top: Math.round(top) + "px", left: Math.round(left) + "px" });
|
|
575
|
+
html.addClass(this._expandUp ? "expand-up" : "expand-down");
|
|
576
|
+
html.css("visibility", "");
|
|
577
|
+
target.addClass("context");
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/* -------------------------------------------- */
|
|
581
|
+
|
|
582
|
+
static eventListeners() {
|
|
583
|
+
document.addEventListener("click", ev => {
|
|
584
|
+
if ( ui.context ) ui.context.close();
|
|
585
|
+
});
|
|
586
|
+
};
|
|
587
|
+
}
|
|
583
588
|
`.appendNewLineIfNotEmpty();
|
|
584
589
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
585
590
|
}
|
|
@@ -589,30 +594,30 @@ function generateDocumentCreateHbs(entry, id, destination) {
|
|
|
589
594
|
if (!fs.existsSync(generatedFileDir)) {
|
|
590
595
|
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
591
596
|
}
|
|
592
|
-
const fileNode = expandToNode `
|
|
593
|
-
<form id="document-create" autocomplete="off">
|
|
594
|
-
<header>
|
|
595
|
-
<input type="text" class="document-name uninput" name="name" value="{{ name }}" autofocus
|
|
596
|
-
placeholder="{{ localize 'Name' }}">
|
|
597
|
-
{{#if hasFolders}}
|
|
598
|
-
<select class="unselect" name="folder" form="document-create">
|
|
599
|
-
{{ selectOptions folders selected=folder labelAttr="name" valueAttr="id"
|
|
600
|
-
blank=(localize "DOCUMENT.Folder") }}
|
|
601
|
-
</select>
|
|
602
|
-
{{/if}}
|
|
603
|
-
</header>
|
|
604
|
-
<ol class="unlist card">
|
|
605
|
-
{{#each types}}
|
|
606
|
-
<li data-tooltip="{{ description }}">
|
|
607
|
-
<label>
|
|
608
|
-
<img src="{{ icon }}" alt="{{ label }}">
|
|
609
|
-
<span>{{ label }}</span>
|
|
610
|
-
<input type="radio" name="type" value="{{ type }}" required {{#if selected}}checked{{/if}}>
|
|
611
|
-
</label>
|
|
612
|
-
</li>
|
|
613
|
-
{{/each}}
|
|
614
|
-
</ol>
|
|
615
|
-
</form>
|
|
597
|
+
const fileNode = expandToNode `
|
|
598
|
+
<form id="document-create" autocomplete="off">
|
|
599
|
+
<header>
|
|
600
|
+
<input type="text" class="document-name uninput" name="name" value="{{ name }}" autofocus
|
|
601
|
+
placeholder="{{ localize 'Name' }}">
|
|
602
|
+
{{#if hasFolders}}
|
|
603
|
+
<select class="unselect" name="folder" form="document-create">
|
|
604
|
+
{{ selectOptions folders selected=folder labelAttr="name" valueAttr="id"
|
|
605
|
+
blank=(localize "DOCUMENT.Folder") }}
|
|
606
|
+
</select>
|
|
607
|
+
{{/if}}
|
|
608
|
+
</header>
|
|
609
|
+
<ol class="unlist card">
|
|
610
|
+
{{#each types}}
|
|
611
|
+
<li data-tooltip="{{ description }}">
|
|
612
|
+
<label>
|
|
613
|
+
<img src="{{ icon }}" alt="{{ label }}">
|
|
614
|
+
<span>{{ label }}</span>
|
|
615
|
+
<input type="radio" name="type" value="{{ type }}" required {{#if selected}}checked{{/if}}>
|
|
616
|
+
</label>
|
|
617
|
+
</li>
|
|
618
|
+
{{/each}}
|
|
619
|
+
</ol>
|
|
620
|
+
</form>
|
|
616
621
|
`.appendNewLineIfNotEmpty();
|
|
617
622
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
618
623
|
}
|
|
@@ -622,12 +627,12 @@ function generateCombatant(entry, id, destination) {
|
|
|
622
627
|
if (!fs.existsSync(generatedFileDir)) {
|
|
623
628
|
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
624
629
|
}
|
|
625
|
-
const fileNode = expandToNode `
|
|
626
|
-
export default class ${entry.config.name}Combatant extends Combatant {
|
|
627
|
-
_getInitiativeFormula() {
|
|
628
|
-
return String(CONFIG.Combat.initiative.formula || game.system.initiative || this.actor.getInitiativeFormula());
|
|
629
|
-
}
|
|
630
|
-
}
|
|
630
|
+
const fileNode = expandToNode `
|
|
631
|
+
export default class ${entry.config.name}Combatant extends Combatant {
|
|
632
|
+
_getInitiativeFormula() {
|
|
633
|
+
return String(CONFIG.Combat.initiative.formula || game.system.initiative || this.actor.getInitiativeFormula());
|
|
634
|
+
}
|
|
635
|
+
}
|
|
631
636
|
`.appendNewLineIfNotEmpty();
|
|
632
637
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
633
638
|
}
|