[P2] Fix Tera Shell to apply to all hits of multi-strike moves (#4541)

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

* fix undefined property error

* ugh

* Remove obsolete bangs
This commit is contained in:
innerthunder 2024-10-01 18:58:56 -07:00 committed by GitHub
parent a6bcd6eeea
commit 7473c31c77
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 32 additions and 1 deletions

View File

@ -519,6 +519,7 @@ export class FullHpResistTypeAbAttr extends PreDefendAbAttr {
if (pokemon.isFullHp() && typeMultiplier.value > 0.5) { if (pokemon.isFullHp() && typeMultiplier.value > 0.5) {
typeMultiplier.value = 0.5; typeMultiplier.value = 0.5;
pokemon.turnData.moveEffectiveness = 0.5;
return true; return true;
} }
return false; return false;

View File

@ -1538,6 +1538,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns The type damage multiplier, indicating the effectiveness of the move * @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 { 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)) { if (move.hasAttr(TypelessAttr)) {
return 1; return 1;
} }
@ -5019,6 +5023,7 @@ export class PokemonTurnData {
public order: number; public order: number;
public statStagesIncreased: boolean = false; public statStagesIncreased: boolean = false;
public statStagesDecreased: boolean = false; public statStagesDecreased: boolean = false;
public moveEffectiveness: TypeDamageMultiplier | null = null;
} }
export enum AiType { export enum AiType {

View File

@ -354,12 +354,14 @@ export class MoveEffectPhase extends PokemonPhase {
} else { } else {
// Queue message for number of hits made by multi-move // Queue message for number of hits made by multi-move
// If multi-hit attack only hits once, still want to render a message // 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 (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 // 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.queueMessage(i18next.t("battle:attackHitsCount", { count: hitsTotal }));
} }
this.scene.applyModifiers(HitHealModifier, this.player, user); this.scene.applyModifiers(HitHealModifier, this.player, user);
// Clear all cached move effectiveness values among targets
this.getTargets().forEach((target) => target.turnData.moveEffectiveness = null);
} }
} }

View File

@ -1,3 +1,4 @@
import { BattlerIndex } from "#app/battle";
import { Abilities } from "#app/enums/abilities"; import { Abilities } from "#app/enums/abilities";
import { Moves } from "#app/enums/moves"; import { Moves } from "#app/enums/moves";
import { Species } from "#app/enums/species"; import { Species } from "#app/enums/species";
@ -106,4 +107,26 @@ describe("Abilities - Tera Shell", () => {
expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp() - 40); 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);
}
);
}); });