From 7da8bdfdb62038319d18b6e95a76c47723bdc98d Mon Sep 17 00:00:00 2001 From: chaosgrimmon <31082757+chaosgrimmon@users.noreply.github.com> Date: Tue, 4 Jun 2024 09:26:03 -0400 Subject: [PATCH 01/10] [Bug] Epic Drifblim using Drifloon sprite (#1788) --- public/images/pokemon/variant/_masterlist.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/images/pokemon/variant/_masterlist.json b/public/images/pokemon/variant/_masterlist.json index 333ed303443..adca124fc89 100644 --- a/public/images/pokemon/variant/_masterlist.json +++ b/public/images/pokemon/variant/_masterlist.json @@ -4065,7 +4065,7 @@ "426": [ 0, 1, - 2 + 1 ], "427": [ 0, From 7ac7c2b63b5eaebcb4b663bc3a96553e2ef3be5e Mon Sep 17 00:00:00 2001 From: Matthew Olker Date: Tue, 4 Jun 2024 09:54:10 -0400 Subject: [PATCH 02/10] fix mobile settings touch controls --- index.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.css b/index.css index 1a695fa0c4f..9ca2cd60dff 100644 --- a/index.css +++ b/index.css @@ -146,8 +146,8 @@ body { margin-left: 10%; } -#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadRectBtnContainer > .apadSqBtn, -#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadSqBtnContainer +#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_ACCESSIBILITY']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadRectBtnContainer > .apadSqBtn, +#touchControls:not([data-ui-mode='STARTER_SELECT']):not([data-ui-mode='SETTINGS']):not([data-ui-mode='SETTINGS_ACCESSIBILITY']):not([data-ui-mode='SETTINGS_GAMEPAD']):not([data-ui-mode='SETTINGS_KEYBOARD']) #apad .apadSqBtnContainer { display: none; } From ef8b6aa4f9fee580d178b8e5333b41286825d19c Mon Sep 17 00:00:00 2001 From: hayuna Date: Tue, 4 Jun 2024 17:29:38 +0200 Subject: [PATCH 03/10] [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; From 1c73b3b08448d059e8d65ea1509822f7687e3de0 Mon Sep 17 00:00:00 2001 From: Tempoanon <163687446+Tempo-anon@users.noreply.github.com> Date: Tue, 4 Jun 2024 11:39:02 -0400 Subject: [PATCH 04/10] Revert "[Feature] Add possibility to override whole user party (#1643)" (#1796) This reverts commit ef8b6aa4f9fee580d178b8e5333b41286825d19c. --- 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, 40 insertions(+), 123 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index d4b74ea0979..957052d9881 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, indexInParty?: number): PlayerPokemon { - const pokemon = new PlayerPokemon(this, species, level, abilityIndex, formIndex, gender, shiny, variant, ivs, nature, dataSource, indexInParty); + 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); if (postProcess) { postProcess(pokemon); } diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index 4683792aeb8..cb4bfddc685 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, undefined); + const pokemon = new PlayerPokemon(scene, starterSpecies, startingLevel, undefined, formIndex, 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 bc118bcfdbe..8065b4633b7 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -98,7 +98,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public battleData: PokemonBattleData; public battleSummonData: PokemonBattleSummonData; public turnData: PokemonTurnData; - public indexInParty: number; public fieldPosition: FieldPosition; @@ -107,7 +106,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, indexInParty?: number) { + 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) { super(scene, x, y); if (!species.isObtainable() && this.isPlayer()) { @@ -140,9 +139,6 @@ 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) { @@ -820,7 +816,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.STARTER_OVERRIDE[this.indexInParty]?.moveset : Overrides.OPP_MOVESET_OVERRIDE; + const overrideArray: Array = this.isPlayer() ? Overrides.MOVESET_OVERRIDE : Overrides.OPP_MOVESET_OVERRIDE; if (overrideArray.length > 0) { overrideArray.forEach((move: Moves, index: number) => { const ppUsed = this.moveset[index]?.ppUsed || 0; @@ -905,6 +901,9 @@ 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]; } @@ -912,10 +911,6 @@ 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; } @@ -930,8 +925,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns {Ability} The passive ability of the pokemon */ getPassiveAbility(): Ability { - if (Overrides.STARTER_OVERRIDE[this.indexInParty]?.passiveAbility && this.isPlayer()) { - return allAbilities[Overrides.STARTER_OVERRIDE[this.indexInParty].passiveAbility]; + if (Overrides.PASSIVE_ABILITY_OVERRIDE && this.isPlayer()) { + return allAbilities[Overrides.PASSIVE_ABILITY_OVERRIDE]; } if (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE && !this.isPlayer()) { return allAbilities[Overrides.OPP_PASSIVE_ABILITY_OVERRIDE]; @@ -953,7 +948,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ hasPassive(): boolean { // returns override if valid for current case - if ((Overrides.STARTER_OVERRIDE[this.indexInParty]?.passiveAbility !== Abilities.NONE && this.isPlayer()) || + if ((Overrides.PASSIVE_ABILITY_OVERRIDE !== Abilities.NONE && this.isPlayer()) || (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE !== Abilities.NONE && !this.isPlayer())) { return true; } @@ -2827,21 +2822,19 @@ 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, 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) { super(scene, 106, 148, species, level, abilityIndex, formIndex, gender, shiny, variant, ivs, nature, dataSource); - if (Overrides.STARTER_OVERRIDE[indexInParty]?.status) { - this.status = new Status(Overrides.STARTER_OVERRIDE[indexInParty].status); + if (Overrides.STATUS_OVERRIDE) { + this.status = new Status(Overrides.STATUS_OVERRIDE); } - this.indexInParty = indexInParty; - if (Overrides.STARTER_OVERRIDE[this.indexInParty]?.shiny) { + if (Overrides.SHINY_OVERRIDE) { this.shiny = true; this.initShinySparkle(); - if (Overrides.STARTER_OVERRIDE[this.indexInParty]?.shinyVariant) { - this.variant = Overrides.STARTER_OVERRIDE[this.indexInParty].shinyVariant; + if (Overrides.VARIANT_OVERRIDE) { + this.variant = Overrides.VARIANT_OVERRIDE; } } diff --git a/src/overrides.ts b/src/overrides.ts index d866973e669..8f5d4978be3 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -52,95 +52,24 @@ 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; -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, - } -]; +/** + * 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; /** * OPPONENT / ENEMY OVERRIDES diff --git a/src/phases.ts b/src/phases.ts index c1e4a0e17cf..110c4155849 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -529,27 +529,22 @@ export class SelectStarterPhase extends Phase { const party = this.scene.getParty(); const loadPokemonAssets: Promise[] = []; starters.forEach((starter: Starter, i: integer) => { - if (Overrides.STARTER_OVERRIDE[i]?.species) { - starter.species = getPokemonSpecies(Overrides.STARTER_OVERRIDE[i].species as Species); + if (!i && Overrides.STARTER_SPECIES_OVERRIDE) { + starter.species = getPokemonSpecies(Overrides.STARTER_SPECIES_OVERRIDE 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 (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; - } + if (!i && Overrides.STARTER_SPECIES_OVERRIDE) { + starterFormIndex = Overrides.STARTER_FORM_OVERRIDE; } let starterGender = starter.species.malePercent !== null ? !starterProps.female ? Gender.MALE : Gender.FEMALE : Gender.GENDERLESS; - if (Overrides.STARTER_OVERRIDE[i]?.gender !== null) { - starterGender = Overrides.STARTER_OVERRIDE[i].gender; + if (Overrides.GENDER_OVERRIDE !== null) { + starterGender = Overrides.GENDER_OVERRIDE; } 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, null, null, i); + const starterPokemon = this.scene.addPlayerPokemon(starter.species, this.scene.gameMode.getStartingLevel(), starter.abilityIndex, starterFormIndex, starterGender, starterProps.shiny, starterProps.variant, starterIvs, starter.nature); starterPokemon.tryPopulateMoveset(starter.moveset); if (starter.passive) { starterPokemon.passive = true; From 6dbf99cc72d4bb03d3368899173326b478df9153 Mon Sep 17 00:00:00 2001 From: Benjamin Odom Date: Tue, 4 Jun 2024 13:03:02 -0500 Subject: [PATCH 05/10] [Bug] Fix Circular Dependency with BerryType (#1802) * Fix Potential Circular Dependency with BerryType * remove .js --- src/data/berry.ts | 15 +-------------- src/data/enums/berry-type.ts | 14 ++++++++++++++ src/field/pokemon.ts | 2 +- src/modifier/modifier-type.ts | 3 ++- src/modifier/modifier.ts | 3 ++- src/overrides.ts | 2 +- 6 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 src/data/enums/berry-type.ts diff --git a/src/data/berry.ts b/src/data/berry.ts index e832ab0a43e..f5bcd5e4be8 100644 --- a/src/data/berry.ts +++ b/src/data/berry.ts @@ -7,20 +7,7 @@ import { getStatusEffectHealText } from "./status-effect"; import * as Utils from "../utils"; import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability"; import i18next from "../plugins/i18n"; - -export enum BerryType { - SITRUS, - LUM, - ENIGMA, - LIECHI, - GANLON, - PETAYA, - APICOT, - SALAC, - LANSAT, - STARF, - LEPPA -} +import { BerryType } from "./enums/berry-type"; export function getBerryName(berryType: BerryType): string { return i18next.t(`berry:${BerryType[berryType]}.name`); diff --git a/src/data/enums/berry-type.ts b/src/data/enums/berry-type.ts new file mode 100644 index 00000000000..8b7aab16010 --- /dev/null +++ b/src/data/enums/berry-type.ts @@ -0,0 +1,14 @@ + +export enum BerryType { + SITRUS, + LUM, + ENIGMA, + LIECHI, + GANLON, + PETAYA, + APICOT, + SALAC, + LANSAT, + STARF, + LEPPA +} diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8065b4633b7..2b8f28c4826 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -44,7 +44,7 @@ import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMov import { TerrainType } from "../data/terrain"; import { TrainerSlot } from "../data/trainer-config"; import * as Overrides from "../overrides"; -import { BerryType } from "../data/berry"; +import { BerryType } from "../data/enums/berry-type"; import i18next from "../plugins/i18n"; import { speciesEggMoves } from "../data/egg-moves"; import { ModifierTier } from "../modifier/modifier-tier"; diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 5705ee43f16..59185811590 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -11,7 +11,8 @@ import { Type } from "../data/type"; import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from "../ui/party-ui-handler"; import * as Utils from "../utils"; import { TempBattleStat, getTempBattleStatBoosterItemName, getTempBattleStatName } from "../data/temp-battle-stat"; -import { BerryType, getBerryEffectDescription, getBerryName } from "../data/berry"; +import { getBerryEffectDescription, getBerryName } from "../data/berry"; +import { BerryType } from "../data/enums/berry-type"; import { Unlockables } from "../system/unlockables"; import { StatusEffect, getStatusEffectDescriptor } from "../data/status-effect"; import { SpeciesFormKey } from "../data/pokemon-species"; diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 8b965cb4ddc..975420ab528 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -12,7 +12,8 @@ import { FusionSpeciesFormEvolution, pokemonEvolutions, pokemonPrevolutions } fr import { getPokemonMessage } from "../messages"; import * as Utils from "../utils"; import { TempBattleStat } from "../data/temp-battle-stat"; -import { BerryType, getBerryEffectFunc, getBerryPredicate } from "../data/berry"; +import { getBerryEffectFunc, getBerryPredicate } from "../data/berry"; +import { BerryType } from "../data/enums/berry-type"; import { StatusEffect, getStatusEffectHealText } from "../data/status-effect"; import { achvs } from "../system/achv"; import { VoucherType } from "../system/voucher"; diff --git a/src/overrides.ts b/src/overrides.ts index 8f5d4978be3..661f2d14253 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -4,7 +4,7 @@ import { Biome } from "./data/enums/biome"; import { Moves } from "./data/enums/moves"; import { WeatherType } from "./data/weather"; import { Variant } from "./data/variant"; -import { BerryType } from "./data/berry"; +import { BerryType } from "./data/enums/berry-type"; import { TempBattleStat } from "./data/temp-battle-stat"; import { Nature } from "./data/nature"; import { Type } from "./data/type"; From 809c86599d978046d31b095a40c19b7acb546c67 Mon Sep 17 00:00:00 2001 From: Tempoanon <163687446+Tempo-anon@users.noreply.github.com> Date: Tue, 4 Jun 2024 14:37:04 -0400 Subject: [PATCH 06/10] [Feature] Updated Champion teams (#1676) * Updated champion teams * Forgot Alder's legendary * Give Alder Genesect * Merge and update * Update teams a bit more * Red now leads with Pikachu, fixed Iris dialogue * Add champ leads --- src/data/trainer-config.ts | 138 +++++++++++++++++++++++++++++-------- src/locales/en/dialogue.ts | 2 +- 2 files changed, 110 insertions(+), 30 deletions(-) diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 83c4f45b244..af47991ad14 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -618,7 +618,7 @@ export class TrainerConfig { * @param isMale - Whether the Champion is Male or Female (for localization of the title). * @returns {TrainerConfig} - The updated TrainerConfig instance. **/ - initForChampion(signatureSpecies: (Species | Species[])[],isMale: boolean): TrainerConfig { + initForChampion(signatureSpecies: (Species | Species[])[], isMale: boolean): TrainerConfig { // Check if the internationalization (i18n) system is initialized. if (!getIsInitialized()) { initI18n(); @@ -917,20 +917,20 @@ export const signatureSpecies: SignatureSpecies = { AMARYS: [Species.SKARMORY, Species.EMPOLEON, Species.SCIZOR, Species.METAGROSS], LACEY: [Species.EXCADRILL, Species.PRIMARINA, Species.ALCREMIE, Species.GALAR_SLOWBRO], DRAYTON: [Species.DRAGONITE, Species.ARCHALUDON, Species.FLYGON, Species.SCEPTILE], - BLUE: [Species.GYARADOS, Species.MEWTWO, Species.ARCANINE, Species.ALAKAZAM, Species.PIDGEOT], - RED: [Species.CHARIZARD, [Species.LUGIA, Species.HO_OH], Species.SNORLAX, Species.RAICHU, Species.ESPEON], - LANCE_CHAMPION: [Species.DRAGONITE, Species.ZYGARDE, Species.AERODACTYL, Species.KINGDRA, Species.ALOLA_EXEGGUTOR], - STEVEN: [Species.METAGROSS, [Species.DIALGA, Species.PALKIA], Species.SKARMORY, Species.AGGRON, Species.CARBINK], - WALLACE: [Species.MILOTIC, Species.KYOGRE, Species.WHISCASH, Species.WALREIN, Species.LUDICOLO], - CYNTHIA: [Species.SPIRITOMB, Species.GIRATINA, Species.GARCHOMP, Species.MILOTIC, Species.LUCARIO, Species.TOGEKISS], - ALDER: [Species.VOLCARONA, Species.GROUDON, Species.BOUFFALANT, Species.ACCELGOR, Species.CONKELDURR], - IRIS: [Species.HAXORUS, Species.YVELTAL, Species.DRUDDIGON, Species.AGGRON, Species.LAPRAS], - DIANTHA: [Species.HAWLUCHA, Species.XERNEAS, Species.GOURGEIST, Species.GOODRA, Species.GARDEVOIR], - HAU: [Species.ALOLA_RAICHU, [Species.SOLGALEO, Species.LUNALA], Species.NOIVERN, [Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA], Species.CRABOMINABLE], - LEON: [Species.DRAGAPULT, [Species.ZACIAN, Species.ZAMAZENTA], Species.SEISMITOAD, Species.AEGISLASH, Species.CHARIZARD], - GEETA: [Species.GLIMMORA, Species.MIRAIDON, Species.ESPATHRA, Species.VELUZA, Species.KINGAMBIT], - NEMONA: [Species.LYCANROC, Species.KORAIDON, Species.KOMMO_O, Species.PAWMOT, Species.DUSKNOIR], - KIERAN: [Species.POLITOED, [Species.OGERPON, Species.TERAPAGOS], Species.HYDRAPPLE, Species.PORYGON_Z, Species.GRIMMSNARL], + BLUE: [[Species.GYARADOS, Species.EXEGGUTOR, Species.ARCANINE], Species.HO_OH, [Species.RHYPERIOR, Species.MAGNEZONE]], // Alakazam lead, Mega Pidgeot + RED: [Species.LUGIA, Species.SNORLAX, [Species.ESPEON, Species.UMBREON, Species.SYLVEON]], // GMax Pikachu lead, Mega gen 1 starter + LANCE_CHAMPION: [Species.DRAGONITE, Species.KINGDRA, Species.ALOLA_EXEGGUTOR], // Aerodactyl lead, Mega Lati@s + STEVEN: [Species.AGGRON, [Species.ARMALDO, Species.CRADILY], Species.DIALGA], // Skarmorly lead, Mega Metagross + WALLACE: [Species.MILOTIC, Species.PALKIA, Species.LUDICOLO], // Pelipper lead, Mega Swampert + CYNTHIA: [Species.GIRATINA, Species.LUCARIO, Species.TOGEKISS], // Spiritomb lead, Mega Garchomp + ALDER: [Species.VOLCARONA, Species.ZEKROM, [Species.ACCELGOR, Species.ESCAVALIER], Species.KELDEO], // Bouffalant/Braviary lead + IRIS: [Species.HAXORUS, Species.RESHIRAM, Species.ARCHEOPS], // Druddigon lead, Gmax Lapras + DIANTHA: [Species.HAWLUCHA, Species.XERNEAS, Species.GOODRA], // Gourgeist lead, Mega Gardevoir + HAU: [[Species.SOLGALEO, Species.LUNALA], Species.NOIVERN, [Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA], [Species.TAPU_BULU, Species.TAPU_FINI, Species.TAPU_KOKO, Species.TAPU_LELE]], // Alola Raichu lead + LEON: [Species.DRAGAPULT, [Species.ZACIAN, Species.ZAMAZENTA], Species.AEGISLASH], // Rillaboom/Cinderace/Inteleon lead + GEETA: [Species.MIRAIDON, [Species.ESPATHRA, Species.VELUZA], [Species.AVALUGG, Species.HISUI_AVALUGG], Species.KINGAMBIT], // Glimmora lead + NEMONA: [Species.KORAIDON, Species.PAWMOT, [Species.DUDUNSPARCE, Species.ORTHWORM], [Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL]], // Lycanroc lead + KIERAN: [[Species.GRIMMSNARL, Species.INCINEROAR, Species.PORYGON_Z], Species.OGERPON, Species.TERAPAGOS, Species.HYDRAPPLE], // Poliwrath/Politoed lead }; export const trainerConfigs: TrainerConfigs = { @@ -1212,20 +1212,100 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.LACEY]: new TrainerConfig(++t).initForEliteFour(signatureSpecies["LACEY"],false, Type.FAIRY), [TrainerType.DRAYTON]: new TrainerConfig(++t).initForEliteFour(signatureSpecies["DRAYTON"],true, Type.DRAGON), - [TrainerType.BLUE]: new TrainerConfig((t = TrainerType.BLUE)).initForChampion(signatureSpecies["BLUE"],true).setBattleBgm("battle_kanto_champion").setHasDouble("blue_red_double").setDoubleTrainerType(TrainerType.RED).setDoubleTitle("champion_double"), - [TrainerType.RED]: new TrainerConfig(++t).initForChampion(signatureSpecies["RED"],true).setBattleBgm("battle_johto_champion").setHasDouble("red_blue_double").setDoubleTrainerType(TrainerType.BLUE).setDoubleTitle("champion_double"), - [TrainerType.LANCE_CHAMPION]: new TrainerConfig(++t).setName("Lance").initForChampion(signatureSpecies["LANCE_CHAMPION"],true).setBattleBgm("battle_johto_champion"), - [TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion(signatureSpecies["STEVEN"],true).setBattleBgm("battle_hoenn_champion").setHasDouble("steven_wallace_double").setDoubleTrainerType(TrainerType.WALLACE).setDoubleTitle("champion_double"), - [TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion(signatureSpecies["WALLACE"],true).setBattleBgm("battle_hoenn_champion").setHasDouble("wallace_steven_double").setDoubleTrainerType(TrainerType.STEVEN).setDoubleTitle("champion_double"), - [TrainerType.CYNTHIA]: new TrainerConfig(++t).initForChampion(signatureSpecies["CYNTHIA"],false).setBattleBgm("battle_sinnoh_champion"), - [TrainerType.ALDER]: new TrainerConfig(++t).initForChampion(signatureSpecies["ALDER"],true).setHasDouble("alder_iris_double").setDoubleTrainerType(TrainerType.IRIS).setDoubleTitle("champion_double").setBattleBgm("battle_champion_alder"), - [TrainerType.IRIS]: new TrainerConfig(++t).initForChampion(signatureSpecies["IRIS"],false).setBattleBgm("battle_champion_iris").setHasDouble("iris_alder_double").setDoubleTrainerType(TrainerType.ALDER).setDoubleTitle("champion_double"), - [TrainerType.DIANTHA]: new TrainerConfig(++t).initForChampion(signatureSpecies["DIANTHA"],false), - [TrainerType.HAU]: new TrainerConfig(++t).initForChampion(signatureSpecies["HAU"],true), - [TrainerType.LEON]: new TrainerConfig(++t).initForChampion(signatureSpecies["LEON"],true), - [TrainerType.GEETA]: new TrainerConfig(++t).initForChampion(signatureSpecies["GEETA"],false), - [TrainerType.NEMONA]: new TrainerConfig(++t).initForChampion(signatureSpecies["NEMONA"],false), - [TrainerType.KIERAN]: new TrainerConfig(++t).initForChampion(signatureSpecies["KIERAN"],true), + [TrainerType.BLUE]: new TrainerConfig((t = TrainerType.BLUE)).initForChampion(signatureSpecies["BLUE"],true).setBattleBgm("battle_kanto_champion").setHasDouble("blue_red_double").setDoubleTrainerType(TrainerType.RED).setDoubleTitle("champion_double") + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ALAKAZAM], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PIDGEOT], TrainerSlot.TRAINER, true, p => { + p.formIndex = 1; + p.generateAndPopulateMoveset(); + })), + [TrainerType.RED]: new TrainerConfig(++t).initForChampion(signatureSpecies["RED"],true).setBattleBgm("battle_johto_champion").setHasDouble("red_blue_double").setDoubleTrainerType(TrainerType.BLUE).setDoubleTitle("champion_double") + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PIKACHU], TrainerSlot.TRAINER, true, p => { + p.formIndex = 8; + p.generateAndPopulateMoveset(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE], TrainerSlot.TRAINER, true, p => { + p.formIndex = 1; + p.generateAndPopulateMoveset(); + })), + [TrainerType.LANCE_CHAMPION]: new TrainerConfig(++t).setName("Lance").initForChampion(signatureSpecies["LANCE_CHAMPION"],true).setBattleBgm("battle_johto_champion") + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.AERODACTYL], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.LATIAS, Species.LATIOS], TrainerSlot.TRAINER, true, p => { + p.formIndex = 1; + p.generateAndPopulateMoveset(); + })), + [TrainerType.STEVEN]: new TrainerConfig(++t).initForChampion(signatureSpecies["STEVEN"],true).setBattleBgm("battle_hoenn_champion").setHasDouble("steven_wallace_double").setDoubleTrainerType(TrainerType.WALLACE).setDoubleTitle("champion_double") + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SKARMORY], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.METAGROSS], TrainerSlot.TRAINER, true, p => { + p.formIndex = 1; + p.generateAndPopulateMoveset(); + })), + [TrainerType.WALLACE]: new TrainerConfig(++t).initForChampion(signatureSpecies["WALLACE"],true).setBattleBgm("battle_hoenn_champion").setHasDouble("wallace_steven_double").setDoubleTrainerType(TrainerType.STEVEN).setDoubleTitle("champion_double") + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PELIPPER], TrainerSlot.TRAINER, true, p => { + p.abilityIndex = 1; // Drizzle + p.generateAndPopulateMoveset(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.SWAMPERT], TrainerSlot.TRAINER, true, p => { + p.formIndex = 1; + p.generateAndPopulateMoveset(); + })), + [TrainerType.CYNTHIA]: new TrainerConfig(++t).initForChampion(signatureSpecies["CYNTHIA"],false).setBattleBgm("battle_sinnoh_champion") + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SPIRITOMB], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.GARCHOMP], TrainerSlot.TRAINER, true, p => { + p.formIndex = 1; + p.generateAndPopulateMoveset(); + })), + [TrainerType.ALDER]: new TrainerConfig(++t).initForChampion(signatureSpecies["ALDER"],true).setHasDouble("alder_iris_double").setDoubleTrainerType(TrainerType.IRIS).setDoubleTitle("champion_double").setBattleBgm("battle_champion_alder") + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.BOUFFALANT, Species.BRAVIARY], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })), + [TrainerType.IRIS]: new TrainerConfig(++t).initForChampion(signatureSpecies["IRIS"],false).setBattleBgm("battle_champion_iris").setHasDouble("iris_alder_double").setDoubleTrainerType(TrainerType.ALDER).setDoubleTitle("champion_double") + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.DRUDDIGON], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.LAPRAS], TrainerSlot.TRAINER, true, p => { + p.formIndex = 1; + p.generateAndPopulateMoveset(); + })), + [TrainerType.DIANTHA]: new TrainerConfig(++t).initForChampion(signatureSpecies["DIANTHA"],false) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GOURGEIST], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.GARDEVOIR], TrainerSlot.TRAINER, true, p => { + p.formIndex = 1; + p.generateAndPopulateMoveset(); + })), + [TrainerType.HAU]: new TrainerConfig(++t).initForChampion(signatureSpecies["HAU"],true) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ALOLA_RAICHU], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })), + [TrainerType.LEON]: new TrainerConfig(++t).initForChampion(signatureSpecies["LEON"],true) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.RILLABOOM, Species.CINDERACE, Species.INTELEON], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.CHARIZARD], TrainerSlot.TRAINER, true, p => { + p.formIndex = 3; + p.generateAndPopulateMoveset(); + })), + [TrainerType.GEETA]: new TrainerConfig(++t).initForChampion(signatureSpecies["GEETA"],false) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GLIMMORA], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })), + [TrainerType.NEMONA]: new TrainerConfig(++t).initForChampion(signatureSpecies["NEMONA"],false) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.LYCANROC], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })), + [TrainerType.KIERAN]: new TrainerConfig(++t).initForChampion(signatureSpecies["KIERAN"],true) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.POLIWRATH, Species.POLITOED], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + })), [TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL) diff --git a/src/locales/en/dialogue.ts b/src/locales/en/dialogue.ts index 7899ec21d36..c5b0d72d3d7 100644 --- a/src/locales/en/dialogue.ts +++ b/src/locales/en/dialogue.ts @@ -1578,7 +1578,7 @@ export const PGMdialogue: DialogueTranslationEntries = { "encounter": { 1: `Know what? I really look forward to having serious battles with strong Trainers! $I mean, come on! The Trainers who make it here are Trainers who desire victory with every fiber of their being! - #And they are battling alongside Pokémon that have been through countless difficult battles! + $And they are battling alongside Pokémon that have been through countless difficult battles! $If I battle with people like that, not only will I get stronger, my Pokémon will, too! $And we'll get to know each other even better! OK! Brace yourself! $I'm Iris, the Pokémon League Champion, and I'm going to defeat you!`, From a8205ae8199237a669e87624bca04d4f91bd2e3b Mon Sep 17 00:00:00 2001 From: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Date: Tue, 4 Jun 2024 22:11:02 +0200 Subject: [PATCH 07/10] =?UTF-8?q?[Bug]=20Handle=20if=20the=20browser=20giv?= =?UTF-8?q?es=20a=20long=20form=20of=20a=20language=20(like=20"de-DE")=20?= =?UTF-8?q?=E2=80=A6=20(#1795)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Handle if the browser gives a long form of a language (like "de-DE") for cases where we only have the short form "de". * Changed it so that now resolved Language is now used anywhere. This is basically what i orignally did manually but provided from i18next directly --- src/loading-scene.ts | 2 +- src/ui/fight-ui-handler.ts | 4 ++-- src/ui/pokemon-info-container.ts | 2 +- src/ui/starter-select-ui-handler.ts | 6 +++--- src/ui/summary-ui-handler.ts | 6 +++--- src/ui/text.ts | 2 +- src/utils.ts | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/loading-scene.ts b/src/loading-scene.ts index 0b15358c4bc..7c108a3c30e 100644 --- a/src/loading-scene.ts +++ b/src/loading-scene.ts @@ -213,7 +213,7 @@ export class LoadingScene extends SceneBase { this.loadAtlas("types", ""); // Get current lang and load the types atlas for it. English will only load types while all other languages will load types and types_ - const lang = i18next.language; + const lang = i18next.resolvedLanguage; if (lang !== "en") { if (Utils.verifyLang(lang)) { this.loadAtlas(`types_${lang}`, ""); diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index 22a0acb14ae..acbf66b7075 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -35,7 +35,7 @@ export default class FightUiHandler extends UiHandler { this.movesContainer = this.scene.add.container(18, -38.7); ui.add(this.movesContainer); - this.typeIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 57, -36,`types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}` , "unknown"); + this.typeIcon = this.scene.add.sprite((this.scene.game.canvas.width / 6) - 57, -36,`types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}` , "unknown"); this.typeIcon.setVisible(false); ui.add(this.typeIcon); @@ -168,7 +168,7 @@ export default class FightUiHandler extends UiHandler { if (hasMove) { const pokemonMove = moveset[cursor]; - this.typeIcon.setTexture(`types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`, Type[pokemonMove.getMove().type].toLowerCase()).setScale(0.8); + this.typeIcon.setTexture(`types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[pokemonMove.getMove().type].toLowerCase()).setScale(0.8); this.moveCategoryIcon.setTexture("categories", MoveCategory[pokemonMove.getMove().category].toLowerCase()).setScale(1.0); const power = pokemonMove.getMove().power; diff --git a/src/ui/pokemon-info-container.ts b/src/ui/pokemon-info-container.ts index cf4c94e1164..b731b0d22b4 100644 --- a/src/ui/pokemon-info-container.ts +++ b/src/ui/pokemon-info-container.ts @@ -73,7 +73,7 @@ export default class PokemonInfoContainer extends Phaser.GameObjects.Container { } setup(): void { - const currentLanguage = i18next.language; + const currentLanguage = i18next.resolvedLanguage; const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang)); const textSettings = languageSettings[langSettingKey]; const infoBg = addWindow(this.scene, 0, 0, this.infoWindowWidth, 132); diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 3faec4bfcc6..abba4a081df 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -251,7 +251,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { setup() { const ui = this.getUi(); - const currentLanguage = i18next.language; + const currentLanguage = i18next.resolvedLanguage; const langSettingKey = Object.keys(languageSettings).find(lang => currentLanguage.includes(lang)); const textSettings = languageSettings[langSettingKey]; @@ -518,11 +518,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonSprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true }); this.starterSelectContainer.add(this.pokemonSprite); - this.type1Icon = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`); this.type1Icon.setScale(0.5); + this.type1Icon = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); this.type1Icon.setScale(0.5); this.type1Icon.setOrigin(0, 0); this.starterSelectContainer.add(this.type1Icon); - this.type2Icon = this.scene.add.sprite(26, 98, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`); this.type2Icon.setScale(0.5); + this.type2Icon = this.scene.add.sprite(26, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`); this.type2Icon.setScale(0.5); this.type2Icon.setOrigin(0, 0); this.starterSelectContainer.add(this.type2Icon); diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 32f5bffeb1b..1133e7a755c 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -695,7 +695,7 @@ export default class SummaryUiHandler extends UiHandler { const getTypeIcon = (index: integer, type: Type, tera: boolean = false) => { const xCoord = 39 + 34 * index; const typeIcon = !tera - ? this.scene.add.sprite(xCoord, 42, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`, Type[type].toLowerCase()) : this.scene.add.sprite(xCoord, 42, "type_tera"); + ? this.scene.add.sprite(xCoord, 42, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[type].toLowerCase()) : this.scene.add.sprite(xCoord, 42, "type_tera"); if (tera) { typeIcon.setScale(0.5); const typeRgb = getTypeRgb(type); @@ -897,7 +897,7 @@ export default class SummaryUiHandler extends UiHandler { if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) { this.extraMoveRowContainer.setVisible(true); - const newMoveTypeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`, Type[this.newMove.type].toLowerCase()); + const newMoveTypeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[this.newMove.type].toLowerCase()); newMoveTypeIcon.setOrigin(0, 1); this.extraMoveRowContainer.add(newMoveTypeIcon); @@ -920,7 +920,7 @@ export default class SummaryUiHandler extends UiHandler { this.moveRowsContainer.add(moveRowContainer); if (move) { - const typeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.language) ? `_${i18next.language}` : ""}`, Type[move.getMove().type].toLowerCase()); typeIcon.setOrigin(0, 1); + const typeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[move.getMove().type].toLowerCase()); typeIcon.setOrigin(0, 1); moveRowContainer.add(typeIcon); } diff --git a/src/ui/text.ts b/src/ui/text.ts index 4e76386aae7..56e1b492dfa 100644 --- a/src/ui/text.ts +++ b/src/ui/text.ts @@ -98,7 +98,7 @@ export function addTextInputObject(scene: Phaser.Scene, x: number, y: number, wi } function getTextStyleOptions(style: TextStyle, uiTheme: UiTheme, extraStyleOptions?: Phaser.Types.GameObjects.Text.TextStyle): [ Phaser.Types.GameObjects.Text.TextStyle | InputText.IConfig, string, number, number ] { - const lang = i18next.language; + const lang = i18next.resolvedLanguage; let shadowXpos = 4; let shadowYpos = 5; diff --git a/src/utils.ts b/src/utils.ts index adfe0b0df20..6d965369ca3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -396,7 +396,7 @@ English itself counts as not available export function verifyLang(lang?: string): boolean { //IMPORTANT - ONLY ADD YOUR LANG HERE IF YOU'VE ALREADY ADDED ALL THE NECESSARY IMAGES if (!lang) { - lang = i18next.language; + lang = i18next.resolvedLanguage; } switch (lang) { From eecad0fdc46115ef0d1521398c6781fa06fddd6d Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:39:22 -0400 Subject: [PATCH 08/10] Balance endless tokens (#1733) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Balanced tokens * Remove existing tokens, all 10 stack limit * Linter complained * Sorry Mr. Lint I’ll do better next time * Removed redundant min * Used a version system to update tokens * The linter has peculiar tastes * See if this works * I'm at my limit omg wtf Sam * Call me Swoobat the way I keep it Simple * Clean up some log statements * Adjust token weights to make up for removal of sleep and freeze * Be so fr GitHub that’s not a real merge conflict --- src/locales/de/modifier-type.ts | 4 +--- src/locales/en/modifier-type.ts | 4 +--- src/locales/es/modifier-type.ts | 4 +--- src/locales/fr/modifier-type.ts | 4 +--- src/locales/it/modifier-type.ts | 4 +--- src/locales/ko/modifier-type.ts | 4 +--- src/locales/pt_BR/modifier-type.ts | 4 +--- src/locales/zh_CN/modifier-type.ts | 4 +--- src/locales/zh_TW/modifier-type.ts | 4 +--- src/modifier/modifier-type.ts | 34 +++++++++++++----------------- src/modifier/modifier.ts | 34 ++++++++++++++++++------------ src/system/game-data.ts | 5 +++++ 12 files changed, 50 insertions(+), 59 deletions(-) diff --git a/src/locales/de/modifier-type.ts b/src/locales/de/modifier-type.ts index 055751970ab..9f70c31ca63 100644 --- a/src/locales/de/modifier-type.ts +++ b/src/locales/de/modifier-type.ts @@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_HEAL": { name: "Wiederherstellungsmarke", description: "Heilt 2% der maximalen KP pro Runde" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Giftmarke" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { "name": "Lähmungsmarke" }, - "ENEMY_ATTACK_SLEEP_CHANCE": { "name": "Schlafmarke" }, - "ENEMY_ATTACK_FREEZE_CHANCE": { "name": "Gefriermarke" }, "ENEMY_ATTACK_BURN_CHANCE": { "name": "Brandmarke" }, - "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "name": "Vollheilungsmarke", "description": "Fügt eine 10%ige Chance hinzu, jede Runde einen Statuszustand zu heilen" }, + "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "name": "Vollheilungsmarke", "description": "Fügt eine 2,5%ige Chance hinzu, jede Runde einen Statuszustand zu heilen" }, "ENEMY_ENDURE_CHANCE": { "name": "Ausdauer-Marke" }, "ENEMY_FUSED_CHANCE": { "name": "Fusionsmarke", "description": "Fügt eine 1%ige Chance hinzu, dass ein wildes Pokémon eine Fusion ist" }, diff --git a/src/locales/en/modifier-type.ts b/src/locales/en/modifier-type.ts index e988f0a5250..dac87e1d939 100644 --- a/src/locales/en/modifier-type.ts +++ b/src/locales/en/modifier-type.ts @@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_HEAL": { name: "Recovery Token", description: "Heals 2% of max HP every turn" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Poison Token" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Paralyze Token" }, - "ENEMY_ATTACK_SLEEP_CHANCE": { name: "Sleep Token" }, - "ENEMY_ATTACK_FREEZE_CHANCE": { name: "Freeze Token" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Burn Token" }, - "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Adds a 10% chance every turn to heal a status condition" }, + "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Adds a 2.5% chance every turn to heal a status condition" }, "ENEMY_ENDURE_CHANCE": { name: "Endure Token" }, "ENEMY_FUSED_CHANCE": { name: "Fusion Token", description: "Adds a 1% chance that a wild Pokémon will be a fusion" }, }, diff --git a/src/locales/es/modifier-type.ts b/src/locales/es/modifier-type.ts index e5f77549737..7b5b1e0c90b 100644 --- a/src/locales/es/modifier-type.ts +++ b/src/locales/es/modifier-type.ts @@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_HEAL": { name: "Recovery Token", description: "Cura el 2% de los PS máximo en cada turno" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Poison Token" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Paralyze Token" }, - "ENEMY_ATTACK_SLEEP_CHANCE": { name: "Sleep Token" }, - "ENEMY_ATTACK_FREEZE_CHANCE": { name: "Freeze Token" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Burn Token" }, - "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Agrega un 10% de probabilidad cada turno de curar un problema de estado" }, + "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Agrega un 2.5% de probabilidad cada turno de curar un problema de estado" }, "ENEMY_ENDURE_CHANCE": { name: "Endure Token" }, "ENEMY_FUSED_CHANCE": { name: "Fusion Token", description: "Agrega un 1% de probabilidad de que un Pokémon salvaje sea una fusión" }, }, diff --git a/src/locales/fr/modifier-type.ts b/src/locales/fr/modifier-type.ts index a6960c4f0c5..8315910adb3 100644 --- a/src/locales/fr/modifier-type.ts +++ b/src/locales/fr/modifier-type.ts @@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_HEAL": { name: "Jeton Soin", description: "Soigne 2% des PV max à chaque tour" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Jeton Poison" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Jeton Paralysie" }, - "ENEMY_ATTACK_SLEEP_CHANCE": { name: "Jeton Sommeil" }, - "ENEMY_ATTACK_FREEZE_CHANCE": { name: "Jeton Gel" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Jeton Brulure" }, - "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Jeton Total Soin", description: "Ajoute 10% de chances à chaque tour de se soigner d’un problème de statut." }, + "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Jeton Total Soin", description: "Ajoute 2.5% de chances à chaque tour de se soigner d’un problème de statut." }, "ENEMY_ENDURE_CHANCE": { name: "Jeton Ténacité" }, "ENEMY_FUSED_CHANCE": { name: "Jeton Fusion", description: "Ajoute 1% de chances qu’un Pokémon sauvage soit une fusion." }, }, diff --git a/src/locales/it/modifier-type.ts b/src/locales/it/modifier-type.ts index 668df9601fc..b311aa1e8fa 100644 --- a/src/locales/it/modifier-type.ts +++ b/src/locales/it/modifier-type.ts @@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_HEAL": { name: "Gettone del Recupero", description: "Cura il 2% dei PS massimi ogni turno" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Gettone del Veleno" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Gettone della Paralisi" }, - "ENEMY_ATTACK_SLEEP_CHANCE": { name: "Gettone del Sonno" }, - "ENEMY_ATTACK_FREEZE_CHANCE": { name: "Gettone del Congelamento" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Gettone della Bruciatura" }, - "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Gettone Guarigione Completa", description: "Aggiunge una probabilità del 10% a ogni turno di curare una condizione di stato" }, + "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Gettone Guarigione Completa", description: "Aggiunge una probabilità del 2.5% a ogni turno di curare una condizione di stato" }, "ENEMY_ENDURE_CHANCE": { name: "Gettone di Resistenza" }, "ENEMY_FUSED_CHANCE": { name: "Gettone della fusione", description: "Aggiunge l'1% di possibilità che un Pokémon selvatico sia una fusione" }, }, diff --git a/src/locales/ko/modifier-type.ts b/src/locales/ko/modifier-type.ts index e2d90ed1ff9..5d54018cc96 100644 --- a/src/locales/ko/modifier-type.ts +++ b/src/locales/ko/modifier-type.ts @@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_HEAL": { name: "회복 토큰", description: "매 턴 최대 체력의 2%를 회복" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "독 토큰" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "마비 토큰" }, - "ENEMY_ATTACK_SLEEP_CHANCE": { name: "잠듦 토큰" }, - "ENEMY_ATTACK_FREEZE_CHANCE": { name: "얼음 토큰" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "화상 토큰" }, - "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "만병통치 토큰", description: "매 턴 상태이상에서 회복될 확률 10% 추가" }, + "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "만병통치 토큰", description: "매 턴 상태이상에서 회복될 확률 2.5% 추가" }, "ENEMY_ENDURE_CHANCE": { name: "버티기 토큰" }, "ENEMY_FUSED_CHANCE": { name: "합체 토큰", description: "야생 포켓몬이 합체할 확률 1% 추가" }, }, diff --git a/src/locales/pt_BR/modifier-type.ts b/src/locales/pt_BR/modifier-type.ts index ea384282f15..4865cfb64a2 100644 --- a/src/locales/pt_BR/modifier-type.ts +++ b/src/locales/pt_BR/modifier-type.ts @@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_HEAL": { name: "Token de Recuperação", description: "Cura 2% dos PS máximos a cada turno" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Token de Veneno" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "Token de Paralisia" }, - "ENEMY_ATTACK_SLEEP_CHANCE": { name: "Token de Sono" }, - "ENEMY_ATTACK_FREEZE_CHANCE": { name: "Token de Congelamento" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "Token de Queimadura" }, - "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Token de Cura Total", description: "Adiciona uma chance de 10% a cada turno de curar uma condição de status" }, + "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Token de Cura Total", description: "Adiciona uma chance de 2.5% a cada turno de curar uma condição de status" }, "ENEMY_ENDURE_CHANCE": { name: "Token de Persistência" }, "ENEMY_FUSED_CHANCE": { name: "Token de Fusão", description: "Adiciona uma chance de 1% de que um Pokémon selvagem seja uma fusão" }, }, diff --git a/src/locales/zh_CN/modifier-type.ts b/src/locales/zh_CN/modifier-type.ts index c51ce2cd788..7230f21e330 100644 --- a/src/locales/zh_CN/modifier-type.ts +++ b/src/locales/zh_CN/modifier-type.ts @@ -230,10 +230,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_HEAL": { name: "回复硬币", description: "每回合回复2%最大HP" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "剧毒硬币" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { name: "麻痹硬币" }, - "ENEMY_ATTACK_SLEEP_CHANCE": { name: "睡眠硬币" }, - "ENEMY_ATTACK_FREEZE_CHANCE": { name: "冰冻硬币" }, "ENEMY_ATTACK_BURN_CHANCE": { name: "灼烧硬币" }, - "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "万灵药硬币", description: "增加10%每回合治愈异常状态的概率" }, + "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "万灵药硬币", description: "增加2.5%每回合治愈异常状态的概率" }, "ENEMY_ENDURE_CHANCE": { name: "忍受硬币" }, "ENEMY_FUSED_CHANCE": { name: "融合硬币", description: "增加1%野生融合宝可梦出现概率" }, }, diff --git a/src/locales/zh_TW/modifier-type.ts b/src/locales/zh_TW/modifier-type.ts index 854e65212f4..1ad51965937 100644 --- a/src/locales/zh_TW/modifier-type.ts +++ b/src/locales/zh_TW/modifier-type.ts @@ -282,12 +282,10 @@ export const modifierType: ModifierTypeTranslationEntries = { ENEMY_HEAL: { name: "恢復硬幣", description: "每回合恢復2%最大HP" }, ENEMY_ATTACK_POISON_CHANCE: { name: "劇毒硬幣" }, ENEMY_ATTACK_PARALYZE_CHANCE: { name: "麻痹硬幣" }, - ENEMY_ATTACK_SLEEP_CHANCE: { name: "睡眠硬幣" }, - ENEMY_ATTACK_FREEZE_CHANCE: { name: "冰凍硬幣" }, ENEMY_ATTACK_BURN_CHANCE: { name: "灼燒硬幣" }, ENEMY_STATUS_EFFECT_HEAL_CHANCE: { name: "萬靈藥硬幣", - description: "增加10%每回合治癒異常狀態的概率", + description: "增加2.5%每回合治癒異常狀態的概率", }, ENEMY_ENDURE_CHANCE: { name: "忍受硬幣" }, ENEMY_FUSED_CHANCE: { diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 59185811590..5f1fb1d2956 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -978,8 +978,8 @@ export class EnemyAttackStatusEffectChanceModifierType extends ModifierType { private chancePercent: integer; private effect: StatusEffect; - constructor(localeKey: string, iconImage: string, chancePercent: integer, effect: StatusEffect) { - super(localeKey, iconImage, (type, args) => new Modifiers.EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent), "enemy_status_chance"); + constructor(localeKey: string, iconImage: string, chancePercent: integer, effect: StatusEffect, stackCount?: integer) { + super(localeKey, iconImage, (type, args) => new Modifiers.EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent, stackCount), "enemy_status_chance"); this.chancePercent = chancePercent; this.effect = effect; @@ -1216,14 +1216,12 @@ export const modifierTypes = { ENEMY_DAMAGE_BOOSTER: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_BOOSTER", "wl_item_drop", (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5)), ENEMY_DAMAGE_REDUCTION: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_REDUCTION", "wl_guard_spec", (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5)), //ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'), - ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2)), - ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_POISON_CHANCE", "wl_antidote", 10, StatusEffect.POISON), - ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_PARALYZE_CHANCE", "wl_paralyze_heal", 10, StatusEffect.PARALYSIS), - ENEMY_ATTACK_SLEEP_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_SLEEP_CHANCE", "wl_awakening", 10, StatusEffect.SLEEP), - ENEMY_ATTACK_FREEZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_FREEZE_CHANCE", "wl_ice_heal", 10, StatusEffect.FREEZE), - ENEMY_ATTACK_BURN_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_BURN_CHANCE", "wl_burn_heal", 10, StatusEffect.BURN), - ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new Modifiers.EnemyStatusEffectHealChanceModifier(type, 10)), - ENEMY_ENDURE_CHANCE: () => new EnemyEndureChanceModifierType("modifierType:ModifierType.ENEMY_ENDURE_CHANCE", "wl_reset_urge", 2.5), + ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2, 10)), + ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_POISON_CHANCE", "wl_antidote", 5, StatusEffect.POISON, 10), + ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_PARALYZE_CHANCE", "wl_paralyze_heal", 2.5, StatusEffect.PARALYSIS, 10), + ENEMY_ATTACK_BURN_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_BURN_CHANCE", "wl_burn_heal", 5, StatusEffect.BURN, 10), + ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new Modifiers.EnemyStatusEffectHealChanceModifier(type, 2.5, 10)), + ENEMY_ENDURE_CHANCE: () => new EnemyEndureChanceModifierType("modifierType:ModifierType.ENEMY_ENDURE_CHANCE", "wl_reset_urge", 2), ENEMY_FUSED_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_FUSED_CHANCE", "wl_custom_spliced", (type, _args) => new Modifiers.EnemyFusionChanceModifier(type, 1)), }; @@ -1466,15 +1464,13 @@ const trainerModifierPool: ModifierPool = { const enemyBuffModifierPool: ModifierPool = { [ModifierTier.COMMON]: [ - new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 10), - new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 10), - new WeightedModifierType(modifierTypes.ENEMY_ATTACK_POISON_CHANCE, 2), - new WeightedModifierType(modifierTypes.ENEMY_ATTACK_PARALYZE_CHANCE, 2), - new WeightedModifierType(modifierTypes.ENEMY_ATTACK_SLEEP_CHANCE, 2), - new WeightedModifierType(modifierTypes.ENEMY_ATTACK_FREEZE_CHANCE, 2), - new WeightedModifierType(modifierTypes.ENEMY_ATTACK_BURN_CHANCE, 2), - new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 10), - new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 5), + new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 9), + new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 9), + new WeightedModifierType(modifierTypes.ENEMY_ATTACK_POISON_CHANCE, 3), + new WeightedModifierType(modifierTypes.ENEMY_ATTACK_PARALYZE_CHANCE, 3), + new WeightedModifierType(modifierTypes.ENEMY_ATTACK_BURN_CHANCE, 3), + new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 9), + new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 4), new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1) ].map(m => { m.setTier(ModifierTier.COMMON); return m; diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 975420ab528..8b2d12d89a0 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -2141,7 +2141,7 @@ export class EnemyDamageReducerModifier extends EnemyDamageMultiplierModifier { } export class EnemyTurnHealModifier extends EnemyPersistentModifier { - private healPercent: number; + public healPercent: number; constructor(type: ModifierType, healPercent: number, stackCount?: integer) { super(type, stackCount); @@ -2176,23 +2176,23 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifier { } getMaxStackCount(scene: BattleScene): integer { - return 15; + return 10; } } export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifier { public effect: StatusEffect; - private chance: number; + public chance: number; constructor(type: ModifierType, effect: StatusEffect, chancePercent: number, stackCount?: integer) { super(type, stackCount); this.effect = effect; - this.chance = (chancePercent || 10) / 100; + this.chance = (chancePercent || 5) / 100; } match(modifier: Modifier): boolean { - return modifier instanceof EnemyAttackStatusEffectChanceModifier && modifier.effect === this.effect && modifier.chance === this.chance; + return modifier instanceof EnemyAttackStatusEffectChanceModifier && modifier.effect === this.effect; } clone(): EnemyAttackStatusEffectChanceModifier { @@ -2211,19 +2211,23 @@ export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifi return false; } + + getMaxStackCount(scene: BattleScene): integer { + return 10; + } } export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier { - private chance: number; + public chance: number; constructor(type: ModifierType, chancePercent: number, stackCount?: integer) { super(type, stackCount); - this.chance = (chancePercent || 10) / 100; + this.chance = (chancePercent || 2.5) / 100; } match(modifier: Modifier): boolean { - return modifier instanceof EnemyStatusEffectHealChanceModifier && modifier.chance === this.chance; + return modifier instanceof EnemyStatusEffectHealChanceModifier; } clone(): EnemyStatusEffectHealChanceModifier { @@ -2245,19 +2249,23 @@ export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier return false; } + + getMaxStackCount(scene: BattleScene): integer { + return 10; + } } export class EnemyEndureChanceModifier extends EnemyPersistentModifier { - private chance: number; + public chance: number; - constructor(type: ModifierType, chancePercent: number, stackCount?: integer) { - super(type, stackCount); + constructor(type: ModifierType, chancePercent?: number, stackCount?: integer) { + super(type, stackCount || 10); - this.chance = (chancePercent || 2.5) / 100; + this.chance = (chancePercent || 2) / 100; } match(modifier: Modifier) { - return modifier instanceof EnemyEndureChanceModifier && modifier.chance === this.chance; + return modifier instanceof EnemyEndureChanceModifier; } clone() { diff --git a/src/system/game-data.ts b/src/system/game-data.ts index ec4a814b643..0b81c4014b5 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -34,6 +34,8 @@ import {setSettingGamepad, SettingGamepad, settingGamepadDefaults} from "./setti import {setSettingKeyboard, SettingKeyboard} from "#app/system/settings/settings-keyboard"; import { TerrainChangedEvent, WeatherChangedEvent } from "#app/field/arena-events.js"; import { Device } from "#app/enums/devices.js"; +import { EnemyAttackStatusEffectChanceModifier } from "../modifier/modifier"; +import { StatusEffect } from "#app/data/status-effect.js"; const saveKey = "x0i2O7WRiANTqPmZ"; // Temporary; secure encryption is not yet necessary @@ -1078,6 +1080,9 @@ export class GameData { if (md?.className === "ExpBalanceModifier") { // Temporarily limit EXP Balance until it gets reworked md.stackCount = Math.min(md.stackCount, 4); } + if (md instanceof EnemyAttackStatusEffectChanceModifier && md.effect === StatusEffect.FREEZE || md.effect === StatusEffect.SLEEP) { + continue; + } ret.push(new PersistentModifierData(md, player)); } return ret; From d04010226d8d02f1c288abafc33da45b149c90de Mon Sep 17 00:00:00 2001 From: Benjamin Odom Date: Tue, 4 Jun 2024 16:59:39 -0500 Subject: [PATCH 09/10] [Bug] Fix Leppa Berries not Updating Flyout PP (#1806) * Fix Leppa Berries not Updating Flyout PP * Code Cleanup * Update battle-flyout.ts --- src/battle-scene-events.ts | 26 ++++++++++++++++++++-- src/phases.ts | 3 ++- src/ui/arena-flyout.ts | 10 ++++----- src/ui/battle-flyout.ts | 45 +++++++++++++++++++++++++++++--------- 4 files changed, 66 insertions(+), 18 deletions(-) diff --git a/src/battle-scene-events.ts b/src/battle-scene-events.ts index 128fd5b5ceb..74fac97d2b7 100644 --- a/src/battle-scene-events.ts +++ b/src/battle-scene-events.ts @@ -1,4 +1,5 @@ import Move from "./data/move"; +import { BerryModifier } from "./modifier/modifier"; /** Alias for all {@linkcode BattleScene} events */ export enum BattleSceneEventType { @@ -13,6 +14,12 @@ export enum BattleSceneEventType { * @see {@linkcode MoveUsedEvent} */ MOVE_USED = "onMoveUsed", + /** + * Triggers when a berry gets successfully used + * @see {@linkcode BerryUsedEvent} + */ + BERRY_USED = "onBerryUsed", + /** * Triggers on the first turn of a new battle * @see {@linkcode TurnInitEvent} @@ -23,6 +30,7 @@ export enum BattleSceneEventType { * @see {@linkcode TurnEndEvent} */ TURN_END = "onTurnEnd", + /** * Triggers when a new {@linkcode Arena} is created during initialization * @see {@linkcode NewArenaEvent} @@ -50,7 +58,7 @@ export class CandyUpgradeNotificationChangedEvent extends Event { */ export class MoveUsedEvent extends Event { /** The ID of the {@linkcode Pokemon} that used the {@linkcode Move} */ - public userId: number; + public pokemonId: number; /** The {@linkcode Move} used */ public move: Move; /** The amount of PP used on the {@linkcode Move} this turn */ @@ -58,11 +66,25 @@ export class MoveUsedEvent extends Event { constructor(userId: number, move: Move, ppUsed: number) { super(BattleSceneEventType.MOVE_USED); - this.userId = userId; + this.pokemonId = userId; this.move = move; this.ppUsed = ppUsed; } } +/** + * Container class for {@linkcode BattleSceneEventType.BERRY_USED} events + * @extends Event +*/ +export class BerryUsedEvent extends Event { + /** The {@linkcode BerryModifier} being used */ + public berryModifier: BerryModifier; + constructor(berry: BerryModifier) { + super(BattleSceneEventType.BERRY_USED); + + this.berryModifier = berry; + } +} + /** * Container class for {@linkcode BattleSceneEventType.TURN_INIT} events * @extends Event diff --git a/src/phases.ts b/src/phases.ts index 110c4155849..c9c93ab414d 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -61,7 +61,7 @@ import { Abilities } from "./data/enums/abilities"; import * as Overrides from "./overrides"; import { TextStyle, addTextObject } from "./ui/text"; import { Type } from "./data/type"; -import { MoveUsedEvent, TurnEndEvent, TurnInitEvent } from "./battle-scene-events"; +import { BerryUsedEvent, MoveUsedEvent, TurnEndEvent, TurnInitEvent } from "./battle-scene-events"; export class LoginPhase extends Phase { @@ -2244,6 +2244,7 @@ export class BerryPhase extends FieldPhase { berryModifier.consumed = false; } } + this.scene.eventTarget.dispatchEvent(new BerryUsedEvent(berryModifier)); // Announce a berry was used } this.scene.updateModifiers(pokemon.isPlayer()); diff --git a/src/ui/arena-flyout.ts b/src/ui/arena-flyout.ts index 73660ca4457..77996625fed 100644 --- a/src/ui/arena-flyout.ts +++ b/src/ui/arena-flyout.ts @@ -81,11 +81,11 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { private readonly fieldEffectInfo: ArenaEffectInfo[] = []; // Stores callbacks in a variable so they can be unsubscribed from when destroyed - private onNewArenaEvent = (event: Event) => this.onNewArena(event); - private onTurnInitEvent = (event: Event) => this.onTurnInit(event); - private onTurnEndEvent = (event: Event) => this.onTurnEnd(event); + private readonly onNewArenaEvent = (event: Event) => this.onNewArena(event); + private readonly onTurnInitEvent = (event: Event) => this.onTurnInit(event); + private readonly onTurnEndEvent = (event: Event) => this.onTurnEnd(event); - private onFieldEffectChangedEvent = (event: Event) => this.onFieldEffectChanged(event); + private readonly onFieldEffectChangedEvent = (event: Event) => this.onFieldEffectChanged(event); constructor(scene: Phaser.Scene) { super(scene, 0, 0); @@ -379,6 +379,6 @@ export default class ArenaFlyout extends Phaser.GameObjects.Container { this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.TAG_ADDED, this.onFieldEffectChangedEvent); this.battleScene.arena.eventTarget.removeEventListener(ArenaEventType.TAG_REMOVED, this.onFieldEffectChangedEvent); - super.destroy(); + super.destroy(fromScene); } } diff --git a/src/ui/battle-flyout.ts b/src/ui/battle-flyout.ts index 3add54920b0..9a9e3ef46a9 100644 --- a/src/ui/battle-flyout.ts +++ b/src/ui/battle-flyout.ts @@ -4,7 +4,9 @@ import * as Utils from "../utils"; import BattleScene from "#app/battle-scene.js"; import { UiTheme } from "#app/enums/ui-theme.js"; import Move from "#app/data/move.js"; -import { BattleSceneEventType, MoveUsedEvent } from "#app/battle-scene-events.js"; +import { BattleSceneEventType, BerryUsedEvent, MoveUsedEvent } from "#app/battle-scene-events.js"; +import { BerryType } from "#app/data/enums/berry-type.js"; +import { Moves } from "#app/data/enums/moves.js"; /** Container for info about a {@linkcode Move} */ interface MoveInfo { @@ -53,7 +55,9 @@ export default class BattleFlyout extends Phaser.GameObjects.Container { /** The array of {@linkcode MoveInfo} used to track moves for the {@linkcode Pokemon} linked to the flyout */ private moveInfo: MoveInfo[] = new Array(); - private readonly onMoveUsed = (event) => this.updateInfo(event); + // Stores callbacks in a variable so they can be unsubscribed from when destroyed + private readonly onMoveUsedEvent = (event: Event) => this.onMoveUsed(event); + private readonly onBerryUsedEvent = (event: Event) => this.onBerryUsed(event); constructor(scene: Phaser.Scene, player: boolean) { super(scene, 0, 0); @@ -109,11 +113,12 @@ export default class BattleFlyout extends Phaser.GameObjects.Container { this.name = `Flyout ${this.pokemon.name}`; this.flyoutParent.name = `Flyout Parent ${this.pokemon.name}`; - this.battleScene.eventTarget.addEventListener(BattleSceneEventType.MOVE_USED, this.onMoveUsed); + this.battleScene.eventTarget.addEventListener(BattleSceneEventType.MOVE_USED, this.onMoveUsedEvent); + this.battleScene.eventTarget.addEventListener(BattleSceneEventType.BERRY_USED, this.onBerryUsedEvent); } /** Sets and formats the text property for all {@linkcode Phaser.GameObjects.Text} in the flyoutText array */ - setText() { + private setText() { for (let i = 0; i < this.flyoutText.length; i++) { const flyoutText = this.flyoutText[i]; const moveInfo = this.moveInfo[i]; @@ -122,21 +127,23 @@ export default class BattleFlyout extends Phaser.GameObjects.Container { continue; } - const currentPp = Math.max(moveInfo.maxPp - moveInfo.ppUsed, 0); + const currentPp = moveInfo.maxPp - moveInfo.ppUsed; flyoutText.text = `${moveInfo.move.name} ${currentPp}/${moveInfo.maxPp}`; } } /** Updates all of the {@linkcode MoveInfo} objects in the moveInfo array */ - updateInfo(event: Event) { + private onMoveUsed(event: Event) { const moveUsedEvent = event as MoveUsedEvent; - if (!moveUsedEvent || moveUsedEvent.userId !== this.pokemon?.id) { + if (!moveUsedEvent + || moveUsedEvent.pokemonId !== this.pokemon?.id + || moveUsedEvent.move.id === Moves.STRUGGLE) { // Ignore Struggle return; } const foundInfo = this.moveInfo.find(x => x?.move.id === moveUsedEvent.move.id); if (foundInfo) { - foundInfo.ppUsed += moveUsedEvent.ppUsed; + foundInfo.ppUsed = Math.min(foundInfo.ppUsed + moveUsedEvent.ppUsed, foundInfo.maxPp); } else { this.moveInfo.push({move: moveUsedEvent.move, maxPp: moveUsedEvent.move.pp, ppUsed: moveUsedEvent.ppUsed}); } @@ -144,6 +151,23 @@ export default class BattleFlyout extends Phaser.GameObjects.Container { this.setText(); } + private onBerryUsed(event: Event) { + const berryUsedEvent = event as BerryUsedEvent; + if (!berryUsedEvent + || berryUsedEvent.berryModifier.pokemonId !== this.pokemon?.id + || berryUsedEvent.berryModifier.berryType !== BerryType.LEPPA) { // We only care about Leppa berries + return; + } + + const foundInfo = this.moveInfo.find(info => info.ppUsed === info.maxPp); + if (!foundInfo) { // This will only happen on a de-sync of PP tracking + return; + } + foundInfo.ppUsed = Math.max(foundInfo.ppUsed - 10, 0); + + this.setText(); + } + /** Animates the flyout to either show or hide it by applying a fade and translation */ toggleFlyout(visible: boolean): void { this.scene.tweens.add({ @@ -156,8 +180,9 @@ export default class BattleFlyout extends Phaser.GameObjects.Container { } destroy(fromScene?: boolean): void { - this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.MOVE_USED, this.onMoveUsed); + this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.MOVE_USED, this.onMoveUsedEvent); + this.battleScene.eventTarget.removeEventListener(BattleSceneEventType.BERRY_USED, this.onBerryUsedEvent); - super.destroy(); + super.destroy(fromScene); } } From 48f60a5b50f6222448823f6c8da4bc43e00bf5ef Mon Sep 17 00:00:00 2001 From: Adrian T <68144167+torranx@users.noreply.github.com> Date: Wed, 5 Jun 2024 06:11:30 +0800 Subject: [PATCH 10/10] [QoL] add message when quick claw is triggered (#1684) --- src/modifier/modifier.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 8b2d12d89a0..28bf2f61c75 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -776,6 +776,9 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier { if (!bypassSpeed.value && pokemon.randSeedInt(10) < this.getStackCount()) { bypassSpeed.value = true; + if (this.type instanceof ModifierTypes.PokemonHeldItemModifierType && this.type.id === "QUICK_CLAW") { + pokemon.scene.queueMessage(getPokemonMessage(pokemon, " used its quick claw to move faster!")); + } return true; }