@nice2dev/game-engine 0.1.0 → 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 (294) hide show
  1. package/CHANGELOG.md +193 -1
  2. package/dist/cjs/ai/BehaviorTree.js +1215 -0
  3. package/dist/cjs/ai/BehaviorTree.js.map +1 -0
  4. package/dist/cjs/ai/StateMachine.js +783 -0
  5. package/dist/cjs/ai/StateMachine.js.map +1 -0
  6. package/dist/cjs/audio/AudioBridge.js +454 -0
  7. package/dist/cjs/audio/AudioBridge.js.map +1 -0
  8. package/dist/cjs/devtools/GameplayAnalytics.js +651 -0
  9. package/dist/cjs/devtools/GameplayAnalytics.js.map +1 -0
  10. package/dist/cjs/dialogue/DialogueSystem.js +1023 -0
  11. package/dist/cjs/dialogue/DialogueSystem.js.map +1 -0
  12. package/dist/cjs/editor/NiceGameEditor.js +569 -71
  13. package/dist/cjs/editor/NiceGameEditor.js.map +1 -1
  14. package/dist/cjs/editor/ShaderGraph.js +1616 -0
  15. package/dist/cjs/editor/ShaderGraph.js.map +1 -0
  16. package/dist/cjs/editor/TimelineEditor.js +819 -0
  17. package/dist/cjs/editor/TimelineEditor.js.map +1 -0
  18. package/dist/cjs/engine/SaveSystemV2.js +494 -0
  19. package/dist/cjs/engine/SaveSystemV2.js.map +1 -0
  20. package/dist/cjs/export/GodotExporter.js +1102 -0
  21. package/dist/cjs/export/GodotExporter.js.map +1 -0
  22. package/dist/cjs/export/PlatformExporter.js +236 -0
  23. package/dist/cjs/export/PlatformExporter.js.map +1 -0
  24. package/dist/cjs/export/ThreeJSExporter.js +1116 -0
  25. package/dist/cjs/export/ThreeJSExporter.js.map +1 -0
  26. package/dist/cjs/export/UnityExporter.js +1193 -0
  27. package/dist/cjs/export/UnityExporter.js.map +1 -0
  28. package/dist/cjs/export/WebExporter.js +1036 -0
  29. package/dist/cjs/export/WebExporter.js.map +1 -0
  30. package/dist/cjs/export/index.js +58 -0
  31. package/dist/cjs/export/index.js.map +1 -0
  32. package/dist/cjs/i18n/useTranslation.js +11 -11
  33. package/dist/cjs/import/AsepriteImporter.js +761 -0
  34. package/dist/cjs/import/AsepriteImporter.js.map +1 -0
  35. package/dist/cjs/import/DragonBonesImporter.js +499 -0
  36. package/dist/cjs/import/DragonBonesImporter.js.map +1 -0
  37. package/dist/cjs/import/GameMakerImporter.js +559 -0
  38. package/dist/cjs/import/GameMakerImporter.js.map +1 -0
  39. package/dist/cjs/import/GodotSceneImporter.js +824 -0
  40. package/dist/cjs/import/GodotSceneImporter.js.map +1 -0
  41. package/dist/cjs/import/LDtkImporter.js +481 -0
  42. package/dist/cjs/import/LDtkImporter.js.map +1 -0
  43. package/dist/cjs/import/Live2DImporter.js +553 -0
  44. package/dist/cjs/import/Live2DImporter.js.map +1 -0
  45. package/dist/cjs/import/NdgFormat.js +499 -0
  46. package/dist/cjs/import/NdgFormat.js.map +1 -0
  47. package/dist/cjs/import/OgmoImporter.js +529 -0
  48. package/dist/cjs/import/OgmoImporter.js.map +1 -0
  49. package/dist/cjs/import/RPGMakerImporter.js +520 -0
  50. package/dist/cjs/import/RPGMakerImporter.js.map +1 -0
  51. package/dist/cjs/import/SceneImporter.js +449 -0
  52. package/dist/cjs/import/SceneImporter.js.map +1 -0
  53. package/dist/cjs/import/SpineImporter.js +583 -0
  54. package/dist/cjs/import/SpineImporter.js.map +1 -0
  55. package/dist/cjs/import/SpriterImporter.js +652 -0
  56. package/dist/cjs/import/SpriterImporter.js.map +1 -0
  57. package/dist/cjs/import/TiledMapImporter.js +859 -0
  58. package/dist/cjs/import/TiledMapImporter.js.map +1 -0
  59. package/dist/cjs/import/UnitySceneImporter.js +732 -0
  60. package/dist/cjs/import/UnitySceneImporter.js.map +1 -0
  61. package/dist/cjs/import/index.js +305 -0
  62. package/dist/cjs/import/index.js.map +1 -0
  63. package/dist/cjs/index.js +291 -1
  64. package/dist/cjs/index.js.map +1 -1
  65. package/dist/cjs/input/GamepadNavigation.js +21 -21
  66. package/dist/cjs/input/useGamepads.js +6 -6
  67. package/dist/cjs/integration/IconSprite.js +281 -0
  68. package/dist/cjs/integration/IconSprite.js.map +1 -0
  69. package/dist/cjs/inventory/InventorySystem.js +930 -0
  70. package/dist/cjs/inventory/InventorySystem.js.map +1 -0
  71. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AbortController.js.map +1 -1
  72. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js.map +1 -1
  73. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js.map +1 -1
  74. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js.map +1 -1
  75. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Errors.js.map +1 -1
  76. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js.map +1 -1
  77. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js.map +1 -1
  78. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js.map +1 -1
  79. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpClient.js.map +1 -1
  80. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js.map +1 -1
  81. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnection.js.map +1 -1
  82. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js.map +1 -1
  83. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js.map +1 -1
  84. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ILogger.js.map +1 -1
  85. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ITransport.js.map +1 -1
  86. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js.map +1 -1
  87. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Loggers.js.map +1 -1
  88. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js.map +1 -1
  89. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js.map +1 -1
  90. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js.map +1 -1
  91. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Subject.js.map +1 -1
  92. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js.map +1 -1
  93. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Utils.js.map +1 -1
  94. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js.map +1 -1
  95. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js.map +1 -1
  96. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/pkg-version.js.map +1 -1
  97. package/dist/cjs/quest/QuestSystem.js +924 -0
  98. package/dist/cjs/quest/QuestSystem.js.map +1 -0
  99. package/dist/cjs/rendering/WebGPURenderPipeline.js +658 -0
  100. package/dist/cjs/rendering/WebGPURenderPipeline.js.map +1 -0
  101. package/dist/cjs/scripting/GraphToAST.js +567 -0
  102. package/dist/cjs/scripting/GraphToAST.js.map +1 -0
  103. package/dist/cjs/scripting/LanguageExporter.js +321 -0
  104. package/dist/cjs/scripting/LanguageExporter.js.map +1 -0
  105. package/dist/cjs/scripting/ScriptAST.js +67 -0
  106. package/dist/cjs/scripting/ScriptAST.js.map +1 -0
  107. package/dist/cjs/scripting/VisualScripting2.js +1140 -0
  108. package/dist/cjs/scripting/VisualScripting2.js.map +1 -0
  109. package/dist/cjs/scripting/exporters/CSharpExporter.js +503 -0
  110. package/dist/cjs/scripting/exporters/CSharpExporter.js.map +1 -0
  111. package/dist/cjs/scripting/exporters/GDScriptExporter.js +452 -0
  112. package/dist/cjs/scripting/exporters/GDScriptExporter.js.map +1 -0
  113. package/dist/cjs/scripting/exporters/LuaExporter.js +457 -0
  114. package/dist/cjs/scripting/exporters/LuaExporter.js.map +1 -0
  115. package/dist/cjs/scripting/exporters/PythonExporter.js +565 -0
  116. package/dist/cjs/scripting/exporters/PythonExporter.js.map +1 -0
  117. package/dist/cjs/scripting/exporters/RustExporter.js +525 -0
  118. package/dist/cjs/scripting/exporters/RustExporter.js.map +1 -0
  119. package/dist/cjs/scripting/exporters/TypeScriptExporter.js +570 -0
  120. package/dist/cjs/scripting/exporters/TypeScriptExporter.js.map +1 -0
  121. package/dist/cjs/systems/ParticleSystem2.js +1478 -0
  122. package/dist/cjs/systems/ParticleSystem2.js.map +1 -0
  123. package/dist/cjs/xr/ARVR.js.map +1 -1
  124. package/dist/esm/ai/BehaviorTree.js +1186 -0
  125. package/dist/esm/ai/BehaviorTree.js.map +1 -0
  126. package/dist/esm/ai/StateMachine.js +767 -0
  127. package/dist/esm/ai/StateMachine.js.map +1 -0
  128. package/dist/esm/audio/AudioBridge.js +446 -0
  129. package/dist/esm/audio/AudioBridge.js.map +1 -0
  130. package/dist/esm/devtools/GameplayAnalytics.js +639 -0
  131. package/dist/esm/devtools/GameplayAnalytics.js.map +1 -0
  132. package/dist/esm/dialogue/DialogueSystem.js +1008 -0
  133. package/dist/esm/dialogue/DialogueSystem.js.map +1 -0
  134. package/dist/esm/editor/NiceGameEditor.js +556 -58
  135. package/dist/esm/editor/NiceGameEditor.js.map +1 -1
  136. package/dist/esm/editor/ShaderGraph.js +1606 -0
  137. package/dist/esm/editor/ShaderGraph.js.map +1 -0
  138. package/dist/esm/editor/TimelineEditor.js +800 -0
  139. package/dist/esm/editor/TimelineEditor.js.map +1 -0
  140. package/dist/esm/engine/SaveSystemV2.js +487 -0
  141. package/dist/esm/engine/SaveSystemV2.js.map +1 -0
  142. package/dist/esm/export/GodotExporter.js +1100 -0
  143. package/dist/esm/export/GodotExporter.js.map +1 -0
  144. package/dist/esm/export/PlatformExporter.js +230 -0
  145. package/dist/esm/export/PlatformExporter.js.map +1 -0
  146. package/dist/esm/export/ThreeJSExporter.js +1114 -0
  147. package/dist/esm/export/ThreeJSExporter.js.map +1 -0
  148. package/dist/esm/export/UnityExporter.js +1191 -0
  149. package/dist/esm/export/UnityExporter.js.map +1 -0
  150. package/dist/esm/export/WebExporter.js +1033 -0
  151. package/dist/esm/export/WebExporter.js.map +1 -0
  152. package/dist/esm/export/index.js +44 -0
  153. package/dist/esm/export/index.js.map +1 -0
  154. package/dist/esm/import/AsepriteImporter.js +759 -0
  155. package/dist/esm/import/AsepriteImporter.js.map +1 -0
  156. package/dist/esm/import/DragonBonesImporter.js +496 -0
  157. package/dist/esm/import/DragonBonesImporter.js.map +1 -0
  158. package/dist/esm/import/GameMakerImporter.js +556 -0
  159. package/dist/esm/import/GameMakerImporter.js.map +1 -0
  160. package/dist/esm/import/GodotSceneImporter.js +822 -0
  161. package/dist/esm/import/GodotSceneImporter.js.map +1 -0
  162. package/dist/esm/import/LDtkImporter.js +479 -0
  163. package/dist/esm/import/LDtkImporter.js.map +1 -0
  164. package/dist/esm/import/Live2DImporter.js +550 -0
  165. package/dist/esm/import/Live2DImporter.js.map +1 -0
  166. package/dist/esm/import/NdgFormat.js +490 -0
  167. package/dist/esm/import/NdgFormat.js.map +1 -0
  168. package/dist/esm/import/OgmoImporter.js +526 -0
  169. package/dist/esm/import/OgmoImporter.js.map +1 -0
  170. package/dist/esm/import/RPGMakerImporter.js +517 -0
  171. package/dist/esm/import/RPGMakerImporter.js.map +1 -0
  172. package/dist/esm/import/SceneImporter.js +441 -0
  173. package/dist/esm/import/SceneImporter.js.map +1 -0
  174. package/dist/esm/import/SpineImporter.js +580 -0
  175. package/dist/esm/import/SpineImporter.js.map +1 -0
  176. package/dist/esm/import/SpriterImporter.js +649 -0
  177. package/dist/esm/import/SpriterImporter.js.map +1 -0
  178. package/dist/esm/import/TiledMapImporter.js +857 -0
  179. package/dist/esm/import/TiledMapImporter.js.map +1 -0
  180. package/dist/esm/import/UnitySceneImporter.js +730 -0
  181. package/dist/esm/import/UnitySceneImporter.js.map +1 -0
  182. package/dist/esm/import/index.js +279 -0
  183. package/dist/esm/import/index.js.map +1 -0
  184. package/dist/esm/index.js +47 -3
  185. package/dist/esm/index.js.map +1 -1
  186. package/dist/esm/integration/IconSprite.js +266 -0
  187. package/dist/esm/integration/IconSprite.js.map +1 -0
  188. package/dist/esm/inventory/InventorySystem.js +924 -0
  189. package/dist/esm/inventory/InventorySystem.js.map +1 -0
  190. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AbortController.js.map +1 -1
  191. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js.map +1 -1
  192. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js.map +1 -1
  193. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js.map +1 -1
  194. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Errors.js.map +1 -1
  195. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js.map +1 -1
  196. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js.map +1 -1
  197. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js.map +1 -1
  198. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpClient.js.map +1 -1
  199. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js.map +1 -1
  200. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnection.js.map +1 -1
  201. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js.map +1 -1
  202. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js.map +1 -1
  203. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ILogger.js.map +1 -1
  204. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ITransport.js.map +1 -1
  205. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js.map +1 -1
  206. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Loggers.js.map +1 -1
  207. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js.map +1 -1
  208. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js.map +1 -1
  209. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js.map +1 -1
  210. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Subject.js.map +1 -1
  211. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js.map +1 -1
  212. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Utils.js.map +1 -1
  213. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js.map +1 -1
  214. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js.map +1 -1
  215. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/pkg-version.js.map +1 -1
  216. package/dist/esm/quest/QuestSystem.js +916 -0
  217. package/dist/esm/quest/QuestSystem.js.map +1 -0
  218. package/dist/esm/rendering/WebGPURenderPipeline.js +642 -0
  219. package/dist/esm/rendering/WebGPURenderPipeline.js.map +1 -0
  220. package/dist/esm/scripting/GraphToAST.js +564 -0
  221. package/dist/esm/scripting/GraphToAST.js.map +1 -0
  222. package/dist/esm/scripting/LanguageExporter.js +311 -0
  223. package/dist/esm/scripting/LanguageExporter.js.map +1 -0
  224. package/dist/esm/scripting/ScriptAST.js +52 -0
  225. package/dist/esm/scripting/ScriptAST.js.map +1 -0
  226. package/dist/esm/scripting/VisualScripting2.js +1130 -0
  227. package/dist/esm/scripting/VisualScripting2.js.map +1 -0
  228. package/dist/esm/scripting/exporters/CSharpExporter.js +501 -0
  229. package/dist/esm/scripting/exporters/CSharpExporter.js.map +1 -0
  230. package/dist/esm/scripting/exporters/GDScriptExporter.js +450 -0
  231. package/dist/esm/scripting/exporters/GDScriptExporter.js.map +1 -0
  232. package/dist/esm/scripting/exporters/LuaExporter.js +455 -0
  233. package/dist/esm/scripting/exporters/LuaExporter.js.map +1 -0
  234. package/dist/esm/scripting/exporters/PythonExporter.js +563 -0
  235. package/dist/esm/scripting/exporters/PythonExporter.js.map +1 -0
  236. package/dist/esm/scripting/exporters/RustExporter.js +523 -0
  237. package/dist/esm/scripting/exporters/RustExporter.js.map +1 -0
  238. package/dist/esm/scripting/exporters/TypeScriptExporter.js +568 -0
  239. package/dist/esm/scripting/exporters/TypeScriptExporter.js.map +1 -0
  240. package/dist/esm/systems/ParticleSystem2.js +1471 -0
  241. package/dist/esm/systems/ParticleSystem2.js.map +1 -0
  242. package/dist/esm/xr/ARVR.js.map +1 -1
  243. package/dist/types/__tests__/setup.d.ts +1 -1
  244. package/dist/types/ai/BehaviorTree.d.ts +375 -0
  245. package/dist/types/ai/StateMachine.d.ts +296 -0
  246. package/dist/types/audio/AudioBridge.d.ts +199 -0
  247. package/dist/types/devtools/GameplayAnalytics.d.ts +279 -0
  248. package/dist/types/dialogue/DialogueSystem.d.ts +326 -0
  249. package/dist/types/dialogue/index.d.ts +2 -0
  250. package/dist/types/editor/NiceGameEditor.d.ts +12 -1
  251. package/dist/types/editor/ShaderGraph.d.ts +207 -0
  252. package/dist/types/editor/TimelineEditor.d.ts +393 -0
  253. package/dist/types/engine/SaveSystemV2.d.ts +155 -0
  254. package/dist/types/export/GodotExporter.d.ts +56 -0
  255. package/dist/types/export/PlatformExporter.d.ts +201 -0
  256. package/dist/types/export/ThreeJSExporter.d.ts +40 -0
  257. package/dist/types/export/UnityExporter.d.ts +69 -0
  258. package/dist/types/export/WebExporter.d.ts +58 -0
  259. package/dist/types/export/index.d.ts +19 -0
  260. package/dist/types/import/AsepriteImporter.d.ts +46 -0
  261. package/dist/types/import/DragonBonesImporter.d.ts +331 -0
  262. package/dist/types/import/GameMakerImporter.d.ts +375 -0
  263. package/dist/types/import/GodotSceneImporter.d.ts +34 -0
  264. package/dist/types/import/LDtkImporter.d.ts +177 -0
  265. package/dist/types/import/Live2DImporter.d.ts +237 -0
  266. package/dist/types/import/NdgFormat.d.ts +387 -0
  267. package/dist/types/import/OgmoImporter.d.ts +237 -0
  268. package/dist/types/import/RPGMakerImporter.d.ts +186 -0
  269. package/dist/types/import/SceneImporter.d.ts +276 -0
  270. package/dist/types/import/SpineImporter.d.ts +372 -0
  271. package/dist/types/import/SpriterImporter.d.ts +230 -0
  272. package/dist/types/import/TiledMapImporter.d.ts +57 -0
  273. package/dist/types/import/UnitySceneImporter.d.ts +87 -0
  274. package/dist/types/import/index.d.ts +59 -0
  275. package/dist/types/index.d.ts +46 -18
  276. package/dist/types/integration/IconSprite.d.ts +196 -0
  277. package/dist/types/inventory/InventorySystem.d.ts +336 -0
  278. package/dist/types/performance/WebGPUCompute.d.ts +0 -10
  279. package/dist/types/quest/QuestSystem.d.ts +287 -0
  280. package/dist/types/rendering/WebGPURenderPipeline.d.ts +255 -0
  281. package/dist/types/scripting/GraphToAST.d.ts +55 -0
  282. package/dist/types/scripting/LanguageExporter.d.ts +136 -0
  283. package/dist/types/scripting/ScriptAST.d.ts +312 -0
  284. package/dist/types/scripting/VisualScripting2.d.ts +353 -0
  285. package/dist/types/scripting/exporters/CSharpExporter.d.ts +44 -0
  286. package/dist/types/scripting/exporters/GDScriptExporter.d.ts +46 -0
  287. package/dist/types/scripting/exporters/LuaExporter.d.ts +46 -0
  288. package/dist/types/scripting/exporters/PythonExporter.d.ts +49 -0
  289. package/dist/types/scripting/exporters/RustExporter.d.ts +46 -0
  290. package/dist/types/scripting/exporters/TypeScriptExporter.d.ts +48 -0
  291. package/dist/types/scripting/exporters/index.d.ts +8 -0
  292. package/dist/types/scripting/index.d.ts +11 -0
  293. package/dist/types/systems/ParticleSystem2.d.ts +646 -0
  294. package/package.json +7 -1
