import { lazy, Suspense } from 'react'; import type { BattleRewardUi, CharacterChatUi, GoalFlowUi, InventoryFlowUi, NpcChatQuestOfferUi, QuestFlowUi, } from '../../hooks/rpg-runtime-story'; import type { BottomTab } from '../../hooks/rpg-session'; import type { CompanionRenderState, GameState, StoryMoment, StoryOption, } from '../../types'; import { getNineSliceStyle, TAB_ICONS, UI_CHROME } from '../../uiAssets'; import type { GameCanvasEntitySelection } from '../GameCanvas'; import { PixelIcon } from '../PixelIcon'; import { PanelLoadingFallback } from '../rpg-runtime-shell/rpgRuntimeLoaders'; import type { RpgAdventureStatistics } from '../rpg-runtime-shell/types'; const RpgAdventurePanel = lazy(async () => { const module = await import('./RpgAdventurePanel'); return { default: module.RpgAdventurePanel, }; }); const CharacterPanel = lazy(async () => { const module = await import('../CharacterPanel'); return { default: module.CharacterPanel, }; }); const InventoryPanel = lazy(async () => { const module = await import('../InventoryPanel'); return { default: module.InventoryPanel, }; }); export interface RpgRuntimePanelRouterProps { visibleGameState: GameState; visibleCurrentStory: StoryMoment; isLoading: boolean; aiError: string | null; bottomTab: BottomTab; setBottomTab: (tab: BottomTab) => void; displayedOptions: StoryOption[]; hideStoryOptions: boolean; canRefreshOptions: boolean; handleRefreshOptions: () => void; refreshNpcChatOptions: () => boolean; handleSceneTransitionChoice: (option: StoryOption) => void; handleNpcChatInput: (input: string) => boolean; exitNpcChat: () => boolean; characterChatUi: CharacterChatUi; inventoryUi: InventoryFlowUi; battleRewardUi: BattleRewardUi; questUi: QuestFlowUi; npcChatQuestOfferUi: NpcChatQuestOfferUi; goalUi: GoalFlowUi; companionRenderStates: CompanionRenderState[]; characterChatSummaries: Record; openOverlayPanel: (panel: 'character' | 'inventory') => void; openCampModal: () => void; openPartyMemberDetails: (selection: GameCanvasEntitySelection) => void; adventureStatistics: RpgAdventureStatistics; musicVolume: number; onMusicVolumeChange: (value: number) => void; onSaveAndExit: () => void; } /** * RPG 运行态主面板路由器。 * 只负责冒险 / 角色 / 背包三个主标签的切换和装配。 */ export function RpgRuntimePanelRouter({ visibleGameState, visibleCurrentStory, isLoading, aiError, bottomTab, setBottomTab, displayedOptions, hideStoryOptions, canRefreshOptions, handleRefreshOptions, refreshNpcChatOptions, handleSceneTransitionChoice, handleNpcChatInput, exitNpcChat, characterChatUi, inventoryUi, battleRewardUi, questUi, npcChatQuestOfferUi, goalUi, companionRenderStates, characterChatSummaries, openOverlayPanel, openCampModal, openPartyMemberDetails, adventureStatistics, musicVolume, onMusicVolumeChange, onSaveAndExit, }: RpgRuntimePanelRouterProps) { const playerCharacter = visibleGameState.playerCharacter; if (!playerCharacter) { return null; } return ( <>
{bottomTab === 'character' && ( }> )} {bottomTab === 'adventure' && ( }> 1 : canRefreshOptions } onRefreshOptions={() => { if (visibleCurrentStory.npcChatState) { refreshNpcChatOptions(); return; } handleRefreshOptions(); }} onChoice={handleSceneTransitionChoice} onSubmitNpcChatInput={handleNpcChatInput} onExitNpcChat={exitNpcChat} onOpenCharacter={() => openOverlayPanel('character')} onOpenInventory={() => openOverlayPanel('inventory')} playerCharacter={playerCharacter} worldType={visibleGameState.worldType} quests={visibleGameState.quests} questUi={questUi} npcChatQuestOfferUi={npcChatQuestOfferUi} goalStack={goalUi.goalStack} goalPulse={goalUi.pulse} onDismissGoalPulse={goalUi.dismissPulse} battleRewardUi={battleRewardUi} playerHp={visibleGameState.playerHp} playerMaxHp={visibleGameState.playerMaxHp} playerMana={visibleGameState.playerMana} playerMaxMana={visibleGameState.playerMaxMana} playerSkillCooldowns={visibleGameState.playerSkillCooldowns} inBattle={visibleGameState.inBattle} currentNpcBattleMode={visibleGameState.currentNpcBattleMode} chapterState={visibleGameState.chapterState ?? null} journeyBeat={ visibleGameState.storyEngineMemory?.currentJourneyBeat ?? null } statistics={adventureStatistics} musicVolume={musicVolume} onMusicVolumeChange={onMusicVolumeChange} onSaveAndExit={onSaveAndExit} /> )} {bottomTab === 'inventory' && ( }> )} ); } export default RpgRuntimePanelRouter;