@nice2dev/game-engine 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/dist/cjs/ai/BehaviorTree.js +1215 -0
  2. package/dist/cjs/ai/BehaviorTree.js.map +1 -0
  3. package/dist/cjs/ai/StateMachine.js +783 -0
  4. package/dist/cjs/ai/StateMachine.js.map +1 -0
  5. package/dist/cjs/editor/ShaderGraph.js +1616 -0
  6. package/dist/cjs/editor/ShaderGraph.js.map +1 -0
  7. package/dist/cjs/editor/TimelineEditor.js +819 -0
  8. package/dist/cjs/editor/TimelineEditor.js.map +1 -0
  9. package/dist/cjs/export/GodotExporter.js +1102 -0
  10. package/dist/cjs/export/GodotExporter.js.map +1 -0
  11. package/dist/cjs/export/PlatformExporter.js +236 -0
  12. package/dist/cjs/export/PlatformExporter.js.map +1 -0
  13. package/dist/cjs/export/ThreeJSExporter.js +1116 -0
  14. package/dist/cjs/export/ThreeJSExporter.js.map +1 -0
  15. package/dist/cjs/export/UnityExporter.js +1193 -0
  16. package/dist/cjs/export/UnityExporter.js.map +1 -0
  17. package/dist/cjs/export/WebExporter.js +1036 -0
  18. package/dist/cjs/export/WebExporter.js.map +1 -0
  19. package/dist/cjs/export/index.js +58 -0
  20. package/dist/cjs/export/index.js.map +1 -0
  21. package/dist/cjs/import/AsepriteImporter.js +761 -0
  22. package/dist/cjs/import/AsepriteImporter.js.map +1 -0
  23. package/dist/cjs/import/DragonBonesImporter.js +499 -0
  24. package/dist/cjs/import/DragonBonesImporter.js.map +1 -0
  25. package/dist/cjs/import/GameMakerImporter.js +559 -0
  26. package/dist/cjs/import/GameMakerImporter.js.map +1 -0
  27. package/dist/cjs/import/GodotSceneImporter.js +824 -0
  28. package/dist/cjs/import/GodotSceneImporter.js.map +1 -0
  29. package/dist/cjs/import/LDtkImporter.js +481 -0
  30. package/dist/cjs/import/LDtkImporter.js.map +1 -0
  31. package/dist/cjs/import/Live2DImporter.js +553 -0
  32. package/dist/cjs/import/Live2DImporter.js.map +1 -0
  33. package/dist/cjs/import/NdgFormat.js +499 -0
  34. package/dist/cjs/import/NdgFormat.js.map +1 -0
  35. package/dist/cjs/import/OgmoImporter.js +529 -0
  36. package/dist/cjs/import/OgmoImporter.js.map +1 -0
  37. package/dist/cjs/import/RPGMakerImporter.js +520 -0
  38. package/dist/cjs/import/RPGMakerImporter.js.map +1 -0
  39. package/dist/cjs/import/SceneImporter.js +449 -0
  40. package/dist/cjs/import/SceneImporter.js.map +1 -0
  41. package/dist/cjs/import/SpineImporter.js +583 -0
  42. package/dist/cjs/import/SpineImporter.js.map +1 -0
  43. package/dist/cjs/import/SpriterImporter.js +652 -0
  44. package/dist/cjs/import/SpriterImporter.js.map +1 -0
  45. package/dist/cjs/import/TiledMapImporter.js +859 -0
  46. package/dist/cjs/import/TiledMapImporter.js.map +1 -0
  47. package/dist/cjs/import/UnitySceneImporter.js +732 -0
  48. package/dist/cjs/import/UnitySceneImporter.js.map +1 -0
  49. package/dist/cjs/import/index.js +305 -0
  50. package/dist/cjs/import/index.js.map +1 -0
  51. package/dist/cjs/index.js +201 -0
  52. package/dist/cjs/index.js.map +1 -1
  53. package/dist/cjs/scripting/GraphToAST.js +567 -0
  54. package/dist/cjs/scripting/GraphToAST.js.map +1 -0
  55. package/dist/cjs/scripting/LanguageExporter.js +321 -0
  56. package/dist/cjs/scripting/LanguageExporter.js.map +1 -0
  57. package/dist/cjs/scripting/ScriptAST.js +67 -0
  58. package/dist/cjs/scripting/ScriptAST.js.map +1 -0
  59. package/dist/cjs/scripting/VisualScripting2.js +1140 -0
  60. package/dist/cjs/scripting/VisualScripting2.js.map +1 -0
  61. package/dist/cjs/scripting/exporters/CSharpExporter.js +503 -0
  62. package/dist/cjs/scripting/exporters/CSharpExporter.js.map +1 -0
  63. package/dist/cjs/scripting/exporters/GDScriptExporter.js +452 -0
  64. package/dist/cjs/scripting/exporters/GDScriptExporter.js.map +1 -0
  65. package/dist/cjs/scripting/exporters/LuaExporter.js +457 -0
  66. package/dist/cjs/scripting/exporters/LuaExporter.js.map +1 -0
  67. package/dist/cjs/scripting/exporters/PythonExporter.js +565 -0
  68. package/dist/cjs/scripting/exporters/PythonExporter.js.map +1 -0
  69. package/dist/cjs/scripting/exporters/RustExporter.js +525 -0
  70. package/dist/cjs/scripting/exporters/RustExporter.js.map +1 -0
  71. package/dist/cjs/scripting/exporters/TypeScriptExporter.js +570 -0
  72. package/dist/cjs/scripting/exporters/TypeScriptExporter.js.map +1 -0
  73. package/dist/cjs/systems/ParticleSystem2.js +1478 -0
  74. package/dist/cjs/systems/ParticleSystem2.js.map +1 -0
  75. package/dist/esm/ai/BehaviorTree.js +1186 -0
  76. package/dist/esm/ai/BehaviorTree.js.map +1 -0
  77. package/dist/esm/ai/StateMachine.js +767 -0
  78. package/dist/esm/ai/StateMachine.js.map +1 -0
  79. package/dist/esm/editor/ShaderGraph.js +1606 -0
  80. package/dist/esm/editor/ShaderGraph.js.map +1 -0
  81. package/dist/esm/editor/TimelineEditor.js +800 -0
  82. package/dist/esm/editor/TimelineEditor.js.map +1 -0
  83. package/dist/esm/export/GodotExporter.js +1100 -0
  84. package/dist/esm/export/GodotExporter.js.map +1 -0
  85. package/dist/esm/export/PlatformExporter.js +230 -0
  86. package/dist/esm/export/PlatformExporter.js.map +1 -0
  87. package/dist/esm/export/ThreeJSExporter.js +1114 -0
  88. package/dist/esm/export/ThreeJSExporter.js.map +1 -0
  89. package/dist/esm/export/UnityExporter.js +1191 -0
  90. package/dist/esm/export/UnityExporter.js.map +1 -0
  91. package/dist/esm/export/WebExporter.js +1033 -0
  92. package/dist/esm/export/WebExporter.js.map +1 -0
  93. package/dist/esm/export/index.js +44 -0
  94. package/dist/esm/export/index.js.map +1 -0
  95. package/dist/esm/import/AsepriteImporter.js +759 -0
  96. package/dist/esm/import/AsepriteImporter.js.map +1 -0
  97. package/dist/esm/import/DragonBonesImporter.js +496 -0
  98. package/dist/esm/import/DragonBonesImporter.js.map +1 -0
  99. package/dist/esm/import/GameMakerImporter.js +556 -0
  100. package/dist/esm/import/GameMakerImporter.js.map +1 -0
  101. package/dist/esm/import/GodotSceneImporter.js +822 -0
  102. package/dist/esm/import/GodotSceneImporter.js.map +1 -0
  103. package/dist/esm/import/LDtkImporter.js +479 -0
  104. package/dist/esm/import/LDtkImporter.js.map +1 -0
  105. package/dist/esm/import/Live2DImporter.js +550 -0
  106. package/dist/esm/import/Live2DImporter.js.map +1 -0
  107. package/dist/esm/import/NdgFormat.js +490 -0
  108. package/dist/esm/import/NdgFormat.js.map +1 -0
  109. package/dist/esm/import/OgmoImporter.js +526 -0
  110. package/dist/esm/import/OgmoImporter.js.map +1 -0
  111. package/dist/esm/import/RPGMakerImporter.js +517 -0
  112. package/dist/esm/import/RPGMakerImporter.js.map +1 -0
  113. package/dist/esm/import/SceneImporter.js +441 -0
  114. package/dist/esm/import/SceneImporter.js.map +1 -0
  115. package/dist/esm/import/SpineImporter.js +580 -0
  116. package/dist/esm/import/SpineImporter.js.map +1 -0
  117. package/dist/esm/import/SpriterImporter.js +649 -0
  118. package/dist/esm/import/SpriterImporter.js.map +1 -0
  119. package/dist/esm/import/TiledMapImporter.js +857 -0
  120. package/dist/esm/import/TiledMapImporter.js.map +1 -0
  121. package/dist/esm/import/UnitySceneImporter.js +730 -0
  122. package/dist/esm/import/UnitySceneImporter.js.map +1 -0
  123. package/dist/esm/import/index.js +279 -0
  124. package/dist/esm/import/index.js.map +1 -0
  125. package/dist/esm/index.js +36 -0
  126. package/dist/esm/index.js.map +1 -1
  127. package/dist/esm/scripting/GraphToAST.js +564 -0
  128. package/dist/esm/scripting/GraphToAST.js.map +1 -0
  129. package/dist/esm/scripting/LanguageExporter.js +311 -0
  130. package/dist/esm/scripting/LanguageExporter.js.map +1 -0
  131. package/dist/esm/scripting/ScriptAST.js +52 -0
  132. package/dist/esm/scripting/ScriptAST.js.map +1 -0
  133. package/dist/esm/scripting/VisualScripting2.js +1130 -0
  134. package/dist/esm/scripting/VisualScripting2.js.map +1 -0
  135. package/dist/esm/scripting/exporters/CSharpExporter.js +501 -0
  136. package/dist/esm/scripting/exporters/CSharpExporter.js.map +1 -0
  137. package/dist/esm/scripting/exporters/GDScriptExporter.js +450 -0
  138. package/dist/esm/scripting/exporters/GDScriptExporter.js.map +1 -0
  139. package/dist/esm/scripting/exporters/LuaExporter.js +455 -0
  140. package/dist/esm/scripting/exporters/LuaExporter.js.map +1 -0
  141. package/dist/esm/scripting/exporters/PythonExporter.js +563 -0
  142. package/dist/esm/scripting/exporters/PythonExporter.js.map +1 -0
  143. package/dist/esm/scripting/exporters/RustExporter.js +523 -0
  144. package/dist/esm/scripting/exporters/RustExporter.js.map +1 -0
  145. package/dist/esm/scripting/exporters/TypeScriptExporter.js +568 -0
  146. package/dist/esm/scripting/exporters/TypeScriptExporter.js.map +1 -0
  147. package/dist/esm/systems/ParticleSystem2.js +1471 -0
  148. package/dist/esm/systems/ParticleSystem2.js.map +1 -0
  149. package/dist/types/ai/BehaviorTree.d.ts +375 -0
  150. package/dist/types/ai/StateMachine.d.ts +296 -0
  151. package/dist/types/editor/ShaderGraph.d.ts +207 -0
  152. package/dist/types/editor/TimelineEditor.d.ts +393 -0
  153. package/dist/types/export/GodotExporter.d.ts +56 -0
  154. package/dist/types/export/PlatformExporter.d.ts +201 -0
  155. package/dist/types/export/ThreeJSExporter.d.ts +40 -0
  156. package/dist/types/export/UnityExporter.d.ts +69 -0
  157. package/dist/types/export/WebExporter.d.ts +58 -0
  158. package/dist/types/export/index.d.ts +19 -0
  159. package/dist/types/import/AsepriteImporter.d.ts +46 -0
  160. package/dist/types/import/DragonBonesImporter.d.ts +331 -0
  161. package/dist/types/import/GameMakerImporter.d.ts +375 -0
  162. package/dist/types/import/GodotSceneImporter.d.ts +34 -0
  163. package/dist/types/import/LDtkImporter.d.ts +177 -0
  164. package/dist/types/import/Live2DImporter.d.ts +237 -0
  165. package/dist/types/import/NdgFormat.d.ts +387 -0
  166. package/dist/types/import/OgmoImporter.d.ts +237 -0
  167. package/dist/types/import/RPGMakerImporter.d.ts +186 -0
  168. package/dist/types/import/SceneImporter.d.ts +276 -0
  169. package/dist/types/import/SpineImporter.d.ts +372 -0
  170. package/dist/types/import/SpriterImporter.d.ts +230 -0
  171. package/dist/types/import/TiledMapImporter.d.ts +57 -0
  172. package/dist/types/import/UnitySceneImporter.d.ts +87 -0
  173. package/dist/types/import/index.d.ts +59 -0
  174. package/dist/types/index.d.ts +29 -17
  175. package/dist/types/scripting/GraphToAST.d.ts +55 -0
  176. package/dist/types/scripting/LanguageExporter.d.ts +136 -0
  177. package/dist/types/scripting/ScriptAST.d.ts +312 -0
  178. package/dist/types/scripting/VisualScripting2.d.ts +353 -0
  179. package/dist/types/scripting/exporters/CSharpExporter.d.ts +44 -0
  180. package/dist/types/scripting/exporters/GDScriptExporter.d.ts +46 -0
  181. package/dist/types/scripting/exporters/LuaExporter.d.ts +46 -0
  182. package/dist/types/scripting/exporters/PythonExporter.d.ts +49 -0
  183. package/dist/types/scripting/exporters/RustExporter.d.ts +46 -0
  184. package/dist/types/scripting/exporters/TypeScriptExporter.d.ts +48 -0
  185. package/dist/types/scripting/exporters/index.d.ts +8 -0
  186. package/dist/types/scripting/index.d.ts +11 -0
  187. package/dist/types/systems/ParticleSystem2.d.ts +646 -0
  188. package/package.json +2 -2
