@neocompose/cli 0.72.4 → 0.73.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/neo.mjs CHANGED
@@ -872,7 +872,42 @@ function generatedCSharpTypeName(value, fallback) {
872
872
  const safe = /^[0-9]/.test(candidate) ? `_${candidate}` : candidate;
873
873
  return isGeneratedCSharpReservedKeyword(safe) ? `${safe}Type` : safe;
874
874
  }
875
- var GENERATED_CSHARP_RESERVED_KEYWORDS, GENERATED_CSHARP_IDENTIFIER_REGEX;
875
+ function generatedCSharpShortId(id2) {
876
+ return id2.replace(/[^A-Za-z0-9_]/g, "").slice(0, 8) || "Id";
877
+ }
878
+ function dialogueGroupReservedNameError(name) {
879
+ const propertyName = generatedCSharpTypeName(name, "DialogueGroup");
880
+ if (!DIALOGUE_GROUP_RESERVED_NAMES.has(propertyName)) return void 0;
881
+ return `Dialogue group name "${name}" is reserved because ${propertyName} is a Dialogues member.`;
882
+ }
883
+ function dialogueGroupPropertyNames(groups, onCollision) {
884
+ const ordered = [...groups].sort(compareGroupIds);
885
+ const used = /* @__PURE__ */ new Set();
886
+ const names = /* @__PURE__ */ new Map();
887
+ for (const group of ordered) {
888
+ const propertyName = generatedCSharpTypeName(group.name, "DialogueGroup");
889
+ if (!used.has(propertyName)) {
890
+ used.add(propertyName);
891
+ names.set(group.id, propertyName);
892
+ continue;
893
+ }
894
+ const uniqueName = `${propertyName}_${generatedCSharpShortId(group.id)}`;
895
+ onCollision?.({
896
+ groupId: group.id,
897
+ groupName: group.name,
898
+ propertyName,
899
+ uniqueName
900
+ });
901
+ names.set(group.id, uniqueName);
902
+ }
903
+ return names;
904
+ }
905
+ function compareGroupIds(left, right) {
906
+ if (left.id < right.id) return -1;
907
+ if (left.id > right.id) return 1;
908
+ return 0;
909
+ }
910
+ var GENERATED_CSHARP_RESERVED_KEYWORDS, GENERATED_CSHARP_IDENTIFIER_REGEX, DIALOGUE_GROUP_RESERVED_NAMES;
876
911
  var init_generated_csharp_identifiers = __esm({
877
912
  "../packages/neoscript-language/src/generated-csharp-identifiers.ts"() {
878
913
  "use strict";
@@ -956,6 +991,240 @@ var init_generated_csharp_identifiers = __esm({
956
991
  "while"
957
992
  ]);
958
993
  GENERATED_CSHARP_IDENTIFIER_REGEX = /^[_A-Za-z][_A-Za-z0-9]*$/;
994
+ DIALOGUE_GROUP_RESERVED_NAMES = /* @__PURE__ */ new Set([
995
+ "TryTrigger",
996
+ "CanTrigger",
997
+ "VisitCount",
998
+ "HasVisited",
999
+ "OnTrigger",
1000
+ "OnEligible",
1001
+ "OnEligibleError"
1002
+ ]);
1003
+ }
1004
+ });
1005
+
1006
+ // ../packages/neoscript-language/src/dialogue-types.ts
1007
+ function renamedDialogueTypeMessage(name, position) {
1008
+ const replacement = RENAMED_DIALOGUE_TYPES.get(name)?.[position];
1009
+ if (replacement === void 0) return void 0;
1010
+ return `\`${name}\` was renamed to \`${replacement}\`.`;
1011
+ }
1012
+ function method(ownerId, name, returnType, parameters, documentation) {
1013
+ return {
1014
+ id: `${ownerId}:${name}`,
1015
+ name,
1016
+ kind: "method",
1017
+ type: returnType,
1018
+ returnType,
1019
+ parameters,
1020
+ documentation
1021
+ };
1022
+ }
1023
+ function neoScriptDialogueReferenceMethods(ownerId) {
1024
+ return [
1025
+ method(
1026
+ ownerId,
1027
+ "TryTrigger",
1028
+ BOOL_TYPE,
1029
+ [ON_FINISH_PARAMETER],
1030
+ "Triggers the referenced dialogue. Returns true when it started or was queued."
1031
+ ),
1032
+ method(
1033
+ ownerId,
1034
+ "CanTrigger",
1035
+ BOOL_TYPE,
1036
+ [],
1037
+ "Checks whether the referenced dialogue's conditions are met, without triggering it."
1038
+ )
1039
+ ];
1040
+ }
1041
+ function rootMethods() {
1042
+ const dialogueId = {
1043
+ name: "dialogueId",
1044
+ type: STRING_TYPE
1045
+ };
1046
+ const pointer = { name: "pointer", type: STRING_TYPE };
1047
+ return [
1048
+ method(
1049
+ NEOSCRIPT_DIALOGUES_TYPE_ID,
1050
+ "TryTrigger",
1051
+ BOOL_TYPE,
1052
+ [dialogueId, ON_FINISH_PARAMETER],
1053
+ "Triggers a direct dialogue. Returns true when it started or was queued."
1054
+ ),
1055
+ method(
1056
+ NEOSCRIPT_DIALOGUES_TYPE_ID,
1057
+ "CanTrigger",
1058
+ BOOL_TYPE,
1059
+ [dialogueId],
1060
+ "Checks whether a direct dialogue's conditions are met, without triggering it."
1061
+ ),
1062
+ method(
1063
+ NEOSCRIPT_DIALOGUES_TYPE_ID,
1064
+ "VisitCount",
1065
+ INT_TYPE,
1066
+ [pointer],
1067
+ "Returns how many times a dialogue or text node was visited."
1068
+ ),
1069
+ method(
1070
+ NEOSCRIPT_DIALOGUES_TYPE_ID,
1071
+ "HasVisited",
1072
+ BOOL_TYPE,
1073
+ [pointer],
1074
+ "Returns whether a dialogue or text node was visited."
1075
+ )
1076
+ ];
1077
+ }
1078
+ function groupMethods(typeId, receiver) {
1079
+ if (receiver.kind === "standard") {
1080
+ return [
1081
+ method(
1082
+ typeId,
1083
+ "TryTrigger",
1084
+ BOOL_TYPE,
1085
+ [ON_FINISH_PARAMETER],
1086
+ "Triggers this group's highest-priority eligible dialogue. Returns true when it started or was queued."
1087
+ ),
1088
+ method(
1089
+ typeId,
1090
+ "CanTrigger",
1091
+ BOOL_TYPE,
1092
+ [],
1093
+ "Checks whether this group has an eligible dialogue, without triggering it."
1094
+ )
1095
+ ];
1096
+ }
1097
+ if (receiver.kind !== "lookup" || receiver.entryType === void 0) return [];
1098
+ const value = {
1099
+ name: "value",
1100
+ type: receiver.entryType
1101
+ };
1102
+ return [
1103
+ method(
1104
+ typeId,
1105
+ "TryTrigger",
1106
+ BOOL_TYPE,
1107
+ [value, ON_FINISH_PARAMETER],
1108
+ "Triggers the highest-priority eligible dialogue for the lookup value. Returns true when it started or was queued."
1109
+ ),
1110
+ method(
1111
+ typeId,
1112
+ "CanTrigger",
1113
+ BOOL_TYPE,
1114
+ [value],
1115
+ "Checks whether the lookup value has an eligible dialogue, without triggering it."
1116
+ )
1117
+ ];
1118
+ }
1119
+ function neoScriptDialogueTypes(groups) {
1120
+ const names = dialogueGroupPropertyNames(groups);
1121
+ const children = /* @__PURE__ */ new Map();
1122
+ for (const group of groups) {
1123
+ const siblings = children.get(group.parentId);
1124
+ if (siblings === void 0) children.set(group.parentId, [group]);
1125
+ else siblings.push(group);
1126
+ }
1127
+ const rootPath = `root.${NEOSCRIPT_DIALOGUES_MEMBER_NAME}`;
1128
+ const types = [];
1129
+ const typeFor = (parentId, path) => {
1130
+ const members = [];
1131
+ for (const group of children.get(parentId) ?? []) {
1132
+ const name = names.get(group.id);
1133
+ const groupPath = `${path}.${name}`;
1134
+ const typeId = `${NEOSCRIPT_DIALOGUES_TYPE_ID}:${group.id}`;
1135
+ const receiver = {
1136
+ kind: group.kind,
1137
+ path: groupPath,
1138
+ groupId: group.id,
1139
+ ...group.lookup ? { entryType: group.lookup.entryType } : {}
1140
+ };
1141
+ const lookup = group.lookup ? ` Looks up ${group.lookup.entryTypeName} in \`${group.lookup.collection}\`.` : "";
1142
+ const documentation = `${KIND_LABELS[group.kind]} \`${groupPath}\`.${lookup}`;
1143
+ types.push({
1144
+ id: typeId,
1145
+ name: groupPath,
1146
+ kind: "synthetic",
1147
+ documentation,
1148
+ dialogues: receiver,
1149
+ members: [
1150
+ ...typeFor(group.id, groupPath),
1151
+ ...groupMethods(typeId, receiver)
1152
+ ]
1153
+ });
1154
+ members.push({
1155
+ id: `${typeId}:member`,
1156
+ name,
1157
+ kind: "property",
1158
+ type: { kind: "named", typeId },
1159
+ documentation,
1160
+ detail: KIND_LABELS[group.kind],
1161
+ writable: false,
1162
+ writability: "readOnly",
1163
+ ...group.location ? { location: group.location } : {},
1164
+ ...group.selectionLocation ? { selectionLocation: group.selectionLocation } : {}
1165
+ });
1166
+ }
1167
+ return members;
1168
+ };
1169
+ const topLevel = typeFor(null, rootPath);
1170
+ types.push({
1171
+ id: NEOSCRIPT_DIALOGUES_TYPE_ID,
1172
+ name: rootPath,
1173
+ kind: "synthetic",
1174
+ documentation: "The project's dialogues and dialogue groups, the same paths as the generated C# Dialogues.",
1175
+ dialogues: { kind: "root", path: rootPath },
1176
+ members: [...topLevel, ...rootMethods()]
1177
+ });
1178
+ return {
1179
+ member: {
1180
+ id: `${NEOSCRIPT_DIALOGUES_TYPE_ID}:member`,
1181
+ name: NEOSCRIPT_DIALOGUES_MEMBER_NAME,
1182
+ kind: "property",
1183
+ type: { kind: "named", typeId: NEOSCRIPT_DIALOGUES_TYPE_ID },
1184
+ documentation: "The project's dialogues. Trigger them, check them, and read dialogue memory.",
1185
+ writable: false,
1186
+ writability: "readOnly"
1187
+ },
1188
+ types
1189
+ };
1190
+ }
1191
+ var NEOSCRIPT_DIALOGUES_MEMBER_NAME, NEOSCRIPT_DIALOGUES_TYPE_ID, RENAMED_DIALOGUE_TYPES, BOOL_TYPE, INT_TYPE, STRING_TYPE, NEOSCRIPT_DIALOGUE_ON_FINISH_TYPE, ON_FINISH_PARAMETER, KIND_LABELS;
1192
+ var init_dialogue_types = __esm({
1193
+ "../packages/neoscript-language/src/dialogue-types.ts"() {
1194
+ "use strict";
1195
+ init_generated_csharp_identifiers();
1196
+ NEOSCRIPT_DIALOGUES_MEMBER_NAME = "Dialogues";
1197
+ NEOSCRIPT_DIALOGUES_TYPE_ID = "builtin:Dialogues";
1198
+ RENAMED_DIALOGUE_TYPES = /* @__PURE__ */ new Map([
1199
+ ["Dialogue", { base: "NeoDialogue", value: "NeoDialogueReference" }],
1200
+ [
1201
+ "DialogueRef",
1202
+ { base: "NeoDialogueReference", value: "NeoDialogueReference" }
1203
+ ],
1204
+ ["DialogueGroup", { base: "NeoDialogueGroup", value: "NeoDialogueGroup" }],
1205
+ ["PriorityGroup", { base: "NeoPriorityGroup", value: "NeoPriorityGroup" }],
1206
+ ["PriorityOption", { base: "NeoPriorityOption", value: "NeoPriorityOption" }]
1207
+ ]);
1208
+ BOOL_TYPE = { kind: "primitive", name: "bool" };
1209
+ INT_TYPE = { kind: "primitive", name: "int" };
1210
+ STRING_TYPE = { kind: "primitive", name: "string" };
1211
+ NEOSCRIPT_DIALOGUE_ON_FINISH_TYPE = {
1212
+ kind: "delegate",
1213
+ returnType: { kind: "primitive", name: "void" },
1214
+ parameterTypes: [],
1215
+ nullable: true
1216
+ };
1217
+ ON_FINISH_PARAMETER = {
1218
+ name: "onFinish",
1219
+ type: NEOSCRIPT_DIALOGUE_ON_FINISH_TYPE,
1220
+ defaultValue: { displayText: "null", value: null },
1221
+ documentation: "Runs once the dialogue ends, whether it finished, failed, or was disposed."
1222
+ };
1223
+ KIND_LABELS = {
1224
+ standard: "Dialogue group",
1225
+ lookup: "Lookup dialogue group",
1226
+ folder: "Dialogue folder"
1227
+ };
959
1228
  }
960
1229
  });
961
1230
 
@@ -1073,10 +1342,11 @@ function vectorTypes() {
1073
1342
  members: structuredLeafFieldProperties(name)
1074
1343
  }));
1075
1344
  }
