From 38b1a7fc6183052d12470103b34eec34587137a1 Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Tue, 18 Jun 2024 23:27:06 +1000 Subject: [PATCH] Make starter selection account for evolutions and forms (#2077) Only the second and on can be selected with future valid criteria --- src/data/challenge.ts | 49 ++++++++++++++++++++++++++--- src/ui/starter-select-ui-handler.ts | 12 ++++--- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 658381951c7..5c689ef7345 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -1,12 +1,14 @@ import * as Utils from "../utils"; import i18next from "i18next"; -import { GameData } from "#app/system/game-data.js"; -import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "./pokemon-species"; +import { DexAttrProps, GameData } from "#app/system/game-data.js"; +import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./pokemon-species"; import Pokemon from "#app/field/pokemon.js"; import { BattleType, FixedBattleConfig } from "#app/battle.js"; import Trainer, { TrainerVariant } from "#app/field/trainer.js"; import { GameMode } from "#app/game-mode.js"; import { Type } from "./type"; +import { pokemonEvolutions } from "./pokemon-evolutions"; +import { pokemonFormChanges } from "./pokemon-forms"; import { Challenges } from "#enums/challenges"; import { Species } from "#enums/species"; import { TrainerType } from "#enums/trainer-type"; @@ -277,8 +279,22 @@ export class SingleGenerationChallenge extends Challenge { case ChallengeType.STARTER_CHOICE: const species = args[0] as PokemonSpecies; const isValidStarter = args[1] as Utils.BooleanHolder; + const amountOfPokemon = args[3] as number; const starterGeneration = species.speciesId === Species.VICTINI ? 5 : species.generation; - if (starterGeneration !== this.value) { + const generations = [starterGeneration]; + if (amountOfPokemon > 0) { + const speciesToCheck = [species.speciesId]; + while (speciesToCheck.length) { + const checking = speciesToCheck.pop(); + if (pokemonEvolutions.hasOwnProperty(checking)) { + pokemonEvolutions[checking].forEach(e => { + speciesToCheck.push(e.speciesId); + generations.push(getPokemonSpecies(e.speciesId).generation); + }); + } + } + } + if (!generations.includes(this.value)) { isValidStarter.value = false; return true; } @@ -372,7 +388,32 @@ export class SingleTypeChallenge extends Challenge { case ChallengeType.STARTER_CHOICE: const species = args[0] as PokemonSpecies; const isValidStarter = args[1] as Utils.BooleanHolder; - if (!species.isOfType(this.value - 1)) { + const dexAttr = args[2] as DexAttrProps; + const amountOfPokemon = args[3] as number; + const speciesForm = getPokemonSpeciesForm(species.speciesId, dexAttr.formIndex); + const types = [speciesForm.type1, speciesForm.type2]; + if (amountOfPokemon > 0) { + const speciesToCheck = [species.speciesId]; + while (speciesToCheck.length) { + const checking = speciesToCheck.pop(); + if (pokemonEvolutions.hasOwnProperty(checking)) { + pokemonEvolutions[checking].forEach(e => { + speciesToCheck.push(e.speciesId); + types.push(getPokemonSpecies(e.speciesId).type1, getPokemonSpecies(e.speciesId).type2); + }); + } + if (pokemonFormChanges.hasOwnProperty(checking)) { + pokemonFormChanges[checking].forEach(f1 => { + getPokemonSpecies(checking).forms.forEach(f2 => { + if (f1.formKey === f2.formKey) { + types.push(f2.type1, f2.type2); + } + }); + }); + } + } + } + if (!types.includes(this.value - 1)) { isValidStarter.value = false; return true; } diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 2c4a413f2f1..2dd77b53ae0 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -1097,7 +1097,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const species = this.genSpecies[this.getGenCursorWithScroll()][this.cursor]; const isValidForChallenge = new Utils.BooleanHolder(true); - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor), this.starterGens.length); if (!isDupe && isValidForChallenge.value && this.tryUpdateValue(this.scene.gameData.getSpeciesStarterValue(species.speciesId))) { const cursorObj = this.starterCursorObjs[this.starterCursors.length]; @@ -2216,8 +2216,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonSprite.setVisible(!this.statsMode); }); - (this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite) - .setTexture(species.getIconAtlasKey(formIndex, shiny, variant), species.getIconId(female, formIndex, shiny, variant)); + + const isValidForChallenge = new Utils.BooleanHolder(true); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(species, this.dexAttrCursor), this.starterGens.length); + const starterSprite = this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite; + starterSprite.setTexture(species.getIconAtlasKey(formIndex, shiny, variant), species.getIconId(female, formIndex, shiny, variant)); + starterSprite.setAlpha(isValidForChallenge.value ? 1 : 0.375); this.checkIconId((this.starterSelectGenIconContainers[this.getGenCursorWithScroll()].getAt(this.cursor) as Phaser.GameObjects.Sprite), species, female, formIndex, shiny, variant); this.canCycleShiny = !!(dexEntry.caughtAttr & DexAttr.NON_SHINY && dexEntry.caughtAttr & DexAttr.SHINY); this.canCycleGender = !!(dexEntry.caughtAttr & DexAttr.MALE && dexEntry.caughtAttr & DexAttr.FEMALE); @@ -2434,7 +2438,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { * we change to can AddParty value to true since the user has enough cost to choose this pokemon and this pokemon registered too. */ const isValidForChallenge = new Utils.BooleanHolder(true); - Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, this.genSpecies[g][s], isValidForChallenge); + Challenge.applyChallenges(this.scene.gameMode, Challenge.ChallengeType.STARTER_CHOICE, this.genSpecies[g][s], isValidForChallenge, this.scene.gameData.getSpeciesDexAttrProps(this.genSpecies[g][s], this.scene.gameData.getSpeciesDefaultDexAttr(this.genSpecies[g][s], false, true)), this.starterGens.length + (add ? 1 : 0)); const canBeChosen = remainValue >= speciesStarterValue && isValidForChallenge.value;