@@ -0,0 +1,859 @@
1
+ 'use strict';
2
+
3
+ var SceneImporter = require('./SceneImporter.js');
4
+
5
+ /**
6
+ * @file TiledMapImporter.ts
7
+ * @description Import Tiled Map Editor files (.tmx, .tsx)
8
+ * PRO-1.3: Scene Format Interoperability
9
+ *
10
+ * Supports:
11
+ * - Tiled Map files (.tmx, .tmj)
12
+ * - Tileset files (.tsx, .tsj)
13
+ * - Template files (.tx, .tj)
14
+ * - World files (.world)
15
+ *
16
+ * Features:
17
+ * - Tile layers
18
+ * - Object layers
19
+ * - Image layers
20
+ * - Group layers
21
+ * - Animations
22
+ * - Custom properties
23
+ * - Collision shapes
24
+ */
25
+ // ============================================================
26
+ // Tiled Map Importer
27
+ // ============================================================
28
+ class TiledMapImporter extends SceneImporter.SceneImporter {
29
+ constructor() {
30
+ super('tiled');
31
+ this.tilesets = new Map();
32
+ this.tilesetsById = new Map();
33
+ }
34
+ async import(options) {
35
+ const startTime = Date.now();
36
+ this.options = options;
37
+ this.clearMessages();
38
+ this.tilesets.clear();
39
+ this.tilesetsById.clear();
40
+ const errors = await this.validate(options.sourcePath);
41
+ if (errors.some((e) => e.fatal)) {
42
+ return {
43
+ ...this.createEmptyResult(),
44
+ errors: errors,
45
+ };
46
+ }
47
+ const scenes = [];
48
+ const assets = [];
49
+ try {
50
+ const content = await this.readFile(options.sourcePath);
51
+ const isJson = options.sourcePath.endsWith('.tmj') || options.sourcePath.endsWith('.json');
52
+ const map = isJson ? this.parseJsonMap(content) : this.parseXmlMap(content);
53
+ if (map) {
54
+ // Parse external tilesets
55
+ await this.loadExternalTilesets(map, options.sourcePath);
56
+ const parsed = this.convertTiledMapToScene(map);
57
+ const niceScene = this.convertParsedToNiceScene(parsed);
58
+ scenes.push(niceScene);
59
+ const extractedAssets = this.extractAssets(map);
60
+ assets.push(...extractedAssets);
61
+ }
62
+ }
63
+ catch (error) {
64
+ this.addError('IMPORT_ERROR', `Failed to import: ${error}`, options.sourcePath, undefined, true);
65
+ }
66
+ return this.createResult(scenes, assets, startTime);
67
+ }
68
+ async parseFile(content, filePath) {
69
+ const stringContent = typeof content === 'string' ? content : new TextDecoder().decode(content);
70
+ const isJson = filePath.endsWith('.tmj') || filePath.endsWith('.json');
71
+ const map = isJson ? this.parseJsonMap(stringContent) : this.parseXmlMap(stringContent);
72
+ if (!map)
73
+ return null;
74
+ return this.convertTiledMapToScene(map);
75
+ }
76
+ async validate(sourcePath) {
77
+ const errors = [];
78
+ if (!this.canHandle(sourcePath)) {
79
+ errors.push({
80
+ code: 'INVALID_FORMAT',
81
+ message: `File ${sourcePath} is not a valid Tiled file`,
82
+ file: sourcePath,
83
+ fatal: true,
84
+ });
85
+ }
86
+ return errors;
87
+ }
88
+ // ----------------------------------------
89
+ // Tiled Parsing
90
+ // ----------------------------------------
91
+ parseJsonMap(content) {
92
+ try {
93
+ const json = JSON.parse(content);
94
+ return this.normalizeJsonMap(json);
95
+ }
96
+ catch (error) {
97
+ this.addError('JSON_PARSE_ERROR', `Failed to parse JSON: ${error}`);
98
+ return null;
99
+ }
100
+ }
101
+ normalizeJsonMap(json) {
102
+ var _a, _b;
103
+ return {
104
+ version: String(json.version || '1.0'),
105
+ tiledVersion: String(json.tiledversion || ''),
106
+ orientation: json.orientation || 'orthogonal',
107
+ renderOrder: json.renderorder || 'right-down',
108
+ width: Number(json.width) || 0,
109
+ height: Number(json.height) || 0,
110
+ tileWidth: Number(json.tilewidth) || 0,
111
+ tileHeight: Number(json.tileheight) || 0,
112
+ infinite: Boolean(json.infinite),
113
+ backgroundColor: json.backgroundcolor ? String(json.backgroundcolor) : undefined,
114
+ nextLayerId: Number(json.nextlayerid) || 0,
115
+ nextObjectId: Number(json.nextobjectid) || 0,
116
+ parallaxOriginX: json.parallaxoriginx ? Number(json.parallaxoriginx) : undefined,
117
+ parallaxOriginY: json.parallaxoriginy ? Number(json.parallaxoriginy) : undefined,
118
+ tilesets: ((_a = json.tilesets) === null || _a === void 0 ? void 0 : _a.map((ts) => this.normalizeJsonTileset(ts))) || [],
119
+ layers: ((_b = json.layers) === null || _b === void 0 ? void 0 : _b.map((l) => this.normalizeJsonLayer(l))) || [],
120
+ properties: this.normalizeProperties(json.properties),
121
+ hexSideLength: json.hexsidelength ? Number(json.hexsidelength) : undefined,
122
+ staggerAxis: json.staggeraxis,
123
+ staggerIndex: json.staggerindex,
124
+ };
125
+ }
126
+ normalizeJsonTileset(json) {
127
+ const tileset = {
128
+ firstGid: Number(json.firstgid) || 0,
129
+ source: json.source ? String(json.source) : undefined,
130
+ name: String(json.name || ''),
131
+ tileWidth: Number(json.tilewidth) || 0,
132
+ tileHeight: Number(json.tileheight) || 0,
133
+ spacing: Number(json.spacing) || 0,
134
+ margin: Number(json.margin) || 0,
135
+ tileCount: Number(json.tilecount) || 0,
136
+ columns: Number(json.columns) || 0,
137
+ image: json.image ? String(json.image) : undefined,
138
+ imageWidth: json.imagewidth ? Number(json.imagewidth) : undefined,
139
+ imageHeight: json.imageheight ? Number(json.imageheight) : undefined,
140
+ transparentColor: json.transparentcolor ? String(json.transparentcolor) : undefined,
141
+ properties: this.normalizeProperties(json.properties),
142
+ };
143
+ if (json.tiles) {
144
+ tileset.tiles = json.tiles.map((t) => this.normalizeJsonTile(t));
145
+ }
146
+ if (json.tileoffset) {
147
+ const offset = json.tileoffset;
148
+ tileset.tileOffset = { x: Number(offset.x) || 0, y: Number(offset.y) || 0 };
149
+ }
150
+ return tileset;
151
+ }
152
+ normalizeJsonTile(json) {
153
+ var _a;
154
+ const tile = {
155
+ id: Number(json.id) || 0,
156
+ type: json.type ? String(json.type) : undefined,
157
+ properties: this.normalizeProperties(json.properties),
158
+ };
159
+ if (json.animation) {
160
+ tile.animation = json.animation.map((f) => ({
161
+ tileId: Number(f.tileid),
162
+ duration: Number(f.duration),
163
+ }));
164
+ }
165
+ if (json.objectgroup) {
166
+ const og = json.objectgroup;
167
+ tile.objectGroup = {
168
+ drawOrder: String(og.draworder || 'index'),
169
+ id: Number(og.id) || 0,
170
+ name: String(og.name || ''),
171
+ objects: ((_a = og.objects) === null || _a === void 0 ? void 0 : _a.map((o) => this.normalizeJsonObject(o))) || [],
172
+ };
173
+ }
174
+ return tile;
175
+ }
176
+ normalizeJsonLayer(json) {
177
+ var _a;
178
+ const layer = {
179
+ id: Number(json.id) || 0,
180
+ name: String(json.name || ''),
181
+ type: json.type || 'tilelayer',
182
+ visible: json.visible !== false,
183
+ opacity: json.opacity !== undefined ? Number(json.opacity) : 1,
184
+ offsetX: Number(json.offsetx) || 0,
185
+ offsetY: Number(json.offsety) || 0,
186
+ parallaxX: json.parallaxx !== undefined ? Number(json.parallaxx) : 1,
187
+ parallaxY: json.parallaxy !== undefined ? Number(json.parallaxy) : 1,
188
+ tintColor: json.tintcolor ? String(json.tintcolor) : undefined,
189
+ locked: json.locked ? Boolean(json.locked) : undefined,
190
+ class: json.class ? String(json.class) : undefined,
191
+ properties: this.normalizeProperties(json.properties),
192
+ };
193
+ // Tile layer specific
194
+ if (json.type === 'tilelayer') {
195
+ layer.width = Number(json.width) || 0;
196
+ layer.height = Number(json.height) || 0;
197
+ layer.data = json.data;
198
+ layer.encoding = json.encoding;
199
+ layer.compression = json.compression;
200
+ if (json.chunks) {
201
+ layer.chunks = json.chunks.map((c) => {
202
+ const chunk = c;
203
+ return {
204
+ x: Number(chunk.x),
205
+ y: Number(chunk.y),
206
+ width: Number(chunk.width),
207
+ height: Number(chunk.height),
208
+ data: chunk.data,
209
+ };
210
+ });
211
+ }
212
+ }
213
+ // Object layer specific
214
+ if (json.type === 'objectgroup') {
215
+ layer.objects =
216
+ ((_a = json.objects) === null || _a === void 0 ? void 0 : _a.map((o) => this.normalizeJsonObject(o))) || [];
217
+ layer.drawOrder = json.draworder || 'topdown';
218
+ layer.color = json.color ? String(json.color) : undefined;
219
+ }
220
+ // Image layer specific
221
+ if (json.type === 'imagelayer') {
222
+ layer.image = json.image ? String(json.image) : undefined;
223
+ layer.repeatX = json.repeatx ? Boolean(json.repeatx) : undefined;
224
+ layer.repeatY = json.repeaty ? Boolean(json.repeaty) : undefined;
225
+ }
226
+ // Group layer specific
227
+ if (json.type === 'group' && json.layers) {
228
+ layer.layers = json.layers.map((l) => this.normalizeJsonLayer(l));
229
+ }
230
+ return layer;
231
+ }
232
+ normalizeJsonObject(json) {
233
+ return {
234
+ id: Number(json.id) || 0,
235
+ name: String(json.name || ''),
236
+ type: String(json.type || json.class || ''),
237
+ x: Number(json.x) || 0,
238
+ y: Number(json.y) || 0,
239
+ width: Number(json.width) || 0,
240
+ height: Number(json.height) || 0,
241
+ rotation: Number(json.rotation) || 0,
242
+ visible: json.visible !== false,
243
+ gid: json.gid ? Number(json.gid) : undefined,
244
+ template: json.template ? String(json.template) : undefined,
245
+ point: json.point ? Boolean(json.point) : undefined,
246
+ ellipse: json.ellipse ? Boolean(json.ellipse) : undefined,
247
+ polygon: json.polygon,
248
+ polyline: json.polyline,
249
+ text: json.text,
250
+ properties: this.normalizeProperties(json.properties),
251
+ };
252
+ }
253
+ normalizeProperties(props) {
254
+ if (!props)
255
+ return undefined;
256
+ return props.map((p) => {
257
+ const prop = p;
258
+ return {
259
+ name: String(prop.name || ''),
260
+ type: prop.type || 'string',
261
+ value: prop.value,
262
+ propertyType: prop.propertytype ? String(prop.propertytype) : undefined,
263
+ };
264
+ });
265
+ }
266
+ parseXmlMap(content) {
267
+ try {
268
+ const xml = SceneImporter.parseXML(content);
269
+ return this.normalizeXmlMap(xml);
270
+ }
271
+ catch (error) {
272
+ this.addError('XML_PARSE_ERROR', `Failed to parse XML: ${error}`);
273
+ return null;
274
+ }
275
+ }
276
+ normalizeXmlMap(xml) {
277
+ const map = {
278
+ version: xml.attributes.version || '1.0',
279
+ tiledVersion: xml.attributes.tiledversion || '',
280
+ orientation: xml.attributes.orientation || 'orthogonal',
281
+ renderOrder: xml.attributes.renderorder || 'right-down',
282
+ width: parseInt(xml.attributes.width || '0', 10),
283
+ height: parseInt(xml.attributes.height || '0', 10),
284
+ tileWidth: parseInt(xml.attributes.tilewidth || '0', 10),
285
+ tileHeight: parseInt(xml.attributes.tileheight || '0', 10),
286
+ infinite: xml.attributes.infinite === '1',
287
+ backgroundColor: xml.attributes.backgroundcolor,
288
+ nextLayerId: parseInt(xml.attributes.nextlayerid || '0', 10),
289
+ nextObjectId: parseInt(xml.attributes.nextobjectid || '0', 10),
290
+ tilesets: [],
291
+ layers: [],
292
+ properties: this.parseXmlProperties(xml.children.find((c) => c.name === 'properties')),
293
+ };
294
+ // Parse tilesets
295
+ for (const child of xml.children.filter((c) => c.name === 'tileset')) {
296
+ map.tilesets.push(this.normalizeXmlTileset(child));
297
+ }
298
+ // Parse layers
299
+ for (const child of xml.children) {
300
+ if (['layer', 'objectgroup', 'imagelayer', 'group'].includes(child.name)) {
301
+ map.layers.push(this.normalizeXmlLayer(child));
302
+ }
303
+ }
304
+ return map;
305
+ }
306
+ normalizeXmlTileset(xml) {
307
+ const tileset = {
308
+ firstGid: parseInt(xml.attributes.firstgid || '0', 10),
309
+ source: xml.attributes.source,
310
+ name: xml.attributes.name || '',
311
+ tileWidth: parseInt(xml.attributes.tilewidth || '0', 10),
312
+ tileHeight: parseInt(xml.attributes.tileheight || '0', 10),
313
+ spacing: parseInt(xml.attributes.spacing || '0', 10),
314
+ margin: parseInt(xml.attributes.margin || '0', 10),
315
+ tileCount: parseInt(xml.attributes.tilecount || '0', 10),
316
+ columns: parseInt(xml.attributes.columns || '0', 10),
317
+ properties: this.parseXmlProperties(xml.children.find((c) => c.name === 'properties')),
318
+ };
319
+ // Image
320
+ const image = xml.children.find((c) => c.name === 'image');
321
+ if (image) {
322
+ tileset.image = image.attributes.source;
323
+ tileset.imageWidth = parseInt(image.attributes.width || '0', 10);
324
+ tileset.imageHeight = parseInt(image.attributes.height || '0', 10);
325
+ tileset.transparentColor = image.attributes.trans;
326
+ }
327
+ // Tiles
328
+ const tiles = xml.children.filter((c) => c.name === 'tile');
329
+ if (tiles.length > 0) {
330
+ tileset.tiles = tiles.map((t) => this.normalizeXmlTile(t));
331
+ }
332
+ // Tile offset
333
+ const offset = xml.children.find((c) => c.name === 'tileoffset');
334
+ if (offset) {
335
+ tileset.tileOffset = {
336
+ x: parseInt(offset.attributes.x || '0', 10),
337
+ y: parseInt(offset.attributes.y || '0', 10),
338
+ };
339
+ }
340
+ return tileset;
341
+ }
342
+ normalizeXmlTile(xml) {
343
+ const tile = {
344
+ id: parseInt(xml.attributes.id || '0', 10),
345
+ type: xml.attributes.type,
346
+ properties: this.parseXmlProperties(xml.children.find((c) => c.name === 'properties')),
347
+ };
348
+ // Animation
349
+ const animation = xml.children.find((c) => c.name === 'animation');
350
+ if (animation) {
351
+ tile.animation = animation.children
352
+ .filter((c) => c.name === 'frame')
353
+ .map((f) => ({
354
+ tileId: parseInt(f.attributes.tileid || '0', 10),
355
+ duration: parseInt(f.attributes.duration || '0', 10),
356
+ }));
357
+ }
358
+ // Collision (objectgroup)
359
+ const objectGroup = xml.children.find((c) => c.name === 'objectgroup');
360
+ if (objectGroup) {
361
+ tile.objectGroup = {
362
+ drawOrder: objectGroup.attributes.draworder || 'index',
363
+ id: parseInt(objectGroup.attributes.id || '0', 10),
364
+ name: objectGroup.attributes.name || '',
365
+ objects: objectGroup.children
366
+ .filter((c) => c.name === 'object')
367
+ .map((o) => this.normalizeXmlObject(o)),
368
+ };
369
+ }
370
+ return tile;
371
+ }
372
+ normalizeXmlLayer(xml) {
373
+ const type = this.getLayerType(xml.name);
374
+ const layer = {
375
+ id: parseInt(xml.attributes.id || '0', 10),
376
+ name: xml.attributes.name || '',
377
+ type,
378
+ visible: xml.attributes.visible !== '0',
379
+ opacity: parseFloat(xml.attributes.opacity || '1'),
380
+ offsetX: parseFloat(xml.attributes.offsetx || '0'),
381
+ offsetY: parseFloat(xml.attributes.offsety || '0'),
382
+ parallaxX: parseFloat(xml.attributes.parallaxx || '1'),
383
+ parallaxY: parseFloat(xml.attributes.parallaxy || '1'),
384
+ tintColor: xml.attributes.tintcolor,
385
+ locked: xml.attributes.locked === '1',
386
+ class: xml.attributes.class,
387
+ properties: this.parseXmlProperties(xml.children.find((c) => c.name === 'properties')),
388
+ };
389
+ // Tile layer
390
+ if (type === 'tilelayer') {
391
+ layer.width = parseInt(xml.attributes.width || '0', 10);
392
+ layer.height = parseInt(xml.attributes.height || '0', 10);
393
+ const dataNode = xml.children.find((c) => c.name === 'data');
394
+ if (dataNode) {
395
+ layer.encoding = dataNode.attributes.encoding;
396
+ layer.compression = dataNode.attributes.compression;
397
+ if (layer.encoding === 'csv' || !layer.encoding) {
398
+ // CSV data
399
+ layer.data = dataNode.text.split(',').map((s) => parseInt(s.trim(), 10));
400
+ }
401
+ else if (layer.encoding === 'base64') {
402
+ // Base64 encoded - would need decompression for gzip/zlib
403
+ // For now, store as warning
404
+ this.addWarning('BASE64_DATA', 'Base64 encoded tile data requires decompression', xml.attributes.name);
405
+ }
406
+ // Chunks for infinite maps
407
+ const chunks = dataNode.children.filter((c) => c.name === 'chunk');
408
+ if (chunks.length > 0) {
409
+ layer.chunks = chunks.map((c) => ({
410
+ x: parseInt(c.attributes.x || '0', 10),
411
+ y: parseInt(c.attributes.y || '0', 10),
412
+ width: parseInt(c.attributes.width || '0', 10),
413
+ height: parseInt(c.attributes.height || '0', 10),
414
+ data: c.text.split(',').map((s) => parseInt(s.trim(), 10)),
415
+ }));
416
+ }
417
+ }
418
+ }
419
+ // Object layer
420
+ if (type === 'objectgroup') {
421
+ layer.objects = xml.children
422
+ .filter((c) => c.name === 'object')
423
+ .map((o) => this.normalizeXmlObject(o));
424
+ layer.drawOrder = xml.attributes.draworder || 'topdown';
425
+ layer.color = xml.attributes.color;
426
+ }
427
+ // Image layer
428
+ if (type === 'imagelayer') {
429
+ const image = xml.children.find((c) => c.name === 'image');
430
+ if (image) {
431
+ layer.image = image.attributes.source;
432
+ }
433
+ layer.repeatX = xml.attributes.repeatx === '1';
434
+ layer.repeatY = xml.attributes.repeaty === '1';
435
+ }
436
+ // Group layer
437
+ if (type === 'group') {
438
+ layer.layers = [];
439
+ for (const child of xml.children) {
440
+ if (['layer', 'objectgroup', 'imagelayer', 'group'].includes(child.name)) {
441
+ layer.layers.push(this.normalizeXmlLayer(child));
442
+ }
443
+ }
444
+ }
445
+ return layer;
446
+ }
447
+ normalizeXmlObject(xml) {
448
+ const obj = {
449
+ id: parseInt(xml.attributes.id || '0', 10),
450
+ name: xml.attributes.name || '',
451
+ type: xml.attributes.type || xml.attributes.class || '',
452
+ x: parseFloat(xml.attributes.x || '0'),
453
+ y: parseFloat(xml.attributes.y || '0'),
454
+ width: parseFloat(xml.attributes.width || '0'),
455
+ height: parseFloat(xml.attributes.height || '0'),
456
+ rotation: parseFloat(xml.attributes.rotation || '0'),
457
+ visible: xml.attributes.visible !== '0',
458
+ gid: xml.attributes.gid ? parseInt(xml.attributes.gid, 10) : undefined,
459
+ template: xml.attributes.template,
460
+ properties: this.parseXmlProperties(xml.children.find((c) => c.name === 'properties')),
461
+ };
462
+ // Point
463
+ if (xml.children.some((c) => c.name === 'point')) {
464
+ obj.point = true;
465
+ }
466
+ // Ellipse
467
+ if (xml.children.some((c) => c.name === 'ellipse')) {
468
+ obj.ellipse = true;
469
+ }
470
+ // Polygon
471
+ const polygon = xml.children.find((c) => c.name === 'polygon');
472
+ if (polygon && polygon.attributes.points) {
473
+ obj.polygon = this.parsePoints(polygon.attributes.points);
474
+ }
475
+ // Polyline
476
+ const polyline = xml.children.find((c) => c.name === 'polyline');
477
+ if (polyline && polyline.attributes.points) {
478
+ obj.polyline = this.parsePoints(polyline.attributes.points);
479
+ }
480
+ // Text
481
+ const text = xml.children.find((c) => c.name === 'text');
482
+ if (text) {
483
+ obj.text = {
484
+ text: text.text || '',
485
+ fontFamily: text.attributes.fontfamily || 'sans-serif',
486
+ pixelSize: parseInt(text.attributes.pixelsize || '16', 10),
487
+ wrap: text.attributes.wrap === '1',
488
+ color: text.attributes.color || '#000000',
489
+ bold: text.attributes.bold === '1',
490
+ italic: text.attributes.italic === '1',
491
+ underline: text.attributes.underline === '1',
492
+ strikeout: text.attributes.strikeout === '1',
493
+ kerning: text.attributes.kerning !== '0',
494
+ halign: text.attributes.halign || 'left',
495
+ valign: text.attributes.valign || 'top',
496
+ };
497
+ }
498
+ return obj;
499
+ }
500
+ parseXmlProperties(xml) {
501
+ if (!xml)
502
+ return undefined;
503
+ return xml.children
504
+ .filter((c) => c.name === 'property')
505
+ .map((p) => ({
506
+ name: p.attributes.name || '',
507
+ type: p.attributes.type || 'string',
508
+ value: this.parsePropertyValue(p.attributes.value || p.text, p.attributes.type),
509
+ propertyType: p.attributes.propertytype,
510
+ }));
511
+ }
512
+ parsePropertyValue(value, type) {
513
+ switch (type) {
514
+ case 'int':
515
+ return parseInt(value, 10);
516
+ case 'float':
517
+ return parseFloat(value);
518
+ case 'bool':
519
+ return value === 'true';
520
+ default:
521
+ return value;
522
+ }
523
+ }
524
+ parsePoints(pointsStr) {
525
+ return pointsStr.split(' ').map((p) => {
526
+ const [x, y] = p.split(',').map((v) => parseFloat(v));
527
+ return { x, y };
528
+ });
529
+ }
530
+ getLayerType(xmlName) {
531
+ switch (xmlName) {
532
+ case 'layer':
533
+ return 'tilelayer';
534
+ case 'objectgroup':
535
+ return 'objectgroup';
536
+ case 'imagelayer':
537
+ return 'imagelayer';
538
+ case 'group':
539
+ return 'group';
540
+ default:
541
+ return 'tilelayer';
542
+ }
543
+ }
544
+ async loadExternalTilesets(map, mapPath) {
545
+ const basePath = mapPath.substring(0, mapPath.lastIndexOf('/') + 1);
546
+ for (const tileset of map.tilesets) {
547
+ if (tileset.source) {
548
+ try {
549
+ const tilesetPath = basePath + tileset.source;
550
+ const content = await this.readFile(tilesetPath);
551
+ const isJson = tileset.source.endsWith('.tsj') || tileset.source.endsWith('.json');
552
+ let externalTileset;
553
+ if (isJson) {
554
+ const json = JSON.parse(content);
555
+ externalTileset = this.normalizeJsonTileset(json);
556
+ }
557
+ else {
558
+ const xml = SceneImporter.parseXML(content);
559
+ const tilesetNode = xml.name === 'tileset' ? xml : xml.children.find((c) => c.name === 'tileset');
560
+ if (tilesetNode) {
561
+ externalTileset = this.normalizeXmlTileset(tilesetNode);
562
+ }
563
+ else {
564
+ continue;
565
+ }
566
+ }
567
+ // Merge external tileset data
568
+ Object.assign(tileset, externalTileset, { firstGid: tileset.firstGid });
569
+ }
570
+ catch (error) {
571
+ this.addWarning('TILESET_LOAD_ERROR', `Failed to load external tileset: ${tileset.source}`, tileset.source);
572
+ }
573
+ }
574
+ // Index tileset by first gid
575
+ this.tilesets.set(tileset.name, tileset);
576
+ this.tilesetsById.set(tileset.firstGid, tileset);
577
+ }
578
+ }
579
+ // ----------------------------------------
580
+ // Conversion
581
+ // ----------------------------------------
582
+ convertTiledMapToScene(map) {
583
+ const layers = [];
584
+ const entities = [];
585
+ let zIndex = 0;
586
+ this.processLayers(map.layers, layers, entities, zIndex);
587
+ return {
588
+ name: 'TiledMap',
589
+ width: map.width * map.tileWidth,
590
+ height: map.height * map.tileHeight,
591
+ backgroundColor: map.backgroundColor || '#000000',
592
+ layers,
593
+ entities,
594
+ properties: {
595
+ orientation: map.orientation,
596
+ renderOrder: map.renderOrder,
597
+ tileWidth: map.tileWidth,
598
+ tileHeight: map.tileHeight,
599
+ infinite: map.infinite,
600
+ ...this.convertProperties(map.properties),
601
+ },
602
+ };
603
+ }
604
+ processLayers(layers, outLayers, outEntities, zIndex) {
605
+ for (const layer of layers) {
606
+ if (layer.type === 'group' && layer.layers) {
607
+ zIndex = this.processLayers(layer.layers, outLayers, outEntities, zIndex);
608
+ }
609
+ else {
610
+ outLayers.push(this.convertLayer(layer, zIndex));
611
+ // Extract objects as entities
612
+ if (layer.type === 'objectgroup' && layer.objects) {
613
+ for (const obj of layer.objects) {
614
+ outEntities.push(this.convertObject(obj, layer.name, zIndex));
615
+ }
616
+ }
617
+ zIndex++;
618
+ }
619
+ }
620
+ return zIndex;
621
+ }
622
+ convertLayer(layer, zIndex) {
623
+ const parsedLayer = {
624
+ name: layer.name,
625
+ type: this.mapLayerType(layer.type),
626
+ visible: layer.visible,
627
+ opacity: layer.opacity,
628
+ offsetX: layer.offsetX,
629
+ offsetY: layer.offsetY,
630
+ parallaxX: layer.parallaxX,
631
+ parallaxY: layer.parallaxY,
632
+ zIndex,
633
+ properties: this.convertProperties(layer.properties),
634
+ };
635
+ // Tile data
636
+ if (layer.type === 'tilelayer' && layer.data) {
637
+ parsedLayer.data = {
638
+ width: layer.width || 0,
639
+ height: layer.height || 0,
640
+ tileWidth: 0, // Will be set from tileset
641
+ tileHeight: 0,
642
+ tiles: layer.data,
643
+ };
644
+ }
645
+ return parsedLayer;
646
+ }
647
+ mapLayerType(type) {
648
+ switch (type) {
649
+ case 'tilelayer':
650
+ return 'tile';
651
+ case 'objectgroup':
652
+ return 'object';
653
+ case 'imagelayer':
654
+ return 'image';
655
+ case 'group':
656
+ return 'group';
657
+ default:
658
+ return 'object';
659
+ }
660
+ }
661
+ convertObject(obj, layerName, zIndex) {
662
+ const components = [];
663
+ // Determine shape type
664
+ if (obj.polygon) {
665
+ components.push({
666
+ type: 'PolygonCollider',
667
+ data: {
668
+ points: obj.polygon,
669
+ isTrigger: false,
670
+ },
671
+ });
672
+ }
673
+ else if (obj.polyline) {
674
+ components.push({
675
+ type: 'EdgeCollider',
676
+ data: {
677
+ points: obj.polyline,
678
+ },
679
+ });
680
+ }
681
+ else if (obj.ellipse) {
682
+ components.push({
683
+ type: 'CircleCollider',
684
+ data: {
685
+ radius: Math.max(obj.width, obj.height) / 2,
686
+ isTrigger: false,
687
+ },
688
+ });
689
+ }
690
+ else if (obj.point) {
691
+ components.push({
692
+ type: 'Point',
693
+ data: {},
694
+ });
695
+ }
696
+ else if (obj.text) {
697
+ components.push({
698
+ type: 'Text',
699
+ data: {
700
+ text: obj.text.text,
701
+ fontFamily: obj.text.fontFamily,
702
+ fontSize: obj.text.pixelSize,
703
+ color: obj.text.color,
704
+ bold: obj.text.bold,
705
+ italic: obj.text.italic,
706
+ align: obj.text.halign,
707
+ valign: obj.text.valign,
708
+ wrap: obj.text.wrap,
709
+ },
710
+ });
711
+ }
712
+ else if (obj.gid) {
713
+ // Tile object
714
+ const tileset = this.findTilesetForGid(obj.gid);
715
+ if (tileset) {
716
+ const localId = obj.gid - tileset.firstGid;
717
+ components.push({
718
+ type: 'Sprite',
719
+ data: {
720
+ tileset: tileset.name,
721
+ tileId: localId,
722
+ width: obj.width,
723
+ height: obj.height,
724
+ },
725
+ });
726
+ }
727
+ }
728
+ else {
729
+ // Rectangle
730
+ components.push({
731
+ type: 'BoxCollider',
732
+ data: {
733
+ width: obj.width,
734
+ height: obj.height,
735
+ isTrigger: false,
736
+ },
737
+ });
738
+ }
739
+ return {
740
+ id: obj.id.toString(),
741
+ name: obj.name || `Object_${obj.id}`,
742
+ type: obj.type || 'TiledObject',
743
+ x: obj.x,
744
+ y: obj.y,
745
+ width: obj.width,
746
+ height: obj.height,
747
+ rotation: obj.rotation,
748
+ scaleX: 1,
749
+ scaleY: 1,
750
+ visible: obj.visible,
751
+ components,
752
+ children: [],
753
+ properties: {
754
+ layer: layerName,
755
+ zIndex,
756
+ ...this.convertProperties(obj.properties),
757
+ },
758
+ };
759
+ }
760
+ findTilesetForGid(gid) {
761
+ // Clear flip flags
762
+ const tileId = gid & 0x0fffffff;
763
+ let result = null;
764
+ let maxFirstGid = 0;
765
+ for (const [_, tileset] of this.tilesetsById) {
766
+ if (tileset.firstGid <= tileId && tileset.firstGid > maxFirstGid) {
767
+ maxFirstGid = tileset.firstGid;
768
+ result = tileset;
769
+ }
770
+ }
771
+ return result;
772
+ }
773
+ convertProperties(props) {
774
+ if (!props)
775
+ return {};
776
+ const result = {};
777
+ for (const prop of props) {
778
+ result[prop.name] = prop.value;
779
+ }
780
+ return result;
781
+ }
782
+ extractAssets(map) {
783
+ var _a;
784
+ const assets = [];
785
+ // Extract tileset images
786
+ for (const tileset of map.tilesets) {
787
+ if (tileset.image) {
788
+ assets.push({
789
+ id: this.generateId(),
790
+ name: tileset.name,
791
+ type: 'tileset',
792
+ path: tileset.image,
793
+ data: {
794
+ tileWidth: tileset.tileWidth,
795
+ tileHeight: tileset.tileHeight,
796
+ tileCount: tileset.tileCount,
797
+ columns: tileset.columns,
798
+ margin: tileset.margin,
799
+ spacing: tileset.spacing,
800
+ firstGid: tileset.firstGid,
801
+ tiles: (_a = tileset.tiles) === null || _a === void 0 ? void 0 : _a.map((t) => {
802
+ var _a;
803
+ return ({
804
+ id: t.id,
805
+ type: t.type,
806
+ animation: t.animation,
807
+ collision: (_a = t.objectGroup) === null || _a === void 0 ? void 0 : _a.objects,
808
+ });
809
+ }),
810
+ },
811
+ });
812
+ }
813
+ }
814
+ // Extract image layer images
815
+ for (const layer of this.flattenLayers(map.layers)) {
816
+ if (layer.type === 'imagelayer' && layer.image) {
817
+ assets.push({
818
+ id: this.generateId(),
819
+ name: layer.name + '_image',
820
+ type: 'texture',
821
+ path: layer.image,
822
+ data: {
823
+ repeatX: layer.repeatX,
824
+ repeatY: layer.repeatY,
825
+ },
826
+ });
827
+ }
828
+ }
829
+ return assets;
830
+ }
831
+ flattenLayers(layers) {
832
+ const result = [];
833
+ for (const layer of layers) {
834
+ result.push(layer);
835
+ if (layer.type === 'group' && layer.layers) {
836
+ result.push(...this.flattenLayers(layer.layers));
837
+ }
838
+ }
839
+ return result;
840
+ }
841
+ // ----------------------------------------
842
+ // Helper Methods
843
+ // ----------------------------------------
844
+ async readFile(path) {
845
+ var _a;
846
+ if (typeof globalThis.process !== 'undefined' && ((_a = globalThis.process.versions) === null || _a === void 0 ? void 0 : _a.node)) {
847
+ const fs = await import('fs');
848
+ return fs.readFileSync(path, 'utf-8');
849
+ }
850
+ else if (typeof fetch !== 'undefined') {
851
+ const response = await fetch(path);
852
+ return response.text();
853
+ }
854
+ throw new Error('Unable to read file in current environment');
855
+ }
856
+ }
857
+
858
+ exports.TiledMapImporter = TiledMapImporter;
859
+ //# sourceMappingURL=TiledMapImporter.js.map