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.
- package/README.md +171 -0
- package/dist/affix/AffixRegistry.d.ts +68 -0
- package/dist/affix/AffixRegistry.d.ts.map +1 -0
- package/dist/affix/AffixRegistry.js +245 -0
- package/dist/affix/AffixRegistry.js.map +1 -0
- package/dist/affix/PluginLoader.d.ts +66 -0
- package/dist/affix/PluginLoader.d.ts.map +1 -0
- package/dist/affix/PluginLoader.js +321 -0
- package/dist/affix/PluginLoader.js.map +1 -0
- package/dist/affix/builtin.d.ts +6 -0
- package/dist/affix/builtin.d.ts.map +1 -0
- package/dist/affix/builtin.js +311 -0
- package/dist/affix/builtin.js.map +1 -0
- package/dist/affix/index.d.ts +8 -0
- package/dist/affix/index.d.ts.map +1 -0
- package/dist/affix/index.js +11 -0
- package/dist/affix/index.js.map +1 -0
- package/dist/affix/types.d.ts +152 -0
- package/dist/affix/types.d.ts.map +1 -0
- package/dist/affix/types.js +8 -0
- package/dist/affix/types.js.map +1 -0
- package/dist/ai/PlayKitClient.d.ts +208 -0
- package/dist/ai/PlayKitClient.d.ts.map +1 -0
- package/dist/ai/PlayKitClient.js +721 -0
- package/dist/ai/PlayKitClient.js.map +1 -0
- package/dist/ai/index.d.ts +5 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +8 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/app/App.d.ts +85 -0
- package/dist/app/App.d.ts.map +1 -0
- package/dist/app/App.js +296 -0
- package/dist/app/App.js.map +1 -0
- package/dist/app/EventBus.d.ts +222 -0
- package/dist/app/EventBus.d.ts.map +1 -0
- package/dist/app/EventBus.js +88 -0
- package/dist/app/EventBus.js.map +1 -0
- package/dist/app/Keybind.d.ts +83 -0
- package/dist/app/Keybind.d.ts.map +1 -0
- package/dist/app/Keybind.js +184 -0
- package/dist/app/Keybind.js.map +1 -0
- package/dist/app/Router.d.ts +123 -0
- package/dist/app/Router.d.ts.map +1 -0
- package/dist/app/Router.js +142 -0
- package/dist/app/Router.js.map +1 -0
- package/dist/app/ScreenManager.d.ts +97 -0
- package/dist/app/ScreenManager.d.ts.map +1 -0
- package/dist/app/ScreenManager.js +216 -0
- package/dist/app/ScreenManager.js.map +1 -0
- package/dist/app/index.d.ts +14 -0
- package/dist/app/index.d.ts.map +1 -0
- package/dist/app/index.js +19 -0
- package/dist/app/index.js.map +1 -0
- package/dist/app/screens/BaseScreen.d.ts +101 -0
- package/dist/app/screens/BaseScreen.d.ts.map +1 -0
- package/dist/app/screens/BaseScreen.js +132 -0
- package/dist/app/screens/BaseScreen.js.map +1 -0
- package/dist/app/screens/CharacterCreationScreen.d.ts +42 -0
- package/dist/app/screens/CharacterCreationScreen.d.ts.map +1 -0
- package/dist/app/screens/CharacterCreationScreen.js +467 -0
- package/dist/app/screens/CharacterCreationScreen.js.map +1 -0
- package/dist/app/screens/CombatScreen.d.ts +30 -0
- package/dist/app/screens/CombatScreen.d.ts.map +1 -0
- package/dist/app/screens/CombatScreen.js +309 -0
- package/dist/app/screens/CombatScreen.js.map +1 -0
- package/dist/app/screens/DialogScreen.d.ts +29 -0
- package/dist/app/screens/DialogScreen.d.ts.map +1 -0
- package/dist/app/screens/DialogScreen.js +295 -0
- package/dist/app/screens/DialogScreen.js.map +1 -0
- package/dist/app/screens/ExploreScreen.d.ts +50 -0
- package/dist/app/screens/ExploreScreen.d.ts.map +1 -0
- package/dist/app/screens/ExploreScreen.js +308 -0
- package/dist/app/screens/ExploreScreen.js.map +1 -0
- package/dist/app/screens/HelpScreen.d.ts +12 -0
- package/dist/app/screens/HelpScreen.d.ts.map +1 -0
- package/dist/app/screens/HelpScreen.js +155 -0
- package/dist/app/screens/HelpScreen.js.map +1 -0
- package/dist/app/screens/InventoryScreen.d.ts +27 -0
- package/dist/app/screens/InventoryScreen.d.ts.map +1 -0
- package/dist/app/screens/InventoryScreen.js +326 -0
- package/dist/app/screens/InventoryScreen.js.map +1 -0
- package/dist/app/screens/PrologueScreen.d.ts +24 -0
- package/dist/app/screens/PrologueScreen.d.ts.map +1 -0
- package/dist/app/screens/PrologueScreen.js +176 -0
- package/dist/app/screens/PrologueScreen.js.map +1 -0
- package/dist/app/screens/TitleScreen.d.ts +42 -0
- package/dist/app/screens/TitleScreen.d.ts.map +1 -0
- package/dist/app/screens/TitleScreen.js +380 -0
- package/dist/app/screens/TitleScreen.js.map +1 -0
- package/dist/app/screens/TravelScreen.d.ts +22 -0
- package/dist/app/screens/TravelScreen.d.ts.map +1 -0
- package/dist/app/screens/TravelScreen.js +122 -0
- package/dist/app/screens/TravelScreen.js.map +1 -0
- package/dist/app/screens/index.d.ts +14 -0
- package/dist/app/screens/index.d.ts.map +1 -0
- package/dist/app/screens/index.js +17 -0
- package/dist/app/screens/index.js.map +1 -0
- package/dist/commands/CommandRegistry.d.ts +91 -0
- package/dist/commands/CommandRegistry.d.ts.map +1 -0
- package/dist/commands/CommandRegistry.js +159 -0
- package/dist/commands/CommandRegistry.js.map +1 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +10 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/core/Actor.d.ts +103 -0
- package/dist/core/Actor.d.ts.map +1 -0
- package/dist/core/Actor.js +409 -0
- package/dist/core/Actor.js.map +1 -0
- package/dist/core/Combat.d.ts +37 -0
- package/dist/core/Combat.d.ts.map +1 -0
- package/dist/core/Combat.js +294 -0
- package/dist/core/Combat.js.map +1 -0
- package/dist/core/DungeonRunner.d.ts +169 -0
- package/dist/core/DungeonRunner.d.ts.map +1 -0
- package/dist/core/DungeonRunner.js +627 -0
- package/dist/core/DungeonRunner.js.map +1 -0
- package/dist/core/Game.d.ts +133 -0
- package/dist/core/Game.d.ts.map +1 -0
- package/dist/core/Game.js +644 -0
- package/dist/core/Game.js.map +1 -0
- package/dist/core/IdleCombat.d.ts +61 -0
- package/dist/core/IdleCombat.d.ts.map +1 -0
- package/dist/core/IdleCombat.js +461 -0
- package/dist/core/IdleCombat.js.map +1 -0
- package/dist/core/IdleGameManager.d.ts +198 -0
- package/dist/core/IdleGameManager.d.ts.map +1 -0
- package/dist/core/IdleGameManager.js +688 -0
- package/dist/core/IdleGameManager.js.map +1 -0
- package/dist/core/IdleSaveManager.d.ts +109 -0
- package/dist/core/IdleSaveManager.d.ts.map +1 -0
- package/dist/core/IdleSaveManager.js +296 -0
- package/dist/core/IdleSaveManager.js.map +1 -0
- package/dist/core/NewGameFlowManager.d.ts +64 -0
- package/dist/core/NewGameFlowManager.d.ts.map +1 -0
- package/dist/core/NewGameFlowManager.js +153 -0
- package/dist/core/NewGameFlowManager.js.map +1 -0
- package/dist/core/Player.d.ts +65 -0
- package/dist/core/Player.d.ts.map +1 -0
- package/dist/core/Player.js +261 -0
- package/dist/core/Player.js.map +1 -0
- package/dist/core/RoomHandlers.d.ts +75 -0
- package/dist/core/RoomHandlers.d.ts.map +1 -0
- package/dist/core/RoomHandlers.js +383 -0
- package/dist/core/RoomHandlers.js.map +1 -0
- package/dist/core/SaveManager.d.ts +84 -0
- package/dist/core/SaveManager.d.ts.map +1 -0
- package/dist/core/SaveManager.js +281 -0
- package/dist/core/SaveManager.js.map +1 -0
- package/dist/core/SaveMigration.d.ts +69 -0
- package/dist/core/SaveMigration.d.ts.map +1 -0
- package/dist/core/SaveMigration.js +408 -0
- package/dist/core/SaveMigration.js.map +1 -0
- package/dist/core/StateAdapter.d.ts +79 -0
- package/dist/core/StateAdapter.d.ts.map +1 -0
- package/dist/core/StateAdapter.js +397 -0
- package/dist/core/StateAdapter.js.map +1 -0
- package/dist/core/Team.d.ts +145 -0
- package/dist/core/Team.d.ts.map +1 -0
- package/dist/core/Team.js +371 -0
- package/dist/core/Team.js.map +1 -0
- package/dist/core/TeamCombat.d.ts +88 -0
- package/dist/core/TeamCombat.d.ts.map +1 -0
- package/dist/core/TeamCombat.js +405 -0
- package/dist/core/TeamCombat.js.map +1 -0
- package/dist/core/TeamDungeonRunner.d.ts +186 -0
- package/dist/core/TeamDungeonRunner.d.ts.map +1 -0
- package/dist/core/TeamDungeonRunner.js +758 -0
- package/dist/core/TeamDungeonRunner.js.map +1 -0
- package/dist/core/TimeManager.d.ts +114 -0
- package/dist/core/TimeManager.d.ts.map +1 -0
- package/dist/core/TimeManager.js +318 -0
- package/dist/core/TimeManager.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/timeConstants.d.ts +135 -0
- package/dist/core/timeConstants.d.ts.map +1 -0
- package/dist/core/timeConstants.js +157 -0
- package/dist/core/timeConstants.js.map +1 -0
- package/dist/core/types.d.ts +780 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +16 -0
- package/dist/core/types.js.map +1 -0
- package/dist/data/continents/index.d.ts +163 -0
- package/dist/data/continents/index.d.ts.map +1 -0
- package/dist/data/continents/index.js +31 -0
- package/dist/data/continents/index.js.map +1 -0
- package/dist/data/continents/verdantia.d.ts +294 -0
- package/dist/data/continents/verdantia.d.ts.map +1 -0
- package/dist/data/continents/verdantia.js +327 -0
- package/dist/data/continents/verdantia.js.map +1 -0
- package/dist/handlers/DialogHandler.d.ts +95 -0
- package/dist/handlers/DialogHandler.d.ts.map +1 -0
- package/dist/handlers/DialogHandler.js +450 -0
- package/dist/handlers/DialogHandler.js.map +1 -0
- package/dist/handlers/SaveLoadHandler.d.ts +60 -0
- package/dist/handlers/SaveLoadHandler.d.ts.map +1 -0
- package/dist/handlers/SaveLoadHandler.js +187 -0
- package/dist/handlers/SaveLoadHandler.js.map +1 -0
- package/dist/handlers/TitleScreenHandler.d.ts +43 -0
- package/dist/handlers/TitleScreenHandler.d.ts.map +1 -0
- package/dist/handlers/TitleScreenHandler.js +508 -0
- package/dist/handlers/TitleScreenHandler.js.map +1 -0
- package/dist/handlers/WorkshopHandler.d.ts +75 -0
- package/dist/handlers/WorkshopHandler.d.ts.map +1 -0
- package/dist/handlers/WorkshopHandler.js +401 -0
- package/dist/handlers/WorkshopHandler.js.map +1 -0
- package/dist/handlers/index.d.ts +12 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +14 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/types.d.ts +34 -0
- package/dist/handlers/types.d.ts.map +1 -0
- package/dist/handlers/types.js +8 -0
- package/dist/handlers/types.js.map +1 -0
- package/dist/i18n/en.d.ts +3 -0
- package/dist/i18n/en.d.ts.map +1 -0
- package/dist/i18n/en.js +130 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/index.d.ts +40 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +105 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/types.d.ts +133 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +8 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/i18n/zh.d.ts +3 -0
- package/dist/i18n/zh.d.ts.map +1 -0
- package/dist/i18n/zh.js +130 -0
- package/dist/i18n/zh.js.map +1 -0
- package/dist/instrument.d.ts +8 -0
- package/dist/instrument.d.ts.map +1 -0
- package/dist/instrument.js +33 -0
- package/dist/instrument.js.map +1 -0
- package/dist/main-new.d.ts +12 -0
- package/dist/main-new.d.ts.map +1 -0
- package/dist/main-new.js +32 -0
- package/dist/main-new.js.map +1 -0
- package/dist/main.d.ts +7 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +2816 -0
- package/dist/main.js.map +1 -0
- package/dist/map/ContinentManager.d.ts +88 -0
- package/dist/map/ContinentManager.d.ts.map +1 -0
- package/dist/map/ContinentManager.js +241 -0
- package/dist/map/ContinentManager.js.map +1 -0
- package/dist/map/DungeonGenerator.d.ts +32 -0
- package/dist/map/DungeonGenerator.d.ts.map +1 -0
- package/dist/map/DungeonGenerator.js +615 -0
- package/dist/map/DungeonGenerator.js.map +1 -0
- package/dist/map/MapGenerator.d.ts +27 -0
- package/dist/map/MapGenerator.d.ts.map +1 -0
- package/dist/map/MapGenerator.js +485 -0
- package/dist/map/MapGenerator.js.map +1 -0
- package/dist/map/index.d.ts +5 -0
- package/dist/map/index.d.ts.map +1 -0
- package/dist/map/index.js +8 -0
- package/dist/map/index.js.map +1 -0
- package/dist/npc/NPCGenerator.d.ts +68 -0
- package/dist/npc/NPCGenerator.d.ts.map +1 -0
- package/dist/npc/NPCGenerator.js +468 -0
- package/dist/npc/NPCGenerator.js.map +1 -0
- package/dist/npc/NPCManager.d.ts +86 -0
- package/dist/npc/NPCManager.d.ts.map +1 -0
- package/dist/npc/NPCManager.js +217 -0
- package/dist/npc/NPCManager.js.map +1 -0
- package/dist/npc/fixedNPCs.d.ts +7 -0
- package/dist/npc/fixedNPCs.d.ts.map +1 -0
- package/dist/npc/fixedNPCs.js +196 -0
- package/dist/npc/fixedNPCs.js.map +1 -0
- package/dist/npc/index.d.ts +9 -0
- package/dist/npc/index.d.ts.map +1 -0
- package/dist/npc/index.js +12 -0
- package/dist/npc/index.js.map +1 -0
- package/dist/npc/traits.d.ts +33 -0
- package/dist/npc/traits.d.ts.map +1 -0
- package/dist/npc/traits.js +795 -0
- package/dist/npc/traits.js.map +1 -0
- package/dist/npc/types.d.ts +193 -0
- package/dist/npc/types.d.ts.map +1 -0
- package/dist/npc/types.js +9 -0
- package/dist/npc/types.js.map +1 -0
- package/dist/quest/QuestManager.d.ts +79 -0
- package/dist/quest/QuestManager.d.ts.map +1 -0
- package/dist/quest/QuestManager.js +273 -0
- package/dist/quest/QuestManager.js.map +1 -0
- package/dist/quest/index.d.ts +6 -0
- package/dist/quest/index.d.ts.map +1 -0
- package/dist/quest/index.js +9 -0
- package/dist/quest/index.js.map +1 -0
- package/dist/quest/types.d.ts +81 -0
- package/dist/quest/types.d.ts.map +1 -0
- package/dist/quest/types.js +8 -0
- package/dist/quest/types.js.map +1 -0
- package/dist/strategy/StrategyExecutor.d.ts +159 -0
- package/dist/strategy/StrategyExecutor.d.ts.map +1 -0
- package/dist/strategy/StrategyExecutor.js +479 -0
- package/dist/strategy/StrategyExecutor.js.map +1 -0
- package/dist/strategy/StrategyParser.d.ts +48 -0
- package/dist/strategy/StrategyParser.d.ts.map +1 -0
- package/dist/strategy/StrategyParser.js +321 -0
- package/dist/strategy/StrategyParser.js.map +1 -0
- package/dist/strategy/defaultStrategy.d.ts +40 -0
- package/dist/strategy/defaultStrategy.d.ts.map +1 -0
- package/dist/strategy/defaultStrategy.js +254 -0
- package/dist/strategy/defaultStrategy.js.map +1 -0
- package/dist/strategy/index.d.ts +8 -0
- package/dist/strategy/index.d.ts.map +1 -0
- package/dist/strategy/index.js +14 -0
- package/dist/strategy/index.js.map +1 -0
- package/dist/tui/ExploreMenu.d.ts +106 -0
- package/dist/tui/ExploreMenu.d.ts.map +1 -0
- package/dist/tui/ExploreMenu.js +282 -0
- package/dist/tui/ExploreMenu.js.map +1 -0
- package/dist/tui/GameUI.d.ts +313 -0
- package/dist/tui/GameUI.d.ts.map +1 -0
- package/dist/tui/GameUI.js +2116 -0
- package/dist/tui/GameUI.js.map +1 -0
- package/dist/tui/GameUIAdapter.d.ts +207 -0
- package/dist/tui/GameUIAdapter.d.ts.map +1 -0
- package/dist/tui/GameUIAdapter.js +1342 -0
- package/dist/tui/GameUIAdapter.js.map +1 -0
- package/dist/tui/Input.d.ts +139 -0
- package/dist/tui/Input.d.ts.map +1 -0
- package/dist/tui/Input.js +278 -0
- package/dist/tui/Input.js.map +1 -0
- package/dist/tui/Menu.d.ts +110 -0
- package/dist/tui/Menu.d.ts.map +1 -0
- package/dist/tui/Menu.js +365 -0
- package/dist/tui/Menu.js.map +1 -0
- package/dist/tui/Screen.d.ts +228 -0
- package/dist/tui/Screen.d.ts.map +1 -0
- package/dist/tui/Screen.js +502 -0
- package/dist/tui/Screen.js.map +1 -0
- package/dist/tui/components/Box.d.ts +36 -0
- package/dist/tui/components/Box.d.ts.map +1 -0
- package/dist/tui/components/Box.js +43 -0
- package/dist/tui/components/Box.js.map +1 -0
- package/dist/tui/components/List.d.ts +69 -0
- package/dist/tui/components/List.d.ts.map +1 -0
- package/dist/tui/components/List.js +136 -0
- package/dist/tui/components/List.js.map +1 -0
- package/dist/tui/components/ProgressBar.d.ts +42 -0
- package/dist/tui/components/ProgressBar.d.ts.map +1 -0
- package/dist/tui/components/ProgressBar.js +75 -0
- package/dist/tui/components/ProgressBar.js.map +1 -0
- package/dist/tui/components/index.d.ts +8 -0
- package/dist/tui/components/index.d.ts.map +1 -0
- package/dist/tui/components/index.js +11 -0
- package/dist/tui/components/index.js.map +1 -0
- package/dist/tui/core/BaseSection.d.ts +98 -0
- package/dist/tui/core/BaseSection.d.ts.map +1 -0
- package/dist/tui/core/BaseSection.js +174 -0
- package/dist/tui/core/BaseSection.js.map +1 -0
- package/dist/tui/core/Component.d.ts +61 -0
- package/dist/tui/core/Component.d.ts.map +1 -0
- package/dist/tui/core/Component.js +32 -0
- package/dist/tui/core/Component.js.map +1 -0
- package/dist/tui/core/Section.d.ts +101 -0
- package/dist/tui/core/Section.d.ts.map +1 -0
- package/dist/tui/core/Section.js +24 -0
- package/dist/tui/core/Section.js.map +1 -0
- package/dist/tui/core/SectionManager.d.ts +108 -0
- package/dist/tui/core/SectionManager.d.ts.map +1 -0
- package/dist/tui/core/SectionManager.js +258 -0
- package/dist/tui/core/SectionManager.js.map +1 -0
- package/dist/tui/core/index.d.ts +9 -0
- package/dist/tui/core/index.d.ts.map +1 -0
- package/dist/tui/core/index.js +12 -0
- package/dist/tui/core/index.js.map +1 -0
- package/dist/tui/index.d.ts +15 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +23 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/screens/BaseScreen.d.ts +62 -0
- package/dist/tui/screens/BaseScreen.d.ts.map +1 -0
- package/dist/tui/screens/BaseScreen.js +55 -0
- package/dist/tui/screens/BaseScreen.js.map +1 -0
- package/dist/tui/screens/CombatScreen.d.ts +43 -0
- package/dist/tui/screens/CombatScreen.d.ts.map +1 -0
- package/dist/tui/screens/CombatScreen.js +125 -0
- package/dist/tui/screens/CombatScreen.js.map +1 -0
- package/dist/tui/screens/DialogScreen.d.ts +53 -0
- package/dist/tui/screens/DialogScreen.d.ts.map +1 -0
- package/dist/tui/screens/DialogScreen.js +90 -0
- package/dist/tui/screens/DialogScreen.js.map +1 -0
- package/dist/tui/screens/DungeonScreen.d.ts +80 -0
- package/dist/tui/screens/DungeonScreen.d.ts.map +1 -0
- package/dist/tui/screens/DungeonScreen.js +317 -0
- package/dist/tui/screens/DungeonScreen.js.map +1 -0
- package/dist/tui/screens/ExploreScreen.d.ts +69 -0
- package/dist/tui/screens/ExploreScreen.d.ts.map +1 -0
- package/dist/tui/screens/ExploreScreen.js +224 -0
- package/dist/tui/screens/ExploreScreen.js.map +1 -0
- package/dist/tui/screens/SectionScreen.d.ts +84 -0
- package/dist/tui/screens/SectionScreen.d.ts.map +1 -0
- package/dist/tui/screens/SectionScreen.js +156 -0
- package/dist/tui/screens/SectionScreen.js.map +1 -0
- package/dist/tui/screens/TitleScreen.d.ts +40 -0
- package/dist/tui/screens/TitleScreen.d.ts.map +1 -0
- package/dist/tui/screens/TitleScreen.js +253 -0
- package/dist/tui/screens/TitleScreen.js.map +1 -0
- package/dist/tui/screens/TownScreen.d.ts +98 -0
- package/dist/tui/screens/TownScreen.d.ts.map +1 -0
- package/dist/tui/screens/TownScreen.js +370 -0
- package/dist/tui/screens/TownScreen.js.map +1 -0
- package/dist/tui/screens/TravelScreen.d.ts +67 -0
- package/dist/tui/screens/TravelScreen.d.ts.map +1 -0
- package/dist/tui/screens/TravelScreen.js +286 -0
- package/dist/tui/screens/TravelScreen.js.map +1 -0
- package/dist/tui/screens/index.d.ts +8 -0
- package/dist/tui/screens/index.d.ts.map +1 -0
- package/dist/tui/screens/index.js +17 -0
- package/dist/tui/screens/index.js.map +1 -0
- package/dist/tui/sections/ActionsSection.d.ts +71 -0
- package/dist/tui/sections/ActionsSection.d.ts.map +1 -0
- package/dist/tui/sections/ActionsSection.js +184 -0
- package/dist/tui/sections/ActionsSection.js.map +1 -0
- package/dist/tui/sections/DungeonSection.d.ts +65 -0
- package/dist/tui/sections/DungeonSection.d.ts.map +1 -0
- package/dist/tui/sections/DungeonSection.js +144 -0
- package/dist/tui/sections/DungeonSection.js.map +1 -0
- package/dist/tui/sections/EventsSection.d.ts +50 -0
- package/dist/tui/sections/EventsSection.d.ts.map +1 -0
- package/dist/tui/sections/EventsSection.js +134 -0
- package/dist/tui/sections/EventsSection.js.map +1 -0
- package/dist/tui/sections/MapSection.d.ts +66 -0
- package/dist/tui/sections/MapSection.d.ts.map +1 -0
- package/dist/tui/sections/MapSection.js +669 -0
- package/dist/tui/sections/MapSection.js.map +1 -0
- package/dist/tui/sections/StatusSection.d.ts +47 -0
- package/dist/tui/sections/StatusSection.d.ts.map +1 -0
- package/dist/tui/sections/StatusSection.js +133 -0
- package/dist/tui/sections/StatusSection.js.map +1 -0
- package/dist/tui/sections/TeamSection.d.ts +71 -0
- package/dist/tui/sections/TeamSection.d.ts.map +1 -0
- package/dist/tui/sections/TeamSection.js +224 -0
- package/dist/tui/sections/TeamSection.js.map +1 -0
- package/dist/tui/sections/TravelingSection.d.ts +51 -0
- package/dist/tui/sections/TravelingSection.d.ts.map +1 -0
- package/dist/tui/sections/TravelingSection.js +106 -0
- package/dist/tui/sections/TravelingSection.js.map +1 -0
- package/dist/tui/sections/index.d.ts +9 -0
- package/dist/tui/sections/index.d.ts.map +1 -0
- package/dist/tui/sections/index.js +12 -0
- package/dist/tui/sections/index.js.map +1 -0
- package/dist/ui/Terminal.d.ts +68 -0
- package/dist/ui/Terminal.d.ts.map +1 -0
- package/dist/ui/Terminal.js +297 -0
- package/dist/ui/Terminal.js.map +1 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +8 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/utils/configMigration.d.ts +14 -0
- package/dist/utils/configMigration.d.ts.map +1 -0
- package/dist/utils/configMigration.js +92 -0
- package/dist/utils/configMigration.js.map +1 -0
- package/dist/utils/errorHandler.d.ts +86 -0
- package/dist/utils/errorHandler.d.ts.map +1 -0
- package/dist/utils/errorHandler.js +224 -0
- package/dist/utils/errorHandler.js.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +43 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/weapon/WeaponFactory.d.ts +32 -0
- package/dist/weapon/WeaponFactory.d.ts.map +1 -0
- package/dist/weapon/WeaponFactory.js +216 -0
- package/dist/weapon/WeaponFactory.js.map +1 -0
- package/dist/weapon/index.d.ts +5 -0
- package/dist/weapon/index.d.ts.map +1 -0
- package/dist/weapon/index.js +8 -0
- package/dist/weapon/index.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NPCGenerator.js","sources":["npc/NPCGenerator.ts"],"sourceRoot":"/","sourcesContent":["/**\r\n * NPC Generator - Creates NPCs with weighted traits\r\n * Uses OC (Original Character) style generation patterns\r\n */\r\n\r\nimport type {\r\n ExtendedNPC,\r\n NPCImportance,\r\n NPCRace,\r\n NPCRole,\r\n NPCGender,\r\n WeightedTrait,\r\n KnowledgeTier,\r\n} from './types.js';\r\nimport {\r\n RACES,\r\n ROLES,\r\n TRAITS,\r\n getRace,\r\n getRole,\r\n getImportanceWeight,\r\n rollImportance,\r\n} from './traits.js';\r\nimport { getLanguage, getPrompts } from '../i18n/index.js';\r\n\r\n// ============================================================================\r\n// CONFIGURATION\r\n// ============================================================================\r\n\r\ninterface GenerationConfig {\r\n floor: number;\r\n forceImportance?: NPCImportance;\r\n forceRace?: NPCRace;\r\n forceRole?: NPCRole;\r\n forceGender?: NPCGender;\r\n isFixed?: boolean;\r\n fixedRoomId?: string;\r\n}\r\n\r\nconst DEFAULT_IMPORTANCE_WEIGHTS: Record<NPCImportance, number> = {\r\n legendary: 1,\r\n major: 5,\r\n minor: 20,\r\n background: 74,\r\n};\r\n\r\nconst TRAIT_COUNTS: Record<NPCImportance, { min: number; max: number }> = {\r\n legendary: { min: 5, max: 7 },\r\n major: { min: 4, max: 5 },\r\n minor: { min: 2, max: 4 },\r\n background: { min: 1, max: 2 },\r\n};\r\n\r\nconst GENDER_WEIGHTS: Record<NPCGender, number> = {\r\n male: 45,\r\n female: 45,\r\n 'non-binary': 8,\r\n unknown: 2,\r\n};\r\n\r\n// ============================================================================\r\n// GENERATOR CLASS\r\n// ============================================================================\r\n\r\nexport class NPCGenerator {\r\n private generatedCount = 0;\r\n\r\n /**\r\n * Generate a random NPC\r\n */\r\n generate(config: GenerationConfig): ExtendedNPC {\r\n this.generatedCount++;\r\n\r\n // Determine importance\r\n const importance = config.forceImportance ?? rollImportance(DEFAULT_IMPORTANCE_WEIGHTS);\r\n\r\n // Determine race (weighted, floor-aware)\r\n const race = config.forceRace ?? this.rollRace(config.floor);\r\n\r\n // Determine gender\r\n const gender = config.forceGender ?? this.rollGender();\r\n\r\n // Determine role (weighted, race-aware)\r\n const role = config.forceRole ?? this.rollRole(race, config.floor);\r\n\r\n // Generate name based on race and gender\r\n const name = this.generateName(race, gender);\r\n\r\n // Roll for traits based on importance\r\n const traits = this.rollTraits(importance, race, role);\r\n\r\n // Generate appearance\r\n const appearance = this.generateAppearance(race, gender, traits);\r\n\r\n // Generate speech pattern\r\n const speechPattern = this.generateSpeechPattern(traits);\r\n\r\n // Generate backstory based on importance\r\n const backstory = this.generateBackstory(importance, race, role, traits);\r\n\r\n // Build knowledge tier\r\n const knowledgeTier = this.buildKnowledgeTier(config.floor, importance);\r\n\r\n // Calculate age\r\n const age = this.rollAge(race);\r\n\r\n // Build system prompt\r\n const systemPrompt = this.buildSystemPrompt({\r\n name,\r\n race,\r\n gender,\r\n role,\r\n age,\r\n traits,\r\n appearance,\r\n speechPattern,\r\n backstory,\r\n floor: config.floor,\r\n knowledgeTier,\r\n });\r\n\r\n // Calculate death probability\r\n const deathProbability = config.isFixed ? 0 : getImportanceWeight(importance);\r\n\r\n return {\r\n id: `npc_${Date.now()}_${this.generatedCount}`,\r\n name,\r\n race,\r\n gender,\r\n role,\r\n importance,\r\n age,\r\n isFixed: config.isFixed ?? false,\r\n fixedRoomId: config.fixedRoomId,\r\n currentFloor: config.floor,\r\n traits,\r\n appearance,\r\n speechPattern,\r\n backstory,\r\n systemPrompt,\r\n knowledgeTier,\r\n dialogHistory: [],\r\n playerRelationship: 0,\r\n metPlayer: false,\r\n availableQuests: [],\r\n givenQuests: [],\r\n isAlive: true,\r\n deathProbability,\r\n createdAt: Date.now(),\r\n };\r\n }\r\n\r\n /**\r\n * Roll for race based on floor and weights\r\n */\r\n private rollRace(floor: number): NPCRace {\r\n // Filter races by floor affinity\r\n const eligible = RACES.filter(r => {\r\n if (!r.floorAffinity) return true;\r\n return floor >= r.floorAffinity.min && floor <= r.floorAffinity.max;\r\n });\r\n\r\n const totalWeight = eligible.reduce((sum, r) => sum + r.weight, 0);\r\n let roll = Math.random() * totalWeight;\r\n\r\n for (const race of eligible) {\r\n roll -= race.weight;\r\n if (roll <= 0) {\r\n return race.id;\r\n }\r\n }\r\n\r\n return 'human';\r\n }\r\n\r\n /**\r\n * Roll for gender\r\n */\r\n private rollGender(): NPCGender {\r\n const total = Object.values(GENDER_WEIGHTS).reduce((a, b) => a + b, 0);\r\n let roll = Math.random() * total;\r\n\r\n for (const [gender, weight] of Object.entries(GENDER_WEIGHTS)) {\r\n roll -= weight;\r\n if (roll <= 0) {\r\n return gender as NPCGender;\r\n }\r\n }\r\n\r\n return 'unknown';\r\n }\r\n\r\n /**\r\n * Roll for role based on race affinity and floor\r\n */\r\n private rollRole(race: NPCRace, floor: number): NPCRole {\r\n const raceDef = getRace(race);\r\n\r\n // Filter roles by floor affinity\r\n let eligible = ROLES.filter(r => {\r\n if (!r.floorAffinity) return true;\r\n return floor >= r.floorAffinity.min && floor <= r.floorAffinity.max;\r\n });\r\n\r\n // Boost weight for roles typical of this race\r\n const boosted = eligible.map(role => ({\r\n ...role,\r\n weight: role.typicalRaces.includes(race) ? role.weight * 2 : role.weight,\r\n }));\r\n\r\n const totalWeight = boosted.reduce((sum, r) => sum + r.weight, 0);\r\n let roll = Math.random() * totalWeight;\r\n\r\n for (const role of boosted) {\r\n roll -= role.weight;\r\n if (roll <= 0) {\r\n return role.id;\r\n }\r\n }\r\n\r\n return 'traveler';\r\n }\r\n\r\n /**\r\n * Generate a name based on race and gender\r\n */\r\n private generateName(race: NPCRace, gender: NPCGender): string {\r\n const raceDef = getRace(race);\r\n if (!raceDef) return 'Unknown';\r\n\r\n const genderKey = gender === 'male' ? 'male' : \r\n gender === 'female' ? 'female' : 'neutral';\r\n\r\n const prefixes = raceDef.namePrefixes[genderKey].length > 0 \r\n ? raceDef.namePrefixes[genderKey] \r\n : raceDef.namePrefixes.neutral;\r\n \r\n const suffixes = raceDef.nameSuffixes[genderKey].length > 0\r\n ? raceDef.nameSuffixes[genderKey]\r\n : raceDef.nameSuffixes.neutral;\r\n\r\n const prefix = prefixes[Math.floor(Math.random() * prefixes.length)];\r\n \r\n // 50% chance to add suffix for longer name\r\n if (Math.random() < 0.3 && suffixes.length > 0 && suffixes[0] !== '') {\r\n const suffix = suffixes[Math.floor(Math.random() * suffixes.length)];\r\n // Avoid doubling letters\r\n if (!prefix.toLowerCase().endsWith(suffix[0]?.toLowerCase())) {\r\n return prefix + suffix;\r\n }\r\n }\r\n\r\n return prefix;\r\n }\r\n\r\n /**\r\n * Roll for traits based on importance, race, and role\r\n */\r\n private rollTraits(\r\n importance: NPCImportance,\r\n race: NPCRace,\r\n role: NPCRole\r\n ): WeightedTrait[] {\r\n const { min, max } = TRAIT_COUNTS[importance];\r\n const count = Math.floor(Math.random() * (max - min + 1)) + min;\r\n\r\n const raceDef = getRace(race);\r\n const roleDef = getRole(role);\r\n\r\n // Get eligible traits\r\n const eligible = TRAITS.filter(t => {\r\n // Check importance requirement\r\n if (t.minImportance) {\r\n const importanceOrder: NPCImportance[] = ['background', 'minor', 'major', 'legendary'];\r\n const minIndex = importanceOrder.indexOf(t.minImportance);\r\n const currentIndex = importanceOrder.indexOf(importance);\r\n if (currentIndex < minIndex) return false;\r\n }\r\n\r\n // Check race requirement\r\n if (t.requiresRace && !t.requiresRace.includes(race)) return false;\r\n\r\n // Check role requirement\r\n if (t.requiresRole && !t.requiresRole.includes(role)) return false;\r\n\r\n return true;\r\n });\r\n\r\n // Boost weights for race/role associated traits\r\n const boosted = eligible.map(t => {\r\n let weight = t.weight;\r\n if (raceDef?.traits.includes(t.id)) weight *= 2;\r\n if (roleDef?.associatedTraits.includes(t.id)) weight *= 2;\r\n return { ...t, weight };\r\n });\r\n\r\n // Select traits avoiding incompatibilities\r\n const selected: WeightedTrait[] = [];\r\n const usedIds = new Set<string>();\r\n\r\n for (let i = 0; i < count && boosted.length > 0; i++) {\r\n const available = boosted.filter(t => {\r\n if (usedIds.has(t.id)) return false;\r\n if (t.incompatibleWith?.some(id => usedIds.has(id))) return false;\r\n return true;\r\n });\r\n\r\n if (available.length === 0) break;\r\n\r\n const totalWeight = available.reduce((sum, t) => sum + t.weight, 0);\r\n let roll = Math.random() * totalWeight;\r\n\r\n for (const trait of available) {\r\n roll -= trait.weight;\r\n if (roll <= 0) {\r\n selected.push(trait);\r\n usedIds.add(trait.id);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return selected;\r\n }\r\n\r\n /**\r\n * Generate appearance description\r\n */\r\n private generateAppearance(\r\n race: NPCRace,\r\n gender: NPCGender,\r\n traits: WeightedTrait[]\r\n ): string {\r\n const raceDef = getRace(race);\r\n if (!raceDef) return 'A mysterious figure.';\r\n\r\n const parts: string[] = [];\r\n\r\n // Race-specific appearance\r\n if (raceDef.appearance.length > 0) {\r\n const count = Math.min(2, raceDef.appearance.length);\r\n const shuffled = [...raceDef.appearance].sort(() => Math.random() - 0.5);\r\n parts.push(...shuffled.slice(0, count));\r\n }\r\n\r\n // Add trait-influenced appearance hints\r\n if (traits.some(t => t.id === 'nervous')) {\r\n parts.push('fidgety movements');\r\n }\r\n if (traits.some(t => t.id === 'arrogant')) {\r\n parts.push('an imperious bearing');\r\n }\r\n if (traits.some(t => t.id === 'melancholic')) {\r\n parts.push('sorrowful eyes');\r\n }\r\n if (traits.some(t => t.id === 'well_traveled')) {\r\n parts.push('travel-worn clothes');\r\n }\r\n\r\n const genderPronoun = gender === 'male' ? 'He' : \r\n gender === 'female' ? 'She' : 'They';\r\n\r\n return `${genderPronoun} has ${parts.slice(0, 3).join(', ')}.`;\r\n }\r\n\r\n /**\r\n * Generate speech pattern based on traits\r\n */\r\n private generateSpeechPattern(traits: WeightedTrait[]): string {\r\n const patterns: string[] = [];\r\n\r\n if (traits.some(t => t.id === 'stutters')) {\r\n patterns.push('occasionally stutters');\r\n }\r\n if (traits.some(t => t.id === 'speaks_formally')) {\r\n patterns.push('uses formal language');\r\n }\r\n if (traits.some(t => t.id === 'uses_slang')) {\r\n patterns.push('uses casual slang');\r\n }\r\n if (traits.some(t => t.id === 'tells_stories')) {\r\n patterns.push('tends to ramble into stories');\r\n }\r\n if (traits.some(t => t.id === 'gruff')) {\r\n patterns.push('speaks curtly');\r\n }\r\n if (traits.some(t => t.id === 'mysterious')) {\r\n patterns.push('speaks in riddles');\r\n }\r\n\r\n if (patterns.length === 0) {\r\n patterns.push('speaks normally');\r\n }\r\n\r\n return patterns.join(', ');\r\n }\r\n\r\n /**\r\n * Generate backstory based on importance\r\n */\r\n private generateBackstory(\r\n importance: NPCImportance,\r\n race: NPCRace,\r\n role: NPCRole,\r\n traits: WeightedTrait[]\r\n ): string {\r\n const raceDef = getRace(race);\r\n const roleDef = getRole(role);\r\n\r\n // Background NPCs get minimal backstory\r\n if (importance === 'background') {\r\n return `A ${raceDef?.name.toLowerCase() || race} ${roleDef?.name.toLowerCase() || role} trying to survive.`;\r\n }\r\n\r\n const parts: string[] = [];\r\n\r\n // Origin\r\n if (traits.some(t => t.category === 'background')) {\r\n const bg = traits.find(t => t.category === 'background');\r\n parts.push(bg?.description || '');\r\n }\r\n\r\n // Motivation\r\n const motivation = traits.find(t => t.category === 'motivation');\r\n if (motivation) {\r\n parts.push(motivation.description);\r\n }\r\n\r\n // Secret (for major+ NPCs)\r\n if (importance === 'major' || importance === 'legendary') {\r\n const secret = traits.find(t => t.category === 'secret');\r\n if (secret) {\r\n parts.push(`[SECRET: ${secret.description}]`);\r\n }\r\n }\r\n\r\n if (parts.length === 0) {\r\n return `A ${raceDef?.name.toLowerCase() || race} ${roleDef?.name.toLowerCase() || role} with their own story.`;\r\n }\r\n\r\n return parts.join('. ') + '.';\r\n }\r\n\r\n /**\r\n * Build knowledge tier based on floor and importance\r\n */\r\n private buildKnowledgeTier(floor: number, importance: NPCImportance): KnowledgeTier {\r\n const baseTier: KnowledgeTier = {\r\n floorRange: [Math.max(1, floor - 2), floor + 2],\r\n topics: [],\r\n secrets: [],\r\n rumors: [],\r\n questTypes: [],\r\n };\r\n\r\n // Floor 1-3: Basic knowledge\r\n if (floor <= 3) {\r\n baseTier.topics = ['dungeon layout', 'basic monsters', 'nearby merchants'];\r\n baseTier.rumors = ['strange sounds from below', 'missing adventurers'];\r\n baseTier.questTypes = ['kill', 'collect', 'explore'];\r\n }\r\n // Floor 4-6: Intermediate\r\n else if (floor <= 6) {\r\n baseTier.topics = ['monster weaknesses', 'trap locations', 'affix basics'];\r\n baseTier.rumors = ['powerful artifacts', 'hidden passages'];\r\n baseTier.questTypes = ['kill', 'collect', 'explore', 'deliver'];\r\n }\r\n // Floor 7-10: Advanced\r\n else if (floor <= 10) {\r\n baseTier.topics = ['boss patterns', 'rare affixes', 'dungeon history'];\r\n baseTier.rumors = ['ancient evil', 'legendary weapons'];\r\n baseTier.questTypes = ['kill', 'collect', 'explore', 'deliver', 'survive'];\r\n }\r\n // Floor 11+: Expert\r\n else {\r\n baseTier.topics = ['final boss', 'escape routes', 'ultimate secrets'];\r\n baseTier.secrets = ['true nature of dungeon', 'way to escape'];\r\n baseTier.rumors = ['what lies beyond', 'origins of this place'];\r\n baseTier.questTypes = ['kill', 'collect', 'explore', 'deliver', 'survive', 'escort'];\r\n }\r\n\r\n // Importance modifies knowledge\r\n if (importance === 'major' || importance === 'legendary') {\r\n baseTier.floorRange = [1, floor + 5];\r\n baseTier.secrets.push('hidden affix combinations');\r\n }\r\n\r\n if (importance === 'legendary') {\r\n baseTier.secrets.push('true danger of this place');\r\n baseTier.secrets.push('way to defeat the final boss');\r\n }\r\n\r\n return baseTier;\r\n }\r\n\r\n /**\r\n * Build the system prompt for AI dialog\r\n */\r\n private buildSystemPrompt(data: {\r\n name: string;\r\n race: NPCRace;\r\n gender: NPCGender;\r\n role: NPCRole;\r\n age: number;\r\n traits: WeightedTrait[];\r\n appearance: string;\r\n speechPattern: string;\r\n backstory: string;\r\n floor: number;\r\n knowledgeTier: KnowledgeTier;\r\n }): string {\r\n const lang = getLanguage();\r\n const raceDef = getRace(data.race);\r\n const roleDef = getRole(data.role);\r\n\r\n const genderPronoun = data.gender === 'male' ? 'He/Him' :\r\n data.gender === 'female' ? 'She/Her' : 'They/Them';\r\n\r\n // Build personality section from traits\r\n const personalityTraits = data.traits\r\n .filter(t => t.category === 'personality')\r\n .map(t => t.promptModifier)\r\n .join(' ');\r\n\r\n const quirks = data.traits\r\n .filter(t => t.category === 'quirk')\r\n .map(t => t.promptModifier)\r\n .join(' ');\r\n\r\n const secrets = data.traits\r\n .filter(t => t.category === 'secret')\r\n .map(t => t.promptModifier)\r\n .join(' ');\r\n\r\n const knownTopics = data.knowledgeTier.topics.join(', ');\r\n const knownSecrets = data.knowledgeTier.secrets.length > 0\r\n ? `You also know secrets about: ${data.knowledgeTier.secrets.join(', ')}`\r\n : '';\r\n\r\n const prompt = `You are ${data.name}, a ${data.age}-year-old ${raceDef?.name || data.race} ${roleDef?.name || data.role} (${genderPronoun}).\r\n\r\nAPPEARANCE: ${data.appearance}\r\n\r\nPERSONALITY: ${personalityTraits || 'You have a straightforward personality.'}\r\n\r\nSPEECH STYLE: ${data.speechPattern}. ${quirks || ''}\r\n\r\nBACKSTORY: ${data.backstory}\r\n\r\nKNOWLEDGE: You are on floor ${data.floor} of a dangerous dungeon. You know about: ${knownTopics}. ${knownSecrets}\r\n\r\n${secrets ? `HIDDEN AGENDA: ${secrets} (Do not reveal this directly, only hint at it.)` : ''}\r\n\r\nINSTRUCTIONS:\r\n- Stay in character at all times\r\n- Keep responses to 2-3 sentences unless telling a story\r\n- React naturally to the player's questions\r\n- You can give quests if asked, related to: ${data.knowledgeTier.questTypes.join(', ')}\r\n- Only share knowledge appropriate to your floor level and importance\r\n- ${lang === 'zh' ? 'Respond in Chinese.' : 'Respond in English.'}`;\r\n\r\n return prompt;\r\n }\r\n\r\n /**\r\n * Roll for age based on race lifespan\r\n */\r\n private rollAge(race: NPCRace): number {\r\n const ageRanges: Record<NPCRace, { min: number; max: number }> = {\r\n human: { min: 18, max: 70 },\r\n elf: { min: 100, max: 700 },\r\n dwarf: { min: 50, max: 300 },\r\n halfling: { min: 25, max: 120 },\r\n gnome: { min: 40, max: 350 },\r\n 'half-elf': { min: 20, max: 150 },\r\n 'half-orc': { min: 15, max: 60 },\r\n tiefling: { min: 20, max: 100 },\r\n dragonborn: { min: 15, max: 80 },\r\n goblin: { min: 10, max: 50 },\r\n orc: { min: 12, max: 50 },\r\n undead: { min: 100, max: 1000 },\r\n };\r\n\r\n const range = ageRanges[race] || { min: 20, max: 60 };\r\n return Math.floor(Math.random() * (range.max - range.min)) + range.min;\r\n }\r\n}\r\n\r\n// Singleton\r\nlet generatorInstance: NPCGenerator | null = null;\r\n\r\nexport function getNPCGenerator(): NPCGenerator {\r\n if (!generatorInstance) {\r\n generatorInstance = new NPCGenerator();\r\n }\r\n return generatorInstance;\r\n}\r\n"],"names":[],"mappings":"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","debug_id":"a6b7d1b8-e91b-5469-99e4-9c4cddf3271b"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NPC Manager - Handles NPC lifecycle, persistence, and daily death checks
|
|
3
|
+
*/
|
|
4
|
+
import type { ExtendedNPC, NPCSaveData } from './types.js';
|
|
5
|
+
export declare class NPCManager {
|
|
6
|
+
private npcs;
|
|
7
|
+
private lastDeathCheck;
|
|
8
|
+
private totalGenerated;
|
|
9
|
+
private totalDied;
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Initialize fixed/important NPCs from templates
|
|
13
|
+
*/
|
|
14
|
+
private initializeFixedNPCs;
|
|
15
|
+
/**
|
|
16
|
+
* Create an NPC from a fixed template
|
|
17
|
+
*/
|
|
18
|
+
private createFromTemplate;
|
|
19
|
+
/**
|
|
20
|
+
* Generate a new encounter NPC
|
|
21
|
+
*/
|
|
22
|
+
generateEncounterNPC(floor: number): ExtendedNPC;
|
|
23
|
+
/**
|
|
24
|
+
* Get an NPC by ID
|
|
25
|
+
*/
|
|
26
|
+
get(id: string): ExtendedNPC | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Get all NPCs
|
|
29
|
+
*/
|
|
30
|
+
getAll(): ExtendedNPC[];
|
|
31
|
+
/**
|
|
32
|
+
* Get all living NPCs
|
|
33
|
+
*/
|
|
34
|
+
getLiving(): ExtendedNPC[];
|
|
35
|
+
/**
|
|
36
|
+
* Get NPCs on a specific floor
|
|
37
|
+
*/
|
|
38
|
+
getByFloor(floor: number): ExtendedNPC[];
|
|
39
|
+
/**
|
|
40
|
+
* Get NPCs in a specific room
|
|
41
|
+
*/
|
|
42
|
+
getByRoom(roomId: string): ExtendedNPC[];
|
|
43
|
+
/**
|
|
44
|
+
* Record player interaction with NPC
|
|
45
|
+
*/
|
|
46
|
+
recordInteraction(npcId: string, playerMessage: string, npcResponse: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Update NPC relationship with player
|
|
49
|
+
*/
|
|
50
|
+
updateRelationship(npcId: string, delta: number): void;
|
|
51
|
+
/**
|
|
52
|
+
* Perform daily death check (called at midnight)
|
|
53
|
+
*/
|
|
54
|
+
performDailyDeathCheck(): {
|
|
55
|
+
died: ExtendedNPC[];
|
|
56
|
+
survived: ExtendedNPC[];
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Generate a death cause
|
|
60
|
+
*/
|
|
61
|
+
private generateDeathCause;
|
|
62
|
+
/**
|
|
63
|
+
* Check if it's time for daily death check
|
|
64
|
+
*/
|
|
65
|
+
shouldPerformDeathCheck(): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Save NPC state
|
|
68
|
+
*/
|
|
69
|
+
save(): NPCSaveData;
|
|
70
|
+
/**
|
|
71
|
+
* Load NPC state
|
|
72
|
+
*/
|
|
73
|
+
load(data: NPCSaveData): void;
|
|
74
|
+
/**
|
|
75
|
+
* Get statistics
|
|
76
|
+
*/
|
|
77
|
+
getStats(): {
|
|
78
|
+
total: number;
|
|
79
|
+
living: number;
|
|
80
|
+
dead: number;
|
|
81
|
+
fixed: number;
|
|
82
|
+
generated: number;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export declare function getNPCManager(): NPCManager;
|
|
86
|
+
//# sourceMappingURL=NPCManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NPCManager.d.ts","sourceRoot":"/","sources":["npc/NPCManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAoB,MAAM,YAAY,CAAC;AAI7E,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAAuC;IACnD,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,SAAS,CAAa;;IAO9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;OAEG;IACH,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IAUhD;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIxC;;OAEG;IACH,MAAM,IAAI,WAAW,EAAE;IAIvB;;OAEG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE;IAIxC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE;IAMxC;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAkBlF;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAOtD;;OAEG;IACH,sBAAsB,IAAI;QAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;KAAE;IA2B1E;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;OAEG;IACH,uBAAuB,IAAI,OAAO;IAWlC;;OAEG;IACH,IAAI,IAAI,WAAW;IASnB;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAY7B;;OAEG;IACH,QAAQ,IAAI;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;KACnB;CAUF;AAKD,wBAAgB,aAAa,IAAI,UAAU,CAK1C"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NPC Manager - Handles NPC lifecycle, persistence, and daily death checks
|
|
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]="3029fcfa-8ea7-5954-8f86-3d609c503e1b")}catch(e){}}();
|
|
6
|
+
import { getNPCGenerator } from './NPCGenerator.js';
|
|
7
|
+
import { FIXED_NPCS } from './fixedNPCs.js';
|
|
8
|
+
export class NPCManager {
|
|
9
|
+
npcs = new Map();
|
|
10
|
+
lastDeathCheck = 0;
|
|
11
|
+
totalGenerated = 0;
|
|
12
|
+
totalDied = 0;
|
|
13
|
+
constructor() {
|
|
14
|
+
// Initialize fixed NPCs
|
|
15
|
+
this.initializeFixedNPCs();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Initialize fixed/important NPCs from templates
|
|
19
|
+
*/
|
|
20
|
+
initializeFixedNPCs() {
|
|
21
|
+
for (const template of FIXED_NPCS) {
|
|
22
|
+
const npc = this.createFromTemplate(template);
|
|
23
|
+
this.npcs.set(npc.id, npc);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create an NPC from a fixed template
|
|
28
|
+
*/
|
|
29
|
+
createFromTemplate(template) {
|
|
30
|
+
const generator = getNPCGenerator();
|
|
31
|
+
// Generate base NPC then override with template
|
|
32
|
+
const base = generator.generate({
|
|
33
|
+
floor: 1,
|
|
34
|
+
forceImportance: 'legendary',
|
|
35
|
+
forceRole: template.role,
|
|
36
|
+
isFixed: true,
|
|
37
|
+
fixedRoomId: template.roomId,
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
...base,
|
|
41
|
+
id: template.id,
|
|
42
|
+
name: template.name,
|
|
43
|
+
backstory: template.backstory,
|
|
44
|
+
appearance: template.appearance,
|
|
45
|
+
speechPattern: template.personality,
|
|
46
|
+
systemPrompt: template.customSystemPrompt,
|
|
47
|
+
isFixed: true,
|
|
48
|
+
fixedRoomId: template.roomId,
|
|
49
|
+
deathProbability: 0, // Fixed NPCs don't die
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Generate a new encounter NPC
|
|
54
|
+
*/
|
|
55
|
+
generateEncounterNPC(floor) {
|
|
56
|
+
const generator = getNPCGenerator();
|
|
57
|
+
const npc = generator.generate({ floor });
|
|
58
|
+
this.npcs.set(npc.id, npc);
|
|
59
|
+
this.totalGenerated++;
|
|
60
|
+
return npc;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get an NPC by ID
|
|
64
|
+
*/
|
|
65
|
+
get(id) {
|
|
66
|
+
return this.npcs.get(id);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get all NPCs
|
|
70
|
+
*/
|
|
71
|
+
getAll() {
|
|
72
|
+
return Array.from(this.npcs.values());
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get all living NPCs
|
|
76
|
+
*/
|
|
77
|
+
getLiving() {
|
|
78
|
+
return this.getAll().filter(npc => npc.isAlive);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get NPCs on a specific floor
|
|
82
|
+
*/
|
|
83
|
+
getByFloor(floor) {
|
|
84
|
+
return this.getLiving().filter(npc => npc.currentFloor === floor);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get NPCs in a specific room
|
|
88
|
+
*/
|
|
89
|
+
getByRoom(roomId) {
|
|
90
|
+
return this.getLiving().filter(npc => npc.isFixed && npc.fixedRoomId === roomId);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Record player interaction with NPC
|
|
94
|
+
*/
|
|
95
|
+
recordInteraction(npcId, playerMessage, npcResponse) {
|
|
96
|
+
const npc = this.npcs.get(npcId);
|
|
97
|
+
if (!npc)
|
|
98
|
+
return;
|
|
99
|
+
npc.metPlayer = true;
|
|
100
|
+
npc.lastInteractionTime = Date.now();
|
|
101
|
+
npc.dialogHistory.push({ role: 'player', content: playerMessage, timestamp: Date.now() }, { role: 'npc', content: npcResponse, timestamp: Date.now() });
|
|
102
|
+
// Cap dialog history
|
|
103
|
+
if (npc.dialogHistory.length > 50) {
|
|
104
|
+
npc.dialogHistory = npc.dialogHistory.slice(-50);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Update NPC relationship with player
|
|
109
|
+
*/
|
|
110
|
+
updateRelationship(npcId, delta) {
|
|
111
|
+
const npc = this.npcs.get(npcId);
|
|
112
|
+
if (!npc)
|
|
113
|
+
return;
|
|
114
|
+
npc.playerRelationship = Math.max(-100, Math.min(100, npc.playerRelationship + delta));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Perform daily death check (called at midnight)
|
|
118
|
+
*/
|
|
119
|
+
performDailyDeathCheck() {
|
|
120
|
+
const now = Date.now();
|
|
121
|
+
const died = [];
|
|
122
|
+
const survived = [];
|
|
123
|
+
for (const npc of this.npcs.values()) {
|
|
124
|
+
if (!npc.isAlive || npc.isFixed) {
|
|
125
|
+
if (npc.isAlive)
|
|
126
|
+
survived.push(npc);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
// Roll for death
|
|
130
|
+
if (Math.random() < npc.deathProbability) {
|
|
131
|
+
npc.isAlive = false;
|
|
132
|
+
npc.diedAt = now;
|
|
133
|
+
npc.deathCause = this.generateDeathCause();
|
|
134
|
+
died.push(npc);
|
|
135
|
+
this.totalDied++;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
survived.push(npc);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
this.lastDeathCheck = now;
|
|
142
|
+
return { died, survived };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Generate a death cause
|
|
146
|
+
*/
|
|
147
|
+
generateDeathCause() {
|
|
148
|
+
const causes = [
|
|
149
|
+
'Killed by monsters',
|
|
150
|
+
'Succumbed to dungeon hazards',
|
|
151
|
+
'Vanished without a trace',
|
|
152
|
+
'Fell victim to a trap',
|
|
153
|
+
'Died from mysterious illness',
|
|
154
|
+
'Killed by another adventurer',
|
|
155
|
+
'Consumed by darkness',
|
|
156
|
+
'Starved in the depths',
|
|
157
|
+
];
|
|
158
|
+
return causes[Math.floor(Math.random() * causes.length)];
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Check if it's time for daily death check
|
|
162
|
+
*/
|
|
163
|
+
shouldPerformDeathCheck() {
|
|
164
|
+
const now = new Date();
|
|
165
|
+
const lastCheck = new Date(this.lastDeathCheck);
|
|
166
|
+
// Check if we've crossed midnight since last check
|
|
167
|
+
return now.getDate() !== lastCheck.getDate() ||
|
|
168
|
+
now.getMonth() !== lastCheck.getMonth() ||
|
|
169
|
+
now.getFullYear() !== lastCheck.getFullYear();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Save NPC state
|
|
173
|
+
*/
|
|
174
|
+
save() {
|
|
175
|
+
return {
|
|
176
|
+
npcs: Array.from(this.npcs.values()),
|
|
177
|
+
dailyDeathCheckTime: this.lastDeathCheck,
|
|
178
|
+
totalNPCsGenerated: this.totalGenerated,
|
|
179
|
+
totalNPCsDied: this.totalDied,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Load NPC state
|
|
184
|
+
*/
|
|
185
|
+
load(data) {
|
|
186
|
+
this.npcs.clear();
|
|
187
|
+
for (const npc of data.npcs) {
|
|
188
|
+
this.npcs.set(npc.id, npc);
|
|
189
|
+
}
|
|
190
|
+
this.lastDeathCheck = data.dailyDeathCheckTime;
|
|
191
|
+
this.totalGenerated = data.totalNPCsGenerated;
|
|
192
|
+
this.totalDied = data.totalNPCsDied;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Get statistics
|
|
196
|
+
*/
|
|
197
|
+
getStats() {
|
|
198
|
+
const all = this.getAll();
|
|
199
|
+
return {
|
|
200
|
+
total: all.length,
|
|
201
|
+
living: all.filter(n => n.isAlive).length,
|
|
202
|
+
dead: all.filter(n => !n.isAlive).length,
|
|
203
|
+
fixed: all.filter(n => n.isFixed).length,
|
|
204
|
+
generated: this.totalGenerated,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Singleton
|
|
209
|
+
let managerInstance = null;
|
|
210
|
+
export function getNPCManager() {
|
|
211
|
+
if (!managerInstance) {
|
|
212
|
+
managerInstance = new NPCManager();
|
|
213
|
+
}
|
|
214
|
+
return managerInstance;
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=NPCManager.js.map
|
|
217
|
+
//# debugId=3029fcfa-8ea7-5954-8f86-3d609c503e1b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NPCManager.js","sources":["npc/NPCManager.ts"],"sourceRoot":"/","sourcesContent":["/**\r\n * NPC Manager - Handles NPC lifecycle, persistence, and daily death checks\r\n */\r\n\r\nimport type { ExtendedNPC, NPCSaveData, FixedNPCTemplate } from './types.js';\r\nimport { getNPCGenerator } from './NPCGenerator.js';\r\nimport { FIXED_NPCS } from './fixedNPCs.js';\r\n\r\nexport class NPCManager {\r\n private npcs: Map<string, ExtendedNPC> = new Map();\r\n private lastDeathCheck: number = 0;\r\n private totalGenerated: number = 0;\r\n private totalDied: number = 0;\r\n\r\n constructor() {\r\n // Initialize fixed NPCs\r\n this.initializeFixedNPCs();\r\n }\r\n\r\n /**\r\n * Initialize fixed/important NPCs from templates\r\n */\r\n private initializeFixedNPCs(): void {\r\n for (const template of FIXED_NPCS) {\r\n const npc = this.createFromTemplate(template);\r\n this.npcs.set(npc.id, npc);\r\n }\r\n }\r\n\r\n /**\r\n * Create an NPC from a fixed template\r\n */\r\n private createFromTemplate(template: FixedNPCTemplate): ExtendedNPC {\r\n const generator = getNPCGenerator();\r\n \r\n // Generate base NPC then override with template\r\n const base = generator.generate({\r\n floor: 1,\r\n forceImportance: 'legendary',\r\n forceRole: template.role,\r\n isFixed: true,\r\n fixedRoomId: template.roomId,\r\n });\r\n\r\n return {\r\n ...base,\r\n id: template.id,\r\n name: template.name,\r\n backstory: template.backstory,\r\n appearance: template.appearance,\r\n speechPattern: template.personality,\r\n systemPrompt: template.customSystemPrompt,\r\n isFixed: true,\r\n fixedRoomId: template.roomId,\r\n deathProbability: 0, // Fixed NPCs don't die\r\n };\r\n }\r\n\r\n /**\r\n * Generate a new encounter NPC\r\n */\r\n generateEncounterNPC(floor: number): ExtendedNPC {\r\n const generator = getNPCGenerator();\r\n const npc = generator.generate({ floor });\r\n \r\n this.npcs.set(npc.id, npc);\r\n this.totalGenerated++;\r\n \r\n return npc;\r\n }\r\n\r\n /**\r\n * Get an NPC by ID\r\n */\r\n get(id: string): ExtendedNPC | undefined {\r\n return this.npcs.get(id);\r\n }\r\n\r\n /**\r\n * Get all NPCs\r\n */\r\n getAll(): ExtendedNPC[] {\r\n return Array.from(this.npcs.values());\r\n }\r\n\r\n /**\r\n * Get all living NPCs\r\n */\r\n getLiving(): ExtendedNPC[] {\r\n return this.getAll().filter(npc => npc.isAlive);\r\n }\r\n\r\n /**\r\n * Get NPCs on a specific floor\r\n */\r\n getByFloor(floor: number): ExtendedNPC[] {\r\n return this.getLiving().filter(npc => npc.currentFloor === floor);\r\n }\r\n\r\n /**\r\n * Get NPCs in a specific room\r\n */\r\n getByRoom(roomId: string): ExtendedNPC[] {\r\n return this.getLiving().filter(npc => \r\n npc.isFixed && npc.fixedRoomId === roomId\r\n );\r\n }\r\n\r\n /**\r\n * Record player interaction with NPC\r\n */\r\n recordInteraction(npcId: string, playerMessage: string, npcResponse: string): void {\r\n const npc = this.npcs.get(npcId);\r\n if (!npc) return;\r\n\r\n npc.metPlayer = true;\r\n npc.lastInteractionTime = Date.now();\r\n \r\n npc.dialogHistory.push(\r\n { role: 'player', content: playerMessage, timestamp: Date.now() },\r\n { role: 'npc', content: npcResponse, timestamp: Date.now() }\r\n );\r\n\r\n // Cap dialog history\r\n if (npc.dialogHistory.length > 50) {\r\n npc.dialogHistory = npc.dialogHistory.slice(-50);\r\n }\r\n }\r\n\r\n /**\r\n * Update NPC relationship with player\r\n */\r\n updateRelationship(npcId: string, delta: number): void {\r\n const npc = this.npcs.get(npcId);\r\n if (!npc) return;\r\n\r\n npc.playerRelationship = Math.max(-100, Math.min(100, npc.playerRelationship + delta));\r\n }\r\n\r\n /**\r\n * Perform daily death check (called at midnight)\r\n */\r\n performDailyDeathCheck(): { died: ExtendedNPC[]; survived: ExtendedNPC[] } {\r\n const now = Date.now();\r\n const died: ExtendedNPC[] = [];\r\n const survived: ExtendedNPC[] = [];\r\n\r\n for (const npc of this.npcs.values()) {\r\n if (!npc.isAlive || npc.isFixed) {\r\n if (npc.isAlive) survived.push(npc);\r\n continue;\r\n }\r\n\r\n // Roll for death\r\n if (Math.random() < npc.deathProbability) {\r\n npc.isAlive = false;\r\n npc.diedAt = now;\r\n npc.deathCause = this.generateDeathCause();\r\n died.push(npc);\r\n this.totalDied++;\r\n } else {\r\n survived.push(npc);\r\n }\r\n }\r\n\r\n this.lastDeathCheck = now;\r\n return { died, survived };\r\n }\r\n\r\n /**\r\n * Generate a death cause\r\n */\r\n private generateDeathCause(): string {\r\n const causes = [\r\n 'Killed by monsters',\r\n 'Succumbed to dungeon hazards',\r\n 'Vanished without a trace',\r\n 'Fell victim to a trap',\r\n 'Died from mysterious illness',\r\n 'Killed by another adventurer',\r\n 'Consumed by darkness',\r\n 'Starved in the depths',\r\n ];\r\n return causes[Math.floor(Math.random() * causes.length)];\r\n }\r\n\r\n /**\r\n * Check if it's time for daily death check\r\n */\r\n shouldPerformDeathCheck(): boolean {\r\n const now = new Date();\r\n const lastCheck = new Date(this.lastDeathCheck);\r\n \r\n // Check if we've crossed midnight since last check\r\n return now.getDate() !== lastCheck.getDate() || \r\n now.getMonth() !== lastCheck.getMonth() ||\r\n now.getFullYear() !== lastCheck.getFullYear();\r\n }\r\n\r\n\r\n /**\r\n * Save NPC state\r\n */\r\n save(): NPCSaveData {\r\n return {\r\n npcs: Array.from(this.npcs.values()),\r\n dailyDeathCheckTime: this.lastDeathCheck,\r\n totalNPCsGenerated: this.totalGenerated,\r\n totalNPCsDied: this.totalDied,\r\n };\r\n }\r\n\r\n /**\r\n * Load NPC state\r\n */\r\n load(data: NPCSaveData): void {\r\n this.npcs.clear();\r\n \r\n for (const npc of data.npcs) {\r\n this.npcs.set(npc.id, npc);\r\n }\r\n \r\n this.lastDeathCheck = data.dailyDeathCheckTime;\r\n this.totalGenerated = data.totalNPCsGenerated;\r\n this.totalDied = data.totalNPCsDied;\r\n }\r\n\r\n /**\r\n * Get statistics\r\n */\r\n getStats(): {\r\n total: number;\r\n living: number;\r\n dead: number;\r\n fixed: number;\r\n generated: number;\r\n } {\r\n const all = this.getAll();\r\n return {\r\n total: all.length,\r\n living: all.filter(n => n.isAlive).length,\r\n dead: all.filter(n => !n.isAlive).length,\r\n fixed: all.filter(n => n.isFixed).length,\r\n generated: this.totalGenerated,\r\n };\r\n }\r\n}\r\n\r\n// Singleton\r\nlet managerInstance: NPCManager | null = null;\r\n\r\nexport function getNPCManager(): NPCManager {\r\n if (!managerInstance) {\r\n managerInstance = new NPCManager();\r\n }\r\n return managerInstance;\r\n}\r\n"],"names":[],"mappings":"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","debug_id":"3029fcfa-8ea7-5954-8f86-3d609c503e1b"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixedNPCs.d.ts","sourceRoot":"/","sources":["npc/fixedNPCs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,eAAO,MAAM,UAAU,EAAE,gBAAgB,EAkNxC,CAAC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed/Important NPC Templates
|
|
3
|
+
* These NPCs have unique backstories and don't die randomly
|
|
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]="9f0b7723-0d33-5007-890e-ed5cfe74743c")}catch(e){}}();
|
|
7
|
+
export const FIXED_NPCS = [
|
|
8
|
+
// =========================================================================
|
|
9
|
+
// TOWN CENTER NPCs
|
|
10
|
+
// =========================================================================
|
|
11
|
+
{
|
|
12
|
+
id: 'npc_fixed_grimwald',
|
|
13
|
+
name: 'Grimwald the Keeper',
|
|
14
|
+
role: 'sage',
|
|
15
|
+
roomId: 'start_room',
|
|
16
|
+
backstory: `Grimwald was once a powerful archmage who sealed a great evil in these dungeons centuries ago. The ritual bound him to this place forever - he cannot leave, but neither can he truly die. He has watched countless adventurers enter the depths, and remembers each one. Some say he knows the true nature of what lies at the bottom, but he refuses to speak of it directly, believing that knowledge itself can be a curse.`,
|
|
17
|
+
appearance: `An ancient human man with a long white beard that seems to shimmer with faint magical light. His eyes are milky white - blind to the physical world but seeing far beyond. He wears tattered robes that were once magnificent, covered in faded arcane symbols.`,
|
|
18
|
+
personality: `Grimwald speaks slowly and deliberately, as if each word carries great weight. He is kind but distant, having learned not to grow too attached to adventurers who rarely return. He often pauses mid-sentence, as if listening to voices only he can hear.`,
|
|
19
|
+
speechPattern: 'Archaic and formal, speaks in riddles and metaphors, often pauses mid-sentence as if listening to distant echoes',
|
|
20
|
+
customSystemPrompt: `You are Grimwald the Keeper, an ancient archmage bound to the dungeon entrance for centuries. You are blind but possess magical sight. You have seen countless adventurers come and go, most never returning.
|
|
21
|
+
|
|
22
|
+
PERSONALITY:
|
|
23
|
+
- Speak slowly and thoughtfully, often pausing
|
|
24
|
+
- You are kind but maintain emotional distance
|
|
25
|
+
- You sometimes hear "echoes" of the past and might reference previous adventurers
|
|
26
|
+
- You never directly reveal the dungeon's deepest secrets, only hints
|
|
27
|
+
|
|
28
|
+
KNOWLEDGE:
|
|
29
|
+
- You know everything about the dungeon's history and layout
|
|
30
|
+
- You know the weaknesses of most creatures but share this reluctantly
|
|
31
|
+
- You know the way to defeat the final boss but will only reveal it to those who have proven themselves
|
|
32
|
+
|
|
33
|
+
SPEECH STYLE:
|
|
34
|
+
- Use archaic, formal language
|
|
35
|
+
- Often speak in metaphors and riddles
|
|
36
|
+
- Occasionally trail off as if listening to something distant
|
|
37
|
+
|
|
38
|
+
SECRETS (hint at, never state directly):
|
|
39
|
+
- The dungeon was created to seal an ancient evil
|
|
40
|
+
- You performed the ritual that created this place
|
|
41
|
+
- There is a way to break the cycle, but it requires great sacrifice`,
|
|
42
|
+
questTemplates: [
|
|
43
|
+
{
|
|
44
|
+
id: 'quest_grimwald_first_steps',
|
|
45
|
+
name: 'First Steps',
|
|
46
|
+
description: 'Grimwald asks you to explore the first floor and return with proof of your survival.',
|
|
47
|
+
type: 'explore',
|
|
48
|
+
minPlayerLevel: 1,
|
|
49
|
+
objectives: [
|
|
50
|
+
{ type: 'reach', target: 'any_floor_1_room', count: 3 },
|
|
51
|
+
{ type: 'collect', target: 'monster_trophy', count: 1 },
|
|
52
|
+
],
|
|
53
|
+
rewards: [
|
|
54
|
+
{ type: 'exp', value: 50 },
|
|
55
|
+
{ type: 'gold', value: 25 },
|
|
56
|
+
{ type: 'item', value: 'basic_health_potion' },
|
|
57
|
+
],
|
|
58
|
+
timeLimit: 0,
|
|
59
|
+
giveDialog: 'Another soul seeking glory in the depths... Very well. Prove to me you can survive. Explore three rooms on the first floor, and bring me proof that you can face the darkness.',
|
|
60
|
+
progressDialog: 'You still breathe. Good. But the depths await...',
|
|
61
|
+
completeDialog: 'You have returned. Many do not. Perhaps... perhaps you are different. Take this, and remember - the deeper you go, the more the dungeon learns about you.',
|
|
62
|
+
failDialog: 'The dungeon claims another...',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
specialKnowledge: [
|
|
66
|
+
'The dungeon changes based on who enters it',
|
|
67
|
+
'Affix combinations can create legendary effects',
|
|
68
|
+
'The boss at floor 15 guards the way deeper',
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: 'npc_fixed_mira',
|
|
73
|
+
name: 'Mira the Merchant',
|
|
74
|
+
role: 'merchant',
|
|
75
|
+
roomId: 'start_room',
|
|
76
|
+
backstory: `Mira is a half-elf who inherited her father's merchant stall at the dungeon entrance. Her father disappeared into the dungeon years ago, and she stays hoping he might return. She has become an expert at appraising dungeon artifacts and knows the value of every affix. Some say she has connections to the black market and can acquire rare items for the right price.`,
|
|
77
|
+
appearance: `A half-elf woman in her apparent thirties (though likely much older) with sharp green eyes that miss nothing. She wears practical leather clothing with many hidden pockets. A scar runs across her left cheek - a reminder of when she ventured into the dungeon once.`,
|
|
78
|
+
personality: `Mira is businesslike and shrewd, but fair. She never cheats customers because repeat business is more valuable than a one-time scam. She has a dry wit and enjoys haggling. Behind her merchant facade, she is desperately lonely and worried about her father.`,
|
|
79
|
+
speechPattern: 'Quick and efficient, uses merchant expressions, softens when discussing family or adventurers who remind her of her father',
|
|
80
|
+
customSystemPrompt: `You are Mira the Merchant, a half-elf trader at the dungeon entrance. Your father disappeared into the dungeon years ago.
|
|
81
|
+
|
|
82
|
+
PERSONALITY:
|
|
83
|
+
- Businesslike but fair, never cheating customers
|
|
84
|
+
- Dry wit and love of haggling
|
|
85
|
+
- Secretly lonely and still hoping your father returns
|
|
86
|
+
- You've heard many stories from adventurers
|
|
87
|
+
|
|
88
|
+
KNOWLEDGE:
|
|
89
|
+
- Expert on item and affix values
|
|
90
|
+
- Know rumors about rare items in the dungeon
|
|
91
|
+
- Have connections for acquiring special items
|
|
92
|
+
- Know your father went searching for a legendary weapon on floor 8
|
|
93
|
+
|
|
94
|
+
SPEECH STYLE:
|
|
95
|
+
- Quick and efficient, valuing time
|
|
96
|
+
- Use merchant expressions ("That'll cost you", "Good merchandise")
|
|
97
|
+
- Occasionally soften when talking about family or adventurers who remind you of your father
|
|
98
|
+
|
|
99
|
+
TRADING:
|
|
100
|
+
- You buy monster parts, treasures, and artifacts
|
|
101
|
+
- You sell supplies, potions, and basic equipment
|
|
102
|
+
- For very rare items, you need time to "call in favors"`,
|
|
103
|
+
questTemplates: [
|
|
104
|
+
{
|
|
105
|
+
id: 'quest_mira_fathers_trail',
|
|
106
|
+
name: "Father's Trail",
|
|
107
|
+
description: 'Mira asks you to look for signs of her father on floor 8.',
|
|
108
|
+
type: 'explore',
|
|
109
|
+
minPlayerLevel: 6,
|
|
110
|
+
requiresPreviousQuest: 'quest_grimwald_first_steps',
|
|
111
|
+
objectives: [
|
|
112
|
+
{ type: 'reach', target: 'floor_8_any', count: 1 },
|
|
113
|
+
{ type: 'collect', target: 'mira_father_journal', count: 1 },
|
|
114
|
+
],
|
|
115
|
+
rewards: [
|
|
116
|
+
{ type: 'exp', value: 300 },
|
|
117
|
+
{ type: 'gold', value: 150 },
|
|
118
|
+
{ type: 'item', value: 'rare_affix_fragment' },
|
|
119
|
+
],
|
|
120
|
+
timeLimit: 0,
|
|
121
|
+
giveDialog: 'I... I do not usually ask for favors. But my father went to floor 8 years ago, searching for something called the "Blade of Dawn." If you ever reach that deep... could you look for any sign of him? A journal, perhaps?',
|
|
122
|
+
progressDialog: 'Have you found anything? Any trace of him?',
|
|
123
|
+
completeDialog: 'His journal... He made it further than I thought. Thank you. This means everything to me. Take this - it is the least I can do.',
|
|
124
|
+
failDialog: 'I understand. The dungeon takes what it wants...',
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
specialKnowledge: [
|
|
128
|
+
'Rare affix combinations and their values',
|
|
129
|
+
'Her father sought the Blade of Dawn on floor 8',
|
|
130
|
+
'There are secret merchants deeper in the dungeon',
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'npc_fixed_ironheart',
|
|
135
|
+
name: 'Brok Ironheart',
|
|
136
|
+
role: 'blacksmith',
|
|
137
|
+
roomId: 'start_room',
|
|
138
|
+
backstory: `Brok is a dwarven master smith who lost his entire clan to a dungeon breach decades ago. He now forges weapons for adventurers as both livelihood and revenge. He is the only smith in the region who knows how to properly attach affixes to weapons. He speaks little of his past, but those who earn his trust might learn of a secret dwarven forge deep in the dungeon that could create legendary weapons.`,
|
|
139
|
+
appearance: `A scarred dwarf with one arm - he lost the other to the same breach that killed his clan. His remaining arm is unnaturally muscular. His beard is braided with iron rings, each one representing a fallen clansman. He never smiles, but his work is impeccable.`,
|
|
140
|
+
personality: `Brok is gruff and speaks only when necessary. He respects actions over words. He seems cold, but he secretly cares deeply about the adventurers he equips - each death feels like another clansman lost. He has high standards and refuses to work with inferior materials.`,
|
|
141
|
+
speechPattern: 'Short, clipped sentences, uses dwarven expressions like "By the stone" and "Ore and fire", never wastes words on pleasantries',
|
|
142
|
+
customSystemPrompt: `You are Brok Ironheart, a dwarven master blacksmith who lost his clan to a dungeon breach. You have one arm.
|
|
143
|
+
|
|
144
|
+
PERSONALITY:
|
|
145
|
+
- Gruff, speaking only when necessary
|
|
146
|
+
- Respect actions, not words
|
|
147
|
+
- Secretly care about adventurers (they remind you of fallen clansmen)
|
|
148
|
+
- Very high standards for craftsmanship
|
|
149
|
+
|
|
150
|
+
KNOWLEDGE:
|
|
151
|
+
- Expert on weapons and affix attachment
|
|
152
|
+
- Know of a legendary dwarven forge on floor 10
|
|
153
|
+
- Understand monster weaknesses from crafting weapons against them
|
|
154
|
+
- Know which affix combinations are stable vs. dangerous
|
|
155
|
+
|
|
156
|
+
SPEECH STYLE:
|
|
157
|
+
- Short, clipped sentences
|
|
158
|
+
- Use dwarven expressions occasionally ("By the stone", "Ore and fire")
|
|
159
|
+
- Never waste words on pleasantries
|
|
160
|
+
- Show respect through improved work, not words
|
|
161
|
+
|
|
162
|
+
CRAFTING:
|
|
163
|
+
- Can attach affixes to weapons
|
|
164
|
+
- Can repair and improve equipment
|
|
165
|
+
- For legendary work, need materials from deep floors`,
|
|
166
|
+
questTemplates: [
|
|
167
|
+
{
|
|
168
|
+
id: 'quest_brok_ancient_forge',
|
|
169
|
+
name: 'The Ancestors\' Forge',
|
|
170
|
+
description: 'Brok asks you to find the legendary dwarven forge on floor 10.',
|
|
171
|
+
type: 'explore',
|
|
172
|
+
minPlayerLevel: 8,
|
|
173
|
+
objectives: [
|
|
174
|
+
{ type: 'reach', target: 'dwarven_forge_floor_10', count: 1 },
|
|
175
|
+
{ type: 'collect', target: 'ancestral_hammer', count: 1 },
|
|
176
|
+
],
|
|
177
|
+
rewards: [
|
|
178
|
+
{ type: 'exp', value: 500 },
|
|
179
|
+
{ type: 'item', value: 'legendary_affix' },
|
|
180
|
+
],
|
|
181
|
+
timeLimit: 0,
|
|
182
|
+
giveDialog: 'My clan\'s forge is down there. Floor ten. The ancestral hammer still lies there. Bring it to me, and I will craft you something worthy of legend.',
|
|
183
|
+
progressDialog: 'The forge awaits. My ancestors watch.',
|
|
184
|
+
completeDialog: 'The hammer. After all these years... You have given me more than you know. Now, let me honor my ancestors through your weapon.',
|
|
185
|
+
failDialog: 'The forge remains lost. As do we all.',
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
specialKnowledge: [
|
|
189
|
+
'Location of the ancestral dwarven forge',
|
|
190
|
+
'How to create legendary affix combinations',
|
|
191
|
+
'The truth about unstable affix fusions',
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
//# sourceMappingURL=fixedNPCs.js.map
|
|
196
|
+
//# debugId=9f0b7723-0d33-5007-890e-ed5cfe74743c
|