idlerpg.sh 0.1.0

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 (478) hide show
  1. package/README.md +171 -0
  2. package/dist/affix/AffixRegistry.d.ts +68 -0
  3. package/dist/affix/AffixRegistry.d.ts.map +1 -0
  4. package/dist/affix/AffixRegistry.js +245 -0
  5. package/dist/affix/AffixRegistry.js.map +1 -0
  6. package/dist/affix/PluginLoader.d.ts +66 -0
  7. package/dist/affix/PluginLoader.d.ts.map +1 -0
  8. package/dist/affix/PluginLoader.js +321 -0
  9. package/dist/affix/PluginLoader.js.map +1 -0
  10. package/dist/affix/builtin.d.ts +6 -0
  11. package/dist/affix/builtin.d.ts.map +1 -0
  12. package/dist/affix/builtin.js +311 -0
  13. package/dist/affix/builtin.js.map +1 -0
  14. package/dist/affix/index.d.ts +8 -0
  15. package/dist/affix/index.d.ts.map +1 -0
  16. package/dist/affix/index.js +11 -0
  17. package/dist/affix/index.js.map +1 -0
  18. package/dist/affix/types.d.ts +152 -0
  19. package/dist/affix/types.d.ts.map +1 -0
  20. package/dist/affix/types.js +8 -0
  21. package/dist/affix/types.js.map +1 -0
  22. package/dist/ai/PlayKitClient.d.ts +208 -0
  23. package/dist/ai/PlayKitClient.d.ts.map +1 -0
  24. package/dist/ai/PlayKitClient.js +721 -0
  25. package/dist/ai/PlayKitClient.js.map +1 -0
  26. package/dist/ai/index.d.ts +5 -0
  27. package/dist/ai/index.d.ts.map +1 -0
  28. package/dist/ai/index.js +8 -0
  29. package/dist/ai/index.js.map +1 -0
  30. package/dist/app/App.d.ts +85 -0
  31. package/dist/app/App.d.ts.map +1 -0
  32. package/dist/app/App.js +296 -0
  33. package/dist/app/App.js.map +1 -0
  34. package/dist/app/EventBus.d.ts +222 -0
  35. package/dist/app/EventBus.d.ts.map +1 -0
  36. package/dist/app/EventBus.js +88 -0
  37. package/dist/app/EventBus.js.map +1 -0
  38. package/dist/app/Keybind.d.ts +83 -0
  39. package/dist/app/Keybind.d.ts.map +1 -0
  40. package/dist/app/Keybind.js +184 -0
  41. package/dist/app/Keybind.js.map +1 -0
  42. package/dist/app/Router.d.ts +123 -0
  43. package/dist/app/Router.d.ts.map +1 -0
  44. package/dist/app/Router.js +142 -0
  45. package/dist/app/Router.js.map +1 -0
  46. package/dist/app/ScreenManager.d.ts +97 -0
  47. package/dist/app/ScreenManager.d.ts.map +1 -0
  48. package/dist/app/ScreenManager.js +216 -0
  49. package/dist/app/ScreenManager.js.map +1 -0
  50. package/dist/app/index.d.ts +14 -0
  51. package/dist/app/index.d.ts.map +1 -0
  52. package/dist/app/index.js +19 -0
  53. package/dist/app/index.js.map +1 -0
  54. package/dist/app/screens/BaseScreen.d.ts +101 -0
  55. package/dist/app/screens/BaseScreen.d.ts.map +1 -0
  56. package/dist/app/screens/BaseScreen.js +132 -0
  57. package/dist/app/screens/BaseScreen.js.map +1 -0
  58. package/dist/app/screens/CharacterCreationScreen.d.ts +42 -0
  59. package/dist/app/screens/CharacterCreationScreen.d.ts.map +1 -0
  60. package/dist/app/screens/CharacterCreationScreen.js +467 -0
  61. package/dist/app/screens/CharacterCreationScreen.js.map +1 -0
  62. package/dist/app/screens/CombatScreen.d.ts +30 -0
  63. package/dist/app/screens/CombatScreen.d.ts.map +1 -0
  64. package/dist/app/screens/CombatScreen.js +309 -0
  65. package/dist/app/screens/CombatScreen.js.map +1 -0
  66. package/dist/app/screens/DialogScreen.d.ts +29 -0
  67. package/dist/app/screens/DialogScreen.d.ts.map +1 -0
  68. package/dist/app/screens/DialogScreen.js +295 -0
  69. package/dist/app/screens/DialogScreen.js.map +1 -0
  70. package/dist/app/screens/ExploreScreen.d.ts +50 -0
  71. package/dist/app/screens/ExploreScreen.d.ts.map +1 -0
  72. package/dist/app/screens/ExploreScreen.js +308 -0
  73. package/dist/app/screens/ExploreScreen.js.map +1 -0
  74. package/dist/app/screens/HelpScreen.d.ts +12 -0
  75. package/dist/app/screens/HelpScreen.d.ts.map +1 -0
  76. package/dist/app/screens/HelpScreen.js +155 -0
  77. package/dist/app/screens/HelpScreen.js.map +1 -0
  78. package/dist/app/screens/InventoryScreen.d.ts +27 -0
  79. package/dist/app/screens/InventoryScreen.d.ts.map +1 -0
  80. package/dist/app/screens/InventoryScreen.js +326 -0
  81. package/dist/app/screens/InventoryScreen.js.map +1 -0
  82. package/dist/app/screens/PrologueScreen.d.ts +24 -0
  83. package/dist/app/screens/PrologueScreen.d.ts.map +1 -0
  84. package/dist/app/screens/PrologueScreen.js +176 -0
  85. package/dist/app/screens/PrologueScreen.js.map +1 -0
  86. package/dist/app/screens/TitleScreen.d.ts +42 -0
  87. package/dist/app/screens/TitleScreen.d.ts.map +1 -0
  88. package/dist/app/screens/TitleScreen.js +380 -0
  89. package/dist/app/screens/TitleScreen.js.map +1 -0
  90. package/dist/app/screens/TravelScreen.d.ts +22 -0
  91. package/dist/app/screens/TravelScreen.d.ts.map +1 -0
  92. package/dist/app/screens/TravelScreen.js +122 -0
  93. package/dist/app/screens/TravelScreen.js.map +1 -0
  94. package/dist/app/screens/index.d.ts +14 -0
  95. package/dist/app/screens/index.d.ts.map +1 -0
  96. package/dist/app/screens/index.js +17 -0
  97. package/dist/app/screens/index.js.map +1 -0
  98. package/dist/commands/CommandRegistry.d.ts +91 -0
  99. package/dist/commands/CommandRegistry.d.ts.map +1 -0
  100. package/dist/commands/CommandRegistry.js +159 -0
  101. package/dist/commands/CommandRegistry.js.map +1 -0
  102. package/dist/commands/index.d.ts +7 -0
  103. package/dist/commands/index.d.ts.map +1 -0
  104. package/dist/commands/index.js +10 -0
  105. package/dist/commands/index.js.map +1 -0
  106. package/dist/core/Actor.d.ts +103 -0
  107. package/dist/core/Actor.d.ts.map +1 -0
  108. package/dist/core/Actor.js +409 -0
  109. package/dist/core/Actor.js.map +1 -0
  110. package/dist/core/Combat.d.ts +37 -0
  111. package/dist/core/Combat.d.ts.map +1 -0
  112. package/dist/core/Combat.js +294 -0
  113. package/dist/core/Combat.js.map +1 -0
  114. package/dist/core/DungeonRunner.d.ts +169 -0
  115. package/dist/core/DungeonRunner.d.ts.map +1 -0
  116. package/dist/core/DungeonRunner.js +627 -0
  117. package/dist/core/DungeonRunner.js.map +1 -0
  118. package/dist/core/Game.d.ts +133 -0
  119. package/dist/core/Game.d.ts.map +1 -0
  120. package/dist/core/Game.js +644 -0
  121. package/dist/core/Game.js.map +1 -0
  122. package/dist/core/IdleCombat.d.ts +61 -0
  123. package/dist/core/IdleCombat.d.ts.map +1 -0
  124. package/dist/core/IdleCombat.js +461 -0
  125. package/dist/core/IdleCombat.js.map +1 -0
  126. package/dist/core/IdleGameManager.d.ts +198 -0
  127. package/dist/core/IdleGameManager.d.ts.map +1 -0
  128. package/dist/core/IdleGameManager.js +688 -0
  129. package/dist/core/IdleGameManager.js.map +1 -0
  130. package/dist/core/IdleSaveManager.d.ts +109 -0
  131. package/dist/core/IdleSaveManager.d.ts.map +1 -0
  132. package/dist/core/IdleSaveManager.js +296 -0
  133. package/dist/core/IdleSaveManager.js.map +1 -0
  134. package/dist/core/NewGameFlowManager.d.ts +64 -0
  135. package/dist/core/NewGameFlowManager.d.ts.map +1 -0
  136. package/dist/core/NewGameFlowManager.js +153 -0
  137. package/dist/core/NewGameFlowManager.js.map +1 -0
  138. package/dist/core/Player.d.ts +65 -0
  139. package/dist/core/Player.d.ts.map +1 -0
  140. package/dist/core/Player.js +261 -0
  141. package/dist/core/Player.js.map +1 -0
  142. package/dist/core/RoomHandlers.d.ts +75 -0
  143. package/dist/core/RoomHandlers.d.ts.map +1 -0
  144. package/dist/core/RoomHandlers.js +383 -0
  145. package/dist/core/RoomHandlers.js.map +1 -0
  146. package/dist/core/SaveManager.d.ts +84 -0
  147. package/dist/core/SaveManager.d.ts.map +1 -0
  148. package/dist/core/SaveManager.js +281 -0
  149. package/dist/core/SaveManager.js.map +1 -0
  150. package/dist/core/SaveMigration.d.ts +69 -0
  151. package/dist/core/SaveMigration.d.ts.map +1 -0
  152. package/dist/core/SaveMigration.js +408 -0
  153. package/dist/core/SaveMigration.js.map +1 -0
  154. package/dist/core/StateAdapter.d.ts +79 -0
  155. package/dist/core/StateAdapter.d.ts.map +1 -0
  156. package/dist/core/StateAdapter.js +397 -0
  157. package/dist/core/StateAdapter.js.map +1 -0
  158. package/dist/core/Team.d.ts +145 -0
  159. package/dist/core/Team.d.ts.map +1 -0
  160. package/dist/core/Team.js +371 -0
  161. package/dist/core/Team.js.map +1 -0
  162. package/dist/core/TeamCombat.d.ts +88 -0
  163. package/dist/core/TeamCombat.d.ts.map +1 -0
  164. package/dist/core/TeamCombat.js +405 -0
  165. package/dist/core/TeamCombat.js.map +1 -0
  166. package/dist/core/TeamDungeonRunner.d.ts +186 -0
  167. package/dist/core/TeamDungeonRunner.d.ts.map +1 -0
  168. package/dist/core/TeamDungeonRunner.js +758 -0
  169. package/dist/core/TeamDungeonRunner.js.map +1 -0
  170. package/dist/core/TimeManager.d.ts +114 -0
  171. package/dist/core/TimeManager.d.ts.map +1 -0
  172. package/dist/core/TimeManager.js +318 -0
  173. package/dist/core/TimeManager.js.map +1 -0
  174. package/dist/core/index.d.ts +9 -0
  175. package/dist/core/index.d.ts.map +1 -0
  176. package/dist/core/index.js +12 -0
  177. package/dist/core/index.js.map +1 -0
  178. package/dist/core/timeConstants.d.ts +135 -0
  179. package/dist/core/timeConstants.d.ts.map +1 -0
  180. package/dist/core/timeConstants.js +157 -0
  181. package/dist/core/timeConstants.js.map +1 -0
  182. package/dist/core/types.d.ts +780 -0
  183. package/dist/core/types.d.ts.map +1 -0
  184. package/dist/core/types.js +16 -0
  185. package/dist/core/types.js.map +1 -0
  186. package/dist/data/continents/index.d.ts +163 -0
  187. package/dist/data/continents/index.d.ts.map +1 -0
  188. package/dist/data/continents/index.js +31 -0
  189. package/dist/data/continents/index.js.map +1 -0
  190. package/dist/data/continents/verdantia.d.ts +294 -0
  191. package/dist/data/continents/verdantia.d.ts.map +1 -0
  192. package/dist/data/continents/verdantia.js +327 -0
  193. package/dist/data/continents/verdantia.js.map +1 -0
  194. package/dist/handlers/DialogHandler.d.ts +95 -0
  195. package/dist/handlers/DialogHandler.d.ts.map +1 -0
  196. package/dist/handlers/DialogHandler.js +450 -0
  197. package/dist/handlers/DialogHandler.js.map +1 -0
  198. package/dist/handlers/SaveLoadHandler.d.ts +60 -0
  199. package/dist/handlers/SaveLoadHandler.d.ts.map +1 -0
  200. package/dist/handlers/SaveLoadHandler.js +187 -0
  201. package/dist/handlers/SaveLoadHandler.js.map +1 -0
  202. package/dist/handlers/TitleScreenHandler.d.ts +43 -0
  203. package/dist/handlers/TitleScreenHandler.d.ts.map +1 -0
  204. package/dist/handlers/TitleScreenHandler.js +508 -0
  205. package/dist/handlers/TitleScreenHandler.js.map +1 -0
  206. package/dist/handlers/WorkshopHandler.d.ts +75 -0
  207. package/dist/handlers/WorkshopHandler.d.ts.map +1 -0
  208. package/dist/handlers/WorkshopHandler.js +401 -0
  209. package/dist/handlers/WorkshopHandler.js.map +1 -0
  210. package/dist/handlers/index.d.ts +12 -0
  211. package/dist/handlers/index.d.ts.map +1 -0
  212. package/dist/handlers/index.js +14 -0
  213. package/dist/handlers/index.js.map +1 -0
  214. package/dist/handlers/types.d.ts +34 -0
  215. package/dist/handlers/types.d.ts.map +1 -0
  216. package/dist/handlers/types.js +8 -0
  217. package/dist/handlers/types.js.map +1 -0
  218. package/dist/i18n/en.d.ts +3 -0
  219. package/dist/i18n/en.d.ts.map +1 -0
  220. package/dist/i18n/en.js +130 -0
  221. package/dist/i18n/en.js.map +1 -0
  222. package/dist/i18n/index.d.ts +40 -0
  223. package/dist/i18n/index.d.ts.map +1 -0
  224. package/dist/i18n/index.js +105 -0
  225. package/dist/i18n/index.js.map +1 -0
  226. package/dist/i18n/types.d.ts +133 -0
  227. package/dist/i18n/types.d.ts.map +1 -0
  228. package/dist/i18n/types.js +8 -0
  229. package/dist/i18n/types.js.map +1 -0
  230. package/dist/i18n/zh.d.ts +3 -0
  231. package/dist/i18n/zh.d.ts.map +1 -0
  232. package/dist/i18n/zh.js +130 -0
  233. package/dist/i18n/zh.js.map +1 -0
  234. package/dist/instrument.d.ts +8 -0
  235. package/dist/instrument.d.ts.map +1 -0
  236. package/dist/instrument.js +33 -0
  237. package/dist/instrument.js.map +1 -0
  238. package/dist/main-new.d.ts +12 -0
  239. package/dist/main-new.d.ts.map +1 -0
  240. package/dist/main-new.js +32 -0
  241. package/dist/main-new.js.map +1 -0
  242. package/dist/main.d.ts +7 -0
  243. package/dist/main.d.ts.map +1 -0
  244. package/dist/main.js +2816 -0
  245. package/dist/main.js.map +1 -0
  246. package/dist/map/ContinentManager.d.ts +88 -0
  247. package/dist/map/ContinentManager.d.ts.map +1 -0
  248. package/dist/map/ContinentManager.js +241 -0
  249. package/dist/map/ContinentManager.js.map +1 -0
  250. package/dist/map/DungeonGenerator.d.ts +32 -0
  251. package/dist/map/DungeonGenerator.d.ts.map +1 -0
  252. package/dist/map/DungeonGenerator.js +615 -0
  253. package/dist/map/DungeonGenerator.js.map +1 -0
  254. package/dist/map/MapGenerator.d.ts +27 -0
  255. package/dist/map/MapGenerator.d.ts.map +1 -0
  256. package/dist/map/MapGenerator.js +485 -0
  257. package/dist/map/MapGenerator.js.map +1 -0
  258. package/dist/map/index.d.ts +5 -0
  259. package/dist/map/index.d.ts.map +1 -0
  260. package/dist/map/index.js +8 -0
  261. package/dist/map/index.js.map +1 -0
  262. package/dist/npc/NPCGenerator.d.ts +68 -0
  263. package/dist/npc/NPCGenerator.d.ts.map +1 -0
  264. package/dist/npc/NPCGenerator.js +468 -0
  265. package/dist/npc/NPCGenerator.js.map +1 -0
  266. package/dist/npc/NPCManager.d.ts +86 -0
  267. package/dist/npc/NPCManager.d.ts.map +1 -0
  268. package/dist/npc/NPCManager.js +217 -0
  269. package/dist/npc/NPCManager.js.map +1 -0
  270. package/dist/npc/fixedNPCs.d.ts +7 -0
  271. package/dist/npc/fixedNPCs.d.ts.map +1 -0
  272. package/dist/npc/fixedNPCs.js +196 -0
  273. package/dist/npc/fixedNPCs.js.map +1 -0
  274. package/dist/npc/index.d.ts +9 -0
  275. package/dist/npc/index.d.ts.map +1 -0
  276. package/dist/npc/index.js +12 -0
  277. package/dist/npc/index.js.map +1 -0
  278. package/dist/npc/traits.d.ts +33 -0
  279. package/dist/npc/traits.d.ts.map +1 -0
  280. package/dist/npc/traits.js +795 -0
  281. package/dist/npc/traits.js.map +1 -0
  282. package/dist/npc/types.d.ts +193 -0
  283. package/dist/npc/types.d.ts.map +1 -0
  284. package/dist/npc/types.js +9 -0
  285. package/dist/npc/types.js.map +1 -0
  286. package/dist/quest/QuestManager.d.ts +79 -0
  287. package/dist/quest/QuestManager.d.ts.map +1 -0
  288. package/dist/quest/QuestManager.js +273 -0
  289. package/dist/quest/QuestManager.js.map +1 -0
  290. package/dist/quest/index.d.ts +6 -0
  291. package/dist/quest/index.d.ts.map +1 -0
  292. package/dist/quest/index.js +9 -0
  293. package/dist/quest/index.js.map +1 -0
  294. package/dist/quest/types.d.ts +81 -0
  295. package/dist/quest/types.d.ts.map +1 -0
  296. package/dist/quest/types.js +8 -0
  297. package/dist/quest/types.js.map +1 -0
  298. package/dist/strategy/StrategyExecutor.d.ts +159 -0
  299. package/dist/strategy/StrategyExecutor.d.ts.map +1 -0
  300. package/dist/strategy/StrategyExecutor.js +479 -0
  301. package/dist/strategy/StrategyExecutor.js.map +1 -0
  302. package/dist/strategy/StrategyParser.d.ts +48 -0
  303. package/dist/strategy/StrategyParser.d.ts.map +1 -0
  304. package/dist/strategy/StrategyParser.js +321 -0
  305. package/dist/strategy/StrategyParser.js.map +1 -0
  306. package/dist/strategy/defaultStrategy.d.ts +40 -0
  307. package/dist/strategy/defaultStrategy.d.ts.map +1 -0
  308. package/dist/strategy/defaultStrategy.js +254 -0
  309. package/dist/strategy/defaultStrategy.js.map +1 -0
  310. package/dist/strategy/index.d.ts +8 -0
  311. package/dist/strategy/index.d.ts.map +1 -0
  312. package/dist/strategy/index.js +14 -0
  313. package/dist/strategy/index.js.map +1 -0
  314. package/dist/tui/ExploreMenu.d.ts +106 -0
  315. package/dist/tui/ExploreMenu.d.ts.map +1 -0
  316. package/dist/tui/ExploreMenu.js +282 -0
  317. package/dist/tui/ExploreMenu.js.map +1 -0
  318. package/dist/tui/GameUI.d.ts +313 -0
  319. package/dist/tui/GameUI.d.ts.map +1 -0
  320. package/dist/tui/GameUI.js +2116 -0
  321. package/dist/tui/GameUI.js.map +1 -0
  322. package/dist/tui/GameUIAdapter.d.ts +207 -0
  323. package/dist/tui/GameUIAdapter.d.ts.map +1 -0
  324. package/dist/tui/GameUIAdapter.js +1342 -0
  325. package/dist/tui/GameUIAdapter.js.map +1 -0
  326. package/dist/tui/Input.d.ts +139 -0
  327. package/dist/tui/Input.d.ts.map +1 -0
  328. package/dist/tui/Input.js +278 -0
  329. package/dist/tui/Input.js.map +1 -0
  330. package/dist/tui/Menu.d.ts +110 -0
  331. package/dist/tui/Menu.d.ts.map +1 -0
  332. package/dist/tui/Menu.js +365 -0
  333. package/dist/tui/Menu.js.map +1 -0
  334. package/dist/tui/Screen.d.ts +228 -0
  335. package/dist/tui/Screen.d.ts.map +1 -0
  336. package/dist/tui/Screen.js +502 -0
  337. package/dist/tui/Screen.js.map +1 -0
  338. package/dist/tui/components/Box.d.ts +36 -0
  339. package/dist/tui/components/Box.d.ts.map +1 -0
  340. package/dist/tui/components/Box.js +43 -0
  341. package/dist/tui/components/Box.js.map +1 -0
  342. package/dist/tui/components/List.d.ts +69 -0
  343. package/dist/tui/components/List.d.ts.map +1 -0
  344. package/dist/tui/components/List.js +136 -0
  345. package/dist/tui/components/List.js.map +1 -0
  346. package/dist/tui/components/ProgressBar.d.ts +42 -0
  347. package/dist/tui/components/ProgressBar.d.ts.map +1 -0
  348. package/dist/tui/components/ProgressBar.js +75 -0
  349. package/dist/tui/components/ProgressBar.js.map +1 -0
  350. package/dist/tui/components/index.d.ts +8 -0
  351. package/dist/tui/components/index.d.ts.map +1 -0
  352. package/dist/tui/components/index.js +11 -0
  353. package/dist/tui/components/index.js.map +1 -0
  354. package/dist/tui/core/BaseSection.d.ts +98 -0
  355. package/dist/tui/core/BaseSection.d.ts.map +1 -0
  356. package/dist/tui/core/BaseSection.js +174 -0
  357. package/dist/tui/core/BaseSection.js.map +1 -0
  358. package/dist/tui/core/Component.d.ts +61 -0
  359. package/dist/tui/core/Component.d.ts.map +1 -0
  360. package/dist/tui/core/Component.js +32 -0
  361. package/dist/tui/core/Component.js.map +1 -0
  362. package/dist/tui/core/Section.d.ts +101 -0
  363. package/dist/tui/core/Section.d.ts.map +1 -0
  364. package/dist/tui/core/Section.js +24 -0
  365. package/dist/tui/core/Section.js.map +1 -0
  366. package/dist/tui/core/SectionManager.d.ts +108 -0
  367. package/dist/tui/core/SectionManager.d.ts.map +1 -0
  368. package/dist/tui/core/SectionManager.js +258 -0
  369. package/dist/tui/core/SectionManager.js.map +1 -0
  370. package/dist/tui/core/index.d.ts +9 -0
  371. package/dist/tui/core/index.d.ts.map +1 -0
  372. package/dist/tui/core/index.js +12 -0
  373. package/dist/tui/core/index.js.map +1 -0
  374. package/dist/tui/index.d.ts +15 -0
  375. package/dist/tui/index.d.ts.map +1 -0
  376. package/dist/tui/index.js +23 -0
  377. package/dist/tui/index.js.map +1 -0
  378. package/dist/tui/screens/BaseScreen.d.ts +62 -0
  379. package/dist/tui/screens/BaseScreen.d.ts.map +1 -0
  380. package/dist/tui/screens/BaseScreen.js +55 -0
  381. package/dist/tui/screens/BaseScreen.js.map +1 -0
  382. package/dist/tui/screens/CombatScreen.d.ts +43 -0
  383. package/dist/tui/screens/CombatScreen.d.ts.map +1 -0
  384. package/dist/tui/screens/CombatScreen.js +125 -0
  385. package/dist/tui/screens/CombatScreen.js.map +1 -0
  386. package/dist/tui/screens/DialogScreen.d.ts +53 -0
  387. package/dist/tui/screens/DialogScreen.d.ts.map +1 -0
  388. package/dist/tui/screens/DialogScreen.js +90 -0
  389. package/dist/tui/screens/DialogScreen.js.map +1 -0
  390. package/dist/tui/screens/DungeonScreen.d.ts +80 -0
  391. package/dist/tui/screens/DungeonScreen.d.ts.map +1 -0
  392. package/dist/tui/screens/DungeonScreen.js +317 -0
  393. package/dist/tui/screens/DungeonScreen.js.map +1 -0
  394. package/dist/tui/screens/ExploreScreen.d.ts +69 -0
  395. package/dist/tui/screens/ExploreScreen.d.ts.map +1 -0
  396. package/dist/tui/screens/ExploreScreen.js +224 -0
  397. package/dist/tui/screens/ExploreScreen.js.map +1 -0
  398. package/dist/tui/screens/SectionScreen.d.ts +84 -0
  399. package/dist/tui/screens/SectionScreen.d.ts.map +1 -0
  400. package/dist/tui/screens/SectionScreen.js +156 -0
  401. package/dist/tui/screens/SectionScreen.js.map +1 -0
  402. package/dist/tui/screens/TitleScreen.d.ts +40 -0
  403. package/dist/tui/screens/TitleScreen.d.ts.map +1 -0
  404. package/dist/tui/screens/TitleScreen.js +253 -0
  405. package/dist/tui/screens/TitleScreen.js.map +1 -0
  406. package/dist/tui/screens/TownScreen.d.ts +98 -0
  407. package/dist/tui/screens/TownScreen.d.ts.map +1 -0
  408. package/dist/tui/screens/TownScreen.js +370 -0
  409. package/dist/tui/screens/TownScreen.js.map +1 -0
  410. package/dist/tui/screens/TravelScreen.d.ts +67 -0
  411. package/dist/tui/screens/TravelScreen.d.ts.map +1 -0
  412. package/dist/tui/screens/TravelScreen.js +286 -0
  413. package/dist/tui/screens/TravelScreen.js.map +1 -0
  414. package/dist/tui/screens/index.d.ts +8 -0
  415. package/dist/tui/screens/index.d.ts.map +1 -0
  416. package/dist/tui/screens/index.js +17 -0
  417. package/dist/tui/screens/index.js.map +1 -0
  418. package/dist/tui/sections/ActionsSection.d.ts +71 -0
  419. package/dist/tui/sections/ActionsSection.d.ts.map +1 -0
  420. package/dist/tui/sections/ActionsSection.js +184 -0
  421. package/dist/tui/sections/ActionsSection.js.map +1 -0
  422. package/dist/tui/sections/DungeonSection.d.ts +65 -0
  423. package/dist/tui/sections/DungeonSection.d.ts.map +1 -0
  424. package/dist/tui/sections/DungeonSection.js +144 -0
  425. package/dist/tui/sections/DungeonSection.js.map +1 -0
  426. package/dist/tui/sections/EventsSection.d.ts +50 -0
  427. package/dist/tui/sections/EventsSection.d.ts.map +1 -0
  428. package/dist/tui/sections/EventsSection.js +134 -0
  429. package/dist/tui/sections/EventsSection.js.map +1 -0
  430. package/dist/tui/sections/MapSection.d.ts +66 -0
  431. package/dist/tui/sections/MapSection.d.ts.map +1 -0
  432. package/dist/tui/sections/MapSection.js +669 -0
  433. package/dist/tui/sections/MapSection.js.map +1 -0
  434. package/dist/tui/sections/StatusSection.d.ts +47 -0
  435. package/dist/tui/sections/StatusSection.d.ts.map +1 -0
  436. package/dist/tui/sections/StatusSection.js +133 -0
  437. package/dist/tui/sections/StatusSection.js.map +1 -0
  438. package/dist/tui/sections/TeamSection.d.ts +71 -0
  439. package/dist/tui/sections/TeamSection.d.ts.map +1 -0
  440. package/dist/tui/sections/TeamSection.js +224 -0
  441. package/dist/tui/sections/TeamSection.js.map +1 -0
  442. package/dist/tui/sections/TravelingSection.d.ts +51 -0
  443. package/dist/tui/sections/TravelingSection.d.ts.map +1 -0
  444. package/dist/tui/sections/TravelingSection.js +106 -0
  445. package/dist/tui/sections/TravelingSection.js.map +1 -0
  446. package/dist/tui/sections/index.d.ts +9 -0
  447. package/dist/tui/sections/index.d.ts.map +1 -0
  448. package/dist/tui/sections/index.js +12 -0
  449. package/dist/tui/sections/index.js.map +1 -0
  450. package/dist/ui/Terminal.d.ts +68 -0
  451. package/dist/ui/Terminal.d.ts.map +1 -0
  452. package/dist/ui/Terminal.js +297 -0
  453. package/dist/ui/Terminal.js.map +1 -0
  454. package/dist/ui/index.d.ts +5 -0
  455. package/dist/ui/index.d.ts.map +1 -0
  456. package/dist/ui/index.js +8 -0
  457. package/dist/ui/index.js.map +1 -0
  458. package/dist/utils/configMigration.d.ts +14 -0
  459. package/dist/utils/configMigration.d.ts.map +1 -0
  460. package/dist/utils/configMigration.js +92 -0
  461. package/dist/utils/configMigration.js.map +1 -0
  462. package/dist/utils/errorHandler.d.ts +86 -0
  463. package/dist/utils/errorHandler.d.ts.map +1 -0
  464. package/dist/utils/errorHandler.js +224 -0
  465. package/dist/utils/errorHandler.js.map +1 -0
  466. package/dist/utils/logger.d.ts +14 -0
  467. package/dist/utils/logger.d.ts.map +1 -0
  468. package/dist/utils/logger.js +43 -0
  469. package/dist/utils/logger.js.map +1 -0
  470. package/dist/weapon/WeaponFactory.d.ts +32 -0
  471. package/dist/weapon/WeaponFactory.d.ts.map +1 -0
  472. package/dist/weapon/WeaponFactory.js +216 -0
  473. package/dist/weapon/WeaponFactory.js.map +1 -0
  474. package/dist/weapon/index.d.ts +5 -0
  475. package/dist/weapon/index.d.ts.map +1 -0
  476. package/dist/weapon/index.js +8 -0
  477. package/dist/weapon/index.js.map +1 -0
  478. package/package.json +46 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MapGenerator.js","sources":["map/MapGenerator.ts"],"sourceRoot":"/","sourcesContent":["/**\r\n * Procedural Map Generator using Binary Space Partitioning (BSP)\r\n */\r\n\r\nimport type { GameMap, Room, RoomType, Position, Enemy, NPC } from '../core/types.js';\r\n\r\ninterface BSPNode {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n left: BSPNode | null;\r\n right: BSPNode | null;\r\n room: Room | null;\r\n}\r\n\r\ninterface MapGeneratorConfig {\r\n width: number;\r\n height: number;\r\n floor: number;\r\n minRoomSize: number;\r\n maxRoomSize: number;\r\n roomTypes: RoomTypeWeight[];\r\n seed?: number;\r\n}\r\n\r\ninterface RoomTypeWeight {\r\n type: RoomType;\r\n weight: number;\r\n}\r\n\r\nconst DEFAULT_CONFIG: MapGeneratorConfig = {\r\n width: 50,\r\n height: 50,\r\n floor: 1,\r\n minRoomSize: 5,\r\n maxRoomSize: 15,\r\n roomTypes: [\r\n { type: 'combat', weight: 50 },\r\n { type: 'shop', weight: 15 },\r\n { type: 'treasure', weight: 15 },\r\n { type: 'event', weight: 15 },\r\n { type: 'boss', weight: 5 },\r\n ],\r\n};\r\n\r\n// Simple seeded random number generator\r\nclass SeededRandom {\r\n private seed: number;\r\n\r\n constructor(seed: number) {\r\n this.seed = seed;\r\n }\r\n\r\n next(): number {\r\n this.seed = (this.seed * 1103515245 + 12345) & 0x7fffffff;\r\n return this.seed / 0x7fffffff;\r\n }\r\n\r\n nextInt(min: number, max: number): number {\r\n return Math.floor(this.next() * (max - min + 1)) + min;\r\n }\r\n\r\n pick<T>(array: T[]): T {\r\n return array[Math.floor(this.next() * array.length)];\r\n }\r\n}\r\n\r\n/**\r\n * Generate a dungeon map using BSP algorithm\r\n */\r\nexport function generateMap(config: Partial<MapGeneratorConfig> = {}): GameMap {\r\n const cfg = { ...DEFAULT_CONFIG, ...config };\r\n const rng = new SeededRandom(cfg.seed ?? Date.now());\r\n\r\n // Create BSP tree\r\n const root: BSPNode = {\r\n x: 0,\r\n y: 0,\r\n width: cfg.width,\r\n height: cfg.height,\r\n left: null,\r\n right: null,\r\n room: null,\r\n };\r\n\r\n // Split the space\r\n splitNode(root, cfg.minRoomSize, rng);\r\n\r\n // Create rooms in leaf nodes\r\n const rooms = new Map<string, Room>();\r\n const leafNodes: BSPNode[] = [];\r\n collectLeafNodes(root, leafNodes);\r\n\r\n // Generate rooms\r\n let roomIndex = 0;\r\n let bossRoomId: string | undefined;\r\n\r\n for (const node of leafNodes) {\r\n const roomId = `room_${cfg.floor}_${roomIndex}`;\r\n const roomType = selectRoomType(cfg.roomTypes, rng, roomIndex === leafNodes.length - 1);\r\n\r\n if (roomType === 'boss') {\r\n bossRoomId = roomId;\r\n }\r\n\r\n const room = createRoom(roomId, node, roomType, cfg.floor, rng);\r\n node.room = room;\r\n rooms.set(roomId, room);\r\n roomIndex++;\r\n }\r\n\r\n // Connect rooms\r\n connectRooms(root, rooms);\r\n\r\n // Add start room (town/safe zone)\r\n const startRoomId = 'start_room';\r\n const firstRoom = leafNodes[0].room!;\r\n const startRoom: Room = {\r\n id: startRoomId,\r\n type: 'town',\r\n position: { x: firstRoom.position.x - 1, y: firstRoom.position.y, floor: cfg.floor },\r\n name: 'Town Center',\r\n description: 'A safe haven for adventurers. Merchants and craftsmen offer their services here.',\r\n isExplored: true,\r\n isCleared: true,\r\n connections: [firstRoom.id],\r\n };\r\n rooms.set(startRoomId, startRoom);\r\n firstRoom.connections.push(startRoomId);\r\n\r\n return {\r\n id: `map_floor_${cfg.floor}`,\r\n name: `Dungeon Floor ${cfg.floor}`,\r\n type: 'dungeon',\r\n floor: cfg.floor,\r\n rooms,\r\n startRoomId,\r\n bossRoomId,\r\n generatedAt: Date.now(),\r\n };\r\n}\r\n\r\n/**\r\n * Split a BSP node recursively\r\n */\r\nfunction splitNode(node: BSPNode, minSize: number, rng: SeededRandom): void {\r\n const canSplitH = node.height >= minSize * 2;\r\n const canSplitV = node.width >= minSize * 2;\r\n\r\n if (!canSplitH && !canSplitV) {\r\n return; // Leaf node\r\n }\r\n\r\n // Decide split direction\r\n let splitHorizontally: boolean;\r\n if (canSplitH && canSplitV) {\r\n splitHorizontally = rng.next() < 0.5;\r\n } else {\r\n splitHorizontally = canSplitH;\r\n }\r\n\r\n if (splitHorizontally) {\r\n const splitPoint = rng.nextInt(minSize, node.height - minSize);\r\n node.left = {\r\n x: node.x,\r\n y: node.y,\r\n width: node.width,\r\n height: splitPoint,\r\n left: null,\r\n right: null,\r\n room: null,\r\n };\r\n node.right = {\r\n x: node.x,\r\n y: node.y + splitPoint,\r\n width: node.width,\r\n height: node.height - splitPoint,\r\n left: null,\r\n right: null,\r\n room: null,\r\n };\r\n } else {\r\n const splitPoint = rng.nextInt(minSize, node.width - minSize);\r\n node.left = {\r\n x: node.x,\r\n y: node.y,\r\n width: splitPoint,\r\n height: node.height,\r\n left: null,\r\n right: null,\r\n room: null,\r\n };\r\n node.right = {\r\n x: node.x + splitPoint,\r\n y: node.y,\r\n width: node.width - splitPoint,\r\n height: node.height,\r\n left: null,\r\n right: null,\r\n room: null,\r\n };\r\n }\r\n\r\n splitNode(node.left, minSize, rng);\r\n splitNode(node.right, minSize, rng);\r\n}\r\n\r\n/**\r\n * Collect all leaf nodes\r\n */\r\nfunction collectLeafNodes(node: BSPNode, leaves: BSPNode[]): void {\r\n if (!node.left && !node.right) {\r\n leaves.push(node);\r\n } else {\r\n if (node.left) collectLeafNodes(node.left, leaves);\r\n if (node.right) collectLeafNodes(node.right, leaves);\r\n }\r\n}\r\n\r\n/**\r\n * Select a room type based on weights\r\n */\r\nfunction selectRoomType(\r\n types: RoomTypeWeight[],\r\n rng: SeededRandom,\r\n forceBoss: boolean\r\n): RoomType {\r\n if (forceBoss) {\r\n return 'boss';\r\n }\r\n\r\n const totalWeight = types.reduce((sum, t) => sum + t.weight, 0);\r\n let roll = rng.next() * totalWeight;\r\n\r\n for (const type of types) {\r\n roll -= type.weight;\r\n if (roll <= 0) {\r\n return type.type;\r\n }\r\n }\r\n\r\n return 'empty';\r\n}\r\n\r\n/**\r\n * Create a room from a BSP node\r\n */\r\nfunction createRoom(\r\n id: string,\r\n node: BSPNode,\r\n type: RoomType,\r\n floor: number,\r\n rng: SeededRandom\r\n): Room {\r\n const position: Position = {\r\n x: node.x + Math.floor(node.width / 2),\r\n y: node.y + Math.floor(node.height / 2),\r\n floor,\r\n };\r\n\r\n const room: Room = {\r\n id,\r\n type,\r\n position,\r\n name: generateRoomName(type, rng),\r\n description: generateRoomDescription(type, rng),\r\n isExplored: false,\r\n isCleared: type === 'town' || type === 'rest',\r\n connections: [],\r\n };\r\n\r\n // Add content based on room type\r\n if (type === 'combat' || type === 'boss') {\r\n room.enemies = generateEnemies(floor, type === 'boss', rng);\r\n }\r\n\r\n if (type === 'shop') {\r\n room.npcs = [generateNPC('merchant', rng)];\r\n }\r\n\r\n if (type === 'treasure') {\r\n room.items = generateTreasure(floor, rng);\r\n }\r\n\r\n return room;\r\n}\r\n\r\n/**\r\n * Connect rooms through the BSP tree\r\n */\r\nfunction connectRooms(node: BSPNode, rooms: Map<string, Room>): void {\r\n if (!node.left || !node.right) return;\r\n\r\n // Connect children first\r\n connectRooms(node.left, rooms);\r\n connectRooms(node.right, rooms);\r\n\r\n // Connect a room from left subtree to a room from right subtree\r\n const leftRoom = getRandomRoomFromNode(node.left);\r\n const rightRoom = getRandomRoomFromNode(node.right);\r\n\r\n if (leftRoom && rightRoom) {\r\n if (!leftRoom.connections.includes(rightRoom.id)) {\r\n leftRoom.connections.push(rightRoom.id);\r\n }\r\n if (!rightRoom.connections.includes(leftRoom.id)) {\r\n rightRoom.connections.push(leftRoom.id);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Get a random room from a BSP subtree\r\n */\r\nfunction getRandomRoomFromNode(node: BSPNode): Room | null {\r\n if (node.room) return node.room;\r\n \r\n const rooms: Room[] = [];\r\n const collectRooms = (n: BSPNode) => {\r\n if (n.room) rooms.push(n.room);\r\n if (n.left) collectRooms(n.left);\r\n if (n.right) collectRooms(n.right);\r\n };\r\n collectRooms(node);\r\n\r\n return rooms.length > 0 ? rooms[Math.floor(Math.random() * rooms.length)] : null;\r\n}\r\n\r\n/**\r\n * Generate a room name\r\n */\r\nfunction generateRoomName(type: RoomType, rng: SeededRandom): string {\r\n const names: Record<RoomType, string[]> = {\r\n empty: ['Empty Chamber', 'Abandoned Hall', 'Dusty Room'],\r\n combat: ['Dark Corridor', 'Monster Den', 'Infested Hall', 'Danger Zone'],\r\n shop: ['Merchant\\'s Corner', 'Trading Post', 'Hidden Shop'],\r\n treasure: ['Treasure Chamber', 'Golden Vault', 'Loot Room'],\r\n event: ['Mysterious Shrine', 'Ancient Altar', 'Strange Portal'],\r\n boss: ['Throne Room', 'Lair of Darkness', 'Final Chamber'],\r\n rest: ['Safe Haven', 'Resting Spot', 'Sanctuary'],\r\n town: ['Town Center', 'Village Square', 'Safe Zone'],\r\n dungeon_entrance: ['Dungeon Gate', 'Dark Entrance', 'Ominous Doorway'],\r\n };\r\n\r\n return rng.pick(names[type] || names.empty);\r\n}\r\n\r\n/**\r\n * Generate a room description\r\n */\r\nfunction generateRoomDescription(type: RoomType, rng: SeededRandom): string {\r\n const descriptions: Record<RoomType, string[]> = {\r\n empty: [\r\n 'An empty room with nothing of interest.',\r\n 'Dust covers every surface. Nothing moves.',\r\n ],\r\n combat: [\r\n 'Shadows move in the darkness. Something lurks here.',\r\n 'The air feels hostile. Enemies await.',\r\n ],\r\n shop: [\r\n 'A merchant has set up shop in this unlikely place.',\r\n 'Various goods line makeshift shelves.',\r\n ],\r\n treasure: [\r\n 'Glittering treasures catch your eye.',\r\n 'Ancient chests hold forgotten riches.',\r\n ],\r\n event: [\r\n 'Strange energy pulses from within.',\r\n 'Something unusual awaits discovery.',\r\n ],\r\n boss: [\r\n 'An oppressive presence fills the room.',\r\n 'This is where the strongest foe awaits.',\r\n ],\r\n rest: [\r\n 'A peaceful respite from the dangers outside.',\r\n 'You can rest safely here.',\r\n ],\r\n town: [\r\n 'A safe haven for adventurers.',\r\n 'Civilization amidst the chaos.',\r\n ],\r\n dungeon_entrance: [\r\n 'The entrance to untold dangers and treasures.',\r\n 'Darkness beckons from beyond the threshold.',\r\n ],\r\n };\r\n\r\n return rng.pick(descriptions[type] || descriptions.empty);\r\n}\r\n\r\n/**\r\n * Generate enemies for a room\r\n */\r\nfunction generateEnemies(floor: number, isBoss: boolean, rng: SeededRandom): Enemy[] {\r\n const enemies: Enemy[] = [];\r\n const baseLevel = floor;\r\n const count = isBoss ? 1 : rng.nextInt(1, 3);\r\n\r\n const enemyTypes = [\r\n { name: 'Goblin', hpMult: 1, atkMult: 1, defMult: 0.8 },\r\n { name: 'Skeleton', hpMult: 0.8, atkMult: 1.1, defMult: 0.9 },\r\n { name: 'Slime', hpMult: 1.2, atkMult: 0.8, defMult: 0.5 },\r\n { name: 'Orc', hpMult: 1.5, atkMult: 1.2, defMult: 1 },\r\n { name: 'Dark Knight', hpMult: 2, atkMult: 1.5, defMult: 1.5 },\r\n ];\r\n\r\n const bossTypes = [\r\n { name: 'Goblin King', hpMult: 3, atkMult: 1.5, defMult: 1.2 },\r\n { name: 'Ancient Lich', hpMult: 2.5, atkMult: 2, defMult: 1 },\r\n { name: 'Dragon Whelp', hpMult: 4, atkMult: 1.8, defMult: 1.5 },\r\n ];\r\n\r\n for (let i = 0; i < count; i++) {\r\n const type = isBoss\r\n ? rng.pick(bossTypes)\r\n : rng.pick(enemyTypes);\r\n\r\n const level = baseLevel + (isBoss ? 2 : rng.nextInt(-1, 1));\r\n\r\n enemies.push({\r\n id: `enemy_${Date.now()}_${i}`,\r\n name: type.name,\r\n level,\r\n hp: Math.floor(20 * level * type.hpMult),\r\n maxHp: Math.floor(20 * level * type.hpMult),\r\n attack: Math.floor(5 * level * type.atkMult),\r\n defense: Math.floor(3 * level * type.defMult),\r\n speed: 5 + level,\r\n expReward: 10 * level * (isBoss ? 5 : 1),\r\n goldReward: rng.nextInt(5, 20) * level,\r\n dropTable: [\r\n { itemId: 'health_potion', chance: 0.3, quantity: { min: 1, max: 2 } },\r\n { itemId: 'affix_fragment', chance: isBoss ? 0.8 : 0.1, quantity: { min: 1, max: 1 } },\r\n ],\r\n isBoss,\r\n });\r\n }\r\n\r\n return enemies;\r\n}\r\n\r\n/**\r\n * Generate an NPC\r\n */\r\nfunction generateNPC(type: string, rng: SeededRandom): NPC {\r\n const names = ['Morris', 'Elena', 'Gareth', 'Lyra', 'Thorne', 'Isolde', 'Cedric', 'Rowena', 'Aldric'];\r\n const name = rng.pick(names);\r\n\r\n // NPC type-specific system prompts\r\n const systemPrompts: Record<string, string> = {\r\n merchant: `You are ${name}, a mysterious merchant in a dark dungeon. You speak in riddles and hints. You have rare affix fragments for sale, but your prices are steep. You occasionally drop cryptic warnings about dangers ahead. Keep responses concise (2-3 sentences). Speak in an enigmatic, slightly unsettling tone.`,\r\n sage: `You are ${name}, a wise sage who has lived in the dungeon for centuries. You possess knowledge of ancient affixes and forgotten lore. You speak calmly and offer guidance to adventurers. Keep responses helpful but mysterious. 2-3 sentences maximum.`,\r\n guard: `You are ${name}, a gruff dungeon guard who has seen many adventurers come and go. You're skeptical of newcomers but respect strength. You might offer tips about nearby dangers if persuaded. Keep responses short and gruff.`,\r\n traveler: `You are ${name}, a fellow adventurer exploring the dungeon. You're friendly and willing to share information about areas you've explored. You might trade items or offer to team up temporarily. Keep responses casual and brief.`,\r\n blacksmith: `You are ${name}, a master blacksmith who has set up shop in a safe zone. You can forge and enhance weapons, and you know much about affix combinations. You speak directly about your craft. Keep responses practical and to the point.`,\r\n quest_giver: `You are ${name}, a mysterious figure with tasks for brave adventurers. You offer quests and rewards. You speak with purpose and urgency. Keep responses intriguing and motivating.`,\r\n };\r\n\r\n const descriptions: Record<string, string> = {\r\n merchant: `${name} stands behind a cluttered stall, eyes gleaming with shrewd intelligence.`,\r\n sage: `${name} sits in quiet contemplation, an aura of ancient wisdom surrounding them.`,\r\n guard: `${name} stands at attention, armor battle-worn but well-maintained.`,\r\n traveler: `${name} rests against the wall, gear dusty from recent travels.`,\r\n blacksmith: `${name} works the forge, muscles glistening with sweat.`,\r\n quest_giver: `${name} beckons you closer with an air of mystery.`,\r\n };\r\n\r\n return {\r\n id: `npc_${type}_${Date.now()}_${rng.nextInt(1000, 9999)}`,\r\n name,\r\n type: type as import('../core/types.js').NPCType,\r\n description: descriptions[type] || `A ${type} named ${name}`,\r\n systemPrompt: systemPrompts[type] || `You are ${name}, a character in a dungeon. Respond briefly and in character.`,\r\n dialogHistory: [],\r\n };\r\n}\r\n\r\n/**\r\n * Generate treasure items\r\n */\r\nfunction generateTreasure(floor: number, rng: SeededRandom): import('../core/types.js').InventoryItem[] {\r\n const items: import('../core/types.js').InventoryItem[] = [];\r\n\r\n // Gold\r\n items.push({\r\n id: 'gold',\r\n type: 'material',\r\n name: 'Gold',\r\n description: 'Shiny coins',\r\n quantity: rng.nextInt(10, 50) * floor,\r\n });\r\n\r\n // Random chance for affix fragment\r\n if (rng.next() < 0.3) {\r\n items.push({\r\n id: `affix_fragment_${Date.now()}`,\r\n type: 'affix_fragment',\r\n name: 'Affix Fragment',\r\n description: 'A mysterious fragment that holds power',\r\n quantity: 1,\r\n });\r\n }\r\n\r\n return items;\r\n}\r\n\r\n/**\r\n * Generate a simple text representation of the map\r\n */\r\nexport function renderMapToString(map: GameMap, currentRoomId: string): string {\r\n const lines: string[] = [];\r\n const visited = new Set<string>();\r\n\r\n lines.push('┌─── Map ───────────────────────┐');\r\n\r\n // Simple connected node representation\r\n const queue = [map.startRoomId];\r\n visited.add(map.startRoomId);\r\n let depth = 0;\r\n\r\n while (queue.length > 0 && depth < 5) {\r\n const levelSize = queue.length;\r\n let line = '│ ';\r\n\r\n for (let i = 0; i < levelSize && i < 5; i++) {\r\n const roomId = queue.shift()!;\r\n const room = map.rooms.get(roomId);\r\n\r\n if (room) {\r\n const symbol = roomId === currentRoomId\r\n ? '[@]'\r\n : getRoomSymbol(room);\r\n line += symbol + '━';\r\n\r\n for (const connId of room.connections) {\r\n if (!visited.has(connId)) {\r\n visited.add(connId);\r\n queue.push(connId);\r\n }\r\n }\r\n }\r\n }\r\n\r\n lines.push(line.slice(0, -1).padEnd(33) + '│');\r\n depth++;\r\n }\r\n\r\n lines.push('│ │');\r\n lines.push('│ [@]You [T]Town [D]Dungeon │');\r\n lines.push('│ [B]Boss [S]Shop [?]Unknown │');\r\n lines.push('└───────────────────────────────┘');\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\n/**\r\n * Get symbol for room type\r\n */\r\nfunction getRoomSymbol(room: Room): string {\r\n if (!room.isExplored) return '[?]';\r\n\r\n const symbols: Record<RoomType, string> = {\r\n empty: '[·]',\r\n combat: '[!]',\r\n shop: '[S]',\r\n treasure: '[T]',\r\n event: '[E]',\r\n boss: '[B]',\r\n rest: '[R]',\r\n town: '[T]',\r\n dungeon_entrance: '[D]',\r\n };\r\n\r\n return symbols[room.type] || '[·]';\r\n}\r\n"],"names":[],"mappings":"AAAA;;GAEG;;;AA6BH,MAAM,cAAc,GAAuB;IACzC,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,EAAE;IACf,SAAS,EAAE;QACT,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE;QAC9B,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5B,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE;QAChC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAC7B,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE;KAC5B;CACF,CAAC;AAEF,wCAAwC;AACxC,MAAM,YAAY;IACR,IAAI,CAAS;IAErB,YAAY,IAAY;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,UAAU,GAAG,KAAK,CAAC,GAAG,UAAU,CAAC;QAC1D,OAAO,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,GAAW;QAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IACzD,CAAC;IAED,IAAI,CAAI,KAAU;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,SAAsC,EAAE;IAClE,MAAM,GAAG,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAErD,kBAAkB;IAClB,MAAM,IAAI,GAAY;QACpB,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;QACJ,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;KACX,CAAC;IAEF,kBAAkB;IAClB,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAEtC,6BAA6B;IAC7B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;IACtC,MAAM,SAAS,GAAc,EAAE,CAAC;IAChC,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAElC,iBAAiB;IACjB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,UAA8B,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,QAAQ,GAAG,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,SAAS,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAExF,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,UAAU,GAAG,MAAM,CAAC;QACtB,CAAC;QAED,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAChE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACxB,SAAS,EAAE,CAAC;IACd,CAAC;IAED,gBAAgB;IAChB,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE1B,kCAAkC;IAClC,MAAM,WAAW,GAAG,YAAY,CAAC;IACjC,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAK,CAAC;IACrC,MAAM,SAAS,GAAS;QACtB,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,EAAE,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE;QACpF,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,kFAAkF;QAC/F,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;KAC5B,CAAC;IACF,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAClC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAExC,OAAO;QACL,EAAE,EAAE,aAAa,GAAG,CAAC,KAAK,EAAE;QAC5B,IAAI,EAAE,iBAAiB,GAAG,CAAC,KAAK,EAAE;QAClC,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK;QACL,WAAW;QACX,UAAU;QACV,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;KACxB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,IAAa,EAAE,OAAe,EAAE,GAAiB;IAClE,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,GAAG,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC;IAE5C,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,EAAE,CAAC;QAC7B,OAAO,CAAC,YAAY;IACtB,CAAC;IAED,yBAAyB;IACzB,IAAI,iBAA0B,CAAC;IAC/B,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;QAC3B,iBAAiB,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,iBAAiB,GAAG,SAAS,CAAC;IAChC,CAAC;IAED,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;QAC/D,IAAI,CAAC,IAAI,GAAG;YACV,CAAC,EAAE,IAAI,CAAC,CAAC;YACT,CAAC,EAAE,IAAI,CAAC,CAAC;YACT,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;SACX,CAAC;QACF,IAAI,CAAC,KAAK,GAAG;YACX,CAAC,EAAE,IAAI,CAAC,CAAC;YACT,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,UAAU;YACtB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,UAAU;YAChC,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;SACX,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,GAAG;YACV,CAAC,EAAE,IAAI,CAAC,CAAC;YACT,CAAC,EAAE,IAAI,CAAC,CAAC;YACT,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;SACX,CAAC;QACF,IAAI,CAAC,KAAK,GAAG;YACX,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,UAAU;YACtB,CAAC,EAAE,IAAI,CAAC,CAAC;YACT,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,UAAU;YAC9B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,IAAI;SACX,CAAC;IACJ,CAAC;IAED,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACnC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,IAAa,EAAE,MAAiB;IACxD,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,IAAI,IAAI,CAAC,IAAI;YAAE,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,KAAK;YAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,KAAuB,EACvB,GAAiB,EACjB,SAAkB;IAElB,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChE,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,WAAW,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC;QACpB,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CACjB,EAAU,EACV,IAAa,EACb,IAAc,EACd,KAAa,EACb,GAAiB;IAEjB,MAAM,QAAQ,GAAa;QACzB,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACtC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QACvC,KAAK;KACN,CAAC;IAEF,MAAM,IAAI,GAAS;QACjB,EAAE;QACF,IAAI;QACJ,QAAQ;QACR,IAAI,EAAE,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC;QACjC,WAAW,EAAE,uBAAuB,CAAC,IAAI,EAAE,GAAG,CAAC;QAC/C,UAAU,EAAE,KAAK;QACjB,SAAS,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM;QAC7C,WAAW,EAAE,EAAE;KAChB,CAAC;IAEF,iCAAiC;IACjC,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACzC,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,KAAK,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,IAAa,EAAE,KAAwB;IAC3D,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK;QAAE,OAAO;IAEtC,yBAAyB;IACzB,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEhC,gEAAgE;IAChE,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEpD,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;YACjD,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACjD,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,IAAa;IAC1C,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhC,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,MAAM,YAAY,GAAG,CAAC,CAAU,EAAE,EAAE;QAClC,IAAI,CAAC,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,CAAC,IAAI;YAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC,KAAK;YAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC;IACF,YAAY,CAAC,IAAI,CAAC,CAAC;IAEnB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACnF,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,IAAc,EAAE,GAAiB;IACzD,MAAM,KAAK,GAA+B;QACxC,KAAK,EAAE,CAAC,eAAe,EAAE,gBAAgB,EAAE,YAAY,CAAC;QACxD,MAAM,EAAE,CAAC,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,CAAC;QACxE,IAAI,EAAE,CAAC,oBAAoB,EAAE,cAAc,EAAE,aAAa,CAAC;QAC3D,QAAQ,EAAE,CAAC,kBAAkB,EAAE,cAAc,EAAE,WAAW,CAAC;QAC3D,KAAK,EAAE,CAAC,mBAAmB,EAAE,eAAe,EAAE,gBAAgB,CAAC;QAC/D,IAAI,EAAE,CAAC,aAAa,EAAE,kBAAkB,EAAE,eAAe,CAAC;QAC1D,IAAI,EAAE,CAAC,YAAY,EAAE,cAAc,EAAE,WAAW,CAAC;QACjD,IAAI,EAAE,CAAC,aAAa,EAAE,gBAAgB,EAAE,WAAW,CAAC;QACpD,gBAAgB,EAAE,CAAC,cAAc,EAAE,eAAe,EAAE,iBAAiB,CAAC;KACvE,CAAC;IAEF,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAAC,IAAc,EAAE,GAAiB;IAChE,MAAM,YAAY,GAA+B;QAC/C,KAAK,EAAE;YACL,yCAAyC;YACzC,2CAA2C;SAC5C;QACD,MAAM,EAAE;YACN,qDAAqD;YACrD,uCAAuC;SACxC;QACD,IAAI,EAAE;YACJ,oDAAoD;YACpD,uCAAuC;SACxC;QACD,QAAQ,EAAE;YACR,sCAAsC;YACtC,uCAAuC;SACxC;QACD,KAAK,EAAE;YACL,oCAAoC;YACpC,qCAAqC;SACtC;QACD,IAAI,EAAE;YACJ,wCAAwC;YACxC,yCAAyC;SAC1C;QACD,IAAI,EAAE;YACJ,8CAA8C;YAC9C,2BAA2B;SAC5B;QACD,IAAI,EAAE;YACJ,+BAA+B;YAC/B,gCAAgC;SACjC;QACD,gBAAgB,EAAE;YAChB,+CAA+C;YAC/C,6CAA6C;SAC9C;KACF,CAAC;IAEF,OAAO,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,KAAa,EAAE,MAAe,EAAE,GAAiB;IACxE,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,MAAM,SAAS,GAAG,KAAK,CAAC;IACxB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE7C,MAAM,UAAU,GAAG;QACjB,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE;QACvD,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;QAC7D,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;QAC1D,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE;QACtD,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;KAC/D,CAAC;IAEF,MAAM,SAAS,GAAG;QAChB,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;QAC9D,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;QAC7D,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;KAChE,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM;YACjB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACrB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEzB,MAAM,KAAK,GAAG,SAAS,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAE5D,OAAO,CAAC,IAAI,CAAC;YACX,EAAE,EAAE,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE;YAC9B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK;YACL,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;YACxC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3C,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC;YAC5C,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC;YAC7C,KAAK,EAAE,CAAC,GAAG,KAAK;YAChB,SAAS,EAAE,EAAE,GAAG,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxC,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK;YACtC,SAAS,EAAE;gBACT,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;gBACtE,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;aACvF;YACD,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,IAAY,EAAE,GAAiB;IAClD,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACtG,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE7B,mCAAmC;IACnC,MAAM,aAAa,GAA2B;QAC5C,QAAQ,EAAE,WAAW,IAAI,oSAAoS;QAC7T,IAAI,EAAE,WAAW,IAAI,0OAA0O;QAC/P,KAAK,EAAE,WAAW,IAAI,gNAAgN;QACtO,QAAQ,EAAE,WAAW,IAAI,oNAAoN;QAC7O,UAAU,EAAE,WAAW,IAAI,0NAA0N;QACrP,WAAW,EAAE,WAAW,IAAI,qKAAqK;KAClM,CAAC;IAEF,MAAM,YAAY,GAA2B;QAC3C,QAAQ,EAAE,GAAG,IAAI,2EAA2E;QAC5F,IAAI,EAAE,GAAG,IAAI,2EAA2E;QACxF,KAAK,EAAE,GAAG,IAAI,8DAA8D;QAC5E,QAAQ,EAAE,GAAG,IAAI,0DAA0D;QAC3E,UAAU,EAAE,GAAG,IAAI,kDAAkD;QACrE,WAAW,EAAE,GAAG,IAAI,6CAA6C;KAClE,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,OAAO,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;QAC1D,IAAI;QACJ,IAAI,EAAE,IAA0C;QAChD,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,UAAU,IAAI,EAAE;QAC5D,YAAY,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,WAAW,IAAI,+DAA+D;QACnH,aAAa,EAAE,EAAE;KAClB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,KAAa,EAAE,GAAiB;IACxD,MAAM,KAAK,GAA+C,EAAE,CAAC;IAE7D,OAAO;IACP,KAAK,CAAC,IAAI,CAAC;QACT,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,aAAa;QAC1B,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,KAAK;KACtC,CAAC,CAAC;IAEH,mCAAmC;IACnC,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,kBAAkB,IAAI,CAAC,GAAG,EAAE,EAAE;YAClC,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,wCAAwC;YACrD,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAY,EAAE,aAAqB;IACnE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAEhD,uCAAuC;IACvC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;QAC/B,IAAI,IAAI,GAAG,IAAI,CAAC;QAEhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;YAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAEnC,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,MAAM,GAAG,MAAM,KAAK,aAAa;oBACrC,CAAC,CAAC,KAAK;oBACP,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBACxB,IAAI,IAAI,MAAM,GAAG,GAAG,CAAC;gBAErB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;wBACzB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;wBACpB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;QAC/C,KAAK,EAAE,CAAC;IACV,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAEhD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,IAAU;IAC/B,IAAI,CAAC,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAEnC,MAAM,OAAO,GAA6B;QACxC,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,KAAK;QACX,gBAAgB,EAAE,KAAK;KACxB,CAAC;IAEF,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;AACrC,CAAC","debug_id":"410f4e46-1aa6-55e2-80b7-2bc845b5aef6"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Map module exports