1076
- var NEO_PROJECT_IGNORED_DIRECTORY_NAMES, NEOSCRIPT_KEYWORDS, NEOSCRIPT_INFERRED_LOCAL_KEYWORD, NEOSCRIPT_CONSTRUCTOR_KEYWORD, NEOSCRIPT_PRIMITIVE_TYPES, NEOSCRIPT_BUILTIN_ANNOTATION_TYPES, NEOSCRIPT_BUILTIN_NAMESPACES, NEOSCRIPT_BUILTIN_TYPES, NEO_VARIANT_TYPE_NAME, NEO_VARIANT_FOLDER_TYPE_NAME, NEO_LOOKUP_VARIANT_TYPE_NAME, NEO_LOOKUP_VARIANT_FOLDER_TYPE_NAME, NEO_VARIANT_SCOPE_NAME, NEO_VARIANT_RESERVED_NAME, NEO_VARIANT_FOLDER_PATH_SEPARATOR, NEOSCRIPT_OPERATORS, STRING_TYPE, INT_TYPE, FLOAT_TYPE, BOOL_TYPE, IMAGE_REF_TYPE, SPRITE_INFO_TYPE, FLOAT_OPTIONAL_TYPE, NEOSCRIPT_STRUCTURED_LEAF_FIELDS, NEOSCRIPT_IMAGE_REGISTRY_TYPE, NEOSCRIPT_AUDIO_CLIP_REGISTRY_TYPE, NEOSCRIPT_PENDING_SYMBOL_ID_PREFIX, REGISTRY_ENTRY_TYPES, NEOSCRIPT_GLOBALS, NEOSCRIPT_SPRITE_INFO_EMPTY_MEMBER_ID, NEOSCRIPT_SPRITE_INFO_EMPTY_VALUE, NEOSCRIPT_MATH_TYPE_ID, MATH_INFERENCE_RULE, MATH_INTEGRAL_RULE, NEOSCRIPT_LIST_TYPE_NAME, NEOSCRIPT_LIST_TYPE_ID, NEOSCRIPT_LIST_REPEAT_NAME, LIST_ENTRY_TYPE, NEOSCRIPT_BUILTIN_TYPE_SYMBOLS;
1345
+ var NEO_PROJECT_IGNORED_DIRECTORY_NAMES, NEOSCRIPT_KEYWORDS, NEOSCRIPT_INFERRED_LOCAL_KEYWORD, NEOSCRIPT_CONSTRUCTOR_KEYWORD, NEOSCRIPT_PRIMITIVE_TYPES, NEOSCRIPT_BUILTIN_ANNOTATION_TYPES, NEOSCRIPT_BUILTIN_NAMESPACES, NEOSCRIPT_BUILTIN_TYPES, NEO_VARIANT_TYPE_NAME, NEO_VARIANT_FOLDER_TYPE_NAME, NEO_LOOKUP_VARIANT_TYPE_NAME, NEO_LOOKUP_VARIANT_FOLDER_TYPE_NAME, NEO_VARIANT_SCOPE_NAME, NEO_VARIANT_RESERVED_NAME, NEO_VARIANT_FOLDER_PATH_SEPARATOR, NEOSCRIPT_OPERATORS, STRING_TYPE2, INT_TYPE2, FLOAT_TYPE, BOOL_TYPE2, IMAGE_REF_TYPE, SPRITE_INFO_TYPE, FLOAT_OPTIONAL_TYPE, NEOSCRIPT_STRUCTURED_LEAF_FIELDS, NEOSCRIPT_IMAGE_REGISTRY_TYPE, NEOSCRIPT_AUDIO_CLIP_REGISTRY_TYPE, NEOSCRIPT_PENDING_SYMBOL_ID_PREFIX, REGISTRY_ENTRY_TYPES, NEOSCRIPT_GLOBALS, NEOSCRIPT_SPRITE_INFO_EMPTY_MEMBER_ID, NEOSCRIPT_SPRITE_INFO_EMPTY_VALUE, NEOSCRIPT_MATH_TYPE_ID, MATH_INFERENCE_RULE, MATH_INTEGRAL_RULE, NEOSCRIPT_LIST_TYPE_NAME, NEOSCRIPT_LIST_TYPE_ID, NEOSCRIPT_LIST_REPEAT_NAME, LIST_ENTRY_TYPE, NEOSCRIPT_BUILTIN_TYPE_SYMBOLS;
1077
1346
  var init_language_spec = __esm({
1078
1347
  "../packages/neoscript-language/src/language-spec.ts"() {
1079
1348
  "use strict";
1349
+ init_dialogue_types();
1080
1350
  NEO_PROJECT_IGNORED_DIRECTORY_NAMES = /* @__PURE__ */ new Set(
1081
1351
  [
1082
1352
  ".git",
@@ -1147,7 +1417,7 @@ var init_language_spec = __esm({
1147
1417
  "FunctionRef",
1148
1418
  "NeoDelegate",
1149
1419
  "NeoAction",
1150
- "Dialogue",
1420
+ "NeoDialogue",
1151
1421
  "Trigger",
1152
1422
  "Node",
1153
1423
  "Text",
@@ -1157,7 +1427,7 @@ var init_language_spec = __esm({
1157
1427
  "Outcome",
1158
1428
  "SpriteInfo",
1159
1429
  "AudioClipInfo",
1160
- "DialogueRef",
1430
+ "NeoDialogueReference",
1161
1431
  "Vector2",
1162
1432
  "Vector2Int",
1163
1433
  "Vector3",
@@ -1206,10 +1476,10 @@ var init_language_spec = __esm({
1206
1476
  "<",
1207
1477
  ">"
1208
1478
  ];
1209
- STRING_TYPE = { kind: "primitive", name: "string" };
1210
- INT_TYPE = { kind: "primitive", name: "int" };
1479
+ STRING_TYPE2 = { kind: "primitive", name: "string" };
1480
+ INT_TYPE2 = { kind: "primitive", name: "int" };
1211
1481
  FLOAT_TYPE = { kind: "primitive", name: "float" };
1212
- BOOL_TYPE = { kind: "primitive", name: "bool" };
1482
+ BOOL_TYPE2 = { kind: "primitive", name: "bool" };
1213
1483
  IMAGE_REF_TYPE = {
1214
1484
  kind: "primitive",
1215
1485
  name: "ImageRef"
@@ -1234,7 +1504,7 @@ var init_language_spec = __esm({
1234
1504
  {
1235
1505
  name: "SliceIndex",
1236
1506
  key: "sliceIndex",
1237
- type: INT_TYPE,
1507
+ type: INT_TYPE2,
1238
1508
  documentation: "Index into the file's slices."
1239
1509
  }
1240
1510
  ],
@@ -1256,13 +1526,13 @@ var init_language_spec = __esm({
1256
1526
  {
1257
1527
  name: "x",
1258
1528
  key: "x",
1259
- type: INT_TYPE,
1529
+ type: INT_TYPE2,
1260
1530
  documentation: "Vector2Int x component."
1261
1531
  },
1262
1532
  {
1263
1533
  name: "y",
1264
1534
  key: "y",
1265
- type: INT_TYPE,
1535
+ type: INT_TYPE2,
1266
1536
  documentation: "Vector2Int y component."
1267
1537
  }
1268
1538
  ],
@@ -1290,19 +1560,19 @@ var init_language_spec = __esm({
1290
1560
  {
1291
1561
  name: "x",
1292
1562
  key: "x",
1293
- type: INT_TYPE,
1563
+ type: INT_TYPE2,
1294
1564
  documentation: "Vector3Int x component."
1295
1565
  },
1296
1566
  {
1297
1567
  name: "y",
1298
1568
  key: "y",
1299
- type: INT_TYPE,
1569
+ type: INT_TYPE2,
1300
1570
  documentation: "Vector3Int y component."
1301
1571
  },
1302
1572
  {
1303
1573
  name: "z",
1304
1574
  key: "z",
1305
- type: INT_TYPE,
1575
+ type: INT_TYPE2,
1306
1576
  documentation: "Vector3Int z component."
1307
1577
  }
1308
1578
  ],
@@ -1349,14 +1619,14 @@ var init_language_spec = __esm({
1349
1619
  NEOSCRIPT_GLOBALS = [
1350
1620
  builtinFunction(
1351
1621
  "VisitCount",
1352
- INT_TYPE,
1353
- [parameter("pointer", STRING_TYPE)],
1622
+ INT_TYPE2,
1623
+ [parameter("pointer", STRING_TYPE2)],
1354
1624
  "Returns the number of visits recorded for a dialogue pointer."
1355
1625
  ),
1356
1626
  builtinFunction(
1357
1627
  "HasVisited",
1358
- BOOL_TYPE,
1359
- [parameter("pointer", STRING_TYPE)],
1628
+ BOOL_TYPE2,
1629
+ [parameter("pointer", STRING_TYPE2)],
1360
1630
  "Returns whether a dialogue pointer has been visited."
1361
1631
  )
1362
1632
  ];
@@ -1395,8 +1665,8 @@ var init_language_spec = __esm({
1395
1665
  // `FileId` and `SliceIndex` come from the field table above — they are
1396
1666
  // the writable, addressable fields, not derived properties (D11).
1397
1667
  ...structuredLeafFieldProperties("SpriteInfo"),
1398
- property("SpriteInfo", "FileName", STRING_TYPE, "Asset file name."),
1399
- property("SpriteInfo", "Name", STRING_TYPE, "Sprite name."),
1668
+ property("SpriteInfo", "FileName", STRING_TYPE2, "Asset file name."),
1669
+ property("SpriteInfo", "Name", STRING_TYPE2, "Sprite name."),
1400
1670
  property(
1401
1671
  "SpriteInfo",
1402
1672
  "Size",
@@ -1426,8 +1696,8 @@ var init_language_spec = __esm({
1426
1696
  name: "AudioClipInfo",
1427
1697
  kind: "builtin",
1428
1698
  members: [
1429
- property("AudioClipInfo", "FileId", STRING_TYPE, "Asset file id."),
1430
- property("AudioClipInfo", "Name", STRING_TYPE, "Audio clip name."),
1699
+ property("AudioClipInfo", "FileId", STRING_TYPE2, "Asset file id."),
1700
+ property("AudioClipInfo", "Name", STRING_TYPE2, "Audio clip name."),
1431
1701
  property(
1432
1702
  "AudioClipInfo",
1433
1703
  "DurationSeconds",
@@ -1437,10 +1707,13 @@ var init_language_spec = __esm({
1437
1707
  ]
1438
1708
  },
1439
1709
  {
1440
- id: "builtin:DialogueRef",
1441
- name: "DialogueRef",
1710
+ id: "builtin:NeoDialogueReference",
1711
+ name: "NeoDialogueReference",
1442
1712
  kind: "builtin",
1443
- members: [property("DialogueRef", "id", STRING_TYPE, "Dialogue id.")]
1713
+ members: [
1714
+ property("NeoDialogueReference", "id", STRING_TYPE2, "Dialogue id."),
1715
+ ...neoScriptDialogueReferenceMethods("builtin:NeoDialogueReference")
1716
+ ]
1444
1717
  },
1445
1718
  ...vectorTypes(),
1446
1719
  {
@@ -1462,7 +1735,7 @@ var init_language_spec = __esm({
1462
1735
  returnType: { kind: "primitive", name: "void" },
1463
1736
  static: true,
1464
1737
  parameters: [
1465
- ...name === "Assert" ? [parameter("condition", BOOL_TYPE)] : [],
1738
+ ...name === "Assert" ? [parameter("condition", BOOL_TYPE2)] : [],
1466
1739
  parameter("message", { kind: "primitive", name: "unknown" })
1467
1740
  ],
1468
1741
  documentation: name === "Assert" ? "Emits an assertion event when condition is false. Both arguments are evaluated. Does not throw." : "Emits a bounded message and the current NeoScript stack. Does not throw when the sink fails."
@@ -1493,25 +1766,25 @@ var init_language_spec = __esm({
1493
1766
  "Round",
1494
1767
  ["x"],
1495
1768
  `Rounds to the nearest integer; midpoints round to even (banker's rounding). ${MATH_INTEGRAL_RULE}`,
1496
- INT_TYPE
1769
+ INT_TYPE2
1497
1770
  ),
1498
1771
  mathFunction(
1499
1772
  "Floor",
1500
1773
  ["x"],
1501
1774
  `Rounds toward negative infinity. ${MATH_INTEGRAL_RULE}`,
1502
- INT_TYPE
1775
+ INT_TYPE2
1503
1776
  ),
1504
1777
  mathFunction(
1505
1778
  "Ceiling",
1506
1779
  ["x"],
1507
1780
  `Rounds toward positive infinity. ${MATH_INTEGRAL_RULE}`,
1508
- INT_TYPE
1781
+ INT_TYPE2
1509
1782
  ),
1510
1783
  mathFunction(
1511
1784
  "Truncate",
1512
1785
  ["x"],
1513
1786
  `Rounds toward zero. ${MATH_INTEGRAL_RULE}`,
1514
- INT_TYPE
1787
+ INT_TYPE2
1515
1788
  ),
1516
1789
  mathFunction(
1517
1790
  "Abs",
@@ -1522,7 +1795,7 @@ var init_language_spec = __esm({
1522
1795
  "Sign",
1523
1796
  ["x"],
1524
1797
  "Returns -1, 0, or 1 for a negative, zero, or positive value. Accepts int, float, or decimal and always returns int.",
1525
- INT_TYPE
1798
+ INT_TYPE2
1526
1799
  ),
1527
1800
  mathFunction(
1528
1801
  "Sqrt",
@@ -1563,7 +1836,7 @@ var init_language_spec = __esm({
1563
1836
  returnType: { kind: "list", elementType: LIST_ENTRY_TYPE },
1564
1837
  parameters: [
1565
1838
  parameter("value", LIST_ENTRY_TYPE),
1566
- parameter("count", INT_TYPE)
1839
+ parameter("count", INT_TYPE2)
1567
1840
  ],
1568
1841
  documentation: "Returns a list of count copies of value. The entry type is inferred from value and the assignment context \u2014 never spell it. value is evaluated exactly once, then count exactly once, so a reference-typed value is the same reference in every entry; count must be a non-negative int, and 0 produces an empty list.",
1569
1842
  static: true
@@ -1675,12 +1948,17 @@ var init_debug_info = __esm({
1675
1948
  });
1676
1949
 
1677
1950
  // ../packages/neoscript-language/src/strict-ir.ts
1678
- var NEOSCRIPT_COMPILER_REVISION;
1951
+ var NEOSCRIPT_COMPILER_REVISION, NeoScriptDialogueOp;
1679
1952
  var init_strict_ir = __esm({
1680
1953
  "../packages/neoscript-language/src/strict-ir.ts"() {
1681
1954
  "use strict";
1682
1955
  init_debug_info();
1683
1956
  NEOSCRIPT_COMPILER_REVISION = 17;
1957
+ NeoScriptDialogueOp = /* @__PURE__ */ ((NeoScriptDialogueOp2) => {
1958
+ NeoScriptDialogueOp2["TryTrigger"] = "TryTrigger";
1959
+ NeoScriptDialogueOp2["CanTrigger"] = "CanTrigger";
1960
+ return NeoScriptDialogueOp2;
1961
+ })(NeoScriptDialogueOp || {});
1684
1962
  }
1685
1963
  });
1686
1964
 
@@ -2580,6 +2858,31 @@ function isNSFunctionHasVisited(value) {
2580
2858
  const v = value;
2581
2859
  return v?.type === "hasVisited" /* hasVisited */ && isNSDialogueMemoryFunctionInfo(v.info);
2582
2860
  }
2861
+ function isNSDialogueOp(value) {
2862
+ return value === "TryTrigger" || value === "CanTrigger";
2863
+ }
2864
+ function isOptionalNSPointer(value) {
2865
+ return value === void 0 || isNSPointer(value);
2866
+ }
2867
+ function isNSFunctionDialogueGroup(value) {
2868
+ const v = value;
2869
+ if (v?.type !== "dialogueGroup" /* dialogueGroup */) return false;
2870
+ const info = v.info;
2871
+ if (typeof info !== "object" || info === null) return false;
2872
+ if (!isNSDialogueOp(Reflect.get(info, "op"))) return false;
2873
+ if (typeof Reflect.get(info, "groupId") !== "string") return false;
2874
+ if (!isOptionalNSPointer(Reflect.get(info, "valuePointer"))) return false;
2875
+ return isOptionalNSPointer(Reflect.get(info, "onFinishPointer"));
2876
+ }
2877
+ function isNSFunctionDialogue(value) {
2878
+ const v = value;
2879
+ if (v?.type !== "dialogue" /* dialogue */) return false;
2880
+ const info = v.info;
2881
+ if (typeof info !== "object" || info === null) return false;
2882
+ if (!isNSDialogueOp(Reflect.get(info, "op"))) return false;
2883
+ if (!isNSPointer(Reflect.get(info, "dialogueIdPointer"))) return false;
2884
+ return isOptionalNSPointer(Reflect.get(info, "onFinishPointer"));
2885
+ }
2583
2886
  function isNSVectorConstructorType(value) {
2584
2887
  return value === 14 /* Vector2 */ || value === 15 /* Vector2Int */ || value === 16 /* Vector3 */ || value === 17 /* Vector3Int */;
2585
2888
  }
@@ -2639,7 +2942,7 @@ function isNSFunction(value) {
2639
2942
  return isNSFunctionClassConstructor(value) || isNSFunctionClassClone(value) || isNSFunctionListIndex(value) || isNSFunctionSelect(value) || isNSFunctionCollectionQuery(value) || isNSFunctionFirst(value) || isNSFunctionFirstOrDefault(value) || isNSFunctionWhere(value) || isNSFunctionContains(value) || isNSFunctionIndexOf(value) || // stringOp was missing from this chain since its introduction — a
2640
2943
  // compiled getter using ToLower()/StartsWith() would fail pointer
2641
2944
  // validation anywhere isNSFunction gates. Fixed alongside decimalOp.
2642
- isNSFunctionStringOp(value) || isNSFunctionDecimalOp(value) || isNSFunctionMathOp(value) || isNSFunctionListRepeat(value) || isNSFunctionCount(value) || isNSFunctionVisitCount(value) || isNSFunctionHasVisited(value) || isNSFunctionVectorConstructor(value) || isNSFunctionImageSlice(value) || isNSFunctionVariantInitialize(value) || isNSFunctionVariantApply(value) || isNSFunctionDeclaredConstructor(value);
2945
+ isNSFunctionStringOp(value) || isNSFunctionDecimalOp(value) || isNSFunctionMathOp(value) || isNSFunctionListRepeat(value) || isNSFunctionCount(value) || isNSFunctionVisitCount(value) || isNSFunctionHasVisited(value) || isNSFunctionDialogueGroup(value) || isNSFunctionDialogue(value) || isNSFunctionVectorConstructor(value) || isNSFunctionImageSlice(value) || isNSFunctionVariantInitialize(value) || isNSFunctionVariantApply(value) || isNSFunctionDeclaredConstructor(value);
2643
2946
  }
2644
2947
  function isNSInstructionVariable(value) {
2645
2948
  const v = value;
@@ -15178,13 +15481,13 @@ function firstTokenAfter(tokens, offset) {
15178
15481
  function validateDocumentShape(kind, declarations, diagnostics) {
15179
15482
  if (kind === "definition") {
15180
15483
  for (const declaration2 of declarations) {
15181
- if (declaration2.kind === "class" && declaration2.baseTypes.some((type) => type.name === "Dialogue")) {
15484
+ if (declaration2.kind === "class" && declaration2.baseTypes.some((type) => type.name === "NeoDialogue")) {
15182
15485
  diagnostics.push({
15183
15486
  range: declaration2.nameRange,
15184
15487
  severity: "error",
15185
15488
  source: "neo-project",
15186
15489
  code: "dialogue-class-in-definition",
15187
- message: "A class that directly derives from `Dialogue` belongs in a `.neoflow` file."
15490
+ message: "A class that directly derives from `NeoDialogue` belongs in a `.neoflow` file."
15188
15491
  });
15189
15492
  }
15190
15493
  }
@@ -15196,7 +15499,7 @@ function validateDocumentShape(kind, declarations, diagnostics) {
15196
15499
  severity: "error",
15197
15500
  source: "neo-project",
15198
15501
  code: "neoflow-single-dialogue-class",
15199
- message: "A `.neoflow` file must contain exactly one sealed class that directly derives from `Dialogue`."
15502
+ message: "A `.neoflow` file must contain exactly one sealed class that directly derives from `NeoDialogue`."
15200
15503
  });
15201
15504
  return;
15202
15505
  }
@@ -15219,13 +15522,13 @@ function validateDocumentShape(kind, declarations, diagnostics) {
15219
15522
  message: "A `.neoflow` dialogue class cannot be generic."
15220
15523
  });
15221
15524
  }
15222
- if (declaration.baseTypes.length !== 1 || declaration.baseTypes[0]?.name !== "Dialogue") {
15525
+ if (declaration.baseTypes.length !== 1 || declaration.baseTypes[0]?.name !== "NeoDialogue") {
15223
15526
  diagnostics.push({
15224
15527
  range: declaration.nameRange,
15225
15528
  severity: "error",
15226
15529
  source: "neo-project",
15227
15530
  code: "neoflow-dialogue-base",
15228
- message: "A `.neoflow` class must directly derive from the system `Dialogue` type."
15531
+ message: "A `.neoflow` class must directly derive from the system `NeoDialogue` type."
15229
15532
  });
15230
15533
  }
15231
15534
  addIncompleteDraftDiagnostic(declaration.annotations, diagnostics);
@@ -16124,7 +16427,7 @@ var init_project_source_parser = __esm({
16124
16427
  this.expect("=");
16125
16428
  const initializerStart = this.cursor;
16126
16429
  const initializer = this.captureInitializer();
16127
- const dialogueGroup = type.name === "DialogueGroup" ? this.parseDialogueGroupBody(initializerStart, initializer) : void 0;
16430
+ const dialogueGroup = type.name === "NeoDialogueGroup" ? this.parseDialogueGroupBody(initializerStart, initializer) : void 0;
16128
16431
  this.reportNestedTypes(initializer);
16129
16432
  return {
16130
16433
  kind: "global",
@@ -16157,7 +16460,7 @@ var init_project_source_parser = __esm({
16157
16460
  while (!this.done() && !this.at("}") && !this.at("when") && this.cursor < end) {
16158
16461
  const before = this.cursor;
16159
16462
  try {
16160
- const member = this.parseMember("DialogueGroup", "class");
16463
+ const member = this.parseMember("NeoDialogueGroup", "class");
16161
16464
  if (member?.kind === "function") functions.push(member);
16162
16465
  } catch (error) {
16163
16466
  this.report(error);
@@ -18803,8 +19106,8 @@ var init_project_local_values = __esm({
18803
19106
  "AudioClipRegistry",
18804
19107
  "NeoImage",
18805
19108
  "NeoAudioClip",
18806
- "PriorityGroup",
18807
- "DialogueGroup",
19109
+ "NeoPriorityGroup",
19110
+ "NeoDialogueGroup",
18808
19111
  "Migration"
18809
19112
  ]);
18810
19113
  }
@@ -23079,26 +23382,13 @@ function buildDialogueGroupClassNameMap(groups, diagnostics) {
23079
23382
  return names;
23080
23383
  }
23081
23384
  function buildDialogueGroupPropertyNameMap(groups, diagnostics) {
23082
- const used = /* @__PURE__ */ new Map();
23083
- const names = /* @__PURE__ */ new Map();
23084
- for (const group of groups) {
23085
- const baseName = toCSharpTypeName(group.name, "DialogueGroup");
23086
- const safeName = isCSharpReservedKeyword(baseName) ? `${baseName}Value` : baseName;
23087
- const existing = used.get(safeName);
23088
- if (existing === void 0) {
23089
- used.set(safeName, group.id);
23090
- names.set(group.id, safeName);
23091
- continue;
23092
- }
23093
- const uniqueName = `${safeName}_${shortId(group.id)}`;
23385
+ return dialogueGroupPropertyNames(groups, (collision) => {
23094
23386
  diagnostics.push({
23095
23387
  severity: "warning",
23096
- message: `Generated C# dialogue group property "${safeName}" is duplicated; using "${uniqueName}" for "${group.name}".`,
23097
- path: `dialogueGroups.${group.id}.name`
23388
+ message: `Generated C# dialogue group property "${collision.propertyName}" is duplicated; using "${collision.uniqueName}" for "${collision.groupName}".`,
23389
+ path: `dialogueGroups.${collision.groupId}.name`
23098
23390
  });
23099
- names.set(group.id, uniqueName);
23100
- }
23101
- return names;
23391
+ });
23102
23392
  }
23103
23393
  function getExtendsClassId(classDef) {
23104
23394
  const value = classDef.extendsClassId;
@@ -25073,7 +25363,7 @@ function resolveLookupEntryMember(ctx, member) {
25073
25363
  return null;
25074
25364
  }
25075
25365
  function shortId(id2) {
25076
- return id2.replace(/[^A-Za-z0-9_]/g, "").slice(0, 8) || "Id";
25366
+ return generatedCSharpShortId(id2);
25077
25367
  }
25078
25368
  function variantTargetCSharpType(ctx, member, env) {
25079
25369
  const target = member.targetTypeInfo;
@@ -25163,6 +25453,7 @@ var init_unity_member_signatures = __esm({
25163
25453
  "use strict";
25164
25454
  init_neoscript_pattern_bindings();
25165
25455
  init_cell_pattern();
25456
+ init_generated_csharp_identifiers();
25166
25457
  init_members();
25167
25458
  init_world_system_classes();
25168
25459
  init_classes();
@@ -26902,19 +27193,21 @@ function sourceDialogueGroups(source) {
26902
27193
  if (cached) return cached;
26903
27194
  const symbols = /* @__PURE__ */ new Map();
26904
27195
  const globals = /* @__PURE__ */ new Map();
27196
+ const priorityGroups = /* @__PURE__ */ new Map();
26905
27197
  const options = /* @__PURE__ */ new Map();
26906
27198
  for (const symbol of source.symbols) {
26907
27199
  if (symbol.kind !== "global") continue;
26908
- if (symbol.detail !== "DialogueGroup" && symbol.detail !== "PriorityGroup")
27200
+ if (symbol.detail !== "NeoDialogueGroup" && symbol.detail !== "NeoPriorityGroup")
26909
27201
  continue;
26910
27202
  const id2 = symbol.id ?? `${symbol.location.uri}#${symbol.name}`;
26911
27203
  globals.set(symbol.name, id2);
27204
+ if (symbol.detail === "NeoPriorityGroup")
27205
+ priorityGroups.set(symbol.name, id2);
26912
27206
  symbols.set(id2, symbol);
26913
27207
  }
26914
27208
  for (const symbol of source.symbols) {
26915
- if (symbol.kind !== "graphChild" || symbol.detail !== "PriorityOption")
26916
- continue;
26917
- const owner = globals.get(symbol.ownerName ?? "");
27209
+ if (symbol.kind !== "graphChild") continue;
27210
+ const owner = priorityGroups.get(symbol.ownerName ?? "");
26918
27211
  if (!owner) continue;
26919
27212
  const id2 = symbol.id ?? `${owner}.${symbol.name}`;
26920
27213
  symbols.set(id2, symbol);
@@ -26928,7 +27221,7 @@ function sourceDialogueGroups(source) {
26928
27221
  for (const declaration of document.declarations) {
26929
27222
  if (declaration.kind !== "global") continue;
26930
27223
  const type = declaration.type.name;
26931
- if (type !== "DialogueGroup" && type !== "Project") continue;
27224
+ if (type !== "NeoDialogueGroup" && type !== "Project") continue;
26932
27225
  const args = constructorArgs(
26933
27226
  declaration.dialogueGroup?.constructor.text ?? declaration.initializer.text
26934
27227
  );
@@ -27009,12 +27302,30 @@ function validateDialogueGroupPaths(source) {
27009
27302
  }
27010
27303
  return diagnostics;
27011
27304
  }
27305
+ function validateDialogueGroupNames(source) {
27306
+ const diagnostics = [];
27307
+ const catalog = sourceDialogueGroups(source);
27308
+ for (const group of catalog.paths.byId.values()) {
27309
+ const message = dialogueGroupReservedNameError(group.name);
27310
+ const symbol = catalog.symbols.get(group.id);
27311
+ if (message === void 0 || symbol === void 0) continue;
27312
+ diagnostics.push({
27313
+ uri: symbol.location.uri,
27314
+ severity: "error",
27315
+ code: "reserved-dialogue-group-name",
27316
+ message,
27317
+ range: symbol.location.range
27318
+ });
27319
+ }
27320
+ return diagnostics;
27321
+ }
27012
27322
  var catalogs;
27013
27323
  var init_project_source_dialogue_groups = __esm({
27014
27324
  "../packages/neoscript-language/src/project-source-dialogue-groups.ts"() {
27015
27325
  "use strict";
27016
27326
  init_dialogue_group_paths();
27017
27327
  init_executable_parser();
27328
+ init_generated_csharp_identifiers();
27018
27329
  catalogs = /* @__PURE__ */ new WeakMap();
27019
27330
  }
27020
27331
  });
@@ -27237,6 +27548,7 @@ function collectGlobalChildEntries(syntax, declaration) {
27237
27548
  const value = tokens[index + 3];
27238
27549
  entries.push({
27239
27550
  typeName: token.text,
27551
+ typeRange: token.range,
27240
27552
  name: name.text,
27241
27553
  nameRange: name.range,
27242
27554
  annotations: pendingAnnotations,
@@ -29640,6 +29952,43 @@ function enumLiteralKeyOptionId(pointer) {
29640
29952
  }
29641
29953
  return pointer.value.value[0];
29642
29954
  }
29955
+ function isDialogueRequestName(name) {
29956
+ return name === "TryTrigger" || name === "CanTrigger";
29957
+ }
29958
+ function dialogueBodyKindLabel(kind) {
29959
+ if (kind === "initializer" || kind === "initializerExpression")
29960
+ return "an initializer";
29961
+ return `a ${kind}`;
29962
+ }
29963
+ function capitalize(text) {
29964
+ return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
29965
+ }
29966
+ function requireDialogueArgCount(name, args, required2, acceptsOnFinish, pos) {
29967
+ if (!acceptsOnFinish) {
29968
+ requireArgCount(name, args, required2, pos);
29969
+ return;
29970
+ }
29971
+ if (args.length === required2 || args.length === required2 + 1) return;
29972
+ throw new CompileError(
29973
+ `${name} expects ${required2} or ${required2 + 1} arguments, got ${args.length}.`,
29974
+ pos
29975
+ );
29976
+ }
29977
+ function dialogueValueError(receiver) {
29978
+ if (receiver.kind === "root") {
29979
+ return `\`${receiver.path}\` is not a value. Use one of its members.`;
29980
+ }
29981
+ if (receiver.kind === "folder") {
29982
+ return `\`${receiver.path}\` is a dialogue folder, not a value. Use one of its groups' members.`;
29983
+ }
29984
+ return `\`${receiver.path}\` is a dialogue group, not a value. Use one of its members.`;
29985
+ }
29986
+ function dialogueIntrinsic(fn) {
29987
+ return {
29988
+ pointer: { type: "function" /* Function */, function: fn },
29989
+ type: { kind: "primitive", name: "bool" }
29990
+ };
29991
+ }
29643
29992
  function intrinsic(kind, info, type) {
29644
29993
  return {
29645
29994
  pointer: {
@@ -29846,7 +30195,7 @@ function primitiveValueKind(name) {
29846
30195
  return 11 /* Sprite */;
29847
30196
  case "AudioClipInfo":
29848
30197
  return 12 /* Audio */;
29849
- case "DialogueRef":
30198
+ case "NeoDialogueReference":
29850
30199
  return 18 /* DialogueLookup */;
29851
30200
  case "Vector2":
29852
30201
  return 14 /* Vector2 */;
@@ -29879,7 +30228,7 @@ function valueKindPrimitive(kind) {
29879
30228
  case 12 /* Audio */:
29880
30229
  return "AudioClipInfo";
29881
30230
  case 18 /* DialogueLookup */:
29882
- return "DialogueRef";
30231
+ return "NeoDialogueReference";
29883
30232
  case 14 /* Vector2 */:
29884
30233
  return "Vector2";
29885
30234
  case 15 /* Vector2Int */:
@@ -30059,7 +30408,7 @@ function resolvePrimitiveMember(type, name) {
30059
30408
  if (name === "length")
30060
30409
  return { type: { kind: "primitive", name: "float" } };
30061
30410
  }
30062
- if (type.name === "DialogueRef" && name === "id")
30411
+ if (type.name === "NeoDialogueReference" && name === "id")
30063
30412
  return { type: { kind: "primitive", name: "string" } };
30064
30413
  return null;
30065
30414
  }
@@ -30158,7 +30507,7 @@ function namedPrimitive(name) {
30158
30507
  case "decimal":
30159
30508
  case "SpriteInfo":
30160
30509
  case "AudioClipInfo":
30161
- case "DialogueRef":
30510
+ case "NeoDialogueReference":
30162
30511
  case "Vector2":
30163
30512
  case "Vector2Int":
30164
30513
  case "Vector3":
@@ -30393,7 +30742,10 @@ function resolveNeoScriptType(type, context, project) {
30393
30742
  }
30394
30743
  const named = project.typeByName.get(type.name);
30395
30744
  if (!named)
30396
- throw new CompileError(`Unknown type '${type.name}'`, type.pos);
30745
+ throw new CompileError(
30746
+ renamedDialogueTypeMessage(type.name, "value") ?? `Unknown type '${type.name}'`,
30747
+ type.pos
30748
+ );
30397
30749
  resolved = {
30398
30750
  kind: "named",
30399
30751
  typeId: named.id,
@@ -30459,6 +30811,7 @@ var init_strict_resolver = __esm({
30459
30811
  init_strict_compile_error();
30460
30812
  init_strict_ir();
30461
30813
  init_test_prelude();
30814
+ init_dialogue_types();
30462
30815
  init_tile_conversion();
30463
30816
  CONSTRUCTING_FUNCTION_KINDS = /* @__PURE__ */ new Set(
30464
30817
  [
@@ -31883,23 +32236,23 @@ var init_strict_resolver = __esm({
31883
32236
  resolveDebugStatement(expr, scope) {
31884
32237
  if (expr.kind !== "call" || expr.callee.kind !== "member" || expr.callee.receiver.kind !== "ident" || expr.callee.receiver.name !== "Debug" || this.hasValueReceiver("Debug", scope) || this.project.typeByName.get("Debug")?.id !== "builtin:Debug" && this.project.typeByName.has("Debug"))
31885
32238
  return null;
31886
- const method2 = expr.callee.name;
32239
+ const method3 = expr.callee.name;
31887
32240
  const severities = {
31888
32241
  Log: "log",
31889
32242
  LogWarning: "warning",
31890
32243
  LogError: "error",
31891
32244
  Assert: "assert"
31892
32245
  };
31893
- if (!Object.hasOwn(severities, method2))
31894
- throw new CompileError(`Unknown Debug method '${method2}'.`, expr.pos);
31895
- const severity = severities[method2];
31896
- const expected = method2 === "Assert" ? 2 : 1;
32246
+ if (!Object.hasOwn(severities, method3))
32247
+ throw new CompileError(`Unknown Debug method '${method3}'.`, expr.pos);
32248
+ const severity = severities[method3];
32249
+ const expected = method3 === "Assert" ? 2 : 1;
31897
32250
  if (expr.args.length !== expected)
31898
32251
  throw new CompileError(
31899
- `Debug.${method2} expects ${expected} argument(s).`,
32252
+ `Debug.${method3} expects ${expected} argument(s).`,
31900
32253
  expr.pos
31901
32254
  );
31902
- const condition = method2 === "Assert" ? this.resolveExpression(requiredAt(expr.args, 0), scope) : void 0;
32255
+ const condition = method3 === "Assert" ? this.resolveExpression(requiredAt(expr.args, 0), scope) : void 0;
31903
32256
  if (condition && (!isPrimitive(condition.type, "bool") || isNullable(condition.type)))
31904
32257
  throw new CompileError(
31905
32258
  "Debug.Assert requires a non-null bool condition.",
@@ -32789,6 +33142,17 @@ var init_strict_resolver = __esm({
32789
33142
  }
32790
33143
  }
32791
33144
  resolveExpression(expression, scope, expected) {
33145
+ const result = this.resolveReceiverExpression(expression, scope, expected);
33146
+ if (result.dialogues !== void 0) {
33147
+ throw new CompileError(
33148
+ dialogueValueError(result.dialogues),
33149
+ expression.pos
33150
+ );
33151
+ }
33152
+ return result;
33153
+ }
33154
+ /** {@link resolveExpression} that also admits a `root.Dialogues` receiver. */
33155
+ resolveReceiverExpression(expression, scope, expected) {
32792
33156
  let result = this.resolveExpressionCore(expression, scope, expected);
32793
33157
  if (result.pointer.type === "function" /* Function */ || result.pointer.type === "callFunction" /* CallFunction */ || result.pointer.type === "callDelegate" /* CallDelegate */ || result.pointer.type === "callAction" /* CallAction */ || result.pointer.type === "callGetter" /* CallGetter */) {
32794
33158
  result = {
@@ -34366,7 +34730,7 @@ var init_strict_resolver = __esm({
34366
34730
  return this.resolveStaticMemberValue(staticType, member, pos);
34367
34731
  }
34368
34732
  }
34369
- const resolvedReceiver = receiverValue ? receiverValue() : this.resolveExpression(receiverAst, scope);
34733
+ const resolvedReceiver = receiverValue ? receiverValue() : this.resolveReceiverExpression(receiverAst, scope);
34370
34734
  if (optional2 && !isNullable(resolvedReceiver.type)) {
34371
34735
  throw new CompileError(
34372
34736
  `\`?.\` requires an optional receiver; got ${this.describe(resolvedReceiver.type)}`,
@@ -34462,7 +34826,7 @@ var init_strict_resolver = __esm({
34462
34826
  }
34463
34827
  const primitiveMember = resolvePrimitiveMember(receiver.type, name);
34464
34828
  if (primitiveMember) {
34465
- if (isPrimitive(receiver.type, "DialogueRef")) {
34829
+ if (isPrimitive(receiver.type, "NeoDialogueReference")) {
34466
34830
  return {
34467
34831
  pointer: {
34468
34832
  type: "keyOf" /* KeyOf */,
@@ -34495,12 +34859,15 @@ var init_strict_resolver = __esm({
34495
34859
  pos
34496
34860
  );
34497
34861
  }
34498
- if (isPrimitive(receiver.type, "DialogueRef")) {
34862
+ if (isPrimitive(receiver.type, "NeoDialogueReference")) {
34499
34863
  throw new CompileError(
34500
34864
  `${this.describe(receiver.type)} has no member '${name}'`,
34501
34865
  pos
34502
34866
  );
34503
34867
  }
34868
+ if (receiver.dialogues !== void 0) {
34869
+ return this.resolveDialogueGroupRead(receiver, name, pos);
34870
+ }
34504
34871
  const memberReceiverType = neoScriptMemberLookupType(receiver.type);
34505
34872
  if (memberReceiverType.kind === "named") {
34506
34873
  const type = this.project.typeById.get(memberReceiverType.typeId);
@@ -34529,6 +34896,10 @@ var init_strict_resolver = __esm({
34529
34896
  if (this.userClassCode && type.id === this.rootTypeId && member.writability !== "user") {
34530
34897
  throw new CompileError("User code can only read `root.User`.", pos);
34531
34898
  }
34899
+ const dialogues = this.dialogueReceiverOf(member.type);
34900
+ if (dialogues !== void 0) {
34901
+ return { ...literal(member.type, null), dialogues, symbol: member };
34902
+ }
34532
34903
  if (member.static === true) {
34533
34904
  throw new CompileError(
34534
34905
  `Static member '${type.name}.${name}' must be accessed through the type name, not an instance.`,
@@ -34883,6 +35254,227 @@ var init_strict_resolver = __esm({
34883
35254
  );
34884
35255
  }
34885
35256
  }
35257
+ /** P105 §2.1. The receiver a value of this type is, if it is one. */
35258
+ dialogueReceiverOf(type) {
35259
+ if (type.kind !== "named") return void 0;
35260
+ return this.project.typeById.get(type.typeId)?.dialogues;
35261
+ }
35262
+ /** P105 §2.1. `<receiver>.<Group>`; the methods are only callable. */
35263
+ resolveDialogueGroupRead(receiver, name, pos) {
35264
+ const path = receiver.dialogues.path;
35265
+ const type = receiver.type.kind === "named" ? this.project.typeById.get(receiver.type.typeId) : void 0;
35266
+ const member = type?.members.find((candidate) => candidate.name === name);
35267
+ if (member === void 0) {
35268
+ throw new CompileError(`${path} has no dialogue group '${name}'.`, pos);
35269
+ }
35270
+ if (member.kind === "method") {
35271
+ throw new CompileError(
35272
+ `'${path}.${name}' must be called with \`()\`; it cannot be read as a value.`,
35273
+ pos
35274
+ );
35275
+ }
35276
+ const dialogues = this.dialogueReceiverOf(member.type);
35277
+ if (dialogues === void 0) {
35278
+ throw new Error(
35279
+ `Dialogue group member '${path}.${name}' has no group type.`
35280
+ );
35281
+ }
35282
+ return { ...literal(member.type, null), dialogues, symbol: member };
35283
+ }
35284
+ /** P105 §2.1. A call on `root.Dialogues` or one of its groups. */
35285
+ resolveDialogueReceiverCall(receiver, name, args, scope, pos) {
35286
+ if (receiver.kind === "root") {
35287
+ if (name === "VisitCount" || name === "HasVisited") {
35288
+ return this.resolveDialogueMemoryRead(name, args, scope, pos);
35289
+ }
35290
+ if (!isDialogueRequestName(name)) {
35291
+ throw new CompileError(
35292
+ `${receiver.path} has no method '${name}'.`,
35293
+ pos
35294
+ );
35295
+ }
35296
+ this.assertDialogueRequestAllowed(name, pos);
35297
+ requireDialogueArgCount(name, args, 1, name === "TryTrigger", pos);
35298
+ const dialogueId = this.resolveExpression(requiredAt(args, 0), scope, {
35299
+ kind: "primitive",
35300
+ name: "string"
35301
+ });
35302
+ this.requireAssignable(
35303
+ dialogueId.type,
35304
+ { kind: "primitive", name: "string" },
35305
+ requiredAt(args, 0).pos,
35306
+ "dialogueId"
35307
+ );
35308
+ return dialogueIntrinsic({
35309
+ type: "dialogue" /* Dialogue */,
35310
+ info: {
35311
+ op: NeoScriptDialogueOp[name],
35312
+ dialogueIdPointer: dialogueId.pointer,
35313
+ ...this.dialogueOnFinish(args[1], scope)
35314
+ }
35315
+ });
35316
+ }
35317
+ if (!isDialogueRequestName(name)) {
35318
+ throw new CompileError(`${receiver.path} has no member '${name}'.`, pos);
35319
+ }
35320
+ if (receiver.kind === "folder") {
35321
+ throw new CompileError(
35322
+ `${receiver.path} is a dialogue folder, so it has no '${name}'. Use one of its groups' members.`,
35323
+ pos
35324
+ );
35325
+ }
35326
+ this.assertDialogueRequestAllowed(name, pos);
35327
+ if (receiver.kind === "standard") {
35328
+ requireDialogueArgCount(name, args, 0, name === "TryTrigger", pos);
35329
+ return dialogueIntrinsic({
35330
+ type: "dialogueGroup" /* DialogueGroup */,
35331
+ info: {
35332
+ op: NeoScriptDialogueOp[name],
35333
+ groupId: receiver.groupId,
35334
+ ...this.dialogueOnFinish(args[0], scope)
35335
+ }
35336
+ });
35337
+ }
35338
+ const entryType = receiver.entryType;
35339
+ if (entryType === void 0) {
35340
+ throw new CompileError(
35341
+ `${receiver.path} can't be triggered: its lookup collection has no entry class.`,
35342
+ pos
35343
+ );
35344
+ }
35345
+ requireDialogueArgCount(name, args, 1, name === "TryTrigger", pos);
35346
+ const value = this.resolveExpression(requiredAt(args, 0), scope, entryType);
35347
+ this.requireAssignable(
35348
+ value.type,
35349
+ entryType,
35350
+ requiredAt(args, 0).pos,
35351
+ "lookup value"
35352
+ );
35353
+ return dialogueIntrinsic({
35354
+ type: "dialogueGroup" /* DialogueGroup */,
35355
+ info: {
35356
+ op: NeoScriptDialogueOp[name],
35357
+ groupId: receiver.groupId,
35358
+ valuePointer: value.pointer,
35359
+ ...this.dialogueOnFinish(args[1], scope)
35360
+ }
35361
+ });
35362
+ }
35363
+ /**
35364
+ * P105 §2.2. `NeoDialogueReference` methods request the dialogue by the
35365
+ * reference's `id`, the same index-0 read `.id` lowers to.
35366
+ */
35367
+ resolveDialogueReferenceCall(receiver, name, args, scope, pos, optional2) {
35368
+ if (this.userClassCode) {
35369
+ throw new CompileError(
35370
+ `User code can't use ${name}. Dialogues run against a save.`,
35371
+ pos
35372
+ );
35373
+ }
35374
+ const nullPropagating = optional2 || receiver.optionalChainType !== void 0;
35375
+ if (!optional2 && isNullable(receiver.type)) {
35376
+ throw new CompileError(
35377
+ `Member '${name}' is called on ${this.describe(receiver.type)}, which may be null. Handle null before calling through it \u2014 use \`!\` if it is always set, or \`?.\` or a null check that narrows it.`,
35378
+ pos
35379
+ );
35380
+ }
35381
+ this.assertDialogueRequestAllowed(name, pos);
35382
+ requireDialogueArgCount(name, args, 0, name === "TryTrigger", pos);
35383
+ const resolved = dialogueIntrinsic({
35384
+ type: "dialogue" /* Dialogue */,
35385
+ info: {
35386
+ op: NeoScriptDialogueOp[name],
35387
+ dialogueIdPointer: {
35388
+ type: "keyOf" /* KeyOf */,
35389
+ keyOf: { pointer: receiver.pointer, key: numberPointer(0) },
35390
+ ...nullPropagating ? { optional: true } : {}
35391
+ },
35392
+ ...this.dialogueOnFinish(args[0], scope)
35393
+ }
35394
+ });
35395
+ if (!nullPropagating) return resolved;
35396
+ return {
35397
+ ...resolved,
35398
+ type: { ...resolved.type, nullable: true },
35399
+ optionalChainType: resolved.type
35400
+ };
35401
+ }
35402
+ dialogueOnFinish(argument2, scope) {
35403
+ if (argument2 === void 0) return {};
35404
+ const onFinish = this.resolveExpression(
35405
+ argument2,
35406
+ scope,
35407
+ NEOSCRIPT_DIALOGUE_ON_FINISH_TYPE
35408
+ );
35409
+ this.requireAssignable(
35410
+ onFinish.type,
35411
+ NEOSCRIPT_DIALOGUE_ON_FINISH_TYPE,
35412
+ argument2.pos,
35413
+ "onFinish"
35414
+ );
35415
+ return { onFinishPointer: onFinish.pointer };
35416
+ }
35417
+ /**
35418
+ * P105 §2.4. Requests run only from bodies that run once per call; reads
35419
+ * run wherever dialogue memory has a value.
35420
+ */
35421
+ assertDialogueRequestAllowed(name, pos) {
35422
+ if (name === "CanTrigger") {
35423
+ this.assertDialogueMemoryReadable(name, pos);
35424
+ return;
35425
+ }
35426
+ const kind = this.context.kind;
35427
+ if (kind === "function" || kind === "action") return;
35428
+ if (kind === "getter" || kind === "property" || kind === "condition") {
35429
+ throw new CompileError(
35430
+ "A getter can't trigger a dialogue. It runs whenever its value is read.",
35431
+ pos
35432
+ );
35433
+ }
35434
+ if (kind === "setter") {
35435
+ throw new CompileError(
35436
+ "A setter can't trigger a dialogue. Trigger it from a function.",
35437
+ pos
35438
+ );
35439
+ }
35440
+ throw new CompileError(
35441
+ `${capitalize(dialogueBodyKindLabel(kind))} body can't trigger a dialogue. Dialogues only run during play.`,
35442
+ pos
35443
+ );
35444
+ }
35445
+ /**
35446
+ * P43 §7.2.2. Dialogue memory is runtime state; it has no value at push
35447
+ * time, in a freshly constructed instance, or while migrating a save.
35448
+ */
35449
+ assertDialogueMemoryReadable(name, pos) {
35450
+ const kind = this.context.kind;
35451
+ if (!isNeoScriptConstructionDocumentKind(kind) && kind !== "migration") {
35452
+ return;
35453
+ }
35454
+ throw new CompileError(
35455
+ `${name} reads runtime dialogue memory, which has no meaning in ${dialogueBodyKindLabel(kind)} body.`,
35456
+ pos
35457
+ );
35458
+ }
35459
+ resolveDialogueMemoryRead(name, args, scope, pos) {
35460
+ this.assertDialogueMemoryReadable(name, pos);
35461
+ requireArgCount(name, args, 1, pos);
35462
+ const pointer = this.resolveExpression(requiredAt(args, 0), scope, {
35463
+ kind: "primitive",
35464
+ name: "string"
35465
+ });
35466
+ if (!isPrimitive(pointer.type, "string")) {
35467
+ throw new CompileError(
35468
+ `${name} pointer must be a string; got ${this.describe(pointer.type)}`,
35469
+ pos
35470
+ );
35471
+ }
35472
+ return intrinsic(
35473
+ name === "VisitCount" ? "visitCount" /* VisitCount */ : "hasVisited" /* HasVisited */,
35474
+ { pointer: pointer.pointer },
35475
+ { kind: "primitive", name: name === "VisitCount" ? "int" : "bool" }
35476
+ );
35477
+ }
34886
35478
  /**
34887
35479
  * P69 §2.7. A member read on the `Math` namespace: the two constants lower
34888
35480
  * to `float` literals, and nothing else on `Math` is readable as a value.
@@ -35088,7 +35680,9 @@ var init_strict_resolver = __esm({
35088
35680
  return () => {
35089
35681
  if (!result) {
35090
35682
  try {
35091
- result = { value: this.resolveExpression(callee.receiver, scope) };
35683
+ result = {
35684
+ value: this.resolveReceiverExpression(callee.receiver, scope)
35685
+ };
35092
35686
  } catch (error) {
35093
35687
  result = { error };
35094
35688
  }
@@ -35143,31 +35737,11 @@ var init_strict_resolver = __esm({
35143
35737
  if (vector3)
35144
35738
  return this.resolveVectorConstructor(vector3, argumentsList2, scope, pos);
35145
35739
  if (callee.name === "VisitCount" || callee.name === "HasVisited") {
35146
- if (isNeoScriptConstructionDocumentKind(this.context.kind)) {
35147
- throw new CompileError(
35148
- `${callee.name} reads runtime dialogue memory, which has no meaning in a ${this.context.kind} body.`,
35149
- pos
35150
- );
35151
- }
35152
- requireArgCount(callee.name, argumentsList2, 1, pos);
35153
- const pointer = this.resolveExpression(
35154
- requiredAt(argumentsList2, 0),
35740
+ return this.resolveDialogueMemoryRead(
35741
+ callee.name,
35742
+ argumentsList2,
35155
35743
  scope,
35156
- { kind: "primitive", name: "string" }
35157
- );
35158
- if (!isPrimitive(pointer.type, "string")) {
35159
- throw new CompileError(
35160
- `${callee.name} pointer must be a string; got ${this.describe(pointer.type)}`,
35161
- pos
35162
- );
35163
- }
35164
- return intrinsic(
35165
- callee.name === "VisitCount" ? "visitCount" /* VisitCount */ : "hasVisited" /* HasVisited */,
35166
- { pointer: pointer.pointer },
35167
- {
35168
- kind: "primitive",
35169
- name: callee.name === "VisitCount" ? "int" : "bool"
35170
- }
35744
+ pos
35171
35745
  );
35172
35746
  }
35173
35747
  const global = this.context.project.globals.find(
@@ -35272,12 +35846,37 @@ var init_strict_resolver = __esm({
35272
35846
  }
35273
35847
  const receiver = receiverValue();
35274
35848
  const optional2 = callee.optional === true;
35849
+ if (receiver.dialogues !== void 0) {
35850
+ if (optional2) {
35851
+ throw new CompileError(
35852
+ `\`?.\` is not valid on ${receiver.dialogues.path}; it is never null.`,
35853
+ pos
35854
+ );
35855
+ }
35856
+ return this.resolveDialogueReceiverCall(
35857
+ receiver.dialogues,
35858
+ callee.name,
35859
+ argumentsList2,
35860
+ scope,
35861
+ pos
35862
+ );
35863
+ }
35275
35864
  if (optional2 && !isNullable(receiver.type)) {
35276
35865
  throw new CompileError(
35277
35866
  `\`?.\` requires an optional receiver; got ${this.describe(receiver.type)}`,
35278
35867
  pos
35279
35868
  );
35280
35869
  }
35870
+ if (isPrimitive(receiver.type, "NeoDialogueReference") && isDialogueRequestName(callee.name)) {
35871
+ return this.resolveDialogueReferenceCall(
35872
+ receiver,
35873
+ callee.name,
35874
+ argumentsList2,
35875
+ scope,
35876
+ pos,
35877
+ optional2
35878
+ );
35879
+ }
35281
35880
  if (callee.name === "Slice" && isPrimitive(receiver.type, "ImageRef")) {
35282
35881
  return this.resolveImageSlice(receiver, argumentsList2, scope, pos);
35283
35882
  }
@@ -37559,6 +38158,7 @@ var init_strict_resolver = __esm({
37559
38158
  }
37560
38159
  }
37561
38160
  const receiver = receiverValue();
38161
+ if (receiver.dialogues !== void 0) return null;
37562
38162
  const memberReceiverType = neoScriptMemberLookupType(receiver.type);
37563
38163
  if (memberReceiverType.kind !== "named") return null;
37564
38164
  const type = this.project.typeById.get(memberReceiverType.typeId);
@@ -42586,7 +43186,7 @@ function createEnvironment(documents, project) {
42586
43186
  if (declaration.kind === "class") {
42587
43187
  types.set(declaration.name, declaration);
42588
43188
  const dialogue = declaration.baseTypes.some(
42589
- (base) => base.name === "Dialogue"
43189
+ (base) => base.name === "NeoDialogue"
42590
43190
  );
42591
43191
  if (dialogue) {
42592
43192
  referenceTargets.set(declaration.name, {
@@ -43303,7 +43903,9 @@ function fieldsForAnnotation(name, context, environment) {
43303
43903
  }
43304
43904
  if (name === "primary") return context.kind === "flowBinding" ? [] : null;
43305
43905
  if (name === "incomplete") {
43306
- return context.kind === "flowGraph" || context.kind === "flowMember" || context.kind === "class" && context.declaration.baseTypes.some((type) => type.name === "Dialogue") ? [{ name: "reason", type: "string" }] : null;
43906
+ return context.kind === "flowGraph" || context.kind === "flowMember" || context.kind === "class" && context.declaration.baseTypes.some(
43907
+ (type) => type.name === "NeoDialogue"
43908
+ ) ? [{ name: "reason", type: "string" }] : null;
43307
43909
  }
43308
43910
  if (name === "visibility") {
43309
43911
  return context.kind === "class" ? [{ name: "visibility", type: "NeoClassVisibility" }] : null;
@@ -43347,7 +43949,7 @@ function settingsFields(context) {
43347
43949
  ];
43348
43950
  }
43349
43951
  if (context.kind === "class") {
43350
- if (context.declaration.baseTypes.some((type2) => type2.name === "Dialogue")) {
43952
+ if (context.declaration.baseTypes.some((type2) => type2.name === "NeoDialogue")) {
43351
43953
  return [
43352
43954
  { name: "name", type: "string" },
43353
43955
  { name: "description", type: "string" },
@@ -43382,7 +43984,7 @@ function settingsFields(context) {
43382
43984
  );
43383
43985
  }
43384
43986
  if (type.name === "Lookup") return lookupSettingsFields();
43385
- if (type.name === "Dialogue")
43987
+ if (type.name === "NeoDialogueReference")
43386
43988
  return settingsClassFields("NeoDialogueSettings");
43387
43989
  if (type.name === "NeoImage" || type.name === "NeoAudioClip" || type.name === "SpriteInfo" || type.name === "AudioClipInfo") {
43388
43990
  return settingsClassFields("NeoFileSettings").filter(
@@ -44815,7 +45417,8 @@ function subscriptKeyType(receiver) {
44815
45417
  if (receiver?.name === "List") return primitiveType("int");
44816
45418
  return void 0;
44817
45419
  }
44818
- function validateReferenceExpression(expression, expected, environment, uri, range2, diagnostics) {
45420
+ function validateReferenceExpression(expression, declared, environment, uri, range2, diagnostics) {
45421
+ const expected = declared?.name === "NeoDialogueReference" ? { ...declared, name: "NeoDialogue" } : declared;
44819
45422
  const typeArguments = expression.typeArguments ?? [];
44820
45423
  const names = expression.argumentNames ?? [];
44821
45424
  const idIndex = names.findIndex((name) => name === "id");
@@ -44907,7 +45510,7 @@ function validateReferenceExpression(expression, expected, environment, uri, ran
44907
45510
  );
44908
45511
  return;
44909
45512
  }
44910
- if (target.kind === "dialogue" && expected && expected.name !== "Dialogue") {
45513
+ if (target.kind === "dialogue" && expected && expected.name !== "NeoDialogue") {
44911
45514
  if (!referenceTypeAssignable(target.type, expected, environment)) {
44912
45515
  malformed(
44913
45516
  `Dialogue target ${path} is incompatible with expected target ${describeType(expected)}.`
@@ -44941,8 +45544,8 @@ function referenceTargetPath(expression) {
44941
45544
  return receiver === null ? null : `${receiver}.${expression.name}`;
44942
45545
  }
44943
45546
  function isDialogueReferenceType(type, environment) {
44944
- if (type.name === "Dialogue") return true;
44945
- return classExtends(type.name, "Dialogue", environment, /* @__PURE__ */ new Set());
45547
+ if (type.name === "NeoDialogue") return true;
45548
+ return classExtends(type.name, "NeoDialogue", environment, /* @__PURE__ */ new Set());
44946
45549
  }
44947
45550
  function referenceTypeAssignable(actual, expected, environment) {
44948
45551
  if (actual.name === expected.name) {
@@ -45876,14 +46479,18 @@ function successfulBodyCache(project) {
45876
46479
  }
45877
46480
  function compileProjectSourceBodies(documents) {
45878
46481
  const graph = buildProjectGraph(documents);
45879
- const groupContexts = dialogueGroupContexts(documents, graph);
45880
- const project = {
45881
- ...graph.project,
45882
- types: [
45883
- ...graph.project.types,
45884
- ...[...groupContexts.values()].map((group) => group.contextType)
45885
- ]
45886
- };
46482
+ const groups = sourceDialogueGroups2(documents, graph);
46483
+ const groupContexts = groups.contexts;
46484
+ const dialogues = neoScriptDialogueTypes(groups.sources);
46485
+ const types = [];
46486
+ for (const type of graph.project.types) {
46487
+ types.push(
46488
+ type.id === PROJECT_ROOT_TYPE_ID ? { ...type, members: [...type.members, dialogues.member] } : type
46489
+ );
46490
+ }
46491
+ for (const group of groupContexts.values()) types.push(group.contextType);
46492
+ types.push(...dialogues.types);
46493
+ const project = { ...graph.project, types };
45887
46494
  const projectIndex = createProjectIndex(project);
45888
46495
  const bodyCache = successfulBodyCache(project);
45889
46496
  const bodies = [];
@@ -46100,76 +46707,78 @@ function compileProjectSourceBodies(documents) {
46100
46707
  }
46101
46708
  return { project, bodies, contexts, diagnostics };
46102
46709
  }
46103
- function dialogueGroupContexts(documents, graph) {
46104
- const result = /* @__PURE__ */ new Map();
46105
- let index;
46106
- let membersByType;
46107
- const collectionMembersByType = () => membersByType ??= new Map(
46108
- graph.project.types.map((type) => [
46109
- type.name,
46110
- new Map(type.members.map((member) => [member.name, member]))
46111
- ])
46112
- );
46710
+ function sourceDialogueGroups2(documents, graph) {
46711
+ const declarations = [];
46712
+ const idsByName = /* @__PURE__ */ new Map();
46113
46713
  for (const [uri, document] of documents) {
46114
46714
  for (const declaration of document.declarations) {
46115
- if (declaration.kind !== "global" || !declaration.dialogueGroup) continue;
46116
- let thisType;
46117
- try {
46118
- const constructor2 = parseExpression(
46119
- declaration.dialogueGroup.constructor.text
46120
- );
46121
- if (constructor2.kind === "new") {
46122
- const kind = constructor2.args[constructor2.argumentNames?.indexOf("kind") ?? -1];
46123
- const collection = constructor2.args[constructor2.argumentNames?.indexOf("collection") ?? -1];
46124
- if (kind?.kind === "contextualEnum" && kind.name === "Lookup") {
46125
- let member;
46126
- if (collection?.kind === "member" && collection.receiver.kind === "ident") {
46127
- member = collectionMembersByType().get(collection.receiver.name)?.get(collection.name);
46128
- } else if (collection?.kind === "call" && collection.callee.kind === "ident" && collection.callee.name === "Reference") {
46129
- const id3 = collection.args[collection.argumentNames?.indexOf("id") ?? -1];
46130
- if (id3?.kind === "litString")
46131
- member = (index ??= createProjectIndex(
46132
- graph.project
46133
- )).symbolById.get(id3.value);
46134
- }
46135
- let entry;
46136
- if (member?.type.kind === "list") entry = member.type.elementType;
46137
- if (member?.type.kind === "dictionary")
46138
- entry = member.type.valueType;
46139
- if (entry?.kind === "named")
46140
- thisType = { ...entry, nullable: false };
46141
- }
46142
- }
46143
- } catch {
46144
- }
46145
- const id2 = `dialogue-context:${uri}:${declaration.name}`;
46146
- result.set(declaration, {
46147
- ...thisType ? { thisType } : {},
46148
- contextType: {
46149
- id: id2,
46150
- name: "DialogueContext",
46151
- kind: "synthetic",
46152
- members: [
46153
- {
46154
- id: `${id2}:primary`,
46155
- name: "primary",
46156
- kind: "property",
46157
- type: { kind: "primitive", name: "unknown" },
46158
- writable: false
46159
- },
46160
- {
46161
- id: `${id2}:trigger`,
46162
- name: "trigger",
46163
- kind: "property",
46164
- type: thisType ?? { kind: "primitive", name: "null" },
46165
- writable: false
46166
- }
46167
- ]
46168
- }
46169
- });
46715
+ if (declaration.kind !== "global") continue;
46716
+ if (declaration.type.name !== "NeoDialogueGroup") continue;
46717
+ const id2 = sourceIdentity2(
46718
+ declaration.annotations,
46719
+ `dialogue-group:${uri}:${declaration.name}`
46720
+ );
46721
+ idsByName.set(declaration.name, id2);
46722
+ declarations.push({ uri, declaration, id: id2 });
46170
46723
  }
46171
46724
  }
46172
- return result;
46725
+ const lookups = new SourceDialogueGroupLookups(graph);
46726
+ const contexts = /* @__PURE__ */ new Map();
46727
+ const sources2 = [];
46728
+ for (const { uri, declaration, id: id2 } of declarations) {
46729
+ const args = constructorArgs(
46730
+ declaration.dialogueGroup?.constructor.text ?? declaration.initializer.text
46731
+ );
46732
+ const kindArgument = args.get("kind");
46733
+ const kind = kindArgument?.kind === "contextualEnum" ? SOURCE_DIALOGUE_GROUP_KINDS[kindArgument.name] : void 0;
46734
+ const lookup = kind === "lookup" ? lookups.resolve(args.get("collection")) : void 0;
46735
+ if (declaration.dialogueGroup)
46736
+ contexts.set(
46737
+ declaration,
46738
+ dialogueGroupContext(
46739
+ `dialogue-context:${uri}:${declaration.name}`,
46740
+ lookup?.entryType
46741
+ )
46742
+ );
46743
+ if (kind === void 0) continue;
46744
+ const name = args.get("name");
46745
+ sources2.push({
46746
+ id: id2,
46747
+ name: name?.kind === "litString" ? name.value : declaration.name,
46748
+ parentId: referenceId(args.get("parent"), idsByName),
46749
+ kind,
46750
+ ...lookup ? { lookup } : {},
46751
+ location: location(uri, declaration.range),
46752
+ selectionLocation: location(uri, declaration.nameRange)
46753
+ });
46754
+ }
46755
+ return { contexts, sources: sources2 };
46756
+ }
46757
+ function dialogueGroupContext(id2, thisType) {
46758
+ return {
46759
+ ...thisType ? { thisType } : {},
46760
+ contextType: {
46761
+ id: id2,
46762
+ name: "DialogueContext",
46763
+ kind: "synthetic",
46764
+ members: [
46765
+ {
46766
+ id: `${id2}:primary`,
46767
+ name: "primary",
46768
+ kind: "property",
46769
+ type: { kind: "primitive", name: "unknown" },
46770
+ writable: false
46771
+ },
46772
+ {
46773
+ id: `${id2}:trigger`,
46774
+ name: "trigger",
46775
+ kind: "property",
46776
+ type: thisType ?? { kind: "primitive", name: "null" },
46777
+ writable: false
46778
+ }
46779
+ ]
46780
+ }
46781
+ };
46173
46782
  }
46174
46783
  function compileBody(args) {
46175
46784
  args.contexts.push({
@@ -46233,7 +46842,7 @@ function compileBody(args) {
46233
46842
  uri: args.uri,
46234
46843
  source: "neo-project",
46235
46844
  code: projectBodyDiagnosticCode(diagnostic.message, args.unit),
46236
- message: `${capitalize(args.unit)} '${args.owner.declaration.name}.${args.memberName}': ${diagnostic.message}`,
46845
+ message: `${capitalize2(args.unit)} '${args.owner.declaration.name}.${args.memberName}': ${diagnostic.message}`,
46237
46846
  relatedInformation: [
46238
46847
  {
46239
46848
  location: location(args.uri, args.declarationRange),
@@ -46779,7 +47388,7 @@ function projectRootType(documents, declarations) {
46779
47388
  }
46780
47389
  }
46781
47390
  }
46782
- return { id: "builtin:Root", name: "Root", kind: "synthetic", members };
47391
+ return { id: PROJECT_ROOT_TYPE_ID, name: "Root", kind: "synthetic", members };
46783
47392
  }
46784
47393
  function sourceTypeRef(type, owner, typeIds, resolvingTypeParameters = /* @__PURE__ */ new Set()) {
46785
47394
  const nullable2 = type.nullable || void 0;
@@ -46792,9 +47401,11 @@ function sourceTypeRef(type, owner, typeIds, resolvingTypeParameters = /* @__PUR
46792
47401
  };
46793
47402
  }
46794
47403
  if (type.name === "Set") {
47404
+ const element = type.typeArguments[0];
46795
47405
  return {
46796
47406
  kind: "set",
46797
- elementType: type.typeArguments[0] ? resolveNested(type.typeArguments[0]) : { kind: "primitive", name: "unknown" },
47407
+ // P105 §2.2. Multiselect dialogue elements are bare dialogue ids.
47408
+ elementType: element?.name === "NeoDialogueReference" ? { kind: "primitive", name: "string" } : element ? resolveNested(element) : { kind: "primitive", name: "unknown" },
46798
47409
  ...nullable2 ? { nullable: nullable2 } : {}
46799
47410
  };
46800
47411
  }
@@ -46996,16 +47607,15 @@ function sourceIdentity2(annotations, fallback) {
46996
47607
  function location(uri, range2) {
46997
47608
  return { uri, range: range2 };
46998
47609
  }
46999
- function capitalize(value) {
47610
+ function capitalize2(value) {
47000
47611
  return `${value[0]?.toUpperCase() ?? ""}${value.slice(1)}`;
47001
47612
  }
47002
- var PRIMITIVE_NAME_LIST, PRIMITIVE_NAMES, STORAGE_WRITABILITY, successfulBodiesByProject;
47613
+ var PRIMITIVE_NAME_LIST, PRIMITIVE_NAMES, STORAGE_WRITABILITY, successfulBodiesByProject, SOURCE_DIALOGUE_GROUP_KINDS, SourceDialogueGroupLookups, PROJECT_ROOT_TYPE_ID;
47003
47614
  var init_project_source_script_compiler = __esm({
47004
47615
  "../packages/neoscript-language/src/project-source-script-compiler.ts"() {
47005
47616
  "use strict";
47006
47617
  init_project_source_settlement();
47007
47618
  init_debug_info();
47008
- init_executable_parser();
47009
47619
  init_compiler();
47010
47620
  init_declared_constructors();
47011
47621
  init_language_spec();
@@ -47016,13 +47626,15 @@ var init_project_source_script_compiler = __esm({
47016
47626
  init_project_source_registry();
47017
47627
  init_source_text();
47018
47628
  init_lexer();
47629
+ init_dialogue_types();
47630
+ init_project_source_dialogue_groups();
47019
47631
  PRIMITIVE_NAME_LIST = [
47020
47632
  ...NEOSCRIPT_PRIMITIVE_TYPES,
47021
47633
  "void",
47022
47634
  "null",
47023
47635
  "SpriteInfo",
47024
47636
  "AudioClipInfo",
47025
- "DialogueRef",
47637
+ "NeoDialogueReference",
47026
47638
  "Vector2",
47027
47639
  "Vector2Int",
47028
47640
  "Vector3",
@@ -47036,6 +47648,46 @@ var init_project_source_script_compiler = __esm({
47036
47648
  User: "user"
47037
47649
  };
47038
47650
  successfulBodiesByProject = /* @__PURE__ */ new Map();
47651
+ SOURCE_DIALOGUE_GROUP_KINDS = { Standard: "standard", Lookup: "lookup", Folder: "folder" };
47652
+ SourceDialogueGroupLookups = class {
47653
+ constructor(graph) {
47654
+ this.graph = graph;
47655
+ }
47656
+ graph;
47657
+ index;
47658
+ membersByType;
47659
+ resolve(collection) {
47660
+ let member;
47661
+ if (collection?.kind === "member" && collection.receiver.kind === "ident") {
47662
+ member = (this.membersByType ??= new Map(
47663
+ this.graph.project.types.map((type) => [
47664
+ type.name,
47665
+ new Map(type.members.map((candidate) => [candidate.name, candidate]))
47666
+ ])
47667
+ )).get(collection.receiver.name)?.get(collection.name);
47668
+ } else if (collection?.kind === "call" && collection.callee.kind === "ident" && collection.callee.name === "Reference") {
47669
+ const id2 = collection.args[collection.argumentNames?.indexOf("id") ?? -1];
47670
+ if (id2?.kind === "litString")
47671
+ member = this.projectIndex().symbolById.get(id2.value);
47672
+ }
47673
+ if (member === void 0) return void 0;
47674
+ let entry;
47675
+ if (member.type.kind === "list") entry = member.type.elementType;
47676
+ if (member.type.kind === "dictionary") entry = member.type.valueType;
47677
+ if (entry?.kind !== "named") return void 0;
47678
+ const entryTypeName = this.projectIndex().typeById.get(entry.typeId)?.name;
47679
+ if (entryTypeName === void 0) return void 0;
47680
+ return {
47681
+ collection: member.name,
47682
+ entryType: { ...entry, nullable: false },
47683
+ entryTypeName
47684
+ };
47685
+ }
47686
+ projectIndex() {
47687
+ return this.index ??= createProjectIndex(this.graph.project);
47688
+ }
47689
+ };
47690
+ PROJECT_ROOT_TYPE_ID = "builtin:Root";
47039
47691
  }
47040
47692
  });
47041
47693
 
@@ -48028,7 +48680,7 @@ function validateClassOverrides(ref, environment, diagnostics) {
48028
48680
  }
48029
48681
  const target = candidates[candidates.length - 1];
48030
48682
  if (!target) {
48031
- const isDialogueTriggerOverride = ref.declaration.baseTypes.some((base) => base.name === "Dialogue") && member.kind === "field" && member.name === "Trigger" && member.type.name === "Trigger";
48683
+ const isDialogueTriggerOverride = ref.declaration.baseTypes.some((base) => base.name === "NeoDialogue") && member.kind === "field" && member.name === "Trigger" && member.type.name === "Trigger";
48032
48684
  if (isDialogueTriggerOverride) continue;
48033
48685
  const opaqueBase = ref.declaration.baseTypes.find(
48034
48686
  (base) => BUILTIN_TYPES.has(base.name) && !environment.declarations.has(base.name)
@@ -48841,9 +49493,9 @@ var init_project_source_type_checker = __esm({
48841
49493
  "AudioTemplate",
48842
49494
  "Localization",
48843
49495
  "LocalizationStatus",
48844
- "PriorityGroup",
48845
- "PriorityOption",
48846
- "DialogueGroup",
49496
+ "NeoPriorityGroup",
49497
+ "NeoPriorityOption",
49498
+ "NeoDialogueGroup",
48847
49499
  "ImageRegistry",
48848
49500
  "AudioClipRegistry",
48849
49501
  "NeoImage",
@@ -49122,6 +49774,7 @@ function analyzeNeoProjectSources(inputs, parsedDocuments = /* @__PURE__ */ new
49122
49774
  }
49123
49775
  validateSymbolUniqueness(symbols, diagnostics);
49124
49776
  diagnostics.push(...validateDialogueGroupPaths({ documents, symbols }));
49777
+ diagnostics.push(...validateDialogueGroupNames({ documents, symbols }));
49125
49778
  diagnostics.push(...validateLocalValueInitializers(documents));
49126
49779
  diagnostics.push(...validateVariantDeclarations(documents));
49127
49780
  validateSystemAnnotationAuthoring(documents, diagnostics);
@@ -49295,7 +49948,18 @@ function collectDeclarationSymbols(uri, document, declaration, symbols, diagnost
49295
49948
  }
49296
49949
  function collectGlobalChildSymbols(uri, document, declaration, symbols, diagnostics) {
49297
49950
  if (declaration.type.name === "Root") return;
49951
+ const priorityGroup = declaration.type.name === "NeoPriorityGroup";
49298
49952
  for (const entry of collectGlobalChildEntries(document.syntax, declaration)) {
49953
+ if (priorityGroup && entry.typeName !== "NeoPriorityOption") {
49954
+ diagnostics.push({
49955
+ uri,
49956
+ range: entry.typeRange,
49957
+ severity: "error",
49958
+ source: "neo-project",
49959
+ code: "unknown-project-type",
49960
+ message: renamedDialogueTypeMessage(entry.typeName, "value") ?? `Priority group options are declared as \`NeoPriorityOption\`, not \`${entry.typeName}\`.`
49961
+ });
49962
+ }
49299
49963
  collectSymbol(
49300
49964
  uri,
49301
49965
  "graphChild",
@@ -49625,7 +50289,7 @@ function validateTypeReferences(documents, symbols, diagnostics) {
49625
50289
  declaration.genericParameters.map((parameter4) => parameter4.name)
49626
50290
  ) : /* @__PURE__ */ new Set();
49627
50291
  for (const base of declaration.baseTypes) {
49628
- validateType(uri, base, generics, projectTypes, diagnostics);
50292
+ validateType(uri, base, generics, projectTypes, diagnostics, "base");
49629
50293
  }
49630
50294
  if (declaration.kind === "class") {
49631
50295
  for (const parameter4 of declaration.genericParameters) {
@@ -49635,7 +50299,8 @@ function validateTypeReferences(documents, symbols, diagnostics) {
49635
50299
  parameter4.constraint,
49636
50300
  generics,
49637
50301
  projectTypes,
49638
- diagnostics
50302
+ diagnostics,
50303
+ "base"
49639
50304
  );
49640
50305
  }
49641
50306
  }
@@ -49699,7 +50364,7 @@ function validateMemberTypes(uri, owner, member, genericParameters, projectTypes
49699
50364
  });
49700
50365
  }
49701
50366
  }
49702
- function validateType(uri, type, genericParameters, projectTypes, diagnostics) {
50367
+ function validateType(uri, type, genericParameters, projectTypes, diagnostics, position = "value") {
49703
50368
  if (!BUILTIN_TYPE_NAMES.has(type.name) && !genericParameters.has(type.name) && !projectTypes.has(type.name)) {
49704
50369
  diagnostics.push({
49705
50370
  uri,
@@ -49707,7 +50372,7 @@ function validateType(uri, type, genericParameters, projectTypes, diagnostics) {
49707
50372
  severity: "error",
49708
50373
  source: "neo-project",
49709
50374
  code: "unknown-project-type",
49710
- message: `Unknown project type '${type.name}'. Declare it in a top-level .neo file or correct the type name.`
50375
+ message: renamedDialogueTypeMessage(type.name, position) ?? `Unknown project type '${type.name}'. Declare it in a top-level .neo file or correct the type name.`
49711
50376
  });
49712
50377
  }
49713
50378
  for (const argument2 of type.typeArguments) {
@@ -49740,6 +50405,7 @@ var BUILTIN_TYPE_NAMES, SYSTEM_RECORD_ID_PREFIX2, RFC_4122_UUID, QUARANTINED_LEG
49740
50405
  var init_project_source_analysis = __esm({
49741
50406
  "../packages/neoscript-language/src/project-source-analysis.ts"() {
49742
50407
  "use strict";
50408
+ init_dialogue_types();
49743
50409
  init_project_source_dialogue_groups();
49744
50410
  init_project_local_values();
49745
50411
  init_language_spec();
@@ -49764,9 +50430,9 @@ var init_project_source_analysis = __esm({
49764
50430
  "AudioTemplate",
49765
50431
  "Localization",
49766
50432
  "LocalizationStatus",
49767
- "PriorityGroup",
49768
- "PriorityOption",
49769
- "DialogueGroup",
50433
+ "NeoPriorityGroup",
50434
+ "NeoPriorityOption",
50435
+ "NeoDialogueGroup",
49770
50436
  "ImageRegistry",
49771
50437
  "AudioClipRegistry",
49772
50438
  "NeoImage",
@@ -50910,7 +51576,7 @@ var init_project_source_manifest = __esm({
50910
51576
  ]);
50911
51577
  FILE_REGISTRY_TYPES = /* @__PURE__ */ new Set(["ImageRegistry", "AudioClipRegistry"]);
50912
51578
  FILE_DECLARATION_TYPES = /* @__PURE__ */ new Set(["NeoImage", "NeoAudioClip"]);
50913
- GROUP_TYPES = /* @__PURE__ */ new Set(["PriorityGroup", "DialogueGroup"]);
51579
+ GROUP_TYPES = /* @__PURE__ */ new Set(["NeoPriorityGroup", "NeoDialogueGroup"]);
50914
51580
  MIGRATION_TYPES = /* @__PURE__ */ new Set(["Migration"]);
50915
51581
  }
50916
51582
  });
@@ -50975,7 +51641,7 @@ var init_registry = __esm({
50975
51641
  "../packages/manifest/schema-contract/registry.mjs"() {
50976
51642
  "use strict";
50977
51643
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
50978
- cliVersion: "0.72.4",
51644
+ cliVersion: "0.73.1",
50979
51645
  projectFileUploadBatchSize: 32,
50980
51646
  documentRecords: {
50981
51647
  member: {
@@ -62280,7 +62946,7 @@ var init_ui_action_source = __esm({
62280
62946
  // src/project-source/dialogue-group-symbols.ts
62281
62947
  function authoredDialogueGroupSymbols(analysis) {
62282
62948
  return new Map(
62283
- analysis?.dialogueGroups.globals.filter((global) => global.type.name === "DialogueGroup").map((global) => [
62949
+ analysis?.dialogueGroups.globals.filter((global) => global.type.name === "NeoDialogueGroup").map((global) => [
62284
62950
  global.id ?? `__pending__:dialogue-group:${encodeURIComponent(global.source.uri)}:${global.source.range.start.line}:${global.source.range.start.character}:${encodeURIComponent(global.name)}`,
62285
62951
  global.name
62286
62952
  ])
@@ -63453,7 +64119,7 @@ function memberSettings(context, member) {
63453
64119
  } else if (member.kind === "dialogueLookup") {
63454
64120
  if (member.dialogueGroupId) {
63455
64121
  settings.push(
63456
- `group: Reference<DialogueGroup>(id: ${quote(member.dialogueGroupId)})`
64122
+ `group: Reference<NeoDialogueGroup>(id: ${quote(member.dialogueGroupId)})`
63457
64123
  );
63458
64124
  }
63459
64125
  if (member.multiselect) settings.push("selection: .Multi");
@@ -63605,7 +64271,7 @@ function renderMemberType(context, member, enclosingClassId, elementSettings = f
63605
64271
  break;
63606
64272
  }
63607
64273
  case "dialogueLookup":
63608
- value = member.multiselect ? "Set<Dialogue>" : "Dialogue";
64274
+ value = member.multiselect ? "Set<NeoDialogueReference>" : "NeoDialogueReference";
63609
64275
  break;
63610
64276
  case "generic":
63611
64277
  value = genericName(context, member.genericParamId);
@@ -63702,7 +64368,7 @@ function renderType(context, type, enclosingClassId) {
63702
64368
  value = "Color";
63703
64369
  break;
63704
64370
  case "dialogueLookup":
63705
- value = "Dialogue";
64371
+ value = "NeoDialogueReference";
63706
64372
  break;
63707
64373
  case "class": {
63708
64374
  const schemaClass2 = required(context.classes, type.classId, "class");
@@ -63896,11 +64562,7 @@ function renderDefaultValue(context, member, wrapper, enclosingClassId) {
63896
64562
  ).name;
63897
64563
  }
63898
64564
  if ((member.kind === "lookup" || member.kind === "dialogueLookup") && Array.isArray(value)) {
63899
- const renderedType = renderMemberType(
63900
- context,
63901
- member,
63902
- enclosingClassId
63903
- ).replace(/\?$/u, "");
64565
+ const renderedType = referenceTargetType(context, member, enclosingClassId);
63904
64566
  const targetType = member.multiselect ? /^Set<(.+)>$/u.exec(renderedType)?.[1] ?? renderedType : renderedType;
63905
64567
  const refs = value.filter((entry) => typeof entry === "string").map((entry) => `Reference<${targetType}>(id: ${quote(entry)})`);
63906
64568
  if (refs.length === 0 && value.length === 0) return "[]";
@@ -63955,9 +64617,16 @@ function renderDefaultValue(context, member, wrapper, enclosingClassId) {
63955
64617
  function spriteFileSource(context, fileId) {
63956
64618
  return context.fileSymbols.get(fileId) ?? `Reference<NeoImage>(id: ${quote(fileId)})`;
63957
64619
  }
64620
+ function referenceTargetType(context, member, enclosingClassId) {
64621
+ if (member.kind === "dialogueLookup") return "NeoDialogue";
64622
+ return renderMemberType(context, member, enclosingClassId).replace(
64623
+ /\?$/u,
64624
+ ""
64625
+ );
64626
+ }
63958
64627
  function renderNestedValue(context, member, value, enclosingClassId) {
63959
64628
  if (typeof value === "string" && member.kind !== "string" && member.kind !== "decimal" && member.kind !== "enum") {
63960
- return `Reference<${renderMemberType(context, member, enclosingClassId).replace(/\?$/, "")}>(id: ${quote(value)})`;
64629
+ return `Reference<${referenceTargetType(context, member, enclosingClassId)}>(id: ${quote(value)})`;
63961
64630
  }
63962
64631
  return renderDefaultValue(
63963
64632
  context,
@@ -66239,7 +66908,7 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
66239
66908
  const storedStatic = declaration.modifiers.includes("static") && !declaration.modifiers.includes("readonly");
66240
66909
  const settings = annotation(declaration.annotations, "settings");
66241
66910
  const inherited = inheritedMember(context, commonInput.overrideOf);
66242
- const storesSelectionArray = context.enumIdsByName.has(fieldType.name) || fieldType.name === "Dialogue" || Boolean(settings && argument(settings, "collection"));
66911
+ const storesSelectionArray = context.enumIdsByName.has(fieldType.name) || fieldType.name === "NeoDialogueReference" || Boolean(settings && argument(settings, "collection"));
66243
66912
  const common = {
66244
66913
  ...commonInput,
66245
66914
  // A stored static initializer authors the live value binding, never an
@@ -66435,7 +67104,7 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
66435
67104
  assertNoElementSettings(fieldType, ownerClass, declaration, "enum");
66436
67105
  return { ...common, kind: "enum", enumId: enumId2, multiselect: true };
66437
67106
  }
66438
- if (entryType.name === "Dialogue" && multiselect) {
67107
+ if (entryType.name === "NeoDialogueReference" && multiselect) {
66439
67108
  assertNoElementSettings(fieldType, ownerClass, declaration, "dialogue");
66440
67109
  return {
66441
67110
  ...common,
@@ -66504,7 +67173,7 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
66504
67173
  }
66505
67174
  };
66506
67175
  }
66507
- if (name === "Dialogue") {
67176
+ if (name === "NeoDialogueReference") {
66508
67177
  return {
66509
67178
  ...common,
66510
67179
  kind: "dialogueLookup",
@@ -67111,7 +67780,8 @@ function lowerType(context, type, ownerClass) {
67111
67780
  };
67112
67781
  }
67113
67782
  }
67114
- if (type.name === "Dialogue") return { kind: "dialogueLookup", nullable: nullable2 };
67783
+ if (type.name === "NeoDialogueReference")
67784
+ return { kind: "dialogueLookup", nullable: nullable2 };
67115
67785
  if (type.name === "object") return { kind: "unknown", nullable: nullable2 };
67116
67786
  throw new Error(`Unknown Neo type ${JSON.stringify(type.name)}.`);
67117
67787
  }
@@ -67910,7 +68580,7 @@ function manifestTypeForSchemaType(context, type) {
67910
68580
  case "vector3Int":
67911
68581
  return { name: "Vector3Int", nullable: nullable2, arguments: [] };
67912
68582
  case "dialogueLookup":
67913
- return { name: "Dialogue", nullable: nullable2, arguments: [] };
68583
+ return { name: "NeoDialogueReference", nullable: nullable2, arguments: [] };
67914
68584
  case "color":
67915
68585
  return { name: "Color", nullable: nullable2, arguments: [] };
67916
68586
  case "class": {
@@ -69453,7 +70123,7 @@ function lowerSupplementalProjectRecordsV4(state, analysis, projectFileRecords)
69453
70123
  );
69454
70124
  }
69455
70125
  const priorityGlobals = analysis.dialogueGroups.globals.filter(
69456
- (global) => global.type.name === "PriorityGroup"
70126
+ (global) => global.type.name === "NeoPriorityGroup"
69457
70127
  );
69458
70128
  const priorityIds = globalIds(priorityGlobals, "priority-group");
69459
70129
  for (const global of priorityGlobals) {
@@ -69468,7 +70138,7 @@ function lowerSupplementalProjectRecordsV4(state, analysis, projectFileRecords)
69468
70138
  );
69469
70139
  }
69470
70140
  const dialogueGlobals = analysis.dialogueGroups.globals.filter(
69471
- (global) => global.type.name === "DialogueGroup"
70141
+ (global) => global.type.name === "NeoDialogueGroup"
69472
70142
  );
69473
70143
  const dialogueIds = globalIds(dialogueGlobals, "dialogue-group");
69474
70144
  const uiLogicResolver = analysisUILogicResolver(analysis);
@@ -69514,7 +70184,7 @@ function emitProjectGlobal(data, textureNames, audioNames, priorityNames) {
69514
70184
  ],
69515
70185
  [
69516
70186
  "defaultPriorityGroup",
69517
- reference(data.defaultPriorityGroupId, priorityNames, "PriorityGroup")
70187
+ reference(data.defaultPriorityGroupId, priorityNames, "NeoPriorityGroup")
69518
70188
  ]
69519
70189
  ].filter((entry) => entry[1] !== null);
69520
70190
  return `Project Project = new(${args.length === 0 ? "" : `
@@ -69533,14 +70203,14 @@ function emitPriorityGroup(data, recordId, name) {
69533
70203
  }
69534
70204
  assertMemberIdentifier2(option.name, "priority option");
69535
70205
  return ` @id(${quote2(option.id)})
69536
- PriorityOption ${option.name} = new();`;
70206
+ NeoPriorityOption ${option.name} = new();`;
69537
70207
  });
69538
70208
  const annotations = [
69539
70209
  `@id(${quote2(recordId)})`,
69540
70210
  ...isObjectRecord2(data.system) ? [emitSystemAnnotation(data.system)] : []
69541
70211
  ];
69542
70212
  return `${annotations.join("\n")}
69543
- PriorityGroup ${name} = new() {
70213
+ NeoPriorityGroup ${name} = new() {
69544
70214
  ${body.join("\n\n")}
69545
70215
  }
69546
70216
  `;
@@ -69554,13 +70224,13 @@ function emitDialogueGroup(data, recordId, name, priorityNames, dialogueNames, u
69554
70224
  const priority = reference(
69555
70225
  data.priorityGroupIdOverride,
69556
70226
  priorityNames,
69557
- "PriorityGroup"
70227
+ "NeoPriorityGroup"
69558
70228
  );
69559
70229
  if (priority) args.push(["priorityGroup", priority]);
69560
70230
  const parent = reference(
69561
70231
  data.parentDialogueGroupId,
69562
70232
  dialogueNames,
69563
- "DialogueGroup"
70233
+ "NeoDialogueGroup"
69564
70234
  );
69565
70235
  if (parent) args.push(["parent", parent]);
69566
70236
  if (typeof data.collectionMemberId === "string") {
@@ -69585,7 +70255,7 @@ function emitDialogueGroup(data, recordId, name, priorityNames, dialogueNames, u
69585
70255
  ${args.map(([argument2, value]) => ` ${argument2}: ${value},`).join("\n")}
69586
70256
  )`;
69587
70257
  return `@id(${quote2(recordId)})
69588
- DialogueGroup ${name} = ${constructor2}${body.length > 0 ? ` {
70258
+ NeoDialogueGroup ${name} = ${constructor2}${body.length > 0 ? ` {
69589
70259
  ${body.map((entry) => indentNeoSource(entry, 2)).join("\n\n")}
69590
70260
  }` : ";"}
69591
70261
  `;
@@ -69629,7 +70299,7 @@ function collectDialogueGroupFunctions(data, groupId, resolver) {
69629
70299
  const existing = functions.get(functionId);
69630
70300
  if (existing.code !== code) {
69631
70301
  throw new Error(
69632
- `DialogueGroup function ${functionId} has divergent persisted uses.`
70302
+ `NeoDialogueGroup function ${functionId} has divergent persisted uses.`
69633
70303
  );
69634
70304
  }
69635
70305
  }
@@ -69646,7 +70316,7 @@ function requiredStringField(value, field, owner) {
69646
70316
  }
69647
70317
  function emitDialogueGroupFunction(fn) {
69648
70318
  if (fn.id === null) {
69649
- throw new Error(`Pulled DialogueGroup function ${fn.name} has no id.`);
70319
+ throw new Error(`Pulled NeoDialogueGroup function ${fn.name} has no id.`);
69650
70320
  }
69651
70321
  const annotation2 = `@id(${quote2(fn.id)})`;
69652
70322
  if (fn.code === null) {
@@ -69664,7 +70334,7 @@ function emitDialogueGroupUseList(uses) {
69664
70334
  ${uses.map((use) => {
69665
70335
  if (use.id === null) {
69666
70336
  throw new Error(
69667
- `Pulled DialogueGroup condition ${use.functionName} has no id.`
70337
+ `Pulled NeoDialogueGroup condition ${use.functionName} has no id.`
69668
70338
  );
69669
70339
  }
69670
70340
  return ` @id(${quote2(use.id)})
@@ -69699,7 +70369,7 @@ function lowerProjectGlobal(baseValue, global, analysis) {
69699
70369
  args.get("defaultPriorityGroup"),
69700
70370
  globalIds(
69701
70371
  analysis.dialogueGroups.globals.filter(
69702
- (entry) => entry.type.name === "PriorityGroup"
70372
+ (entry) => entry.type.name === "NeoPriorityGroup"
69703
70373
  ),
69704
70374
  "priority-group"
69705
70375
  )
@@ -69714,7 +70384,7 @@ function lowerPriorityGroup(baseValue, global) {
69714
70384
  const initializer = global.initializer.trim();
69715
70385
  const bodyMatch = /^new\s*\(\s*\)\s*\{([\s\S]*)\}$/.exec(initializer);
69716
70386
  if (!bodyMatch) {
69717
- throw new Error(`PriorityGroup ${global.name} must use new() { ... }.`);
70387
+ throw new Error(`NeoPriorityGroup ${global.name} must use new() { ... }.`);
69718
70388
  }
69719
70389
  let body = bodyMatch[1];
69720
70390
  while (body.trim().length > 0) {
@@ -69723,16 +70393,20 @@ function lowerPriorityGroup(baseValue, global) {
69723
70393
  const match = PRIORITY_OPTION_PATTERN.exec(body);
69724
70394
  if (!match) {
69725
70395
  throw new Error(
69726
- `PriorityGroup ${global.name} contains an unsupported option declaration near ${JSON.stringify(body.slice(0, 80))}.`
70396
+ `NeoPriorityGroup ${global.name} contains an unsupported option declaration near ${JSON.stringify(body.slice(0, 80))}.`
69727
70397
  );
69728
70398
  }
69729
70399
  const name = match[2];
69730
70400
  const id2 = match[1] ? JSON.parse(`"${match[1]}"`) : `__pending__:priority-option:${encodeURIComponent(globalId(global, "priority-group"))}:${encodeURIComponent(name)}`;
69731
70401
  if (seenNames.has(name)) {
69732
- throw new Error(`PriorityGroup ${global.name} repeats option ${name}.`);
70402
+ throw new Error(
70403
+ `NeoPriorityGroup ${global.name} repeats option ${name}.`
70404
+ );
69733
70405
  }
69734
70406
  if (seenIds.has(id2)) {
69735
- throw new Error(`PriorityGroup ${global.name} repeats option id ${id2}.`);
70407
+ throw new Error(
70408
+ `NeoPriorityGroup ${global.name} repeats option id ${id2}.`
70409
+ );
69736
70410
  }
69737
70411
  seenNames.add(name);
69738
70412
  seenIds.add(id2);
@@ -69762,14 +70436,14 @@ function sourceDialogueGroupType(global) {
69762
70436
  const authored = parseDialogueGroupInitializer(global.initializer);
69763
70437
  return dialogueGroupType(
69764
70438
  global.name,
69765
- constructorArguments(authored.constructor, "DialogueGroup")
70439
+ constructorArguments(authored.constructor, "NeoDialogueGroup")
69766
70440
  );
69767
70441
  }
69768
70442
  function dialogueGroupType(name, args) {
69769
70443
  const kind = args.get("kind");
69770
70444
  if (kind?.kind !== "contextualEnum") {
69771
70445
  throw new Error(
69772
- `DialogueGroup ${name} requires kind: .Standard, .Lookup, or .Folder.`
70446
+ `NeoDialogueGroup ${name} requires kind: .Standard, .Lookup, or .Folder.`
69773
70447
  );
69774
70448
  }
69775
70449
  const type = kind.name === "Lookup" ? 1 /* Lookup */ : kind.name === "Folder" ? 2 /* Folder */ : kind.name === "Standard" ? 0 /* Standard */ : null;
@@ -69780,7 +70454,7 @@ function dialogueGroupType(name, args) {
69780
70454
  function dialogueGroupDisplayName(expression, symbol) {
69781
70455
  if (expression?.kind !== "litString" || expression.value.trim().length === 0)
69782
70456
  throw new Error(
69783
- `DialogueGroup ${symbol} name must be a non-empty string literal.`
70457
+ `NeoDialogueGroup ${symbol} name must be a non-empty string literal.`
69784
70458
  );
69785
70459
  return expression.value;
69786
70460
  }
@@ -69790,7 +70464,7 @@ function lowerDialogueGroup(baseValue, global, priorityIds, dialogueIds, uiLogic
69790
70464
  Reflect.deleteProperty(baseWithoutLookup, "collectionMemberId");
69791
70465
  Reflect.deleteProperty(baseWithoutLookup, "collectionValueId");
69792
70466
  const authored = parseDialogueGroupInitializer(global.initializer);
69793
- const args = constructorArguments(authored.constructor, "DialogueGroup");
70467
+ const args = constructorArguments(authored.constructor, "NeoDialogueGroup");
69794
70468
  const type = dialogueGroupType(global.name, args);
69795
70469
  const collection = args.get("collection");
69796
70470
  let collectionMemberId;
@@ -69858,7 +70532,7 @@ function lowerDialogueGroupConditions(base, global, authored, uiLogicResolver) {
69858
70532
  for (const fn of authored.functions) {
69859
70533
  if (functions.has(fn.name)) {
69860
70534
  throw new Error(
69861
- `DialogueGroup ${global.name} repeats function ${fn.name}.`
70535
+ `NeoDialogueGroup ${global.name} repeats function ${fn.name}.`
69862
70536
  );
69863
70537
  }
69864
70538
  functions.set(fn.name, fn);
@@ -69874,14 +70548,14 @@ function lowerDialogueGroupConditions(base, global, authored, uiLogicResolver) {
69874
70548
  );
69875
70549
  if (usedIds.has(id2)) {
69876
70550
  throw new Error(
69877
- `DialogueGroup ${global.name} repeats condition id ${id2}.`
70551
+ `NeoDialogueGroup ${global.name} repeats condition id ${id2}.`
69878
70552
  );
69879
70553
  }
69880
70554
  usedIds.add(id2);
69881
70555
  const fn = functions.get(use.functionName);
69882
70556
  if (!fn) {
69883
70557
  throw new Error(
69884
- `DialogueGroup ${global.name} condition ${use.functionName} has no body function.`
70558
+ `NeoDialogueGroup ${global.name} condition ${use.functionName} has no body function.`
69885
70559
  );
69886
70560
  }
69887
70561
  usedFunctions.add(fn.name);
@@ -69919,7 +70593,7 @@ function lowerDialogueGroupConditions(base, global, authored, uiLogicResolver) {
69919
70593
  for (const fn of authored.functions) {
69920
70594
  if (!usedFunctions.has(fn.name)) {
69921
70595
  throw new Error(
69922
- `DialogueGroup ${global.name} function ${fn.name} is not referenced by when.`
70596
+ `NeoDialogueGroup ${global.name} function ${fn.name} is not referenced by when.`
69923
70597
  );
69924
70598
  }
69925
70599
  }
@@ -70000,12 +70674,12 @@ function parseDialogueGroupInitializer(initializer) {
70000
70674
  }
70001
70675
  }
70002
70676
  if (closeIndex < 0) {
70003
- throw new Error("DialogueGroup initializer has an unclosed body.");
70677
+ throw new Error("NeoDialogueGroup initializer has an unclosed body.");
70004
70678
  }
70005
70679
  const close = tokens[closeIndex];
70006
70680
  const trailing = tokens.slice(closeIndex + 1);
70007
70681
  if (trailing.length > 1 || trailing[0] && trailing[0].text !== ";") {
70008
- throw new Error("Nothing may follow a DialogueGroup body.");
70682
+ throw new Error("Nothing may follow a NeoDialogueGroup body.");
70009
70683
  }
70010
70684
  let depth = 0;
70011
70685
  let whenIndex = -1;
@@ -70015,7 +70689,7 @@ function parseDialogueGroupInitializer(initializer) {
70015
70689
  else if (token.text === "}") depth -= 1;
70016
70690
  else if (depth === 0 && token.text === "when") {
70017
70691
  if (whenIndex >= 0) {
70018
- throw new Error("DialogueGroup body may declare when only once.");
70692
+ throw new Error("NeoDialogueGroup body may declare when only once.");
70019
70693
  }
70020
70694
  whenIndex = index;
70021
70695
  }
@@ -70026,7 +70700,7 @@ function parseDialogueGroupInitializer(initializer) {
70026
70700
  if (whenIndex < 0) {
70027
70701
  if (parsedFunctions.length > 0) {
70028
70702
  throw new Error(
70029
- "DialogueGroup body functions require a final when: [...] use list."
70703
+ "NeoDialogueGroup body functions require a final when: [...] use list."
70030
70704
  );
70031
70705
  }
70032
70706
  return {
@@ -70038,7 +70712,7 @@ function parseDialogueGroupInitializer(initializer) {
70038
70712
  const colon = tokens[whenIndex + 1];
70039
70713
  if (colon?.text !== ":") {
70040
70714
  throw new Error(
70041
- "DialogueGroup condition uses must be written as when: [...]."
70715
+ "NeoDialogueGroup condition uses must be written as when: [...]."
70042
70716
  );
70043
70717
  }
70044
70718
  let parenDepth = 0;
@@ -70059,10 +70733,12 @@ function parseDialogueGroupInitializer(initializer) {
70059
70733
  }
70060
70734
  }
70061
70735
  if (semicolonIndex < 0) {
70062
- throw new Error("DialogueGroup when: [...] must end with a semicolon.");
70736
+ throw new Error("NeoDialogueGroup when: [...] must end with a semicolon.");
70063
70737
  }
70064
70738
  if (tokens.slice(semicolonIndex + 1, closeIndex).length > 0) {
70065
- throw new Error("DialogueGroup when: [...] must be the final body entry.");
70739
+ throw new Error(
70740
+ "NeoDialogueGroup when: [...] must be the final body entry."
70741
+ );
70066
70742
  }
70067
70743
  const semicolon = tokens[semicolonIndex];
70068
70744
  return {
@@ -70084,17 +70760,17 @@ function parseDialogueGroupFunctions(source) {
70084
70760
  );
70085
70761
  if (errors.length > 0) {
70086
70762
  throw new Error(
70087
- `Invalid DialogueGroup body: ${errors.map((diagnostic) => diagnostic.message).join(" ")}`
70763
+ `Invalid NeoDialogueGroup body: ${errors.map((diagnostic) => diagnostic.message).join(" ")}`
70088
70764
  );
70089
70765
  }
70090
70766
  const declaration = parsed.declarations[0];
70091
70767
  if (declaration?.kind !== "class") {
70092
- throw new Error("DialogueGroup body could not be parsed.");
70768
+ throw new Error("NeoDialogueGroup body could not be parsed.");
70093
70769
  }
70094
70770
  return declaration.members.map((member) => {
70095
70771
  if (member.kind !== "function") {
70096
70772
  throw new Error(
70097
- "DialogueGroup bodies may contain only zero-argument bool functions and a final when: [...] list."
70773
+ "NeoDialogueGroup bodies may contain only zero-argument bool functions and a final when: [...] list."
70098
70774
  );
70099
70775
  }
70100
70776
  assertDialogueGroupFunctionSignature(member);
@@ -70108,19 +70784,19 @@ function parseDialogueGroupFunctions(source) {
70108
70784
  function assertDialogueGroupFunctionSignature(member) {
70109
70785
  if (member.type.name !== "bool" || member.type.nullable || member.type.typeArguments.length > 0 || member.parameters.length > 0 || member.modifiers.includes("async")) {
70110
70786
  throw new Error(
70111
- `DialogueGroup function ${member.name} must be a synchronous zero-argument bool function.`
70787
+ `NeoDialogueGroup function ${member.name} must be a synchronous zero-argument bool function.`
70112
70788
  );
70113
70789
  }
70114
70790
  if (member.body === void 0 && !member.modifiers.includes("native")) {
70115
70791
  throw new Error(
70116
- `DialogueGroup function ${member.name} requires a body or the native modifier.`
70792
+ `NeoDialogueGroup function ${member.name} requires a body or the native modifier.`
70117
70793
  );
70118
70794
  }
70119
70795
  }
70120
70796
  function parseDialogueGroupUseList(expression) {
70121
70797
  const trimmed = expression.trim();
70122
70798
  if (!trimmed.startsWith("[") || !trimmed.endsWith("]")) {
70123
- throw new Error("DialogueGroup when uses must use bracket list syntax.");
70799
+ throw new Error("NeoDialogueGroup when uses must use bracket list syntax.");
70124
70800
  }
70125
70801
  const body = trimmed.slice(1, -1);
70126
70802
  const pattern = /\s*(?:@id\(\s*("(?:[^"\\]|\\.)*")\s*\)\s*)?([A-Za-z_][A-Za-z0-9_]*)\s*(?:,|$)/gy;
@@ -70132,7 +70808,7 @@ function parseDialogueGroupUseList(expression) {
70132
70808
  if (!match) {
70133
70809
  if (body.slice(consumed).trim().length === 0) break;
70134
70810
  throw new Error(
70135
- `Invalid DialogueGroup condition-use list near ${JSON.stringify(body.slice(consumed))}.`
70811
+ `Invalid NeoDialogueGroup condition-use list near ${JSON.stringify(body.slice(consumed))}.`
70136
70812
  );
70137
70813
  }
70138
70814
  result.push({
@@ -70149,7 +70825,7 @@ function annotationId(annotations) {
70149
70825
  const parsed = JSON.parse(expression);
70150
70826
  if (typeof parsed !== "string" || parsed.length === 0) {
70151
70827
  throw new Error(
70152
- "DialogueGroup function @id must contain a non-empty string."
70828
+ "NeoDialogueGroup function @id must contain a non-empty string."
70153
70829
  );
70154
70830
  }
70155
70831
  return parsed;
@@ -70410,7 +71086,7 @@ var init_supplemental_records = __esm({
70410
71086
  init_project_file_source();
70411
71087
  init_source_format();
70412
71088
  init_ui_action_source();
70413
- PRIORITY_OPTION_PATTERN = /^(?:@id\(\s*"((?:[^"\\]|\\.)+)"\s*\)\s*)?PriorityOption\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*new\s*\(\s*\)\s*;/;
71089
+ PRIORITY_OPTION_PATTERN = /^(?:@id\(\s*"((?:[^"\\]|\\.)+)"\s*\)\s*)?[A-Za-z_][A-Za-z0-9_]*\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*new\s*\(\s*\)\s*;/;
70414
71090
  }
70415
71091
  });
70416
71092
 
@@ -70441,7 +71117,7 @@ function builtinTextVariableMember(receiver, name) {
70441
71117
  function createDialogueLoweringIndexesV4(state, analysis, options = {}) {
70442
71118
  const mainLocale = readMainLocale(state);
70443
71119
  const dialogueGroups = analysis.dialogueGroups.globals.filter(
70444
- (global) => global.type.name === "DialogueGroup"
71120
+ (global) => global.type.name === "NeoDialogueGroup"
70445
71121
  );
70446
71122
  const dialogueGroupIds = globalIds2(dialogueGroups, "dialogue-group");
70447
71123
  const lookupDialogueGroupIds = new Set(
@@ -71819,7 +72495,7 @@ function lowerDialogueGroupSettings(context, member, base) {
71819
72495
  const expression = constructorExpression(member.arguments, "group");
71820
72496
  if (expression === null) return null;
71821
72497
  const old = isObjectRecord2(base.dialogueGroupSettings) ? base.dialogueGroupSettings : {};
71822
- const referencedGroupId = referenceId3(expression, "DialogueGroup");
72498
+ const referencedGroupId = referenceId3(expression, "NeoDialogueGroup");
71823
72499
  if (referencedGroupId !== null) {
71824
72500
  if (!context.groupPaths.byId.has(referencedGroupId)) {
71825
72501
  throw dialogueSourceError(
@@ -71835,10 +72511,10 @@ function lowerDialogueGroupSettings(context, member, base) {
71835
72511
  member.arguments,
71836
72512
  "priority"
71837
72513
  );
71838
- const priorityOptionId = priorityExpression === null ? null : referenceId3(priorityExpression, "PriorityOption");
72514
+ const priorityOptionId = priorityExpression === null ? null : referenceId3(priorityExpression, "NeoPriorityOption");
71839
72515
  if (priorityExpression !== null && priorityOptionId === null) {
71840
72516
  throw dialogueSourceError(
71841
- 'Trigger priority must be authored as Reference<PriorityOption>(id: "...").',
72517
+ 'Trigger priority must be authored as Reference<NeoPriorityOption>(id: "...").',
71842
72518
  prioritySource
71843
72519
  );
71844
72520
  }
@@ -72723,7 +73399,7 @@ var init_dialogue_lower = __esm({
72723
73399
  required: required2
72724
73400
  };
72725
73401
  }
72726
- if (type.name === "Dialogue") {
73402
+ if (type.name === "NeoDialogueReference") {
72727
73403
  return { type: 18 /* DialogueLookup */, required: required2 };
72728
73404
  }
72729
73405
  return null;
@@ -72864,7 +73540,8 @@ function projectSchemaManifest(input, options = {}) {
72864
73540
  (item, index) => enumType(item, environment, `enums[${index}]`)
72865
73541
  )
72866
73542
  ];
72867
- const rootType = createRootType(rootMemberIds, environment);
73543
+ const dialogues = neoScriptDialogueTypes(options.dialogueGroups ?? []);
73544
+ const rootType = createRootType(rootMemberIds, environment, dialogues.member);
72868
73545
  declaredTypes.push(rootType);
72869
73546
  const roots = options.roots ?? [
72870
73547
  {
@@ -72883,7 +73560,7 @@ function projectSchemaManifest(input, options = {}) {
72883
73560
  return {
72884
73561
  project: {
72885
73562
  version: options.version ?? `manifest:${nextManifestProjectionVersion++}`,
72886
- types: languageTypes,
73563
+ types: [...languageTypes, ...dialogues.types],
72887
73564
  globals: options.globals ?? [],
72888
73565
  roots,
72889
73566
  listIndexes: members.flatMap(
@@ -73018,7 +73695,7 @@ function staticDefaultWritability(classId, environment) {
73018
73695
  resolvedAllowedStorage(classId, environment)
73019
73696
  );
73020
73697
  }
73021
- function createRootType(ids, environment) {
73698
+ function createRootType(ids, environment, dialogues) {
73022
73699
  const definitions = [
73023
73700
  ["Assets", ids.assets, false, "immutable"],
73024
73701
  ["Save", ids.save, true, "save"],
@@ -73041,6 +73718,7 @@ function createRootType(ids, environment) {
73041
73718
  ...sourceLocation(member.source, environment, `root.${name}.source`)
73042
73719
  });
73043
73720
  }
73721
+ members.push(dialogues);
73044
73722
  return {
73045
73723
  id: "__root__",
73046
73724
  name: "Root",
@@ -73817,8 +74495,7 @@ function memberType(member, environment, visiting, field) {
73817
74495
  return member.multiselect === true ? { kind: "set", elementType: entryType, nullable: nullable2 } : { ...entryType, nullable: nullable2 };
73818
74496
  }
73819
74497
  if (kind === "dialogueLookup") {
73820
- const dialogue = primitive("DialogueRef", false);
73821
- return member.multiselect === true ? { kind: "set", elementType: dialogue, nullable: nullable2 } : { ...dialogue, nullable: nullable2 };
74498
+ return member.multiselect === true ? { kind: "set", elementType: primitive("string", false), nullable: nullable2 } : { ...primitive("NeoDialogueReference", false), nullable: nullable2 };
73822
74499
  }
73823
74500
  if (kind === "computed") {
73824
74501
  return manifestType2(member.returnType, environment, `${field}.returnType`);
@@ -74300,7 +74977,7 @@ function manifestPrimitive(kind) {
74300
74977
  case "vector3Int":
74301
74978
  return "Vector3Int";
74302
74979
  case "dialogueLookup":
74303
- return "DialogueRef";
74980
+ return "NeoDialogueReference";
74304
74981
  case "color":
74305
74982
  return "Color";
74306
74983
  default:
@@ -74467,6 +75144,7 @@ var init_project_schema_manifest = __esm({
74467
75144
  init_project2();
74468
75145
  init_project2();
74469
75146
  init_language_spec();
75147
+ init_dialogue_types();
74470
75148
  nextManifestProjectionVersion = 1;
74471
75149
  }
74472
75150
  });
@@ -74598,6 +75276,58 @@ var init_interface_types = __esm({
74598
75276
  }
74599
75277
  });
74600
75278
 
75279
+ // ../src/models/dialogue/dialogue-group-language.ts
75280
+ function dialogueGroupLanguageContract(group) {
75281
+ return {
75282
+ id: group.id,
75283
+ name: group.name,
75284
+ type: group.type,
75285
+ parentDialogueGroupId: group.parentDialogueGroupId ?? null,
75286
+ collectionMemberId: group.type === 1 /* Lookup */ ? group.collectionMemberId : null
75287
+ };
75288
+ }
75289
+ function storedDialogueGroupSources(groups, memberById2, classById) {
75290
+ const sources2 = [];
75291
+ for (const group of groups) {
75292
+ const lookup = group.type === 1 /* Lookup */ ? lookupEntry(group.collectionMemberId, memberById2, classById) : void 0;
75293
+ sources2.push({
75294
+ id: group.id,
75295
+ name: group.name,
75296
+ parentId: group.parentDialogueGroupId ?? null,
75297
+ kind: KINDS[group.type],
75298
+ ...lookup ? { lookup } : {}
75299
+ });
75300
+ }
75301
+ return sources2;
75302
+ }
75303
+ function lookupEntry(collectionMemberId, memberById2, classById) {
75304
+ const collection = memberById2(collectionMemberId);
75305
+ if (!isMemberListBase(collection) && !isMemberDictionaryBase(collection))
75306
+ return void 0;
75307
+ const entry = memberById2(collection.entryMemberId);
75308
+ if (!isMemberClassBase(entry)) return void 0;
75309
+ const entryClass = classById(entry.classId);
75310
+ if (!entryClass) return void 0;
75311
+ return {
75312
+ collection: collection.name,
75313
+ entryType: { kind: "named", typeId: entryClass.id },
75314
+ entryTypeName: entryClass.name
75315
+ };
75316
+ }
75317
+ var KINDS;
75318
+ var init_dialogue_group_language = __esm({
75319
+ "../src/models/dialogue/dialogue-group-language.ts"() {
75320
+ "use strict";
75321
+ init_members();
75322
+ init_dialogue_group_types();
75323
+ KINDS = {
75324
+ [0 /* Standard */]: "standard",
75325
+ [1 /* Lookup */]: "lookup",
75326
+ [2 /* Folder */]: "folder"
75327
+ };
75328
+ }
75329
+ });
75330
+
74601
75331
  // ../src/runtime/neoscript/analyzer-types.ts
74602
75332
  function createAnalyzerSchemaIndex(context) {
74603
75333
  return projectSchemaIndexFor({
@@ -74817,8 +75547,15 @@ function createNeoScriptProjectInScope(context) {
74817
75547
  })
74818
75548
  });
74819
75549
  }
74820
- const rootType = createRootType2(context);
74821
- languageTypes.push(rootType);
75550
+ const dialogues = neoScriptDialogueTypes(
75551
+ storedDialogueGroupSources(
75552
+ context.vm.dialogueGroups ?? [],
75553
+ (id2) => analyzerMemberById(context, id2),
75554
+ (id2) => analyzerSchemaIndex(context).classesById.get(id2)
75555
+ )
75556
+ );
75557
+ const rootType = createRootType2(context, dialogues.member);
75558
+ languageTypes.push(rootType, ...dialogues.types);
74822
75559
  if (context.dialogueContext) {
74823
75560
  languageTypes.push(createDialogueContextType(context));
74824
75561
  }
@@ -75346,7 +76083,7 @@ function interfaceMemberToSymbol(neoInterface, key, member, context, inherited)
75346
76083
  ...inheritedFrom ? { inheritedFrom } : {}
75347
76084
  };
75348
76085
  }
75349
- function createRootType2(context) {
76086
+ function createRootType2(context, dialogues) {
75350
76087
  const members = [];
75351
76088
  for (const [index, root] of PROJECT_ROOTS.entries()) {
75352
76089
  const name = root.key;
@@ -75371,6 +76108,7 @@ function createRootType2(context) {
75371
76108
  )
75372
76109
  });
75373
76110
  }
76111
+ members.push(dialogues);
75374
76112
  return {
75375
76113
  id: AnalyzerRootClassId,
75376
76114
  name: "Root",
@@ -75473,11 +76211,11 @@ function memberRuntimeType(record7, context, seen = /* @__PURE__ */ new Set(), g
75473
76211
  if (isMemberDialogueLookupBase(member) && isMultiSelectionMember(member)) {
75474
76212
  return {
75475
76213
  kind: "set",
75476
- elementType: primitive2("DialogueRef", true),
76214
+ elementType: primitive2("string", true),
75477
76215
  nullable: !required2
75478
76216
  };
75479
76217
  }
75480
- return primitive2("DialogueRef", required2);
76218
+ return primitive2("NeoDialogueReference", required2);
75481
76219
  case 14 /* Vector2 */:
75482
76220
  return primitive2("Vector2", required2);
75483
76221
  case 15 /* Vector2Int */:
@@ -75725,7 +76463,7 @@ function toLanguageType(type, context, genericEnvironment) {
75725
76463
  case 12 /* Audio */:
75726
76464
  return primitive2("AudioClipInfo", required2);
75727
76465
  case 18 /* DialogueLookup */:
75728
- return primitive2("DialogueRef", required2);
76466
+ return primitive2("NeoDialogueReference", required2);
75729
76467
  case 14 /* Vector2 */:
75730
76468
  return primitive2("Vector2", required2);
75731
76469
  case 15 /* Vector2Int */:
@@ -75925,7 +76663,9 @@ function projectLanguageVersion(context) {
75925
76663
  ...context.vm.projectFiles ?? [],
75926
76664
  // P43 §6. Editing a constructor's parameters changes what a `new Foo(…)`
75927
76665
  // call site resolves to, so an open editor's cached context must rebuild.
75928
- ...context.constructors ?? []
76666
+ ...context.constructors ?? [],
76667
+ // P105 §2.6. Group names, parents, and kinds shape `root.Dialogues`.
76668
+ ...context.vm.dialogueGroups ?? []
75929
76669
  ];
75930
76670
  return [
75931
76671
  `adapter:${NEOSCRIPT_COMPILER_ADAPTER_REVISION}`,
@@ -76133,8 +76873,10 @@ var init_neoscript_language_context_adapter = __esm({
76133
76873
  init_variant_member();
76134
76874
  init_project_root_members();
76135
76875
  init_project_file_registry();
76876
+ init_dialogue_types();
76877
+ init_dialogue_group_language();
76136
76878
  init_analyzer_types();
76137
- NEOSCRIPT_COMPILER_ADAPTER_REVISION = 5;
76879
+ NEOSCRIPT_COMPILER_ADAPTER_REVISION = 6;
76138
76880
  UNKNOWN_TYPE2 = {
76139
76881
  kind: "primitive",
76140
76882
  name: "unknown"
@@ -86405,6 +87147,26 @@ function evalFunction(fn, scope, ctx) {
86405
87147
  const pointer = evalPointer(fn.info.pointer, scope, ctx);
86406
87148
  return dialogueMemoryVisitCount(pointer, ctx) > 0;
86407
87149
  }
87150
+ case "dialogueGroup" /* dialogueGroup */: {
87151
+ if (fn.info.valuePointer !== void 0)
87152
+ evalPointer(fn.info.valuePointer, scope, ctx);
87153
+ if (fn.info.onFinishPointer !== void 0)
87154
+ evalPointer(fn.info.onFinishPointer, scope, ctx);
87155
+ return false;
87156
+ }
87157
+ case "dialogue" /* dialogue */: {
87158
+ const idPointer = fn.info.dialogueIdPointer;
87159
+ const dialogueId = evalPointer(idPointer, scope, ctx);
87160
+ if (dialogueId === null && idPointer.type === "keyOf" /* keyOf */ && idPointer.optional === true)
87161
+ return null;
87162
+ if (typeof dialogueId !== "string")
87163
+ throw new NSGetterRuntimeError(
87164
+ `${fn.info.op} needs a dialogue id string, but got ${dialogueId === null ? "null" : typeof dialogueId}.`
87165
+ );
87166
+ if (fn.info.onFinishPointer !== void 0)
87167
+ evalPointer(fn.info.onFinishPointer, scope, ctx);
87168
+ return false;
87169
+ }
86408
87170
  case "vectorConstructor" /* vectorConstructor */: {
86409
87171
  return evalVectorConstructor(
86410
87172
  fn.info.vectorType,
@@ -95496,6 +96258,7 @@ function createAnalyzerProject(ctx) {
95496
96258
  return {
95497
96259
  project: ctx.project,
95498
96260
  projectFiles: [...ctx.projectFiles ?? []],
96261
+ dialogueGroups: [...ctx.dialogueGroups ?? []],
95499
96262
  members,
95500
96263
  classes: [...ctx.classes],
95501
96264
  enums: [...ctx.enums],
@@ -96823,6 +97586,7 @@ function compileDelegateClosureValue(code, signature) {
96823
97586
  const compiled = compileNSGetter(`return ${code};`, {
96824
97587
  project: signature.project,
96825
97588
  projectFiles: [...signature.projectFiles ?? []],
97589
+ dialogueGroups: signature.dialogueGroups ?? [],
96826
97590
  members: [...signature.members],
96827
97591
  classes: [...signature.classes],
96828
97592
  enums: [...signature.enums],
@@ -96908,6 +97672,7 @@ function compilationProjectContext(args, members = args.members) {
96908
97672
  return {
96909
97673
  project: args.project,
96910
97674
  projectFiles: args.projectFiles ?? [],
97675
+ dialogueGroups: args.dialogueGroups ?? [],
96911
97676
  members: [...members],
96912
97677
  classes: [...args.classes],
96913
97678
  enums: [...args.enums],
@@ -97558,6 +98323,7 @@ function compilationProjectForDocument(document, state) {
97558
98323
  state.compilationProject ??= createNeoScriptCompilationProject({
97559
98324
  project: document.project,
97560
98325
  projectFiles: document.projectFiles,
98326
+ dialogueGroups: document.dialogueGroups,
97561
98327
  members: document.members,
97562
98328
  classes: document.classes,
97563
98329
  enums: document.enums,
@@ -97651,6 +98417,7 @@ function compileValueInitializerDependency(document, valueId, compilationProject
97651
98417
  compileValueRowInitializerBody({
97652
98418
  project: document.project,
97653
98419
  projectFiles: document.projectFiles,
98420
+ dialogueGroups: document.dialogueGroups,
97654
98421
  members: document.members,
97655
98422
  classes: document.classes,
97656
98423
  enums: document.enums,
@@ -97669,6 +98436,7 @@ function compileMemberInitializerDependency(document, memberId, compilationProje
97669
98436
  const compileArgs = {
97670
98437
  project: document.project,
97671
98438
  projectFiles: document.projectFiles,
98439
+ dialogueGroups: document.dialogueGroups,
97672
98440
  members: document.members,
97673
98441
  classes: document.classes,
97674
98442
  enums: document.enums,
@@ -98136,7 +98904,7 @@ function isDialogueProps(value) {
98136
98904
  function isDialogue(value) {
98137
98905
  return isDialogueProps(value);
98138
98906
  }
98139
- var init_dialogue_types = __esm({
98907
+ var init_dialogue_types2 = __esm({
98140
98908
  "../src/models/dialogue/dialogue-types.ts"() {
98141
98909
  "use strict";
98142
98910
  init_core_types();
@@ -99462,7 +100230,7 @@ var init_project_document_read = __esm({
99462
100230
  init_constructors2();
99463
100231
  init_variants();
99464
100232
  init_dialogue_group_types();
99465
- init_dialogue_types();
100233
+ init_dialogue_types2();
99466
100234
  init_priority_types();
99467
100235
  init_enum();
99468
100236
  init_neoscript();
@@ -99772,7 +100540,9 @@ function collectCompilerReferencesInto(value, field, ids, names, constructedClas
99772
100540
  function isCompilerReferenceField(field) {
99773
100541
  return /(?:member|class|enum|interface|constructor|variant)(?:Type)?Ids?$/i.test(
99774
100542
  field
99775
- ) || field === "baseTypeIds" || field === "collectionValueId" || field === "fileId" || field === "primaryLinkedValueId" || field === "recordIds" || field === "valueId";
100543
+ ) || field === "baseTypeIds" || field === "collectionValueId" || field === "fileId" || // P105 §2.5. Dialogue-group calls name their group by `groupId`. The
100544
+ // IR kind is new, so the derived-edge extractor version doesn't change.
100545
+ field === "groupId" || field === "primaryLinkedValueId" || field === "recordIds" || field === "valueId";
99776
100546
  }
99777
100547
  function collectChangedContractIds(args) {
99778
100548
  const impactedIds = /* @__PURE__ */ new Set();
@@ -99802,7 +100572,26 @@ function collectChangedContractIds(args) {
99802
100572
  );
99803
100573
  const currentSchemaRecords = schemaRecordsByKind(args.currentDocument);
99804
100574
  const postSchemaRecords = schemaRecordsByKind(args.postDocument);
100575
+ const currentGroups = new DialogueGroupTree(args.currentDocument);
100576
+ const postGroups = new DialogueGroupTree(args.postDocument);
99805
100577
  for (const change of args.changes) {
100578
+ if (change.recordKind === "dialogue-group") {
100579
+ const current2 = currentGroups.byId.get(change.recordId);
100580
+ const next2 = postGroups.byId.get(change.recordId);
100581
+ if (current2 !== void 0 && next2 !== void 0 && canonicalJsonStringify(dialogueGroupLanguageContract(current2)) === canonicalJsonStringify(dialogueGroupLanguageContract(next2))) {
100582
+ continue;
100583
+ }
100584
+ currentGroups.addSubtree(change.recordId, impactedIds);
100585
+ postGroups.addSubtree(change.recordId, impactedIds);
100586
+ for (const group of [current2, next2]) {
100587
+ if (group !== void 0) {
100588
+ impactedTypeNames.add(
100589
+ generatedCSharpTypeName(group.name, "DialogueGroup")
100590
+ );
100591
+ }
100592
+ }
100593
+ continue;
100594
+ }
99806
100595
  if (change.recordKind === "class" || change.recordKind === "enum" || change.recordKind === "interface") {
99807
100596
  const kind = change.recordKind;
99808
100597
  const current2 = currentSchemaRecords[kind].get(change.recordId);
@@ -100322,7 +101111,7 @@ function withoutFields(value, ignored) {
100322
101111
  Object.entries(value).filter(([field]) => !ignored.has(field))
100323
101112
  );
100324
101113
  }
100325
- var NON_CONTRACT_MEMBER_FIELDS, NS_PROPERTY_BODY_FIELDS, NS_FUNCTION_BODY_FIELDS, NO_PLACEMENTS, classPlacementIndexes;
101114
+ var NON_CONTRACT_MEMBER_FIELDS, NS_PROPERTY_BODY_FIELDS, NS_FUNCTION_BODY_FIELDS, DialogueGroupTree, NO_PLACEMENTS, classPlacementIndexes;
100326
101115
  var init_neo_script_recompile_scope = __esm({
100327
101116
  "../src/database/neo-script-recompile-scope.ts"() {
100328
101117
  "use strict";
@@ -100330,6 +101119,8 @@ var init_neo_script_recompile_scope = __esm({
100330
101119
  init_neo_script_derived_bodies();
100331
101120
  init_canonical_json();
100332
101121
  init_lexer();
101122
+ init_generated_csharp_identifiers();
101123
+ init_dialogue_group_language();
100333
101124
  init_member_kind_enum();
100334
101125
  init_member_kinds();
100335
101126
  init_inheritance();
@@ -100363,6 +101154,31 @@ var init_neo_script_recompile_scope = __esm({
100363
101154
  "bodyMode",
100364
101155
  "uiAction"
100365
101156
  ]);
101157
+ DialogueGroupTree = class {
101158
+ byId = /* @__PURE__ */ new Map();
101159
+ children = /* @__PURE__ */ new Map();
101160
+ constructor(document) {
101161
+ for (const group of document.dialogueGroups ?? []) {
101162
+ this.byId.set(group.id, group);
101163
+ const parentId = group.parentDialogueGroupId;
101164
+ if (parentId === null || parentId === void 0) continue;
101165
+ const siblings = this.children.get(parentId) ?? [];
101166
+ siblings.push(group.id);
101167
+ this.children.set(parentId, siblings);
101168
+ }
101169
+ }
101170
+ addSubtree(id2, ids) {
101171
+ ids.add(id2);
101172
+ const queue = [id2];
101173
+ for (const groupId of queue) {
101174
+ for (const child2 of this.children.get(groupId) ?? []) {
101175
+ if (ids.has(child2)) continue;
101176
+ ids.add(child2);
101177
+ queue.push(child2);
101178
+ }
101179
+ }
101180
+ }
101181
+ };
100366
101182
  NO_PLACEMENTS = /* @__PURE__ */ new Set();
100367
101183
  classPlacementIndexes = /* @__PURE__ */ new WeakMap();
100368
101184
  }
@@ -101198,7 +102014,7 @@ var init_project_record_validation = __esm({
101198
102014
  init_packed_value_record_validation();
101199
102015
  init_enum();
101200
102016
  init_interface_types();
101201
- init_dialogue_types();
102017
+ init_dialogue_types2();
101202
102018
  init_dialogue_group_types();
101203
102019
  init_priority_types();
101204
102020
  init_files();
@@ -106009,6 +106825,7 @@ function resolveDialogueCompileContext(args) {
106009
106825
  classes: args.classes,
106010
106826
  enums: args.enums,
106011
106827
  interfaces: args.interfaces ?? [],
106828
+ dialogueGroups: args.dialogueGroups,
106012
106829
  thisClass: resolveNeoSchemaClassFromTypeInfo(thisClass, args.classes),
106013
106830
  returnTypeInfo: args.returnTypeInfo,
106014
106831
  ...valueAliases.length ? { valueAliases } : {},
@@ -106078,6 +106895,7 @@ function resolveDialogueGroupCompileContext(args) {
106078
106895
  classes: args.classes,
106079
106896
  enums: args.enums,
106080
106897
  interfaces: args.interfaces ?? [],
106898
+ dialogueGroups: args.dialogueGroups,
106081
106899
  thisClass,
106082
106900
  returnTypeInfo: args.returnTypeInfo,
106083
106901
  dialogueContext: {
@@ -106110,7 +106928,15 @@ function compileDialogueLogic(request, projectData, reuseProject) {
106110
106928
  "Invalid dialogue logic compile body: expected ICompileDialogueLogicRequest."
106111
106929
  );
106112
106930
  }
106113
- const { project, members, classes, values, enums, interfaces } = projectData;
106931
+ const {
106932
+ project,
106933
+ members,
106934
+ classes,
106935
+ values,
106936
+ enums,
106937
+ interfaces,
106938
+ dialogueGroups
106939
+ } = projectData;
106114
106940
  if (request.target === 0 /* Condition */) {
106115
106941
  const ctx2 = request.dialogueGroup ? resolveDialogueGroupCompileContext({
106116
106942
  project,
@@ -106119,6 +106945,7 @@ function compileDialogueLogic(request, projectData, reuseProject) {
106119
106945
  values,
106120
106946
  enums,
106121
106947
  interfaces,
106948
+ dialogueGroups,
106122
106949
  dialogueGroup: request.dialogueGroup,
106123
106950
  returnTypeInfo: { type: 1 /* Bool */, required: true }
106124
106951
  }) : resolveDialogueCompileContext({
@@ -106128,6 +106955,7 @@ function compileDialogueLogic(request, projectData, reuseProject) {
106128
106955
  values,
106129
106956
  enums,
106130
106957
  interfaces,
106958
+ dialogueGroups,
106131
106959
  dialogue: request.dialogue ?? {},
106132
106960
  node: request.node,
106133
106961
  returnTypeInfo: { type: 1 /* Bool */, required: true }
@@ -106162,6 +106990,7 @@ function compileDialogueLogic(request, projectData, reuseProject) {
106162
106990
  values,
106163
106991
  enums,
106164
106992
  interfaces,
106993
+ dialogueGroups,
106165
106994
  dialogue: request.dialogue ?? {},
106166
106995
  node: request.node,
106167
106996
  returnTypeInfo: sourceBacked ? request.textVariable.typeInfo : { type: 3 /* String */, required: true }
@@ -106191,6 +107020,7 @@ function compileDialogueLogic(request, projectData, reuseProject) {
106191
107020
  values,
106192
107021
  enums,
106193
107022
  interfaces,
107023
+ dialogueGroups,
106194
107024
  dialogue: request.dialogue ?? {},
106195
107025
  node: request.node,
106196
107026
  returnTypeInfo: { type: 0 /* Null */, required: true }
@@ -108377,7 +109207,7 @@ var init_general_function_call_ir_source_recompile = __esm({
108377
109207
  "use strict";
108378
109208
  init_members();
108379
109209
  init_core();
108380
- init_dialogue_types();
109210
+ init_dialogue_types2();
108381
109211
  init_logic_types();
108382
109212
  init_inheritance();
108383
109213
  init_project_content_hash();
@@ -108875,6 +109705,9 @@ function neoScriptCompilationProjectContract(document) {
108875
109705
  name: file.name,
108876
109706
  fileType: file.fileType
108877
109707
  })),
109708
+ dialogueGroups: (document.dialogueGroups ?? []).map(
109709
+ dialogueGroupLanguageContract
109710
+ ),
108878
109711
  members: document.members.map(
108879
109712
  (member) => neoScriptMemberContractProjection(
108880
109713
  member
@@ -108925,6 +109758,7 @@ var init_project_fingerprint = __esm({
108925
109758
  "use strict";
108926
109759
  init_strict_ir();
108927
109760
  init_neo_script_recompile_scope();
109761
+ init_dialogue_group_language();
108928
109762
  init_compiler_adapter();
108929
109763
  }
108930
109764
  });
@@ -113756,6 +114590,7 @@ function prepareServerOwnedValueInitializerBodies(args) {
113756
114590
  const compilationProject = cachedServerCompilationProject({
113757
114591
  project: document.project,
113758
114592
  projectFiles: document.projectFiles,
114593
+ dialogueGroups: document.dialogueGroups,
113759
114594
  members: document.members,
113760
114595
  classes: document.classes,
113761
114596
  enums: document.enums,
@@ -113781,6 +114616,7 @@ function prepareServerOwnedValueInitializerBodies(args) {
113781
114616
  compileValueRowInitializerBody({
113782
114617
  project: document.project,
113783
114618
  projectFiles: document.projectFiles,
114619
+ dialogueGroups: document.dialogueGroups,
113784
114620
  members: document.members,
113785
114621
  classes: document.classes,
113786
114622
  enums: document.enums,
@@ -113996,6 +114832,7 @@ function compileInlineDelegateConstructorArguments(args) {
113996
114832
  compiled[argumentKey] = compileDelegateClosureValue(argument2.code, {
113997
114833
  project: document.project,
113998
114834
  projectFiles: document.projectFiles,
114835
+ dialogueGroups: document.dialogueGroups,
113999
114836
  members: document.members,
114000
114837
  classes: document.classes,
114001
114838
  enums: document.enums,
@@ -114045,6 +114882,7 @@ function createDelegateValueBodyCompiler(postDocument, targetIds) {
114045
114882
  compiled.value = compileDelegateClosureValue(row.value.code, {
114046
114883
  project: document.project,
114047
114884
  projectFiles: document.projectFiles,
114885
+ dialogueGroups: document.dialogueGroups,
114048
114886
  members: document.members,
114049
114887
  classes: document.classes,
114050
114888
  enums: document.enums,
@@ -114225,6 +115063,7 @@ function prepareServerOwnedConstructorBodies(args) {
114225
115063
  ),
114226
115064
  project: document.project,
114227
115065
  projectFiles: document.projectFiles,
115066
+ dialogueGroups: document.dialogueGroups,
114228
115067
  members: document.members,
114229
115068
  classes: document.classes,
114230
115069
  enums: document.enums,
@@ -114406,6 +115245,7 @@ function compileOneAuthoredMember(args) {
114406
115245
  scriptSources: args.scriptSources,
114407
115246
  project: args.document.project,
114408
115247
  projectFiles: args.document.projectFiles,
115248
+ dialogueGroups: args.document.dialogueGroups,
114409
115249
  members: args.members,
114410
115250
  classes: args.document.classes,
114411
115251
  enums: args.document.enums,
@@ -123071,6 +123911,7 @@ function replayStoredConstructionV4(args) {
123071
123911
  const compilationProject = args.compilationProject ?? (args.compileDocumentBodies === true ? createNeoScriptCompilationProject({
123072
123912
  project: document.project,
123073
123913
  projectFiles: document.projectFiles,
123914
+ dialogueGroups: document.dialogueGroups,
123074
123915
  members: document.members,
123075
123916
  classes: document.classes,
123076
123917
  enums: document.enums,
@@ -123127,6 +123968,7 @@ function replayStoredConstructionV4(args) {
123127
123968
  compileValueRowInitializerBody({
123128
123969
  project: document.project,
123129
123970
  projectFiles: document.projectFiles,
123971
+ dialogueGroups: document.dialogueGroups,
123130
123972
  members: document.members,
123131
123973
  classes: document.classes,
123132
123974
  enums: document.enums,
@@ -123198,6 +124040,7 @@ function compilePulledUncompiledConstructorsV4(document, compilationProject, rep
123198
124040
  const project = compilationProject ?? createNeoScriptCompilationProject({
123199
124041
  project: document.project,
123200
124042
  projectFiles: document.projectFiles,
124043
+ dialogueGroups: document.dialogueGroups,
123201
124044
  members: document.members,
123202
124045
  classes: document.classes,
123203
124046
  enums: document.enums,
@@ -123207,6 +124050,7 @@ function compilePulledUncompiledConstructorsV4(document, compilationProject, rep
123207
124050
  const compileArgs = {
123208
124051
  project: document.project,
123209
124052
  projectFiles: document.projectFiles,
124053
+ dialogueGroups: document.dialogueGroups,
123210
124054
  members: document.members,
123211
124055
  classes: document.classes,
123212
124056
  enums: document.enums,
@@ -123223,6 +124067,7 @@ function compilePulledProjectDocumentForEvaluationV4(document, compilationProjec
123223
124067
  const sharedCompilationProject = compilationProject ?? createNeoScriptCompilationProject({
123224
124068
  project: document.project,
123225
124069
  projectFiles: document.projectFiles,
124070
+ dialogueGroups: document.dialogueGroups,
123226
124071
  members: document.members,
123227
124072
  classes: document.classes,
123228
124073
  enums: document.enums,
@@ -123233,6 +124078,7 @@ function compilePulledProjectDocumentForEvaluationV4(document, compilationProjec
123233
124078
  const compileArgs = {
123234
124079
  project: document.project,
123235
124080
  projectFiles: document.projectFiles,
124081
+ dialogueGroups: document.dialogueGroups,
123236
124082
  members: document.members,
123237
124083
  classes: document.classes,
123238
124084
  enums: document.enums,
@@ -129560,7 +130406,7 @@ function validateReferenceContract(context, member, target, ownerValueId) {
129560
130406
  `Dialogue member ${member.name} requires a dialogue target.`
129561
130407
  );
129562
130408
  }
129563
- if (target.genericTypeName && target.genericTypeName !== "Dialogue" && target.genericTypeName !== target.typeName) {
130409
+ if (target.genericTypeName && target.genericTypeName !== "NeoDialogue" && target.genericTypeName !== target.typeName) {
129564
130410
  throw new Error(
129565
130411
  `Reference<${target.genericTypeName}> does not accept dialogue ${target.id}.`
129566
130412
  );
@@ -129583,7 +130429,7 @@ function lookupEntryTypeName(context, member) {
129583
130429
  if (entry.kind === "class")
129584
130430
  return context.classes.get(entry.classId)?.name ?? null;
129585
130431
  if (entry.kind === "enum") return null;
129586
- if (entry.kind === "dialogueLookup") return "Dialogue";
130432
+ if (entry.kind === "dialogueLookup") return "NeoDialogueReference";
129587
130433
  return entry.kind;
129588
130434
  }
129589
130435
  function referenceTypeNameAssignable(context, actualName, expectedName) {
@@ -130105,7 +130951,7 @@ function freshConstructionReplaysDeclaredDefault(resolved, child2, defaultValue)
130105
130951
  function classMemberByName(context, classId, name) {
130106
130952
  const memberId = classMemberIdByName(context, classId, name);
130107
130953
  if (memberId !== null) return requiredMember(context, memberId);
130108
- throw new Error(
130954
+ throw new MissingStoredMemberError(
130109
130955
  `Class ${context.classes.get(classId)?.name ?? classId} has no stored member ${name}.`
130110
130956
  );
130111
130957
  }
@@ -131711,7 +132557,7 @@ function storedSchemaTypeName(context, type, environment, valueId) {
131711
132557
  case "lookup":
131712
132558
  return storedSchemaTypeName(context, type.entryType, environment);
131713
132559
  case "dialogueLookup":
131714
- return "Dialogue";
132560
+ return "NeoDialogueReference";
131715
132561
  case "delegate":
131716
132562
  return "object";
131717
132563
  case "action":
@@ -132288,7 +133134,7 @@ function referenceValue(context, member, body, dialogue) {
132288
133134
  }
132289
133135
  const symbol = context.localValues?.byValueId.get(id2)?.name ?? context.symbolsByValueId.get(id2);
132290
133136
  if (symbol !== void 0) return `Reference(${symbol})`;
132291
- const type = dialogue ? "Dialogue" : memberReferenceType(context, member);
133137
+ const type = dialogue ? "NeoDialogue" : memberReferenceType(context, member);
132292
133138
  if (!dialogue) {
132293
133139
  const key = uniqueIndexKeyForTarget(context, member, id2);
132294
133140
  if (key !== null) return `Reference<${type}>(key: ${quote3(key)})`;
@@ -132647,7 +133493,7 @@ function memberDefaultBody(member) {
132647
133493
  if (!("value" in defaultValue)) return null;
132648
133494
  return defaultValue.value;
132649
133495
  }
132650
- var INFERRED_GENERIC_CLASS_PREFIX, MEMBER_KIND_DICTIONARY2, MEMBER_KIND_LIST2, MEMBER_KIND_CLASS2, LEADING_AUTHORED_ROW_ID, INITIALIZER_KEY_PLACEHOLDER, CANONICAL_CONSTRUCTOR_INLINE_WIDTH;
133496
+ var INFERRED_GENERIC_CLASS_PREFIX, MEMBER_KIND_DICTIONARY2, MEMBER_KIND_LIST2, MEMBER_KIND_CLASS2, LEADING_AUTHORED_ROW_ID, INITIALIZER_KEY_PLACEHOLDER, MissingStoredMemberError, CANONICAL_CONSTRUCTOR_INLINE_WIDTH;
132651
133497
  var init_value_sources = __esm({
132652
133498
  "src/project-source/value-sources.ts"() {
132653
133499
  "use strict";
@@ -132712,6 +133558,8 @@ var init_value_sources = __esm({
132712
133558
  `${PENDING_ID_PREFIX}reference-key:init:\\d+`,
132713
133559
  "g"
132714
133560
  );
133561
+ MissingStoredMemberError = class extends Error {
133562
+ };
132715
133563
  CANONICAL_CONSTRUCTOR_INLINE_WIDTH = 88;
132716
133564
  }
132717
133565
  });
@@ -136537,9 +137385,11 @@ function emitDialogue(args) {
136537
137385
  content: `@id(${quote5(dialogueId)})
136538
137386
  ${args.recoveryReason ? `@incomplete(${quote5(args.recoveryReason)})
136539
137387
  ` : ""}@settings(
136540
- ${settings.map(([name, value]) => ` ${name}: ${value}`).join(",\n")}
137388
+ ${settings.map(([name, value]) => ` ${name}: ${value}`).join(
137389
+ ",\n"
137390
+ )}
136541
137391
  )
136542
- sealed class ${args.className} : Dialogue {
137392
+ sealed class ${args.className} : NeoDialogue {
136543
137393
  ${members.map((member) => indentNeoSource(member, 2)).join("\n\n")}
136544
137394
  }
136545
137395
  `,
@@ -136574,11 +137424,14 @@ function emitTrigger(context, node) {
136574
137424
  if (groupName && optionName && !context.groupChildNames.get(groupId)?.has(optionName))
136575
137425
  args.push(["group", `${groupName}.${optionName}`]);
136576
137426
  else if (groupId) {
136577
- args.push(["group", `Reference<DialogueGroup>(id: ${quote5(groupId)})`]);
137427
+ args.push([
137428
+ "group",
137429
+ `Reference<NeoDialogueGroup>(id: ${quote5(groupId)})`
137430
+ ]);
136578
137431
  if (optionId) {
136579
137432
  args.push([
136580
137433
  "priority",
136581
- `Reference<PriorityOption>(id: ${quote5(optionId)})`
137434
+ `Reference<NeoPriorityOption>(id: ${quote5(optionId)})`
136582
137435
  ]);
136583
137436
  }
136584
137437
  }
@@ -137283,7 +138136,7 @@ var init_dialogue_sources = __esm({
137283
138136
  init_ui_action_source();
137284
138137
  PERSISTED_VARIABLE_PATH = /^(?:ref|linked):([^.]+)(\..+)?$/u;
137285
138138
  DIALOGUE_SYSTEM_TYPE_NAMES = [
137286
- "Dialogue",
138139
+ "NeoDialogue",
137287
138140
  "Trigger",
137288
138141
  "Text",
137289
138142
  "Actions",
@@ -138478,6 +139331,7 @@ function loadOrBuildNeoScriptProjectV1(root, document) {
138478
139331
  const project = createNeoScriptCompilationProject({
138479
139332
  project: document.project,
138480
139333
  projectFiles: document.projectFiles,
139334
+ dialogueGroups: document.dialogueGroups,
138481
139335
  members: document.members,
138482
139336
  classes: document.classes,
138483
139337
  enums: document.enums,
@@ -139410,6 +140264,25 @@ function workspaceStatusInitializerDiagnostic(workspace, status, sites, texts, a
139410
140264
  }
139411
140265
  }
139412
140266
  function computeWorkspaceStatus(workspace, options) {
140267
+ const conflictedFiles = [];
140268
+ const parseErrors = [];
140269
+ const parseWarnings = [];
140270
+ try {
140271
+ return computeStatus(
140272
+ workspace,
140273
+ options,
140274
+ conflictedFiles,
140275
+ parseErrors,
140276
+ parseWarnings
140277
+ );
140278
+ } catch (error) {
140279
+ if (error instanceof MissingStoredMemberError && parseErrors.some(isBlockingSchemaSourceError)) {
140280
+ return refusedStatus(conflictedFiles, parseErrors, parseWarnings);
140281
+ }
140282
+ throw error;
140283
+ }
140284
+ }
140285
+ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWarnings) {
139413
140286
  assertCurrentBaseline(workspace.state.records);
139414
140287
  let phaseStarted = performance.now();
139415
140288
  options.onPhase?.("Reading project schema\u2026");
@@ -139419,9 +140292,6 @@ function computeWorkspaceStatus(workspace, options) {
139419
140292
  phaseStarted = finished;
139420
140293
  if (nextLabel !== void 0) options.onPhase?.(nextLabel);
139421
140294
  };
139422
- const conflictedFiles = [];
139423
- const parseErrors = [];
139424
- const parseWarnings = [];
139425
140295
  const migrationSources = [];
139426
140296
  const projectSources = [];
139427
140297
  if (options.virtualSourceFiles === void 0) {
@@ -140630,6 +141500,7 @@ function replayAnimationDeclarationInitializersV4(records3, document, fallbackDo
140630
141500
  const compilationProject = createNeoScriptCompilationProject({
140631
141501
  project: replayDocument.project,
140632
141502
  projectFiles: replayDocument.projectFiles,
141503
+ dialogueGroups: replayDocument.dialogueGroups,
140633
141504
  members: replayDocument.members,
140634
141505
  classes: replayDocument.classes,
140635
141506
  enums: replayDocument.enums,
@@ -147042,37 +147913,37 @@ function collectionSymbols(kind, type) {
147042
147913
  const readOnly = type.readOnly === true;
147043
147914
  const canMutate = !readOnly;
147044
147915
  const symbols = [
147045
- method(
147916
+ method2(
147046
147917
  "Where",
147047
147918
  type,
147048
147919
  lambdaParameters(kind, entryType, keyType),
147049
147920
  "Filter this collection."
147050
147921
  ),
147051
- method(
147922
+ method2(
147052
147923
  "First",
147053
147924
  entryType,
147054
147925
  lambdaParameters(kind, entryType, keyType),
147055
147926
  "Return the first matching entry; throws when none exists."
147056
147927
  ),
147057
- method(
147928
+ method2(
147058
147929
  "FirstOrDefault",
147059
147930
  withNullability(entryType, true),
147060
147931
  lambdaParameters(kind, entryType, keyType),
147061
147932
  "Return the first matching entry, or null."
147062
147933
  ),
147063
- method(
147934
+ method2(
147064
147935
  "Select",
147065
147936
  { kind: "list", elementType: UNKNOWN_TYPE },
147066
147937
  lambdaParameters(kind, entryType, keyType),
147067
147938
  "Map each collection entry."
147068
147939
  ),
147069
- method(
147940
+ method2(
147070
147941
  "Contains",
147071
147942
  { kind: "primitive", name: "bool" },
147072
147943
  [parameter3("value", entryType)],
147073
147944
  "Return whether the collection contains a value."
147074
147945
  ),
147075
- method(
147946
+ method2(
147076
147947
  "Count",
147077
147948
  { kind: "primitive", name: "int" },
147078
147949
  [optionalCollectionPredicate(kind, entryType, keyType)],
@@ -147120,7 +147991,7 @@ function collectionSymbols(kind, type) {
147120
147991
  })
147121
147992
  ];
147122
147993
  symbols.push(
147123
- method(
147994
+ method2(
147124
147995
  name,
147125
147996
  returnType,
147126
147997
  parameters,
@@ -147130,7 +148001,7 @@ function collectionSymbols(kind, type) {
147130
148001
  }
147131
148002
  if (kind === "list") {
147132
148003
  symbols.push(
147133
- method(
148004
+ method2(
147134
148005
  "IndexOf",
147135
148006
  { kind: "primitive", name: "int" },
147136
148007
  [parameter3("value", entryType)],
@@ -147220,7 +148091,7 @@ function optionalCollectionPredicate(kind, entry, key) {
147220
148091
  defaultValue: { displayText: "null", value: null }
147221
148092
  };
147222
148093
  }
147223
- function method(name, returnType, parameters, documentation) {
148094
+ function method2(name, returnType, parameters, documentation) {
147224
148095
  return {
147225
148096
  id: `builtin:collection:${name}`,
147226
148097
  name,
@@ -147232,11 +148103,11 @@ function method(name, returnType, parameters, documentation) {
147232
148103
  };
147233
148104
  }
147234
148105
  function mutationMethod(name, returnType, parameters, documentation) {
147235
- return method(name, returnType, parameters, documentation);
148106
+ return method2(name, returnType, parameters, documentation);
147236
148107
  }
147237
148108
  function stringReplaceSymbol() {
147238
148109
  const stringType = { kind: "primitive", name: "string" };
147239
- return method(
148110
+ return method2(
147240
148111
  "Replace",
147241
148112
  stringType,
147242
148113
  [parameter3("search", stringType), parameter3("replacement", stringType)],
@@ -147244,7 +148115,7 @@ function stringReplaceSymbol() {
147244
148115
  );
147245
148116
  }
147246
148117
  function stringContainsSymbol() {
147247
- return method(
148118
+ return method2(
147248
148119
  "Contains",
147249
148120
  { kind: "primitive", name: "bool" },
147250
148121
  [parameter3("substring", { kind: "primitive", name: "string" })],
@@ -147367,9 +148238,9 @@ function inferLambdaParameterType(local, snapshot) {
147367
148238
  ]);
147368
148239
  for (let cursor = declarationIndex - 1; cursor >= 1; cursor--) {
147369
148240
  const open = tokens[cursor];
147370
- const method2 = tokens[cursor - 1];
148241
+ const method3 = tokens[cursor - 1];
147371
148242
  if (!open || open.kind !== "punctuation" || open.text !== "(") continue;
147372
- if (!method2 || method2.kind !== "identifier" || !lambdaMethods.has(method2.text)) {
148243
+ if (!method3 || method3.kind !== "identifier" || !lambdaMethods.has(method3.text)) {
147373
148244
  continue;
147374
148245
  }
147375
148246
  const dot = tokens[cursor - 2];
@@ -148723,7 +149594,7 @@ function projectAnnotationNamesAt(analysis, document, position) {
148723
149594
  "settings",
148724
149595
  "storage",
148725
149596
  "relations",
148726
- .../\bDialogue\b/.test(followingDeclaration[2] ?? "") ? ["incomplete"] : []
149597
+ .../\bNeoDialogue\b/.test(followingDeclaration[2] ?? "") ? ["incomplete"] : []
148727
149598
  ];
148728
149599
  }
148729
149600
  if (followingDeclaration) return ["id"];
@@ -148755,7 +149626,7 @@ function projectDeclarationAnnotationNames(declaration) {
148755
149626
  "settings",
148756
149627
  "storage",
148757
149628
  "relations",
148758
- ...declaration.baseTypes.some((type) => type.name === "Dialogue") ? ["incomplete"] : []
149629
+ ...declaration.baseTypes.some((type) => type.name === "NeoDialogue") ? ["incomplete"] : []
148759
149630
  ];
148760
149631
  }
148761
149632
  function projectMemberAnnotationNames(member) {
@@ -151126,7 +151997,7 @@ function dialogueGroupCompletions(analysis, document, position) {
151126
151997
  items.push({
151127
151998
  label: name,
151128
151999
  kind: "variable",
151129
- detail: "DialogueGroup",
152000
+ detail: "NeoDialogueGroup",
151130
152001
  insertText: name,
151131
152002
  symbolId: child2.id
151132
152003
  });
@@ -151136,7 +152007,7 @@ function dialogueGroupCompletions(analysis, document, position) {
151136
152007
  items.push({
151137
152008
  label: name,
151138
152009
  kind: "enumMember",
151139
- detail: "PriorityOption",
152010
+ detail: "NeoPriorityOption",
151140
152011
  insertText: name,
151141
152012
  symbolId: option.id
151142
152013
  });
@@ -153042,10 +153913,10 @@ function readWorkspaceRecordFilesV4(workspace, dialogueGroupSymbols) {
153042
153913
  for (const absolute of listProjectSourceFilesV4(workspace.root)) {
153043
153914
  const path = relative4(workspace.root, absolute).split(sep4).join("/");
153044
153915
  const content = readFileSync11(absolute, "utf8");
153045
- if (dialogueGroupSymbols && /\bDialogueGroup\b/u.test(content) && neoProjectSourceKind(path, content) === "definition") {
153916
+ if (dialogueGroupSymbols && /\bNeoDialogueGroup\b/u.test(content) && neoProjectSourceKind(path, content) === "definition") {
153046
153917
  const source = parseNeoProjectSource(content, "definition", path);
153047
153918
  for (const declaration of source.declarations) {
153048
- if (declaration.kind !== "global" || declaration.type.name !== "DialogueGroup")
153919
+ if (declaration.kind !== "global" || declaration.type.name !== "NeoDialogueGroup")
153049
153920
  continue;
153050
153921
  const annotation2 = declaration.annotations.find(
153051
153922
  (item) => item.name === "id"
@@ -160635,11 +161506,8 @@ function dialogueGroupBaseClass(ctx, group, lookupType) {
160635
161506
  function dialogueGroupTriggerMethods(ctx, group, lookupType) {
160636
161507
  if (group.type === 0 /* Standard */) {
160637
161508
  return [
160638
- "public bool TryTrigger(out NeoDialogue dialogue) =>",
160639
- " TryTriggerStandard(out dialogue);",
160640
- "",
160641
- "public bool TryTrigger(out NeoDialogueTriggerResult result) =>",
160642
- " TryTriggerStandard(out result);"
161509
+ "public bool TryTrigger(Action? onFinish = null) =>",
161510
+ " TryTriggerStandard(onFinish);"
160643
161511
  ];
160644
161512
  }
160645
161513
  if (group.type !== 1 /* Lookup */) return [];
@@ -160649,11 +161517,8 @@ function dialogueGroupTriggerMethods(ctx, group, lookupType) {
160649
161517
  ];
160650
161518
  }
160651
161519
  return [
160652
- `public bool TryTrigger(${lookupType} value, out NeoDialogue dialogue) =>`,
160653
- " TryTriggerLookup(value, out dialogue);",
160654
- "",
160655
- `public bool TryTrigger(${lookupType} value, out NeoDialogueTriggerResult result) =>`,
160656
- " TryTriggerLookup(value, out result);"
161520
+ `public bool TryTrigger(${lookupType} value, Action? onFinish = null) =>`,
161521
+ " TryTriggerLookup(value, onFinish);"
160657
161522
  ];
160658
161523
  }
160659
161524
  function generateDialogueGroupProperty(ctx, group) {
@@ -160887,9 +161752,9 @@ function generateRelationTileGridContentClass(ctx, grid, saved) {
160887
161752
  ""
160888
161753
  ];
160889
161754
  const layerBindingExpression = (layer) => {
160890
- const method2 = `${saved ? "BindWritable" : "BindReadOnly"}${layer.kind === "tile" ? "Tile" : "Object"}Layer`;
161755
+ const method3 = `${saved ? "BindWritable" : "BindReadOnly"}${layer.kind === "tile" ? "Tile" : "Object"}Layer`;
160891
161756
  const imports = csharpStringArray(layer.importedClassIds);
160892
- return `primitive.${method2}<${layer.className}>("${escapeCSharpString(layer.layerClassId)}", ${imports})`;
161757
+ return `primitive.${method3}<${layer.className}>("${escapeCSharpString(layer.layerClassId)}", ${imports})`;
160893
161758
  };
160894
161759
  const privateConstructor = saved ? [
160895
161760
  `private ${className}(${primitiveType2} primitive)`,
@@ -161102,7 +161967,7 @@ function generateEnumClass(ctx, enumId) {
161102
161967
  ...indent([...arms, `_ => ${fallback},`]),
161103
161968
  "};"
161104
161969
  ];
161105
- const method2 = (signature, body) => [
161970
+ const method3 = (signature, body) => [
161106
161971
  signature,
161107
161972
  "{",
161108
161973
  ...indent(body),
@@ -161127,7 +161992,7 @@ function generateEnumClass(ctx, enumId) {
161127
161992
  `public static class ${optionsName}`,
161128
161993
  "{",
161129
161994
  ...indent([
161130
- ...method2(
161995
+ ...method3(
161131
161996
  `public static ${enumName} FromOptionId(string optionId)`,
161132
161997
  switchBody(
161133
161998
  "optionId",
@@ -161136,7 +162001,7 @@ function generateEnumClass(ctx, enumId) {
161136
162001
  )
161137
162002
  ),
161138
162003
  "",
161139
- ...method2(
162004
+ ...method3(
161140
162005
  `public static string OptionId(this ${enumName} value)`,
161141
162006
  switchBody(
161142
162007
  "value",
@@ -161145,7 +162010,7 @@ function generateEnumClass(ctx, enumId) {
161145
162010
  )
161146
162011
  ),
161147
162012
  "",
161148
- ...method2(
162013
+ ...method3(
161149
162014
  `public static string[] ToOptionIds(IEnumerable<${enumName}>? options)`,
161150
162015
  [
161151
162016
  "if (options is null) return Array.Empty<string>();",
@@ -161155,7 +162020,7 @@ function generateEnumClass(ctx, enumId) {
161155
162020
  ]
161156
162021
  ),
161157
162022
  "",
161158
- ...method2(
162023
+ ...method3(
161159
162024
  "public static bool IsKnown(string optionId)",
161160
162025
  switchBody(
161161
162026
  "optionId",
@@ -161164,7 +162029,7 @@ function generateEnumClass(ctx, enumId) {
161164
162029
  )
161165
162030
  ),
161166
162031
  "",
161167
- ...method2(
162032
+ ...method3(
161168
162033
  `public static string TextId(this ${enumName} value)`,
161169
162034
  switchBody(
161170
162035
  "value",
@@ -161173,7 +162038,7 @@ function generateEnumClass(ctx, enumId) {
161173
162038
  )
161174
162039
  ),
161175
162040
  "",
161176
- ...method2(
162041
+ ...method3(
161177
162042
  `public static string Text(this ${enumName} value, NeoClient? client = null)`,
161178
162043
  [
161179
162044
  ctx.singleton ? `return (client ?? ${ctx.projectClassName}.RequireInstance().Client).Localization.ResolveText(value.TextId());` : "return client is null ? value.TextId() : client.Localization.ResolveText(value.TextId());"
@@ -169100,6 +169965,28 @@ function addNeoScriptFunctionReferenceDiagnostics(args) {
169100
169965
  });
169101
169966
  return;
169102
169967
  }
169968
+ if (args.fn.type === "dialogueGroup" /* dialogueGroup */ || args.fn.type === "dialogue" /* dialogue */) {
169969
+ const info = args.fn.info;
169970
+ const pointers = [
169971
+ ["valuePointer", "valuePointer" in info ? info.valuePointer : void 0],
169972
+ [
169973
+ "dialogueIdPointer",
169974
+ "dialogueIdPointer" in info ? info.dialogueIdPointer : void 0
169975
+ ],
169976
+ ["onFinishPointer", info.onFinishPointer]
169977
+ ];
169978
+ for (const [field, pointer] of pointers) {
169979
+ if (pointer === void 0) continue;
169980
+ addPointerReferenceDiagnostics({
169981
+ diagnostics: args.diagnostics,
169982
+ pointer,
169983
+ allowDeferredFunctions: args.allowDeferredFunctions,
169984
+ context: args.context,
169985
+ path: `${args.path}.info.${field}`
169986
+ });
169987
+ }
169988
+ return;
169989
+ }
169103
169990
  if (args.fn.type === "vectorConstructor" /* vectorConstructor */) {
169104
169991
  args.fn.info.componentPointers.forEach((pointer, index) => {
169105
169992
  addPointerReferenceDiagnostics({
@@ -170018,7 +170905,7 @@ var init_dialogue_diagnostics = __esm({
170018
170905
  init_interface_types();
170019
170906
  init_interface_graph();
170020
170907
  init_neoscript();
170021
- init_dialogue_types();
170908
+ init_dialogue_types2();
170022
170909
  init_dialogue_group_types();
170023
170910
  init_logic_types();
170024
170911
  init_core();
@@ -170787,7 +171674,7 @@ var init_project_unity_export_diagnostics = __esm({
170787
171674
  "use strict";
170788
171675
  init_project_world_placement_bindings();
170789
171676
  init_dialogue_diagnostics();
170790
- init_dialogue_types();
171677
+ init_dialogue_types2();
170791
171678
  init_members();
170792
171679
  init_core_types();
170793
171680
  init_inheritance();
@@ -170809,7 +171696,7 @@ var UNITY_CODEGEN_REVISION;
170809
171696
  var init_unity_codegen_revision = __esm({
170810
171697
  "../src/models/exports/unity-codegen-revision.ts"() {
170811
171698
  "use strict";
170812
- UNITY_CODEGEN_REVISION = "45a0847addd4616acfc29f142556dcb2e0a27daae14d6aa456430228e66dbc07";
171699
+ UNITY_CODEGEN_REVISION = "e4a632a177c87244e19da71c9840b8007735773ae5f81578f58ce246ec6cb03d";
170813
171700
  }
170814
171701
  });
170815
171702
 
@@ -170819,7 +171706,7 @@ var init_project_unity_export_types = __esm({
170819
171706
  "../src/models/exports/project-unity-export-types.ts"() {
170820
171707
  "use strict";
170821
171708
  init_unity_codegen_revision();
170822
- PROJECT_UNITY_EXPORT_SCHEMA_VERSION = 38;
171709
+ PROJECT_UNITY_EXPORT_SCHEMA_VERSION = 39;
170823
171710
  }
170824
171711
  });
170825
171712
 
@@ -175872,6 +176759,7 @@ async function buildPostPushCompileSchema(workspace, status) {
175872
176759
  return {
175873
176760
  project,
175874
176761
  projectFiles: [...bucket("project-file").values()],
176762
+ dialogueGroups: [...bucket("dialogue-group").values()],
175875
176763
  members: [...bucket("member").values()],
175876
176764
  classes: [...bucket("class").values()],
175877
176765
  constructors: [...bucket("constructor").values()],
@@ -175885,6 +176773,7 @@ function createPostPushCompileContext(schema) {
175885
176773
  const project = {
175886
176774
  project: schema.project,
175887
176775
  projectFiles: schema.projectFiles,
176776
+ dialogueGroups: schema.dialogueGroups ?? [],
175888
176777
  members: schema.members,
175889
176778
  classes: schema.classes,
175890
176779
  constructors: schema.constructors,
@@ -179633,6 +180522,7 @@ function createCliNeoScriptContext(options) {
179633
180522
  const vm = {
179634
180523
  project: options.documents.project,
179635
180524
  projectFiles: [...options.documents.projectFiles ?? []],
180525
+ dialogueGroups: [...options.documents.dialogueGroups ?? []],
179636
180526
  members,
179637
180527
  classes: [...options.documents.classes],
179638
180528
  enums: [...options.documents.enums],
@@ -179659,10 +180549,25 @@ function createCliNeoScriptContext(options) {
179659
180549
  // root placement is server context, not authored schema-manifest state.
179660
180550
  roots: compilerContext.project.roots,
179661
180551
  globals: compilerContext.project.globals,
179662
- version: compilerContext.project.version
180552
+ version: compilerContext.project.version,
180553
+ dialogueGroups: cliDialogueGroupSources(options.documents)
179663
180554
  });
179664
180555
  return { ...compilerContext, project: projection.project };
179665
180556
  }
180557
+ function cliDialogueGroupSources(documents) {
180558
+ if (!documents.dialogueGroups?.length) return [];
180559
+ const members = new Map(
180560
+ documents.members.map((member) => [member.id, member])
180561
+ );
180562
+ const classes = new Map(
180563
+ documents.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
180564
+ );
180565
+ return storedDialogueGroupSources(
180566
+ documents.dialogueGroups,
180567
+ (id2) => members.get(id2),
180568
+ (id2) => classes.get(id2)
180569
+ );
180570
+ }
179666
180571
  async function validateCliNeoScript(uri, source, context) {
179667
180572
  const service = createCliNeoScriptLanguageService();
179668
180573
  const document = {
@@ -179719,7 +180624,8 @@ function createCliManifestScriptContext(manifest, scriptPath2, unit, options = {
179719
180624
  const projectedManifest = manifestWithUniqueInlineScriptKeys(manifest);
179720
180625
  const projection = projectSchemaManifest(projectedManifest, {
179721
180626
  ...options.rootMemberIds ? { rootMemberIds: options.rootMemberIds } : {},
179722
- ...options.sourceUri ? { sourceUri: options.sourceUri } : {}
180627
+ ...options.sourceUri ? { sourceUri: options.sourceUri } : {},
180628
+ ...options.dialogueGroups ? { dialogueGroups: options.dialogueGroups } : {}
179723
180629
  });
179724
180630
  const normalizedPath = options.memberId === void 0 ? normalizeWorkspacePath(scriptPath2) : inlineScriptKey(scriptPath2, options.memberId);
179725
180631
  const script = projection.scripts.get(normalizedPath);
@@ -179767,7 +180673,8 @@ function analyzeManifestScripts(manifest, options = {}) {
179767
180673
  const projectedManifest = manifestWithUniqueInlineScriptKeys(manifest);
179768
180674
  const projection = projectSchemaManifest(projectedManifest, {
179769
180675
  ...options.rootMemberIds ? { rootMemberIds: options.rootMemberIds } : {},
179770
- ...options.sourceUri ? { sourceUri: options.sourceUri } : {}
180676
+ ...options.sourceUri ? { sourceUri: options.sourceUri } : {},
180677
+ ...options.dialogueGroups ? { dialogueGroups: options.dialogueGroups } : {}
179771
180678
  });
179772
180679
  const sources2 = /* @__PURE__ */ new Map();
179773
180680
  const scriptPathByMemberId = /* @__PURE__ */ new Map();
@@ -179849,6 +180756,7 @@ var init_neoscript_language_adapter = __esm({
179849
180756
  init_service();
179850
180757
  init_strict_ir();
179851
180758
  init_neoscript_language_context_adapter();
180759
+ init_dialogue_group_language();
179852
180760
  }
179853
180761
  });
179854
180762
 
@@ -180821,7 +181729,8 @@ async function runScript(workspace, command, options, dependencies = {}) {
180821
181729
  localCheckManifest,
180822
181730
  localTarget,
180823
181731
  command,
180824
- options
181732
+ options,
181733
+ localCheckDocument === null ? [] : cliDialogueGroupSources(localCheckDocument)
180825
181734
  );
180826
181735
  return;
180827
181736
  }
@@ -180872,6 +181781,7 @@ async function runScript(workspace, command, options, dependencies = {}) {
180872
181781
  const compilerProject = {
180873
181782
  project: document.project,
180874
181783
  projectFiles: document.projectFiles,
181784
+ dialogueGroups: document.dialogueGroups,
180875
181785
  members: document.members,
180876
181786
  classes: document.classes,
180877
181787
  constructors: document.constructors,
@@ -181044,6 +181954,7 @@ async function runScript(workspace, command, options, dependencies = {}) {
181044
181954
  variants: document.variants,
181045
181955
  variantFolders: document.variantFolders,
181046
181956
  projectFiles: document.projectFiles,
181957
+ dialogueGroups: document.dialogueGroups,
181047
181958
  textureTemplates: document.textureTemplates,
181048
181959
  localizationConfig: document.localizationConfig,
181049
181960
  localizedTexts: document.localizedTexts,
@@ -181506,7 +182417,7 @@ function localMemberOwnerKeys(member) {
181506
182417
  }
181507
182418
  return [];
181508
182419
  }
181509
- async function runLocalTargetCommand(manifest, target, command, options) {
182420
+ async function runLocalTargetCommand(manifest, target, command, options, dialogueGroups) {
181510
182421
  const member = target.member;
181511
182422
  const script = member.script;
181512
182423
  if (script === null) {
@@ -181561,6 +182472,7 @@ async function runLocalTargetCommand(manifest, target, command, options) {
181561
182472
  const source = readSource(options, fallback);
181562
182473
  const context = createCliManifestScriptContext(manifest, script.path, unit, {
181563
182474
  memberId: member.id,
182475
+ dialogueGroups,
181564
182476
  ...target.receiverClassId && member.modifier !== "static" ? { receiverClassId: target.receiverClassId } : {}
181565
182477
  });
181566
182478
  const diagnostics = await validateCliNeoScript(
@@ -181622,11 +182534,11 @@ async function runLocalTargetCommand(manifest, target, command, options) {
181622
182534
  options.json ? JSON.stringify({ ...report, ...functionMetadata }, null, 2) : "Compiles cleanly."
181623
182535
  );
181624
182536
  }
181625
- function collectLocalCheckAll(manifest, options) {
182537
+ function collectLocalCheckAll(manifest, options, dialogueGroups) {
181626
182538
  const membersById = new Map(
181627
182539
  manifest.members.filter(isLocalScriptMember).map((member) => [member.id, member])
181628
182540
  );
181629
- const analyses = analyzeManifestScripts(manifest);
182541
+ const analyses = analyzeManifestScripts(manifest, { dialogueGroups });
181630
182542
  const results = analyses.map((analysis) => {
181631
182543
  const member = membersById.get(analysis.memberId);
181632
182544
  if (member === void 0) {
@@ -181664,7 +182576,11 @@ function localScriptUri(path) {
181664
182576
  return `neo-script:///${normalizeScriptPath(path).split("/").map((part) => encodeURIComponent(part)).join("/")}`;
181665
182577
  }
181666
182578
  function runCheckAll(document, manifest, options) {
181667
- const local = collectLocalCheckAll(manifest, options);
182579
+ const local = collectLocalCheckAll(
182580
+ manifest,
182581
+ options,
182582
+ cliDialogueGroupSources(document)
182583
+ );
181668
182584
  let failures = local.failures;
181669
182585
  let checked = local.checked;
181670
182586
  const results = [...local.results];
@@ -181757,7 +182673,7 @@ var init_script = __esm({
181757
182673
  init_save_overlay_resolution();
181758
182674
  init_members();
181759
182675
  init_neoscript();
181760
- init_dialogue_types();
182676
+ init_dialogue_types2();
181761
182677
  init_logic_types();
181762
182678
  init_dialogue_logic_compile_pure();
181763
182679
  init_project_migration_runner();
@@ -181965,6 +182881,7 @@ function sharedEvaluatorBase(rawDocument) {
181965
182881
  variants: document.variants,
181966
182882
  variantFolders: document.variantFolders,
181967
182883
  projectFiles: document.projectFiles,
182884
+ dialogueGroups: document.dialogueGroups,
181968
182885
  textureTemplates: document.textureTemplates,
181969
182886
  localizationConfig: document.localizationConfig,
181970
182887
  localizedTexts: document.localizedTexts,
@@ -185093,6 +186010,7 @@ async function runPendingMigrations(workspace, fetched, migrations, onlyRef) {
185093
186010
  () => compileNSVoidBody(migrationCode, {
185094
186011
  project: document.project,
185095
186012
  projectFiles: document.projectFiles,
186013
+ dialogueGroups: document.dialogueGroups,
185096
186014
  members: document.members,
185097
186015
  classes: document.classes,
185098
186016
  constructors: document.constructors,
@@ -185137,6 +186055,7 @@ async function runPendingMigrations(workspace, fetched, migrations, onlyRef) {
185137
186055
  classes: document.classes,
185138
186056
  enums: document.enums,
185139
186057
  projectFiles: document.projectFiles,
186058
+ dialogueGroups: document.dialogueGroups,
185140
186059
  localizationConfig: document.localizationConfig,
185141
186060
  localizedTexts: document.localizedTexts,
185142
186061
  ...runtime
@@ -186913,7 +187832,7 @@ var init_dialogue_lookup_candidates = __esm({
186913
187832
  var init_dialogue_record_split = __esm({
186914
187833
  "../src/models/dialogue/dialogue-record-split.ts"() {
186915
187834
  "use strict";
186916
- init_dialogue_types();
187835
+ init_dialogue_types2();
186917
187836
  }
186918
187837
  });
186919
187838
 
@@ -186923,7 +187842,7 @@ var init_dialogue_localized_text_links = __esm({
186923
187842
  "use strict";
186924
187843
  init_localized_text_create_envelope();
186925
187844
  init_localization_types();
186926
- init_dialogue_types();
187845
+ init_dialogue_types2();
186927
187846
  }
186928
187847
  });
186929
187848
 
@@ -186958,7 +187877,7 @@ var init_dialogue_triggering = __esm({
186958
187877
  var init_dialogue = __esm({
186959
187878
  "../src/models/dialogue/index.ts"() {
186960
187879
  "use strict";
186961
- init_dialogue_types();
187880
+ init_dialogue_types2();
186962
187881
  init_dialogue_source_identifiers();
186963
187882
  init_dialogue_source_names();
186964
187883
  init_dialogue_lookup_candidates();
@@ -188923,6 +189842,7 @@ function buildWorld(document, raw) {
188923
189842
  variants: document.variants,
188924
189843
  variantFolders: document.variantFolders,
188925
189844
  projectFiles: document.projectFiles,
189845
+ dialogueGroups: document.dialogueGroups,
188926
189846
  localizationConfig: document.localizationConfig,
188927
189847
  localizedTexts: document.localizedTexts,
188928
189848
  ...runtime
@@ -190519,7 +191439,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
190519
191439
  async function main() {
190520
191440
  const args = parseArgs(process.argv.slice(2));
190521
191441
  if (args.command === "--version") {
190522
- console.log("0.72.4");
191442
+ console.log("0.73.1");
190523
191443
  return;
190524
191444
  }
190525
191445
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {