1
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import type { GameState } from '../../types';
|
||||
import type { GameCanvasEntitySelection } from '../GameCanvas';
|
||||
import type { SelectionStage } from '../rpg-entry';
|
||||
|
||||
type OverlayPanel = 'character' | 'inventory' | null;
|
||||
|
||||
function useLazyModalMount(active: boolean) {
|
||||
const [shouldMount, setShouldMount] = useState(active);
|
||||
|
||||
useEffect(() => {
|
||||
if (active) {
|
||||
setShouldMount(true);
|
||||
}
|
||||
}, [active]);
|
||||
|
||||
return shouldMount;
|
||||
}
|
||||
|
||||
/**
|
||||
* RPG 运行态 overlay 与独立面板状态。
|
||||
* 负责保留现有弹窗装配顺序,同时把壳层 UI 状态从旧 GameShell 命名迁出。
|
||||
*/
|
||||
export function useRpgRuntimeOverlayState(params: {
|
||||
gameState: GameState;
|
||||
isMapOpen: boolean;
|
||||
characterChatModalOpen: boolean;
|
||||
hasNpcModalOpen: boolean;
|
||||
}) {
|
||||
const {
|
||||
gameState,
|
||||
isMapOpen,
|
||||
characterChatModalOpen,
|
||||
hasNpcModalOpen,
|
||||
} = params;
|
||||
const [selectionStage, setSelectionStage] = useState<SelectionStage>('platform');
|
||||
const [overlayPanel, setOverlayPanel] = useState<OverlayPanel>(null);
|
||||
const [selectedSceneEntity, setSelectedSceneEntity] =
|
||||
useState<GameCanvasEntitySelection | null>(null);
|
||||
const [showTeamModal, setShowTeamModal] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedSceneEntity(null);
|
||||
}, [gameState.currentScenePreset?.id, gameState.playerCharacter?.id]);
|
||||
|
||||
const shouldMountAdventureEntityModal = useLazyModalMount(
|
||||
Boolean(selectedSceneEntity),
|
||||
);
|
||||
const shouldMountCampModal = useLazyModalMount(showTeamModal);
|
||||
const shouldMountMapModal = useLazyModalMount(isMapOpen);
|
||||
const shouldMountCharacterChatModal = useLazyModalMount(
|
||||
characterChatModalOpen,
|
||||
);
|
||||
const shouldMountNpcModals = useLazyModalMount(hasNpcModalOpen);
|
||||
|
||||
const openOverlayPanel = (panel: Exclude<OverlayPanel, null>) => {
|
||||
setSelectedSceneEntity(null);
|
||||
setOverlayPanel(panel);
|
||||
};
|
||||
|
||||
const closeOverlayPanel = () => setOverlayPanel(null);
|
||||
const openPartyMemberDetails = (selection: GameCanvasEntitySelection) =>
|
||||
setSelectedSceneEntity(selection);
|
||||
const closeAdventureEntityModal = () => setSelectedSceneEntity(null);
|
||||
const openCampModal = () => setShowTeamModal(true);
|
||||
const closeCampModal = () => setShowTeamModal(false);
|
||||
|
||||
const resetSelectionFlow = () => setSelectionStage('platform');
|
||||
|
||||
const resetForSaveAndExit = () => {
|
||||
setSelectedSceneEntity(null);
|
||||
setOverlayPanel(null);
|
||||
setShowTeamModal(false);
|
||||
setSelectionStage('platform');
|
||||
};
|
||||
|
||||
return {
|
||||
selectionStage,
|
||||
setSelectionStage,
|
||||
resetSelectionFlow,
|
||||
overlayPanel,
|
||||
openOverlayPanel,
|
||||
closeOverlayPanel,
|
||||
selectedSceneEntity,
|
||||
setSelectedSceneEntity,
|
||||
openPartyMemberDetails,
|
||||
closeAdventureEntityModal,
|
||||
showTeamModal,
|
||||
openCampModal,
|
||||
closeCampModal,
|
||||
resetForSaveAndExit,
|
||||
shouldMountAdventureEntityModal,
|
||||
shouldMountCampModal,
|
||||
shouldMountMapModal,
|
||||
shouldMountCharacterChatModal,
|
||||
shouldMountNpcModals,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user