mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-21 17:12:44 +02:00
[Item] Add Weather and Terrain Extender Item (#4799)
* [Item] Add Weather and Terrain Extender Item * Add Documentation * Clean Up Unit Tests * Add Weight Function * Include Suggestions
This commit is contained in:
parent
db850c79cd
commit
6316218bd3
@ -308,7 +308,7 @@ export class ClearWeatherAbAttr extends AbAttr {
|
|||||||
|
|
||||||
public override apply(pokemon: Pokemon, passive: boolean, simulated:boolean, cancelled: Utils.BooleanHolder, args: any[]): void {
|
public override apply(pokemon: Pokemon, passive: boolean, simulated:boolean, cancelled: Utils.BooleanHolder, args: any[]): void {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.arena.trySetWeather(WeatherType.NONE, true);
|
globalScene.arena.trySetWeather(WeatherType.NONE, pokemon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,7 +334,7 @@ export class ClearTerrainAbAttr extends AbAttr {
|
|||||||
|
|
||||||
public override apply(pokemon: Pokemon, passive: boolean, simulated:boolean, cancelled: Utils.BooleanHolder, args: any[]): void {
|
public override apply(pokemon: Pokemon, passive: boolean, simulated:boolean, cancelled: Utils.BooleanHolder, args: any[]): void {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.arena.trySetTerrain(TerrainType.NONE, true, true);
|
globalScene.arena.trySetTerrain(TerrainType.NONE, true, pokemon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -954,7 +954,7 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): void {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): void {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.arena.trySetTerrain(this.terrainType, true);
|
globalScene.arena.trySetTerrain(this.terrainType, false, pokemon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1126,7 +1126,7 @@ export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
|
|||||||
|
|
||||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.arena.trySetWeather(this.weatherType, true);
|
globalScene.arena.trySetWeather(this.weatherType, pokemon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2483,7 +2483,7 @@ export class PostSummonWeatherChangeAbAttr extends PostSummonAbAttr {
|
|||||||
|
|
||||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.arena.trySetWeather(this.weatherType, true);
|
globalScene.arena.trySetWeather(this.weatherType, pokemon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2503,7 +2503,7 @@ export class PostSummonTerrainChangeAbAttr extends PostSummonAbAttr {
|
|||||||
|
|
||||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.arena.trySetTerrain(this.terrainType, true);
|
globalScene.arena.trySetTerrain(this.terrainType, false, pokemon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2886,7 +2886,7 @@ export class PreSwitchOutClearWeatherAbAttr extends PreSwitchOutAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (turnOffWeather) {
|
if (turnOffWeather) {
|
||||||
globalScene.arena.trySetWeather(WeatherType.NONE, false);
|
globalScene.arena.trySetWeather(WeatherType.NONE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2986,7 +2986,7 @@ export class PreLeaveFieldClearWeatherAbAttr extends PreLeaveFieldAbAttr {
|
|||||||
*/
|
*/
|
||||||
override applyPreLeaveField(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
override applyPreLeaveField(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.arena.trySetWeather(WeatherType.NONE, false);
|
globalScene.arena.trySetWeather(WeatherType.NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4137,7 +4137,7 @@ export class PostBiomeChangeWeatherChangeAbAttr extends PostBiomeChangeAbAttr {
|
|||||||
|
|
||||||
override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): void {
|
override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): void {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.arena.trySetWeather(this.weatherType, true);
|
globalScene.arena.trySetWeather(this.weatherType, pokemon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4157,7 +4157,7 @@ export class PostBiomeChangeTerrainChangeAbAttr extends PostBiomeChangeAbAttr {
|
|||||||
|
|
||||||
override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): void {
|
override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: Utils.BooleanHolder, args: any[]): void {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.arena.trySetTerrain(this.terrainType, true);
|
globalScene.arena.trySetTerrain(this.terrainType, false, pokemon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2851,7 +2851,7 @@ export class WeatherChangeAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
return globalScene.arena.trySetWeather(this.weatherType, true);
|
return globalScene.arena.trySetWeather(this.weatherType, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCondition(): MoveConditionFunc {
|
getCondition(): MoveConditionFunc {
|
||||||
@ -2870,7 +2870,7 @@ export class ClearWeatherAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
if (globalScene.arena.weather?.weatherType === this.weatherType) {
|
if (globalScene.arena.weather?.weatherType === this.weatherType) {
|
||||||
return globalScene.arena.trySetWeather(WeatherType.NONE, true);
|
return globalScene.arena.trySetWeather(WeatherType.NONE, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -2887,7 +2887,7 @@ export class TerrainChangeAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
return globalScene.arena.trySetTerrain(this.terrainType, true, true);
|
return globalScene.arena.trySetTerrain(this.terrainType, true, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCondition(): MoveConditionFunc {
|
getCondition(): MoveConditionFunc {
|
||||||
@ -2906,7 +2906,7 @@ export class ClearTerrainAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
return globalScene.arena.trySetTerrain(TerrainType.NONE, true, true);
|
return globalScene.arena.trySetTerrain(TerrainType.NONE, true, user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6454,7 +6454,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
export class ChillyReceptionAttr extends ForceSwitchOutAttr {
|
export class ChillyReceptionAttr extends ForceSwitchOutAttr {
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
globalScene.arena.trySetWeather(WeatherType.SNOW, true);
|
globalScene.arena.trySetWeather(WeatherType.SNOW, user);
|
||||||
return super.apply(user, target, move, args);
|
return super.apply(user, target, move, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,8 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w
|
|||||||
// Load animations/sfx for Volcarona moves
|
// Load animations/sfx for Volcarona moves
|
||||||
loadCustomMovesForEncounter([Moves.FIRE_SPIN, Moves.QUIVER_DANCE]);
|
loadCustomMovesForEncounter([Moves.FIRE_SPIN, Moves.QUIVER_DANCE]);
|
||||||
|
|
||||||
globalScene.arena.trySetWeather(WeatherType.SUNNY, true);
|
const pokemon = globalScene.getEnemyPokemon();
|
||||||
|
globalScene.arena.trySetWeather(WeatherType.SUNNY, pokemon);
|
||||||
|
|
||||||
encounter.setDialogueToken("volcaronaName", getPokemonSpecies(Species.VOLCARONA).getName());
|
encounter.setDialogueToken("volcaronaName", getPokemonSpecies(Species.VOLCARONA).getName());
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrig
|
|||||||
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
|
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
|
||||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
|
import { FieldEffectModifier } from "#app/modifier/modifier";
|
||||||
|
|
||||||
export class Arena {
|
export class Arena {
|
||||||
public biomeType: Biome;
|
public biomeType: Biome;
|
||||||
@ -311,10 +312,10 @@ export class Arena {
|
|||||||
/**
|
/**
|
||||||
* Attempts to set a new weather to the battle
|
* Attempts to set a new weather to the battle
|
||||||
* @param weather {@linkcode WeatherType} new {@linkcode WeatherType} to set
|
* @param weather {@linkcode WeatherType} new {@linkcode WeatherType} to set
|
||||||
* @param hasPokemonSource boolean if the new weather is from a pokemon
|
* @param user {@linkcode Pokemon} that caused the weather effect
|
||||||
* @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use
|
* @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use
|
||||||
*/
|
*/
|
||||||
trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean {
|
trySetWeather(weather: WeatherType, user?: Pokemon): boolean {
|
||||||
if (Overrides.WEATHER_OVERRIDE) {
|
if (Overrides.WEATHER_OVERRIDE) {
|
||||||
return this.trySetWeatherOverride(Overrides.WEATHER_OVERRIDE);
|
return this.trySetWeatherOverride(Overrides.WEATHER_OVERRIDE);
|
||||||
}
|
}
|
||||||
@ -336,7 +337,14 @@ export class Arena {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.weather = weather ? new Weather(weather, hasPokemonSource ? 5 : 0) : null;
|
const weatherDuration = new Utils.NumberHolder(0);
|
||||||
|
|
||||||
|
if (!Utils.isNullOrUndefined(user)) {
|
||||||
|
weatherDuration.value = 5;
|
||||||
|
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, weatherDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.weather = weather ? new Weather(weather, 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?
|
||||||
@ -398,14 +406,29 @@ export class Arena {
|
|||||||
return !(this.terrain?.terrainType === (terrain || undefined));
|
return !(this.terrain?.terrainType === (terrain || undefined));
|
||||||
}
|
}
|
||||||
|
|
||||||
trySetTerrain(terrain: TerrainType, hasPokemonSource: boolean, ignoreAnim = false): boolean {
|
/**
|
||||||
|
* Attempts to set a new terrain effect to the battle
|
||||||
|
* @param terrain {@linkcode TerrainType} new {@linkcode TerrainType} to set
|
||||||
|
* @param ignoreAnim boolean if the terrain animation should be ignored
|
||||||
|
* @param user {@linkcode Pokemon} that caused the terrain effect
|
||||||
|
* @returns true if new terrain set, false if no terrain provided or attempting to set the same terrain as currently in use
|
||||||
|
*/
|
||||||
|
trySetTerrain(terrain: TerrainType, ignoreAnim = false, user?: Pokemon): boolean {
|
||||||
if (!this.canSetTerrain(terrain)) {
|
if (!this.canSetTerrain(terrain)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE;
|
const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE;
|
||||||
|
|
||||||
this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null;
|
const terrainDuration = new Utils.NumberHolder(0);
|
||||||
|
|
||||||
|
if (!Utils.isNullOrUndefined(user)) {
|
||||||
|
terrainDuration.value = 5;
|
||||||
|
globalScene.applyModifier(FieldEffectModifier, user.isPlayer(), user, terrainDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.terrain = terrain ? new Terrain(terrain, 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!),
|
||||||
); // TODO: are those bangs correct?
|
); // TODO: are those bangs correct?
|
||||||
@ -802,9 +825,9 @@ export class Arena {
|
|||||||
resetArenaEffects(): void {
|
resetArenaEffects(): void {
|
||||||
// Don't reset weather if a Biome's permanent weather is active
|
// Don't reset weather if a Biome's permanent weather is active
|
||||||
if (this.weather?.turnsLeft !== 0) {
|
if (this.weather?.turnsLeft !== 0) {
|
||||||
this.trySetWeather(WeatherType.NONE, false);
|
this.trySetWeather(WeatherType.NONE);
|
||||||
}
|
}
|
||||||
this.trySetTerrain(TerrainType.NONE, false, true);
|
this.trySetTerrain(TerrainType.NONE, true);
|
||||||
this.resetPlayerFaintCount();
|
this.resetPlayerFaintCount();
|
||||||
this.removeAllTags();
|
this.removeAllTags();
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,7 @@ import {
|
|||||||
type PersistentModifier,
|
type PersistentModifier,
|
||||||
TempExtraModifierModifier,
|
TempExtraModifierModifier,
|
||||||
CriticalCatchChanceBoosterModifier,
|
CriticalCatchChanceBoosterModifier,
|
||||||
|
FieldEffectModifier,
|
||||||
} from "#app/modifier/modifier";
|
} from "#app/modifier/modifier";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
@ -1998,6 +1999,13 @@ export const modifierTypes = {
|
|||||||
return new PokemonNatureChangeModifierType(randSeedInt(getEnumValues(Nature).length) as Nature);
|
return new PokemonNatureChangeModifierType(randSeedInt(getEnumValues(Nature).length) as Nature);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
MYSTICAL_ROCK: () =>
|
||||||
|
new ModifierType(
|
||||||
|
"modifierType:ModifierType.MYSTICAL_ROCK",
|
||||||
|
"mystical_rock",
|
||||||
|
(type, args) => new FieldEffectModifier(type, (args[0] as Pokemon).id),
|
||||||
|
),
|
||||||
|
|
||||||
TERA_SHARD: () =>
|
TERA_SHARD: () =>
|
||||||
new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
|
new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
|
||||||
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in PokemonType) {
|
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in PokemonType) {
|
||||||
@ -2810,6 +2818,47 @@ const modifierPool: ModifierPool = {
|
|||||||
},
|
},
|
||||||
10,
|
10,
|
||||||
),
|
),
|
||||||
|
new WeightedModifierType(
|
||||||
|
modifierTypes.MYSTICAL_ROCK,
|
||||||
|
(party: Pokemon[]) => {
|
||||||
|
return party.some(p => {
|
||||||
|
const moveset = p.getMoveset(true).map(m => m.moveId);
|
||||||
|
|
||||||
|
const hasAbility = [
|
||||||
|
Abilities.DRIZZLE,
|
||||||
|
Abilities.ORICHALCUM_PULSE,
|
||||||
|
Abilities.DRIZZLE,
|
||||||
|
Abilities.SAND_STREAM,
|
||||||
|
Abilities.SAND_SPIT,
|
||||||
|
Abilities.SNOW_WARNING,
|
||||||
|
Abilities.ELECTRIC_SURGE,
|
||||||
|
Abilities.HADRON_ENGINE,
|
||||||
|
Abilities.PSYCHIC_SURGE,
|
||||||
|
Abilities.GRASSY_SURGE,
|
||||||
|
Abilities.SEED_SOWER,
|
||||||
|
Abilities.MISTY_SURGE,
|
||||||
|
].some(a => p.hasAbility(a, false, true));
|
||||||
|
|
||||||
|
const hasMoves = [
|
||||||
|
Moves.SUNNY_DAY,
|
||||||
|
Moves.RAIN_DANCE,
|
||||||
|
Moves.SANDSTORM,
|
||||||
|
Moves.SNOWSCAPE,
|
||||||
|
Moves.HAIL,
|
||||||
|
Moves.CHILLY_RECEPTION,
|
||||||
|
Moves.ELECTRIC_TERRAIN,
|
||||||
|
Moves.PSYCHIC_TERRAIN,
|
||||||
|
Moves.GRASSY_TERRAIN,
|
||||||
|
Moves.MISTY_TERRAIN,
|
||||||
|
].some(m => moveset.includes(m));
|
||||||
|
|
||||||
|
return hasAbility || hasMoves;
|
||||||
|
})
|
||||||
|
? 10
|
||||||
|
: 0;
|
||||||
|
},
|
||||||
|
10,
|
||||||
|
),
|
||||||
new WeightedModifierType(modifierTypes.REVIVER_SEED, 4),
|
new WeightedModifierType(modifierTypes.REVIVER_SEED, 4),
|
||||||
new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)),
|
new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)),
|
||||||
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9),
|
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9),
|
||||||
|
@ -2014,6 +2014,38 @@ export class ResetNegativeStatStageModifier extends PokemonHeldItemModifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifier used for held items, namely Mystical Rock, that extend the
|
||||||
|
* duration of weather and terrain effects.
|
||||||
|
* @extends PokemonHeldItemModifier
|
||||||
|
* @see {@linkcode apply}
|
||||||
|
*/
|
||||||
|
export class FieldEffectModifier extends PokemonHeldItemModifier {
|
||||||
|
/**
|
||||||
|
* Provides two more turns per stack to any weather or terrain effect caused
|
||||||
|
* by the holder.
|
||||||
|
* @param pokemon {@linkcode Pokemon} that holds the held item
|
||||||
|
* @param fieldDuration {@linkcode NumberHolder} that stores the current field effect duration
|
||||||
|
* @returns `true` if the field effect extension was applied successfully
|
||||||
|
*/
|
||||||
|
override apply(_pokemon: Pokemon, fieldDuration: NumberHolder): boolean {
|
||||||
|
fieldDuration.value += 2 * this.stackCount;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
override matchType(modifier: Modifier): boolean {
|
||||||
|
return modifier instanceof FieldEffectModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
override clone(): FieldEffectModifier {
|
||||||
|
return new FieldEffectModifier(this.type, this.pokemonId, this.stackCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
override getMaxHeldItemCount(_pokemon?: Pokemon): number {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export abstract class ConsumablePokemonModifier extends ConsumableModifier {
|
export abstract class ConsumablePokemonModifier extends ConsumableModifier {
|
||||||
public pokemonId: number;
|
public pokemonId: number;
|
||||||
|
|
||||||
|
@ -684,7 +684,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
*/
|
*/
|
||||||
trySetWeatherIfNewBiome(): void {
|
trySetWeatherIfNewBiome(): void {
|
||||||
if (!this.loaded) {
|
if (!this.loaded) {
|
||||||
globalScene.arena.trySetWeather(getRandomWeatherType(globalScene.arena), false);
|
globalScene.arena.trySetWeather(getRandomWeatherType(globalScene.arena));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,6 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase {
|
|||||||
* Set biome weather.
|
* Set biome weather.
|
||||||
*/
|
*/
|
||||||
trySetWeatherIfNewBiome(): void {
|
trySetWeatherIfNewBiome(): void {
|
||||||
globalScene.arena.trySetWeather(getRandomWeatherType(globalScene.arena), false);
|
globalScene.arena.trySetWeather(getRandomWeatherType(globalScene.arena));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,12 +68,12 @@ export class TurnEndPhase extends FieldPhase {
|
|||||||
globalScene.arena.lapseTags();
|
globalScene.arena.lapseTags();
|
||||||
|
|
||||||
if (globalScene.arena.weather && !globalScene.arena.weather.lapse()) {
|
if (globalScene.arena.weather && !globalScene.arena.weather.lapse()) {
|
||||||
globalScene.arena.trySetWeather(WeatherType.NONE, false);
|
globalScene.arena.trySetWeather(WeatherType.NONE);
|
||||||
globalScene.arena.triggerWeatherBasedFormChangesToNormal();
|
globalScene.arena.triggerWeatherBasedFormChangesToNormal();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalScene.arena.terrain && !globalScene.arena.terrain.lapse()) {
|
if (globalScene.arena.terrain && !globalScene.arena.terrain.lapse()) {
|
||||||
globalScene.arena.trySetTerrain(TerrainType.NONE, false);
|
globalScene.arena.trySetTerrain(TerrainType.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.end();
|
this.end();
|
||||||
|
@ -181,7 +181,7 @@ describe("Abilities - Forecast", () => {
|
|||||||
|
|
||||||
expect(castform.formIndex).toBe(SNOWY_FORM);
|
expect(castform.formIndex).toBe(SNOWY_FORM);
|
||||||
|
|
||||||
game.scene.arena.trySetWeather(WeatherType.FOG, false);
|
game.scene.arena.trySetWeather(WeatherType.FOG);
|
||||||
game.move.select(Moves.SPLASH);
|
game.move.select(Moves.SPLASH);
|
||||||
game.move.select(Moves.SPLASH, 1);
|
game.move.select(Moves.SPLASH, 1);
|
||||||
await game.phaseInterceptor.to("TurnStartPhase");
|
await game.phaseInterceptor.to("TurnStartPhase");
|
||||||
|
60
test/items/mystical_rock.test.ts
Normal file
60
test/items/mystical_rock.test.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
|
import Phase from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
describe("Items - Mystical Rock", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phase.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
|
||||||
|
game.override
|
||||||
|
.enemySpecies(Species.SHUCKLE)
|
||||||
|
.enemyMoveset(Moves.SPLASH)
|
||||||
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.moveset([Moves.SUNNY_DAY, Moves.GRASSY_TERRAIN])
|
||||||
|
.startingHeldItems([{ name: "MYSTICAL_ROCK", count: 2 }])
|
||||||
|
.battleType("single");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should increase weather duration by +2 turns per stack", async () => {
|
||||||
|
await game.classicMode.startBattle([Species.GASTLY]);
|
||||||
|
|
||||||
|
game.move.select(Moves.SUNNY_DAY);
|
||||||
|
|
||||||
|
await game.phaseInterceptor.to("MoveEndPhase");
|
||||||
|
|
||||||
|
const weather = globalScene.arena.weather;
|
||||||
|
|
||||||
|
expect(weather).toBeDefined();
|
||||||
|
expect(weather!.turnsLeft).to.equal(9);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should increase terrain duration by +2 turns per stack", async () => {
|
||||||
|
await game.classicMode.startBattle([Species.GASTLY]);
|
||||||
|
|
||||||
|
game.move.select(Moves.GRASSY_TERRAIN);
|
||||||
|
|
||||||
|
await game.phaseInterceptor.to("MoveEndPhase");
|
||||||
|
|
||||||
|
const terrain = globalScene.arena.terrain;
|
||||||
|
|
||||||
|
expect(terrain).toBeDefined();
|
||||||
|
expect(terrain!.turnsLeft).to.equal(9);
|
||||||
|
});
|
||||||
|
});
|
@ -120,7 +120,7 @@ describe("Moves - Dive", () => {
|
|||||||
|
|
||||||
await game.phaseInterceptor.to("TurnEndPhase");
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
await game.phaseInterceptor.to("TurnStartPhase", false);
|
await game.phaseInterceptor.to("TurnStartPhase", false);
|
||||||
game.scene.arena.trySetWeather(WeatherType.HARSH_SUN, false);
|
game.scene.arena.trySetWeather(WeatherType.HARSH_SUN);
|
||||||
|
|
||||||
await game.phaseInterceptor.to("MoveEndPhase");
|
await game.phaseInterceptor.to("MoveEndPhase");
|
||||||
expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL);
|
expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL);
|
||||||
|
Loading…
Reference in New Issue
Block a user