Skip to content

Commit

Permalink
[P2] Fix Tera Shell to apply to all hits of multi-strike moves (pagef…
Browse files Browse the repository at this point in the history
…aultgames#4541)

* Apply Tera Shell to all hits for multi-hit moves

* fix undefined property error

* ugh

* Remove obsolete bangs
  • Loading branch information
innerthunder authored Oct 2, 2024
1 parent a6bcd6e commit 7473c31
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/data/ability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ export class FullHpResistTypeAbAttr extends PreDefendAbAttr {

if (pokemon.isFullHp() && typeMultiplier.value > 0.5) {
typeMultiplier.value = 0.5;
pokemon.turnData.moveEffectiveness = 0.5;
return true;
}
return false;
Expand Down
5 changes: 5 additions & 0 deletions src/field/pokemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns The type damage multiplier, indicating the effectiveness of the move
*/
getMoveEffectiveness(source: Pokemon, move: Move, ignoreAbility: boolean = false, simulated: boolean = true, cancelled?: Utils.BooleanHolder): TypeDamageMultiplier {
if (!Utils.isNullOrUndefined(this.turnData?.moveEffectiveness)) {
return this.turnData?.moveEffectiveness;
}

if (move.hasAttr(TypelessAttr)) {
return 1;
}
Expand Down Expand Up @@ -5019,6 +5023,7 @@ export class PokemonTurnData {
public order: number;
public statStagesIncreased: boolean = false;
public statStagesDecreased: boolean = false;
public moveEffectiveness: TypeDamageMultiplier | null = null;
}

export enum AiType {
Expand Down
4 changes: 3 additions & 1 deletion src/phases/move-effect-phase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,14 @@ export class MoveEffectPhase extends PokemonPhase {
} else {
// Queue message for number of hits made by multi-move
// If multi-hit attack only hits once, still want to render a message
const hitsTotal = user.turnData.hitCount! - Math.max(user.turnData.hitsLeft!, 0); // TODO: are those bangs correct?
const hitsTotal = user.turnData.hitCount - Math.max(user.turnData.hitsLeft, 0);
if (hitsTotal > 1 || (user.turnData.hitsLeft && user.turnData.hitsLeft > 0)) {
// If there are multiple hits, or if there are hits of the multi-hit move left
this.scene.queueMessage(i18next.t("battle:attackHitsCount", { count: hitsTotal }));
}
this.scene.applyModifiers(HitHealModifier, this.player, user);
// Clear all cached move effectiveness values among targets
this.getTargets().forEach((target) => target.turnData.moveEffectiveness = null);
}
}

Expand Down
23 changes: 23 additions & 0 deletions src/test/abilities/tera_shell.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BattlerIndex } from "#app/battle";
import { Abilities } from "#app/enums/abilities";
import { Moves } from "#app/enums/moves";
import { Species } from "#app/enums/species";
Expand Down Expand Up @@ -106,4 +107,26 @@ describe("Abilities - Tera Shell", () => {
expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp() - 40);
}
);

it(
"should change the effectiveness of all strikes of a multi-strike move",
async () => {
game.override.enemyMoveset([Moves.DOUBLE_HIT]);

await game.classicMode.startBattle([Species.SNORLAX]);

const playerPokemon = game.scene.getPlayerPokemon()!;
vi.spyOn(playerPokemon, "apply");

game.move.select(Moves.SPLASH);

await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.move.forceHit();
for (let i = 0; i < 2; i++) {
await game.phaseInterceptor.to("MoveEffectPhase");
expect(playerPokemon.apply).toHaveLastReturnedWith(HitResult.NOT_VERY_EFFECTIVE);
}
expect(playerPokemon.apply).toHaveReturnedTimes(2);
}
);
});

0 comments on commit 7473c31

Please sign in to comment.