intelligent-system-design-language 0.3.22 → 0.3.24

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.
Files changed (106) hide show
  1. package/.claude/agents/langium-language-designer.md +38 -38
  2. package/.claude/agents/typescript-vscode-expert.md +29 -29
  3. package/.claude/agents/ui-ux-designer.md +36 -36
  4. package/.claude/settings.local.json +33 -33
  5. package/.idea/inspectionProfiles/Project_Default.xml +6 -6
  6. package/.idea/isdl.iml +13 -13
  7. package/.idea/modules.xml +8 -8
  8. package/.idea/vcs.xml +6 -6
  9. package/.idea/watcherTasks.xml +3 -3
  10. package/.vscodeignore +18 -18
  11. package/LICENSE +673 -673
  12. package/README.md +86 -86
  13. package/bin/cli.js +4 -4
  14. package/bin/lsp.js +8 -8
  15. package/out/_backgrounds.scss +91 -91
  16. package/out/_handlebars.scss +497 -497
  17. package/out/_isdlStyles.scss +1444 -1444
  18. package/out/_vuetifyOverrides.scss +425 -425
  19. package/out/_vuetifyStyles.scss +31957 -31957
  20. package/out/cli/components/_backgrounds.scss +91 -91
  21. package/out/cli/components/_handlebars.scss +497 -497
  22. package/out/cli/components/_isdlStyles.scss +1444 -1444
  23. package/out/cli/components/_vuetifyOverrides.scss +425 -425
  24. package/out/cli/components/_vuetifyStyles.scss +31957 -31957
  25. package/out/cli/components/active-effect-sheet-generator.js +453 -453
  26. package/out/cli/components/chat-card-generator.js +654 -654
  27. package/out/cli/components/css-generator.js +4 -4
  28. package/out/cli/components/damage-roll-generator.js +160 -160
  29. package/out/cli/components/datamodel-generator.js +257 -257
  30. package/out/cli/components/derived-data-generator.js +923 -923
  31. package/out/cli/components/hotbar-drop-hook-generator.js +82 -82
  32. package/out/cli/components/init-hook-generator.js +495 -495
  33. package/out/cli/components/language-generator.js +1 -1
  34. package/out/cli/components/language-generator.js.map +1 -1
  35. package/out/cli/components/measured-template-preview.js +221 -221
  36. package/out/cli/components/method-generator.js +601 -562
  37. package/out/cli/components/method-generator.js.map +1 -1
  38. package/out/cli/components/ready-hook-generator.js +404 -404
  39. package/out/cli/components/token-generator.js +116 -116
  40. package/out/cli/components/vue/base-components/vue-attribute.js +138 -138
  41. package/out/cli/components/vue/base-components/vue-boolean.js +64 -64
  42. package/out/cli/components/vue/base-components/vue-calculator.js +93 -93
  43. package/out/cli/components/vue/base-components/vue-damage-application.js +356 -356
  44. package/out/cli/components/vue/base-components/vue-damage-bonuses.js +165 -165
  45. package/out/cli/components/vue/base-components/vue-damage-resistances.js +196 -196
  46. package/out/cli/components/vue/base-components/vue-damage-track.js +121 -121
  47. package/out/cli/components/vue/base-components/vue-date-time.js +42 -42
  48. package/out/cli/components/vue/base-components/vue-dice.js +98 -98
  49. package/out/cli/components/vue/base-components/vue-die.js +73 -73
  50. package/out/cli/components/vue/base-components/vue-document-choice.js +149 -149
  51. package/out/cli/components/vue/base-components/vue-document-choices.js +179 -179
  52. package/out/cli/components/vue/base-components/vue-document-link.js +60 -60
  53. package/out/cli/components/vue/base-components/vue-extended-choice.js +88 -88
  54. package/out/cli/components/vue/base-components/vue-inventory.js +519 -519
  55. package/out/cli/components/vue/base-components/vue-macro-choice.js +138 -138
  56. package/out/cli/components/vue/base-components/vue-measured-template.js +530 -530
  57. package/out/cli/components/vue/base-components/vue-money.js +483 -483
  58. package/out/cli/components/vue/base-components/vue-number.js +174 -174
  59. package/out/cli/components/vue/base-components/vue-paperdoll.js +43 -43
  60. package/out/cli/components/vue/base-components/vue-parent-property-reference.js +76 -76
  61. package/out/cli/components/vue/base-components/vue-prosemirror.js +18 -18
  62. package/out/cli/components/vue/base-components/vue-resource.js +136 -136
  63. package/out/cli/components/vue/base-components/vue-roll-visualizer.js +285 -285
  64. package/out/cli/components/vue/base-components/vue-self-property-reference.js +62 -62
  65. package/out/cli/components/vue/base-components/vue-string-choice.js +98 -98
  66. package/out/cli/components/vue/base-components/vue-string-choices.js +203 -203
  67. package/out/cli/components/vue/base-components/vue-string.js +60 -60
  68. package/out/cli/components/vue/base-components/vue-text-field.js +53 -53
  69. package/out/cli/components/vue/base-components/vue-tracker.js +431 -431
  70. package/out/cli/components/vue/vue-action-component-generator.js +64 -64
  71. package/out/cli/components/vue/vue-active-effect-sheet-generator.js +856 -856
  72. package/out/cli/components/vue/vue-datatable-sheet-class-generator.js +292 -292
  73. package/out/cli/components/vue/vue-datatable2-component-generator.js +824 -824
  74. package/out/cli/components/vue/vue-document-creation-app.js +121 -121
  75. package/out/cli/components/vue/vue-document-creation-sheet.js +94 -94
  76. package/out/cli/components/vue/vue-generator.js +40 -40
  77. package/out/cli/components/vue/vue-mixin.js +296 -296
  78. package/out/cli/components/vue/vue-pinned-datatable-component-generator.js +260 -260
  79. package/out/cli/components/vue/vue-prompt-generator.js +80 -80
  80. package/out/cli/components/vue/vue-prompt-sheet-class-generator.js +317 -317
  81. package/out/cli/components/vue/vue-sheet-application-generator.js +1171 -1171
  82. package/out/cli/components/vue/vue-sheet-class-generator.js +510 -510
  83. package/out/cli/generator.js +508 -438
  84. package/out/cli/generator.js.map +1 -1
  85. package/out/extension/github/githubManager.js +35 -35
  86. package/out/extension/github/githubQuickActions.js +120 -120
  87. package/out/extension/github/system-workflow.yml +47 -47
  88. package/out/extension/main.cjs +881 -311
  89. package/out/extension/main.cjs.map +3 -3
  90. package/out/extension/package.json +419 -419
  91. package/out/language/generated/ast.js +98 -2
  92. package/out/language/generated/ast.js.map +1 -1
  93. package/out/language/generated/grammar.js +14688 -14240
  94. package/out/language/generated/grammar.js.map +1 -1
  95. package/out/language/intelligent-system-design-language-validator.js +44 -2
  96. package/out/language/intelligent-system-design-language-validator.js.map +1 -1
  97. package/out/language/isdl-scope-provider.js +7 -1
  98. package/out/language/isdl-scope-provider.js.map +1 -1
  99. package/out/language/main.cjs +881 -311
  100. package/out/language/main.cjs.map +3 -3
  101. package/out/package.json +419 -419
  102. package/out/progressbar.min.js +6 -6
  103. package/out/styles.scss +828 -762
  104. package/out/test/validating/diagnostics.test.js +55 -0
  105. package/out/test/validating/diagnostics.test.js.map +1 -1
  106. package/package.json +419 -419
@@ -1,5 +1,5 @@
1
1
  import { isRollParam, isTypeParam, } from '../../language/generated/ast.js';
2
- import { isReturnExpression, isAssignment, isBinaryExpression, isGroup, isVariableExpression, isLiteral, isRef, isNegExpression, isAccess, isMethodBlock, isIfStatement, isJS, isChatCard, isFleetingAccess, isHtmlExp, isRoll, isDamageRoll, isParentAccess, isParentAssignment, isVariableAssignment, isWhenExpressions, isShorthandComparisonExpression, isItemAccess, isExpression, isResourceExp, isBooleanExp, isSelfMethod, isAttributeExp, isArrayExpression, isEach, isParameter, isPrompt, isLabelParam, isTargetParam, IntelligentSystemDesignLanguageTerminals, isMathExpression, isMathEmptyExpression, isMathSingleExpression, isMathParamExpression, isInitiativeProperty, isStatusProperty, isUpdate, isUpdateParent, isUpdateSelf, isParentTypeCheckExpression, isParentPropertyRefExp, isSelfPropertyRefExp, isLogExpression, isTrackerExp, isVisibilityValue, isFunctionCall, isAction, isDocument, isIncrementDecrementAssignment, isQuickModifyAssignment, isVariableIncrementDecrementAssignment, isVariableQuickModifyAssignment, isParentIncrementDecrementAssignment, isParentQuickModifyAssignment, isLocationParam, isWidthParam, isHeightParam, isNumberRange, isTargetTypeCheckExpression, isTargetAccess, isTargetIncrementDecrementAssignment, isTargetQuickModifyAssignment, isTargetAssignment, isWait, isPlayAudio, isPlayAudioFile, isPlayAudioVolume, isDieField, isTimeLimitParam, isCombatMethods, isCombatProperty, isUserProperty, isMacroExecute, isMeasuredTemplateField, isStringChoiceField, isDamageTypeChoiceField, isDiceField, isDieChoicesParam, isDocumentChoicesExp, isDocumentChoiceExp, isTableField, isInventoryField, isProperty, isRollVisualizerValueParam, isPromptInputAccess } from "../../language/generated/ast.js";
2
+ import { isReturnExpression, isAssignment, isBinaryExpression, isGroup, isVariableExpression, isLiteral, isRef, isNegExpression, isAccess, isMethodBlock, isIfStatement, isJS, isChatCard, isFleetingAccess, isHtmlExp, isRoll, isDamageRoll, isParentAccess, isParentAssignment, isVariableAssignment, isWhenExpressions, isShorthandComparisonExpression, isItemAccess, isExpression, isResourceExp, isBooleanExp, isSelfMethod, isAttributeExp, isArrayExpression, isEach, isParameter, isPrompt, isLabelParam, isTargetParam, IntelligentSystemDesignLanguageTerminals, isMathExpression, isMathEmptyExpression, isMathSingleExpression, isMathParamExpression, isInitiativeProperty, isStatusProperty, isUpdate, isUpdateParent, isUpdateSelf, isParentTypeCheckExpression, isParentPropertyRefExp, isSelfPropertyRefExp, isLogExpression, isTrackerExp, isVisibilityValue, isFunctionCall, isAction, isDocument, isIncrementDecrementAssignment, isQuickModifyAssignment, isVariableIncrementDecrementAssignment, isVariableQuickModifyAssignment, isParentIncrementDecrementAssignment, isParentQuickModifyAssignment, isLocationParam, isWidthParam, isHeightParam, isNumberRange, isTargetTypeCheckExpression, isTargetAccess, isTargetIncrementDecrementAssignment, isTargetQuickModifyAssignment, isTargetAssignment, isWait, isPlayAudio, isPlayAudioFile, isPlayAudioVolume, isDieField, isTimeLimitParam, isCombatMethods, isCombatProperty, isUserProperty, isMacroExecute, isMeasuredTemplateField, isStringChoiceField, isDamageTypeChoiceField, isDiceField, isDieChoicesParam, isDocumentChoicesExp, isDocumentChoiceExp, isTableField, isInventoryField, isProperty, isRollVisualizerValueParam, isPromptInputAccess, isRollResultAccess, isCritParam, isFumbleParam, isSuccessParam, isFailureParam, } from "../../language/generated/ast.js";
3
3
  import { expandToNode, joinToNode } from 'langium/generate';
4
4
  import { getParentDocument, getPromptRegistryKey, getPromptVariable, getSystemPath, getTargetDocument, toMachineIdentifier } from './utils.js';
5
5
  import { AstUtils } from 'langium';
