added multi-lens logic

This commit is contained in:
muscode13 2024-11-01 14:37:13 -06:00
parent bf8da089a2
commit d8c54ff832
3 changed files with 30 additions and 5 deletions

@ -1 +1 @@
Subproject commit 3cf6d553541d79ba165387bc73fb06544d00f1f9 Subproject commit 71390cba88f4103d0d2273d59a6dd8340a4fa54f

View File

@ -9,7 +9,7 @@ import { StatusEffect, getNonVolatileStatusEffects, getStatusEffectDescriptor, g
import { Gender } from "./gender"; import { Gender } from "./gender";
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, FixedDamageAttr } from "./move"; import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, FixedDamageAttr } from "./move";
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
import { BerryModifier, HitHealModifier, PokemonHeldItemModifier } from "../modifier/modifier"; import { BerryModifier, HitHealModifier, PokemonHeldItemModifier, PokemonMultiHitModifier } from "../modifier/modifier";
import { TerrainType } from "./terrain"; import { TerrainType } from "./terrain";
import { SpeciesFormChangeManualTrigger, SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "./pokemon-forms"; import { SpeciesFormChangeManualTrigger, SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "./pokemon-forms";
import i18next from "i18next"; import i18next from "i18next";
@ -5041,14 +5041,16 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
} else if (opponent.turnData.hitsLeft > 1) { } else if (opponent.turnData.hitsLeft > 1) {
return false; return false;
} }
const multiHitModifier = opponent.getHeldItems().find(m => m instanceof PokemonMultiHitModifier);
if (allMoves[enemyLastMoveUsed.move].hasAttr(MultiHitAttr)) { if (allMoves[enemyLastMoveUsed.move].hasAttr(MultiHitAttr)) {
damage = pokemon.turnData.damageTaken; damage = pokemon.turnData.damageTaken;
} }
if (multiHitModifier) {
// Ideally should be in the MultiHitAttr check, but turnData doesn't have proper data from MultiHitAttr.
damage *= 1 + multiHitModifier.stackCount;
}
} }
} }
if (pokemon.hp + damage >= pokemon.getMaxHp() * this.hpRatio) { if (pokemon.hp + damage >= pokemon.getMaxHp() * this.hpRatio) {
// Activates if it falls below half and recovers back above half from a Shell Bell // Activates if it falls below half and recovers back above half from a Shell Bell
const shellBellHeal = calculateShellBellRecovery(pokemon); const shellBellHeal = calculateShellBellRecovery(pokemon);
@ -5852,9 +5854,11 @@ export function initAbilities() {
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, Stat.DEF, 1), .attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, Stat.DEF, 1),
new Ability(Abilities.WIMP_OUT, 7) new Ability(Abilities.WIMP_OUT, 7)
.attr(PostDamageForceSwitchAbAttr) .attr(PostDamageForceSwitchAbAttr)
.edgeCase() // Doesn't account for damage differences with Multi-Lens (damage rolls, critical hits), Multi-Lens does not update turnData properly
.edgeCase(), // Should not trigger when hurting itself in confusion .edgeCase(), // Should not trigger when hurting itself in confusion
new Ability(Abilities.EMERGENCY_EXIT, 7) new Ability(Abilities.EMERGENCY_EXIT, 7)
.attr(PostDamageForceSwitchAbAttr) .attr(PostDamageForceSwitchAbAttr)
.edgeCase() // Doesn't account for damage differences with Multi-Lens (damage rolls, critical hits), Multi-Lens does not update turnData properly
.edgeCase(), // Should not trigger when hurting itself in confusion .edgeCase(), // Should not trigger when hurting itself in confusion
new Ability(Abilities.WATER_COMPACTION, 7) new Ability(Abilities.WATER_COMPACTION, 7)
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => user.getMoveType(move) === Type.WATER && move.category !== MoveCategory.STATUS, Stat.DEF, 2), .attr(PostDefendStatStageChangeAbAttr, (target, user, move) => user.getMoveType(move) === Type.WATER && move.category !== MoveCategory.STATUS, Stat.DEF, 2),

View File

@ -548,6 +548,27 @@ describe("Abilities - Wimp Out", () => {
confirmSwitch(); confirmSwitch();
}); });
it("triggers after last hit of multi hit move (multi lens)", async () => {
game.override
.enemyMoveset(Moves.TACKLE)
.enemyHeldItems([{ name: "MULTI_LENS", count: 1 }]);
await game.classicMode.startBattle([
Species.WIMPOD,
Species.TYRUNT
]);
game.scene.getPlayerPokemon()!.hp *= 0.51;
game.move.select(Moves.ENDURE);
game.doSelectPartyPokemon(1);
await game.phaseInterceptor.to("TurnEndPhase");
const enemyPokemon = game.scene.getEnemyPokemon()!;
expect(enemyPokemon.turnData.hitsLeft).toBe(0);
expect(enemyPokemon.turnData.hitCount).toBe(2);
confirmSwitch();
});
// TODO: This interaction is not implemented yet // TODO: This interaction is not implemented yet
it.todo("Wimp Out will not activate if the Pokémon's HP falls below half due to hurting itself in confusion", async () => { it.todo("Wimp Out will not activate if the Pokémon's HP falls below half due to hurting itself in confusion", async () => {
game.override game.override