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
|
@@ -20,32 +20,32 @@ export function generateBaseActiveEffectBaseSheet(entry, id, destination) {
|
|
|
20
20
|
if (property.modifier == "locked")
|
|
21
21
|
return;
|
|
22
22
|
if (isResourceExp(property)) {
|
|
23
|
-
return expandToNode `
|
|
24
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value", 1);
|
|
25
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max");
|
|
23
|
+
return expandToNode `
|
|
24
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value", 1);
|
|
25
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max");
|
|
26
26
|
`;
|
|
27
27
|
}
|
|
28
28
|
if (isTrackerExp(property)) {
|
|
29
|
-
return expandToNode `
|
|
30
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min");
|
|
31
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value", 1);
|
|
32
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp", 1);
|
|
33
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max");
|
|
29
|
+
return expandToNode `
|
|
30
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min");
|
|
31
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value", 1);
|
|
32
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp", 1);
|
|
33
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max");
|
|
34
34
|
`;
|
|
35
35
|
}
|
|
36
36
|
if (isAttributeExp(property)) {
|
|
37
|
-
return expandToNode `
|
|
38
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value");
|
|
39
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max");
|
|
37
|
+
return expandToNode `
|
|
38
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value");
|
|
39
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max");
|
|
40
40
|
`;
|
|
41
41
|
}
|
|
42
42
|
if (isNumberExp(property)) {
|
|
43
|
-
return expandToNode `
|
|
44
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}", 1);
|
|
43
|
+
return expandToNode `
|
|
44
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${property.name.toLowerCase()}", 1);
|
|
45
45
|
`;
|
|
46
46
|
}
|
|
47
|
-
return expandToNode `
|
|
48
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.${getSystemPath(property)}");
|
|
47
|
+
return expandToNode `
|
|
48
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.${getSystemPath(property)}");
|
|
49
49
|
`;
|
|
50
50
|
}
|
|
51
51
|
function generateDamageTypeActiveEffectFields(entry, document) {
|
|
@@ -57,16 +57,16 @@ export function generateBaseActiveEffectBaseSheet(entry, id, destination) {
|
|
|
57
57
|
}
|
|
58
58
|
const damageTypeFields = damageTypes.map(damageType => {
|
|
59
59
|
const safeTypeName = damageType.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
60
|
-
return expandToNode `
|
|
61
|
-
// ${damageType} damage type Active Effect fields
|
|
62
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${safeTypeName}bonusdamage");
|
|
63
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${safeTypeName}damageresistanceflat");
|
|
64
|
-
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${safeTypeName}damageresistancepercent");
|
|
60
|
+
return expandToNode `
|
|
61
|
+
// ${damageType} damage type Active Effect fields
|
|
62
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${safeTypeName}bonusdamage");
|
|
63
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${safeTypeName}damageresistanceflat");
|
|
64
|
+
addChange("${document.name.toLowerCase()}", "${document.name.toLowerCase()}.system.${safeTypeName}damageresistancepercent");
|
|
65
65
|
`;
|
|
66
66
|
});
|
|
67
|
-
return expandToNode `
|
|
68
|
-
// Auto-generated damage type Active Effect fields
|
|
69
|
-
${joinToNode(damageTypeFields, field => field, { appendNewLineIfNotEmpty: true })}
|
|
67
|
+
return expandToNode `
|
|
68
|
+
// Auto-generated damage type Active Effect fields
|
|
69
|
+
${joinToNode(damageTypeFields, field => field, { appendNewLineIfNotEmpty: true })}
|
|
70
70
|
`;
|
|
71
71
|
}
|
|
72
72
|
// Collect all damage types from the entry (same function as in datamodel-generator)
|
|
@@ -120,297 +120,297 @@ export function generateBaseActiveEffectBaseSheet(entry, id, destination) {
|
|
|
120
120
|
// };
|
|
121
121
|
// `;
|
|
122
122
|
// }
|
|
123
|
-
const fileNode = expandToNode `
|
|
124
|
-
import VueRenderingMixin from './VueRenderingMixin.mjs';
|
|
125
|
-
import { ActiveEffectApp } from "./components/components.vue.es.mjs";
|
|
126
|
-
const { DOCUMENT_OWNERSHIP_LEVELS } = CONST;
|
|
127
|
-
export default class ${entry.config.name}EffectVueSheet extends VueRenderingMixin(foundry.applications.api.DocumentSheetV2) {
|
|
128
|
-
|
|
129
|
-
vueParts = {
|
|
130
|
-
"active-effect": {
|
|
131
|
-
component: ActiveEffectApp,
|
|
132
|
-
template: "<active-effect :context=\\"context\\">Vue rendering for sheet failed.</active-effect>"
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
_arrayEntryKey = 0;
|
|
137
|
-
_renderKey = 0;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
/** @override */
|
|
141
|
-
static DEFAULT_OPTIONS = {
|
|
142
|
-
classes: ["${id}", "sheet", "vue-sheet", "active-effect", "active-effect-sheet"],
|
|
143
|
-
viewPermission: DOCUMENT_OWNERSHIP_LEVELS.LIMITED,
|
|
144
|
-
editPermission: DOCUMENT_OWNERSHIP_LEVELS.OWNER,
|
|
145
|
-
position: {
|
|
146
|
-
width: 600,
|
|
147
|
-
height: 600,
|
|
148
|
-
},
|
|
149
|
-
window: {
|
|
150
|
-
resizable: true,
|
|
151
|
-
title: "Active Effect"
|
|
152
|
-
},
|
|
153
|
-
tag: "form",
|
|
154
|
-
actions: {
|
|
155
|
-
onEditImage: this._onEditImage
|
|
156
|
-
},
|
|
157
|
-
changeActions: {
|
|
158
|
-
},
|
|
159
|
-
// Custom property that's merged into this.options
|
|
160
|
-
dragDrop: [
|
|
161
|
-
],
|
|
162
|
-
form: {
|
|
163
|
-
handler: ${entry.config.name}EffectVueSheet._onSubmitForm,
|
|
164
|
-
submitOnChange: false,
|
|
165
|
-
submitOnClose: true,
|
|
166
|
-
closeOnSubmit: false
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
/* -------------------------------------------- */
|
|
171
|
-
|
|
172
|
-
static async _onEditImage(event, target) {
|
|
173
|
-
const current = foundry.utils.getProperty(this.document, target.dataset.edit);
|
|
174
|
-
const fp = new FilePicker({
|
|
175
|
-
current,
|
|
176
|
-
type: "image",
|
|
177
|
-
callback: (path) => {
|
|
178
|
-
this.document.update({ [target.dataset.edit]: path });
|
|
179
|
-
},
|
|
180
|
-
top: this.position.top + 40,
|
|
181
|
-
left: this.position.left + 10
|
|
182
|
-
});
|
|
183
|
-
return fp.browse();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/* -------------------------------------------- */
|
|
187
|
-
|
|
188
|
-
async _prepareContext(options) {
|
|
189
|
-
const context = await super._prepareContext(options);
|
|
190
|
-
this.object = this.document.toObject();
|
|
191
|
-
context.effect = this.object;
|
|
192
|
-
context.descriptionHTML = await TextEditor.enrichHTML(this.object.description, {secrets: this.object.isOwner});
|
|
193
|
-
|
|
194
|
-
// Status Conditions
|
|
195
|
-
const statuses = CONFIG.statusEffects.map(s => {
|
|
196
|
-
return {
|
|
197
|
-
id: s.id,
|
|
198
|
-
label: game.i18n.localize(s.name),
|
|
199
|
-
selected: context.effect.statuses.includes(s.id) ? "selected" : ""
|
|
200
|
-
};
|
|
201
|
-
});
|
|
202
|
-
context.statuses = statuses;
|
|
203
|
-
if ( context.effect.origin ) {
|
|
204
|
-
context.originLink = await TextEditor.enrichHTML("@UUID[" + context.effect.origin + "]");
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function setValue(obj, access, value, mode) {
|
|
208
|
-
if ( typeof(access)=='string' ) {
|
|
209
|
-
access = access.split('.');
|
|
210
|
-
}
|
|
211
|
-
// Split up an access path into sub-objects, such as "system.attribute.value" => "system": {"attribute": {"value": ...}}
|
|
212
|
-
if ( access.length > 1 ) {
|
|
213
|
-
const key = access.shift();
|
|
214
|
-
if ( !obj[key] ) obj[key] = {};
|
|
215
|
-
setValue(obj[key], access, value, mode);
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
obj[access[0]] = value;
|
|
219
|
-
obj[access[0] + "-mode"] = mode;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Turn the changes into the friendlier format
|
|
224
|
-
for ( const change of context.effect.changes ) {
|
|
225
|
-
setValue(context, change.key, change.value, change.mode);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Output initialization
|
|
229
|
-
const vueContext = {
|
|
230
|
-
// Validates both permissions and compendium status
|
|
231
|
-
editable: this.isEditable,
|
|
232
|
-
owner: this.document.isOwner,
|
|
233
|
-
limited: this.document.limited,
|
|
234
|
-
|
|
235
|
-
// Add the document.
|
|
236
|
-
object: context.effect,
|
|
237
|
-
document: this.document,
|
|
238
|
-
|
|
239
|
-
// Add the data to context.data for easier access, as well as flags.
|
|
240
|
-
system: this.document.system,
|
|
241
|
-
flags: this.document.flags,
|
|
242
|
-
|
|
243
|
-
// Editors
|
|
244
|
-
editors: {},
|
|
245
|
-
|
|
246
|
-
// Force re-renders. Defined in the vue mixin.
|
|
247
|
-
_renderKey: this._renderKey ?? 0,
|
|
248
|
-
_arrayEntryKey: this._arrayEntryKey ?? 0,
|
|
249
|
-
isItemEffect: this.document.parent.documentName === "Item",
|
|
250
|
-
originLink: context.originLink
|
|
251
|
-
// tabs: this._getTabs(options.parts),
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
await this._enrichEditor(vueContext, "description");
|
|
255
|
-
|
|
256
|
-
const numberTypes = ['multiply', 'add', 'downgrade', 'upgrade', 'override'];
|
|
257
|
-
const stringTypes = ['override'];
|
|
258
|
-
const booleanTypes = ['override'];
|
|
259
|
-
|
|
260
|
-
vueContext.numberModes = numberTypes.map(type => ({
|
|
261
|
-
value: type,
|
|
262
|
-
label: game.i18n.localize(\`EFFECT.CHANGES.TYPES.\${type}\`)
|
|
263
|
-
}));
|
|
264
|
-
vueContext.numberModes.push({
|
|
265
|
-
value: 'custom',
|
|
266
|
-
label: game.i18n.localize("EFFECTS.AddOnce")
|
|
267
|
-
});
|
|
268
|
-
vueContext.basicNumberModes = numberTypes.map(type => ({
|
|
269
|
-
value: type,
|
|
270
|
-
label: game.i18n.localize(\`EFFECT.CHANGES.TYPES.\${type}\`)
|
|
271
|
-
}));
|
|
272
|
-
vueContext.stringModes = stringTypes.map(type => ({
|
|
273
|
-
value: type,
|
|
274
|
-
label: game.i18n.localize(\`EFFECT.CHANGES.TYPES.\${type}\`)
|
|
275
|
-
}));
|
|
276
|
-
vueContext.booleanModes = booleanTypes.map(type => ({
|
|
277
|
-
value: type,
|
|
278
|
-
label: game.i18n.localize(\`EFFECT.CHANGES.TYPES.\${type}\`)
|
|
279
|
-
}));
|
|
280
|
-
vueContext.resourceModes = [
|
|
281
|
-
{ value: 'custom', label: game.i18n.localize("EFFECTS.AddOnce") }
|
|
282
|
-
];
|
|
283
|
-
vueContext.trackerModes = [
|
|
284
|
-
{ value: 'custom', label: game.i18n.localize("EFFECTS.AddOnce") }
|
|
285
|
-
];
|
|
286
|
-
|
|
287
|
-
// Copy current change values into vueContext so the Vue component can read them
|
|
288
|
-
for ( const change of context.effect.changes ) {
|
|
289
|
-
setValue(vueContext, change.key, change.value, change.mode);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
console.dir("Vue Active Effect Context", vueContext);
|
|
293
|
-
return vueContext;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
async _enrichEditor(context, field) {
|
|
298
|
-
const enrichmentOptions = {
|
|
299
|
-
// Whether to show secret blocks in the finished html
|
|
300
|
-
secrets: this.document.isOwner,
|
|
301
|
-
// Data to fill in for inline rolls
|
|
302
|
-
rollData: {},
|
|
303
|
-
// Relative UUID resolution
|
|
304
|
-
relativeTo: this.document
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
const editorOptions = {
|
|
308
|
-
toggled: true,
|
|
309
|
-
collaborate: true,
|
|
310
|
-
documentUUID: this.document.uuid,
|
|
311
|
-
height: 300
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
const editorValue = this.document.system?.[field] ?? foundry.utils.getProperty(this.document.system, field);
|
|
315
|
-
context.editors[\`\${field}\`] = {
|
|
316
|
-
enriched: await TextEditor.enrichHTML(editorValue, enrichmentOptions),
|
|
317
|
-
element: foundry.applications.elements.HTMLProseMirrorElement.create({
|
|
318
|
-
...editorOptions,
|
|
319
|
-
name: \`system.\${field}\`,
|
|
320
|
-
value: editorValue ?? ""
|
|
321
|
-
})
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/* -------------------------------------------- */
|
|
326
|
-
|
|
327
|
-
_prepareSubmitData(event, form, formData) {
|
|
328
|
-
// We don't modify the image via the sheet itself, so we can remove it from the submit data to avoid errors.
|
|
329
|
-
delete formData.object.img;
|
|
330
|
-
return super._prepareSubmitData(event, form, formData);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/* -------------------------------------------- */
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Process form submission for the sheet
|
|
337
|
-
* @this {${entry.config.name}EffectVueSheet} The handler is called with the application as its bound scope
|
|
338
|
-
* @param {SubmitEvent} event The originating form submission event
|
|
339
|
-
* @param {HTMLFormElement} form The form element that was submitted
|
|
340
|
-
* @param {FormDataExtended} formData Processed data for the submitted form
|
|
341
|
-
* @returns {Promise<void>}
|
|
342
|
-
*/
|
|
343
|
-
static async _onSubmitForm(event, form, formData) {
|
|
344
|
-
console.log("Updating Active Effect", formData);
|
|
345
|
-
const flags = foundry.utils.duplicate(this.document.flags);
|
|
346
|
-
if ( !flags["${id}"] ) {
|
|
347
|
-
flags["${id}"] = {};
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// Retrieve the existing effects.
|
|
351
|
-
let changes = this.document.changes ? [...this.document.changes] : [];
|
|
352
|
-
|
|
353
|
-
// Build an array of effects from the form data
|
|
354
|
-
let newChanges = [];
|
|
355
|
-
|
|
356
|
-
function addChange(documentName, key, customMode) {
|
|
357
|
-
const value = foundry.utils.getProperty(formData.object, key);
|
|
358
|
-
if ( value === undefined ) {
|
|
359
|
-
// Field not rendered in the form - preserve any existing change.
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
if ( !value ) {
|
|
363
|
-
// Field explicitly cleared (empty string / zero) - remove the change.
|
|
364
|
-
changes = changes.filter(c => c.key !== key);
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
const type = foundry.utils.getProperty(formData.object, key + "-type") ?? 'add';
|
|
368
|
-
newChanges.push({
|
|
369
|
-
key: key,
|
|
370
|
-
value: value,
|
|
371
|
-
type: type
|
|
372
|
-
});
|
|
373
|
-
if ( customMode ) flags["${id}"][key + "-custommode"] = customMode;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
${joinToNode(entry.documents.filter(d => isActor(d)), document => joinToNode(document.body, property => generateAddValue(document, property), { appendNewLineIfNotEmpty: true }))}
|
|
377
|
-
|
|
378
|
-
// Auto-generated damage type Active Effect fields
|
|
379
|
-
${joinToNode(entry.documents.filter(d => isActor(d)), document => generateDamageTypeActiveEffectFields(entry, document), { appendNewLineIfNotEmpty: true })}
|
|
380
|
-
|
|
381
|
-
// Update the existing changes to replace duplicates.
|
|
382
|
-
for (let i = 0; i < changes.length; i++) {
|
|
383
|
-
const newChange = newChanges.find(c => c.key == changes[i].key);
|
|
384
|
-
if (newChange) {
|
|
385
|
-
// Replace with the new change and update the array to prevent duplicates.
|
|
386
|
-
changes[i] = newChange;
|
|
387
|
-
newChanges = newChanges.filter(c => c.key != changes[i].key);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// Filter changes for empty form fields.
|
|
392
|
-
const finalChanges = changes.concat(newChanges).filter(c => c.value !== null && c.value !== undefined && c.value !== '');
|
|
393
|
-
console.log("Active Effect Changes", finalChanges);
|
|
394
|
-
await this.document.update({
|
|
395
|
-
name: formData.object.name,
|
|
396
|
-
description: formData.object.description ?? '',
|
|
397
|
-
disabled: formData.object.disabled ?? false,
|
|
398
|
-
transfer: formData.object.transfer ?? false,
|
|
399
|
-
changes: finalChanges,
|
|
400
|
-
flags: flags
|
|
401
|
-
});
|
|
402
|
-
|
|
403
|
-
// Rerender the parent sheets to update the effect lists.
|
|
404
|
-
this.document.parent?.sheet?.render();
|
|
405
|
-
if ( this.document.parent?.documentName === "Item" ) {
|
|
406
|
-
this.document.parent?.parent?.applyActiveEffects();
|
|
407
|
-
|
|
408
|
-
// Wait half a second
|
|
409
|
-
await new Promise(r => setTimeout(r, 500));
|
|
410
|
-
this.document.parent?.parent?.sheet?.render();
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
}
|
|
123
|
+
const fileNode = expandToNode `
|
|
124
|
+
import VueRenderingMixin from './VueRenderingMixin.mjs';
|
|
125
|
+
import { ActiveEffectApp } from "./components/components.vue.es.mjs";
|
|
126
|
+
const { DOCUMENT_OWNERSHIP_LEVELS } = CONST;
|
|
127
|
+
export default class ${entry.config.name}EffectVueSheet extends VueRenderingMixin(foundry.applications.api.DocumentSheetV2) {
|
|
128
|
+
|
|
129
|
+
vueParts = {
|
|
130
|
+
"active-effect": {
|
|
131
|
+
component: ActiveEffectApp,
|
|
132
|
+
template: "<active-effect :context=\\"context\\">Vue rendering for sheet failed.</active-effect>"
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
_arrayEntryKey = 0;
|
|
137
|
+
_renderKey = 0;
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
/** @override */
|
|
141
|
+
static DEFAULT_OPTIONS = {
|
|
142
|
+
classes: ["${id}", "sheet", "vue-sheet", "active-effect", "active-effect-sheet"],
|
|
143
|
+
viewPermission: DOCUMENT_OWNERSHIP_LEVELS.LIMITED,
|
|
144
|
+
editPermission: DOCUMENT_OWNERSHIP_LEVELS.OWNER,
|
|
145
|
+
position: {
|
|
146
|
+
width: 600,
|
|
147
|
+
height: 600,
|
|
148
|
+
},
|
|
149
|
+
window: {
|
|
150
|
+
resizable: true,
|
|
151
|
+
title: "Active Effect"
|
|
152
|
+
},
|
|
153
|
+
tag: "form",
|
|
154
|
+
actions: {
|
|
155
|
+
onEditImage: this._onEditImage
|
|
156
|
+
},
|
|
157
|
+
changeActions: {
|
|
158
|
+
},
|
|
159
|
+
// Custom property that's merged into this.options
|
|
160
|
+
dragDrop: [
|
|
161
|
+
],
|
|
162
|
+
form: {
|
|
163
|
+
handler: ${entry.config.name}EffectVueSheet._onSubmitForm,
|
|
164
|
+
submitOnChange: false,
|
|
165
|
+
submitOnClose: true,
|
|
166
|
+
closeOnSubmit: false
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/* -------------------------------------------- */
|
|
171
|
+
|
|
172
|
+
static async _onEditImage(event, target) {
|
|
173
|
+
const current = foundry.utils.getProperty(this.document, target.dataset.edit);
|
|
174
|
+
const fp = new FilePicker({
|
|
175
|
+
current,
|
|
176
|
+
type: "image",
|
|
177
|
+
callback: (path) => {
|
|
178
|
+
this.document.update({ [target.dataset.edit]: path });
|
|
179
|
+
},
|
|
180
|
+
top: this.position.top + 40,
|
|
181
|
+
left: this.position.left + 10
|
|
182
|
+
});
|
|
183
|
+
return fp.browse();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* -------------------------------------------- */
|
|
187
|
+
|
|
188
|
+
async _prepareContext(options) {
|
|
189
|
+
const context = await super._prepareContext(options);
|
|
190
|
+
this.object = this.document.toObject();
|
|
191
|
+
context.effect = this.object;
|
|
192
|
+
context.descriptionHTML = await TextEditor.enrichHTML(this.object.description, {secrets: this.object.isOwner});
|
|
193
|
+
|
|
194
|
+
// Status Conditions
|
|
195
|
+
const statuses = CONFIG.statusEffects.map(s => {
|
|
196
|
+
return {
|
|
197
|
+
id: s.id,
|
|
198
|
+
label: game.i18n.localize(s.name),
|
|
199
|
+
selected: context.effect.statuses.includes(s.id) ? "selected" : ""
|
|
200
|
+
};
|
|
201
|
+
});
|
|
202
|
+
context.statuses = statuses;
|
|
203
|
+
if ( context.effect.origin ) {
|
|
204
|
+
context.originLink = await TextEditor.enrichHTML("@UUID[" + context.effect.origin + "]");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function setValue(obj, access, value, mode) {
|
|
208
|
+
if ( typeof(access)=='string' ) {
|
|
209
|
+
access = access.split('.');
|
|
210
|
+
}
|
|
211
|
+
// Split up an access path into sub-objects, such as "system.attribute.value" => "system": {"attribute": {"value": ...}}
|
|
212
|
+
if ( access.length > 1 ) {
|
|
213
|
+
const key = access.shift();
|
|
214
|
+
if ( !obj[key] ) obj[key] = {};
|
|
215
|
+
setValue(obj[key], access, value, mode);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
obj[access[0]] = value;
|
|
219
|
+
obj[access[0] + "-mode"] = mode;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Turn the changes into the friendlier format
|
|
224
|
+
for ( const change of context.effect.changes ) {
|
|
225
|
+
setValue(context, change.key, change.value, change.mode);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Output initialization
|
|
229
|
+
const vueContext = {
|
|
230
|
+
// Validates both permissions and compendium status
|
|
231
|
+
editable: this.isEditable,
|
|
232
|
+
owner: this.document.isOwner,
|
|
233
|
+
limited: this.document.limited,
|
|
234
|
+
|
|
235
|
+
// Add the document.
|
|
236
|
+
object: context.effect,
|
|
237
|
+
document: this.document,
|
|
238
|
+
|
|
239
|
+
// Add the data to context.data for easier access, as well as flags.
|
|
240
|
+
system: this.document.system,
|
|
241
|
+
flags: this.document.flags,
|
|
242
|
+
|
|
243
|
+
// Editors
|
|
244
|
+
editors: {},
|
|
245
|
+
|
|
246
|
+
// Force re-renders. Defined in the vue mixin.
|
|
247
|
+
_renderKey: this._renderKey ?? 0,
|
|
248
|
+
_arrayEntryKey: this._arrayEntryKey ?? 0,
|
|
249
|
+
isItemEffect: this.document.parent.documentName === "Item",
|
|
250
|
+
originLink: context.originLink
|
|
251
|
+
// tabs: this._getTabs(options.parts),
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
await this._enrichEditor(vueContext, "description");
|
|
255
|
+
|
|
256
|
+
const numberTypes = ['multiply', 'add', 'downgrade', 'upgrade', 'override'];
|
|
257
|
+
const stringTypes = ['override'];
|
|
258
|
+
const booleanTypes = ['override'];
|
|
259
|
+
|
|
260
|
+
vueContext.numberModes = numberTypes.map(type => ({
|
|
261
|
+
value: type,
|
|
262
|
+
label: game.i18n.localize(\`EFFECT.CHANGES.TYPES.\${type}\`)
|
|
263
|
+
}));
|
|
264
|
+
vueContext.numberModes.push({
|
|
265
|
+
value: 'custom',
|
|
266
|
+
label: game.i18n.localize("EFFECTS.AddOnce")
|
|
267
|
+
});
|
|
268
|
+
vueContext.basicNumberModes = numberTypes.map(type => ({
|
|
269
|
+
value: type,
|
|
270
|
+
label: game.i18n.localize(\`EFFECT.CHANGES.TYPES.\${type}\`)
|
|
271
|
+
}));
|
|
272
|
+
vueContext.stringModes = stringTypes.map(type => ({
|
|
273
|
+
value: type,
|
|
274
|
+
label: game.i18n.localize(\`EFFECT.CHANGES.TYPES.\${type}\`)
|
|
275
|
+
}));
|
|
276
|
+
vueContext.booleanModes = booleanTypes.map(type => ({
|
|
277
|
+
value: type,
|
|
278
|
+
label: game.i18n.localize(\`EFFECT.CHANGES.TYPES.\${type}\`)
|
|
279
|
+
}));
|
|
280
|
+
vueContext.resourceModes = [
|
|
281
|
+
{ value: 'custom', label: game.i18n.localize("EFFECTS.AddOnce") }
|
|
282
|
+
];
|
|
283
|
+
vueContext.trackerModes = [
|
|
284
|
+
{ value: 'custom', label: game.i18n.localize("EFFECTS.AddOnce") }
|
|
285
|
+
];
|
|
286
|
+
|
|
287
|
+
// Copy current change values into vueContext so the Vue component can read them
|
|
288
|
+
for ( const change of context.effect.changes ) {
|
|
289
|
+
setValue(vueContext, change.key, change.value, change.mode);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
console.dir("Vue Active Effect Context", vueContext);
|
|
293
|
+
return vueContext;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
async _enrichEditor(context, field) {
|
|
298
|
+
const enrichmentOptions = {
|
|
299
|
+
// Whether to show secret blocks in the finished html
|
|
300
|
+
secrets: this.document.isOwner,
|
|
301
|
+
// Data to fill in for inline rolls
|
|
302
|
+
rollData: {},
|
|
303
|
+
// Relative UUID resolution
|
|
304
|
+
relativeTo: this.document
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const editorOptions = {
|
|
308
|
+
toggled: true,
|
|
309
|
+
collaborate: true,
|
|
310
|
+
documentUUID: this.document.uuid,
|
|
311
|
+
height: 300
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const editorValue = this.document.system?.[field] ?? foundry.utils.getProperty(this.document.system, field);
|
|
315
|
+
context.editors[\`\${field}\`] = {
|
|
316
|
+
enriched: await TextEditor.enrichHTML(editorValue, enrichmentOptions),
|
|
317
|
+
element: foundry.applications.elements.HTMLProseMirrorElement.create({
|
|
318
|
+
...editorOptions,
|
|
319
|
+
name: \`system.\${field}\`,
|
|
320
|
+
value: editorValue ?? ""
|
|
321
|
+
})
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* -------------------------------------------- */
|
|
326
|
+
|
|
327
|
+
_prepareSubmitData(event, form, formData) {
|
|
328
|
+
// We don't modify the image via the sheet itself, so we can remove it from the submit data to avoid errors.
|
|
329
|
+
delete formData.object.img;
|
|
330
|
+
return super._prepareSubmitData(event, form, formData);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* -------------------------------------------- */
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Process form submission for the sheet
|
|
337
|
+
* @this {${entry.config.name}EffectVueSheet} The handler is called with the application as its bound scope
|
|
338
|
+
* @param {SubmitEvent} event The originating form submission event
|
|
339
|
+
* @param {HTMLFormElement} form The form element that was submitted
|
|
340
|
+
* @param {FormDataExtended} formData Processed data for the submitted form
|
|
341
|
+
* @returns {Promise<void>}
|
|
342
|
+
*/
|
|
343
|
+
static async _onSubmitForm(event, form, formData) {
|
|
344
|
+
console.log("Updating Active Effect", formData);
|
|
345
|
+
const flags = foundry.utils.duplicate(this.document.flags);
|
|
346
|
+
if ( !flags["${id}"] ) {
|
|
347
|
+
flags["${id}"] = {};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Retrieve the existing effects.
|
|
351
|
+
let changes = this.document.changes ? [...this.document.changes] : [];
|
|
352
|
+
|
|
353
|
+
// Build an array of effects from the form data
|
|
354
|
+
let newChanges = [];
|
|
355
|
+
|
|
356
|
+
function addChange(documentName, key, customMode) {
|
|
357
|
+
const value = foundry.utils.getProperty(formData.object, key);
|
|
358
|
+
if ( value === undefined ) {
|
|
359
|
+
// Field not rendered in the form - preserve any existing change.
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if ( !value ) {
|
|
363
|
+
// Field explicitly cleared (empty string / zero) - remove the change.
|
|
364
|
+
changes = changes.filter(c => c.key !== key);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const type = foundry.utils.getProperty(formData.object, key + "-type") ?? 'add';
|
|
368
|
+
newChanges.push({
|
|
369
|
+
key: key,
|
|
370
|
+
value: value,
|
|
371
|
+
type: type
|
|
372
|
+
});
|
|
373
|
+
if ( customMode ) flags["${id}"][key + "-custommode"] = customMode;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
${joinToNode(entry.documents.filter(d => isActor(d)), document => joinToNode(document.body, property => generateAddValue(document, property), { appendNewLineIfNotEmpty: true }))}
|
|
377
|
+
|
|
378
|
+
// Auto-generated damage type Active Effect fields
|
|
379
|
+
${joinToNode(entry.documents.filter(d => isActor(d)), document => generateDamageTypeActiveEffectFields(entry, document), { appendNewLineIfNotEmpty: true })}
|
|
380
|
+
|
|
381
|
+
// Update the existing changes to replace duplicates.
|
|
382
|
+
for (let i = 0; i < changes.length; i++) {
|
|
383
|
+
const newChange = newChanges.find(c => c.key == changes[i].key);
|
|
384
|
+
if (newChange) {
|
|
385
|
+
// Replace with the new change and update the array to prevent duplicates.
|
|
386
|
+
changes[i] = newChange;
|
|
387
|
+
newChanges = newChanges.filter(c => c.key != changes[i].key);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Filter changes for empty form fields.
|
|
392
|
+
const finalChanges = changes.concat(newChanges).filter(c => c.value !== null && c.value !== undefined && c.value !== '');
|
|
393
|
+
console.log("Active Effect Changes", finalChanges);
|
|
394
|
+
await this.document.update({
|
|
395
|
+
name: formData.object.name,
|
|
396
|
+
description: formData.object.description ?? '',
|
|
397
|
+
disabled: formData.object.disabled ?? false,
|
|
398
|
+
transfer: formData.object.transfer ?? false,
|
|
399
|
+
changes: finalChanges,
|
|
400
|
+
flags: flags
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
// Rerender the parent sheets to update the effect lists.
|
|
404
|
+
this.document.parent?.sheet?.render();
|
|
405
|
+
if ( this.document.parent?.documentName === "Item" ) {
|
|
406
|
+
this.document.parent?.parent?.applyActiveEffects();
|
|
407
|
+
|
|
408
|
+
// Wait half a second
|
|
409
|
+
await new Promise(r => setTimeout(r, 500));
|
|
410
|
+
this.document.parent?.parent?.sheet?.render();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
414
|
`.appendNewLineIfNotEmpty();
|
|
415
415
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
416
416
|
}
|
|
@@ -434,12 +434,12 @@ export function generateActiveEffectHandlebars(id, entry, destination) {
|
|
|
434
434
|
}
|
|
435
435
|
if (fields.length == 0)
|
|
436
436
|
return undefined;
|
|
437
|
-
return expandToNode `
|
|
438
|
-
<!-- ${property.name} Section -->
|
|
439
|
-
<fieldset>
|
|
440
|
-
<legend>{{localize "${property.name}"}}</legend>
|
|
441
|
-
${joinToNode(fields, field => field, { appendNewLineIfNotEmpty: true })}
|
|
442
|
-
</fieldset>
|
|
437
|
+
return expandToNode `
|
|
438
|
+
<!-- ${property.name} Section -->
|
|
439
|
+
<fieldset>
|
|
440
|
+
<legend>{{localize "${property.name}"}}</legend>
|
|
441
|
+
${joinToNode(fields, field => field, { appendNewLineIfNotEmpty: true })}
|
|
442
|
+
</fieldset>
|
|
443
443
|
`;
|
|
444
444
|
}
|
|
445
445
|
if (isLayout(property)) {
|
|
@@ -453,14 +453,14 @@ export function generateActiveEffectHandlebars(id, entry, destination) {
|
|
|
453
453
|
// If this is calculated, it's implicitly locked
|
|
454
454
|
if (property.params.find(x => isNumberParamValue(x)))
|
|
455
455
|
return;
|
|
456
|
-
return expandToNode `
|
|
457
|
-
<div class="form-group">
|
|
458
|
-
<label>{{localize "${property.name}"}}</label>
|
|
459
|
-
<select name="${document.name.toLowerCase()}.${getSystemPath(property)}-mode" data-dtype="Number">
|
|
460
|
-
{{selectOptions numberModes selected=${document.name.toLowerCase()}.${getSystemPath(property)}-mode}}
|
|
461
|
-
</select>
|
|
462
|
-
<input type="number" name="${document.name.toLowerCase()}.${getSystemPath(property)}" value="{{${document.name.toLowerCase()}.${getSystemPath(property)}}}" />
|
|
463
|
-
</div>
|
|
456
|
+
return expandToNode `
|
|
457
|
+
<div class="form-group">
|
|
458
|
+
<label>{{localize "${property.name}"}}</label>
|
|
459
|
+
<select name="${document.name.toLowerCase()}.${getSystemPath(property)}-mode" data-dtype="Number">
|
|
460
|
+
{{selectOptions numberModes selected=${document.name.toLowerCase()}.${getSystemPath(property)}-mode}}
|
|
461
|
+
</select>
|
|
462
|
+
<input type="number" name="${document.name.toLowerCase()}.${getSystemPath(property)}" value="{{${document.name.toLowerCase()}.${getSystemPath(property)}}}" />
|
|
463
|
+
</div>
|
|
464
464
|
`;
|
|
465
465
|
}
|
|
466
466
|
if (isAttributeExp(property)) {
|
|
@@ -480,64 +480,64 @@ export function generateActiveEffectHandlebars(id, entry, destination) {
|
|
|
480
480
|
// <input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max}}" />
|
|
481
481
|
// </div>
|
|
482
482
|
// `;
|
|
483
|
-
return expandToNode `
|
|
484
|
-
<div class="form-group">
|
|
485
|
-
<label>{{localize "${property.name}"}} Value</label>
|
|
486
|
-
<select name="${document.name.toLowerCase()}.${getSystemPath(property)}-mode" data-dtype="Number">
|
|
487
|
-
{{selectOptions numberModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode}}
|
|
488
|
-
</select>
|
|
489
|
-
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value}}" />
|
|
490
|
-
</div>
|
|
483
|
+
return expandToNode `
|
|
484
|
+
<div class="form-group">
|
|
485
|
+
<label>{{localize "${property.name}"}} Value</label>
|
|
486
|
+
<select name="${document.name.toLowerCase()}.${getSystemPath(property)}-mode" data-dtype="Number">
|
|
487
|
+
{{selectOptions numberModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode}}
|
|
488
|
+
</select>
|
|
489
|
+
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value}}" />
|
|
490
|
+
</div>
|
|
491
491
|
`;
|
|
492
492
|
}
|
|
493
493
|
if (isResourceExp(property)) {
|
|
494
|
-
return expandToNode `
|
|
495
|
-
<div class="form-group">
|
|
496
|
-
<label>{{localize "${property.name}"}} Current</label>
|
|
497
|
-
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode" data-dtype="Number">
|
|
498
|
-
{{selectOptions resourceModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode}}
|
|
499
|
-
</select>
|
|
500
|
-
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value}}" />
|
|
501
|
-
</div>
|
|
502
|
-
<div class="form-group">
|
|
503
|
-
<label>{{localize "${property.name}"}} Max</label>
|
|
504
|
-
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max-mode" data-dtype="Number">
|
|
505
|
-
{{selectOptions numberModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max-mode}}
|
|
506
|
-
</select>
|
|
507
|
-
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max}}" />
|
|
508
|
-
</div>
|
|
494
|
+
return expandToNode `
|
|
495
|
+
<div class="form-group">
|
|
496
|
+
<label>{{localize "${property.name}"}} Current</label>
|
|
497
|
+
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode" data-dtype="Number">
|
|
498
|
+
{{selectOptions resourceModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode}}
|
|
499
|
+
</select>
|
|
500
|
+
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value}}" />
|
|
501
|
+
</div>
|
|
502
|
+
<div class="form-group">
|
|
503
|
+
<label>{{localize "${property.name}"}} Max</label>
|
|
504
|
+
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max-mode" data-dtype="Number">
|
|
505
|
+
{{selectOptions numberModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max-mode}}
|
|
506
|
+
</select>
|
|
507
|
+
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max}}" />
|
|
508
|
+
</div>
|
|
509
509
|
`;
|
|
510
510
|
}
|
|
511
511
|
if (isTrackerExp(property)) {
|
|
512
|
-
return expandToNode `
|
|
513
|
-
<div class="form-group">
|
|
514
|
-
<label>{{localize "${property.name}"}} Min</label>
|
|
515
|
-
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min-mode" data-dtype="Number">
|
|
516
|
-
{{selectOptions numberModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min-mode}}
|
|
517
|
-
</select>
|
|
518
|
-
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min}}" />
|
|
519
|
-
</div>
|
|
520
|
-
<div class="form-group">
|
|
521
|
-
<label>{{localize "${property.name}"}} Current</label>
|
|
522
|
-
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode" data-dtype="Number">
|
|
523
|
-
{{selectOptions resourceModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode}}
|
|
524
|
-
</select>
|
|
525
|
-
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value}}" />
|
|
526
|
-
</div>
|
|
527
|
-
<div class="form-group">
|
|
528
|
-
<label>{{localize "${property.name}"}} Temp</label>
|
|
529
|
-
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp-mode" data-dtype="Number">
|
|
530
|
-
{{selectOptions resourceModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp-mode}}
|
|
531
|
-
</select>
|
|
532
|
-
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp}}" />
|
|
533
|
-
</div>
|
|
534
|
-
<div class="form-group">
|
|
535
|
-
<label>{{localize "${property.name}"}} Max</label>
|
|
536
|
-
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max-mode" data-dtype="Number">
|
|
537
|
-
{{selectOptions numberModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max-mode}}
|
|
538
|
-
</select>
|
|
539
|
-
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max}}" />
|
|
540
|
-
</div>
|
|
512
|
+
return expandToNode `
|
|
513
|
+
<div class="form-group">
|
|
514
|
+
<label>{{localize "${property.name}"}} Min</label>
|
|
515
|
+
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min-mode" data-dtype="Number">
|
|
516
|
+
{{selectOptions numberModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min-mode}}
|
|
517
|
+
</select>
|
|
518
|
+
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.min}}" />
|
|
519
|
+
</div>
|
|
520
|
+
<div class="form-group">
|
|
521
|
+
<label>{{localize "${property.name}"}} Current</label>
|
|
522
|
+
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode" data-dtype="Number">
|
|
523
|
+
{{selectOptions resourceModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value-mode}}
|
|
524
|
+
</select>
|
|
525
|
+
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.value}}" />
|
|
526
|
+
</div>
|
|
527
|
+
<div class="form-group">
|
|
528
|
+
<label>{{localize "${property.name}"}} Temp</label>
|
|
529
|
+
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp-mode" data-dtype="Number">
|
|
530
|
+
{{selectOptions resourceModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp-mode}}
|
|
531
|
+
</select>
|
|
532
|
+
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.temp}}" />
|
|
533
|
+
</div>
|
|
534
|
+
<div class="form-group">
|
|
535
|
+
<label>{{localize "${property.name}"}} Max</label>
|
|
536
|
+
<select name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max-mode" data-dtype="Number">
|
|
537
|
+
{{selectOptions numberModes selected=${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max-mode}}
|
|
538
|
+
</select>
|
|
539
|
+
<input type="number" name="${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max" value="{{${document.name.toLowerCase()}.system.${property.name.toLowerCase()}.max}}" />
|
|
540
|
+
</div>
|
|
541
541
|
`;
|
|
542
542
|
}
|
|
543
543
|
if (isStringExp(property)) {
|
|
@@ -554,89 +554,89 @@ export function generateActiveEffectHandlebars(id, entry, destination) {
|
|
|
554
554
|
// </div>
|
|
555
555
|
// `;
|
|
556
556
|
// }
|
|
557
|
-
return expandToNode `
|
|
558
|
-
<div class="form-group">
|
|
559
|
-
<label>{{localize "${property.name}"}}</label>
|
|
560
|
-
<select name="${document.name.toLowerCase()}.${getSystemPath(property)}-mode" data-dtype="String">
|
|
561
|
-
{{selectOptions stringModes selected=${document.name.toLowerCase()}.${getSystemPath(property)}-mode}}
|
|
562
|
-
</select>
|
|
563
|
-
<input type="text" name="${document.name.toLowerCase()}.${getSystemPath(property)}" value="{{${document.name.toLowerCase()}.${getSystemPath(property)}}}" />
|
|
564
|
-
</div>
|
|
557
|
+
return expandToNode `
|
|
558
|
+
<div class="form-group">
|
|
559
|
+
<label>{{localize "${property.name}"}}</label>
|
|
560
|
+
<select name="${document.name.toLowerCase()}.${getSystemPath(property)}-mode" data-dtype="String">
|
|
561
|
+
{{selectOptions stringModes selected=${document.name.toLowerCase()}.${getSystemPath(property)}-mode}}
|
|
562
|
+
</select>
|
|
563
|
+
<input type="text" name="${document.name.toLowerCase()}.${getSystemPath(property)}" value="{{${document.name.toLowerCase()}.${getSystemPath(property)}}}" />
|
|
564
|
+
</div>
|
|
565
565
|
`;
|
|
566
566
|
}
|
|
567
567
|
if (isBooleanExp(property)) {
|
|
568
|
-
return expandToNode `
|
|
569
|
-
<div class="form-group">
|
|
570
|
-
<label>{{localize "${property.name}"}}</label>
|
|
571
|
-
<select name="${document.name.toLowerCase()}.${getSystemPath(property)}-mode" data-dtype="Boolean">
|
|
572
|
-
{{selectOptions booleanModes selected=${document.name.toLowerCase()}.${getSystemPath(property)}-mode}}
|
|
573
|
-
</select>
|
|
574
|
-
<input type="checkbox" name="${document.name.toLowerCase()}.${getSystemPath(property)}" {{checked ${document.name.toLowerCase()}.${getSystemPath(property)}}} />
|
|
575
|
-
</div>
|
|
568
|
+
return expandToNode `
|
|
569
|
+
<div class="form-group">
|
|
570
|
+
<label>{{localize "${property.name}"}}</label>
|
|
571
|
+
<select name="${document.name.toLowerCase()}.${getSystemPath(property)}-mode" data-dtype="Boolean">
|
|
572
|
+
{{selectOptions booleanModes selected=${document.name.toLowerCase()}.${getSystemPath(property)}-mode}}
|
|
573
|
+
</select>
|
|
574
|
+
<input type="checkbox" name="${document.name.toLowerCase()}.${getSystemPath(property)}" {{checked ${document.name.toLowerCase()}.${getSystemPath(property)}}} />
|
|
575
|
+
</div>
|
|
576
576
|
`;
|
|
577
577
|
}
|
|
578
578
|
return;
|
|
579
579
|
}
|
|
580
580
|
function generateDocumentTab(document) {
|
|
581
|
-
return expandToNode `
|
|
582
|
-
<!-- ${document.name} Tab -->
|
|
583
|
-
<section class="tab" data-tab="${document.name.toLowerCase()}">
|
|
584
|
-
${joinToNode(document.body, property => generateField(document, property), { appendNewLineIfNotEmpty: true })}
|
|
585
|
-
</section>
|
|
581
|
+
return expandToNode `
|
|
582
|
+
<!-- ${document.name} Tab -->
|
|
583
|
+
<section class="tab" data-tab="${document.name.toLowerCase()}">
|
|
584
|
+
${joinToNode(document.body, property => generateField(document, property), { appendNewLineIfNotEmpty: true })}
|
|
585
|
+
</section>
|
|
586
586
|
`;
|
|
587
587
|
}
|
|
588
|
-
const fileNode = expandToNode `
|
|
589
|
-
<form class="{{cssClass}}" autocomplete="off">
|
|
590
|
-
<!-- Effect Header -->
|
|
591
|
-
<header class="sheet-header">
|
|
592
|
-
<img class="effect-icon effect-img" src="{{ effect.img }}" data-edit="img">
|
|
593
|
-
<h1 class="effect-title"><input type="text" name="name" value="{{effect.name}}" placeholder="{{localize 'ARCHMAGE.name'}}"/></h1>
|
|
594
|
-
</header>
|
|
595
|
-
|
|
596
|
-
<article class="sheet-content">
|
|
597
|
-
<section class="sheet-body">
|
|
598
|
-
<!-- Effect Configuration Tabs -->
|
|
599
|
-
<nav class="sheet-tabs tabs">
|
|
600
|
-
<a class="item" data-tab="info"><i class="fas fa-book"></i> {{localize "Info"}}</a>
|
|
601
|
-
${joinToNode(entry.documents.filter(d => isActor(d)), property => `<a class="item" data-tab="${property.name.toLowerCase()}">{{localize "${property.name}"}}</a>`, { appendNewLineIfNotEmpty: true })}
|
|
602
|
-
</nav>
|
|
603
|
-
|
|
604
|
-
<div class="sheet-tabs-content">
|
|
605
|
-
<!-- Info Tab -->
|
|
606
|
-
<section class="tab" data-tab="info">
|
|
607
|
-
<div class="form-group stacked">
|
|
608
|
-
<label>{{ localize "EFFECT.Description" }}</label>
|
|
609
|
-
{{editor descriptionHTML target="description" button=false editable=editable engine="prosemirror" collaborate=false}}
|
|
610
|
-
</div>
|
|
611
|
-
|
|
612
|
-
<div class="form-group">
|
|
613
|
-
<label>{{ localize "EFFECT.Disabled" }}</label>
|
|
614
|
-
<input type="checkbox" name="disabled" {{ checked effect.disabled }}/>
|
|
615
|
-
</div>
|
|
616
|
-
|
|
617
|
-
{{#if originLink}}
|
|
618
|
-
<div class="form-group">
|
|
619
|
-
<label>{{ localize "EFFECT.Origin" }}</label>
|
|
620
|
-
{{{originLink}}}
|
|
621
|
-
</div>
|
|
622
|
-
{{/if}}
|
|
623
|
-
|
|
624
|
-
{{#if isItemEffect}}
|
|
625
|
-
<div class="form-group">
|
|
626
|
-
<label>{{ labels.transfer.name }}</label>
|
|
627
|
-
<div class="form-fields">
|
|
628
|
-
<input type="checkbox" name="transfer" {{checked data.transfer}}/>
|
|
629
|
-
</div>
|
|
630
|
-
<p class="hint">{{ labels.transfer.hint }}</p>
|
|
631
|
-
</div>
|
|
632
|
-
{{/if}}
|
|
633
|
-
</div>
|
|
634
|
-
|
|
635
|
-
${joinToNode(entry.documents, property => generateDocumentTab(property), { appendNewLineIfNotEmpty: true })}
|
|
636
|
-
</section>
|
|
637
|
-
</section>
|
|
638
|
-
</article>
|
|
639
|
-
</form>
|
|
588
|
+
const fileNode = expandToNode `
|
|
589
|
+
<form class="{{cssClass}}" autocomplete="off">
|
|
590
|
+
<!-- Effect Header -->
|
|
591
|
+
<header class="sheet-header">
|
|
592
|
+
<img class="effect-icon effect-img" src="{{ effect.img }}" data-edit="img">
|
|
593
|
+
<h1 class="effect-title"><input type="text" name="name" value="{{effect.name}}" placeholder="{{localize 'ARCHMAGE.name'}}"/></h1>
|
|
594
|
+
</header>
|
|
595
|
+
|
|
596
|
+
<article class="sheet-content">
|
|
597
|
+
<section class="sheet-body">
|
|
598
|
+
<!-- Effect Configuration Tabs -->
|
|
599
|
+
<nav class="sheet-tabs tabs">
|
|
600
|
+
<a class="item" data-tab="info"><i class="fas fa-book"></i> {{localize "Info"}}</a>
|
|
601
|
+
${joinToNode(entry.documents.filter(d => isActor(d)), property => `<a class="item" data-tab="${property.name.toLowerCase()}">{{localize "${property.name}"}}</a>`, { appendNewLineIfNotEmpty: true })}
|
|
602
|
+
</nav>
|
|
603
|
+
|
|
604
|
+
<div class="sheet-tabs-content">
|
|
605
|
+
<!-- Info Tab -->
|
|
606
|
+
<section class="tab" data-tab="info">
|
|
607
|
+
<div class="form-group stacked">
|
|
608
|
+
<label>{{ localize "EFFECT.Description" }}</label>
|
|
609
|
+
{{editor descriptionHTML target="description" button=false editable=editable engine="prosemirror" collaborate=false}}
|
|
610
|
+
</div>
|
|
611
|
+
|
|
612
|
+
<div class="form-group">
|
|
613
|
+
<label>{{ localize "EFFECT.Disabled" }}</label>
|
|
614
|
+
<input type="checkbox" name="disabled" {{ checked effect.disabled }}/>
|
|
615
|
+
</div>
|
|
616
|
+
|
|
617
|
+
{{#if originLink}}
|
|
618
|
+
<div class="form-group">
|
|
619
|
+
<label>{{ localize "EFFECT.Origin" }}</label>
|
|
620
|
+
{{{originLink}}}
|
|
621
|
+
</div>
|
|
622
|
+
{{/if}}
|
|
623
|
+
|
|
624
|
+
{{#if isItemEffect}}
|
|
625
|
+
<div class="form-group">
|
|
626
|
+
<label>{{ labels.transfer.name }}</label>
|
|
627
|
+
<div class="form-fields">
|
|
628
|
+
<input type="checkbox" name="transfer" {{checked data.transfer}}/>
|
|
629
|
+
</div>
|
|
630
|
+
<p class="hint">{{ labels.transfer.hint }}</p>
|
|
631
|
+
</div>
|
|
632
|
+
{{/if}}
|
|
633
|
+
</div>
|
|
634
|
+
|
|
635
|
+
${joinToNode(entry.documents, property => generateDocumentTab(property), { appendNewLineIfNotEmpty: true })}
|
|
636
|
+
</section>
|
|
637
|
+
</section>
|
|
638
|
+
</article>
|
|
639
|
+
</form>
|
|
640
640
|
`.appendNewLineIfNotEmpty();
|
|
641
641
|
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
642
642
|
}
|