@@ -30,19 +30,19 @@ export function translateDiceParts(expression, noLabels = false) {
30
30
  console.log("Translating Dice Part: ", expression.$type);
31
31
  if (isLiteral(expression)) {
32
32
  if (typeof expression.val == "string") {
33
- return expandToNode `
34
- "${expression.val}"
33
+ return expandToNode `
34
+ "${expression.val}"
35
35
  `;
36
36
  }
37
- return expandToNode `
38
- "${expression.val}"
37
+ return expandToNode `
38
+ "${expression.val}"
39
39
  `;
40
40
  }
41
41
  if (isRef(expression)) {
42
42
  // If string or number, return the value
43
43
  if (typeof expression.val == "string" || typeof expression.val == "number") {
44
- return expandToNode `
45
- "${expression.val}"
44
+ return expandToNode `
45
+ "${expression.val}"
46
46
  `;
47
47
  }
48
48
  if (expression.val.ref == undefined) {
@@ -50,19 +50,19 @@ export function translateDiceParts(expression, noLabels = false) {
50
50
  }
51
51
  if (expression.subProperties != undefined && expression.subProperties.length > 0) {
52
52
  const subLabel = noLabels ? "" : `[${humanize(expression.subProperties[0])}]`;
53
- return expandToNode `
54
- "@${(_a = expression.val.ref) === null || _a === void 0 ? void 0 : _a.name}${expression.subProperties[0].toLowerCase()}${subLabel}"
53
+ return expandToNode `
54
+ "@${(_a = expression.val.ref) === null || _a === void 0 ? void 0 : _a.name}${expression.subProperties[0].toLowerCase()}${subLabel}"
55
55
  `;
56
56
  }
57
57
  console.log("Ref:", `${expression.val.$refText}`);
58
58
  if (IntelligentSystemDesignLanguageTerminals.DICE.test(`${expression.val}`)) {
59
- return expandToNode `
60
- "${expression.val}"
59
+ return expandToNode `
60
+ "${expression.val}"
61
61
  `;
62
62
  }
63
63
  const refLabel = noLabels ? "" : `[${humanize((_c = (_b = expression.val.ref) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : expression.val.$refText)}]`;
64
- return expandToNode `
65
- "@${(_f = (_e = (_d = expression.val.ref) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.toLowerCase()) !== null && _f !== void 0 ? _f : expression.val.$refText}${refLabel}"
64
+ return expandToNode `
65
+ "@${(_f = (_e = (_d = expression.val.ref) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.toLowerCase()) !== null && _f !== void 0 ? _f : expression.val.$refText}${refLabel}"
66
66
  `;
67
67
  }
68
68
  if (isParentAccess(expression)) {
@@ -87,8 +87,8 @@ export function translateDiceParts(expression, noLabels = false) {
87
87
  }
88
88
  label = label.trim();
89
89
  const parentLabelSuffix = noLabels ? "" : `[${label}]`;
90
- return expandToNode `
91
- \`@${path.replaceAll(".", "").toLowerCase()}${parentLabelSuffix}\`
90
+ return expandToNode `
91
+ \`@${path.replaceAll(".", "").toLowerCase()}${parentLabelSuffix}\`
92
92
  `;
93
93
  }
94
94
  if (isTargetAccess(expression)) {
@@ -113,8 +113,8 @@ export function translateDiceParts(expression, noLabels = false) {
113
113
  }
114
114
  label = label.trim();
115
115
  const targetLabelSuffix = noLabels ? "" : `[${label}]`;
116
- return expandToNode `
117
- \`@${path.replaceAll(".", "").toLowerCase()}${targetLabelSuffix}\`
116
+ return expandToNode `
117
+ \`@${path.replaceAll(".", "").toLowerCase()}${targetLabelSuffix}\`
118
118
  `;
119
119
  }
120
120
  if (isPromptInputAccess(expression)) {
@@ -124,8 +124,8 @@ export function translateDiceParts(expression, noLabels = false) {
124
124
  for (const subProperty of (_10 = expression.subProperties) !== null && _10 !== void 0 ? _10 : []) {
125
125
  key = `${key}.${subProperty}`;
126
126
  }
127
- return expandToNode `
128
- \`@${key.replaceAll(".", "").toLowerCase()}\`
127
+ return expandToNode `
128
+ \`@${key.replaceAll(".", "").toLowerCase()}\`
129
129
  `;
130
130
  }
131
131
  if (isAccess(expression)) {
@@ -142,11 +142,11 @@ export function translateDiceParts(expression, noLabels = false) {
142
142
  const subPropertyName = expression.subProperties[0].toLowerCase();
143
143
  const subPropertyLabel = humanize(expression.subProperties[0]);
144
144
  // Generate dynamic expansion for each document in the choices array
145
- return expandToNode `
146
- context.object.system.${choicesFieldName}.map((doc, index) => {
147
- if (!doc || !doc.system) return '';
148
- return '@' + doc.uuid.replace(/[^a-zA-Z0-9]/g, '').toLowerCase() + '${subPropertyName}[' + doc.name + ' ${subPropertyLabel}]';
149
- }).filter(Boolean).join(' + ')
145
+ return expandToNode `
146
+ context.object.system.${choicesFieldName}.map((doc, index) => {
147
+ if (!doc || !doc.system) return '';
148
+ return '@' + doc.uuid.replace(/[^a-zA-Z0-9]/g, '').toLowerCase() + '${subPropertyName}[' + doc.name + ' ${subPropertyLabel}]';
149
+ }).filter(Boolean).join(' + ')
150
150
  `;
151
151
  }
152
152
  if (isParentPropertyRefExp((_25 = expression.property) === null || _25 === void 0 ? void 0 : _25.ref)) {
@@ -163,15 +163,15 @@ export function translateDiceParts(expression, noLabels = false) {
163
163
  }
164
164
  console.log("Access:", path, label);
165
165
  const accessLabelSuffix = noLabels ? "" : `[${label}]`;
166
- return expandToNode `
167
- \`@${path.replaceAll(".", "").toLowerCase()}${accessLabelSuffix}\`
166
+ return expandToNode `
167
+ \`@${path.replaceAll(".", "").toLowerCase()}${accessLabelSuffix}\`
168
168
  `;
169
169
  }
170
170
  if (isFleetingAccess(expression)) {
171
171
  // If this is a roll expression, just output it directly
172
172
  if (isRoll((_32 = expression.variable.ref) === null || _32 === void 0 ? void 0 : _32.value)) {
173
- return expandToNode `
174
- ${(_33 = expression.variable.ref) === null || _33 === void 0 ? void 0 : _33.name}
173
+ return expandToNode `
174
+ ${(_33 = expression.variable.ref) === null || _33 === void 0 ? void 0 : _33.name}
175
175
  `;
176
176
  }
177
177
  let path = (_35 = (_34 = expression.variable.ref) === null || _34 === void 0 ? void 0 : _34.name) !== null && _35 !== void 0 ? _35 : "";
@@ -181,18 +181,18 @@ export function translateDiceParts(expression, noLabels = false) {
181
181
  label = `${label} ${humanize(expression.subProperty)}`;
182
182
  }
183
183
  const fleetingLabelSuffix = noLabels ? "" : `[${label}]`;
184
- return expandToNode `
185
- \`@${path.replaceAll(".", "").toLowerCase()}${fleetingLabelSuffix}\`
184
+ return expandToNode `
185
+ \`@${path.replaceAll(".", "").toLowerCase()}${fleetingLabelSuffix}\`
186
186
  `;
187
187
  }
188
188
  if (isBinaryExpression(expression)) {
189
- return expandToNode `
190
- ${translateDiceParts(expression.e1, noLabels)} + "${expression.op}" + ${translateDiceParts(expression.e2, noLabels)}
189
+ return expandToNode `
190
+ ${translateDiceParts(expression.e1, noLabels)} + "${expression.op}" + ${translateDiceParts(expression.e2, noLabels)}
191
191
  `;
192
192
  }
193
193
  if (isGroup(expression)) {
194
- return expandToNode `
195
- "(" + ${translateDiceParts(expression.ge, noLabels)} + ")"
194
+ return expandToNode `
195
+ "(" + ${translateDiceParts(expression.ge, noLabels)} + ")"
196
196
  `;
197
197
  }
198
198
  return;
@@ -252,8 +252,8 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
252
252
  path = `${path}.${subProperty}`;
253
253
  label = `${label}.${subProperty}`;
254
254
  }
255
- return expandToNode `
256
- "${label.replaceAll(".", "").toLowerCase()}": ${path}
255
+ return expandToNode `
256
+ "${label.replaceAll(".", "").toLowerCase()}": ${path}
257
257
  `;
258
258
  }
259
259
  if (isTargetAccess(expression)) {
@@ -273,8 +273,8 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
273
273
  path = `${path}.${subProperty}`;
274
274
  label = `${label}.${subProperty}`;
275
275
  }
276
- return expandToNode `
277
- "${label.replaceAll(".", "").toLowerCase()}": ${path}
276
+ return expandToNode `
277
+ "${label.replaceAll(".", "").toLowerCase()}": ${path}
278
278
  `;
279
279
  }
280
280
  if (isPromptInputAccess(expression)) {
@@ -293,14 +293,14 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
293
293
  // data, which a prompt doesn't compute). Build the "<number><die>" formula string
294
294
  // so it drops into the roll as e.g. "2d6"; reading both keeps it reactive.
295
295
  if (isDiceField(ref) && !hasSub) {
296
- return expandToNode `
297
- "${fieldName}": \`\${${base}.number}\${${base}.die}\`
296
+ return expandToNode `
297
+ "${fieldName}": \`\${${base}.number}\${${base}.die}\`
298
298
  `;
299
299
  }
300
300
  // A die prompt input is stored as the die string itself (e.g. "d8").
301
301
  if (isDieField(ref) && !hasSub) {
302
- return expandToNode `
303
- "${fieldName}": ${base}
302
+ return expandToNode `
303
+ "${fieldName}": ${base}
304
304
  `;
305
305
  }
306
306
  let key = fieldName;
@@ -309,8 +309,8 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
309
309
  key = `${key}.${subProperty}`;
310
310
  dataPath = `${dataPath}.${subProperty.toLowerCase()}`;
311
311
  }
312
- return expandToNode `
313
- "${key.replaceAll(".", "").toLowerCase()}": ${dataPath} ?? 0
312
+ return expandToNode `
313
+ "${key.replaceAll(".", "").toLowerCase()}": ${dataPath} ?? 0
314
314
  `;
315
315
  }
316
316
  if (isAccess(expression)) {
@@ -333,8 +333,8 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
333
333
  subProperty = "?.mod";
334
334
  }
335
335
  console.log(label, path);
336
- return expandToNode `
337
- "${label.replaceAll(".", "").replaceAll(" ", "").toLowerCase()}": foundry.utils.getProperty(context.object.parent, ${path}.toLowerCase())${subProperty}
336
+ return expandToNode `
337
+ "${label.replaceAll(".", "").replaceAll(" ", "").toLowerCase()}": foundry.utils.getProperty(context.object.parent, ${path}.toLowerCase())${subProperty}
338
338
  `;
339
339
  }
340
340
  else if (isSelfPropertyRefExp((_22 = expression.property) === null || _22 === void 0 ? void 0 : _22.ref)) {
@@ -350,8 +350,8 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
350
350
  subProperty = "?.mod";
351
351
  }
352
352
  console.log(label, selfPropertyPath);
353
- return expandToNode `
354
- "${label.replaceAll(".", "").replaceAll(" ", "").toLowerCase()}": foundry.utils.getProperty(context.object, "system." + ${selfPropertyPath}.toLowerCase())${subProperty}
353
+ return expandToNode `
354
+ "${label.replaceAll(".", "").replaceAll(" ", "").toLowerCase()}": foundry.utils.getProperty(context.object, "system." + ${selfPropertyPath}.toLowerCase())${subProperty}
355
355
  `;
356
356
  }
357
357
  else {
@@ -360,25 +360,25 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
360
360
  const choicesFieldName = expression.property.ref.name.toLowerCase();
361
361
  const subPropertyName = expression.subProperties[0].toLowerCase();
362
362
  // Generate data for each document in the choices array
363
- return expandToNode `
364
- ...Object.fromEntries(context.object.system.${choicesFieldName}.map((doc, index) => {
365
- if (!doc || !doc.system) return null;
366
-
367
- // Determine the accessor based on property type
368
- let accessor = '.${subPropertyName}';
369
- ${isResourceExp((_31 = expression.property) === null || _31 === void 0 ? void 0 : _31.ref) || isTrackerExp((_32 = expression.property) === null || _32 === void 0 ? void 0 : _32.ref) ? `
370
- if (doc.system.${subPropertyName} && typeof doc.system.${subPropertyName} === 'object' && 'value' in doc.system.${subPropertyName}) {
371
- accessor = '.${subPropertyName}.value';
372
- }` : ''}
373
- ${isAttributeExp((_33 = expression.property) === null || _33 === void 0 ? void 0 : _33.ref) ? `
374
- if (doc.system.${subPropertyName} && typeof doc.system.${subPropertyName} === 'object' && 'mod' in doc.system.${subPropertyName}) {
375
- accessor = '.${subPropertyName}.mod';
376
- }` : ''}
377
-
378
- const key = doc.uuid.replace(/[^a-zA-Z0-9]/g, '').toLowerCase() + '${subPropertyName}';
379
- const value = foundry.utils.getProperty(doc, 'system' + accessor) ?? 0;
380
- return [key, value];
381
- }).filter(Boolean))
363
+ return expandToNode `
364
+ ...Object.fromEntries(context.object.system.${choicesFieldName}.map((doc, index) => {
365
+ if (!doc || !doc.system) return null;
366
+
367
+ // Determine the accessor based on property type
368
+ let accessor = '.${subPropertyName}';
369
+ ${isResourceExp((_31 = expression.property) === null || _31 === void 0 ? void 0 : _31.ref) || isTrackerExp((_32 = expression.property) === null || _32 === void 0 ? void 0 : _32.ref) ? `
370
+ if (doc.system.${subPropertyName} && typeof doc.system.${subPropertyName} === 'object' && 'value' in doc.system.${subPropertyName}) {
371
+ accessor = '.${subPropertyName}.value';
372
+ }` : ''}
373
+ ${isAttributeExp((_33 = expression.property) === null || _33 === void 0 ? void 0 : _33.ref) ? `
374
+ if (doc.system.${subPropertyName} && typeof doc.system.${subPropertyName} === 'object' && 'mod' in doc.system.${subPropertyName}) {
375
+ accessor = '.${subPropertyName}.mod';
376
+ }` : ''}
377
+
378
+ const key = doc.uuid.replace(/[^a-zA-Z0-9]/g, '').toLowerCase() + '${subPropertyName}';
379
+ const value = foundry.utils.getProperty(doc, 'system' + accessor) ?? 0;
380
+ return [key, value];
381
+ }).filter(Boolean))
382
382
  `;
383
383
  }
384
384
  path = `${path}.${(_35 = (_34 = expression.property) === null || _34 === void 0 ? void 0 : _34.ref) === null || _35 === void 0 ? void 0 : _35.name.toLowerCase()}`;
@@ -404,8 +404,8 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
404
404
  label = `${label} ${humanize(subProperty)}`;
405
405
  }
406
406
  console.log(label, path);
407
- return expandToNode `
408
- "${label.replaceAll(".", "").replaceAll(" ", "").toLowerCase()}": ${path} ?? 0
407
+ return expandToNode `
408
+ "${label.replaceAll(".", "").replaceAll(" ", "").toLowerCase()}": ${path} ?? 0
409
409
  `;
410
410
  }
411
411
  if (isFleetingAccess(expression)) {
@@ -428,8 +428,8 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
428
428
  path = `${path}[${(_51 = accessExp === null || accessExp === void 0 ? void 0 : accessExp.contents) === null || _51 === void 0 ? void 0 : _51.toString()}]`;
429
429
  }
430
430
  console.log(label, path);
431
- return expandToNode `
432
- "${label}": ${path} ?? 0
431
+ return expandToNode `
432
+ "${label}": ${path} ?? 0
433
433
  `;
434
434
  }
435
435
  // if (isVariableAccess(expression)) {
@@ -460,38 +460,38 @@ export function translateDiceData(expression, entry, id, preDerived, generatingP
460
460
  // If string or number, return the value
461
461
  if (typeof expression.val == "string" || typeof expression.val == "number") {
462
462
  console.log(expression.val);
463
- return expandToNode `
464
- "${expression.val}": ${expression.val}
463
+ return expandToNode `
464
+ "${expression.val}": ${expression.val}
465
465
  `;
466
466
  }
467
467
  if (expression.val.ref == undefined) {
468
468
  return;
469
469
  }
470
470
  if (expression.subProperties != undefined && expression.subProperties.length > 0) {
471
- return expandToNode `
472
- "${(_53 = expression.val.ref) === null || _53 === void 0 ? void 0 : _53.name.toLowerCase()}${expression.subProperties[0].toLowerCase()}": ${(_54 = expression.val.ref) === null || _54 === void 0 ? void 0 : _54.name}.${expression.subProperties[0].toLowerCase()} ?? 0
471
+ return expandToNode `
472
+ "${(_53 = expression.val.ref) === null || _53 === void 0 ? void 0 : _53.name.toLowerCase()}${expression.subProperties[0].toLowerCase()}": ${(_54 = expression.val.ref) === null || _54 === void 0 ? void 0 : _54.name}.${expression.subProperties[0].toLowerCase()} ?? 0
473
473
  `;
474
474
  }
475
475
  console.log((_55 = expression.val.ref) === null || _55 === void 0 ? void 0 : _55.name, (_56 = expression.val.ref) === null || _56 === void 0 ? void 0 : _56.$type);
476
- return expandToNode `
477
- "${(_59 = (_58 = (_57 = expression.val.ref) === null || _57 === void 0 ? void 0 : _57.name) === null || _58 === void 0 ? void 0 : _58.toLowerCase()) !== null && _59 !== void 0 ? _59 : expression.val.$refText}": ${(_61 = (_60 = expression.val.ref) === null || _60 === void 0 ? void 0 : _60.name) !== null && _61 !== void 0 ? _61 : expression.val.$refText} ?? 0
476
+ return expandToNode `
477
+ "${(_59 = (_58 = (_57 = expression.val.ref) === null || _57 === void 0 ? void 0 : _57.name) === null || _58 === void 0 ? void 0 : _58.toLowerCase()) !== null && _59 !== void 0 ? _59 : expression.val.$refText}": ${(_61 = (_60 = expression.val.ref) === null || _60 === void 0 ? void 0 : _60.name) !== null && _61 !== void 0 ? _61 : expression.val.$refText} ?? 0
478
478
  `;
479
479
  }
480
480
  if (isBinaryExpression(expression)) {
481
481
  const expressions = [expression.e1, expression.e2];
482
- return expandToNode `
483
- ${joinToNode(expressions, e => translateDiceData(e, entry, id, preDerived, generatingProperty), { separator: ", " })}
482
+ return expandToNode `
483
+ ${joinToNode(expressions, e => translateDiceData(e, entry, id, preDerived, generatingProperty), { separator: ", " })}
484
484
  `;
485
485
  }
486
486
  if (isGroup(expression)) {
487
- return expandToNode `
488
- ${translateDiceData(expression.ge, entry, id, preDerived, generatingProperty)}
487
+ return expandToNode `
488
+ ${translateDiceData(expression.ge, entry, id, preDerived, generatingProperty)}
489
489
  `;
490
490
  }
491
491
  return undefined;
492
492
  }
493
493
  export function translateExpression(entry, id, expression, preDerived = false, generatingProperty = undefined) {
494
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
494
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5;
495
495
  function humanize(string) {
496
496
  if (string == undefined) {
497
497
  return "";
@@ -504,14 +504,14 @@ export function translateExpression(entry, id, expression, preDerived = false, g
504
504
  //console.log(preDerived, generatingProperty);
505
505
  function translateMethodExpression(expression) {
506
506
  //console.log("Translating Method Expression: " + expression.name);
507
- return expandToNode `
508
- ${expression.type == "fleeting" ? "let" : "const"} ${expression.name} = ${translateExpression(entry, id, expression.value, preDerived, generatingProperty)};
507
+ return expandToNode `
508
+ ${expression.type == "fleeting" ? "let" : "const"} ${expression.name} = ${translateExpression(entry, id, expression.value, preDerived, generatingProperty)};
509
509
  `;
510
510
  }
511
511
  function translateReturnExpression(expression) {
512
512
  //console.log("Translating Return Expression: " + expression.value);
513
- return expandToNode `
514
- return ${translateExpression(entry, id, expression.value, preDerived, generatingProperty)};
513
+ return expandToNode `
514
+ return ${translateExpression(entry, id, expression.value, preDerived, generatingProperty)};
515
515
  `;
516
516
  }
517
517
  function translateAssignmentExpression(expression) {
@@ -524,46 +524,46 @@ export function translateExpression(entry, id, expression, preDerived = false, g
524
524
  const fieldName = (_e = (_d = expression.property) === null || _d === void 0 ? void 0 : _d.ref) === null || _e === void 0 ? void 0 : _e.name.toLowerCase();
525
525
  const modifier = expression.term == "++" ? "+ 1" : "- 1";
526
526
  const readPath = getSystemPath((_f = expression.property) === null || _f === void 0 ? void 0 : _f.ref, expression.subProperties, (_g = expression.propertyLookup) === null || _g === void 0 ? void 0 : _g.ref);
527
- return expandToNode `
528
- const ${fieldName}DieChoices = ["d4","d6","d8","d10","d12","d20"];
529
- const ${fieldName}CurrentDieIndex = ${fieldName}DieChoices.indexOf(context.object.${readPath});
530
- if (${fieldName}CurrentDieIndex === -1) {
531
- console.error("Invalid die size: " + context.object.${readPath});
532
- update["${systemPath}"] = 'd4';
533
- return;
534
- }
535
- let ${fieldName}NewDieIndex = ${fieldName}CurrentDieIndex;
536
- ${fieldName}NewDieIndex = Math.max(0, Math.min(${fieldName}DieChoices.length - 1, ${fieldName}CurrentDieIndex ${modifier}));
537
- update["${systemPath}"] = ${fieldName}DieChoices[${fieldName}NewDieIndex];
527
+ return expandToNode `
528
+ const ${fieldName}DieChoices = ["d4","d6","d8","d10","d12","d20"];
529
+ const ${fieldName}CurrentDieIndex = ${fieldName}DieChoices.indexOf(context.object.${readPath});
530
+ if (${fieldName}CurrentDieIndex === -1) {
531
+ console.error("Invalid die size: " + context.object.${readPath});
532
+ update["${systemPath}"] = 'd4';
533
+ return;
534
+ }
535
+ let ${fieldName}NewDieIndex = ${fieldName}CurrentDieIndex;
536
+ ${fieldName}NewDieIndex = Math.max(0, Math.min(${fieldName}DieChoices.length - 1, ${fieldName}CurrentDieIndex ${modifier}));
537
+ update["${systemPath}"] = ${fieldName}DieChoices[${fieldName}NewDieIndex];
538
538
  `;
539
539
  }
540
540
  if ((isResourceExp((_h = expression.property) === null || _h === void 0 ? void 0 : _h.ref) || isTrackerExp((_j = expression.property) === null || _j === void 0 ? void 0 : _j.ref)) && (expression.subProperties == undefined || expression.subProperties.length == 0 || expression.subProperties[0] == "temp")) {
541
541
  // We need to check for temp first when decrementing
542
542
  const tempPath = `system.${(_l = (_k = expression.property) === null || _k === void 0 ? void 0 : _k.ref) === null || _l === void 0 ? void 0 : _l.name.toLowerCase()}.temp`;
543
543
  if (isIncrementDecrementAssignment(expression) && expression.term == "--") {
544
- return expandToNode `
545
- if ( context.object.${tempPath} > 0 ) {
546
- update["${tempPath}"] = context.object.${tempPath} - 1;
547
- }
548
- else {
549
- update["${systemPath}"] = context.object.${systemPath} - 1;
550
- }
544
+ return expandToNode `
545
+ if ( context.object.${tempPath} > 0 ) {
546
+ update["${tempPath}"] = context.object.${tempPath} - 1;
547
+ }
548
+ else {
549
+ update["${systemPath}"] = context.object.${systemPath} - 1;
550
+ }
551
551
  `;
552
552
  }
553
553
  if (isQuickModifyAssignment(expression) && expression.term == "-=") {
554
- return expandToNode `
555
- if ( context.object.${tempPath} > 0 ) {
556
- update["${tempPath}"] = context.object.${tempPath} - ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
557
-
558
- if ( update["${tempPath}"] < 0 ) {
559
- // Apply the remainder to the system property
560
- update["${systemPath}"] = context.object.${systemPath} + update["${tempPath}"];
561
- update["${tempPath}"] = 0;
562
- }
563
- }
564
- else {
565
- update["${systemPath}"] = context.object.${systemPath} - ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
566
- }
554
+ return expandToNode `
555
+ if ( context.object.${tempPath} > 0 ) {
556
+ update["${tempPath}"] = context.object.${tempPath} - ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
557
+
558
+ if ( update["${tempPath}"] < 0 ) {
559
+ // Apply the remainder to the system property
560
+ update["${systemPath}"] = context.object.${systemPath} + update["${tempPath}"];
561
+ update["${tempPath}"] = 0;
562
+ }
563
+ }
564
+ else {
565
+ update["${systemPath}"] = context.object.${systemPath} - ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
566
+ }
567
567
  `;
568
568
  }
569
569
  }
@@ -575,8 +575,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
575
575
  function generateModification() {
576
576
  if (isIncrementDecrementAssignment(expression)) {
577
577
  const modifier = expression.term == "++" ? "+" : "-";
578
- return expandToNode `
579
- ${propertyName}NewDieIndex = Math.max(0, Math.min(${propertyName}DieChoices.length - 1, ${propertyName}CurrentDieIndex ${modifier} 1));
578
+ return expandToNode `
579
+ ${propertyName}NewDieIndex = Math.max(0, Math.min(${propertyName}DieChoices.length - 1, ${propertyName}CurrentDieIndex ${modifier} 1));
580
580
  `;
581
581
  }
582
582
  if (isQuickModifyAssignment(expression)) {
@@ -598,25 +598,25 @@ export function translateExpression(entry, id, expression, preDerived = false, g
598
598
  modifier = "+";
599
599
  break;
600
600
  }
601
- return expandToNode `
602
- ${propertyName}NewDieIndex = Math.max(0, Math.min(${propertyName}DieChoices.length - 1, ${propertyName}CurrentDieIndex ${modifier} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)}));
601
+ return expandToNode `
602
+ ${propertyName}NewDieIndex = Math.max(0, Math.min(${propertyName}DieChoices.length - 1, ${propertyName}CurrentDieIndex ${modifier} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)}));
603
603
  `;
604
604
  }
605
- return expandToNode `
606
- ${propertyName}NewDieIndex = Math.max(0, Math.min(${propertyName}DieChoices.length - 1, ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)}));
605
+ return expandToNode `
606
+ ${propertyName}NewDieIndex = Math.max(0, Math.min(${propertyName}DieChoices.length - 1, ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)}));
607
607
  `;
608
608
  }
609
- return expandToNode `
610
- const ${propertyName}DieChoices = ${JSON.stringify(dieChoices)};
611
- const ${propertyName}CurrentDieIndex = ${propertyName}DieChoices.indexOf(context.object.${systemPath});
612
- if (${propertyName}CurrentDieIndex === -1) {
613
- console.error("Invalid die size: " + context.object.${systemPath});
614
- update["${systemPath}"] = '${dieChoices[0]}';
615
- return;
616
- }
617
- let ${propertyName}NewDieIndex = ${propertyName}CurrentDieIndex;
618
- ${generateModification()}
619
- update["${systemPath}"] = ${propertyName}DieChoices[${propertyName}NewDieIndex];
609
+ return expandToNode `
610
+ const ${propertyName}DieChoices = ${JSON.stringify(dieChoices)};
611
+ const ${propertyName}CurrentDieIndex = ${propertyName}DieChoices.indexOf(context.object.${systemPath});
612
+ if (${propertyName}CurrentDieIndex === -1) {
613
+ console.error("Invalid die size: " + context.object.${systemPath});
614
+ update["${systemPath}"] = '${dieChoices[0]}';
615
+ return;
616
+ }
617
+ let ${propertyName}NewDieIndex = ${propertyName}CurrentDieIndex;
618
+ ${generateModification()}
619
+ update["${systemPath}"] = ${propertyName}DieChoices[${propertyName}NewDieIndex];
620
620
  `;
621
621
  }
622
622
  // Special case for dice fields with .die subproperty - use die choice navigation
@@ -625,23 +625,23 @@ export function translateExpression(entry, id, expression, preDerived = false, g
625
625
  const fieldName = (_v = (_u = expression.property) === null || _u === void 0 ? void 0 : _u.ref) === null || _v === void 0 ? void 0 : _v.name.toLowerCase();
626
626
  const modifier = expression.term == "++" ? "+ 1" : "- 1";
627
627
  const readPath = getSystemPath((_w = expression.property) === null || _w === void 0 ? void 0 : _w.ref, expression.subProperties, (_x = expression.propertyLookup) === null || _x === void 0 ? void 0 : _x.ref);
628
- return expandToNode `
629
- const ${fieldName}DieChoices = ["d4","d6","d8","d10","d12","d20"];
630
- const ${fieldName}CurrentDieIndex = ${fieldName}DieChoices.indexOf(context.object.${readPath});
631
- if (${fieldName}CurrentDieIndex === -1) {
632
- console.error("Invalid die size: " + context.object.${readPath});
633
- update["${systemPath}"] = 'd4';
634
- return;
635
- }
636
- let ${fieldName}NewDieIndex = ${fieldName}CurrentDieIndex;
637
- ${fieldName}NewDieIndex = Math.max(0, Math.min(${fieldName}DieChoices.length - 1, ${fieldName}CurrentDieIndex ${modifier}));
638
- update["${systemPath}"] = ${fieldName}DieChoices[${fieldName}NewDieIndex];
628
+ return expandToNode `
629
+ const ${fieldName}DieChoices = ["d4","d6","d8","d10","d12","d20"];
630
+ const ${fieldName}CurrentDieIndex = ${fieldName}DieChoices.indexOf(context.object.${readPath});
631
+ if (${fieldName}CurrentDieIndex === -1) {
632
+ console.error("Invalid die size: " + context.object.${readPath});
633
+ update["${systemPath}"] = 'd4';
634
+ return;
635
+ }
636
+ let ${fieldName}NewDieIndex = ${fieldName}CurrentDieIndex;
637
+ ${fieldName}NewDieIndex = Math.max(0, Math.min(${fieldName}DieChoices.length - 1, ${fieldName}CurrentDieIndex ${modifier}));
638
+ update["${systemPath}"] = ${fieldName}DieChoices[${fieldName}NewDieIndex];
639
639
  `;
640
640
  }
641
641
  if (isIncrementDecrementAssignment(expression)) {
642
642
  const modifier = expression.term == "++" ? "+" : "-";
643
- return expandToNode `
644
- update["${systemPath}"] = context.object.${systemPath} ${modifier} 1;
643
+ return expandToNode `
644
+ update["${systemPath}"] = context.object.${systemPath} ${modifier} 1;
645
645
  `;
646
646
  }
647
647
  if (isQuickModifyAssignment(expression)) {
@@ -663,12 +663,12 @@ export function translateExpression(entry, id, expression, preDerived = false, g
663
663
  modifier = "+";
664
664
  break;
665
665
  }
666
- return expandToNode `
667
- update["${systemPath}"] = context.object.${systemPath} ${modifier} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
666
+ return expandToNode `
667
+ update["${systemPath}"] = context.object.${systemPath} ${modifier} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
668
668
  `;
669
669
  }
670
- return expandToNode `
671
- update["${systemPath}"] = ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
670
+ return expandToNode `
671
+ update["${systemPath}"] = ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
672
672
  `;
673
673
  }
674
674
  function translateVariableAssignment(expression) {
@@ -679,18 +679,18 @@ export function translateExpression(entry, id, expression, preDerived = false, g
679
679
  }
680
680
  // ++ or --
681
681
  if (isVariableIncrementDecrementAssignment(expression)) {
682
- return expandToNode `
683
- ${name}${expression.term};
682
+ return expandToNode `
683
+ ${name}${expression.term};
684
684
  `;
685
685
  }
686
686
  // +=, -=, *=, /=
687
687
  if (isVariableQuickModifyAssignment(expression)) {
688
- return expandToNode `
689
- ${name} ${expression.term} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
688
+ return expandToNode `
689
+ ${name} ${expression.term} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
690
690
  `;
691
691
  }
692
- return expandToNode `
693
- ${name} = ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
692
+ return expandToNode `
693
+ ${name} = ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
694
694
  `;
695
695
  }
696
696
  function translateParentAssignmentExpression(expression) {
@@ -699,8 +699,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
699
699
  let systemPath = getSystemPath((_a = expression.property) === null || _a === void 0 ? void 0 : _a.ref, expression.subProperties, (_b = expression.propertyLookup) === null || _b === void 0 ? void 0 : _b.ref, false, true);
700
700
  if (isParentIncrementDecrementAssignment(expression)) {
701
701
  const modifier = expression.term == "++" ? "+" : "-";
702
- return expandToNode `
703
- parentUpdate["${systemPath}"] = context.object.parent.${systemPath} ${modifier} 1;
702
+ return expandToNode `
703
+ parentUpdate["${systemPath}"] = context.object.parent.${systemPath} ${modifier} 1;
704
704
  `;
705
705
  }
706
706
  if (isParentQuickModifyAssignment(expression)) {
@@ -722,12 +722,12 @@ export function translateExpression(entry, id, expression, preDerived = false, g
722
722
  modifier = "+";
723
723
  break;
724
724
  }
725
- return expandToNode `
726
- parentUpdate["${systemPath}"] = context.object.parent.${systemPath} ${modifier} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
725
+ return expandToNode `
726
+ parentUpdate["${systemPath}"] = context.object.parent.${systemPath} ${modifier} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
727
727
  `;
728
728
  }
729
- return expandToNode `
730
- parentUpdate["${systemPath}"] = ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
729
+ return expandToNode `
730
+ parentUpdate["${systemPath}"] = ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
731
731
  `;
732
732
  }
733
733
  function translateTargetAssignmentExpression(expression) {
@@ -735,8 +735,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
735
735
  let systemPath = getSystemPath((_a = expression.property) === null || _a === void 0 ? void 0 : _a.ref, expression.subProperties, undefined, false, true);
736
736
  if (isTargetIncrementDecrementAssignment(expression)) {
737
737
  const modifier = expression.term == "++" ? "+" : "-";
738
- return expandToNode `
739
- targetUpdate["${systemPath}"] = context.target.${systemPath} ${modifier} 1;
738
+ return expandToNode `
739
+ targetUpdate["${systemPath}"] = context.target.${systemPath} ${modifier} 1;
740
740
  `;
741
741
  }
742
742
  if (isTargetQuickModifyAssignment(expression)) {
@@ -758,12 +758,12 @@ export function translateExpression(entry, id, expression, preDerived = false, g
758
758
  modifier = "+";
759
759
  break;
760
760
  }
761
- return expandToNode `
762
- targetUpdate["${systemPath}"] = context.target.${systemPath} ${modifier} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
761
+ return expandToNode `
762
+ targetUpdate["${systemPath}"] = context.target.${systemPath} ${modifier} ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
763
763
  `;
764
764
  }
765
- return expandToNode `
766
- targetUpdate["${systemPath}"] = ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
765
+ return expandToNode `
766
+ targetUpdate["${systemPath}"] = ${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)};
767
767
  `;
768
768
  }
769
769
  function translateBinaryExpression(expression) {
@@ -793,26 +793,26 @@ export function translateExpression(entry, id, expression, preDerived = false, g
793
793
  console.log("Translating Literal Expression: " + expression.val);
794
794
  if (typeof expression.val == "string") {
795
795
  if (expression.val == "nothing") {
796
- return expandToNode `
797
- null
796
+ return expandToNode `
797
+ null
798
798
  `;
799
799
  }
800
800
  else if (expression.val == "true" || expression.val == "false") {
801
- return expandToNode `
802
- ${expression.val}
801
+ return expandToNode `
802
+ ${expression.val}
803
803
  `;
804
804
  }
805
805
  if (isInitiativeProperty(generatingProperty)) {
806
- return expandToNode `
807
- ${expression.val}
806
+ return expandToNode `
807
+ ${expression.val}
808
808
  `;
809
809
  }
810
- return expandToNode `
811
- "${expression.val}"
810
+ return expandToNode `
811
+ "${expression.val}"
812
812
  `;
813
813
  }
814
- return expandToNode `
815
- ${expression.val}
814
+ return expandToNode `
815
+ ${expression.val}
816
816
  `;
817
817
  }
818
818
  function translateReferenceExpression(expression) {
@@ -830,12 +830,18 @@ export function translateExpression(entry, id, expression, preDerived = false, g
830
830
  accessPath = `${accessPath}.system`;
831
831
  }
832
832
  }
833
+ const refTargetIsRoll = isVariableExpression(expression.val.ref) && isRoll(expression.val.ref.value);
833
834
  for (const subProperty of (_c = expression.subProperties) !== null && _c !== void 0 ? _c : []) {
834
- if (subProperty.toLowerCase() == "name") {
835
+ const lowerSub = subProperty.toLowerCase();
836
+ if (lowerSub == "name") {
835
837
  accessPath = `${(_d = expression.val.ref) === null || _d === void 0 ? void 0 : _d.name}.name`;
836
838
  }
839
+ else if (refTargetIsRoll && lowerSub == "dice") {
840
+ // Foundry's Roll#dice returns DiceTerms; the face-value array lives on diceFaces.
841
+ accessPath = `${accessPath}.diceFaces`;
842
+ }
837
843
  else {
838
- accessPath = `${accessPath}.${subProperty.toLowerCase()}`;
844
+ accessPath = `${accessPath}.${lowerSub}`;
839
845
  }
840
846
  }
841
847
  // A bare reference to a roll variable (e.g. `fleeting r = roll(d20 + 1)`
@@ -852,14 +858,14 @@ export function translateExpression(entry, id, expression, preDerived = false, g
852
858
  accessPath = `${accessPath}.total`;
853
859
  }
854
860
  console.log("Access Path: ", accessPath);
855
- return expandToNode `
856
- ${accessPath}
861
+ return expandToNode `
862
+ ${accessPath}
857
863
  `;
858
864
  }
859
865
  function translateGroupedExpression(expression) {
860
866
  //console.log("Translating Grouped Expression: " + expression.ge);
861
- return expandToNode `
862
- (${translateExpression(entry, id, expression.ge, preDerived, generatingProperty)})
867
+ return expandToNode `
868
+ (${translateExpression(entry, id, expression.ge, preDerived, generatingProperty)})
863
869
  `;
864
870
  }
865
871
  function translateNegatedExpression(expression) {
@@ -867,12 +873,12 @@ export function translateExpression(entry, id, expression, preDerived = false, g
867
873
  var _a;
868
874
  // If this is a boolean, we need to negate it differently
869
875
  if (isAccess(expression.ne) && isBooleanExp((_a = expression.ne.property) === null || _a === void 0 ? void 0 : _a.ref)) {
870
- return expandToNode `
871
- !${translateExpression(entry, id, expression.ne, preDerived, generatingProperty)}
876
+ return expandToNode `
877
+ !${translateExpression(entry, id, expression.ne, preDerived, generatingProperty)}
872
878
  `;
873
879
  }
874
- return expandToNode `
875
- -(${translateExpression(entry, id, expression.ne, preDerived, generatingProperty)})
880
+ return expandToNode `
881
+ -(${translateExpression(entry, id, expression.ne, preDerived, generatingProperty)})
876
882
  `;
877
883
  }
878
884
  function translateAccessExpression(expression, generatingProperty = undefined) {
@@ -891,8 +897,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
891
897
  break;
892
898
  }
893
899
  console.log("Access Name: ", accessName);
894
- return expandToNode `
895
- context.object.${accessName}
900
+ return expandToNode `
901
+ context.object.${accessName}
896
902
  `;
897
903
  }
898
904
  if (((_a = expression.property) === null || _a === void 0 ? void 0 : _a.ref) == undefined) {
@@ -903,20 +909,20 @@ export function translateExpression(entry, id, expression, preDerived = false, g
903
909
  if (generatingProperty && ((_c = expression.property) === null || _c === void 0 ? void 0 : _c.ref) == generatingProperty) {
904
910
  console.log("Generating self referencing Property Access: ", (_d = expression.property.ref) === null || _d === void 0 ? void 0 : _d.name);
905
911
  if (isInitiativeProperty(generatingProperty)) {
906
- return expandToNode `
907
- @system.${(_e = expression.property.ref) === null || _e === void 0 ? void 0 : _e.name.toLowerCase()}
912
+ return expandToNode `
913
+ @system.${(_e = expression.property.ref) === null || _e === void 0 ? void 0 : _e.name.toLowerCase()}
908
914
  `;
909
915
  }
910
916
  // Special case: For attribute self-references, use .value instead of .mod to avoid recursion
911
917
  if (isAttributeExp(generatingProperty)) {
912
918
  const systemPath = `system.${(_f = expression.property.ref) === null || _f === void 0 ? void 0 : _f.name.toLowerCase()}.value`;
913
- return expandToNode `
914
- ${systemPath}
919
+ return expandToNode `
920
+ ${systemPath}
915
921
  `;
916
922
  }
917
923
  const systemPath = getSystemPath((_g = expression.property) === null || _g === void 0 ? void 0 : _g.ref, expression.subProperties, generatingProperty);
918
- return expandToNode `
919
- ${systemPath}
924
+ return expandToNode `
925
+ ${systemPath}
920
926
  `;
921
927
  }
922
928
  // Parent/Self property references store a *path* to another property (e.g. a chosen parent
@@ -939,13 +945,13 @@ export function translateExpression(entry, id, expression, preDerived = false, g
939
945
  }
940
946
  if (isParentPropertyRefExp((_l = expression.property) === null || _l === void 0 ? void 0 : _l.ref)) {
941
947
  // Parent refs store a full path (e.g. "system.fight") resolved against the parent.
942
- return expandToNode `
943
- foundry.utils.getProperty(context.object.parent, context.object.system.${refName}.toLowerCase())${accessor}
948
+ return expandToNode `
949
+ foundry.utils.getProperty(context.object.parent, context.object.system.${refName}.toLowerCase())${accessor}
944
950
  `;
945
951
  }
946
952
  // Self refs store a property name resolved against this document under system.
947
- return expandToNode `
948
- foundry.utils.getProperty(context.object, "system." + context.object.system.${refName}.toLowerCase())${accessor}
953
+ return expandToNode `
954
+ foundry.utils.getProperty(context.object, "system." + context.object.system.${refName}.toLowerCase())${accessor}
949
955
  `;
950
956
  }
951
957
  let systemPath = getSystemPath((_m = expression.property) === null || _m === void 0 ? void 0 : _m.ref, expression.subProperties, expression);
@@ -955,24 +961,24 @@ export function translateExpression(entry, id, expression, preDerived = false, g
955
961
  }
956
962
  console.log("System Path: ", systemPath);
957
963
  if (isInitiativeProperty(generatingProperty)) {
958
- return expandToNode `
959
- @${systemPath}
964
+ return expandToNode `
965
+ @${systemPath}
960
966
  `;
961
967
  }
962
968
  if (isAction(generatingProperty)) {
963
- return expandToNode `
964
- context.object.${systemPath}
969
+ return expandToNode `
970
+ context.object.${systemPath}
965
971
  `;
966
972
  }
967
973
  // If accessing a property on a document choice, wrap with ?? 0 to handle missing documents
968
974
  const needsNullCoalescing = isDocumentChoiceExp((_o = expression.property) === null || _o === void 0 ? void 0 : _o.ref) && expression.subProperties && expression.subProperties.length > 0;
969
975
  if (needsNullCoalescing) {
970
- return expandToNode `
971
- (${systemPath} ?? 0)
976
+ return expandToNode `
977
+ (${systemPath} ?? 0)
972
978
  `;
973
979
  }
974
- return expandToNode `
975
- ${systemPath}
980
+ return expandToNode `
981
+ ${systemPath}
976
982
  `;
977
983
  }
978
984
  // function translateResourceAccessExpression(expression: ResourceAccess): CompositeGeneratorNode | undefined {
@@ -991,35 +997,35 @@ export function translateExpression(entry, id, expression, preDerived = false, g
991
997
  //console.log("Translating If Statement: ");
992
998
  var _a;
993
999
  function translateElseIfStatement(elif) {
994
- return expandToNode `
995
- else if (${translateExpression(entry, id, elif.expression, preDerived, generatingProperty)}) {
996
- ${translateBodyExpressionToJavascript(entry, id, elif.method.body, preDerived, generatingProperty)}
997
- }
1000
+ return expandToNode `
1001
+ else if (${translateExpression(entry, id, elif.expression, preDerived, generatingProperty)}) {
1002
+ ${translateBodyExpressionToJavascript(entry, id, elif.method.body, preDerived, generatingProperty)}
1003
+ }
998
1004
  `;
999
1005
  }
1000
- return expandToNode `
1001
- if (${translateExpression(entry, id, expression.expression, preDerived, generatingProperty)}) {
1002
- ${translateBodyExpressionToJavascript(entry, id, expression.method.body, preDerived, generatingProperty)}
1003
- }
1004
- ${joinToNode(expression.elseIfs, translateElseIfStatement, { appendNewLineIfNotEmpty: true })}
1005
- ${expression.elseMethod != undefined ? expandToNode `
1006
- else {
1007
- ${translateBodyExpressionToJavascript(entry, id, (_a = expression.elseMethod) === null || _a === void 0 ? void 0 : _a.body, preDerived, generatingProperty)}
1008
- }
1009
- `.appendNewLineIfNotEmpty() : ""}
1006
+ return expandToNode `
1007
+ if (${translateExpression(entry, id, expression.expression, preDerived, generatingProperty)}) {
1008
+ ${translateBodyExpressionToJavascript(entry, id, expression.method.body, preDerived, generatingProperty)}
1009
+ }
1010
+ ${joinToNode(expression.elseIfs, translateElseIfStatement, { appendNewLineIfNotEmpty: true })}
1011
+ ${expression.elseMethod != undefined ? expandToNode `
1012
+ else {
1013
+ ${translateBodyExpressionToJavascript(entry, id, (_a = expression.elseMethod) === null || _a === void 0 ? void 0 : _a.body, preDerived, generatingProperty)}
1014
+ }
1015
+ `.appendNewLineIfNotEmpty() : ""}
1010
1016
  `;
1011
1017
  }
1012
1018
  function translateComparisonExpression(expression) {
1013
1019
  var _a, _b, _c, _d, _e, _f;
1014
1020
  console.log("Translating Comparison Expression: ");
1015
1021
  if (isParentTypeCheckExpression(expression)) {
1016
- return expandToNode `
1017
- context.object.parent && context.object.parent.type == "${(_b = (_a = expression.document.ref) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.toLowerCase()}"
1022
+ return expandToNode `
1023
+ context.object.parent && context.object.parent.type == "${(_b = (_a = expression.document.ref) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.toLowerCase()}"
1018
1024
  `;
1019
1025
  }
1020
1026
  if (isTargetTypeCheckExpression(expression)) {
1021
- return expandToNode `
1022
- context.target && context.target.type == "${(_d = (_c = expression.document.ref) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.toLowerCase()}"
1027
+ return expandToNode `
1028
+ context.target && context.target.type == "${(_d = (_c = expression.document.ref) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.toLowerCase()}"
1023
1029
  `;
1024
1030
  }
1025
1031
  // If the term is "equals" or "==", we need to translate it to "===" in JavaScript
@@ -1030,70 +1036,70 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1030
1036
  if (isShorthandComparisonExpression(expression)) {
1031
1037
  console.log("Shorthand Comparison Expression: ", term);
1032
1038
  if (term == "exists") {
1033
- return expandToNode `
1034
- ${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)} != undefined
1039
+ return expandToNode `
1040
+ ${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)} != undefined
1035
1041
  `;
1036
1042
  }
1037
1043
  else if (term == "!exists") {
1038
- return expandToNode `
1039
- ${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)} == undefined
1044
+ return expandToNode `
1045
+ ${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)} == undefined
1040
1046
  `;
1041
1047
  }
1042
1048
  else if (term == "isEmpty") {
1043
- return expandToNode `
1044
- (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.length === 0
1049
+ return expandToNode `
1050
+ (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.length === 0
1045
1051
  `;
1046
1052
  }
1047
1053
  else if (term == "isNotEmpty") {
1048
- return expandToNode `
1049
- (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.length > 0
1054
+ return expandToNode `
1055
+ (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.length > 0
1050
1056
  `;
1051
1057
  }
1052
- return expandToNode `
1053
- ${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)} ${term}
1058
+ return expandToNode `
1059
+ ${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)} ${term}
1054
1060
  `;
1055
1061
  }
1056
1062
  console.log("Comparison Expression: ", expression.e1.$type, term, expression.e2.$type);
1057
1063
  if (term == "has") {
1058
- return expandToNode `
1059
- (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.includes(${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)})
1064
+ return expandToNode `
1065
+ (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.includes(${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)})
1060
1066
  `;
1061
1067
  }
1062
1068
  if (term == "excludes") {
1063
- return expandToNode `
1064
- !(${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.includes(${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)})
1069
+ return expandToNode `
1070
+ !(${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.includes(${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)})
1065
1071
  `;
1066
1072
  }
1067
1073
  if (term == "startsWith") {
1068
- return expandToNode `
1069
- (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.startsWith(${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)})
1074
+ return expandToNode `
1075
+ (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.startsWith(${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)})
1070
1076
  `;
1071
1077
  }
1072
1078
  if (term == "endsWith") {
1073
- return expandToNode `
1074
- (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.endsWith(${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)})
1079
+ return expandToNode `
1080
+ (${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)})?.endsWith(${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)})
1075
1081
  `;
1076
1082
  }
1077
- return expandToNode `
1078
- ${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)} ${term} ${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)}
1083
+ return expandToNode `
1084
+ ${translateExpression(entry, id, expression.e1, preDerived, generatingProperty)} ${term} ${translateExpression(entry, id, expression.e2, preDerived, generatingProperty)}
1079
1085
  `;
1080
1086
  }
1081
1087
  if (expression == undefined) {
1082
1088
  return;
1083
1089
  }
1084
1090
  if (typeof expression == "string" && expression == "nothing") {
1085
- return expandToNode `
1086
- null
1091
+ return expandToNode `
1092
+ null
1087
1093
  `;
1088
1094
  }
1089
1095
  if (typeof expression == "string") {
1090
- return expandToNode `
1091
- "${expression}"
1096
+ return expandToNode `
1097
+ "${expression}"
1092
1098
  `;
1093
1099
  }
1094
1100
  if (typeof expression == "number") {
1095
- return expandToNode `
1096
- ${expression}
1101
+ return expandToNode `
1102
+ ${expression}
1097
1103
  `;
1098
1104
  }
1099
1105
  if (isMethodBlock(expression)) {
@@ -1144,8 +1150,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1144
1150
  let systemPath = getSystemPath((_a = expression.property) === null || _a === void 0 ? void 0 : _a.ref, expression.subProperties, expression, true);
1145
1151
  path = `${path}?.${systemPath}`;
1146
1152
  console.log("Translating Parent Access Expression: ", path);
1147
- return expandToNode `
1148
- ${path} ?? 0
1153
+ return expandToNode `
1154
+ ${path} ?? 0
1149
1155
  `;
1150
1156
  }
1151
1157
  if (isTargetAccess(expression)) {
@@ -1153,8 +1159,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1153
1159
  let systemPath = getSystemPath((_b = expression.property) === null || _b === void 0 ? void 0 : _b.ref, expression.subProperties, undefined, true);
1154
1160
  path = `${path}?.${systemPath}`;
1155
1161
  console.log("Translating Target Access Expression: ", path);
1156
- return expandToNode `
1157
- ${path}
1162
+ return expandToNode `
1163
+ ${path}
1158
1164
  `;
1159
1165
  }
1160
1166
  if (isItemAccess(expression)) {
@@ -1176,8 +1182,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1176
1182
  }
1177
1183
  }
