From bb88fd6d11231e11ac71c7ae2cb2a67b6fdd6cce Mon Sep 17 00:00:00 2001 From: geeil-han Date: Wed, 15 Jan 2025 10:08:49 +0100 Subject: [PATCH 1/7] implementation of rage fist --- src/data/custom-pokemon-data.ts | 10 +- src/data/move.ts | 28 ++++- src/field/pokemon.ts | 5 + src/phases/encounter-phase.ts | 6 + src/phases/new-biome-encounter-phase.ts | 1 + src/test/moves/rage_fist.test.ts | 156 ++++++++++++++++++++++++ 6 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 src/test/moves/rage_fist.test.ts diff --git a/src/data/custom-pokemon-data.ts b/src/data/custom-pokemon-data.ts index 1c3bbbc3180..55b06db5179 100644 --- a/src/data/custom-pokemon-data.ts +++ b/src/data/custom-pokemon-data.ts @@ -5,7 +5,8 @@ import type { Nature } from "#enums/nature"; /** * Data that can customize a Pokemon in non-standard ways from its Species - * Currently only used by Mystery Encounters and Mints. + * Used by Mystery Encounters and Mints + * Also used as a counter how often a Pokemon got hit until new arena encounter */ export class CustomPokemonData { public spriteScale: number; @@ -13,6 +14,8 @@ export class CustomPokemonData { public passive: Abilities | -1; public nature: Nature | -1; public types: Type[]; + //hitsRecivedCount aka hitsRecCount saves how often the pokemon got hit until a new arena encounter (used for Rage Fist) + public hitsRecCount: number; constructor(data?: CustomPokemonData | Partial) { if (!isNullOrUndefined(data)) { @@ -24,5 +27,10 @@ export class CustomPokemonData { this.passive = this.passive ?? -1; this.nature = this.nature ?? -1; this.types = this.types ?? []; + this.hitsRecCount = this.hitsRecCount ?? 0; + } + + resetHitRecivedCount(): void { + this.hitsRecCount = 0; } } diff --git a/src/data/move.ts b/src/data/move.ts index f3a1f3aa119..956dbe702ba 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -3993,12 +3993,34 @@ export class FriendshipPowerAttr extends VariablePowerAttr { } } -export class HitCountPowerAttr extends VariablePowerAttr { +/** + * This Attribute calculates the current power of {@linkcode Moves.RAGE_FIST} + * The counter for power calculation does not reset on every wave but on every new arena encounter + */ +export class RageFistPowerAttr extends VariablePowerAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - (args[0] as Utils.NumberHolder).value += Math.min(user.battleData.hitCount, 6) * 50; + const BDHitCount = user.battleData.hitCount; + const previousHitCount = user.battleData.prevHitCount; + + this.updateHitRecivedCount(user, BDHitCount, previousHitCount); + + console.log(`GHNote hitsRecCount: ${user.customPokemonData.hitsRecCount}`); + + (args[0] as Utils.NumberHolder).value = 50 + (Math.min(user.customPokemonData.hitsRecCount, 6) * 50); return true; } + + /** + * Updates the hitCount of recived hits during this arena encounter + * @param user Pokemon calling Rage Fist + * @param BDHitCount The hitCount of reviced hits this battle up until the function is called + * @param previousHitCount The hitCount of reviced hits this battle the last time Rage Fist was called + */ + updateHitRecivedCount(user: Pokemon, BDHitCount: number, previousHitCount: number): void { + user.customPokemonData.hitsRecCount += (BDHitCount - previousHitCount); + user.battleData.prevHitCount = BDHitCount; + } } /** @@ -11004,7 +11026,7 @@ export function initMoves() { .attr(MultiHitAttr, MultiHitType._2), new AttackMove(Moves.RAGE_FIST, Type.GHOST, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 9) .partial() // Counter resets every wave instead of on arena reset - .attr(HitCountPowerAttr) + .attr(RageFistPowerAttr) .punchingMove(), new AttackMove(Moves.ARMOR_CANNON, Type.FIRE, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9) .attr(StatStageChangeAttr, [ Stat.DEF, Stat.SPDEF ], -1, true), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8fc00e2ebeb..1e377e70291 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -5281,7 +5281,12 @@ export class PokemonSummonData { } export class PokemonBattleData { + //counts the hits the pokemon recived public hitCount: number = 0; + /** + * used for {@linkcode Moves.RAGE_FIST} in order to save hit Counts recived before Rage Fist is applied + */ + public prevHitCount: number = 0; public endured: boolean = false; public berriesEaten: BerryType[] = []; public abilitiesApplied: Abilities[] = []; diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 6dae7dff8f9..2083f09896a 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -104,6 +104,12 @@ export class EncounterPhase extends BattlePhase { } if (!this.loaded) { if (battle.battleType === BattleType.TRAINER) { + //resets hitRecCount during Trainer ecnounter + for (const pokemon of globalScene.getPlayerParty()) { + if (pokemon) { + pokemon.customPokemonData.resetHitRecivedCount(); + } + } battle.enemyParty[e] = battle.trainer?.genPartyMember(e)!; // TODO:: is the bang correct here? } else { let enemySpecies = globalScene.randomSpecies(battle.waveIndex, level, true); diff --git a/src/phases/new-biome-encounter-phase.ts b/src/phases/new-biome-encounter-phase.ts index be6815333e5..b0a7bf4d1ae 100644 --- a/src/phases/new-biome-encounter-phase.ts +++ b/src/phases/new-biome-encounter-phase.ts @@ -14,6 +14,7 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase { for (const pokemon of globalScene.getPlayerParty()) { if (pokemon) { pokemon.resetBattleData(); + pokemon.customPokemonData.resetHitRecivedCount(); } } diff --git a/src/test/moves/rage_fist.test.ts b/src/test/moves/rage_fist.test.ts new file mode 100644 index 00000000000..61f612eddd4 --- /dev/null +++ b/src/test/moves/rage_fist.test.ts @@ -0,0 +1,156 @@ +import { BattlerIndex } from "#app/battle"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { allMoves } from "#app/data/move"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Moves - Rage Fist", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .battleType("single") + .moveset([ Moves.RAGE_FIST, Moves.SPLASH, Moves.SUBSTITUTE ]) + .startingLevel(100) + .enemyLevel(1) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.DOUBLE_KICK); + }); + + it("should have 100 more power if hit twice before calling Rage Fist", async () => { + game.override + .enemySpecies(Species.MAGIKARP); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const move = allMoves[Moves.RAGE_FIST]; + vi.spyOn(move, "calculateBattlePower"); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + }); + + it("should maintain its power during next battle if it is within the same arena encounter", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(1); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const move = allMoves[Moves.RAGE_FIST]; + vi.spyOn(move, "calculateBattlePower"); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextWave(); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(move.calculateBattlePower).toHaveLastReturnedWith(250); + }); + + it("should reset the hitRecCounter if we enter new trainer battle", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(4); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const move = allMoves[Moves.RAGE_FIST]; + vi.spyOn(move, "calculateBattlePower"); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextWave(); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + }); + + it("should not increase the hitCounter if Substitute is hit", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(4); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const move = allMoves[Moves.RAGE_FIST]; + vi.spyOn(move, "calculateBattlePower"); + + game.move.select(Moves.SUBSTITUTE); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + expect(game.scene.getPlayerPokemon()?.customPokemonData.hitsRecCount).toBe(0); + }); + + //For some unknown reason the second Rage fist is not called. This might be due to entering a new biome + it.todo("should reset the hitRecCounter if we enter new biome", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(10); + + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const move = allMoves[Moves.RAGE_FIST]; + vi.spyOn(move, "calculateBattlePower"); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextWave(); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("BerryPhase", false); + + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + }); + + //Test does not work correctly. Feel free to add changes if you can make it work + it.todo("should not reset the hitRecCounter if switched out", async () => { + game.override + .enemySpecies(Species.MAGIKARP) + .startingWave(1); + + await game.classicMode.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); + + const move = allMoves[Moves.RAGE_FIST]; + vi.spyOn(move, "calculateBattlePower"); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + game.doSelectPartyPokemon(1); + await game.toNextWave(); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + game.doSelectPartyPokemon(0); + await game.phaseInterceptor.to("CommandPhase"); + + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(Species.CHARIZARD); + }); +}); From fb7925061cd53362ec8dedc71671184a702ed303 Mon Sep 17 00:00:00 2001 From: geeilhan <107366005+geeilhan@users.noreply.github.com> Date: Sat, 18 Jan 2025 12:14:29 +0100 Subject: [PATCH 2/7] Apply suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/custom-pokemon-data.ts | 2 +- src/field/pokemon.ts | 6 ++---- src/test/moves/rage_fist.test.ts | 21 +++------------------ 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/src/data/custom-pokemon-data.ts b/src/data/custom-pokemon-data.ts index 55b06db5179..849b9e9f237 100644 --- a/src/data/custom-pokemon-data.ts +++ b/src/data/custom-pokemon-data.ts @@ -14,7 +14,7 @@ export class CustomPokemonData { public passive: Abilities | -1; public nature: Nature | -1; public types: Type[]; - //hitsRecivedCount aka hitsRecCount saves how often the pokemon got hit until a new arena encounter (used for Rage Fist) + /** `hitsReceivedCount` aka `hitsRecCount` saves how often the pokemon got hit until a new arena encounter (used for Rage Fist) */ public hitsRecCount: number; constructor(data?: CustomPokemonData | Partial) { diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 1e377e70291..e9142df5eb0 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -5281,11 +5281,9 @@ export class PokemonSummonData { } export class PokemonBattleData { - //counts the hits the pokemon recived + /** counts the hits the pokemon received */ public hitCount: number = 0; - /** - * used for {@linkcode Moves.RAGE_FIST} in order to save hit Counts recived before Rage Fist is applied - */ + /** used for {@linkcode Moves.RAGE_FIST} in order to save hit Counts received before Rage Fist is applied */ public prevHitCount: number = 0; public endured: boolean = false; public berriesEaten: BerryType[] = []; diff --git a/src/test/moves/rage_fist.test.ts b/src/test/moves/rage_fist.test.ts index 61f612eddd4..7235b5e8ddf 100644 --- a/src/test/moves/rage_fist.test.ts +++ b/src/test/moves/rage_fist.test.ts @@ -10,6 +10,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite describe("Moves - Rage Fist", () => { let phaserGame: Phaser.Game; let game: GameManager; + const move = allMoves[Moves.RAGE_FIST]; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -30,6 +31,8 @@ describe("Moves - Rage Fist", () => { .enemyLevel(1) .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.DOUBLE_KICK); + + vi.spyOn(move, "calculateBattlePower"); }); it("should have 100 more power if hit twice before calling Rage Fist", async () => { @@ -38,9 +41,6 @@ describe("Moves - Rage Fist", () => { await game.classicMode.startBattle([ Species.MAGIKARP ]); - const move = allMoves[Moves.RAGE_FIST]; - vi.spyOn(move, "calculateBattlePower"); - game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("TurnEndPhase"); @@ -55,9 +55,6 @@ describe("Moves - Rage Fist", () => { await game.classicMode.startBattle([ Species.MAGIKARP ]); - const move = allMoves[Moves.RAGE_FIST]; - vi.spyOn(move, "calculateBattlePower"); - game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextWave(); @@ -76,9 +73,6 @@ describe("Moves - Rage Fist", () => { await game.classicMode.startBattle([ Species.MAGIKARP ]); - const move = allMoves[Moves.RAGE_FIST]; - vi.spyOn(move, "calculateBattlePower"); - game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextWave(); @@ -97,9 +91,6 @@ describe("Moves - Rage Fist", () => { await game.classicMode.startBattle([ Species.MAGIKARP ]); - const move = allMoves[Moves.RAGE_FIST]; - vi.spyOn(move, "calculateBattlePower"); - game.move.select(Moves.SUBSTITUTE); await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); await game.phaseInterceptor.to("MoveEffectPhase"); @@ -115,9 +106,6 @@ describe("Moves - Rage Fist", () => { await game.classicMode.startBattle([ Species.MAGIKARP ]); - const move = allMoves[Moves.RAGE_FIST]; - vi.spyOn(move, "calculateBattlePower"); - game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); await game.toNextWave(); @@ -137,9 +125,6 @@ describe("Moves - Rage Fist", () => { await game.classicMode.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); - const move = allMoves[Moves.RAGE_FIST]; - vi.spyOn(move, "calculateBattlePower"); - game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); game.doSelectPartyPokemon(1); From 1345eec3fa2cde096d3e5384773660fe6f83e80d Mon Sep 17 00:00:00 2001 From: geeilhan <107366005+geeilhan@users.noreply.github.com> Date: Sat, 18 Jan 2025 12:33:08 +0100 Subject: [PATCH 3/7] Update src/test/moves/rage_fist.test.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/test/moves/rage_fist.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/moves/rage_fist.test.ts b/src/test/moves/rage_fist.test.ts index 7235b5e8ddf..75533e2b2c6 100644 --- a/src/test/moves/rage_fist.test.ts +++ b/src/test/moves/rage_fist.test.ts @@ -108,7 +108,7 @@ describe("Moves - Rage Fist", () => { game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); - await game.toNextWave(); + await game.toNextTurn(); game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); From eb9ac890a645217278cd6257b8aa38d248dc9634 Mon Sep 17 00:00:00 2001 From: geeil-han Date: Sat, 18 Jan 2025 13:22:43 +0100 Subject: [PATCH 4/7] added removed TODO from some test cases --- src/test/moves/rage_fist.test.ts | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/test/moves/rage_fist.test.ts b/src/test/moves/rage_fist.test.ts index 75533e2b2c6..a85be5a88d9 100644 --- a/src/test/moves/rage_fist.test.ts +++ b/src/test/moves/rage_fist.test.ts @@ -98,8 +98,7 @@ describe("Moves - Rage Fist", () => { expect(game.scene.getPlayerPokemon()?.customPokemonData.hitsRecCount).toBe(0); }); - //For some unknown reason the second Rage fist is not called. This might be due to entering a new biome - it.todo("should reset the hitRecCounter if we enter new biome", async () => { + it("should reset the hitRecCounter if we enter new biome", async () => { game.override .enemySpecies(Species.MAGIKARP) .startingWave(10); @@ -117,25 +116,28 @@ describe("Moves - Rage Fist", () => { expect(move.calculateBattlePower).toHaveLastReturnedWith(150); }); - //Test does not work correctly. Feel free to add changes if you can make it work - it.todo("should not reset the hitRecCounter if switched out", async () => { + it("should not reset the hitRecCounter if switched out", async () => { game.override .enemySpecies(Species.MAGIKARP) - .startingWave(1); + .startingWave(1) + .enemyMoveset(Moves.TACKLE); await game.classicMode.startBattle([ Species.CHARIZARD, Species.BLASTOISE ]); - game.move.select(Moves.RAGE_FIST); + game.move.select(Moves.SPLASH); await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); - game.doSelectPartyPokemon(1); - await game.toNextWave(); + await game.toNextTurn(); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + game.doSwitchPokemon(1); + await game.toNextTurn(); game.move.select(Moves.RAGE_FIST); - await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); - game.doSelectPartyPokemon(0); - await game.phaseInterceptor.to("CommandPhase"); + await game.phaseInterceptor.to("MoveEndPhase"); - expect(move.calculateBattlePower).toHaveLastReturnedWith(150); expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(Species.CHARIZARD); + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); }); }); From 4f0f4ce2d5ba1fc1262dcc6234f54a5e3f0a68b5 Mon Sep 17 00:00:00 2001 From: geeilhan <107366005+geeilhan@users.noreply.github.com> Date: Sat, 18 Jan 2025 15:57:47 +0100 Subject: [PATCH 5/7] Apply suggestions from code review Added changes to documentation and cleaning up code Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/custom-pokemon-data.ts | 2 +- src/data/move.ts | 26 ++++++++++++------------- src/phases/encounter-phase.ts | 2 +- src/phases/new-biome-encounter-phase.ts | 2 +- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/data/custom-pokemon-data.ts b/src/data/custom-pokemon-data.ts index 849b9e9f237..4a5eb89aeed 100644 --- a/src/data/custom-pokemon-data.ts +++ b/src/data/custom-pokemon-data.ts @@ -30,7 +30,7 @@ export class CustomPokemonData { this.hitsRecCount = this.hitsRecCount ?? 0; } - resetHitRecivedCount(): void { + resetHitReceivedCount(): void { this.hitsRecCount = 0; } } diff --git a/src/data/move.ts b/src/data/move.ts index 5482a83a26e..2bc750d55a3 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -3994,32 +3994,30 @@ export class FriendshipPowerAttr extends VariablePowerAttr { } /** - * This Attribute calculates the current power of {@linkcode Moves.RAGE_FIST} + * This Attribute calculates the current power of {@linkcode Moves.RAGE_FIST}. * The counter for power calculation does not reset on every wave but on every new arena encounter */ export class RageFistPowerAttr extends VariablePowerAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const BDHitCount = user.battleData.hitCount; - const previousHitCount = user.battleData.prevHitCount; + const { hitCount, prevHitCount } = user.battleData; + const basePower: Utils.NumberHolder = args[0]; - this.updateHitRecivedCount(user, BDHitCount, previousHitCount); + this.updateHitReceivedCount(user, hitCount, prevHitCount); - console.log(`GHNote hitsRecCount: ${user.customPokemonData.hitsRecCount}`); - - (args[0] as Utils.NumberHolder).value = 50 + (Math.min(user.customPokemonData.hitsRecCount, 6) * 50); + basePower.value = 50 + (Math.min(user.customPokemonData.hitsRecCount, 6) * 50); return true; } /** - * Updates the hitCount of recived hits during this arena encounter + * Updates the number of hits the Pokemon has taken in battle * @param user Pokemon calling Rage Fist - * @param BDHitCount The hitCount of reviced hits this battle up until the function is called - * @param previousHitCount The hitCount of reviced hits this battle the last time Rage Fist was called + * @param hitCount The number of received hits this battle + * @param previousHitCount The number of received hits this battle since last time Rage Fist was used */ - updateHitRecivedCount(user: Pokemon, BDHitCount: number, previousHitCount: number): void { - user.customPokemonData.hitsRecCount += (BDHitCount - previousHitCount); - user.battleData.prevHitCount = BDHitCount; + updateHitReceivedCount(user: Pokemon, hitCount: number, previousHitCount: number): void { + user.customPokemonData.hitsRecCount += (hitCount - previousHitCount); + user.battleData.prevHitCount = hitCount; } } @@ -11013,7 +11011,7 @@ export function initMoves() { new AttackMove(Moves.TWIN_BEAM, Type.PSYCHIC, MoveCategory.SPECIAL, 40, 100, 10, -1, 0, 9) .attr(MultiHitAttr, MultiHitType._2), new AttackMove(Moves.RAGE_FIST, Type.GHOST, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 9) - .partial() // Counter resets every wave instead of on arena reset + .edgeCase() // Counter incorrectly increases on confusion self-hits .attr(RageFistPowerAttr) .punchingMove(), new AttackMove(Moves.ARMOR_CANNON, Type.FIRE, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9) diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 2083f09896a..353dd6681cb 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -107,7 +107,7 @@ export class EncounterPhase extends BattlePhase { //resets hitRecCount during Trainer ecnounter for (const pokemon of globalScene.getPlayerParty()) { if (pokemon) { - pokemon.customPokemonData.resetHitRecivedCount(); + pokemon.customPokemonData.resetHitReceivedCount(); } } battle.enemyParty[e] = battle.trainer?.genPartyMember(e)!; // TODO:: is the bang correct here? diff --git a/src/phases/new-biome-encounter-phase.ts b/src/phases/new-biome-encounter-phase.ts index b0a7bf4d1ae..2de9a4300c5 100644 --- a/src/phases/new-biome-encounter-phase.ts +++ b/src/phases/new-biome-encounter-phase.ts @@ -14,7 +14,7 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase { for (const pokemon of globalScene.getPlayerParty()) { if (pokemon) { pokemon.resetBattleData(); - pokemon.customPokemonData.resetHitRecivedCount(); + pokemon.customPokemonData.resetHitReceivedCount(); } } From 06d00571603d931b2365175037581428637dbc76 Mon Sep 17 00:00:00 2001 From: geeil-han Date: Sat, 18 Jan 2025 15:59:33 +0100 Subject: [PATCH 6/7] added protected to updateHitReceivedCount() --- src/data/move.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/move.ts b/src/data/move.ts index 2bc750d55a3..06f3c85e9c4 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4015,7 +4015,7 @@ export class RageFistPowerAttr extends VariablePowerAttr { * @param hitCount The number of received hits this battle * @param previousHitCount The number of received hits this battle since last time Rage Fist was used */ - updateHitReceivedCount(user: Pokemon, hitCount: number, previousHitCount: number): void { + protected updateHitReceivedCount(user: Pokemon, hitCount: number, previousHitCount: number): void { user.customPokemonData.hitsRecCount += (hitCount - previousHitCount); user.battleData.prevHitCount = hitCount; } From 22fd34615a5dcc22a2fdc84064d012592e595308 Mon Sep 17 00:00:00 2001 From: geeil-han Date: Wed, 22 Jan 2025 02:38:27 +0100 Subject: [PATCH 7/7] selfhit due to confusion does not count for rage fist --- src/data/battler-tags.ts | 1 + src/data/move.ts | 4 ++-- src/field/pokemon.ts | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 4c68de5abc5..d72f909ae6e 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -667,6 +667,7 @@ export class ConfusedTag extends BattlerTag { globalScene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself")); pokemon.damageAndUpdate(damage); pokemon.battleData.hitCount++; + pokemon.battleData.confHitCount++; (globalScene.getCurrentPhase() as MovePhase).cancel(); } } diff --git a/src/data/move.ts b/src/data/move.ts index 06f3c85e9c4..d9dd4bafbed 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4010,13 +4010,13 @@ export class RageFistPowerAttr extends VariablePowerAttr { } /** - * Updates the number of hits the Pokemon has taken in battle + * Updates the number of hits the Pokemon has taken in battle not including self inflicted hits due to confusion * @param user Pokemon calling Rage Fist * @param hitCount The number of received hits this battle * @param previousHitCount The number of received hits this battle since last time Rage Fist was used */ protected updateHitReceivedCount(user: Pokemon, hitCount: number, previousHitCount: number): void { - user.customPokemonData.hitsRecCount += (hitCount - previousHitCount); + user.customPokemonData.hitsRecCount += ((hitCount - user.battleData.confHitCount) - previousHitCount); user.battleData.prevHitCount = hitCount; } } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index a4b8603cbb0..8eacb20f9d4 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -5289,6 +5289,8 @@ export class PokemonBattleData { public hitCount: number = 0; /** used for {@linkcode Moves.RAGE_FIST} in order to save hit Counts received before Rage Fist is applied */ public prevHitCount: number = 0; + /** used to count the hitCount of self-hits due to confusion */ + public confHitCount: number = 0; public endured: boolean = false; public berriesEaten: BerryType[] = []; public abilitiesApplied: Abilities[] = [];