Renamed arena traps to entry hazards fr fr

This commit is contained in:
Bertie690 2025-08-16 19:04:25 -04:00
parent db0c43e367
commit 08ee9e62aa
12 changed files with 55 additions and 52 deletions

View File

@ -2,7 +2,7 @@ import type { ArenaTagTypeMap } from "#data/arena-tag";
import type { ArenaTagType } from "#enums/arena-tag-type"; import type { ArenaTagType } from "#enums/arena-tag-type";
/** Subset of {@linkcode ArenaTagType}s that apply some negative effect to pokemon that switch in ({@link https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards#List_of_traps | entry hazards} and Imprison. */ /** Subset of {@linkcode ArenaTagType}s that apply some negative effect to pokemon that switch in ({@link https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards#List_of_traps | entry hazards} and Imprison. */
export type ArenaTrapTagType = export type EntryHazardTagType =
| ArenaTagType.STICKY_WEB | ArenaTagType.STICKY_WEB
| ArenaTagType.SPIKES | ArenaTagType.SPIKES
| ArenaTagType.TOXIC_SPIKES | ArenaTagType.TOXIC_SPIKES

View File

@ -6,7 +6,7 @@ import type { SpeciesFormChangeRevertWeatherFormTrigger } from "#data/form-chang
import { applyAbAttrs } from "#abilities/apply-ab-attrs"; import { applyAbAttrs } from "#abilities/apply-ab-attrs";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import type { ArenaTrapTag, SuppressAbilitiesTag } from "#data/arena-tag"; import type { EntryHazardTag, SuppressAbilitiesTag } from "#data/arena-tag";
import type { BattlerTag } from "#data/battler-tags"; import type { BattlerTag } from "#data/battler-tags";
import { GroundedTag } from "#data/battler-tags"; import { GroundedTag } from "#data/battler-tags";
import { getBerryEffectFunc } from "#data/berry"; import { getBerryEffectFunc } from "#data/berry";
@ -1113,7 +1113,7 @@ export class PostDefendApplyArenaTrapTagAbAttr extends PostDefendAbAttr {
} }
override canApply({ pokemon, opponent: attacker, move }: PostMoveInteractionAbAttrParams): boolean { override canApply({ pokemon, opponent: attacker, move }: PostMoveInteractionAbAttrParams): boolean {
const tag = globalScene.arena.getTag(this.arenaTagType) as ArenaTrapTag; const tag = globalScene.arena.getTag(this.arenaTagType) as EntryHazardTag;
return ( return (
this.condition(pokemon, attacker, move) && this.condition(pokemon, attacker, move) &&
(!globalScene.arena.getTag(this.arenaTagType) || tag.layers < tag.maxLayers) (!globalScene.arena.getTag(this.arenaTagType) || tag.layers < tag.maxLayers)

View File

@ -24,7 +24,7 @@ import type { Pokemon } from "#field/pokemon";
import type { import type {
ArenaScreenTagType, ArenaScreenTagType,
ArenaTagTypeData, ArenaTagTypeData,
ArenaTrapTagType, EntryHazardTagType,
SerializableArenaTagType, SerializableArenaTagType,
} from "#types/arena-tags"; } from "#types/arena-tags";
import type { Mutable } from "#types/type-helpers"; import type { Mutable } from "#types/type-helpers";
@ -725,12 +725,12 @@ export class IonDelugeTag extends ArenaTag {
} }
/** /**
* Abstract class to implement [arena traps (AKA entry hazards)](https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards). * Abstract class to implement [entry hazards](https://bulbapedia.bulbagarden.net/wiki/List_of_moves_that_cause_entry_hazards).
* These persistent tags remain on-field across turns and apply effects to any {@linkcode Pokemon} switching in. \ * These persistent tags remain on-field across turns and apply effects to any {@linkcode Pokemon} switching in. \
* Uniquely, adding a tag multiple times will stack multiple "layers" of the effect, increasing its severity. * Uniquely, adding a tag multiple times may stack multiple "layers" of the effect, increasing its severity.
*/ */
export abstract class ArenaTrapTag extends SerializableArenaTag { export abstract class EntryHazardTag extends SerializableArenaTag {
abstract readonly tagType: ArenaTrapTagType; public declare abstract readonly tagType: EntryHazardTagType;
/** /**
* The current number of layers this tag has. * The current number of layers this tag has.
* Starts at 1 and increases each time the trap is laid. * Starts at 1 and increases each time the trap is laid.
@ -837,7 +837,7 @@ export abstract class ArenaTrapTag extends SerializableArenaTag {
* Abstract class to implement damaging entry hazards. * Abstract class to implement damaging entry hazards.
* Currently used for {@linkcode SpikesTag} and {@linkcode StealthRockTag}. * Currently used for {@linkcode SpikesTag} and {@linkcode StealthRockTag}.
*/ */
abstract class DamagingTrapTag extends ArenaTrapTag { abstract class DamagingTrapTag extends EntryHazardTag {
override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { override activateTrap(pokemon: Pokemon, simulated: boolean): boolean {
// Check for magic guard immunity // Check for magic guard immunity
const cancelled = new BooleanHolder(false); const cancelled = new BooleanHolder(false);
@ -956,7 +956,7 @@ class StealthRockTag extends DamagingTrapTag {
* based on the current layer count. \ * based on the current layer count. \
* Poison-type Pokémon will remove it entirely upon switch-in. * Poison-type Pokémon will remove it entirely upon switch-in.
*/ */
class ToxicSpikesTag extends ArenaTrapTag { class ToxicSpikesTag extends EntryHazardTag {
/** /**
* Whether the tag is currently in the process of being neutralized by a Poison-type. * Whether the tag is currently in the process of being neutralized by a Poison-type.
* @defaultValue `false` * @defaultValue `false`
@ -1024,7 +1024,7 @@ class ToxicSpikesTag extends ArenaTrapTag {
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Sticky_Web_(move) | Sticky Web}. * Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Sticky_Web_(move) | Sticky Web}.
* Applies a single-layer trap that lowers the Speed of all grounded Pokémon switching in. * Applies a single-layer trap that lowers the Speed of all grounded Pokémon switching in.
*/ */
class StickyWebTag extends ArenaTrapTag { class StickyWebTag extends EntryHazardTag {
public readonly tagType = ArenaTagType.STICKY_WEB; public readonly tagType = ArenaTagType.STICKY_WEB;
public override get maxLayers() { public override get maxLayers() {
return 1 as const; return 1 as const;
@ -1087,7 +1087,7 @@ class StickyWebTag extends ArenaTrapTag {
* Imprison remains in effect as long as the source Pokemon is active and present on the field. * Imprison remains in effect as long as the source Pokemon is active and present on the field.
* Imprison will apply to any opposing Pokemon that switch onto the field as well. * Imprison will apply to any opposing Pokemon that switch onto the field as well.
*/ */
class ImprisonTag extends ArenaTrapTag { class ImprisonTag extends EntryHazardTag {
public readonly tagType = ArenaTagType.IMPRISON; public readonly tagType = ArenaTagType.IMPRISON;
public override get maxLayers() { public override get maxLayers() {
return 1 as const; return 1 as const;

View File

@ -6,7 +6,7 @@ import { loggedInUser } from "#app/account";
import type { GameMode } from "#app/game-mode"; import type { GameMode } from "#app/game-mode";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import type { ArenaTrapTag } from "#data/arena-tag"; import type { EntryHazardTag } from "#data/arena-tag";
import { WeakenMoveTypeTag } from "#data/arena-tag"; import { WeakenMoveTypeTag } from "#data/arena-tag";
import { MoveChargeAnim } from "#data/battle-anims"; import { MoveChargeAnim } from "#data/battle-anims";
import { import {
@ -6083,7 +6083,7 @@ export class AddArenaTrapTagAttr extends AddArenaTagAttr {
getCondition(): MoveConditionFunc { getCondition(): MoveConditionFunc {
return (user, target, move) => { return (user, target, move) => {
const side = (this.selfSideTarget !== user.isPlayer()) ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER; const side = (this.selfSideTarget !== user.isPlayer()) ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER;
const tag = globalScene.arena.getTagOnSide(this.tagType, side) as ArenaTrapTag; const tag = globalScene.arena.getTagOnSide(this.tagType, side) as EntryHazardTag;
if (!tag) { if (!tag) {
return true; return true;
} }
@ -6107,7 +6107,7 @@ export class AddArenaTrapTagHitAttr extends AddArenaTagAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true);
const side = (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; const side = (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
const tag = globalScene.arena.getTagOnSide(this.tagType, side) as ArenaTrapTag; const tag = globalScene.arena.getTagOnSide(this.tagType, side) as EntryHazardTag;
if ((moveChance < 0 || moveChance === 100 || user.randBattleSeedInt(100) < moveChance) && user.getLastXMoves(1)[0]?.result === MoveResult.SUCCESS) { if ((moveChance < 0 || moveChance === 100 || user.randBattleSeedInt(100) < moveChance) && user.getLastXMoves(1)[0]?.result === MoveResult.SUCCESS) {
globalScene.arena.addTag(this.tagType, 0, move.id, user.id, side); globalScene.arena.addTag(this.tagType, 0, move.id, user.id, side);
if (!tag) { if (!tag) {

View File

@ -8,7 +8,7 @@ import Overrides from "#app/overrides";
import type { BiomeTierTrainerPools, PokemonPools } from "#balance/biomes"; import type { BiomeTierTrainerPools, PokemonPools } from "#balance/biomes";
import { BiomePoolTier, biomePokemonPools, biomeTrainerPools } from "#balance/biomes"; import { BiomePoolTier, biomePokemonPools, biomeTrainerPools } from "#balance/biomes";
import type { ArenaTag } from "#data/arena-tag"; import type { ArenaTag } from "#data/arena-tag";
import { ArenaTrapTag, getArenaTag } from "#data/arena-tag"; import { EntryHazardTag, getArenaTag } from "#data/arena-tag";
import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "#data/form-change-triggers"; import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "#data/form-change-triggers";
import type { PokemonSpecies } from "#data/pokemon-species"; import type { PokemonSpecies } from "#data/pokemon-species";
import { PositionalTagManager } from "#data/positional-tags/positional-tag-manager"; import { PositionalTagManager } from "#data/positional-tags/positional-tag-manager";
@ -709,8 +709,8 @@ export class Arena {
if (existingTag) { if (existingTag) {
existingTag.onOverlap(this, globalScene.getPokemonById(sourceId)); existingTag.onOverlap(this, globalScene.getPokemonById(sourceId));
if (existingTag instanceof ArenaTrapTag) { if (existingTag instanceof EntryHazardTag) {
const { tagType, side, turnCount, layers, maxLayers } = existingTag as ArenaTrapTag; const { tagType, side, turnCount, layers, maxLayers } = existingTag as EntryHazardTag;
this.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, layers, maxLayers)); this.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, layers, maxLayers));
} }
@ -723,7 +723,7 @@ export class Arena {
newTag.onAdd(this, quiet); newTag.onAdd(this, quiet);
this.tags.push(newTag); this.tags.push(newTag);
const { layers = 0, maxLayers = 0 } = newTag instanceof ArenaTrapTag ? newTag : {}; const { layers = 0, maxLayers = 0 } = newTag instanceof EntryHazardTag ? newTag : {};
this.eventTarget.dispatchEvent( this.eventTarget.dispatchEvent(
new TagAddedEvent(newTag.tagType, newTag.side, newTag.turnCount, layers, maxLayers), new TagAddedEvent(newTag.tagType, newTag.side, newTag.turnCount, layers, maxLayers),

View File

@ -1,7 +1,7 @@
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { pokemonPrevolutions } from "#balance/pokemon-evolutions"; import { pokemonPrevolutions } from "#balance/pokemon-evolutions";
import { signatureSpecies } from "#balance/signature-species"; import { signatureSpecies } from "#balance/signature-species";
import { ArenaTrapTag } from "#data/arena-tag"; import { EntryHazardTag } from "#data/arena-tag";
import type { PokemonSpecies } from "#data/pokemon-species"; import type { PokemonSpecies } from "#data/pokemon-species";
import { ArenaTagSide } from "#enums/arena-tag-side"; import { ArenaTagSide } from "#enums/arena-tag-side";
import { PartyMemberStrength } from "#enums/party-member-strength"; import { PartyMemberStrength } from "#enums/party-member-strength";
@ -584,8 +584,8 @@ export class Trainer extends Phaser.GameObjects.Container {
score /= playerField.length; score /= playerField.length;
if (forSwitch && !p.isOnField()) { if (forSwitch && !p.isOnField()) {
globalScene.arena globalScene.arena
.findTagsOnSide(t => t instanceof ArenaTrapTag, ArenaTagSide.ENEMY) .findTagsOnSide(t => t instanceof EntryHazardTag, ArenaTagSide.ENEMY)
.map(t => (score *= (t as ArenaTrapTag).getMatchupScoreMultiplier(p))); .map(t => (score *= (t as EntryHazardTag).getMatchupScoreMultiplier(p)));
} }
} }

View File

@ -1,6 +1,6 @@
import { applyAbAttrs } from "#abilities/apply-ab-attrs"; import { applyAbAttrs } from "#abilities/apply-ab-attrs";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { ArenaTrapTag } from "#data/arena-tag"; import { EntryHazardTag } from "#data/arena-tag";
import { MysteryEncounterPostSummonTag } from "#data/battler-tags"; import { MysteryEncounterPostSummonTag } from "#data/battler-tags";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
@ -16,7 +16,7 @@ export class PostSummonPhase extends PokemonPhase {
if (pokemon.status?.effect === StatusEffect.TOXIC) { if (pokemon.status?.effect === StatusEffect.TOXIC) {
pokemon.status.toxicTurnCount = 0; pokemon.status.toxicTurnCount = 0;
} }
globalScene.arena.applyTags(ArenaTrapTag, false, pokemon); globalScene.arena.applyTags(EntryHazardTag, false, pokemon);
// If this is mystery encounter and has post summon phase tag, apply post summon effects // If this is mystery encounter and has post summon phase tag, apply post summon effects
if ( if (

View File

@ -10,7 +10,7 @@ import { Tutorial } from "#app/tutorial";
import { speciesEggMoves } from "#balance/egg-moves"; import { speciesEggMoves } from "#balance/egg-moves";
import { pokemonPrevolutions } from "#balance/pokemon-evolutions"; import { pokemonPrevolutions } from "#balance/pokemon-evolutions";
import { speciesStarterCosts } from "#balance/starters"; import { speciesStarterCosts } from "#balance/starters";
import { ArenaTrapTag } from "#data/arena-tag"; import { EntryHazardTag } from "#data/arena-tag";
import { allMoves, allSpecies } from "#data/data-lists"; import { allMoves, allSpecies } from "#data/data-lists";
import type { Egg } from "#data/egg"; import type { Egg } from "#data/egg";
import { pokemonFormChanges } from "#data/pokemon-forms"; import { pokemonFormChanges } from "#data/pokemon-forms";
@ -1135,8 +1135,8 @@ export class GameData {
globalScene.arena.tags = sessionData.arena.tags; globalScene.arena.tags = sessionData.arena.tags;
if (globalScene.arena.tags) { if (globalScene.arena.tags) {
for (const tag of globalScene.arena.tags) { for (const tag of globalScene.arena.tags) {
if (tag instanceof ArenaTrapTag) { if (tag instanceof EntryHazardTag) {
const { tagType, side, turnCount, layers, maxLayers } = tag as ArenaTrapTag; const { tagType, side, turnCount, layers, maxLayers } = tag as EntryHazardTag;
globalScene.arena.eventTarget.dispatchEvent( globalScene.arena.eventTarget.dispatchEvent(
new TagAddedEvent(tagType, side, turnCount, layers, maxLayers), new TagAddedEvent(tagType, side, turnCount, layers, maxLayers),
); );

View File

@ -1,5 +1,5 @@
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { ArenaTrapTag } from "#data/arena-tag"; import { EntryHazardTag } from "#data/arena-tag";
import { TerrainType } from "#data/terrain"; import { TerrainType } from "#data/terrain";
import { ArenaTagSide } from "#enums/arena-tag-side"; import { ArenaTagSide } from "#enums/arena-tag-side";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
@ -287,7 +287,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
switch (arenaEffectChangedEvent.constructor) { switch (arenaEffectChangedEvent.constructor) {
case TagAddedEvent: { case TagAddedEvent: {
const tagAddedEvent = arenaEffectChangedEvent as TagAddedEvent; const tagAddedEvent = arenaEffectChangedEvent as TagAddedEvent;
const isArenaTrapTag = globalScene.arena.getTag(tagAddedEvent.arenaTagType) instanceof ArenaTrapTag; const isArenaTrapTag = globalScene.arena.getTag(tagAddedEvent.arenaTagType) instanceof EntryHazardTag;
let arenaEffectType: ArenaEffectType; let arenaEffectType: ArenaEffectType;
if (tagAddedEvent.arenaTagSide === ArenaTagSide.BOTH) { if (tagAddedEvent.arenaTagSide === ArenaTagSide.BOTH) {

View File

@ -1,4 +1,4 @@
import { ArenaTrapTag } from "#data/arena-tag"; import { EntryHazardTag } from "#data/arena-tag";
import { allMoves } from "#data/data-lists"; import { allMoves } from "#data/data-lists";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { ArenaTagSide } from "#enums/arena-tag-side"; import { ArenaTagSide } from "#enums/arena-tag-side";
@ -50,12 +50,12 @@ describe("Moves - Ceaseless Edge", () => {
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to(MoveEffectPhase, false);
// Spikes should not have any layers before move effect is applied // Spikes should not have any layers before move effect is applied
const tagBefore = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; const tagBefore = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as EntryHazardTag;
expect(tagBefore instanceof ArenaTrapTag).toBeFalsy(); expect(tagBefore instanceof EntryHazardTag).toBeFalsy();
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as EntryHazardTag;
expect(tagAfter instanceof ArenaTrapTag).toBeTruthy(); expect(tagAfter instanceof EntryHazardTag).toBeTruthy();
expect(tagAfter.layers).toBe(1); expect(tagAfter.layers).toBe(1);
expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp);
}); });
@ -72,12 +72,12 @@ describe("Moves - Ceaseless Edge", () => {
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to(MoveEffectPhase, false);
// Spikes should not have any layers before move effect is applied // Spikes should not have any layers before move effect is applied
const tagBefore = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; const tagBefore = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as EntryHazardTag;
expect(tagBefore instanceof ArenaTrapTag).toBeFalsy(); expect(tagBefore instanceof EntryHazardTag).toBeFalsy();
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as EntryHazardTag;
expect(tagAfter instanceof ArenaTrapTag).toBeTruthy(); expect(tagAfter instanceof EntryHazardTag).toBeTruthy();
expect(tagAfter.layers).toBe(2); expect(tagAfter.layers).toBe(2);
expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp);
}); });
@ -90,12 +90,12 @@ describe("Moves - Ceaseless Edge", () => {
game.move.select(MoveId.CEASELESS_EDGE); game.move.select(MoveId.CEASELESS_EDGE);
await game.phaseInterceptor.to(MoveEffectPhase, false); await game.phaseInterceptor.to(MoveEffectPhase, false);
// Spikes should not have any layers before move effect is applied // Spikes should not have any layers before move effect is applied
const tagBefore = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; const tagBefore = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as EntryHazardTag;
expect(tagBefore instanceof ArenaTrapTag).toBeFalsy(); expect(tagBefore instanceof EntryHazardTag).toBeFalsy();
await game.toNextTurn(); await game.toNextTurn();
const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as EntryHazardTag;
expect(tagAfter instanceof ArenaTrapTag).toBeTruthy(); expect(tagAfter instanceof EntryHazardTag).toBeTruthy();
expect(tagAfter.layers).toBe(2); expect(tagAfter.layers).toBe(2);
const hpBeforeSpikes = game.scene.currentBattle.enemyParty[1].hp; const hpBeforeSpikes = game.scene.currentBattle.enemyParty[1].hp;

View File

@ -1,4 +1,4 @@
import type { ArenaTrapTag } from "#data/arena-tag"; import type { EntryHazardTag } from "#data/arena-tag";
import { allMoves } from "#data/data-lists"; import { allMoves } from "#data/data-lists";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { ArenaTagSide } from "#enums/arena-tag-side"; import { ArenaTagSide } from "#enums/arena-tag-side";
@ -195,7 +195,7 @@ describe("Moves - Destiny Bond", () => {
expect(playerPokemon.isFainted()).toBe(true); expect(playerPokemon.isFainted()).toBe(true);
// Ceaseless Edge spikes effect should still activate // Ceaseless Edge spikes effect should still activate
const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag; const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.ENEMY) as EntryHazardTag;
expect(tagAfter.tagType).toBe(ArenaTagType.SPIKES); expect(tagAfter.tagType).toBe(ArenaTagType.SPIKES);
expect(tagAfter.layers).toBe(1); expect(tagAfter.layers).toBe(1);
}); });
@ -220,7 +220,10 @@ describe("Moves - Destiny Bond", () => {
expect(playerPokemon1?.isFainted()).toBe(true); expect(playerPokemon1?.isFainted()).toBe(true);
// Pledge secondary effect should still activate // Pledge secondary effect should still activate
const tagAfter = game.scene.arena.getTagOnSide(ArenaTagType.GRASS_WATER_PLEDGE, ArenaTagSide.ENEMY) as ArenaTrapTag; const tagAfter = game.scene.arena.getTagOnSide(
ArenaTagType.GRASS_WATER_PLEDGE,
ArenaTagSide.ENEMY,
) as EntryHazardTag;
expect(tagAfter.tagType).toBe(ArenaTagType.GRASS_WATER_PLEDGE); expect(tagAfter.tagType).toBe(ArenaTagType.GRASS_WATER_PLEDGE);
}); });

View File

@ -1,5 +1,4 @@
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { ArenaTrapTag } from "#data/arena-tag";
import { allMoves } from "#data/data-lists"; import { allMoves } from "#data/data-lists";
import type { TypeDamageMultiplier } from "#data/type"; import type { TypeDamageMultiplier } from "#data/type";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
@ -14,7 +13,7 @@ import { SpeciesId } from "#enums/species-id";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import { GameManager } from "#test/test-utils/game-manager"; import { GameManager } from "#test/test-utils/game-manager";
import type { ArenaTrapTagType } from "#types/arena-tags"; import type { EntryHazardTagType } from "#types/arena-tags";
import i18next from "i18next"; import i18next from "i18next";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -46,7 +45,7 @@ describe("Moves - Entry Hazards", () => {
.battleType(BattleType.TRAINER); .battleType(BattleType.TRAINER);
}); });
describe.each<{ name: string; move: MoveId; tagType: ArenaTrapTagType }>([ describe.each<{ name: string; move: MoveId; tagType: EntryHazardTagType }>([
{ name: "Spikes", move: MoveId.SPIKES, tagType: ArenaTagType.SPIKES }, { name: "Spikes", move: MoveId.SPIKES, tagType: ArenaTagType.SPIKES },
{ {
name: "Toxic Spikes", name: "Toxic Spikes",
@ -79,18 +78,19 @@ describe("Moves - Entry Hazards", () => {
// TODO: re-enable after re-fixing hazards moves // TODO: re-enable after re-fixing hazards moves
it.todo("should work when all targets fainted", async () => { it.todo("should work when all targets fainted", async () => {
game.override.enemySpecies(SpeciesId.DIGLETT).battleStyle("double").startingLevel(1000); game.override.battleStyle("double");
await game.classicMode.startBattle([SpeciesId.RAYQUAZA, SpeciesId.SHUCKLE]); await game.classicMode.startBattle([SpeciesId.RAYQUAZA, SpeciesId.SHUCKLE]);
const [enemy1, enemy2] = game.scene.getEnemyField(); const [enemy1, enemy2] = game.scene.getEnemyField();
game.move.use(MoveId.HYPER_VOICE, BattlerIndex.PLAYER); game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER);
game.move.use(MoveId.SPIKES, BattlerIndex.PLAYER_2); game.move.use(move, BattlerIndex.PLAYER_2);
await game.doKillOpponents();
await game.toEndOfTurn(); await game.toEndOfTurn();
expect(enemy1.isFainted()).toBe(true); expect(enemy1.isFainted()).toBe(true);
expect(enemy2.isFainted()).toBe(true); expect(enemy2.isFainted()).toBe(true);
expect(game.scene.arena.getTagOnSide(ArenaTrapTag, ArenaTagSide.ENEMY)).toBeDefined(); expect(game).toHaveArenaTag(tagType, ArenaTagSide.ENEMY);
}); });
const maxLayers = tagType === ArenaTagType.SPIKES ? 3 : tagType === ArenaTagType.TOXIC_SPIKES ? 2 : 1; const maxLayers = tagType === ArenaTagType.SPIKES ? 3 : tagType === ArenaTagType.TOXIC_SPIKES ? 2 : 1;