1178
1184
  }
1179
- return expandToNode `
1180
- ${path}
1185
+ return expandToNode `
1186
+ ${path}
1181
1187
  `;
1182
1188
  }
1183
1189
  if (isIfStatement(expression)) {
@@ -1186,15 +1192,29 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1186
1192
  if (isWhenExpressions(expression)) {
1187
1193
  return translateComparisonExpression(expression);
1188
1194
  }
1195
+ if (isRollResultAccess(expression)) {
1196
+ const target = (_h = expression.variable.ref) === null || _h === void 0 ? void 0 : _h.name;
1197
+ const jsMethod = expression.method === "count" ? "countDice"
1198
+ : expression.method === "contains" ? "containsDie"
1199
+ : expression.method;
1200
+ const arg = expression.arg;
1201
+ const argJs = arg.param != undefined
1202
+ ? expandToNode `(${arg.param.name}) => ${translateExpression(entry, id, arg.body, preDerived, generatingProperty)}`
1203
+ : translateExpression(entry, id, arg.value, preDerived, generatingProperty);
1204
+ return expandToNode `${target}.${jsMethod}(${argJs})`;
1205
+ }
1189
1206
  if (isFleetingAccess(expression)) {
1190
- let accessPath = (_h = expression.variable.ref) === null || _h === void 0 ? void 0 : _h.name;
1207
+ let accessPath = (_j = expression.variable.ref) === null || _j === void 0 ? void 0 : _j.name;
1191
1208
  if (expression.subProperty != undefined) {
1192
- accessPath = `${accessPath}.${fleetingSubProperty(expression)}`;
1209
+ // Foundry's Roll#dice returns DiceTerms; remap r.dice to the face-value getter.
1210
+ const isRollDice = (isRoll((_k = expression.variable.ref) === null || _k === void 0 ? void 0 : _k.value) || isDamageRoll((_l = expression.variable.ref) === null || _l === void 0 ? void 0 : _l.value))
1211
+ && expression.subProperty.toLowerCase() === "dice";
1212
+ accessPath = `${accessPath}.${isRollDice ? "diceFaces" : fleetingSubProperty(expression)}`;
1193
1213
  }
1194
1214
  else if (expression.arrayAccess != undefined) {
1195
1215
  accessPath = `${accessPath}[${translateExpression(entry, id, expression.arrayAccess, preDerived, generatingProperty)}]`;
1196
1216
  }
1197
- else if (isRoll((_j = expression.variable.ref) === null || _j === void 0 ? void 0 : _j.value) || isDamageRoll((_k = expression.variable.ref) === null || _k === void 0 ? void 0 : _k.value)) {
1217
+ else if (isRoll((_m = expression.variable.ref) === null || _m === void 0 ? void 0 : _m.value) || isDamageRoll((_o = expression.variable.ref) === null || _o === void 0 ? void 0 : _o.value)) {
1198
1218
  // A bare reference to a roll variable used in a general expression
1199
1219
  // (comparison, arithmetic, assignment, return, function arg) should
1200
1220
  // use the roll's numeric total rather than the Roll object itself.
@@ -1202,19 +1222,19 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1202
1222
  // for dice display, so this does not affect "chat { roll1 }".
1203
1223
  accessPath = `${accessPath}.total`;
1204
1224
  }
1205
- return expandToNode `
1206
- ${accessPath}
1225
+ return expandToNode `
1226
+ ${accessPath}
1207
1227
  `;
