From ef8b6aa4f9fee580d178b8e5333b41286825d19c Mon Sep 17 00:00:00 2001 From: hayuna Date: Tue, 4 Jun 2024 17:29:38 +0200 Subject: [PATCH] [Feature] Add possibility to override whole user party (#1643) * Add possibility to override whole user party * Update species overriding * Replace SPARTER_SPECIES_OVERRIDE with array * Replace SPARTER_SPECIES_OVERRIDE with array * Add possibility to override species forms * Add possibility to override species forms * Fix eslint styling * Add possibility to override Abilities for party * Override status, gender, moveset * Add possibility to override shinies * Fix CI --- src/battle-scene.ts | 4 +- src/data/daily-run.ts | 2 +- src/field/pokemon.ts | 35 ++++++++------ src/overrides.ts | 103 +++++++++++++++++++++++++++++++++++------- src/phases.ts | 19 +++++--- 5 files changed, 123 insertions(+), 40 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 957052d9881..d4b74ea0979 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -686,8 +686,8 @@ export default class BattleScene extends SceneBase { return findInParty(this.getParty()) || findInParty(this.getEnemyParty()); } - addPlayerPokemon(species: PokemonSpecies, level: integer, abilityIndex: integer, formIndex: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData, postProcess?: (playerPokemon: PlayerPokemon) => void): PlayerPokemon { - const pokemon = new PlayerPokemon(this, species, level, abilityIndex, formIndex, gender, shiny, variant, ivs, nature, dataSource); + addPlayerPokemon(species: PokemonSpecies, level: integer, abilityIndex: integer, formIndex: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData, postProcess?: (playerPokemon: PlayerPokemon) => void, indexInParty?: number): PlayerPokemon { + const pokemon = new PlayerPokemon(this, species, level, abilityIndex, formIndex, gender, shiny, variant, ivs, nature, dataSource, indexInParty); if (postProcess) { postProcess(pokemon); } diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index cb4bfddc685..4683792aeb8 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -61,7 +61,7 @@ export function getDailyRunStarters(scene: BattleScene, seed: string): Starter[] function getDailyRunStarter(scene: BattleScene, starterSpeciesForm: PokemonSpeciesForm, startingLevel: integer): Starter { const starterSpecies = starterSpeciesForm instanceof PokemonSpecies ? starterSpeciesForm : getPokemonSpecies(starterSpeciesForm.speciesId); const formIndex = starterSpeciesForm instanceof PokemonSpecies ? undefined : starterSpeciesForm.formIndex; - const pokemon = new PlayerPokemon(scene, starterSpecies, startingLevel, undefined, formIndex, undefined, undefined, undefined, undefined, undefined, undefined); + const pokemon = new PlayerPokemon(scene, starterSpecies, startingLevel, undefined, formIndex, undefined, undefined, undefined, undefined, undefined, undefined, undefined); const starter: Starter = { species: starterSpecies, dexAttr: pokemon.getDexAttr(), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8065b4633b7..bc118bcfdbe 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -98,6 +98,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public battleData: PokemonBattleData; public battleSummonData: PokemonBattleSummonData; public turnData: PokemonTurnData; + public indexInParty: number; public fieldPosition: FieldPosition; @@ -106,7 +107,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { private shinySparkle: Phaser.GameObjects.Sprite; - constructor(scene: BattleScene, x: number, y: number, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData) { + constructor(scene: BattleScene, x: number, y: number, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData, indexInParty?: number) { super(scene, x, y); if (!species.isObtainable() && this.isPlayer()) { @@ -139,6 +140,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (variant !== undefined) { this.variant = variant; } + if (indexInParty !== undefined) { + this.indexInParty = indexInParty; + } this.exp = dataSource?.exp || getLevelTotalExp(this.level, species.growthRate); this.levelExp = dataSource?.levelExp || 0; if (dataSource) { @@ -816,7 +820,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { : this.moveset; // Overrides moveset based on arrays specified in overrides.ts - const overrideArray: Array = this.isPlayer() ? Overrides.MOVESET_OVERRIDE : Overrides.OPP_MOVESET_OVERRIDE; + const overrideArray: Array = this.isPlayer() ? Overrides.STARTER_OVERRIDE[this.indexInParty]?.moveset : Overrides.OPP_MOVESET_OVERRIDE; if (overrideArray.length > 0) { overrideArray.forEach((move: Moves, index: number) => { const ppUsed = this.moveset[index]?.ppUsed || 0; @@ -901,9 +905,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (!ignoreOverride && this.summonData?.ability) { return allAbilities[this.summonData.ability]; } - if (Overrides.ABILITY_OVERRIDE && this.isPlayer()) { - return allAbilities[Overrides.ABILITY_OVERRIDE]; - } if (Overrides.OPP_ABILITY_OVERRIDE && !this.isPlayer()) { return allAbilities[Overrides.OPP_ABILITY_OVERRIDE]; } @@ -911,6 +912,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return allAbilities[this.getFusionSpeciesForm(ignoreOverride).getAbility(this.fusionAbilityIndex)]; } let abilityId = this.getSpeciesForm(ignoreOverride).getAbility(this.abilityIndex); + if (Overrides.STARTER_OVERRIDE[this.indexInParty]?.ability) { + abilityId = Overrides.STARTER_OVERRIDE[this.indexInParty].ability; + } + if (abilityId === Abilities.NONE) { abilityId = this.species.ability1; } @@ -925,8 +930,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns {Ability} The passive ability of the pokemon */ getPassiveAbility(): Ability { - if (Overrides.PASSIVE_ABILITY_OVERRIDE && this.isPlayer()) { - return allAbilities[Overrides.PASSIVE_ABILITY_OVERRIDE]; + if (Overrides.STARTER_OVERRIDE[this.indexInParty]?.passiveAbility && this.isPlayer()) { + return allAbilities[Overrides.STARTER_OVERRIDE[this.indexInParty].passiveAbility]; } if (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE && !this.isPlayer()) { return allAbilities[Overrides.OPP_PASSIVE_ABILITY_OVERRIDE]; @@ -948,7 +953,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ hasPassive(): boolean { // returns override if valid for current case - if ((Overrides.PASSIVE_ABILITY_OVERRIDE !== Abilities.NONE && this.isPlayer()) || + if ((Overrides.STARTER_OVERRIDE[this.indexInParty]?.passiveAbility !== Abilities.NONE && this.isPlayer()) || (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE !== Abilities.NONE && !this.isPlayer())) { return true; } @@ -2822,19 +2827,21 @@ export default interface Pokemon { export class PlayerPokemon extends Pokemon { public compatibleTms: Moves[]; + public indexInParty: number; - constructor(scene: BattleScene, species: PokemonSpecies, level: integer, abilityIndex: integer, formIndex: integer, gender: Gender, shiny: boolean, variant: Variant, ivs: integer[], nature: Nature, dataSource: Pokemon | PokemonData) { + constructor(scene: BattleScene, species: PokemonSpecies, level: integer, abilityIndex: integer, formIndex: integer, gender: Gender, shiny: boolean, variant: Variant, ivs: integer[], nature: Nature, dataSource: Pokemon | PokemonData, indexInParty: number) { super(scene, 106, 148, species, level, abilityIndex, formIndex, gender, shiny, variant, ivs, nature, dataSource); - if (Overrides.STATUS_OVERRIDE) { - this.status = new Status(Overrides.STATUS_OVERRIDE); + if (Overrides.STARTER_OVERRIDE[indexInParty]?.status) { + this.status = new Status(Overrides.STARTER_OVERRIDE[indexInParty].status); } + this.indexInParty = indexInParty; - if (Overrides.SHINY_OVERRIDE) { + if (Overrides.STARTER_OVERRIDE[this.indexInParty]?.shiny) { this.shiny = true; this.initShinySparkle(); - if (Overrides.VARIANT_OVERRIDE) { - this.variant = Overrides.VARIANT_OVERRIDE; + if (Overrides.STARTER_OVERRIDE[this.indexInParty]?.shinyVariant) { + this.variant = Overrides.STARTER_OVERRIDE[this.indexInParty].shinyVariant; } } diff --git a/src/overrides.ts b/src/overrides.ts index 8f5d4978be3..d866973e669 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -52,24 +52,95 @@ export const POKEBALL_OVERRIDE: { active: boolean, pokeballs: PokeballCounts } = * PLAYER OVERRIDES */ -// forms can be found in pokemon-species.ts -export const STARTER_FORM_OVERRIDE: integer = 0; // default 5 or 20 for Daily export const STARTING_LEVEL_OVERRIDE: integer = 0; -/** - * SPECIES OVERRIDE - * will only apply to the first starter in your party or each enemy pokemon - * default is 0 to not override - * @example SPECIES_OVERRIDE = Species.Bulbasaur; - */ -export const STARTER_SPECIES_OVERRIDE: Species | integer = 0; -export const ABILITY_OVERRIDE: Abilities = Abilities.NONE; -export const PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE; -export const STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE; -export const GENDER_OVERRIDE: Gender = null; -export const MOVESET_OVERRIDE: Array = []; -export const SHINY_OVERRIDE: boolean = false; -export const VARIANT_OVERRIDE: Variant = 0; +interface StarterOverride { + /** + * SPECIES OVERRIDE + * will apply to each starter in your party + * default is 0 to not override + * @example STARTER_OVERRIDE.species = Species.Bulbasaur; + */ + + species: Species | integer; + // forms can be found in pokemon-species.ts + form: integer; + ability: Abilities; + passiveAbility: Abilities; + status: StatusEffect; + gender: Gender; + moveset: Moves[]; + shiny: boolean; + shinyVariant: Variant; +} +export const STARTER_OVERRIDE: StarterOverride[] = [ + { + species: 0, + form: 0, + ability: Abilities.NONE, + passiveAbility: Abilities.NONE, + status: StatusEffect.NONE, + gender: null, + moveset: [], + shiny: false, + shinyVariant: 0, + }, + { + species: 0, + form: 0, + ability: Abilities.NONE, + passiveAbility: Abilities.NONE, + status: StatusEffect.NONE, + gender: null, + moveset: [], + shiny: false, + shinyVariant: 0, + }, + { + species: 0, + form: 0, + ability: Abilities.NONE, + passiveAbility: Abilities.NONE, + status: StatusEffect.NONE, + gender: null, + moveset: [], + shiny: false, + shinyVariant: 0, + }, + { + species: 0, + form: 0, + ability: Abilities.NONE, + passiveAbility: Abilities.NONE, + status: StatusEffect.NONE, + gender: null, + moveset: [], + shiny: false, + shinyVariant: 0, + }, + { + species: 0, + form: 0, + ability: Abilities.NONE, + passiveAbility: Abilities.NONE, + status: StatusEffect.NONE, + gender: null, + moveset: [], + shiny: false, + shinyVariant: 0, + }, + { + species: 0, + form: 0, + ability: Abilities.NONE, + passiveAbility: Abilities.NONE, + status: StatusEffect.NONE, + gender: null, + moveset: [], + shiny: false, + shinyVariant: 0, + } +]; /** * OPPONENT / ENEMY OVERRIDES diff --git a/src/phases.ts b/src/phases.ts index 110c4155849..c1e4a0e17cf 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -529,22 +529,27 @@ export class SelectStarterPhase extends Phase { const party = this.scene.getParty(); const loadPokemonAssets: Promise[] = []; starters.forEach((starter: Starter, i: integer) => { - if (!i && Overrides.STARTER_SPECIES_OVERRIDE) { - starter.species = getPokemonSpecies(Overrides.STARTER_SPECIES_OVERRIDE as Species); + if (Overrides.STARTER_OVERRIDE[i]?.species) { + starter.species = getPokemonSpecies(Overrides.STARTER_OVERRIDE[i].species as Species); } const starterProps = this.scene.gameData.getSpeciesDexAttrProps(starter.species, starter.dexAttr); let starterFormIndex = Math.min(starterProps.formIndex, Math.max(starter.species.forms.length - 1, 0)); - if (!i && Overrides.STARTER_SPECIES_OVERRIDE) { - starterFormIndex = Overrides.STARTER_FORM_OVERRIDE; + if (Overrides.STARTER_OVERRIDE[i]?.form) { + starterFormIndex = Overrides.STARTER_OVERRIDE[i].form; + const availableForms = starter.species.forms.length; + // prevent use forms which does not exist for species + if (Overrides.STARTER_OVERRIDE[i].form >= availableForms) { + starterFormIndex = 0; + } } let starterGender = starter.species.malePercent !== null ? !starterProps.female ? Gender.MALE : Gender.FEMALE : Gender.GENDERLESS; - if (Overrides.GENDER_OVERRIDE !== null) { - starterGender = Overrides.GENDER_OVERRIDE; + if (Overrides.STARTER_OVERRIDE[i]?.gender !== null) { + starterGender = Overrides.STARTER_OVERRIDE[i].gender; } const starterIvs = this.scene.gameData.dexData[starter.species.speciesId].ivs.slice(0); - const starterPokemon = this.scene.addPlayerPokemon(starter.species, this.scene.gameMode.getStartingLevel(), starter.abilityIndex, starterFormIndex, starterGender, starterProps.shiny, starterProps.variant, starterIvs, starter.nature); + const starterPokemon = this.scene.addPlayerPokemon(starter.species, this.scene.gameMode.getStartingLevel(), starter.abilityIndex, starterFormIndex, starterGender, starterProps.shiny, starterProps.variant, starterIvs, starter.nature, null, null, i); starterPokemon.tryPopulateMoveset(starter.moveset); if (starter.passive) { starterPokemon.passive = true;