mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-23 23:13:42 +02:00
Merge remote-tracking branch 'upstream/beta' into arena-tag-cleanup
This commit is contained in:
commit
78c44b3e3d
@ -85,6 +85,10 @@ interface BaseArenaTag {
|
|||||||
* The tag's remaining duration. Setting to any number `<=0` will make the tag's duration effectively infinite.
|
* The tag's remaining duration. Setting to any number `<=0` will make the tag's duration effectively infinite.
|
||||||
*/
|
*/
|
||||||
turnCount: number;
|
turnCount: number;
|
||||||
|
/**
|
||||||
|
* The tag's max duration.
|
||||||
|
*/
|
||||||
|
maxDuration: number;
|
||||||
/**
|
/**
|
||||||
* The {@linkcode MoveId} that created this tag, or `undefined` if not set by a move.
|
* The {@linkcode MoveId} that created this tag, or `undefined` if not set by a move.
|
||||||
*/
|
*/
|
||||||
@ -112,6 +116,7 @@ export abstract class ArenaTag implements BaseArenaTag {
|
|||||||
public abstract readonly tagType: ArenaTagType;
|
public abstract readonly tagType: ArenaTagType;
|
||||||
// Intentionally left undocumented to inherit comments from interface
|
// Intentionally left undocumented to inherit comments from interface
|
||||||
public turnCount: number;
|
public turnCount: number;
|
||||||
|
public maxDuration: number;
|
||||||
public sourceMove?: MoveId;
|
public sourceMove?: MoveId;
|
||||||
public sourceId: number | undefined;
|
public sourceId: number | undefined;
|
||||||
public side: ArenaTagSide;
|
public side: ArenaTagSide;
|
||||||
@ -145,6 +150,7 @@ export abstract class ArenaTag implements BaseArenaTag {
|
|||||||
|
|
||||||
constructor(turnCount: number, sourceMove?: MoveId, sourceId?: number, side: ArenaTagSide = ArenaTagSide.BOTH) {
|
constructor(turnCount: number, sourceMove?: MoveId, sourceId?: number, side: ArenaTagSide = ArenaTagSide.BOTH) {
|
||||||
this.turnCount = turnCount;
|
this.turnCount = turnCount;
|
||||||
|
this.maxDuration = turnCount;
|
||||||
this.sourceMove = sourceMove;
|
this.sourceMove = sourceMove;
|
||||||
this.sourceId = sourceId;
|
this.sourceId = sourceId;
|
||||||
this.side = side;
|
this.side = side;
|
||||||
@ -224,6 +230,7 @@ export abstract class ArenaTag implements BaseArenaTag {
|
|||||||
*/
|
*/
|
||||||
loadTag<const T extends this>(source: BaseArenaTag & Pick<T, "tagType">): void {
|
loadTag<const T extends this>(source: BaseArenaTag & Pick<T, "tagType">): void {
|
||||||
this.turnCount = source.turnCount;
|
this.turnCount = source.turnCount;
|
||||||
|
this.maxDuration = source.maxDuration;
|
||||||
this.sourceMove = source.sourceMove;
|
this.sourceMove = source.sourceMove;
|
||||||
this.sourceId = source.sourceId;
|
this.sourceId = source.sourceId;
|
||||||
this.side = source.side;
|
this.side = source.side;
|
||||||
|
@ -1119,7 +1119,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
|||||||
},
|
},
|
||||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.HITMONLEE, SpeciesId.HITMONCHAN, SpeciesId.LUCARIO, SpeciesId.THROH, SpeciesId.SAWK, { 1: [ SpeciesId.PANCHAM ], 52: [ SpeciesId.PANGORO ] } ] },
|
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.HITMONLEE, SpeciesId.HITMONCHAN, SpeciesId.LUCARIO, SpeciesId.THROH, SpeciesId.SAWK, { 1: [ SpeciesId.PANCHAM ], 52: [ SpeciesId.PANGORO ] } ] },
|
||||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.HITMONTOP, SpeciesId.GALLADE, SpeciesId.GALAR_FARFETCHD ] },
|
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.HITMONTOP, SpeciesId.GALLADE, SpeciesId.GALAR_FARFETCHD ] },
|
||||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TERRAKION, { 1: [ SpeciesId.KUBFU ], 60: [ SpeciesId.URSHIFU] }, SpeciesId.GALAR_ZAPDOS ] },
|
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TERRAKION, { 1: [ SpeciesId.KUBFU ], 60: [ SpeciesId.URSHIFU ] }, SpeciesId.GALAR_ZAPDOS ] },
|
||||||
[BiomePoolTier.BOSS]: {
|
[BiomePoolTier.BOSS]: {
|
||||||
[TimeOfDay.DAWN]: [],
|
[TimeOfDay.DAWN]: [],
|
||||||
[TimeOfDay.DAY]: [],
|
[TimeOfDay.DAY]: [],
|
||||||
@ -1128,7 +1128,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
|||||||
[TimeOfDay.ALL]: [ SpeciesId.HITMONLEE, SpeciesId.HITMONCHAN, SpeciesId.HARIYAMA, SpeciesId.MEDICHAM, SpeciesId.LUCARIO, SpeciesId.TOXICROAK, SpeciesId.THROH, SpeciesId.SAWK, SpeciesId.SCRAFTY, SpeciesId.MIENSHAO, SpeciesId.BEWEAR, SpeciesId.GRAPPLOCT, SpeciesId.ANNIHILAPE ]
|
[TimeOfDay.ALL]: [ SpeciesId.HITMONLEE, SpeciesId.HITMONCHAN, SpeciesId.HARIYAMA, SpeciesId.MEDICHAM, SpeciesId.LUCARIO, SpeciesId.TOXICROAK, SpeciesId.THROH, SpeciesId.SAWK, SpeciesId.SCRAFTY, SpeciesId.MIENSHAO, SpeciesId.BEWEAR, SpeciesId.GRAPPLOCT, SpeciesId.ANNIHILAPE ]
|
||||||
},
|
},
|
||||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.HITMONTOP, SpeciesId.GALLADE, SpeciesId.PANGORO, SpeciesId.SIRFETCHD, SpeciesId.HISUI_DECIDUEYE ] },
|
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.HITMONTOP, SpeciesId.GALLADE, SpeciesId.PANGORO, SpeciesId.SIRFETCHD, SpeciesId.HISUI_DECIDUEYE ] },
|
||||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TERRAKION, { 1: [ SpeciesId.KUBFU ], 60: [ SpeciesId.URSHIFU] } ] },
|
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TERRAKION, { 1: [ SpeciesId.KUBFU ], 60: [ SpeciesId.URSHIFU ] } ] },
|
||||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ZAMAZENTA, SpeciesId.GALAR_ZAPDOS ] }
|
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ZAMAZENTA, SpeciesId.GALAR_ZAPDOS ] }
|
||||||
},
|
},
|
||||||
[BiomeId.FACTORY]: {
|
[BiomeId.FACTORY]: {
|
||||||
@ -1597,10 +1597,10 @@ export const biomePokemonPools: BiomePokemonPools = {
|
|||||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ SpeciesId.SOLOSIS ], 32: [ SpeciesId.DUOSION ], 41: [ SpeciesId.REUNICLUS ] } ] },
|
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ SpeciesId.SOLOSIS ], 32: [ SpeciesId.DUOSION ], 41: [ SpeciesId.REUNICLUS ] } ] },
|
||||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO, { 1: [ SpeciesId.PORYGON ], 30: [ SpeciesId.PORYGON2 ] } ] },
|
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO, { 1: [ SpeciesId.PORYGON ], 30: [ SpeciesId.PORYGON2 ] } ] },
|
||||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ROTOM ] },
|
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ROTOM ] },
|
||||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [SpeciesId.TYPE_NULL], 60: [ SpeciesId.SILVALLY ] } ] },
|
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ { 1: [ SpeciesId.TYPE_NULL ], 60: [ SpeciesId.SILVALLY ] } ] },
|
||||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MUK, SpeciesId.ELECTRODE, SpeciesId.BRONZONG, SpeciesId.MAGNEZONE, SpeciesId.PORYGON_Z, SpeciesId.REUNICLUS, SpeciesId.KLINKLANG ] },
|
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MUK, SpeciesId.ELECTRODE, SpeciesId.BRONZONG, SpeciesId.MAGNEZONE, SpeciesId.PORYGON_Z, SpeciesId.REUNICLUS, SpeciesId.KLINKLANG ] },
|
||||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ROTOM, SpeciesId.ZYGARDE, { 1: [SpeciesId.TYPE_NULL], 60: [ SpeciesId.SILVALLY ] } ] },
|
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ROTOM, SpeciesId.ZYGARDE, { 1: [ SpeciesId.TYPE_NULL ], 60: [ SpeciesId.SILVALLY ] } ] },
|
||||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MEWTWO, SpeciesId.MIRAIDON ] }
|
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MEWTWO, SpeciesId.MIRAIDON ] }
|
||||||
},
|
},
|
||||||
[BiomeId.END]: {
|
[BiomeId.END]: {
|
||||||
@ -5627,10 +5627,12 @@ export function initBiomes() {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[ SpeciesId.TYPE_NULL, PokemonType.NORMAL, -1, [
|
[ SpeciesId.TYPE_NULL, PokemonType.NORMAL, -1, [
|
||||||
[ BiomeId.LABORATORY, BiomePoolTier.ULTRA_RARE ]
|
[ BiomeId.LABORATORY, BiomePoolTier.ULTRA_RARE ],
|
||||||
|
[ BiomeId.LABORATORY, BiomePoolTier.BOSS_SUPER_RARE ]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[ SpeciesId.SILVALLY, PokemonType.NORMAL, -1, [
|
[ SpeciesId.SILVALLY, PokemonType.NORMAL, -1, [
|
||||||
|
[ BiomeId.LABORATORY, BiomePoolTier.ULTRA_RARE ],
|
||||||
[ BiomeId.LABORATORY, BiomePoolTier.BOSS_SUPER_RARE ]
|
[ BiomeId.LABORATORY, BiomePoolTier.BOSS_SUPER_RARE ]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
@ -5773,10 +5775,12 @@ export function initBiomes() {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[ SpeciesId.POIPOLE, PokemonType.POISON, -1, [
|
[ SpeciesId.POIPOLE, PokemonType.POISON, -1, [
|
||||||
[ BiomeId.SWAMP, BiomePoolTier.ULTRA_RARE ]
|
[ BiomeId.SWAMP, BiomePoolTier.ULTRA_RARE ],
|
||||||
|
[ BiomeId.SWAMP, BiomePoolTier.BOSS_SUPER_RARE ]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[ SpeciesId.NAGANADEL, PokemonType.POISON, PokemonType.DRAGON, [
|
[ SpeciesId.NAGANADEL, PokemonType.POISON, PokemonType.DRAGON, [
|
||||||
|
[ BiomeId.SWAMP, BiomePoolTier.ULTRA_RARE ],
|
||||||
[ BiomeId.SWAMP, BiomePoolTier.BOSS_SUPER_RARE ]
|
[ BiomeId.SWAMP, BiomePoolTier.BOSS_SUPER_RARE ]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
@ -6165,10 +6169,12 @@ export function initBiomes() {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[ SpeciesId.KUBFU, PokemonType.FIGHTING, -1, [
|
[ SpeciesId.KUBFU, PokemonType.FIGHTING, -1, [
|
||||||
[ BiomeId.DOJO, BiomePoolTier.ULTRA_RARE ]
|
[ BiomeId.DOJO, BiomePoolTier.ULTRA_RARE ],
|
||||||
|
[ BiomeId.DOJO, BiomePoolTier.BOSS_SUPER_RARE ]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[ SpeciesId.URSHIFU, PokemonType.FIGHTING, PokemonType.DARK, [
|
[ SpeciesId.URSHIFU, PokemonType.FIGHTING, PokemonType.DARK, [
|
||||||
|
[ BiomeId.DOJO, BiomePoolTier.ULTRA_RARE ],
|
||||||
[ BiomeId.DOJO, BiomePoolTier.BOSS_SUPER_RARE ]
|
[ BiomeId.DOJO, BiomePoolTier.BOSS_SUPER_RARE ]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
@ -7209,7 +7215,8 @@ export function initBiomes() {
|
|||||||
],
|
],
|
||||||
[ TrainerType.SCIENTIST, [
|
[ TrainerType.SCIENTIST, [
|
||||||
[ BiomeId.DESERT, BiomePoolTier.COMMON ],
|
[ BiomeId.DESERT, BiomePoolTier.COMMON ],
|
||||||
[ BiomeId.RUINS, BiomePoolTier.COMMON ]
|
[ BiomeId.RUINS, BiomePoolTier.COMMON ],
|
||||||
|
[ BiomeId.LABORATORY, BiomePoolTier.COMMON ]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[ TrainerType.SMASHER, []],
|
[ TrainerType.SMASHER, []],
|
||||||
@ -7224,7 +7231,8 @@ export function initBiomes() {
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
[ TrainerType.SWIMMER, [
|
[ TrainerType.SWIMMER, [
|
||||||
[ BiomeId.SEA, BiomePoolTier.COMMON ]
|
[ BiomeId.SEA, BiomePoolTier.COMMON ],
|
||||||
|
[ BiomeId.SEABED, BiomePoolTier.COMMON ]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[ TrainerType.TWINS, [
|
[ TrainerType.TWINS, [
|
||||||
@ -7590,11 +7598,13 @@ export function initBiomes() {
|
|||||||
[ TrainerType.ALDER, []],
|
[ TrainerType.ALDER, []],
|
||||||
[ TrainerType.IRIS, []],
|
[ TrainerType.IRIS, []],
|
||||||
[ TrainerType.DIANTHA, []],
|
[ TrainerType.DIANTHA, []],
|
||||||
|
[ TrainerType.KUKUI, []],
|
||||||
[ TrainerType.HAU, []],
|
[ TrainerType.HAU, []],
|
||||||
|
[ TrainerType.LEON, []],
|
||||||
|
[ TrainerType.MUSTARD, []],
|
||||||
[ TrainerType.GEETA, []],
|
[ TrainerType.GEETA, []],
|
||||||
[ TrainerType.NEMONA, []],
|
[ TrainerType.NEMONA, []],
|
||||||
[ TrainerType.KIERAN, []],
|
[ TrainerType.KIERAN, []],
|
||||||
[ TrainerType.LEON, []],
|
|
||||||
[ TrainerType.RIVAL, []]
|
[ TrainerType.RIVAL, []]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -22,10 +22,12 @@ export interface SerializedTerrain {
|
|||||||
export class Terrain {
|
export class Terrain {
|
||||||
public terrainType: TerrainType;
|
public terrainType: TerrainType;
|
||||||
public turnsLeft: number;
|
public turnsLeft: number;
|
||||||
|
public maxDuration: number;
|
||||||
|
|
||||||
constructor(terrainType: TerrainType, turnsLeft?: number) {
|
constructor(terrainType: TerrainType, turnsLeft = 0, maxDuration: number = turnsLeft) {
|
||||||
this.terrainType = terrainType;
|
this.terrainType = terrainType;
|
||||||
this.turnsLeft = turnsLeft || 0;
|
this.turnsLeft = turnsLeft;
|
||||||
|
this.maxDuration = maxDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
lapse(): boolean {
|
lapse(): boolean {
|
||||||
|
@ -19,10 +19,12 @@ export interface SerializedWeather {
|
|||||||
export class Weather {
|
export class Weather {
|
||||||
public weatherType: WeatherType;
|
public weatherType: WeatherType;
|
||||||
public turnsLeft: number;
|
public turnsLeft: number;
|
||||||
|
public maxDuration: number;
|
||||||
|
|
||||||
constructor(weatherType: WeatherType, turnsLeft?: number) {
|
constructor(weatherType: WeatherType, turnsLeft = 0, maxDuration: number = turnsLeft) {
|
||||||
this.weatherType = weatherType;
|
this.weatherType = weatherType;
|
||||||
this.turnsLeft = !this.isImmutable() ? turnsLeft || 0 : 0;
|
this.turnsLeft = this.isImmutable() ? 0 : turnsLeft;
|
||||||
|
this.maxDuration = this.isImmutable() ? 0 : maxDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
lapse(): boolean {
|
lapse(): boolean {
|
||||||
|
@ -20,10 +20,13 @@ export enum ArenaEventType {
|
|||||||
export class ArenaEvent extends Event {
|
export class ArenaEvent extends Event {
|
||||||
/** The total duration of the {@linkcode ArenaEventType} */
|
/** The total duration of the {@linkcode ArenaEventType} */
|
||||||
public duration: number;
|
public duration: number;
|
||||||
constructor(eventType: ArenaEventType, duration: number) {
|
/** The maximum duration of the {@linkcode ArenaEventType} */
|
||||||
|
public maxDuration: number;
|
||||||
|
constructor(eventType: ArenaEventType, duration: number, maxDuration: number = duration) {
|
||||||
super(eventType);
|
super(eventType);
|
||||||
|
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
|
this.maxDuration = maxDuration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Container class for {@linkcode ArenaEventType.WEATHER_CHANGED} events */
|
/** Container class for {@linkcode ArenaEventType.WEATHER_CHANGED} events */
|
||||||
@ -32,8 +35,8 @@ export class WeatherChangedEvent extends ArenaEvent {
|
|||||||
public oldWeatherType: WeatherType;
|
public oldWeatherType: WeatherType;
|
||||||
/** The {@linkcode WeatherType} being set */
|
/** The {@linkcode WeatherType} being set */
|
||||||
public newWeatherType: WeatherType;
|
public newWeatherType: WeatherType;
|
||||||
constructor(oldWeatherType: WeatherType, newWeatherType: WeatherType, duration: number) {
|
constructor(oldWeatherType: WeatherType, newWeatherType: WeatherType, duration: number, maxDuration?: number) {
|
||||||
super(ArenaEventType.WEATHER_CHANGED, duration);
|
super(ArenaEventType.WEATHER_CHANGED, duration, maxDuration);
|
||||||
|
|
||||||
this.oldWeatherType = oldWeatherType;
|
this.oldWeatherType = oldWeatherType;
|
||||||
this.newWeatherType = newWeatherType;
|
this.newWeatherType = newWeatherType;
|
||||||
@ -45,8 +48,8 @@ export class TerrainChangedEvent extends ArenaEvent {
|
|||||||
public oldTerrainType: TerrainType;
|
public oldTerrainType: TerrainType;
|
||||||
/** The {@linkcode TerrainType} being set */
|
/** The {@linkcode TerrainType} being set */
|
||||||
public newTerrainType: TerrainType;
|
public newTerrainType: TerrainType;
|
||||||
constructor(oldTerrainType: TerrainType, newTerrainType: TerrainType, duration: number) {
|
constructor(oldTerrainType: TerrainType, newTerrainType: TerrainType, duration: number, maxDuration?: number) {
|
||||||
super(ArenaEventType.TERRAIN_CHANGED, duration);
|
super(ArenaEventType.TERRAIN_CHANGED, duration, maxDuration);
|
||||||
|
|
||||||
this.oldTerrainType = oldTerrainType;
|
this.oldTerrainType = oldTerrainType;
|
||||||
this.newTerrainType = newTerrainType;
|
this.newTerrainType = newTerrainType;
|
||||||
@ -68,10 +71,11 @@ export class TagAddedEvent extends ArenaEvent {
|
|||||||
arenaTagType: ArenaTagType,
|
arenaTagType: ArenaTagType,
|
||||||
arenaTagSide: ArenaTagSide,
|
arenaTagSide: ArenaTagSide,
|
||||||
duration: number,
|
duration: number,
|
||||||
|
maxDuration?: number,
|
||||||
arenaTagLayers?: number,
|
arenaTagLayers?: number,
|
||||||
arenaTagMaxLayers?: number,
|
arenaTagMaxLayers?: number,
|
||||||
) {
|
) {
|
||||||
super(ArenaEventType.TAG_ADDED, duration);
|
super(ArenaEventType.TAG_ADDED, duration, maxDuration);
|
||||||
|
|
||||||
this.arenaTagType = arenaTagType;
|
this.arenaTagType = arenaTagType;
|
||||||
this.arenaTagSide = arenaTagSide;
|
this.arenaTagSide = arenaTagSide;
|
||||||
|
@ -344,7 +344,7 @@ export class Arena {
|
|||||||
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, weatherDuration);
|
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, weatherDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.weather = weather ? new Weather(weather, weatherDuration.value) : null;
|
this.weather = weather ? new Weather(weather, weatherDuration.value, weatherDuration.value) : null;
|
||||||
this.eventTarget.dispatchEvent(
|
this.eventTarget.dispatchEvent(
|
||||||
new WeatherChangedEvent(oldWeatherType, this.weather?.weatherType!, this.weather?.turnsLeft!),
|
new WeatherChangedEvent(oldWeatherType, this.weather?.weatherType!, this.weather?.turnsLeft!),
|
||||||
); // TODO: is this bang correct?
|
); // TODO: is this bang correct?
|
||||||
@ -425,7 +425,7 @@ export class Arena {
|
|||||||
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, terrainDuration);
|
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, terrainDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.terrain = terrain ? new Terrain(terrain, terrainDuration.value) : null;
|
this.terrain = terrain ? new Terrain(terrain, terrainDuration.value, terrainDuration.value) : null;
|
||||||
|
|
||||||
this.eventTarget.dispatchEvent(
|
this.eventTarget.dispatchEvent(
|
||||||
new TerrainChangedEvent(oldTerrainType, this.terrain?.terrainType!, this.terrain?.turnsLeft!),
|
new TerrainChangedEvent(oldTerrainType, this.terrain?.terrainType!, this.terrain?.turnsLeft!),
|
||||||
@ -732,8 +732,8 @@ export class Arena {
|
|||||||
existingTag.onOverlap(globalScene.getPokemonById(sourceId));
|
existingTag.onOverlap(globalScene.getPokemonById(sourceId));
|
||||||
|
|
||||||
if (existingTag instanceof EntryHazardTag) {
|
if (existingTag instanceof EntryHazardTag) {
|
||||||
const { tagType, side, turnCount, layers, maxLayers } = existingTag;
|
const { tagType, side, turnCount, maxDuration, layers, maxLayers } = existingTag as EntryHazardTag;
|
||||||
this.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, layers, maxLayers));
|
this.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, maxDuration, layers, maxLayers));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -748,7 +748,7 @@ export class Arena {
|
|||||||
const { layers = 0, maxLayers = 0 } = newTag instanceof EntryHazardTag ? 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, newTag.maxDuration, layers, maxLayers),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,8 +47,12 @@ export class ArenaData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.biome = source.biome;
|
this.biome = source.biome;
|
||||||
this.weather = source.weather ? new Weather(source.weather.weatherType, source.weather.turnsLeft) : null;
|
this.weather = source.weather
|
||||||
this.terrain = source.terrain ? new Terrain(source.terrain.terrainType, source.terrain.turnsLeft) : null;
|
? new Weather(source.weather.weatherType, source.weather.turnsLeft, source.weather.maxDuration)
|
||||||
|
: null;
|
||||||
|
this.terrain = source.terrain
|
||||||
|
? new Terrain(source.terrain.terrainType, source.terrain.turnsLeft, source.terrain.maxDuration)
|
||||||
|
: null;
|
||||||
this.positionalTags = source.positionalTags ?? [];
|
this.positionalTags = source.positionalTags ?? [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1021,6 +1021,7 @@ export class GameData {
|
|||||||
WeatherType.NONE,
|
WeatherType.NONE,
|
||||||
globalScene.arena.weather?.weatherType!,
|
globalScene.arena.weather?.weatherType!,
|
||||||
globalScene.arena.weather?.turnsLeft!,
|
globalScene.arena.weather?.turnsLeft!,
|
||||||
|
globalScene.arena.weather?.maxDuration!,
|
||||||
),
|
),
|
||||||
); // TODO: is this bang correct?
|
); // TODO: is this bang correct?
|
||||||
|
|
||||||
@ -1030,6 +1031,7 @@ export class GameData {
|
|||||||
TerrainType.NONE,
|
TerrainType.NONE,
|
||||||
globalScene.arena.terrain?.terrainType!,
|
globalScene.arena.terrain?.terrainType!,
|
||||||
globalScene.arena.terrain?.turnsLeft!,
|
globalScene.arena.terrain?.turnsLeft!,
|
||||||
|
globalScene.arena.terrain?.maxDuration!,
|
||||||
),
|
),
|
||||||
); // TODO: is this bang correct?
|
); // TODO: is this bang correct?
|
||||||
|
|
||||||
@ -1039,12 +1041,14 @@ export class GameData {
|
|||||||
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 EntryHazardTag) {
|
if (tag instanceof EntryHazardTag) {
|
||||||
const { tagType, side, turnCount, layers, maxLayers } = tag as EntryHazardTag;
|
const { tagType, side, turnCount, maxDuration, 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, maxDuration, layers, maxLayers),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
globalScene.arena.eventTarget.dispatchEvent(new TagAddedEvent(tag.tagType, tag.side, tag.turnCount));
|
globalScene.arena.eventTarget.dispatchEvent(
|
||||||
|
new TagAddedEvent(tag.tagType, tag.side, tag.turnCount, tag.maxDuration),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
|||||||
this.fieldEffectInfo.push({
|
this.fieldEffectInfo.push({
|
||||||
name,
|
name,
|
||||||
effectType: arenaEffectType,
|
effectType: arenaEffectType,
|
||||||
maxDuration: tagAddedEvent.duration,
|
maxDuration: tagAddedEvent.maxDuration,
|
||||||
duration: tagAddedEvent.duration,
|
duration: tagAddedEvent.duration,
|
||||||
tagType: tagAddedEvent.arenaTagType,
|
tagType: tagAddedEvent.arenaTagType,
|
||||||
});
|
});
|
||||||
@ -353,7 +353,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
|||||||
),
|
),
|
||||||
effectType:
|
effectType:
|
||||||
fieldEffectChangedEvent instanceof WeatherChangedEvent ? ArenaEffectType.WEATHER : ArenaEffectType.TERRAIN,
|
fieldEffectChangedEvent instanceof WeatherChangedEvent ? ArenaEffectType.WEATHER : ArenaEffectType.TERRAIN,
|
||||||
maxDuration: fieldEffectChangedEvent.duration,
|
maxDuration: fieldEffectChangedEvent.maxDuration,
|
||||||
duration: fieldEffectChangedEvent.duration,
|
duration: fieldEffectChangedEvent.duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,19 +17,17 @@ export function removeCookie(cName: string): void {
|
|||||||
|
|
||||||
export function getCookie(cName: string): string {
|
export function getCookie(cName: string): string {
|
||||||
// check if there are multiple cookies with the same name and delete them
|
// check if there are multiple cookies with the same name and delete them
|
||||||
if (document.cookie.split(";").filter(c => c.includes(cName)).length > 1) {
|
if (document.cookie.split(";").filter(c => c.trim().includes(cName)).length > 1) {
|
||||||
removeCookie(cName);
|
removeCookie(cName);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const name = `${cName}=`;
|
const name = `${cName}=`;
|
||||||
const ca = document.cookie.split(";");
|
const cookieArray = document.cookie.split(";");
|
||||||
for (let c of ca) {
|
// Check all cookies in the document and see if any of them match, grabbing the first one whose value lines up
|
||||||
// ⚠️ DO NOT REPLACE THIS WITH C = C.TRIM() - IT BREAKS IN NON-CHROMIUM BROWSERS ⚠️
|
for (const cookie of cookieArray) {
|
||||||
while (c.charAt(0) === " ") {
|
const cookieTrimmed = cookie.trim();
|
||||||
c = c.substring(1);
|
if (cookieTrimmed.startsWith(name)) {
|
||||||
}
|
return cookieTrimmed.slice(name.length, cookieTrimmed.length);
|
||||||
if (c.indexOf(name) === 0) {
|
|
||||||
return c.substring(name.length, c.length);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
@ -30,12 +30,13 @@ describe("Ability Duplication", () => {
|
|||||||
.enemyMoveset(MoveId.SPLASH);
|
.enemyMoveset(MoveId.SPLASH);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: Find a cleaner way of checking ability duplication effects than suppressing the ability
|
||||||
it("huge power should only be applied once if both normal and passive", async () => {
|
it("huge power should only be applied once if both normal and passive", async () => {
|
||||||
game.override.passiveAbility(AbilityId.HUGE_POWER);
|
game.override.passiveAbility(AbilityId.HUGE_POWER);
|
||||||
|
|
||||||
await game.classicMode.startBattle([SpeciesId.MAGIKARP]);
|
await game.classicMode.startBattle([SpeciesId.MAGIKARP]);
|
||||||
|
|
||||||
const [magikarp] = game.scene.getPlayerField();
|
const magikarp = game.field.getPlayerPokemon();
|
||||||
const magikarpAttack = magikarp.getEffectiveStat(Stat.ATK);
|
const magikarpAttack = magikarp.getEffectiveStat(Stat.ATK);
|
||||||
|
|
||||||
magikarp.summonData.abilitySuppressed = true;
|
magikarp.summonData.abilitySuppressed = true;
|
||||||
@ -48,7 +49,7 @@ describe("Ability Duplication", () => {
|
|||||||
|
|
||||||
await game.classicMode.startBattle([SpeciesId.MAGIKARP]);
|
await game.classicMode.startBattle([SpeciesId.MAGIKARP]);
|
||||||
|
|
||||||
const [magikarp] = game.scene.getPlayerField();
|
const magikarp = game.field.getPlayerPokemon();
|
||||||
const magikarpAttack = magikarp.getEffectiveStat(Stat.ATK);
|
const magikarpAttack = magikarp.getEffectiveStat(Stat.ATK);
|
||||||
|
|
||||||
magikarp.summonData.abilitySuppressed = true;
|
magikarp.summonData.abilitySuppressed = true;
|
||||||
|
@ -5,8 +5,7 @@ import { MoveId } from "#enums/move-id";
|
|||||||
import { MoveResult } from "#enums/move-result";
|
import { MoveResult } from "#enums/move-result";
|
||||||
import { PokemonAnimType } from "#enums/pokemon-anim-type";
|
import { PokemonAnimType } from "#enums/pokemon-anim-type";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import type { EffectiveStat } from "#enums/stat";
|
import { EFFECTIVE_STATS } from "#enums/stat";
|
||||||
import { Stat } from "#enums/stat";
|
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
import { GameManager } from "#test/test-utils/game-manager";
|
import { GameManager } from "#test/test-utils/game-manager";
|
||||||
@ -48,23 +47,24 @@ describe("Abilities - Commander", () => {
|
|||||||
|
|
||||||
const [tatsugiri, dondozo] = game.scene.getPlayerField();
|
const [tatsugiri, dondozo] = game.scene.getPlayerField();
|
||||||
|
|
||||||
const affectedStats: EffectiveStat[] = [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD];
|
|
||||||
|
|
||||||
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
|
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
|
||||||
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
|
expect(dondozo).toHaveBattlerTag(BattlerTagType.COMMANDED);
|
||||||
affectedStats.forEach(stat => expect(dondozo.getStatStage(stat)).toBe(2));
|
EFFECTIVE_STATS.forEach(stat => {
|
||||||
|
expect(dondozo).toHaveStatStage(stat, 2);
|
||||||
game.move.select(MoveId.SPLASH, 1);
|
});
|
||||||
|
|
||||||
|
game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER_2);
|
||||||
expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy();
|
expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy();
|
||||||
|
|
||||||
// Force both enemies to target the Tatsugiri
|
// Force both enemies to target the Tatsugiri
|
||||||
await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
|
await game.move.forceEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
|
||||||
await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
|
await game.move.forceEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
|
||||||
|
|
||||||
await game.phaseInterceptor.to("BerryPhase", false);
|
await game.toEndOfTurn();
|
||||||
game.scene.getEnemyField().forEach(enemy => expect(enemy.getLastXMoves(1)[0].result).toBe(MoveResult.MISS));
|
const [enemy1, enemy2] = game.scene.getEnemyField();
|
||||||
expect(tatsugiri.isFullHp()).toBeTruthy();
|
expect(enemy1).toHaveUsedMove({ move: MoveId.TACKLE, result: MoveResult.MISS });
|
||||||
|
expect(enemy2).toHaveUsedMove({ move: MoveId.TACKLE, result: MoveResult.MISS });
|
||||||
|
expect(tatsugiri).toHaveFullHp();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should activate when a Dondozo switches in and cancel the source's move", async () => {
|
it("should activate when a Dondozo switches in and cancel the source's move", async () => {
|
||||||
@ -72,7 +72,7 @@ describe("Abilities - Commander", () => {
|
|||||||
|
|
||||||
await game.classicMode.startBattle([SpeciesId.TATSUGIRI, SpeciesId.MAGIKARP, SpeciesId.DONDOZO]);
|
await game.classicMode.startBattle([SpeciesId.TATSUGIRI, SpeciesId.MAGIKARP, SpeciesId.DONDOZO]);
|
||||||
|
|
||||||
const tatsugiri = game.scene.getPlayerField()[0];
|
const [tatsugiri, _, dondozo] = game.scene.getPlayerParty();
|
||||||
|
|
||||||
game.move.select(MoveId.LIQUIDATION, 0, BattlerIndex.ENEMY);
|
game.move.select(MoveId.LIQUIDATION, 0, BattlerIndex.ENEMY);
|
||||||
game.doSwitchPokemon(2);
|
game.doSwitchPokemon(2);
|
||||||
@ -80,12 +80,11 @@ describe("Abilities - Commander", () => {
|
|||||||
await game.phaseInterceptor.to("MovePhase", false);
|
await game.phaseInterceptor.to("MovePhase", false);
|
||||||
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
|
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
|
||||||
|
|
||||||
const dondozo = game.scene.getPlayerField()[1];
|
|
||||||
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
|
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
|
||||||
|
|
||||||
await game.phaseInterceptor.to("BerryPhase", false);
|
await game.phaseInterceptor.to("BerryPhase", false);
|
||||||
expect(tatsugiri.getMoveHistory()).toHaveLength(0);
|
expect(tatsugiri.getMoveHistory()).toHaveLength(0);
|
||||||
expect(game.scene.getEnemyField()[0].isFullHp()).toBeTruthy();
|
expect(game.field.getEnemyPokemon()).toHaveFullHp();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("source should reenter the field when Dondozo faints", async () => {
|
it("source should reenter the field when Dondozo faints", async () => {
|
||||||
@ -192,26 +191,26 @@ describe("Abilities - Commander", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should interrupt the source's semi-invulnerability", async () => {
|
it("should interrupt the source's semi-invulnerability", async () => {
|
||||||
game.override.moveset([MoveId.SPLASH, MoveId.DIVE]).enemyMoveset(MoveId.SPLASH);
|
|
||||||
|
|
||||||
await game.classicMode.startBattle([SpeciesId.TATSUGIRI, SpeciesId.MAGIKARP, SpeciesId.DONDOZO]);
|
await game.classicMode.startBattle([SpeciesId.TATSUGIRI, SpeciesId.MAGIKARP, SpeciesId.DONDOZO]);
|
||||||
|
|
||||||
const tatsugiri = game.scene.getPlayerField()[0];
|
const [tatsugiri, , dondozo] = game.scene.getPlayerParty();
|
||||||
|
|
||||||
game.move.select(MoveId.DIVE, 0, BattlerIndex.ENEMY);
|
game.move.use(MoveId.DIVE, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
||||||
game.move.select(MoveId.SPLASH, 1);
|
game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER_2);
|
||||||
|
await game.move.forceEnemyMove(MoveId.SPLASH);
|
||||||
|
await game.move.forceEnemyMove(MoveId.SPLASH);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
expect(tatsugiri.getTag(BattlerTagType.UNDERWATER)).toBeDefined();
|
expect(tatsugiri).toHaveBattlerTag(BattlerTagType.UNDERWATER);
|
||||||
|
|
||||||
game.doSwitchPokemon(2);
|
game.doSwitchPokemon(2);
|
||||||
|
|
||||||
await game.phaseInterceptor.to("MovePhase", false);
|
await game.phaseInterceptor.to("MovePhase", false);
|
||||||
const dondozo = game.scene.getPlayerField()[1];
|
|
||||||
expect(tatsugiri.getTag(BattlerTagType.UNDERWATER)).toBeUndefined();
|
|
||||||
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
|
|
||||||
|
|
||||||
await game.toNextTurn();
|
expect(tatsugiri).not.toHaveBattlerTag(BattlerTagType.UNDERWATER);
|
||||||
const enemy = game.scene.getEnemyField()[0];
|
expect(dondozo).toHaveBattlerTag(BattlerTagType.COMMANDED);
|
||||||
expect(enemy.isFullHp()).toBeTruthy();
|
|
||||||
|
await game.toEndOfTurn();
|
||||||
|
|
||||||
|
expect(game.field.getEnemyPokemon()).toHaveFullHp();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -74,8 +74,8 @@ describe("Abilities - Dancer", () => {
|
|||||||
.enemyLevel(10);
|
.enemyLevel(10);
|
||||||
await game.classicMode.startBattle([SpeciesId.ORICORIO, SpeciesId.FEEBAS]);
|
await game.classicMode.startBattle([SpeciesId.ORICORIO, SpeciesId.FEEBAS]);
|
||||||
|
|
||||||
const [oricorio] = game.scene.getPlayerField();
|
const oricorio = game.field.getPlayerPokemon();
|
||||||
const [, shuckle2] = game.scene.getEnemyField();
|
const shuckle2 = game.scene.getEnemyField()[1];
|
||||||
|
|
||||||
game.move.select(MoveId.REVELATION_DANCE, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2);
|
game.move.select(MoveId.REVELATION_DANCE, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2);
|
||||||
game.move.select(MoveId.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2);
|
game.move.select(MoveId.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2);
|
||||||
|
@ -58,12 +58,12 @@ describe("Abilities - Flower Gift", () => {
|
|||||||
const ally_target = allyAttacker ? BattlerIndex.ENEMY : null;
|
const ally_target = allyAttacker ? BattlerIndex.ENEMY : null;
|
||||||
|
|
||||||
await game.classicMode.startBattle([SpeciesId.CHERRIM, SpeciesId.MAGIKARP]);
|
await game.classicMode.startBattle([SpeciesId.CHERRIM, SpeciesId.MAGIKARP]);
|
||||||
const target = allyAttacker ? game.scene.getEnemyField()[0] : game.scene.getPlayerField()[1];
|
const target = allyAttacker ? game.field.getEnemyPokemon() : game.scene.getPlayerField()[1];
|
||||||
const initialHp = target.getMaxHp();
|
const initialHp = target.getMaxHp();
|
||||||
|
|
||||||
// Override the ability for the target and attacker only
|
// Override the ability for the target and attacker only
|
||||||
vi.spyOn(game.scene.getPlayerField()[1], "getAbility").mockReturnValue(allAbilities[allyAbility]);
|
vi.spyOn(game.scene.getPlayerField()[1], "getAbility").mockReturnValue(allAbilities[allyAbility]);
|
||||||
vi.spyOn(game.scene.getEnemyField()[0], "getAbility").mockReturnValue(allAbilities[enemyAbility]);
|
vi.spyOn(game.field.getEnemyPokemon(), "getAbility").mockReturnValue(allAbilities[enemyAbility]);
|
||||||
|
|
||||||
// turn 1
|
// turn 1
|
||||||
game.move.select(MoveId.SUNNY_DAY, 0);
|
game.move.select(MoveId.SUNNY_DAY, 0);
|
||||||
|
@ -66,7 +66,7 @@ describe("Abilities - Flower Veil", () => {
|
|||||||
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.BULBASAUR]);
|
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.BULBASAUR]);
|
||||||
|
|
||||||
// Clear the ability of the ally to isolate the test
|
// Clear the ability of the ally to isolate the test
|
||||||
const ally = game.scene.getPlayerField()[1]!;
|
const ally = game.scene.getPlayerField()[1];
|
||||||
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
|
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
|
||||||
game.move.select(MoveId.SPLASH);
|
game.move.select(MoveId.SPLASH);
|
||||||
game.move.select(MoveId.SPLASH);
|
game.move.select(MoveId.SPLASH);
|
||||||
|
@ -76,7 +76,7 @@ describe("Abilities - Forecast", () => {
|
|||||||
|
|
||||||
vi.spyOn(game.scene.getPlayerParty()[5], "getAbility").mockReturnValue(allAbilities[AbilityId.CLOUD_NINE]);
|
vi.spyOn(game.scene.getPlayerParty()[5], "getAbility").mockReturnValue(allAbilities[AbilityId.CLOUD_NINE]);
|
||||||
|
|
||||||
const castform = game.scene.getPlayerField()[0];
|
const castform = game.field.getPlayerPokemon();
|
||||||
expect(castform.formIndex).toBe(NORMAL_FORM);
|
expect(castform.formIndex).toBe(NORMAL_FORM);
|
||||||
|
|
||||||
game.move.select(MoveId.RAIN_DANCE);
|
game.move.select(MoveId.RAIN_DANCE);
|
||||||
|
@ -64,7 +64,7 @@ describe("Abilities - Magic Bounce", () => {
|
|||||||
game.move.use(MoveId.SPLASH, 1);
|
game.move.use(MoveId.SPLASH, 1);
|
||||||
await game.phaseInterceptor.to("BerryPhase");
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
const user = game.scene.getPlayerField()[0];
|
const user = game.field.getPlayerPokemon();
|
||||||
expect(user.getStatStage(Stat.ATK)).toBe(-2);
|
expect(user.getStatStage(Stat.ATK)).toBe(-2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -92,8 +92,7 @@ describe("Ability - Mirror Armor", () => {
|
|||||||
game.override.battleStyle("double").enemyAbility(AbilityId.MIRROR_ARMOR).ability(AbilityId.INTIMIDATE);
|
game.override.battleStyle("double").enemyAbility(AbilityId.MIRROR_ARMOR).ability(AbilityId.INTIMIDATE);
|
||||||
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.CHARMANDER]);
|
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.CHARMANDER]);
|
||||||
|
|
||||||
const [enemy1, enemy2] = game.scene.getEnemyField();
|
const [player1, player2, enemy1, enemy2] = game.scene.getField();
|
||||||
const [player1, player2] = game.scene.getPlayerField();
|
|
||||||
|
|
||||||
// Enemy has intimidate, enemy should lose -1 atk
|
// Enemy has intimidate, enemy should lose -1 atk
|
||||||
game.move.select(MoveId.SPLASH);
|
game.move.select(MoveId.SPLASH);
|
||||||
|
@ -58,6 +58,6 @@ describe("Abilities - No Guard", () => {
|
|||||||
|
|
||||||
await game.classicMode.startBattle();
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
expect(game.scene.getEnemyField().length).toBe(2);
|
expect(game.scene.getEnemyField()).toHaveLength(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -37,9 +37,7 @@ describe("Abilities - Storm Drain", () => {
|
|||||||
it("should redirect water type moves", async () => {
|
it("should redirect water type moves", async () => {
|
||||||
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MAGIKARP]);
|
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MAGIKARP]);
|
||||||
|
|
||||||
const enemy1 = game.scene.getEnemyField()[0];
|
const [enemy1, enemy2] = game.scene.getEnemyField();
|
||||||
const enemy2 = game.scene.getEnemyField()[1];
|
|
||||||
|
|
||||||
game.field.mockAbility(enemy2, AbilityId.STORM_DRAIN);
|
game.field.mockAbility(enemy2, AbilityId.STORM_DRAIN);
|
||||||
|
|
||||||
game.move.select(MoveId.WATER_GUN, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
game.move.select(MoveId.WATER_GUN, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
||||||
@ -53,8 +51,7 @@ describe("Abilities - Storm Drain", () => {
|
|||||||
game.override.moveset([MoveId.SPLASH, MoveId.AERIAL_ACE]);
|
game.override.moveset([MoveId.SPLASH, MoveId.AERIAL_ACE]);
|
||||||
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MAGIKARP]);
|
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MAGIKARP]);
|
||||||
|
|
||||||
const enemy1 = game.scene.getEnemyField()[0];
|
const [enemy1, enemy2] = game.scene.getEnemyField();
|
||||||
const enemy2 = game.scene.getEnemyField()[1];
|
|
||||||
|
|
||||||
game.field.mockAbility(enemy2, AbilityId.STORM_DRAIN);
|
game.field.mockAbility(enemy2, AbilityId.STORM_DRAIN);
|
||||||
|
|
||||||
@ -83,8 +80,7 @@ describe("Abilities - Storm Drain", () => {
|
|||||||
game.override.ability(AbilityId.NORMALIZE);
|
game.override.ability(AbilityId.NORMALIZE);
|
||||||
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MAGIKARP]);
|
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MAGIKARP]);
|
||||||
|
|
||||||
const enemy1 = game.scene.getEnemyField()[0];
|
const [enemy1, enemy2] = game.scene.getEnemyField();
|
||||||
const enemy2 = game.scene.getEnemyField()[1];
|
|
||||||
game.field.mockAbility(enemy2, AbilityId.STORM_DRAIN);
|
game.field.mockAbility(enemy2, AbilityId.STORM_DRAIN);
|
||||||
|
|
||||||
game.move.select(MoveId.WATER_GUN, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
game.move.select(MoveId.WATER_GUN, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
||||||
@ -98,8 +94,7 @@ describe("Abilities - Storm Drain", () => {
|
|||||||
game.override.ability(AbilityId.LIQUID_VOICE);
|
game.override.ability(AbilityId.LIQUID_VOICE);
|
||||||
await game.classicMode.startBattle([SpeciesId.FEEBAS]);
|
await game.classicMode.startBattle([SpeciesId.FEEBAS]);
|
||||||
|
|
||||||
const enemy1 = game.scene.getEnemyField()[0];
|
const [enemy1, enemy2] = game.scene.getEnemyField();
|
||||||
const enemy2 = game.scene.getEnemyField()[1];
|
|
||||||
|
|
||||||
game.field.mockAbility(enemy2, AbilityId.STORM_DRAIN);
|
game.field.mockAbility(enemy2, AbilityId.STORM_DRAIN);
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ describe("Abilities - Unburden", () => {
|
|||||||
.startingHeldItems([{ name: "WIDE_LENS" }]);
|
.startingHeldItems([{ name: "WIDE_LENS" }]);
|
||||||
await game.classicMode.startBattle([SpeciesId.TREECKO, SpeciesId.FEEBAS, SpeciesId.MILOTIC]);
|
await game.classicMode.startBattle([SpeciesId.TREECKO, SpeciesId.FEEBAS, SpeciesId.MILOTIC]);
|
||||||
|
|
||||||
const treecko = game.scene.getPlayerField()[0];
|
const treecko = game.field.getPlayerPokemon();
|
||||||
const treeckoInitialHeldItems = getHeldItemCount(treecko);
|
const treeckoInitialHeldItems = getHeldItemCount(treecko);
|
||||||
const initialSpeed = treecko.getStat(Stat.SPD);
|
const initialSpeed = treecko.getStat(Stat.SPD);
|
||||||
|
|
||||||
@ -374,7 +374,7 @@ describe("Abilities - Unburden", () => {
|
|||||||
game.doSelectPartyPokemon(0, "RevivalBlessingPhase");
|
game.doSelectPartyPokemon(0, "RevivalBlessingPhase");
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
expect(game.scene.getPlayerField()[0]).toBe(treecko);
|
expect(game.field.getPlayerPokemon()).toBe(treecko);
|
||||||
expect(getHeldItemCount(treecko)).toBeLessThan(treeckoInitialHeldItems);
|
expect(getHeldItemCount(treecko)).toBeLessThan(treeckoInitialHeldItems);
|
||||||
expect(treecko.getEffectiveStat(Stat.SPD)).toBe(initialSpeed);
|
expect(treecko.getEffectiveStat(Stat.SPD)).toBe(initialSpeed);
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,7 @@ import { GameManager } from "#test/test-utils/game-manager";
|
|||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
// TODO: These tests are stupid and need to be redone
|
||||||
describe("Escape chance calculations", () => {
|
describe("Escape chance calculations", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
@ -31,7 +31,7 @@ describe("Items - Double Battle Chance Boosters", () => {
|
|||||||
|
|
||||||
await game.classicMode.startBattle();
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
expect(game.scene.getEnemyField().length).toBe(2);
|
expect(game.scene.getEnemyField()).toHaveLength(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should guarantee double boss battle with 3 unique tiers", async () => {
|
it("should guarantee double boss battle with 3 unique tiers", async () => {
|
||||||
@ -41,7 +41,7 @@ describe("Items - Double Battle Chance Boosters", () => {
|
|||||||
|
|
||||||
const enemyField = game.scene.getEnemyField();
|
const enemyField = game.scene.getEnemyField();
|
||||||
|
|
||||||
expect(enemyField.length).toBe(2);
|
expect(enemyField).toHaveLength(2);
|
||||||
expect(enemyField[0].isBoss()).toBe(true);
|
expect(enemyField[0].isBoss()).toBe(true);
|
||||||
expect(enemyField[1].isBoss()).toBe(true);
|
expect(enemyField[1].isBoss()).toBe(true);
|
||||||
});
|
});
|
||||||
|
@ -44,7 +44,7 @@ describe("Items - Grip Claw", () => {
|
|||||||
it("should steal items on contact and only from the attack target", async () => {
|
it("should steal items on contact and only from the attack target", async () => {
|
||||||
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MILOTIC]);
|
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MILOTIC]);
|
||||||
|
|
||||||
const [playerPokemon] = game.scene.getPlayerField();
|
const playerPokemon = game.field.getPlayerPokemon();
|
||||||
|
|
||||||
const gripClaw = playerPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier;
|
const gripClaw = playerPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier;
|
||||||
vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100);
|
vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100);
|
||||||
@ -73,7 +73,7 @@ describe("Items - Grip Claw", () => {
|
|||||||
it("should not steal items when using a targetted, non attack move", async () => {
|
it("should not steal items when using a targetted, non attack move", async () => {
|
||||||
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MILOTIC]);
|
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.MILOTIC]);
|
||||||
|
|
||||||
const [playerPokemon] = game.scene.getPlayerField();
|
const playerPokemon = game.field.getPlayerPokemon();
|
||||||
|
|
||||||
const gripClaw = playerPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier;
|
const gripClaw = playerPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier;
|
||||||
vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100);
|
vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100);
|
||||||
|
@ -103,7 +103,7 @@ describe("Items - Multi Lens", () => {
|
|||||||
|
|
||||||
await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.FEEBAS]);
|
await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.FEEBAS]);
|
||||||
|
|
||||||
const [magikarp] = game.scene.getPlayerField();
|
const magikarp = game.field.getPlayerPokemon();
|
||||||
|
|
||||||
game.move.select(MoveId.SWIFT, 0);
|
game.move.select(MoveId.SWIFT, 0);
|
||||||
game.move.select(MoveId.SPLASH, 1);
|
game.move.select(MoveId.SPLASH, 1);
|
||||||
|
@ -102,7 +102,7 @@ describe("Moves - Ability-Ignoring Moves", () => {
|
|||||||
|
|
||||||
// Both the initial and redirected instruct use ignored sturdy
|
// Both the initial and redirected instruct use ignored sturdy
|
||||||
const [enemy1, enemy2] = game.scene.getEnemyField();
|
const [enemy1, enemy2] = game.scene.getEnemyField();
|
||||||
expect(enemy1.isFainted()).toBe(true);
|
expect(enemy1).toHaveFainted();
|
||||||
expect(enemy2.isFainted()).toBe(true);
|
expect(enemy2).toHaveFainted();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { AbilityId } from "#enums/ability-id";
|
import { AbilityId } from "#enums/ability-id";
|
||||||
|
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||||
import { MoveId } from "#enums/move-id";
|
import { MoveId } from "#enums/move-id";
|
||||||
import { SpeciesId } from "#enums/species-id";
|
import { SpeciesId } from "#enums/species-id";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
@ -32,26 +33,21 @@ describe("Moves - Defog", () => {
|
|||||||
.enemyMoveset([MoveId.DEFOG, MoveId.GROWL]);
|
.enemyMoveset([MoveId.DEFOG, MoveId.GROWL]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: Refactor these tests they suck ass
|
||||||
it("should not allow Safeguard to be active", async () => {
|
it("should not allow Safeguard to be active", async () => {
|
||||||
await game.classicMode.startBattle([SpeciesId.REGIELEKI]);
|
await game.classicMode.startBattle([SpeciesId.REGIELEKI]);
|
||||||
|
|
||||||
const playerPokemon = game.scene.getPlayerField();
|
game.scene.arena.addTag(ArenaTagType.SAFEGUARD, 0, 0, 0);
|
||||||
const enemyPokemon = game.scene.getEnemyField();
|
|
||||||
|
|
||||||
game.move.select(MoveId.SAFEGUARD);
|
game.move.use(MoveId.DEFOG);
|
||||||
await game.move.selectEnemyMove(MoveId.DEFOG);
|
await game.toEndOfTurn();
|
||||||
await game.phaseInterceptor.to("BerryPhase");
|
|
||||||
|
|
||||||
expect(playerPokemon[0].isSafeguarded(enemyPokemon[0])).toBe(false);
|
expect(game).not.toHaveArenaTag(ArenaTagType.SAFEGUARD);
|
||||||
|
|
||||||
expect(true).toBe(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not allow Mist to be active", async () => {
|
it("should not allow Mist to be active", async () => {
|
||||||
await game.classicMode.startBattle([SpeciesId.REGIELEKI]);
|
await game.classicMode.startBattle([SpeciesId.REGIELEKI]);
|
||||||
|
|
||||||
const playerPokemon = game.scene.getPlayerField();
|
|
||||||
|
|
||||||
game.move.select(MoveId.MIST);
|
game.move.select(MoveId.MIST);
|
||||||
await game.move.selectEnemyMove(MoveId.DEFOG);
|
await game.move.selectEnemyMove(MoveId.DEFOG);
|
||||||
|
|
||||||
@ -62,8 +58,6 @@ describe("Moves - Defog", () => {
|
|||||||
|
|
||||||
await game.phaseInterceptor.to("BerryPhase");
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
expect(playerPokemon[0].getStatStage(Stat.ATK)).toBe(-1);
|
expect(game.field.getPlayerPokemon()).toHaveStatStage(Stat.ATK, -1);
|
||||||
|
|
||||||
expect(true).toBe(true);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -160,11 +160,7 @@ describe("Moves - Destiny Bond", () => {
|
|||||||
game.override.moveset([MoveId.DESTINY_BOND, MoveId.CRUNCH]).battleStyle("double");
|
game.override.moveset([MoveId.DESTINY_BOND, MoveId.CRUNCH]).battleStyle("double");
|
||||||
await game.classicMode.startBattle([SpeciesId.SHEDINJA, SpeciesId.BULBASAUR, SpeciesId.SQUIRTLE]);
|
await game.classicMode.startBattle([SpeciesId.SHEDINJA, SpeciesId.BULBASAUR, SpeciesId.SQUIRTLE]);
|
||||||
|
|
||||||
const enemyPokemon0 = game.scene.getEnemyField()[0];
|
const [playerPokemon0, playerPokemon1, enemyPokemon0, enemyPokemon1] = game.scene.getField();
|
||||||
const enemyPokemon1 = game.scene.getEnemyField()[1];
|
|
||||||
const playerPokemon0 = game.scene.getPlayerField()[0];
|
|
||||||
const playerPokemon1 = game.scene.getPlayerField()[1];
|
|
||||||
|
|
||||||
// Shedinja uses Destiny Bond, then ally Bulbasaur KO's Shedinja with Crunch
|
// Shedinja uses Destiny Bond, then ally Bulbasaur KO's Shedinja with Crunch
|
||||||
game.move.select(MoveId.DESTINY_BOND, 0);
|
game.move.select(MoveId.DESTINY_BOND, 0);
|
||||||
game.move.select(MoveId.CRUNCH, 1, BattlerIndex.PLAYER);
|
game.move.select(MoveId.CRUNCH, 1, BattlerIndex.PLAYER);
|
||||||
|
@ -171,7 +171,7 @@ describe("Moves - Dragon Tail", () => {
|
|||||||
const enemy = game.field.getEnemyPokemon();
|
const enemy = game.field.getEnemyPokemon();
|
||||||
expect(enemy).toBeDefined();
|
expect(enemy).toBeDefined();
|
||||||
expect(enemy.hp).toBe(Math.floor(enemy.getMaxHp() / 2));
|
expect(enemy.hp).toBe(Math.floor(enemy.getMaxHp() / 2));
|
||||||
expect(game.scene.getEnemyField().length).toBe(1);
|
expect(game.scene.getEnemyField()).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not cause a softlock when activating a player's reviver seed", async () => {
|
it("should not cause a softlock when activating a player's reviver seed", async () => {
|
||||||
|
@ -107,7 +107,7 @@ describe("Moves - Fell Stinger", () => {
|
|||||||
|
|
||||||
await game.classicMode.startBattle([SpeciesId.LEAVANNY]);
|
await game.classicMode.startBattle([SpeciesId.LEAVANNY]);
|
||||||
const leadPokemon = game.field.getPlayerPokemon();
|
const leadPokemon = game.field.getPlayerPokemon();
|
||||||
const leftEnemy = game.scene.getEnemyField()[0]!;
|
const leftEnemy = game.field.getEnemyPokemon();
|
||||||
|
|
||||||
// Turn 1: set Salt Cure, enemy splashes and does nothing
|
// Turn 1: set Salt Cure, enemy splashes and does nothing
|
||||||
game.move.select(MoveId.SALT_CURE, 0, leftEnemy.getBattlerIndex());
|
game.move.select(MoveId.SALT_CURE, 0, leftEnemy.getBattlerIndex());
|
||||||
|
@ -498,7 +498,7 @@ describe("Moves - Instruct", () => {
|
|||||||
.enemyLevel(1);
|
.enemyLevel(1);
|
||||||
await game.classicMode.startBattle([SpeciesId.KORAIDON, SpeciesId.KLEFKI]);
|
await game.classicMode.startBattle([SpeciesId.KORAIDON, SpeciesId.KLEFKI]);
|
||||||
|
|
||||||
const koraidon = game.scene.getPlayerField()[0]!;
|
const koraidon = game.field.getPlayerPokemon();
|
||||||
|
|
||||||
game.move.select(MoveId.BREAKING_SWIPE);
|
game.move.select(MoveId.BREAKING_SWIPE);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
@ -527,7 +527,7 @@ describe("Moves - Instruct", () => {
|
|||||||
.enemyLevel(1);
|
.enemyLevel(1);
|
||||||
await game.classicMode.startBattle([SpeciesId.KORAIDON, SpeciesId.KLEFKI]);
|
await game.classicMode.startBattle([SpeciesId.KORAIDON, SpeciesId.KLEFKI]);
|
||||||
|
|
||||||
const koraidon = game.scene.getPlayerField()[0]!;
|
const koraidon = game.field.getPlayerPokemon();
|
||||||
|
|
||||||
game.move.select(MoveId.BRUTAL_SWING);
|
game.move.select(MoveId.BRUTAL_SWING);
|
||||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||||
@ -587,7 +587,7 @@ describe("Moves - Instruct", () => {
|
|||||||
.enemyLevel(5);
|
.enemyLevel(5);
|
||||||
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.IVYSAUR]);
|
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.IVYSAUR]);
|
||||||
|
|
||||||
const [, ivysaur] = game.scene.getPlayerField();
|
const ivysaur = game.scene.getPlayerField()[1];
|
||||||
|
|
||||||
game.move.select(MoveId.SPLASH, BattlerIndex.PLAYER);
|
game.move.select(MoveId.SPLASH, BattlerIndex.PLAYER);
|
||||||
game.move.select(MoveId.SPLASH, BattlerIndex.PLAYER_2);
|
game.move.select(MoveId.SPLASH, BattlerIndex.PLAYER_2);
|
||||||
|
@ -111,7 +111,8 @@ describe("Moves - Jaw Lock", () => {
|
|||||||
|
|
||||||
await game.classicMode.startBattle([SpeciesId.CHARMANDER, SpeciesId.BULBASAUR]);
|
await game.classicMode.startBattle([SpeciesId.CHARMANDER, SpeciesId.BULBASAUR]);
|
||||||
|
|
||||||
const playerPokemon = game.scene.getPlayerField();
|
const playerPokemon = game.field.getPlayerPokemon();
|
||||||
|
|
||||||
const enemyPokemon = game.scene.getEnemyField();
|
const enemyPokemon = game.scene.getEnemyField();
|
||||||
|
|
||||||
game.move.select(MoveId.JAW_LOCK, 0, BattlerIndex.ENEMY);
|
game.move.select(MoveId.JAW_LOCK, 0, BattlerIndex.ENEMY);
|
||||||
@ -120,7 +121,7 @@ describe("Moves - Jaw Lock", () => {
|
|||||||
|
|
||||||
await game.phaseInterceptor.to(MoveEffectPhase);
|
await game.phaseInterceptor.to(MoveEffectPhase);
|
||||||
|
|
||||||
expect(playerPokemon[0].getTag(BattlerTagType.TRAPPED)).toBeDefined();
|
expect(playerPokemon.getTag(BattlerTagType.TRAPPED)).toBeDefined();
|
||||||
expect(enemyPokemon[0].getTag(BattlerTagType.TRAPPED)).toBeDefined();
|
expect(enemyPokemon[0].getTag(BattlerTagType.TRAPPED)).toBeDefined();
|
||||||
|
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
@ -131,8 +132,8 @@ describe("Moves - Jaw Lock", () => {
|
|||||||
await game.phaseInterceptor.to(MoveEffectPhase);
|
await game.phaseInterceptor.to(MoveEffectPhase);
|
||||||
|
|
||||||
expect(enemyPokemon[1].getTag(BattlerTagType.TRAPPED)).toBeUndefined();
|
expect(enemyPokemon[1].getTag(BattlerTagType.TRAPPED)).toBeUndefined();
|
||||||
expect(playerPokemon[0].getTag(BattlerTagType.TRAPPED)).toBeDefined();
|
expect(playerPokemon.getTag(BattlerTagType.TRAPPED)).toBeDefined();
|
||||||
expect(playerPokemon[0].getTag(BattlerTagType.TRAPPED)?.sourceId).toBe(enemyPokemon[0].id);
|
expect(playerPokemon.getTag(BattlerTagType.TRAPPED)?.sourceId).toBe(enemyPokemon[0].id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not trap either pokemon if the target is protected", async () => {
|
it("should not trap either pokemon if the target is protected", async () => {
|
||||||
|
@ -34,8 +34,7 @@ describe("Moves - Tailwind", () => {
|
|||||||
|
|
||||||
it("doubles the Speed stat of the Pokemons on its side", async () => {
|
it("doubles the Speed stat of the Pokemons on its side", async () => {
|
||||||
await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.MEOWTH]);
|
await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.MEOWTH]);
|
||||||
const magikarp = game.scene.getPlayerField()[0];
|
const [magikarp, meowth] = game.scene.getPlayerField();
|
||||||
const meowth = game.scene.getPlayerField()[1];
|
|
||||||
|
|
||||||
const magikarpSpd = magikarp.getStat(Stat.SPD);
|
const magikarpSpd = magikarp.getStat(Stat.SPD);
|
||||||
const meowthSpd = meowth.getStat(Stat.SPD);
|
const meowthSpd = meowth.getStat(Stat.SPD);
|
||||||
|
62
test/utils/cookies.test.ts
Normal file
62
test/utils/cookies.test.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { getCookie } from "#utils/cookies";
|
||||||
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
describe("Unit Tests - cookies.ts", () => {
|
||||||
|
describe("getCookie", () => {
|
||||||
|
const cookieStart = document.cookie;
|
||||||
|
beforeEach(() => {
|
||||||
|
// clear cookie before each test
|
||||||
|
document.cookie = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// restore original cookie after each test
|
||||||
|
document.cookie = cookieStart;
|
||||||
|
});
|
||||||
|
/**
|
||||||
|
* Spies on `document.cookie` and replaces its value with the provided string.
|
||||||
|
*/
|
||||||
|
function setDocumentCookie(value: string) {
|
||||||
|
vi.spyOn(document, "cookie", "get").mockReturnValue(value);
|
||||||
|
}
|
||||||
|
it("returns the value of a single cookie", () => {
|
||||||
|
setDocumentCookie("foo=bar");
|
||||||
|
expect(getCookie("foo")).toBe("bar");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns empty string if cookie is not found", () => {
|
||||||
|
setDocumentCookie("foo=bar");
|
||||||
|
expect(getCookie("baz")).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns the value when multiple cookies exist", () => {
|
||||||
|
setDocumentCookie("foo=bar; baz=qux");
|
||||||
|
expect(getCookie("baz")).toBe("qux");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("trims leading spaces in cookies", () => {
|
||||||
|
setDocumentCookie("foo=bar; baz=qux");
|
||||||
|
expect(getCookie("baz")).toBe("qux");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns the value of the first matching cookie if only one exists", () => {
|
||||||
|
setDocumentCookie("foo=bar; test=val");
|
||||||
|
expect(getCookie("foo")).toBe("bar");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns empty string if document.cookie is empty", () => {
|
||||||
|
setDocumentCookie("");
|
||||||
|
expect(getCookie("foo")).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles cookies that aren't separated with a space", () => {
|
||||||
|
setDocumentCookie("foo=bar;baz=qux;quux=corge;grault=garply");
|
||||||
|
expect(getCookie("baz")).toBe("qux");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles cookies that may have leading tab characters", () => {
|
||||||
|
setDocumentCookie("foo=bar;\tbaz=qux");
|
||||||
|
expect(getCookie("baz")).toBe("qux");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user