diff --git a/src/components/Evolution.tsx b/src/components/Evolution.tsx index 862c780..64dfc22 100644 --- a/src/components/Evolution.tsx +++ b/src/components/Evolution.tsx @@ -5,6 +5,9 @@ import usePokemonMetadata from "../app/use-pokemon-metadata"; import useEvent from "../app/use-event"; import { Event } from "../app/emitter"; import PixelImage from "../styles/PixelImage"; +import { useDispatch, useSelector } from "react-redux"; +import { selectEvolution } from "../state/uiSlice"; +import { selectPokemon, updateSpecificPokemon } from "../state/gameSlice"; const StyledEvolution = styled.div` position: absolute; @@ -239,25 +242,36 @@ const TextContainer = styled.div` } `; -interface Props { - show: boolean; - close: () => void; - pokemonId: number; -} - -const Evolution = ({ show, close, pokemonId }: Props) => { - const metadata = usePokemonMetadata(pokemonId); +const Evolution = () => { + const dispatch = useDispatch(); + const pokemonIndex = useSelector(selectEvolution); + const allPokemon = useSelector(selectPokemon); + const evolvingPokemon = allPokemon[pokemonIndex || 0]; + const evolvingId = evolvingPokemon ? evolvingPokemon.id : null; + const metadata = usePokemonMetadata(evolvingId); const evolvesMetadata = usePokemonMetadata( metadata?.evolution?.pokemon || null ); + const show = pokemonIndex !== null; const [evolved, setEvolved] = useState(false); useEvent(Event.A, () => { - if (evolved) { - setEvolved(false); - close(); - } + if (!show) return; + if (!evolved) return; + if (!metadata) throw new Error("No metadata for evolution"); + if (!metadata.evolution) throw new Error("No evolving pokemon"); + + setEvolved(false); + dispatch( + updateSpecificPokemon({ + index: pokemonIndex, + pokemon: { + ...evolvingPokemon, + id: metadata.evolution.pokemon, + }, + }) + ); }); if (!show) return null; diff --git a/src/components/Game.tsx b/src/components/Game.tsx index 860971e..8237598 100644 --- a/src/components/Game.tsx +++ b/src/components/Game.tsx @@ -32,6 +32,7 @@ import TextThenAction from "./TextThenAction"; import LearnMove from "../app/LearnMove"; import QuestHandler from "./QuestHandler"; import ConfirmationMenu from "./ConfirmationMenu"; +import Evolution from "./Evolution"; const Container = styled.div` position: absolute; @@ -122,6 +123,7 @@ const Game = () => { <LearnMove /> <PlayerMenu /> <ActionOnPokemon /> + <Evolution /> <ConfirmationMenu /> <LoadScreen /> <TitleScreen /> diff --git a/src/components/PokemonEncounter.tsx b/src/components/PokemonEncounter.tsx index 5cfd157..7bd563e 100644 --- a/src/components/PokemonEncounter.tsx +++ b/src/components/PokemonEncounter.tsx @@ -44,9 +44,11 @@ import ballRight from "../assets/battle/ball-right.png"; import Menu, { MenuItemType } from "./Menu"; import PokemonList from "./PokemonList"; import { + selectEvolution, selectItemsMenu, selectPokeballThrowing, selectStartMenu, + showEvolution, showItemsMenu, showTextThenAction, stopThrowingPokeball, @@ -57,7 +59,6 @@ import { MoveMetadata } from "../app/move-metadata"; import processMove, { MoveResult } from "../app/move-helper"; import getXp from "../app/xp-helper"; import getLevelData, { getLearnedMove } from "../app/level-helper"; -import Evolution from "./Evolution"; import MoveSelect from "./MoveSelect"; import catchesPokemon from "../app/pokeball-helper"; import { PokemonEncounterType, PokemonInstance } from "../state/state-types"; @@ -573,7 +574,6 @@ const PokemonEncounter = () => { // 20 = they fainted // 21 = gained xp // 22 = leveled up - // 23 = Evolving // 24 = active fainted // 25 = select new pokemon // 26 = out of pokemon @@ -611,6 +611,7 @@ const PokemonEncounter = () => { const processingPokemon = pokemon[involvedPokemon[processingInvolvedPokemon] || 0]; const processingMetadata = usePokemonMetadata(processingPokemon?.id || null); + const pokemonEvolving = useSelector(selectEvolution); const [alertText, setAlertText] = useState<string | null>(null); const [clickableNotice, setClickableNotice] = useState<string | null>(null); @@ -839,6 +840,7 @@ const PokemonEncounter = () => { useEvent(Event.A, () => { if (startMenuOpen) return; + if (pokemonEvolving !== null) return; if (clickableNotice) { setClickableNotice(null); @@ -924,9 +926,10 @@ const PokemonEncounter = () => { setStage(29); } else if (move && hasFourMoves) { setStage(30); - } else if (isEvolving) { - setStage(23); } else { + if (isEvolving) { + dispatch(showEvolution(involvedPokemon[processingInvolvedPokemon])); + } endEncounter_(); } } @@ -968,10 +971,9 @@ const PokemonEncounter = () => { ); if (isEvolving) { - setStage(23); - } else { - endEncounter_(); + dispatch(showEvolution(involvedPokemon[processingInvolvedPokemon])); } + endEncounter_(); } if (stage === 30) { @@ -1433,26 +1435,6 @@ const PokemonEncounter = () => { select={(move: string) => processBattle(move)} close={() => setStage(11)} /> - <Evolution - pokemonId={processingPokemon.id} - show={stage === 23} - close={() => { - if (!processingMetadata) - throw new Error("No processing metadata"); - if (!processingMetadata.evolution) - throw new Error("No evolution"); - dispatch( - updateSpecificPokemon({ - index: involvedPokemon[processingInvolvedPokemon], - pokemon: { - ...processingPokemon, - id: processingMetadata.evolution.pokemon, - }, - }) - ); - endEncounter_(); - }} - /> {stage === 25 && ( <PokemonList text="Bring out which POKéMON?" @@ -1487,10 +1469,13 @@ const PokemonEncounter = () => { processingPokemon.level >= processingMetadata.evolution.level; if (isEvolving) { - setStage(23); - } else { - endEncounter_(); + dispatch( + showEvolution( + involvedPokemon[processingInvolvedPokemon] + ) + ); } + endEncounter_(); dispatch( updateSpecificPokemon({ index: involvedPokemon[processingInvolvedPokemon], @@ -1518,10 +1503,11 @@ const PokemonEncounter = () => { processingPokemon.level >= processingMetadata.evolution.level; if (isEvolving) { - setStage(23); - } else { - endEncounter_(); + dispatch( + showEvolution(involvedPokemon[processingInvolvedPokemon]) + ); } + endEncounter_(); }, }, ]} @@ -1531,10 +1517,11 @@ const PokemonEncounter = () => { processingMetadata.evolution && processingPokemon.level >= processingMetadata.evolution.level; if (isEvolving) { - setStage(23); - } else { - endEncounter_(); + dispatch( + showEvolution(involvedPokemon[processingInvolvedPokemon]) + ); } + endEncounter_(); }} bottom="0" right="0" diff --git a/src/components/StartMenu.tsx b/src/components/StartMenu.tsx index 7f83859..f520b6a 100644 --- a/src/components/StartMenu.tsx +++ b/src/components/StartMenu.tsx @@ -87,10 +87,10 @@ const StartMenu = () => { updateSpecificPokemon({ index: 0, pokemon: { - id: 6, - level: 100, + id: 1, + level: 15, xp: 0, - hp: getPokemonStats(6, 100).hp, + hp: getPokemonStats(3, 100).hp, moves: [ { id: "scratch", pp: 35 }, { id: "growl", pp: 40 }, diff --git a/src/state/uiSlice.ts b/src/state/uiSlice.ts index a2ab213..4229c0f 100644 --- a/src/state/uiSlice.ts +++ b/src/state/uiSlice.ts @@ -40,6 +40,7 @@ interface UiState { learningMove: LearningMoveType | null; blackScreen: boolean; confirmationMenu: ConfimationMenuType | null; + evolution: number | null; } const initialState: UiState = { @@ -60,6 +61,7 @@ const initialState: UiState = { learningMove: null, blackScreen: false, confirmationMenu: null, + evolution: null, }; export const uiSlice = createSlice({ @@ -165,6 +167,12 @@ export const uiSlice = createSlice({ hideConfirmationMenu: (state) => { state.confirmationMenu = null; }, + showEvolution: (state, action: PayloadAction<number>) => { + state.evolution = action.payload; + }, + hideEvolution: (state) => { + state.evolution = null; + }, }, }); @@ -199,6 +207,8 @@ export const { setBlackScreen, showConfirmationMenu, hideConfirmationMenu, + showEvolution, + hideEvolution, } = uiSlice.actions; export const selectText = (state: RootState) => state.ui.text; @@ -241,7 +251,8 @@ export const selectMenuOpen = (state: RootState) => state.ui.pokeMartMenu || state.ui.textThenAction !== null || state.ui.learningMove !== null || - state.ui.confirmationMenu !== null; + state.ui.confirmationMenu !== null || + state.ui.evolution !== null; export const selectStartMenuSubOpen = (state: RootState) => state.ui.itemsMenu || state.ui.playerMenu; @@ -264,4 +275,6 @@ export const selectBlackScreen = (state: RootState) => state.ui.blackScreen; export const selectConfirmationMenu = (state: RootState) => state.ui.confirmationMenu; +export const selectEvolution = (state: RootState) => state.ui.evolution; + export default uiSlice.reducer;