1208
1228
  }
1209
1229
  if (isParameter(expression)) {
1210
- return expandToNode `
1211
- ${expression.name}
1230
+ return expandToNode `
1231
+ ${expression.name}
1212
1232
  `;
1213
1233
  }
1214
1234
  if (isJS(expression)) {
1215
1235
  // Remove the last "}" from the JS expression
1216
- return expandToNode `
1217
- ${expression.js.replace("@js{", "").slice(0, -1)}
1236
+ return expandToNode `
1237
+ ${expression.js.replace("@js{", "").slice(0, -1)}
1218
1238
  `;
1219
1239
  }
1220
1240
  if (isChatCard(expression)) {
@@ -1231,37 +1251,37 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1231
1251
  case "Effects":
1232
1252
  return undefined; // Renders in a different way
1233
1253
  case "DocumentType":
1234
- return expandToNode `
1235
- { isRoll: false, label: "Type", value: context.object.type, wide: ${wide}, hasValue: context.object.type != "" },
1254
+ return expandToNode `
1255
+ { isRoll: false, label: "Type", value: context.object.type, wide: ${wide}, hasValue: context.object.type != "" },
1236
1256
  `;
1237
1257
  case "EditMode":
1238
- return expandToNode `
1239
- { isRoll: false, label: "Edit Mode", value: context.object.getFlag('${id}', 'editMode') ?? true, wide: ${wide}, hasValue: context.object.getFlag('${id}', 'editMode') != undefined },
1258
+ return expandToNode `
1259
+ { isRoll: false, label: "Edit Mode", value: context.object.getFlag('${id}', 'editMode') ?? true, wide: ${wide}, hasValue: context.object.getFlag('${id}', 'editMode') != undefined },
1240
1260
  `;
1241
1261
  // Properties on the document
1242
1262
  default:
1243
- return expandToNode `
1244
- { isRoll: false, label: "${expression.access.toString()}", value: context.object.${expression.access.toString().toLowerCase()}, wide: ${wide}, hasValue: context.object.${expression.access.toString().toLowerCase()} != "" },
1263
+ return expandToNode `
1264
+ { isRoll: false, label: "${expression.access.toString()}", value: context.object.${expression.access.toString().toLowerCase()}, wide: ${wide}, hasValue: context.object.${expression.access.toString().toLowerCase()} != "" },
1245
1265
  `;
1246
1266
  }
1247
1267
  }
1248
1268
  if (isMeasuredTemplateField((_d = expression.property) === null || _d === void 0 ? void 0 : _d.ref)) {
1249
- return expandToNode `
1250
- { isRoll: false, isMeasuredTemplate: true, label: "${humanize((_g = (_f = (_e = expression.property) === null || _e === void 0 ? void 0 : _e.ref) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : "")}", value: context.object.${systemPath}?.summary, wide: true, hasValue: context.object.${systemPath} != undefined, object: context.object.${systemPath} },
1269
+ return expandToNode `
1270
+ { isRoll: false, isMeasuredTemplate: true, label: "${humanize((_g = (_f = (_e = expression.property) === null || _e === void 0 ? void 0 : _e.ref) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : "")}", value: context.object.${systemPath}?.summary, wide: true, hasValue: context.object.${systemPath} != undefined, object: context.object.${systemPath} },
1251
1271
  `;
1252
1272
  }