3
+ */
4
+ export { generateMap, renderMapToString } from './MapGenerator.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["map/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Map module exports
3
+ */
4
+
5
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6a4f54c1-166c-5903-ab37-4904b0125e62")}catch(e){}}();
6
+ export { generateMap, renderMapToString } from './MapGenerator.js';
7
+ //# sourceMappingURL=index.js.map
8
+ //# debugId=6a4f54c1-166c-5903-ab37-4904b0125e62
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["map/index.ts"],"sourceRoot":"/","sourcesContent":["/**\r\n * Map module exports\r\n */\r\n\r\nexport { generateMap, renderMapToString } from './MapGenerator.js';\r\n"],"names":[],"mappings":"AAAA;;GAEG;;;AAEH,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC","debug_id":"6a4f54c1-166c-5903-ab37-4904b0125e62"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * NPC Generator - Creates NPCs with weighted traits
3
+ * Uses OC (Original Character) style generation patterns
4
+ */
5
+ import type { ExtendedNPC, NPCImportance, NPCRace, NPCRole, NPCGender } from './types.js';
6
+ interface GenerationConfig {
7
+ floor: number;
8
+ forceImportance?: NPCImportance;
9
+ forceRace?: NPCRace;
10
+ forceRole?: NPCRole;
11
+ forceGender?: NPCGender;
12
+ isFixed?: boolean;
13
+ fixedRoomId?: string;
14
+ }
15
+ export declare class NPCGenerator {
16
+ private generatedCount;
17
+ /**
18
+ * Generate a random NPC
19
+ */
20
+ generate(config: GenerationConfig): ExtendedNPC;
21
+ /**
22
+ * Roll for race based on floor and weights
23
+ */
24
+ private rollRace;
25
+ /**
26
+ * Roll for gender
27
+ */
28
+ private rollGender;
29
+ /**
30
+ * Roll for role based on race affinity and floor
31
+ */
32
+ private rollRole;
33
+ /**
34
+ * Generate a name based on race and gender
35
+ */
36
+ private generateName;
37
+ /**
38
+ * Roll for traits based on importance, race, and role
39
+ */
40
+ private rollTraits;
41
+ /**
42
+ * Generate appearance description
43
+ */
44
+ private generateAppearance;
45
+ /**
46
+ * Generate speech pattern based on traits
47
+ */
48
+ private generateSpeechPattern;
49
+ /**
50
+ * Generate backstory based on importance
51
+ */
52
+ private generateBackstory;
53
+ /**
54
+ * Build knowledge tier based on floor and importance
55
+ */
56
+ private buildKnowledgeTier;
57
+ /**
58
+ * Build the system prompt for AI dialog
59
+ */
60
+ private buildSystemPrompt;
61
+ /**
62
+ * Roll for age based on race lifespan
63
+ */
64
+ private rollAge;
65
+ }
66
+ export declare function getNPCGenerator(): NPCGenerator;
67
+ export {};
68
+ //# sourceMappingURL=NPCGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NPCGenerator.d.ts","sourceRoot":"/","sources":["npc/NPCGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,SAAS,EAGV,MAAM,YAAY,CAAC;AAgBpB,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,aAAa,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA2BD,qBAAa,YAAY;IACvB,OAAO,CAAC,cAAc,CAAK;IAE3B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW;IAkF/C;;OAEG;IACH,OAAO,CAAC,QAAQ;IAoBhB;;OAEG;IACH,OAAO,CAAC,UAAU;IAclB;;OAEG;IACH,OAAO,CAAC,QAAQ;IA4BhB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6BpB;;OAEG;IACH,OAAO,CAAC,UAAU;IAmElB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqC1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA6B7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA2CzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiD1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkEzB;;OAEG;IACH,OAAO,CAAC,OAAO;CAmBhB;AAKD,wBAAgB,eAAe,IAAI,YAAY,CAK9C"}
@@ -0,0 +1,468 @@
1
+ /**
2
+ * NPC Generator - Creates NPCs with weighted traits
3
+ * Uses OC (Original Character) style generation patterns
4
+ */
5
+
6
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a6b7d1b8-e91b-5469-99e4-9c4cddf3271b")}catch(e){}}();
7
+ import { RACES, ROLES, TRAITS, getRace, getRole, getImportanceWeight, rollImportance, } from './traits.js';
8
+ import { getLanguage } from '../i18n/index.js';
9
+ const DEFAULT_IMPORTANCE_WEIGHTS = {
10
+ legendary: 1,
11
+ major: 5,
12
+ minor: 20,
13
+ background: 74,
14
+ };
15
+ const TRAIT_COUNTS = {
16
+ legendary: { min: 5, max: 7 },
17
+ major: { min: 4, max: 5 },
18
+ minor: { min: 2, max: 4 },
19
+ background: { min: 1, max: 2 },
20
+ };
21
+ const GENDER_WEIGHTS = {
22
+ male: 45,
23
+ female: 45,
24
+ 'non-binary': 8,
25
+ unknown: 2,
26
+ };
27
+ // ============================================================================
28
+ // GENERATOR CLASS
29
+ // ============================================================================
30
+ export class NPCGenerator {
31
+ generatedCount = 0;
32
+ /**
33
+ * Generate a random NPC
34
+ */
35
+ generate(config) {
36
+ this.generatedCount++;
37
+ // Determine importance
38
+ const importance = config.forceImportance ?? rollImportance(DEFAULT_IMPORTANCE_WEIGHTS);
39
+ // Determine race (weighted, floor-aware)
40
+ const race = config.forceRace ?? this.rollRace(config.floor);
41
+ // Determine gender
42
+ const gender = config.forceGender ?? this.rollGender();
43
+ // Determine role (weighted, race-aware)
44
+ const role = config.forceRole ?? this.rollRole(race, config.floor);
45
+ // Generate name based on race and gender
46
+ const name = this.generateName(race, gender);
47
+ // Roll for traits based on importance
48
+ const traits = this.rollTraits(importance, race, role);
49
+ // Generate appearance
50
+ const appearance = this.generateAppearance(race, gender, traits);
51
+ // Generate speech pattern
52
+ const speechPattern = this.generateSpeechPattern(traits);
53
+ // Generate backstory based on importance
54
+ const backstory = this.generateBackstory(importance, race, role, traits);
55
+ // Build knowledge tier
56
+ const knowledgeTier = this.buildKnowledgeTier(config.floor, importance);
57
+ // Calculate age
58
+ const age = this.rollAge(race);
59
+ // Build system prompt
60
+ const systemPrompt = this.buildSystemPrompt({
61
+ name,
62
+ race,
63
+ gender,
64
+ role,
65
+ age,
66
+ traits,
67
+ appearance,
68
+ speechPattern,
69
+ backstory,
70
+ floor: config.floor,
71
+ knowledgeTier,
72
+ });
73
+ // Calculate death probability
74
+ const deathProbability = config.isFixed ? 0 : getImportanceWeight(importance);
75
+ return {
76
+ id: `npc_${Date.now()}_${this.generatedCount}`,
77
+ name,
78
+ race,
79
+ gender,
80
+ role,
81
+ importance,
82
+ age,
83
+ isFixed: config.isFixed ?? false,
84
+ fixedRoomId: config.fixedRoomId,
85
+ currentFloor: config.floor,
86
+ traits,
87
+ appearance,
88
+ speechPattern,
89
+ backstory,
90
+ systemPrompt,
91
+ knowledgeTier,
92
+ dialogHistory: [],
93
+ playerRelationship: 0,
94
+ metPlayer: false,
95
+ availableQuests: [],
96
+ givenQuests: [],
97
+ isAlive: true,
98
+ deathProbability,
99
+ createdAt: Date.now(),
100
+ };
101
+ }
102
+ /**
103
+ * Roll for race based on floor and weights
104
+ */
105
+ rollRace(floor) {
106
+ // Filter races by floor affinity
107
+ const eligible = RACES.filter(r => {
108
+ if (!r.floorAffinity)
109
+ return true;
110
+ return floor >= r.floorAffinity.min && floor <= r.floorAffinity.max;
111
+ });
112
+ const totalWeight = eligible.reduce((sum, r) => sum + r.weight, 0);
113
+ let roll = Math.random() * totalWeight;
114
+ for (const race of eligible) {
115
+ roll -= race.weight;
116
+ if (roll <= 0) {
117
+ return race.id;
118
+ }
119
+ }
120
+ return 'human';
121
+ }
122
+ /**
123
+ * Roll for gender
124
+ */
125
+ rollGender() {
126
+ const total = Object.values(GENDER_WEIGHTS).reduce((a, b) => a + b, 0);
127
+ let roll = Math.random() * total;
128
+ for (const [gender, weight] of Object.entries(GENDER_WEIGHTS)) {
129
+ roll -= weight;
130
+ if (roll <= 0) {
131
+ return gender;
132
+ }
133
+ }
134
+ return 'unknown';
135
+ }
136
+ /**
137
+ * Roll for role based on race affinity and floor
138
+ */
139
+ rollRole(race, floor) {
140
+ const raceDef = getRace(race);
141
+ // Filter roles by floor affinity
142
+ let eligible = ROLES.filter(r => {
143
+ if (!r.floorAffinity)
144
+ return true;
145
+ return floor >= r.floorAffinity.min && floor <= r.floorAffinity.max;
146
+ });
147
+ // Boost weight for roles typical of this race
148
+ const boosted = eligible.map(role => ({
149
+ ...role,
150
+ weight: role.typicalRaces.includes(race) ? role.weight * 2 : role.weight,
151
+ }));
152
+ const totalWeight = boosted.reduce((sum, r) => sum + r.weight, 0);
153
+ let roll = Math.random() * totalWeight;
154
+ for (const role of boosted) {
155
+ roll -= role.weight;
156
+ if (roll <= 0) {
157
+ return role.id;
158
+ }
159
+ }
160
+ return 'traveler';
161
+ }
162
+ /**
163
+ * Generate a name based on race and gender
164
+ */
165
+ generateName(race, gender) {
166
+ const raceDef = getRace(race);
167
+ if (!raceDef)
168
+ return 'Unknown';
169
+ const genderKey = gender === 'male' ? 'male' :
170
+ gender === 'female' ? 'female' : 'neutral';
171
+ const prefixes = raceDef.namePrefixes[genderKey].length > 0
172
+ ? raceDef.namePrefixes[genderKey]
173
+ : raceDef.namePrefixes.neutral;
174
+ const suffixes = raceDef.nameSuffixes[genderKey].length > 0
175
+ ? raceDef.nameSuffixes[genderKey]
176
+ : raceDef.nameSuffixes.neutral;
177
+ const prefix = prefixes[Math.floor(Math.random() * prefixes.length)];
178
+ // 50% chance to add suffix for longer name
179
+ if (Math.random() < 0.3 && suffixes.length > 0 && suffixes[0] !== '') {
180
+ const suffix = suffixes[Math.floor(Math.random() * suffixes.length)];
181
+ // Avoid doubling letters
182
+ if (!prefix.toLowerCase().endsWith(suffix[0]?.toLowerCase())) {
183
+ return prefix + suffix;
184
+ }
185
+ }
186
+ return prefix;
187
+ }
188
+ /**
189
+ * Roll for traits based on importance, race, and role
190
+ */
191
+ rollTraits(importance, race, role) {
192
+ const { min, max } = TRAIT_COUNTS[importance];
193
+ const count = Math.floor(Math.random() * (max - min + 1)) + min;
194
+ const raceDef = getRace(race);
195
+ const roleDef = getRole(role);
196
+ // Get eligible traits
197
+ const eligible = TRAITS.filter(t => {
198
+ // Check importance requirement
199
+ if (t.minImportance) {
200
+ const importanceOrder = ['background', 'minor', 'major', 'legendary'];
201
+ const minIndex = importanceOrder.indexOf(t.minImportance);
202
+ const currentIndex = importanceOrder.indexOf(importance);
203
+ if (currentIndex < minIndex)
204
+ return false;
205
+ }
206
+ // Check race requirement
207
+ if (t.requiresRace && !t.requiresRace.includes(race))
208
+ return false;
209
+ // Check role requirement
210
+ if (t.requiresRole && !t.requiresRole.includes(role))
211
+ return false;
212
+ return true;
213
+ });
214
+ // Boost weights for race/role associated traits
215
+ const boosted = eligible.map(t => {
216
+ let weight = t.weight;
217
+ if (raceDef?.traits.includes(t.id))
218
+ weight *= 2;
219
+ if (roleDef?.associatedTraits.includes(t.id))
220
+ weight *= 2;
221
+ return { ...t, weight };
222
+ });
223
+ // Select traits avoiding incompatibilities
224
+ const selected = [];
225
+ const usedIds = new Set();
226
+ for (let i = 0; i < count && boosted.length > 0; i++) {
227
+ const available = boosted.filter(t => {
228
+ if (usedIds.has(t.id))
229
+ return false;
230
+ if (t.incompatibleWith?.some(id => usedIds.has(id)))
231
+ return false;
232
+ return true;
233
+ });
234
+ if (available.length === 0)
235
+ break;
236
+ const totalWeight = available.reduce((sum, t) => sum + t.weight, 0);
237
+ let roll = Math.random() * totalWeight;
238
+ for (const trait of available) {
239
+ roll -= trait.weight;
240
+ if (roll <= 0) {
241
+ selected.push(trait);
242
+ usedIds.add(trait.id);
243
+ break;
244
+ }
245
+ }
246
+ }
247
+ return selected;
248
+ }
249
+ /**
250
+ * Generate appearance description
251
+ */
252
+ generateAppearance(race, gender, traits) {
253
+ const raceDef = getRace(race);
254
+ if (!raceDef)
255
+ return 'A mysterious figure.';
256
+ const parts = [];
257
+ // Race-specific appearance
258
+ if (raceDef.appearance.length > 0) {
259
+ const count = Math.min(2, raceDef.appearance.length);
260
+ const shuffled = [...raceDef.appearance].sort(() => Math.random() - 0.5);
261
+ parts.push(...shuffled.slice(0, count));
262
+ }
263
+ // Add trait-influenced appearance hints
264
+ if (traits.some(t => t.id === 'nervous')) {
265
+ parts.push('fidgety movements');
266
+ }
267
+ if (traits.some(t => t.id === 'arrogant')) {
268
+ parts.push('an imperious bearing');
269
+ }
270
+ if (traits.some(t => t.id === 'melancholic')) {
271
+ parts.push('sorrowful eyes');
272
+ }
273
+ if (traits.some(t => t.id === 'well_traveled')) {
274
+ parts.push('travel-worn clothes');
275
+ }
276
+ const genderPronoun = gender === 'male' ? 'He' :
277
+ gender === 'female' ? 'She' : 'They';
278
+ return `${genderPronoun} has ${parts.slice(0, 3).join(', ')}.`;
279
+ }
280
+ /**
281
+ * Generate speech pattern based on traits
282
+ */
283
+ generateSpeechPattern(traits) {
284
+ const patterns = [];
285
+ if (traits.some(t => t.id === 'stutters')) {
286
+ patterns.push('occasionally stutters');
287
+ }
288
+ if (traits.some(t => t.id === 'speaks_formally')) {
289
+ patterns.push('uses formal language');
290
+ }
291
+ if (traits.some(t => t.id === 'uses_slang')) {
292
+ patterns.push('uses casual slang');
293
+ }
294
+ if (traits.some(t => t.id === 'tells_stories')) {
295
+ patterns.push('tends to ramble into stories');
296
+ }
297
+ if (traits.some(t => t.id === 'gruff')) {
298
+ patterns.push('speaks curtly');
299
+ }
300
+ if (traits.some(t => t.id === 'mysterious')) {
301
+ patterns.push('speaks in riddles');
302
+ }
303
+ if (patterns.length === 0) {
304
+ patterns.push('speaks normally');
305
+ }
306
+ return patterns.join(', ');
307
+ }
308
+ /**
309
+ * Generate backstory based on importance
310
+ */
311
+ generateBackstory(importance, race, role, traits) {
312
+ const raceDef = getRace(race);
313
+ const roleDef = getRole(role);
314
+ // Background NPCs get minimal backstory
315
+ if (importance === 'background') {
316
+ return `A ${raceDef?.name.toLowerCase() || race} ${roleDef?.name.toLowerCase() || role} trying to survive.`;
317
+ }
318
+ const parts = [];
319
+ // Origin
320
+ if (traits.some(t => t.category === 'background')) {
321
+ const bg = traits.find(t => t.category === 'background');
322
+ parts.push(bg?.description || '');
323
+ }
324
+ // Motivation
325
+ const motivation = traits.find(t => t.category === 'motivation');
326
+ if (motivation) {
327
+ parts.push(motivation.description);
328
+ }
329
+ // Secret (for major+ NPCs)
330
+ if (importance === 'major' || importance === 'legendary') {
331
+ const secret = traits.find(t => t.category === 'secret');
332
+ if (secret) {
333
+ parts.push(`[SECRET: ${secret.description}]`);
334
+ }
335
+ }
336
+ if (parts.length === 0) {
337
+ return `A ${raceDef?.name.toLowerCase() || race} ${roleDef?.name.toLowerCase() || role} with their own story.`;
338
+ }
339
+ return parts.join('. ') + '.';
340
+ }
341
+ /**
342
+ * Build knowledge tier based on floor and importance
343
+ */
344
+ buildKnowledgeTier(floor, importance) {
345
+ const baseTier = {
346
+ floorRange: [Math.max(1, floor - 2), floor + 2],
347
+ topics: [],
348
+ secrets: [],
349
+ rumors: [],
350
+ questTypes: [],
351
+ };
352
+ // Floor 1-3: Basic knowledge
353
+ if (floor <= 3) {
354
+ baseTier.topics = ['dungeon layout', 'basic monsters', 'nearby merchants'];
355
+ baseTier.rumors = ['strange sounds from below', 'missing adventurers'];
356
+ baseTier.questTypes = ['kill', 'collect', 'explore'];
357
+ }
358
+ // Floor 4-6: Intermediate
359
+ else if (floor <= 6) {
360
+ baseTier.topics = ['monster weaknesses', 'trap locations', 'affix basics'];
361
+ baseTier.rumors = ['powerful artifacts', 'hidden passages'];
362
+ baseTier.questTypes = ['kill', 'collect', 'explore', 'deliver'];
363
+ }
364
+ // Floor 7-10: Advanced
365
+ else if (floor <= 10) {
366
+ baseTier.topics = ['boss patterns', 'rare affixes', 'dungeon history'];
367
+ baseTier.rumors = ['ancient evil', 'legendary weapons'];
368
+ baseTier.questTypes = ['kill', 'collect', 'explore', 'deliver', 'survive'];
369
+ }
370
+ // Floor 11+: Expert
371
+ else {
372
+ baseTier.topics = ['final boss', 'escape routes', 'ultimate secrets'];
373
+ baseTier.secrets = ['true nature of dungeon', 'way to escape'];
374
+ baseTier.rumors = ['what lies beyond', 'origins of this place'];
375
+ baseTier.questTypes = ['kill', 'collect', 'explore', 'deliver', 'survive', 'escort'];
376
+ }
377
+ // Importance modifies knowledge
378
+ if (importance === 'major' || importance === 'legendary') {
379
+ baseTier.floorRange = [1, floor + 5];
380
+ baseTier.secrets.push('hidden affix combinations');
381
+ }
382
+ if (importance === 'legendary') {
383
+ baseTier.secrets.push('true danger of this place');
384
+ baseTier.secrets.push('way to defeat the final boss');
385
+ }
386
+ return baseTier;
387
+ }
388
+ /**
389
+ * Build the system prompt for AI dialog
390
+ */
391
+ buildSystemPrompt(data) {
392
+ const lang = getLanguage();
393
+ const raceDef = getRace(data.race);
394
+ const roleDef = getRole(data.role);
395
+ const genderPronoun = data.gender === 'male' ? 'He/Him' :
396
+ data.gender === 'female' ? 'She/Her' : 'They/Them';
397
+ // Build personality section from traits
398
+ const personalityTraits = data.traits
399
+ .filter(t => t.category === 'personality')
400
+ .map(t => t.promptModifier)
401
+ .join(' ');
402
+ const quirks = data.traits
403
+ .filter(t => t.category === 'quirk')
404
+ .map(t => t.promptModifier)
405
+ .join(' ');
406
+ const secrets = data.traits
407
+ .filter(t => t.category === 'secret')
408
+ .map(t => t.promptModifier)
409
+ .join(' ');
410
+ const knownTopics = data.knowledgeTier.topics.join(', ');
411
+ const knownSecrets = data.knowledgeTier.secrets.length > 0
412
+ ? `You also know secrets about: ${data.knowledgeTier.secrets.join(', ')}`
413
+ : '';
414
+ const prompt = `You are ${data.name}, a ${data.age}-year-old ${raceDef?.name || data.race} ${roleDef?.name || data.role} (${genderPronoun}).
415
+
416
+ APPEARANCE: ${data.appearance}
417
+
418
+ PERSONALITY: ${personalityTraits || 'You have a straightforward personality.'}
419
+
420
+ SPEECH STYLE: ${data.speechPattern}. ${quirks || ''}
421
+
422
+ BACKSTORY: ${data.backstory}
423
+
424
+ KNOWLEDGE: You are on floor ${data.floor} of a dangerous dungeon. You know about: ${knownTopics}. ${knownSecrets}
425
+
426
+ ${secrets ? `HIDDEN AGENDA: ${secrets} (Do not reveal this directly, only hint at it.)` : ''}
427
+
428
+ INSTRUCTIONS:
429
+ - Stay in character at all times
430
+ - Keep responses to 2-3 sentences unless telling a story
431
+ - React naturally to the player's questions
432
+ - You can give quests if asked, related to: ${data.knowledgeTier.questTypes.join(', ')}
433
+ - Only share knowledge appropriate to your floor level and importance
434
+ - ${lang === 'zh' ? 'Respond in Chinese.' : 'Respond in English.'}`;
435
+ return prompt;
436
+ }
437
+ /**
438
+ * Roll for age based on race lifespan
439
+ */
440
+ rollAge(race) {
441
+ const ageRanges = {
442
+ human: { min: 18, max: 70 },
443
+ elf: { min: 100, max: 700 },
444
+ dwarf: { min: 50, max: 300 },
445
+ halfling: { min: 25, max: 120 },
446
+ gnome: { min: 40, max: 350 },
447
+ 'half-elf': { min: 20, max: 150 },
448
+ 'half-orc': { min: 15, max: 60 },
449
+ tiefling: { min: 20, max: 100 },
450
+ dragonborn: { min: 15, max: 80 },
451
+ goblin: { min: 10, max: 50 },
452
+ orc: { min: 12, max: 50 },
453
+ undead: { min: 100, max: 1000 },
454
+ };
455
+ const range = ageRanges[race] || { min: 20, max: 60 };
456
+ return Math.floor(Math.random() * (range.max - range.min)) + range.min;
457
+ }
458
+ }
459
+ // Singleton
460
+ let generatorInstance = null;
461
+ export function getNPCGenerator() {
462
+ if (!generatorInstance) {
463
+ generatorInstance = new NPCGenerator();
464
+ }
465
+ return generatorInstance;
466
+ }
467
+ //# sourceMappingURL=NPCGenerator.js.map
468
+ //# debugId=a6b7d1b8-e91b-5469-99e4-9c4cddf3271b