98
src/hooks/useTreasureFlow.ts
Normal file
98
src/hooks/useTreasureFlow.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { addInventoryItems } from '../data/npcInteractions';
|
||||
import {
|
||||
buildTreasureEncounterStoryMoment,
|
||||
buildTreasureResultText,
|
||||
resolveTreasureReward,
|
||||
} from '../data/treasureInteractions';
|
||||
import { Character, Encounter, GameState, StoryMoment, StoryOption } from '../types';
|
||||
import type {CommitGeneratedState} from './generatedState';
|
||||
|
||||
type ProgressTreasureQuest = (state: GameState, sceneId: string | null) => GameState;
|
||||
|
||||
export function isTreasureEncounter(encounter: GameState['currentEncounter']): encounter is Encounter {
|
||||
return Boolean(encounter?.kind === 'treasure');
|
||||
}
|
||||
|
||||
export function buildTreasureStory(
|
||||
state: GameState,
|
||||
_character: Character,
|
||||
encounter: Encounter,
|
||||
overrideText?: string,
|
||||
): StoryMoment {
|
||||
return buildTreasureEncounterStoryMoment({
|
||||
state,
|
||||
encounter,
|
||||
overrideText,
|
||||
});
|
||||
}
|
||||
|
||||
export function useTreasureFlow({
|
||||
gameState,
|
||||
commitGeneratedState,
|
||||
progressTreasureQuest,
|
||||
}: {
|
||||
gameState: GameState;
|
||||
commitGeneratedState: CommitGeneratedState;
|
||||
progressTreasureQuest: ProgressTreasureQuest;
|
||||
}) {
|
||||
const handleTreasureInteraction = useCallback((option: StoryOption) => {
|
||||
if (!gameState.playerCharacter || option.interaction?.kind !== 'treasure' || gameState.currentEncounter?.kind !== 'treasure') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const encounter = gameState.currentEncounter;
|
||||
const action = option.interaction.action;
|
||||
const reward = action === 'leave'
|
||||
? null
|
||||
: resolveTreasureReward(gameState, encounter, action);
|
||||
const progressedState = action === 'leave'
|
||||
? gameState
|
||||
: progressTreasureQuest(gameState, gameState.currentScenePreset?.id ?? null);
|
||||
|
||||
const nextState: GameState = {
|
||||
...progressedState,
|
||||
currentEncounter: null,
|
||||
npcInteractionActive: false,
|
||||
sceneMonsters: [],
|
||||
playerX: 0,
|
||||
playerFacing: 'right' as const,
|
||||
animationState: progressedState.animationState,
|
||||
scrollWorld: false,
|
||||
inBattle: false,
|
||||
playerHp: reward
|
||||
? Math.min(progressedState.playerMaxHp, progressedState.playerHp + reward.hp)
|
||||
: progressedState.playerHp,
|
||||
playerMana: reward
|
||||
? Math.min(progressedState.playerMaxMana, progressedState.playerMana + reward.mana)
|
||||
: progressedState.playerMana,
|
||||
playerCurrency: reward
|
||||
? progressedState.playerCurrency + reward.currency
|
||||
: progressedState.playerCurrency,
|
||||
playerInventory: reward
|
||||
? addInventoryItems(progressedState.playerInventory, reward.items)
|
||||
: progressedState.playerInventory,
|
||||
currentBattleNpcId: null,
|
||||
currentNpcBattleMode: null,
|
||||
currentNpcBattleOutcome: null,
|
||||
sparReturnEncounter: null,
|
||||
sparPlayerHpBefore: null,
|
||||
sparPlayerMaxHpBefore: null,
|
||||
sparStoryHistoryBefore: null,
|
||||
};
|
||||
|
||||
void commitGeneratedState(
|
||||
nextState,
|
||||
gameState.playerCharacter,
|
||||
option.actionText,
|
||||
buildTreasureResultText(encounter, action, reward ?? undefined),
|
||||
option.functionId,
|
||||
);
|
||||
return true;
|
||||
}, [commitGeneratedState, gameState, progressTreasureQuest]);
|
||||
|
||||
return {
|
||||
handleTreasureInteraction,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user