1253
1273
  if (isParentPropertyRefExp((_h = expression.property) === null || _h === void 0 ? void 0 : _h.ref)) {
1254
- return expandToNode `
1255
- { isRoll: false, label: "${humanize((_l = (_k = (_j = expression.property) === null || _j === void 0 ? void 0 : _j.ref) === null || _k === void 0 ? void 0 : _k.name) !== null && _l !== void 0 ? _l : "")}", value: context.object.${systemPath}.replace("system", "").replaceAll(".", "").titleCase(), wide: ${wide}, hasValue: context.object.${systemPath} != "" },
1274
+ return expandToNode `
1275
+ { isRoll: false, label: "${humanize((_l = (_k = (_j = expression.property) === null || _j === void 0 ? void 0 : _j.ref) === null || _k === void 0 ? void 0 : _k.name) !== null && _l !== void 0 ? _l : "")}", value: context.object.${systemPath}.replace("system", "").replaceAll(".", "").titleCase(), wide: ${wide}, hasValue: context.object.${systemPath} != "" },
1256
1276
  `;
1257
1277
  }
1258
1278
  if (isSelfPropertyRefExp((_m = expression.property) === null || _m === void 0 ? void 0 : _m.ref)) {
1259
- return expandToNode `
1260
- { isRoll: false, label: "${humanize((_q = (_p = (_o = expression.property) === null || _o === void 0 ? void 0 : _o.ref) === null || _p === void 0 ? void 0 : _p.name) !== null && _q !== void 0 ? _q : "")}", value: foundry.utils.getProperty(context.object, context.object.${systemPath}).replace("system", "").replaceAll(".", "").titleCase(), wide: ${wide}, hasValue: context.object.${systemPath} != "" },
1279
+ return expandToNode `
1280
+ { isRoll: false, label: "${humanize((_q = (_p = (_o = expression.property) === null || _o === void 0 ? void 0 : _o.ref) === null || _p === void 0 ? void 0 : _p.name) !== null && _q !== void 0 ? _q : "")}", value: foundry.utils.getProperty(context.object, context.object.${systemPath}).replace("system", "").replaceAll(".", "").titleCase(), wide: ${wide}, hasValue: context.object.${systemPath} != "" },
1261
1281
  `;
1262
1282
  }
1263
- return expandToNode `
1264
- { isRoll: false, label: "${humanize((_t = (_s = (_r = expression.property) === null || _r === void 0 ? void 0 : _r.ref) === null || _s === void 0 ? void 0 : _s.name) !== null && _t !== void 0 ? _t : "")}", value: context.object.${systemPath}, wide: ${wide}, hasValue: context.object.${systemPath} != "" },
1283
+ return expandToNode `
1284
+ { isRoll: false, label: "${humanize((_t = (_s = (_r = expression.property) === null || _r === void 0 ? void 0 : _r.ref) === null || _s === void 0 ? void 0 : _s.name) !== null && _t !== void 0 ? _t : "")}", value: context.object.${systemPath}, wide: ${wide}, hasValue: context.object.${systemPath} != "" },
1265
1285
  `;
1266
1286
  }
1267
1287
  if (isFleetingAccess(expression)) {
@@ -1276,49 +1296,49 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1276
1296
  if (isDamageRoll((_v = expression.variable.ref) === null || _v === void 0 ? void 0 : _v.value)) {
1277
1297
  roll = true;
1278
1298
  wide = true;
1279
- return expandToNode `
1280
- {
1281
- isRoll: ${roll},
1282
- isDamageRoll: true,
1283
- label: "${humanize((_x = (_w = expression.variable.ref) === null || _w === void 0 ? void 0 : _w.name) !== null && _x !== void 0 ? _x : "")}",
1284
- value: ${accessPath},
1285
- wide: ${wide},
1286
- tooltip: await ${accessPath}.getTooltip(),
1287
- damageType: ${accessPath}.options.type.value,
1288
- damageIcon: ${accessPath}.options.type.icon,
1289
- damageColor: ${accessPath}.options.type.color,
1290
- damageMetadata: ${accessPath}.options.type
1291
- },
1299
+ return expandToNode `
1300
+ {
1301
+ isRoll: ${roll},
1302
+ isDamageRoll: true,
1303
+ label: "${humanize((_x = (_w = expression.variable.ref) === null || _w === void 0 ? void 0 : _w.name) !== null && _x !== void 0 ? _x : "")}",
1304
+ value: ${accessPath},
1305
+ wide: ${wide},
1306
+ tooltip: await ${accessPath}.getTooltip(),
1307
+ damageType: ${accessPath}.options.type.value,
1308
+ damageIcon: ${accessPath}.options.type.icon,
1309
+ damageColor: ${accessPath}.options.type.color,
1310
+ damageMetadata: ${accessPath}.options.type
1311
+ },
1292
1312
  `;
