From 19885e05587ed5518439d6ec11f21c7a2b245220 Mon Sep 17 00:00:00 2001 From: Benjamin Odom Date: Fri, 31 May 2024 17:52:16 -0500 Subject: [PATCH] Add Arena Events (#1627) * Add Arena Events * Update arena-events.ts --- src/field/arena-events.ts | 77 +++++++++++++++++++++++++++++++++++++++ src/field/arena.ts | 7 ++++ src/system/game-data.ts | 5 +++ 3 files changed, 89 insertions(+) create mode 100644 src/field/arena-events.ts diff --git a/src/field/arena-events.ts b/src/field/arena-events.ts new file mode 100644 index 00000000000..1cc632030a5 --- /dev/null +++ b/src/field/arena-events.ts @@ -0,0 +1,77 @@ +import { ArenaTagSide } from "#app/data/arena-tag.js"; +import { ArenaTagType } from "#app/data/enums/arena-tag-type.js"; +import { TerrainType } from "#app/data/terrain.js"; +import { WeatherType } from "#app/data/weather.js"; + +/** Alias for all {@linkcode ArenaEvent} type strings */ +export enum ArenaEventType { + /** Triggers when a {@linkcode WeatherType} is added, overlapped, or removed */ + WEATHER_CHANGED = "onWeatherChanged", + /** Triggers when a {@linkcode TerrainType} is added, overlapped, or removed */ + TERRAIN_CHANGED = "onTerrainChanged", + + /** Triggers when a {@linkcode ArenaTagType} is added or removed */ + TAG_CHANGED = "onTagChanged", +} + +/** + * Base container class for all {@linkcode ArenaEventType} events + * @extends Event + */ +export class ArenaEvent extends Event { + /** The total duration of the {@linkcode ArenaEventType} */ + public duration: number; + constructor(eventType: ArenaEventType, duration: number) { + super(eventType); + + this.duration = duration; + } +} +/** + * Container class for {@linkcode ArenaEventType.WEATHER_CHANGED} events + * @extends ArenaEvent +*/ +export class WeatherChangedEvent extends ArenaEvent { + /** The {@linkcode WeatherType} being overridden */ + public oldWeatherType: WeatherType; + /** The {@linkcode WeatherType} being set */ + public newWeatherType: WeatherType; + constructor(oldWeatherType: WeatherType, newWeatherType: WeatherType, duration: number) { + super(ArenaEventType.WEATHER_CHANGED, duration); + + this.oldWeatherType = oldWeatherType; + this.newWeatherType = newWeatherType; + } +} +/** + * Container class for {@linkcode ArenaEventType.TERRAIN_CHANGED} events + * @extends ArenaEvent +*/ +export class TerrainChangedEvent extends ArenaEvent { + /** The {@linkcode TerrainType} being overridden */ + public oldTerrainType: TerrainType; + /** The {@linkcode TerrainType} being set */ + public newTerrainType: TerrainType; + constructor(oldTerrainType: TerrainType, newTerrainType: TerrainType, duration: number) { + super(ArenaEventType.TERRAIN_CHANGED, duration); + + this.oldTerrainType = oldTerrainType; + this.newTerrainType = newTerrainType; + } +} +/** + * Container class for {@linkcode ArenaEventType.TAG_CHANGED} events + * @extends ArenaEvent +*/ +export class TagChangedEvent extends ArenaEvent { + /** The {@linkcode ArenaTagType} being set */ + public arenaTagType: ArenaTagType; + /** The {@linkcode ArenaTagSide} the tag is being placed on */ + public arenaTagSide: ArenaTagSide; + constructor(arenaTagType: ArenaTagType, arenaTagSide: ArenaTagSide, duration: number) { + super(ArenaEventType.TAG_CHANGED, duration); + + this.arenaTagType = arenaTagType; + this.arenaTagSide = arenaTagSide; + } +} diff --git a/src/field/arena.ts b/src/field/arena.ts index 817e5d5eaad..eac2eafb265 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -19,6 +19,7 @@ import { Terrain, TerrainType } from "../data/terrain"; import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability"; import Pokemon from "./pokemon"; import * as Overrides from "../overrides"; +import { WeatherChangedEvent, TerrainChangedEvent, TagChangedEvent } from "./arena-events"; export class Arena { public scene: BattleScene; @@ -34,6 +35,8 @@ export class Arena { private pokemonPool: PokemonPools; private trainerPool: BiomeTierTrainerPools; + public readonly eventTarget: EventTarget = new EventTarget(); + constructor(scene: BattleScene, biome: Biome, bgm: string) { this.scene = scene; this.biomeType = biome; @@ -300,6 +303,7 @@ export class Arena { const oldWeatherType = this.weather?.weatherType || WeatherType.NONE; this.weather = weather ? new Weather(weather, hasPokemonSource ? 5 : 0) : null; + this.eventTarget.dispatchEvent(new WeatherChangedEvent(oldWeatherType, this.weather?.weatherType, this.weather?.turnsLeft)); if (this.weather) { this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1))); @@ -324,6 +328,7 @@ export class Arena { const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE; this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null; + this.eventTarget.dispatchEvent(new TerrainChangedEvent(oldTerrainType,this.terrain?.terrainType, this.terrain?.turnsLeft)); if (this.terrain) { if (!ignoreAnim) { @@ -545,6 +550,8 @@ export class Arena { this.tags.push(newTag); newTag.onAdd(this); + this.eventTarget.dispatchEvent(new TagChangedEvent(newTag.tagType, newTag.side, newTag.turnCount)); + return true; } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 5bc0df19aa2..b1cbf77f4c6 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -30,6 +30,7 @@ import { allMoves } from "../data/move"; import { TrainerVariant } from "../field/trainer"; import { OutdatedPhase, ReloadSessionPhase } from "#app/phases"; import { Variant, variantData } from "#app/data/variant"; +import { TerrainChangedEvent, WeatherChangedEvent } from "#app/field/arena-events.js"; const saveKey = "x0i2O7WRiANTqPmZ"; // Temporary; secure encryption is not yet necessary @@ -740,6 +741,10 @@ export class GameData { }); scene.arena.weather = sessionData.arena.weather; + scene.arena.eventTarget.dispatchEvent(new WeatherChangedEvent(null, scene.arena.weather?.weatherType, scene.arena.weather?.turnsLeft)); + + scene.arena.terrain = sessionData.arena.terrain; + scene.arena.eventTarget.dispatchEvent(new TerrainChangedEvent(null, scene.arena.terrain?.terrainType, scene.arena.terrain?.turnsLeft)); // TODO //scene.arena.tags = sessionData.arena.tags;