@@ -0,0 +1,916 @@
1
+ import { EventBus } from '../core/EventBus.js';
2
+ import React from 'react';
3
+
4
+ /* ────────────────────────────────────────────────────────────────
5
+ Quest & Mission System
6
+
7
+ A comprehensive quest system with:
8
+ - Multiple quest types (main, side, daily, achievement)
9
+ - Objectives with progress tracking
10
+ - Rewards and prerequisites
11
+ - Quest chains and dependencies
12
+ - State persistence
13
+ ──────────────────────────────────────────────────────────────── */
14
+ /* ═══════════════════════════════════════════════════════════════
15
+ QUEST MANAGER
16
+ ══════════════════════════════════════════════════════════════════ */
17
+ class QuestManager {
18
+ constructor(events) {
19
+ this.quests = new Map();
20
+ this.journal = {
21
+ activeQuests: [],
22
+ completedQuests: [],
23
+ failedQuests: [],
24
+ };
25
+ this.playerLevel = 1;
26
+ this.playerItems = new Set();
27
+ this.playerSkills = new Set();
28
+ this.reputation = new Map();
29
+ this.customConditions = new Map();
30
+ this.events = events !== null && events !== void 0 ? events : new EventBus();
31
+ }
32
+ /* ── Quest Registration ───────────────────────────────────────── */
33
+ registerQuest(quest) {
34
+ this.quests.set(quest.id, quest);
35
+ }
36
+ registerQuests(quests) {
37
+ for (const quest of quests) {
38
+ this.registerQuest(quest);
39
+ }
40
+ }
41
+ unregisterQuest(questId) {
42
+ this.quests.delete(questId);
43
+ }
44
+ getQuest(questId) {
45
+ return this.quests.get(questId);
46
+ }
47
+ getAllQuests() {
48
+ return Array.from(this.quests.values());
49
+ }
50
+ /* ── Player State ─────────────────────────────────────────────── */
51
+ setPlayerLevel(level) {
52
+ this.playerLevel = level;
53
+ this.checkQuestUnlocks();
54
+ }
55
+ addPlayerItem(itemId) {
56
+ this.playerItems.add(itemId);
57
+ this.checkQuestUnlocks();
58
+ }
59
+ removePlayerItem(itemId) {
60
+ this.playerItems.delete(itemId);
61
+ }
62
+ addPlayerSkill(skillId) {
63
+ this.playerSkills.add(skillId);
64
+ this.checkQuestUnlocks();
65
+ }
66
+ setReputation(factionId, amount) {
67
+ this.reputation.set(factionId, amount);
68
+ this.checkQuestUnlocks();
69
+ }
70
+ addReputation(factionId, amount) {
71
+ var _a;
72
+ const current = (_a = this.reputation.get(factionId)) !== null && _a !== void 0 ? _a : 0;
73
+ this.reputation.set(factionId, current + amount);
74
+ this.checkQuestUnlocks();
75
+ }
76
+ registerCustomCondition(key, condition) {
77
+ this.customConditions.set(key, condition);
78
+ }
79
+ /* ── Quest State ──────────────────────────────────────────────── */
80
+ getQuestState(questId) {
81
+ var _a, _b;
82
+ return (_b = (_a = this.journal.activeQuests.find(q => q.questId === questId)) !== null && _a !== void 0 ? _a : this.journal.completedQuests.find(q => q.questId === questId)) !== null && _b !== void 0 ? _b : this.journal.failedQuests.find(q => q.questId === questId);
83
+ }
84
+ getQuestStatus(questId) {
85
+ const state = this.getQuestState(questId);
86
+ if (state)
87
+ return state.status;
88
+ const quest = this.quests.get(questId);
89
+ if (!quest)
90
+ return 'locked';
91
+ return this.canUnlockQuest(questId) ? 'available' : 'locked';
92
+ }
93
+ getActiveQuests() {
94
+ return [...this.journal.activeQuests];
95
+ }
96
+ getCompletedQuests() {
97
+ return [...this.journal.completedQuests];
98
+ }
99
+ getAvailableQuests() {
100
+ return this.getAllQuests().filter(q => {
101
+ const status = this.getQuestStatus(q.id);
102
+ return status === 'available';
103
+ });
104
+ }
105
+ getJournal() {
106
+ return { ...this.journal };
107
+ }
108
+ /* ── Quest Flow ───────────────────────────────────────────────── */
109
+ canUnlockQuest(questId) {
110
+ const quest = this.quests.get(questId);
111
+ if (!quest)
112
+ return false;
113
+ // Already active or completed
114
+ const existingState = this.getQuestState(questId);
115
+ if (existingState && (existingState.status === 'active' || existingState.status === 'completed')) {
116
+ // Check if repeatable
117
+ if (!quest.repeatable)
118
+ return false;
119
+ if (existingState.lastCompletedAt && quest.repeatCooldown) {
120
+ if (Date.now() - existingState.lastCompletedAt < quest.repeatCooldown) {
121
+ return false;
122
+ }
123
+ }
124
+ }
125
+ // Check prerequisites
126
+ return quest.prerequisites.every(prereq => this.checkPrerequisite(prereq));
127
+ }
128
+ checkPrerequisite(prereq) {
129
+ var _a, _b;
130
+ switch (prereq.type) {
131
+ case 'quest':
132
+ if (!prereq.questId)
133
+ return true;
134
+ const state = this.getQuestState(prereq.questId);
135
+ return (state === null || state === void 0 ? void 0 : state.status) === 'completed';
136
+ case 'level':
137
+ return this.playerLevel >= ((_a = prereq.level) !== null && _a !== void 0 ? _a : 0);
138
+ case 'item':
139
+ return prereq.itemId ? this.playerItems.has(prereq.itemId) : true;
140
+ case 'reputation':
141
+ if (!prereq.reputation)
142
+ return true;
143
+ const rep = (_b = this.reputation.get(prereq.reputation.factionId)) !== null && _b !== void 0 ? _b : 0;
144
+ return rep >= prereq.reputation.amount;
145
+ case 'skill':
146
+ return prereq.skillId ? this.playerSkills.has(prereq.skillId) : true;
147
+ case 'time':
148
+ if (!prereq.timeWindow)
149
+ return true;
150
+ const now = Date.now();
151
+ return now >= prereq.timeWindow.start && now <= prereq.timeWindow.end;
152
+ case 'custom':
153
+ if (!prereq.customKey)
154
+ return true;
155
+ const condition = this.customConditions.get(prereq.customKey);
156
+ return condition ? condition() : false;
157
+ default:
158
+ return true;
159
+ }
160
+ }
161
+ acceptQuest(questId) {
162
+ var _a, _b;
163
+ if (!this.canUnlockQuest(questId))
164
+ return false;
165
+ const quest = this.quests.get(questId);
166
+ if (!quest)
167
+ return false;
168
+ // Remove from failed if re-accepting
169
+ this.journal.failedQuests = this.journal.failedQuests.filter(q => q.questId !== questId);
170
+ // Create fresh objectives with 0 progress
171
+ const objectives = quest.objectives.map(obj => ({
172
+ ...obj,
173
+ current: 0,
174
+ completed: false,
175
+ }));
176
+ const state = {
177
+ questId,
178
+ status: 'active',
179
+ objectives,
180
+ startedAt: Date.now(),
181
+ completionCount: (_b = (_a = this.getQuestState(questId)) === null || _a === void 0 ? void 0 : _a.completionCount) !== null && _b !== void 0 ? _b : 0,
182
+ };
183
+ if (quest.timeLimit) {
184
+ state.timeRemaining = quest.timeLimit * 1000;
185
+ }
186
+ this.journal.activeQuests.push(state);
187
+ this.emitEvent('quest:accepted', questId, {});
188
+ return true;
189
+ }
190
+ abandonQuest(questId) {
191
+ const quest = this.quests.get(questId);
192
+ if (!(quest === null || quest === void 0 ? void 0 : quest.canAbandon))
193
+ return false;
194
+ const stateIndex = this.journal.activeQuests.findIndex(q => q.questId === questId);
195
+ if (stateIndex === -1)
196
+ return false;
197
+ const state = this.journal.activeQuests[stateIndex];
198
+ state.status = 'failed';
199
+ state.endedAt = Date.now();
200
+ this.journal.activeQuests.splice(stateIndex, 1);
201
+ this.journal.failedQuests.push(state);
202
+ this.emitEvent('quest:abandoned', questId, {});
203
+ return true;
204
+ }
205
+ /* ── Objective Progress ───────────────────────────────────────── */
206
+ updateObjectiveProgress(questId, objectiveId, amount) {
207
+ const state = this.journal.activeQuests.find(q => q.questId === questId);
208
+ if (!state || state.status !== 'active')
209
+ return false;
210
+ const objective = state.objectives.find(o => o.id === objectiveId);
211
+ if (!objective || objective.completed)
212
+ return false;
213
+ const previousValue = objective.current;
214
+ objective.current = Math.min(objective.current + amount, objective.target);
215
+ this.emitEvent('quest:objective-progress', questId, {
216
+ objectiveId,
217
+ previous: previousValue,
218
+ current: objective.current,
219
+ target: objective.target,
220
+ });
221
+ // Check if objective completed
222
+ if (objective.current >= objective.target) {
223
+ objective.completed = true;
224
+ this.emitEvent('quest:objective-completed', questId, { objectiveId });
225
+ this.checkQuestCompletion(questId);
226
+ }
227
+ return true;
228
+ }
229
+ setObjectiveProgress(questId, objectiveId, value) {
230
+ const state = this.journal.activeQuests.find(q => q.questId === questId);
231
+ if (!state || state.status !== 'active')
232
+ return false;
233
+ const objective = state.objectives.find(o => o.id === objectiveId);
234
+ if (!objective || objective.completed)
235
+ return false;
236
+ const previousValue = objective.current;
237
+ objective.current = Math.min(value, objective.target);
238
+ if (objective.current !== previousValue) {
239
+ this.emitEvent('quest:objective-progress', questId, {
240
+ objectiveId,
241
+ previous: previousValue,
242
+ current: objective.current,
243
+ target: objective.target,
244
+ });
245
+ }
246
+ if (objective.current >= objective.target) {
247
+ objective.completed = true;
248
+ this.emitEvent('quest:objective-completed', questId, { objectiveId });
249
+ this.checkQuestCompletion(questId);
250
+ }
251
+ return true;
252
+ }
253
+ completeObjective(questId, objectiveId) {
254
+ const state = this.journal.activeQuests.find(q => q.questId === questId);
255
+ if (!state || state.status !== 'active')
256
+ return false;
257
+ const objective = state.objectives.find(o => o.id === objectiveId);
258
+ if (!objective || objective.completed)
259
+ return false;
260
+ objective.current = objective.target;
261
+ objective.completed = true;
262
+ this.emitEvent('quest:objective-completed', questId, { objectiveId });
263
+ this.checkQuestCompletion(questId);
264
+ return true;
265
+ }
266
+ /* ── Quest Completion ─────────────────────────────────────────── */
267
+ checkQuestCompletion(questId) {
268
+ const state = this.journal.activeQuests.find(q => q.questId === questId);
269
+ if (!state)
270
+ return;
271
+ // Check if all required objectives are complete
272
+ const requiredComplete = state.objectives
273
+ .filter(o => !o.optional)
274
+ .every(o => o.completed);
275
+ if (requiredComplete) {
276
+ this.completeQuest(questId);
277
+ }
278
+ }
279
+ completeQuest(questId) {
280
+ const stateIndex = this.journal.activeQuests.findIndex(q => q.questId === questId);
281
+ if (stateIndex === -1)
282
+ return false;
283
+ const state = this.journal.activeQuests[stateIndex];
284
+ state.status = 'completed';
285
+ state.endedAt = Date.now();
286
+ state.completionCount++;
287
+ state.lastCompletedAt = Date.now();
288
+ this.journal.activeQuests.splice(stateIndex, 1);
289
+ this.journal.completedQuests.push(state);
290
+ this.emitEvent('quest:completed', questId, { state: { ...state } });
291
+ this.checkQuestUnlocks();
292
+ this.checkFollowUpQuests(questId);
293
+ return true;
294
+ }
295
+ failQuest(questId) {
296
+ const stateIndex = this.journal.activeQuests.findIndex(q => q.questId === questId);
297
+ if (stateIndex === -1)
298
+ return false;
299
+ const state = this.journal.activeQuests[stateIndex];
300
+ state.status = 'failed';
301
+ state.endedAt = Date.now();
302
+ this.journal.activeQuests.splice(stateIndex, 1);
303
+ this.journal.failedQuests.push(state);
304
+ this.emitEvent('quest:failed', questId, {});
305
+ return true;
306
+ }
307
+ checkQuestUnlocks() {
308
+ for (const quest of this.quests.values()) {
309
+ const status = this.getQuestStatus(quest.id);
310
+ if (status === 'locked' && this.canUnlockQuest(quest.id)) {
311
+ this.emitEvent('quest:unlocked', quest.id, {});
312
+ }
313
+ }
314
+ }
315
+ checkFollowUpQuests(completedQuestId) {
316
+ const quest = this.quests.get(completedQuestId);
317
+ if (!(quest === null || quest === void 0 ? void 0 : quest.followUpQuests))
318
+ return;
319
+ for (const followUpId of quest.followUpQuests) {
320
+ if (this.canUnlockQuest(followUpId)) {
321
+ this.emitEvent('quest:unlocked', followUpId, {});
322
+ }
323
+ }
324
+ }
325
+ /* ── Rewards ──────────────────────────────────────────────────── */
326
+ getQuestRewards(questId) {
327
+ const quest = this.quests.get(questId);
328
+ const state = this.getQuestState(questId);
329
+ if (!quest || (state === null || state === void 0 ? void 0 : state.status) !== 'completed')
330
+ return null;
331
+ const main = [...quest.rewards];
332
+ const bonus = [];
333
+ // Add bonus rewards if optional objectives completed
334
+ if (quest.bonusRewards && state) {
335
+ const optionalComplete = state.objectives
336
+ .filter(o => o.optional)
337
+ .every(o => o.completed);
338
+ if (optionalComplete) {
339
+ bonus.push(...quest.bonusRewards);
340
+ }
341
+ }
342
+ return { main, bonus };
343
+ }
344
+ claimRewards(questId) {
345
+ const rewards = this.getQuestRewards(questId);
346
+ if (!rewards)
347
+ return null;
348
+ const allRewards = [...rewards.main, ...rewards.bonus];
349
+ this.emitEvent('quest:reward-claimed', questId, { rewards: allRewards });
350
+ return allRewards;
351
+ }
352
+ /* ── Quest Tracking ───────────────────────────────────────────── */
353
+ trackQuest(questId) {
354
+ const state = this.journal.activeQuests.find(q => q.questId === questId);
355
+ if (!state)
356
+ return;
357
+ this.journal.trackedQuestId = questId;
358
+ this.emitEvent('quest:tracked', questId, {});
359
+ }
360
+ untrackQuest() {
361
+ this.journal.trackedQuestId = undefined;
362
+ }
363
+ getTrackedQuest() {
364
+ if (!this.journal.trackedQuestId)
365
+ return undefined;
366
+ return this.journal.activeQuests.find(q => q.questId === this.journal.trackedQuestId);
367
+ }
368
+ /* ── Timer Update ─────────────────────────────────────────────── */
369
+ update(deltaMs) {
370
+ for (const state of this.journal.activeQuests) {
371
+ if (state.timeRemaining !== undefined && state.timeRemaining > 0) {
372
+ state.timeRemaining -= deltaMs;
373
+ if (state.timeRemaining <= 0) {
374
+ state.timeRemaining = 0;
375
+ this.failQuest(state.questId);
376
+ }
377
+ }
378
+ }
379
+ }
380
+ /* ── Persistence ──────────────────────────────────────────────── */
381
+ saveState() {
382
+ return JSON.parse(JSON.stringify(this.journal));
383
+ }
384
+ loadState(journal) {
385
+ this.journal = JSON.parse(JSON.stringify(journal));
386
+ }
387
+ /* ── Events ───────────────────────────────────────────────────── */
388
+ emitEvent(type, questId, data) {
389
+ this.events.emit(type, {
390
+ type,
391
+ questId,
392
+ data,
393
+ timestamp: Date.now(),
394
+ });
395
+ }
396
+ subscribe(eventType, handler) {
397
+ return this.events.on(eventType, handler);
398
+ }
399
+ }
400
+ /* ═══════════════════════════════════════════════════════════════
401
+ QUEST BUILDER (Fluent API)
402
+ ══════════════════════════════════════════════════════════════════ */
403
+ class QuestBuilder {
404
+ constructor(id, name) {
405
+ this.objectiveCounter = 0;
406
+ this.rewardCounter = 0;
407
+ this.quest = {
408
+ id,
409
+ name,
410
+ summary: '',
411
+ description: '',
412
+ type: 'side',
413
+ difficulty: 'normal',
414
+ objectives: [],
415
+ rewards: [],
416
+ prerequisites: [],
417
+ canAbandon: true,
418
+ repeatable: false,
419
+ };
420
+ }
421
+ summary(summary) {
422
+ this.quest.summary = summary;
423
+ return this;
424
+ }
425
+ description(description) {
426
+ this.quest.description = description;
427
+ return this;
428
+ }
429
+ type(type) {
430
+ this.quest.type = type;
431
+ return this;
432
+ }
433
+ difficulty(difficulty) {
434
+ this.quest.difficulty = difficulty;
435
+ return this;
436
+ }
437
+ icon(icon) {
438
+ this.quest.icon = icon;
439
+ return this;
440
+ }
441
+ giver(npcId) {
442
+ this.quest.giverNpcId = npcId;
443
+ return this;
444
+ }
445
+ turnIn(npcId) {
446
+ this.quest.turnInNpcId = npcId;
447
+ return this;
448
+ }
449
+ location(hint) {
450
+ this.quest.locationHint = hint;
451
+ return this;
452
+ }
453
+ level(level) {
454
+ this.quest.recommendedLevel = level;
455
+ return this;
456
+ }
457
+ timeLimit(seconds) {
458
+ this.quest.timeLimit = seconds;
459
+ return this;
460
+ }
461
+ cannotAbandon() {
462
+ this.quest.canAbandon = false;
463
+ return this;
464
+ }
465
+ repeatable(cooldownMs = 0) {
466
+ this.quest.repeatable = true;
467
+ this.quest.repeatCooldown = cooldownMs;
468
+ return this;
469
+ }
470
+ tags(tags) {
471
+ this.quest.tags = tags;
472
+ return this;
473
+ }
474
+ followUp(questIds) {
475
+ this.quest.followUpQuests = questIds;
476
+ return this;
477
+ }
478
+ /* ── Prerequisites ────────────────────────────────────────────── */
479
+ requireQuest(questId) {
480
+ this.quest.prerequisites.push({ type: 'quest', questId });
481
+ return this;
482
+ }
483
+ requireLevel(level) {
484
+ this.quest.prerequisites.push({ type: 'level', level });
485
+ return this;
486
+ }
487
+ requireItem(itemId) {
488
+ this.quest.prerequisites.push({ type: 'item', itemId });
489
+ return this;
490
+ }
491
+ requireReputation(factionId, amount) {
492
+ this.quest.prerequisites.push({ type: 'reputation', reputation: { factionId, amount } });
493
+ return this;
494
+ }
495
+ requireSkill(skillId) {
496
+ this.quest.prerequisites.push({ type: 'skill', skillId });
497
+ return this;
498
+ }
499
+ requireCustom(customKey) {
500
+ this.quest.prerequisites.push({ type: 'custom', customKey });
501
+ return this;
502
+ }
503
+ /* ── Objectives ───────────────────────────────────────────────── */
504
+ addObjective(objective) {
505
+ const id = `obj_${++this.objectiveCounter}`;
506
+ this.quest.objectives.push({
507
+ ...objective,
508
+ id,
509
+ current: 0,
510
+ completed: false,
511
+ });
512
+ return this;
513
+ }
514
+ collect(itemId, amount, description, optional = false) {
515
+ return this.addObjective({
516
+ type: 'collect',
517
+ description,
518
+ target: amount,
519
+ optional,
520
+ trackingData: { itemId },
521
+ });
522
+ }
523
+ kill(enemyType, amount, description, optional = false) {
524
+ return this.addObjective({
525
+ type: 'kill',
526
+ description,
527
+ target: amount,
528
+ optional,
529
+ trackingData: { enemyType },
530
+ });
531
+ }
532
+ interact(entityId, description, optional = false) {
533
+ return this.addObjective({
534
+ type: 'interact',
535
+ description,
536
+ target: 1,
537
+ optional,
538
+ trackingData: { entityId },
539
+ });
540
+ }
541
+ reach(locationId, description, optional = false) {
542
+ return this.addObjective({
543
+ type: 'reach',
544
+ description,
545
+ target: 1,
546
+ optional,
547
+ trackingData: { locationId },
548
+ });
549
+ }
550
+ escort(npcId, locationId, description, optional = false) {
551
+ return this.addObjective({
552
+ type: 'escort',
553
+ description,
554
+ target: 1,
555
+ optional,
556
+ trackingData: { npcId, locationId },
557
+ });
558
+ }
559
+ defend(seconds, description, optional = false) {
560
+ return this.addObjective({
561
+ type: 'defend',
562
+ description,
563
+ target: seconds,
564
+ optional,
565
+ });
566
+ }
567
+ survive(seconds, description, optional = false) {
568
+ return this.addObjective({
569
+ type: 'survive',
570
+ description,
571
+ target: seconds,
572
+ optional,
573
+ });
574
+ }
575
+ craft(itemId, amount, description, optional = false) {
576
+ return this.addObjective({
577
+ type: 'craft',
578
+ description,
579
+ target: amount,
580
+ optional,
581
+ trackingData: { itemId },
582
+ });
583
+ }
584
+ talk(npcId, description, optional = false) {
585
+ return this.addObjective({
586
+ type: 'talk',
587
+ description,
588
+ target: 1,
589
+ optional,
590
+ trackingData: { npcId },
591
+ });
592
+ }
593
+ discover(locationId, description, optional = false) {
594
+ return this.addObjective({
595
+ type: 'discover',
596
+ description,
597
+ target: 1,
598
+ optional,
599
+ trackingData: { locationId },
600
+ });
601
+ }
602
+ score(threshold, description, optional = false) {
603
+ return this.addObjective({
604
+ type: 'score',
605
+ description,
606
+ target: threshold,
607
+ optional,
608
+ });
609
+ }
610
+ customObjective(type, target, description, data, optional = false) {
611
+ return this.addObjective({
612
+ type: 'custom',
613
+ description,
614
+ target,
615
+ optional,
616
+ trackingData: data,
617
+ });
618
+ }
619
+ /* ── Rewards ──────────────────────────────────────────────────── */
620
+ generateRewardId() {
621
+ return `reward_${++this.rewardCounter}`;
622
+ }
623
+ rewardXP(amount, name = 'Experience') {
624
+ this.quest.rewards.push({
625
+ id: this.generateRewardId(),
626
+ type: 'experience',
627
+ name,
628
+ amount,
629
+ });
630
+ return this;
631
+ }
632
+ rewardCurrency(amount, currencyName = 'Gold') {
633
+ this.quest.rewards.push({
634
+ id: this.generateRewardId(),
635
+ type: 'currency',
636
+ name: currencyName,
637
+ amount,
638
+ });
639
+ return this;
640
+ }
641
+ rewardItem(itemId, name, quantity = 1, icon) {
642
+ this.quest.rewards.push({
643
+ id: this.generateRewardId(),
644
+ type: 'item',
645
+ name,
646
+ itemId,
647
+ quantity,
648
+ icon,
649
+ });
650
+ return this;
651
+ }
652
+ rewardSkill(skillId, name, icon) {
653
+ this.quest.rewards.push({
654
+ id: this.generateRewardId(),
655
+ type: 'skill',
656
+ name,
657
+ skillId,
658
+ icon,
659
+ });
660
+ return this;
661
+ }
662
+ rewardReputation(factionId, amount, factionName) {
663
+ this.quest.rewards.push({
664
+ id: this.generateRewardId(),
665
+ type: 'reputation',
666
+ name: `${factionName} Reputation`,
667
+ reputation: { factionId, amount },
668
+ });
669
+ return this;
670
+ }
671
+ rewardUnlock(unlockId, name, icon) {
672
+ this.quest.rewards.push({
673
+ id: this.generateRewardId(),
674
+ type: 'unlock',
675
+ name,
676
+ unlockId,
677
+ icon,
678
+ });
679
+ return this;
680
+ }
681
+ rewardAchievement(achievementId, name, icon) {
682
+ this.quest.rewards.push({
683
+ id: this.generateRewardId(),
684
+ type: 'achievement',
685
+ name,
686
+ unlockId: achievementId,
687
+ icon,
688
+ });
689
+ return this;
690
+ }
691
+ bonusXP(amount, name = 'Bonus Experience') {
692
+ if (!this.quest.bonusRewards)
693
+ this.quest.bonusRewards = [];
694
+ this.quest.bonusRewards.push({
695
+ id: this.generateRewardId(),
696
+ type: 'experience',
697
+ name,
698
+ amount,
699
+ });
700
+ return this;
701
+ }
702
+ bonusItem(itemId, name, quantity = 1, icon) {
703
+ if (!this.quest.bonusRewards)
704
+ this.quest.bonusRewards = [];
705
+ this.quest.bonusRewards.push({
706
+ id: this.generateRewardId(),
707
+ type: 'item',
708
+ name,
709
+ itemId,
710
+ quantity,
711
+ icon,
712
+ });
713
+ return this;
714
+ }
715
+ build() {
716
+ return { ...this.quest };
717
+ }
718
+ }
719
+ const QuestList = ({ quests, questDefinitions, trackedId, onSelect, onTrack, filter, className = '', style, }) => {
720
+ const filteredQuests = filter
721
+ ? quests.filter(q => {
722
+ const def = questDefinitions.get(q.questId);
723
+ return def && filter.includes(def.type);
724
+ })
725
+ : quests;
726
+ return React.createElement('div', {
727
+ className: `nice-quest-list ${className}`,
728
+ style: {
729
+ display: 'flex',
730
+ flexDirection: 'column',
731
+ gap: '8px',
732
+ ...style,
733
+ },
734
+ }, filteredQuests.map(state => {
735
+ const quest = questDefinitions.get(state.questId);
736
+ if (!quest)
737
+ return null;
738
+ const progress = state.objectives.filter(o => !o.optional);
739
+ const completed = progress.filter(o => o.completed).length;
740
+ const total = progress.length;
741
+ const isTracked = trackedId === state.questId;
742
+ return React.createElement('div', {
743
+ key: state.questId,
744
+ className: `nice-quest-item ${isTracked ? 'tracked' : ''}`,
745
+ onClick: () => onSelect === null || onSelect === void 0 ? void 0 : onSelect(state.questId),
746
+ style: {
747
+ padding: '12px',
748
+ backgroundColor: isTracked ? 'rgba(100, 181, 246, 0.2)' : 'rgba(255, 255, 255, 0.05)',
749
+ border: isTracked ? '2px solid #64b5f6' : '2px solid transparent',
750
+ borderRadius: '8px',
751
+ cursor: 'pointer',
752
+ },
753
+ }, [
754
+ React.createElement('div', {
755
+ key: 'header',
756
+ style: { display: 'flex', justifyContent: 'space-between', marginBottom: '4px' },
757
+ }, [
758
+ React.createElement('span', {
759
+ key: 'name',
760
+ style: { fontWeight: 'bold' },
761
+ }, quest.name),
762
+ React.createElement('span', {
763
+ key: 'type',
764
+ style: {
765
+ fontSize: '12px',
766
+ padding: '2px 6px',
767
+ backgroundColor: getTypeColor(quest.type),
768
+ borderRadius: '4px',
769
+ },
770
+ }, quest.type.toUpperCase()),
771
+ ]),
772
+ React.createElement('div', {
773
+ key: 'progress',
774
+ style: { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '8px' },
775
+ }, [
776
+ React.createElement('div', {
777
+ key: 'bar',
778
+ style: {
779
+ flex: 1,
780
+ height: '4px',
781
+ backgroundColor: 'rgba(255, 255, 255, 0.2)',
782
+ borderRadius: '2px',
783
+ overflow: 'hidden',
784
+ },
785
+ }, React.createElement('div', {
786
+ style: {
787
+ width: `${(completed / total) * 100}%`,
788
+ height: '100%',
789
+ backgroundColor: '#4caf50',
790
+ },
791
+ })),
792
+ React.createElement('span', {
793
+ key: 'text',
794
+ style: { fontSize: '12px', opacity: 0.7 },
795
+ }, `${completed}/${total}`),
796
+ onTrack && React.createElement('button', {
797
+ key: 'track',
798
+ onClick: (e) => {
799
+ e.stopPropagation();
800
+ onTrack(state.questId);
801
+ },
802
+ style: {
803
+ padding: '4px 8px',
804
+ fontSize: '10px',
805
+ backgroundColor: isTracked ? '#64b5f6' : 'transparent',
806
+ border: '1px solid #64b5f6',
807
+ borderRadius: '4px',
808
+ color: isTracked ? '#000' : '#64b5f6',
809
+ cursor: 'pointer',
810
+ },
811
+ }, isTracked ? 'TRACKED' : 'TRACK'),
812
+ ]),
813
+ ]);
814
+ }));
815
+ };
816
+ function getTypeColor(type) {
817
+ switch (type) {
818
+ case 'main': return '#f44336';
819
+ case 'side': return '#2196f3';
820
+ case 'daily': return '#4caf50';
821
+ case 'weekly': return '#9c27b0';
822
+ case 'achievement': return '#ff9800';
823
+ case 'tutorial': return '#00bcd4';
824
+ case 'hidden': return '#607d8b';
825
+ default: return '#9e9e9e';
826
+ }
827
+ }
828
+ const QuestTracker = ({ state, quest, showOptional = false, className = '', style, }) => {
829
+ const objectives = showOptional
830
+ ? state.objectives
831
+ : state.objectives.filter(o => !o.optional);
832
+ return React.createElement('div', {
833
+ className: `nice-quest-tracker ${className}`,
834
+ style: {
835
+ padding: '12px',
836
+ backgroundColor: 'rgba(0, 0, 0, 0.6)',
837
+ borderRadius: '8px',
838
+ color: 'white',
839
+ minWidth: '200px',
840
+ ...style,
841
+ },
842
+ }, [
843
+ React.createElement('div', {
844
+ key: 'header',
845
+ style: {
846
+ fontWeight: 'bold',
847
+ marginBottom: '8px',
848
+ paddingBottom: '8px',
849
+ borderBottom: '1px solid rgba(255, 255, 255, 0.2)',
850
+ },
851
+ }, quest.name),
852
+ React.createElement('div', {
853
+ key: 'objectives',
854
+ style: { display: 'flex', flexDirection: 'column', gap: '4px' },
855
+ }, objectives.map(obj => React.createElement('div', {
856
+ key: obj.id,
857
+ style: {
858
+ display: 'flex',
859
+ alignItems: 'center',
860
+ gap: '8px',
861
+ opacity: obj.completed ? 0.5 : 1,
862
+ textDecoration: obj.completed ? 'line-through' : 'none',
863
+ fontSize: '14px',
864
+ },
865
+ }, [
866
+ React.createElement('span', {
867
+ key: 'check',
868
+ style: { color: obj.completed ? '#4caf50' : '#9e9e9e' },
869
+ }, obj.completed ? '✓' : '○'),
870
+ React.createElement('span', { key: 'desc' }, obj.description),
871
+ obj.target > 1 && React.createElement('span', {
872
+ key: 'progress',
873
+ style: { marginLeft: 'auto', fontSize: '12px', opacity: 0.7 },
874
+ }, `${obj.current}/${obj.target}`),
875
+ ]))),
876
+ state.timeRemaining !== undefined && state.timeRemaining > 0 && React.createElement('div', {
877
+ key: 'timer',
878
+ style: {
879
+ marginTop: '8px',
880
+ paddingTop: '8px',
881
+ borderTop: '1px solid rgba(255, 255, 255, 0.2)',
882
+ textAlign: 'center',
883
+ color: state.timeRemaining < 30000 ? '#f44336' : '#fff',
884
+ },
885
+ }, `Time: ${formatTime(state.timeRemaining)}`),
886
+ ]);
887
+ };
888
+ function formatTime(ms) {
889
+ const seconds = Math.floor(ms / 1000);
890
+ const minutes = Math.floor(seconds / 60);
891
+ const remainingSeconds = seconds % 60;
892
+ return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
893
+ }
894
+ /* ═══════════════════════════════════════════════════════════════
895
+ UTILITY FUNCTIONS
896
+ ══════════════════════════════════════════════════════════════════ */
897
+ function createEmptyQuest(id, name) {
898
+ return new QuestBuilder(id, name).build();
899
+ }
900
+ const DIFFICULTY_COLORS = {
901
+ trivial: '#9e9e9e',
902
+ easy: '#4caf50',
903
+ normal: '#2196f3',
904
+ hard: '#ff9800',
905
+ legendary: '#f44336',
906
+ };
907
+ const DIFFICULTY_XP_MULTIPLIERS = {
908
+ trivial: 0.5,
909
+ easy: 0.75,
910
+ normal: 1,
911
+ hard: 1.5,
912
+ legendary: 2,
913
+ };
914
+
915
+ export { DIFFICULTY_COLORS, DIFFICULTY_XP_MULTIPLIERS, QuestBuilder, QuestList, QuestManager, QuestTracker, createEmptyQuest };
916
+ //# sourceMappingURL=QuestSystem.js.map