1293
1313
  }
1294
1314
  if (isRoll((_y = expression.variable.ref) === null || _y === void 0 ? void 0 : _y.value)) {
1295
1315
  roll = true;
1296
1316
  wide = true;
1297
- return expandToNode `
1298
- { isRoll: ${roll}, label: "${humanize((_0 = (_z = expression.variable.ref) === null || _z === void 0 ? void 0 : _z.name) !== null && _0 !== void 0 ? _0 : "")}", value: ${accessPath}, wide: ${wide}, tooltip: await ${accessPath}.getTooltip() },
1317
+ return expandToNode `
1318
+ { isRoll: ${roll}, label: "${humanize((_0 = (_z = expression.variable.ref) === null || _z === void 0 ? void 0 : _z.name) !== null && _0 !== void 0 ? _0 : "")}", value: ${accessPath}, wide: ${wide}, tooltip: await ${accessPath}.getTooltip() },
1299
1319
  `;
1300
1320
  }
1301
- return expandToNode `
1302
- { isRoll: ${roll}, label: "${humanize((_2 = (_1 = expression.variable.ref) === null || _1 === void 0 ? void 0 : _1.name) !== null && _2 !== void 0 ? _2 : "")}", value: ${accessPath}, wide: ${wide}, hasValue: ${accessPath} != "" },
1321
+ return expandToNode `
1322
+ { isRoll: ${roll}, label: "${humanize((_2 = (_1 = expression.variable.ref) === null || _1 === void 0 ? void 0 : _1.name) !== null && _2 !== void 0 ? _2 : "")}", value: ${accessPath}, wide: ${wide}, hasValue: ${accessPath} != "" },
1303
1323
  `;
1304
1324
  }
1305
1325
  if (isParentAccess(expression)) {
1306
1326
  let systemPath = getSystemPath((_3 = expression.property) === null || _3 === void 0 ? void 0 : _3.ref, expression.subProperties, undefined, true);
1307
1327
  const wide = expression.type == "wide" ? true : false;
1308
- return expandToNode `
1309
- { isRoll: false, label: "${humanize((_6 = (_5 = (_4 = expression.property) === null || _4 === void 0 ? void 0 : _4.ref) === null || _5 === void 0 ? void 0 : _5.name) !== null && _6 !== void 0 ? _6 : "")}", value: context.object.parent?.${systemPath}, wide: ${wide}, hasValue: context.object.parent?.${systemPath} != "" },
1328
+ return expandToNode `
1329
+ { isRoll: false, label: "${humanize((_6 = (_5 = (_4 = expression.property) === null || _4 === void 0 ? void 0 : _4.ref) === null || _5 === void 0 ? void 0 : _5.name) !== null && _6 !== void 0 ? _6 : "")}", value: context.object.parent?.${systemPath}, wide: ${wide}, hasValue: context.object.parent?.${systemPath} != "" },
1310
1330
  `;
1311
1331
  }
1312
1332
  if (isTargetAccess(expression)) {
1313
1333
  let systemPath = getSystemPath((_7 = expression.property) === null || _7 === void 0 ? void 0 : _7.ref, expression.subProperties, undefined, true);
1314
1334
  const wide = expression.type == "wide" ? true : false;
1315
- return expandToNode `
1316
- { isRoll: false, label: "${humanize((_10 = (_9 = (_8 = expression.property) === null || _8 === void 0 ? void 0 : _8.ref) === null || _9 === void 0 ? void 0 : _9.name) !== null && _10 !== void 0 ? _10 : "")}", value: context.target?.${systemPath}, wide: ${wide}, hasValue: context.target?.${systemPath} != "" },
1335
+ return expandToNode `
1336
+ { isRoll: false, label: "${humanize((_10 = (_9 = (_8 = expression.property) === null || _8 === void 0 ? void 0 : _8.ref) === null || _9 === void 0 ? void 0 : _9.name) !== null && _10 !== void 0 ? _10 : "")}", value: context.target?.${systemPath}, wide: ${wide}, hasValue: context.target?.${systemPath} != "" },
1317
1337
  `;
1318
1338
  }
1319
1339
  if (isExpression(expression)) {
1320
- return expandToNode `
1321
- { isParagraph: true, value: ${translateExpression(entry, id, expression, preDerived, generatingProperty)} },
1340
+ return expandToNode `
1341
+ { isParagraph: true, value: ${translateExpression(entry, id, expression, preDerived, generatingProperty)} },
1322
1342
  `;
1323
1343
  }
1324
1344
  return;
@@ -1327,8 +1347,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1327
1347
  var _a, _b, _c;
1328
1348
  if (isAccess(expression)) {
1329
1349
  let systemPath = getSystemPath((_a = expression.property) === null || _a === void 0 ? void 0 : _a.ref, expression.subProperties, (_b = expression.propertyLookup) === null || _b === void 0 ? void 0 : _b.ref);
1330
- return expandToNode `
1331
- context.object.${systemPath}
1350
+ return expandToNode `
1351
+ context.object.${systemPath}
1332
1352
  `;
1333
1353
  }
1334
1354
  if (isFleetingAccess(expression)) {
@@ -1336,47 +1356,47 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1336
1356
  if (expression.subProperty != undefined) {
1337
1357
  accessPath = `${accessPath}.${fleetingSubProperty(expression)}`;
1338
1358
  }
1339
- return expandToNode `
1340
- ${accessPath}
1359
+ return expandToNode `
1360
+ ${accessPath}
1341
1361
  `;
1342
1362
  }
1343
1363
  if (isExpression(expression)) {
1344
- return expandToNode `
1345
- ${translateExpression(entry, id, expression, preDerived, generatingProperty)}
1364
+ return expandToNode `
1365
+ ${translateExpression(entry, id, expression, preDerived, generatingProperty)}
1346
1366
  `;
1347
1367
  }
1348
1368
  return;
1349
1369
  }
1350
1370
  const flavorTag = expression.body.chatExp.find(x => x.type == "flavor");
1351
1371
  const shouldShowEffects = expression.body.chatExp.some(x => isAccess(x) && x.access === "Effects");
1352
- return expandToNode `
1353
- // Create the chat message
1354
- const ${expression.name}Description = context.object.description ?? context.object.system.description;
1355
- const ${expression.name}Context = {
1356
- cssClass: "${id} ${toMachineIdentifier(expression.name)}",
1357
- document: context.object,
1358
- description: ${expression.name}Description,
1359
- hasDescription: ${expression.name}Description!= "",
1360
- hasEffects: ${shouldShowEffects},
1361
- parts: [
1362
- ${joinToNode(expression.body.chatExp.filter(x => x.type != "tag"), (expression) => translateChatBodyExpression(expression), { appendNewLineIfNotEmpty: true })}
1363
- ],
1364
- tags: [
1365
- ${joinToNode(expression.body.chatExp.filter(x => x.type == "tag"), (expression) => translateChatBodyExpression(expression), { appendNewLineIfNotEmpty: true })}
1366
- ]
1367
- };
1368
- const ${expression.name}Content = await renderTemplate("systems/${id}/system/templates/chat/standard-card.hbs", ${expression.name}Context);
1369
- const ${expression.name}ChatFlavor = (system) => {
1370
- return ${flavorTag != undefined ? translateChatBodyExpressionForFlavor(flavorTag) : `""`}
1371
- }
1372
- await ChatMessage.create({
1373
- user: game.user._id,
1374
- speaker: ChatMessage.getSpeaker(),
1375
- content: ${expression.name}Content,
1376
- flavor: ${expression.name}ChatFlavor(context.object.system),
1377
- ...(${expression.name}Context.parts.find(x => x.isRoll) ? {} : { style: CONST.CHAT_MESSAGE_STYLES.IC }),
1378
- rolls: Array.from(${expression.name}Context.parts.filter(x => x.isRoll).map(x => x.value)),
1379
- });
1372
+ return expandToNode `
1373
+ // Create the chat message
1374
+ const ${expression.name}Description = context.object.description ?? context.object.system.description;
1375
+ const ${expression.name}Context = {
1376
+ cssClass: "${id} ${toMachineIdentifier(expression.name)}",
1377
+ document: context.object,
1378
+ description: ${expression.name}Description,
1379
+ hasDescription: ${expression.name}Description!= "",
1380
+ hasEffects: ${shouldShowEffects},
1381
+ parts: [
1382
+ ${joinToNode(expression.body.chatExp.filter(x => x.type != "tag"), (expression) => translateChatBodyExpression(expression), { appendNewLineIfNotEmpty: true })}
1383
+ ],
1384
+ tags: [
1385
+ ${joinToNode(expression.body.chatExp.filter(x => x.type == "tag"), (expression) => translateChatBodyExpression(expression), { appendNewLineIfNotEmpty: true })}
1386
+ ]
1387
+ };
1388
+ const ${expression.name}Content = await renderTemplate("systems/${id}/system/templates/chat/standard-card.hbs", ${expression.name}Context);
1389
+ const ${expression.name}ChatFlavor = (system) => {
1390
+ return ${flavorTag != undefined ? translateChatBodyExpressionForFlavor(flavorTag) : `""`}
1391
+ }
1392
+ await ChatMessage.create({
1393
+ user: game.user._id,
1394
+ speaker: ChatMessage.getSpeaker(),
1395
+ content: ${expression.name}Content,
1396
+ flavor: ${expression.name}ChatFlavor(context.object.system),
1397
+ ...(${expression.name}Context.parts.find(x => x.isRoll) ? {} : { style: CONST.CHAT_MESSAGE_STYLES.IC }),
1398
+ rolls: Array.from(${expression.name}Context.parts.filter(x => x.isRoll).map(x => x.value)),
1399
+ });
1380
1400
  `;
1381
1401
  }
1382
1402
  if (isRoll(expression) || isDamageRoll(expression)) {
@@ -1387,20 +1407,20 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1387
1407
  const typeParam = expression.params.find(isTypeParam);
1388
1408
  let damageTypeDataAccess = '';
1389
1409
  if (isAccess(typeParam.value)) {
1390
- damageTypeDataAccess = `context.object.system.${(_o = (_m = (_l = typeParam.value) === null || _l === void 0 ? void 0 : _l.property) === null || _m === void 0 ? void 0 : _m.ref) === null || _o === void 0 ? void 0 : _o.name.toLowerCase()}`;
1410
+ damageTypeDataAccess = `context.object.system.${(_r = (_q = (_p = typeParam.value) === null || _p === void 0 ? void 0 : _p.property) === null || _q === void 0 ? void 0 : _q.ref) === null || _r === void 0 ? void 0 : _r.name.toLowerCase()}`;
1391
1411
  }
1392
1412
  else if (isParentAccess(typeParam.value)) {
1393
1413
  // Handle parent.SomeDamageType
1394
- const parentPath = (_s = (_r = (_q = (_p = typeParam.value.property) === null || _p === void 0 ? void 0 : _p.ref) === null || _q === void 0 ? void 0 : _q.name) === null || _r === void 0 ? void 0 : _r.toLowerCase()) !== null && _s !== void 0 ? _s : '';
1414
+ const parentPath = (_v = (_u = (_t = (_s = typeParam.value.property) === null || _s === void 0 ? void 0 : _s.ref) === null || _t === void 0 ? void 0 : _t.name) === null || _u === void 0 ? void 0 : _u.toLowerCase()) !== null && _v !== void 0 ? _v : '';
1395
1415
  damageTypeDataAccess = `context.object.parent?.system.${parentPath}`;
1396
1416
  }
1397
- return expandToNode `
1398
- await new ${entry.config.name}DamageRoll(
1399
- ${joinToNode(rollExpression.parts, e => translateDiceParts(e), { separator: " + " })},
1400
- {${joinToNode(rollExpression.parts, e => translateDiceData(e, entry, id, preDerived, generatingProperty), { separator: ", " })},
1401
- actor: context.actor},
1402
- { type: ${damageTypeDataAccess} }
1403
- ).roll()
1417
+ return expandToNode `
1418
+ await new ${entry.config.name}DamageRoll(
1419
+ ${joinToNode(rollExpression.parts, e => translateDiceParts(e), { separator: " + " })},
1420
+ {${joinToNode(rollExpression.parts, e => translateDiceData(e, entry, id, preDerived, generatingProperty), { separator: ", " })},
1421
+ actor: context.actor},
1422
+ { type: ${damageTypeDataAccess} }
1423
+ ).roll()
1404
1424
  `;
1405
1425
  }
1406
1426
  const rollParts = expression.parts;
@@ -1408,32 +1428,51 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1408
1428
  const displayFormula = displayFormulaParts.every(p => p != null)
1409
1429
  ? displayFormulaParts.join("")
1410
1430
  : undefined;
1411
- return expandToNode `
1431
+ // Build the detection-config options (crit/fumble/success/failure) passed as the
1432
+ // Roll constructor's 3rd arg, so getters can read them off this.options after .roll().
1433
+ const critParam = expression.params.find(isCritParam);
1434
+ const fumbleParam = expression.params.find(isFumbleParam);
1435
+ const successParam = expression.params.find(isSuccessParam);
1436
+ const failureParam = expression.params.find(isFailureParam);
1437
+ const optionEntries = [];
1438
+ const thresholdEntry = (key, p) => { var _a; return expandToNode `${key}: { op: "${(_a = p.op) !== null && _a !== void 0 ? _a : '=='}", value: ${translateExpression(entry, id, p.value, preDerived, generatingProperty)} }`; };
1439
+ if (critParam)
1440
+ optionEntries.push(thresholdEntry("crit", critParam));
1441
+ if (fumbleParam)
1442
+ optionEntries.push(thresholdEntry("fumble", fumbleParam));
1443
+ if (successParam)
1444
+ optionEntries.push(thresholdEntry("success", successParam));
1445
+ if (failureParam)
1446
+ optionEntries.push(thresholdEntry("failure", failureParam));
1447
+ const rollOptions = optionEntries.length > 0
1448
+ ? expandToNode `, { ${joinToNode(optionEntries, e => e, { separator: ", " })} }`
1449
+ : undefined;
1450
+ return expandToNode `
1412
1451
  Object.assign(await new ${entry.config.name}Roll(${joinToNode(rollParts, (e, idx) => {
1413
1452
  const nextPart = rollParts[idx + 1];
1414
1453
  const nextIsDice = nextPart != null && isLiteral(nextPart) && typeof nextPart.val === 'string' && IntelligentSystemDesignLanguageTerminals.DICE.test(nextPart.val);
1415
1454
  return translateDiceParts(e, nextIsDice);
1416
- }, { separator: " + " })}, {${joinToNode(rollParts, e => translateDiceData(e, entry, id, preDerived, generatingProperty), { separator: ", " })}}).roll(), ${displayFormula != null ? `{_displayFormula: "${displayFormula}"}` : '{}'})
1455
+ }, { separator: " + " })}, {${joinToNode(rollParts, e => translateDiceData(e, entry, id, preDerived, generatingProperty), { separator: ", " })}}${rollOptions !== null && rollOptions !== void 0 ? rollOptions : ''}).roll(), ${displayFormula != null ? `{_displayFormula: "${displayFormula}"}` : '{}'})
1417
1456
  `;
1418
1457
  }
1419
1458
  if (isSelfMethod(expression)) {
1420
1459
  switch (expression.method) {
1421
1460
  case "delete()": {
1422
- return expandToNode `
1423
- await document.delete();
1424
- selfDeleted = true;
1461
+ return expandToNode `
1462
+ await document.delete();
1463
+ selfDeleted = true;
1425
1464
  `;
1426
1465
  }
1427
1466
  case "update()": {
1428
- return expandToNode `
1429
- if (selfDeleted) {
1430
- ui.notifications.error("Cannot update a deleted document");
1431
- }
1432
- else if (Object.keys(update).length > 0) {
1433
- await document.update(update);
1434
- context.object.system = document.system;
1435
- }
1436
- update = {};
1467
+ return expandToNode `
1468
+ if (selfDeleted) {
1469
+ ui.notifications.error("Cannot update a deleted document");
1470
+ }
1471
+ else if (Object.keys(update).length > 0) {
1472
+ await document.update(update);
1473
+ context.object.system = document.system;
1474
+ }
1475
+ update = {};
1437
1476
  `.appendNewLine();
1438
1477
  }
1439
1478
  default: {
@@ -1442,8 +1481,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1442
1481
  }
1443
1482
  }
1444
1483
  if (isArrayExpression(expression)) {
1445
- return expandToNode `
1446
- [${joinToNode(expression.items, e => translateExpression(entry, id, e, preDerived, generatingProperty), { separator: ", " })}]
1484
+ return expandToNode `
1485
+ [${joinToNode(expression.items, e => translateExpression(entry, id, e, preDerived, generatingProperty), { separator: ", " })}]
1447
1486
  `;
1448
1487
  }
1449
1488
  if (isEach(expression)) {
@@ -1451,10 +1490,10 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1451
1490
  const eachExpression = expression;
1452
1491
  const collection = translateExpression(entry, id, expression.collection, preDerived, generatingProperty);
1453
1492
  if (isNumberRange(expression.collection)) {
1454
- return expandToNode `
1455
- for (const ${translateExpression(entry, id, expression.var, preDerived, generatingProperty)} of ${collection} ?? []) {
1456
- ${translateBodyExpressionToJavascript(entry, id, expression.method.body, preDerived, generatingProperty)}
1457
- }
1493
+ return expandToNode `
1494
+ for (const ${translateExpression(entry, id, expression.var, preDerived, generatingProperty)} of ${collection} ?? []) {
1495
+ ${translateBodyExpressionToJavascript(entry, id, expression.method.body, preDerived, generatingProperty)}
1496
+ }
1458
1497
  `;
1459
1498
  }
1460
1499
  let updateExpression;
@@ -1463,33 +1502,33 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1463
1502
  return isVariableAssignment(x) && x.variable.ref == eachExpression.var;
1464
1503
  })) {
1465
1504
  if (isParentAccess(expression.collection)) {
1466
- updateExpression = expandToNode `
1467
- parentEmbeddedUpdate["${getSystemPath((_t = expression.collection.property) === null || _t === void 0 ? void 0 : _t.ref, [], undefined, false)}"] = ${collection};
1505
+ updateExpression = expandToNode `
1506
+ parentEmbeddedUpdate["${getSystemPath((_w = expression.collection.property) === null || _w === void 0 ? void 0 : _w.ref, [], undefined, false)}"] = ${collection};
1468
1507
  `;
1469
1508
  }
1470
1509
  else if (isTargetAccess(expression.collection)) {
1471
- updateExpression = expandToNode `
1472
- targetEmbeddedUpdate["${getSystemPath((_u = expression.collection.property) === null || _u === void 0 ? void 0 : _u.ref, [], undefined, false)}"] = ${collection};
1510
+ updateExpression = expandToNode `
1511
+ targetEmbeddedUpdate["${getSystemPath((_x = expression.collection.property) === null || _x === void 0 ? void 0 : _x.ref, [], undefined, false)}"] = ${collection};
1473
1512
  `;
1474
1513
  }
1475
1514
  else {
1476
- updateExpression = expandToNode `
1477
- embeddedUpdate["${collection}"] = ${collection};
1515
+ updateExpression = expandToNode `
1516
+ embeddedUpdate["${collection}"] = ${collection};
1478
1517
  `;
1479
1518
  }
1480
1519
  }
1481
- return expandToNode `
1482
- for (const ${translateExpression(entry, id, expression.var, preDerived, generatingProperty)} of ${collection} ?? []) {
1483
- ${translateBodyExpressionToJavascript(entry, id, expression.method.body, preDerived, generatingProperty)}
1484
- }
1485
- ${updateExpression}
1520
+ return expandToNode `
1521
+ for (const ${translateExpression(entry, id, expression.var, preDerived, generatingProperty)} of ${collection} ?? []) {
1522
+ ${translateBodyExpressionToJavascript(entry, id, expression.method.body, preDerived, generatingProperty)}
1523
+ }
1524
+ ${updateExpression}
1486
1525
  `;
1487
1526
  }
1488
1527
  if (isPrompt(expression)) {
1489
1528
  const labelParam = expression.params.find(x => isLabelParam(x));
1490
- const title = (_v = labelParam === null || labelParam === void 0 ? void 0 : labelParam.value) !== null && _v !== void 0 ? _v : "Prompt";
1529
+ const title = (_y = labelParam === null || labelParam === void 0 ? void 0 : labelParam.value) !== null && _y !== void 0 ? _y : "Prompt";
1491
1530
  const targetParam = expression.params.find(x => isTargetParam(x));
1492
- const target = (_w = targetParam === null || targetParam === void 0 ? void 0 : targetParam.value) !== null && _w !== void 0 ? _w : "self";
1531
+ const target = (_z = targetParam === null || targetParam === void 0 ? void 0 : targetParam.value) !== null && _z !== void 0 ? _z : "self";
1493
1532
  // Registry key for the generated Vue prompt app (game.system.prompts.<doc><action><variable>).
1494
1533
  const promptAction = AstUtils.getContainerOfType(expression, isAction);
1495
1534
  const promptDocument = AstUtils.getContainerOfType(expression, isDocument);
@@ -1507,192 +1546,192 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1507
1546
  if (timeLimitParam != undefined) {
1508
1547
  let durationMod = "";
1509
1548
  const duration = translateExpression(entry, id, timeLimitParam.value, preDerived, generatingProperty);
1510
- let units = (_x = timeLimitParam.unit) !== null && _x !== void 0 ? _x : "ms";
1549
+ let units = (_0 = timeLimitParam.unit) !== null && _0 !== void 0 ? _0 : "ms";
1511
1550
  if (units === "seconds") {
1512
1551
  durationMod = ` * 1000`;
1513
1552
  }
1514
1553
  else if (units === "minutes") {
1515
1554
  durationMod = ` * 60 * 1000`;
1516
1555
  }
1517
- durationExpression = expandToNode `
1518
- ${duration}${durationMod}
1556
+ durationExpression = expandToNode `
1557
+ ${duration}${durationMod}
1519
1558
  `;
1520
1559
  }
1521
1560
  if (target == "gm") {
1522
- return expandToNode `
1523
- await new Promise((resolve, reject) => {
1524
-
1525
- const firstGm = game.users.find(u => u.isGM && u.active);
1526
- const uuid = foundry.utils.randomID();
1527
-
1528
- // Setup a listener that will wait for this response
1529
- game.socket.on("system.${id}", (data) => {
1530
- if (data.type != "promptResponse" || data.uuid != uuid) return;
1531
-
1532
- // Resolve the promise with the data
1533
- resolve(data.data);
1534
- });
1535
-
1536
- game.socket.emit("system.${id}", {
1537
- uuid: uuid,
1538
- type: "prompt",
1539
- userId: game.user.id,
1540
- ${widthParam ? `width: ${widthParam.value},` : ""}
1541
- ${heightParam ? `height: ${heightParam.value},` : ""}
1542
- ${locationParam ? expandToNode `left: ${translateExpression(entry, id, locationParam.x, false, generatingProperty)},
1543
- top: ${translateExpression(entry, id, locationParam.y, false, generatingProperty)},` : ""}
1544
- ${timeLimitParam ? expandToNode `timeLimit: ${durationExpression},` : ""}
1545
- title: "${title}",
1546
- promptKey: "${promptKey}",
1547
- documentUuid: context.object.uuid,
1548
- }, {recipients: [firstGm.id]});
1549
- });
1561
+ return expandToNode `
1562
+ await new Promise((resolve, reject) => {
1563
+
1564
+ const firstGm = game.users.find(u => u.isGM && u.active);
1565
+ const uuid = foundry.utils.randomID();
1566
+
1567
+ // Setup a listener that will wait for this response
1568
+ game.socket.on("system.${id}", (data) => {
1569
+ if (data.type != "promptResponse" || data.uuid != uuid) return;
1570
+
1571
+ // Resolve the promise with the data
1572
+ resolve(data.data);
1573
+ });
1574
+
1575
+ game.socket.emit("system.${id}", {
1576
+ uuid: uuid,
1577
+ type: "prompt",
1578
+ userId: game.user.id,
1579
+ ${widthParam ? `width: ${widthParam.value},` : ""}
1580
+ ${heightParam ? `height: ${heightParam.value},` : ""}
1581
+ ${locationParam ? expandToNode `left: ${translateExpression(entry, id, locationParam.x, false, generatingProperty)},
1582
+ top: ${translateExpression(entry, id, locationParam.y, false, generatingProperty)},` : ""}
1583
+ ${timeLimitParam ? expandToNode `timeLimit: ${durationExpression},` : ""}
1584
+ title: "${title}",
1585
+ promptKey: "${promptKey}",
1586
+ documentUuid: context.object.uuid,
1587
+ }, {recipients: [firstGm.id]});
1588
+ });
1550
1589
  `;
1551
1590
  }
1552
1591
  if (target == "target") {
1553
- return expandToNode `
1554
- await new Promise((resolve, reject) => {
1555
- // Try to find a non-GM owner
1556
- let owner = game.users.find(u => u.active && !u.isGM && u.id != game.user.id && context.target.testUserPermission(u, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER));
1557
-
1558
- // If no owner is found, use the first active user
1559
- if (!owner) {
1560
- owner = game.users.find(u => u.active && u.id != game.user.id && context.target.testUserPermission(u, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER));
1561
- }
1562
-
1563
- // If still no owner is found, default to the current user
1564
- if (!owner) {
1565
- owner = game.user.id;
1566
- }
1567
- let ownerId = owner.id;
1568
- const uuid = foundry.utils.randomID();
1569
-
1570
- // Setup a listener that will wait for this response
1571
- game.socket.on("system.${id}", (data) => {
1572
- if (data.type != "promptResponse" || data.uuid != uuid) return;
1573
-
1574
- // Resolve the promise with the data
1575
- resolve(data.data);
1576
- });
1577
-
1578
- game.socket.emit("system.${id}", {
1579
- uuid: uuid,
1580
- type: "prompt",
1581
- userId: game.user.id,
1582
- ${widthParam ? `width: ${widthParam.value},` : ""}
1583
- ${heightParam ? `height: ${heightParam.value},` : ""}
1584
- ${locationParam ? expandToNode `left: ${translateExpression(entry, id, locationParam.x, false, generatingProperty)},
1585
- top: ${translateExpression(entry, id, locationParam.y, false, generatingProperty)},` : ""}
1586
- ${timeLimitParam ? expandToNode `timeLimit: ${durationExpression},` : ""}
1587
- title: "${title}",
1588
- promptKey: "${promptKey}",
1589
- documentUuid: context.object.uuid,
1590
- }, {recipients: [ownerId]});
1591
- });
1592
+ return expandToNode `
1593
+ await new Promise((resolve, reject) => {
1594
+ // Try to find a non-GM owner
1595
+ let owner = game.users.find(u => u.active && !u.isGM && u.id != game.user.id && context.target.testUserPermission(u, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER));
1596
+
1597
+ // If no owner is found, use the first active user
1598
+ if (!owner) {
1599
+ owner = game.users.find(u => u.active && u.id != game.user.id && context.target.testUserPermission(u, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER));
1600
+ }
1601
+
1602
+ // If still no owner is found, default to the current user
1603
+ if (!owner) {
1604
+ owner = game.user.id;
1605
+ }
1606
+ let ownerId = owner.id;
1607
+ const uuid = foundry.utils.randomID();
1608
+
1609
+ // Setup a listener that will wait for this response
1610
+ game.socket.on("system.${id}", (data) => {
1611
+ if (data.type != "promptResponse" || data.uuid != uuid) return;
1612
+
1613
+ // Resolve the promise with the data
1614
+ resolve(data.data);
1615
+ });
1616
+
1617
+ game.socket.emit("system.${id}", {
1618
+ uuid: uuid,
1619
+ type: "prompt",
1620
+ userId: game.user.id,
1621
+ ${widthParam ? `width: ${widthParam.value},` : ""}
1622
+ ${heightParam ? `height: ${heightParam.value},` : ""}
1623
+ ${locationParam ? expandToNode `left: ${translateExpression(entry, id, locationParam.x, false, generatingProperty)},
1624
+ top: ${translateExpression(entry, id, locationParam.y, false, generatingProperty)},` : ""}
1625
+ ${timeLimitParam ? expandToNode `timeLimit: ${durationExpression},` : ""}
1626
+ title: "${title}",
1627
+ promptKey: "${promptKey}",
1628
+ documentUuid: context.object.uuid,
1629
+ }, {recipients: [ownerId]});
1630
+ });
1592
1631
  `;
1593
1632
  }
1594
1633
  if (target == "user") {
1595
- return expandToNode `
1596
- await new Promise(async (resolve, reject) => {
1597
-
1598
- const allActiveUsers = game.users.filter(u => u.active && u.id != game.user.id);
1599
- const targetedUser = await Dialog.prompt({
1600
- title: "Select User",
1601
- content: \`<form>
1602
- <div class="form-group">
1603
- <label>\${game.i18n.localize("User")}</label>
1604
- <select name="user">
1605
- \${allActiveUsers.map(u => \`<option value="\${u.id}">\${u.name}</option>\`).join("")}
1606
- </select>
1607
- </div>
1608
- </form>\`,
1609
- callback: (html, event) => {
1610
- const formData = new FormDataExtended(html[0].querySelector("form"));
1611
- return formData.get("user");
1612
- },
1613
- options: {
1614
- classes: ["${id}", "dialog"],
1615
- }
1616
- });
1617
- const uuid = foundry.utils.randomID();
1618
-
1619
- // Setup a listener that will wait for this response
1620
- game.socket.on("system.${id}", (data) => {
1621
- if (data.type != "promptResponse" || data.uuid != uuid) return;
1622
-
1623
- // Resolve the promise with the data
1624
- resolve(data.data);
1625
- });
1626
-
1627
- game.socket.emit("system.${id}", {
1628
- uuid: uuid,
1629
- type: "prompt",
1630
- userId: game.user.id,
1631
- title: "${title}",
1632
- promptKey: "${promptKey}",
1633
- documentUuid: context.object.uuid,
1634
- ${widthParam ? expandToNode `width: ${widthParam.value},` : ""}
1635
- ${heightParam ? expandToNode `height: ${heightParam.value},` : ""}
1636
- ${locationParam ? expandToNode `left: ${translateExpression(entry, id, locationParam.x, false, generatingProperty)},
1637
- top: ${translateExpression(entry, id, locationParam.y, false, generatingProperty)},` : ""}
1638
- ${timeLimitParam ? expandToNode `timeLimit: ${durationExpression},` : ""}
1639
- }, {recipients: [targetedUser]});
1640
- });
1634
+ return expandToNode `
1635
+ await new Promise(async (resolve, reject) => {
1636
+
1637
+ const allActiveUsers = game.users.filter(u => u.active && u.id != game.user.id);
1638
+ const targetedUser = await Dialog.prompt({
1639
+ title: "Select User",
1640
+ content: \`<form>
1641
+ <div class="form-group">
1642
+ <label>\${game.i18n.localize("User")}</label>
1643
+ <select name="user">
1644
+ \${allActiveUsers.map(u => \`<option value="\${u.id}">\${u.name}</option>\`).join("")}
1645
+ </select>
1646
+ </div>
1647
+ </form>\`,
1648
+ callback: (html, event) => {
1649
+ const formData = new FormDataExtended(html[0].querySelector("form"));
1650
+ return formData.get("user");
1651
+ },
1652
+ options: {
1653
+ classes: ["${id}", "dialog"],
1654
+ }
1655
+ });
1656
+ const uuid = foundry.utils.randomID();
1657
+
1658
+ // Setup a listener that will wait for this response
1659
+ game.socket.on("system.${id}", (data) => {
1660
+ if (data.type != "promptResponse" || data.uuid != uuid) return;
1661
+
1662
+ // Resolve the promise with the data
1663
+ resolve(data.data);
1664
+ });
1665
+
1666
+ game.socket.emit("system.${id}", {
1667
+ uuid: uuid,
1668
+ type: "prompt",
1669
+ userId: game.user.id,
1670
+ title: "${title}",
1671
+ promptKey: "${promptKey}",
1672
+ documentUuid: context.object.uuid,
1673
+ ${widthParam ? expandToNode `width: ${widthParam.value},` : ""}
1674
+ ${heightParam ? expandToNode `height: ${heightParam.value},` : ""}
1675
+ ${locationParam ? expandToNode `left: ${translateExpression(entry, id, locationParam.x, false, generatingProperty)},
1676
+ top: ${translateExpression(entry, id, locationParam.y, false, generatingProperty)},` : ""}
1677
+ ${timeLimitParam ? expandToNode `timeLimit: ${durationExpression},` : ""}
1678
+ }, {recipients: [targetedUser]});
1679
+ });
1641
1680
  `;
1642
1681
  }
1643
1682
  // Self-target: open the generated Vue prompt app (game.system.prompts.<doc><action>).
1644
1683
  // The app resolves this promise with the user's input (or {} on cancel/close).
1645
- return expandToNode `
1646
- await new Promise(async (resolve, reject) => {
1647
- const promptApp = new game.system.prompts.${promptKey}(context.object, { promptResolve: resolve });
1648
- promptApp.render(true);
1649
- });
1684
+ return expandToNode `
1685
+ await new Promise(async (resolve, reject) => {
1686
+ const promptApp = new game.system.prompts.${promptKey}(context.object, { promptResolve: resolve });
1687
+ promptApp.render(true);
1688
+ });
1650
1689
  `;
1651
1690
  }
1652
1691
  if (isMathExpression(expression)) {
1653
1692
  expression = expression;
1654
1693
  console.log("Translating Math Expression: ", expression.operation);
1655
1694
  if (isMathEmptyExpression(expression)) {
1656
- return expandToNode `
1657
- Math.${expression.operation}()
1695
+ return expandToNode `
1696
+ Math.${expression.operation}()
1658
1697
  `;
1659
1698
  }
1660
1699
  if (isMathSingleExpression(expression)) {
1661
- return expandToNode `
1662
- Math.${expression.operation}(${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)})
1700
+ return expandToNode `
1701
+ Math.${expression.operation}(${translateExpression(entry, id, expression.exp, preDerived, generatingProperty)})
1663
1702
  `;
1664
1703
  }
1665
1704
  if (isMathParamExpression(expression)) {
1666
- return expandToNode `
1667
- Math.${expression.operation}(${joinToNode(expression.params, x => translateExpression(entry, id, x, preDerived, generatingProperty), { separator: ", " })})
1705
+ return expandToNode `
1706
+ Math.${expression.operation}(${joinToNode(expression.params, x => translateExpression(entry, id, x, preDerived, generatingProperty), { separator: ", " })})
1668
1707
  `;
1669
1708
  }
1670
1709
  throw new Error("Unknown Math Expression type encountered while translating to JavaScript ");
1671
1710
  }
1672
1711
  if (isLogExpression(expression)) {
1673
1712
  console.log("Translating Log Expression: ");
1674
- return expandToNode `
1675
- console.log(${joinToNode(expression.params, x => translateExpression(entry, id, x, preDerived, generatingProperty), { separator: ", " })})
1713
+ return expandToNode `
1714
+ console.log(${joinToNode(expression.params, x => translateExpression(entry, id, x, preDerived, generatingProperty), { separator: ", " })})
1676
1715
  `;
1677
1716
  }
1678
1717
  if (isUpdate(expression)) {
1679
1718
  console.log("Translating Update Expression:");
1680
- let systemPath = getSystemPath((_y = expression.property) === null || _y === void 0 ? void 0 : _y.ref, expression.subProperties, (_z = expression.propertyLookup) === null || _z === void 0 ? void 0 : _z.ref, false);
1719
+ let systemPath = getSystemPath((_1 = expression.property) === null || _1 === void 0 ? void 0 : _1.ref, expression.subProperties, (_2 = expression.propertyLookup) === null || _2 === void 0 ? void 0 : _2.ref, false);
1681
1720
  if (isUpdateParent(expression)) {
1682
- return expandToNode `
1683
- parentUpdate["${systemPath}"] = foundry.utils.getProperty(context.object.parent, "system.${systemPath}");
1721
+ return expandToNode `
1722
+ parentUpdate["${systemPath}"] = foundry.utils.getProperty(context.object.parent, "system.${systemPath}");
1684
1723
  `;
1685
1724
  }
1686
1725
  else if (isUpdateSelf(expression)) {
1687
- return expandToNode `
1688
- update["system.${systemPath}"] = system.${systemPath};
1726
+ return expandToNode `
1727
+ update["system.${systemPath}"] = system.${systemPath};
1689
1728
  `;
1690
1729
  }
1691
1730
  }
1692
1731
  if (isVisibilityValue(expression)) {
1693
1732
  console.log("Translating Visibility Value Expression: ", expression.visibility);
1694
- return expandToNode `
1695
- "${expression.visibility}"
1733
+ return expandToNode `
1734
+ "${expression.visibility}"
1696
1735
  `;
1697
1736
  }
1698
1737
  if (isFunctionCall(expression)) {
@@ -1706,16 +1745,16 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1706
1745
  // closures in the _prepare<Doc>DerivedData scope (see derived-data-generator). They take the
1707
1746
  // in-scope `system` and no update/await — derived values run synchronously and must be pure.
1708
1747
  if (preDerived) {
1709
- return expandToNode `
1710
- function_${(_0 = expression.method.ref) === null || _0 === void 0 ? void 0 : _0.name}(system${expression.params.length ? ", " : ""}${args})
1748
+ return expandToNode `
1749
+ function_${(_3 = expression.method.ref) === null || _3 === void 0 ? void 0 : _3.name}(system${expression.params.length ? ", " : ""}${args})
1711
1750
  `;
1712
1751
  }
1713
1752
  let accessPath = "this";
1714
1753
  if (isTrackerExp(generatingProperty)) {
1715
1754
  accessPath = "document.sheet";
1716
1755
  }
1717
- return expandToNode `
1718
- await ${accessPath}.function_${(_1 = expression.method.ref) === null || _1 === void 0 ? void 0 : _1.name}(context, update, embeddedUpdate, parentUpdate, parentEmbeddedUpdate, targetUpdate, targetEmbeddedUpdate, ${args})
1756
+ return expandToNode `
1757
+ await ${accessPath}.function_${(_4 = expression.method.ref) === null || _4 === void 0 ? void 0 : _4.name}(context, update, embeddedUpdate, parentUpdate, parentEmbeddedUpdate, targetUpdate, targetEmbeddedUpdate, ${args})
1719
1758
  `;
1720
1759
  }
1721
1760
  if (isNumberRange(expression)) {
@@ -1723,8 +1762,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1723
1762
  const to = translateExpression(entry, id, expression.end, preDerived, generatingProperty);
1724
1763
  console.log("Translating Number Range Expression: ", from, to);
1725
1764
  // Make a JS array of numbers from from to to
1726
- return expandToNode `
1727
- Array.from({length: ${to} - ${from} + 1}, (_, i) => ${from} + i)
1765
+ return expandToNode `
1766
+ Array.from({length: ${to} - ${from} + 1}, (_, i) => ${from} + i)
1728
1767
  `;
1729
1768
  }
1730
1769
  if (isWait(expression)) {
@@ -1738,8 +1777,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1738
1777
  else if (units === "minutes") {
1739
1778
  durationMod = ` * 60 * 1000`;
1740
1779
  }
1741
- return expandToNode `
1742
- await new Promise(resolve => setTimeout(resolve, ${duration}${durationMod})); // Wait for ${expression.duration} ${units}
1780
+ return expandToNode `
1781
+ await new Promise(resolve => setTimeout(resolve, ${duration}${durationMod})); // Wait for ${expression.duration} ${units}
1743
1782
  `;
1744
1783
  }
1745
1784
  if (isPlayAudio(expression)) {
@@ -1747,45 +1786,45 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1747
1786
  if (!fileParam)
1748
1787
  return undefined;
1749
1788
  const volumeParam = expression.params.find(x => isPlayAudioVolume(x));
1750
- const volume = (_2 = volumeParam === null || volumeParam === void 0 ? void 0 : volumeParam.value) !== null && _2 !== void 0 ? _2 : 0.5;
1751
- return expandToNode `
1752
- await game.system.utils.playSfx(${translateExpression(entry, id, fileParam.value, false, generatingProperty)}, ${translateExpression(entry, id, volume, false, generatingProperty)});
1789
+ const volume = (_5 = volumeParam === null || volumeParam === void 0 ? void 0 : volumeParam.value) !== null && _5 !== void 0 ? _5 : 0.5;
1790
+ return expandToNode `
1791
+ await game.system.utils.playSfx(${translateExpression(entry, id, fileParam.value, false, generatingProperty)}, ${translateExpression(entry, id, volume, false, generatingProperty)});
1753
1792
  `;
1754
1793
  }
1755
1794
  if (isCombatMethods(expression)) {
1756
1795
  const method = expression.method;
1757
- return expandToNode `
1758
- if (!game.combat) {
1759
- return;
1760
- }
1761
- if (game.combat.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) {
1762
- ${method == "nextTurn" ? expandToNode `game.combat.nextTurn();` : ""}
1763
- ${method == "end" ? expandToNode `game.combat.endCombat();` : ""}
1764
- }
1765
- else {
1766
- await new Promise((resolve, reject) => {
1767
- const firstGm = game.users.find(u => u.isGM && u.active);
1768
- if (!firstGm) {
1769
- ui.notifications.error("No active GM found to handle combat method request");
1770
- return;
1771
- }
1772
- const uuid = foundry.utils.randomID();
1773
-
1774
- // Setup a listener that will wait for this response
1775
- game.socket.on("system.${id}", (data) => {
1776
- if (data.type != "combatResponse" || data.uuid != uuid) return;
1777
-
1778
- resolve();
1779
- });
1780
-
1781
- game.socket.emit("system.${id}", {
1782
- uuid: uuid,
1783
- type: "combat",
1784
- userId: game.user.id,
1785
- method: "${method}",
1786
- }, {recipients: [firstGm.id]});
1787
- });
1788
- }
1796
+ return expandToNode `
1797
+ if (!game.combat) {
1798
+ return;
1799
+ }
1800
+ if (game.combat.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) {
1801
+ ${method == "nextTurn" ? expandToNode `game.combat.nextTurn();` : ""}
1802
+ ${method == "end" ? expandToNode `game.combat.endCombat();` : ""}
1803
+ }
1804
+ else {
1805
+ await new Promise((resolve, reject) => {
1806
+ const firstGm = game.users.find(u => u.isGM && u.active);
1807
+ if (!firstGm) {
1808
+ ui.notifications.error("No active GM found to handle combat method request");
1809
+ return;
1810
+ }
1811
+ const uuid = foundry.utils.randomID();
1812
+
1813
+ // Setup a listener that will wait for this response
1814
+ game.socket.on("system.${id}", (data) => {
1815
+ if (data.type != "combatResponse" || data.uuid != uuid) return;
1816
+
1817
+ resolve();
1818
+ });
1819
+
1820
+ game.socket.emit("system.${id}", {
1821
+ uuid: uuid,
1822
+ type: "combat",
1823
+ userId: game.user.id,
1824
+ method: "${method}",
1825
+ }, {recipients: [firstGm.id]});
1826
+ });
1827
+ }
1789
1828
  `;
1790
1829
  }
1791
1830
  if (isCombatProperty(expression)) {
@@ -1808,8 +1847,8 @@ export function translateExpression(entry, id, expression, preDerived = false, g
1808
1847
  }
1809
1848
  if (isMacroExecute(expression)) {
1810
1849
  const systemPath = getSystemPath(expression.macro.ref, [], undefined, false);
1811
- return expandToNode `
1812
- await context.object.${systemPath}?.execute();
1850
+ return expandToNode `
1851
+ await context.object.${systemPath}?.execute();
1813
1852
  `;
1814
1853
  }
1815
1854
  console.log(expression.$type);