mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-19 22:09:27 +02:00
Fixed type errors; made tag type a const object
This commit is contained in:
parent
dc849bcd08
commit
a821fc2f80
@ -30,9 +30,9 @@ export function loadPositionalTag(tag: SerializedPositionalTag): PositionalTag {
|
||||
globalScene.arena.eventTarget.dispatchEvent(new PositionalTagAddedEvent(tag));
|
||||
|
||||
// Create the new tag
|
||||
// TODO: review how many type assertions we need here
|
||||
const { tagType, ...rest } = tag;
|
||||
const tagClass = posTagConstructorMap[tagType];
|
||||
// @ts-expect-error - tagType always corresponds to the proper constructor for `rest`
|
||||
return new tagClass(rest);
|
||||
}
|
||||
|
||||
|
38
src/enums/arena-event-type.ts
Normal file
38
src/enums/arena-event-type.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import type { ArenaTag } from "#data/arena-tag";
|
||||
import type { PositionalTag } from "#data/positional-tags/positional-tag";
|
||||
import type { TerrainType } from "#data/terrain";
|
||||
import type { WeatherType } from "#enums/weather-type";
|
||||
import type { ArenaEvent } from "#events/arena";
|
||||
import type { ObjectValues } from "#types/type-helpers";
|
||||
|
||||
/**
|
||||
* Enum representing the types of all {@linkcode ArenaEvent}s that can be emitted.
|
||||
* @eventProperty
|
||||
* @enum
|
||||
*/
|
||||
export const ArenaEventType = {
|
||||
/** Emitted when a {@linkcode WeatherType} is added, overlapped, or removed */
|
||||
WEATHER_CHANGED: "onWeatherChanged",
|
||||
/** Emitted when a {@linkcode TerrainType} is added, overlapped, or removed */
|
||||
TERRAIN_CHANGED: "onTerrainChanged",
|
||||
|
||||
/** Emitted when a new {@linkcode ArenaTag} is added */
|
||||
ARENA_TAG_ADDED: "onArenaTagAdded",
|
||||
/** Emitted when an existing {@linkcode ArenaTag} is removed */
|
||||
ARENA_TAG_REMOVED: "onArenaTagRemoved",
|
||||
|
||||
/** Emitted when a new {@linkcode PositionalTag} is added */
|
||||
POSITIONAL_TAG_ADDED: "onPositionalTagAdded",
|
||||
/** Emitted when an existing {@linkcode PositionalTag} is removed */
|
||||
POSITIONAL_TAG_REMOVED: "onPositionalTagRemoved",
|
||||
} as const;
|
||||
|
||||
export type ArenaEventType = ObjectValues<typeof ArenaEventType>;
|
||||
|
||||
/**
|
||||
Doc comment removal prevention block
|
||||
{@linkcode WeatherType}
|
||||
{@linkcode TerrainType}
|
||||
{@linkcode PositionalTag}
|
||||
{@linkcode ArenaTag}
|
||||
*/
|
@ -1,34 +1,5 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { BattlerIndex } from "#enums/battler-index";
|
||||
|
||||
export enum FieldPosition {
|
||||
CENTER,
|
||||
LEFT,
|
||||
RIGHT
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a {@linkcode BattlerIndex} into a field position.
|
||||
* @param index - The {@linkcode BattlerIndex} to convert
|
||||
* @returns The resultant field position.
|
||||
*/
|
||||
export function battlerIndexToFieldPosition(index: BattlerIndex): FieldPosition {
|
||||
let pos: FieldPosition;
|
||||
switch (index) {
|
||||
case BattlerIndex.ATTACKER:
|
||||
throw new Error("Cannot convert BattlerIndex.ATTACKER to a field position!")
|
||||
case BattlerIndex.PLAYER:
|
||||
case BattlerIndex.ENEMY:
|
||||
pos = FieldPosition.LEFT;
|
||||
break;
|
||||
case BattlerIndex.PLAYER_2:
|
||||
case BattlerIndex.ENEMY_2:
|
||||
pos = FieldPosition.RIGHT;
|
||||
break;
|
||||
}
|
||||
// In single battles, left positions become center
|
||||
if (!globalScene.currentBattle.double && pos === FieldPosition.LEFT) {
|
||||
pos = FieldPosition.CENTER
|
||||
}
|
||||
return pos;
|
||||
}
|
@ -2,32 +2,16 @@ import type { SerializedPositionalTag } from "#data/positional-tags/load-positio
|
||||
// biome-ignore lint/correctness/noUnusedImports: TSDoc
|
||||
import type { PositionalTag } from "#data/positional-tags/positional-tag";
|
||||
import type { TerrainType } from "#data/terrain";
|
||||
import { ArenaEventType } from "#enums/arena-event-type";
|
||||
import type { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import type { ArenaTagType } from "#enums/arena-tag-type";
|
||||
import type { BattlerIndex } from "#enums/battler-index";
|
||||
import type { PositionalTagType } from "#enums/positional-tag-type";
|
||||
import type { WeatherType } from "#enums/weather-type";
|
||||
|
||||
/** Enum representing the types of all {@linkcode ArenaEvent}s that can be emitted. */
|
||||
export enum ArenaEventType {
|
||||
/** Emitted when a {@linkcode WeatherType} is added, overlapped, or removed */
|
||||
WEATHER_CHANGED = "onWeatherChanged",
|
||||
/** Emitted when a {@linkcode TerrainType} is added, overlapped, or removed */
|
||||
TERRAIN_CHANGED = "onTerrainChanged",
|
||||
|
||||
/** Emitted when a new {@linkcode ArenaTag} is added */
|
||||
ARENA_TAG_ADDED = "onArenaTagAdded",
|
||||
/** Emitted when an existing {@linkcode ArenaTag} is removed */
|
||||
ARENA_TAG_REMOVED = "onArenaTagRemoved",
|
||||
|
||||
/** Emitted when a new {@linkcode PositionalTag} is added */
|
||||
POSITIONAL_TAG_ADDED = "onPositionalTagAdded",
|
||||
/** Emitted when an existing {@linkcode PositionalTag} is removed */
|
||||
POSITIONAL_TAG_REMOVED = "onPositionalTagRemoved",
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract container class for all {@linkcode ArenaEventType} events.
|
||||
* @eventProperty
|
||||
*/
|
||||
abstract class ArenaEvent extends Event {
|
||||
/** The {@linkcode ArenaEventType} being emitted. */
|
||||
@ -43,9 +27,10 @@ export type { ArenaEvent };
|
||||
/**
|
||||
* Container class for {@linkcode ArenaEventType.WEATHER_CHANGED} events. \
|
||||
* Emitted whenever a weather effect starts, ends or is replaced.
|
||||
* @eventProperty
|
||||
*/
|
||||
export class WeatherChangedEvent extends ArenaEvent {
|
||||
declare type: ArenaEventType.WEATHER_CHANGED;
|
||||
declare type: typeof ArenaEventType.WEATHER_CHANGED;
|
||||
|
||||
/** The new {@linkcode WeatherType} being set. */
|
||||
public weatherType: WeatherType;
|
||||
@ -66,9 +51,10 @@ export class WeatherChangedEvent extends ArenaEvent {
|
||||
/**
|
||||
* Container class for {@linkcode ArenaEventType.TERRAIN_CHANGED} events. \
|
||||
* Emitted whenever a terrain effect starts, ends or is replaced.
|
||||
* @eventProperty
|
||||
*/
|
||||
export class TerrainChangedEvent extends ArenaEvent {
|
||||
declare type: ArenaEventType.TERRAIN_CHANGED;
|
||||
declare type: typeof ArenaEventType.TERRAIN_CHANGED;
|
||||
|
||||
/** The new {@linkcode TerrainType} being set. */
|
||||
public terrainType: TerrainType;
|
||||
@ -90,9 +76,10 @@ export class TerrainChangedEvent extends ArenaEvent {
|
||||
* Container class for {@linkcode ArenaEventType.ARENA_TAG_ADDED} events. \
|
||||
* Emitted whenever a new {@linkcode ArenaTag} is added to the arena, or whenever an existing
|
||||
* {@linkcode ArenaTrapTag} overlaps and adds new layers.
|
||||
* @eventProperty
|
||||
*/
|
||||
export class ArenaTagAddedEvent extends ArenaEvent {
|
||||
declare type: ArenaEventType.ARENA_TAG_ADDED;
|
||||
declare type: typeof ArenaEventType.ARENA_TAG_ADDED;
|
||||
|
||||
/** The {@linkcode ArenaTagType} of the tag being added */
|
||||
public tagType: ArenaTagType;
|
||||
@ -124,9 +111,10 @@ export class ArenaTagAddedEvent extends ArenaEvent {
|
||||
/**
|
||||
* Container class for {@linkcode ArenaEventType.ARENA_TAG_REMOVED} events. \
|
||||
* Emitted whenever an {@linkcode ArenaTag} is removed from the field for any reason.
|
||||
* @eventProperty
|
||||
*/
|
||||
export class ArenaTagRemovedEvent extends ArenaEvent {
|
||||
declare type: ArenaEventType.ARENA_TAG_REMOVED;
|
||||
declare type: typeof ArenaEventType.ARENA_TAG_REMOVED;
|
||||
|
||||
/** The {@linkcode ArenaTagType} of the tag being removed. */
|
||||
public tagType: ArenaTagType;
|
||||
@ -144,9 +132,10 @@ export class ArenaTagRemovedEvent extends ArenaEvent {
|
||||
/**
|
||||
* Container class for {@linkcode ArenaEventType.POSITIONAL_TAG_ADDED} events. \
|
||||
* Emitted whenever a new {@linkcode PositionalTag} is spawned and added to the arena.
|
||||
* @eventProperty
|
||||
*/
|
||||
export class PositionalTagAddedEvent extends ArenaEvent {
|
||||
declare type: ArenaEventType.POSITIONAL_TAG_ADDED;
|
||||
declare type: typeof ArenaEventType.POSITIONAL_TAG_ADDED;
|
||||
|
||||
/** The {@linkcode SerializedPositionalTag} being added to the arena. */
|
||||
public tag: SerializedPositionalTag;
|
||||
@ -169,9 +158,10 @@ export class PositionalTagAddedEvent extends ArenaEvent {
|
||||
* Container class for {@linkcode ArenaEventType.POSITIONAL_TAG_REMOVED} events. \
|
||||
* Emitted whenever a currently-active {@linkcode PositionalTag} triggers (or disappears)
|
||||
* and is removed from the arena.
|
||||
* @eventProperty
|
||||
*/
|
||||
export class PositionalTagRemovedEvent extends ArenaEvent {
|
||||
declare type: ArenaEventType.POSITIONAL_TAG_REMOVED;
|
||||
declare type: typeof ArenaEventType.POSITIONAL_TAG_REMOVED;
|
||||
|
||||
/** The {@linkcode PositionalTagType} of the tag being deleted. */
|
||||
public tagType: PositionalTagType;
|
||||
|
@ -5,23 +5,23 @@ import type { SerializedPositionalTag } from "#data/positional-tags/load-positio
|
||||
import type { PositionalTag } from "#data/positional-tags/positional-tag";
|
||||
import { type Terrain, TerrainType } from "#data/terrain";
|
||||
import type { Weather } from "#data/weather";
|
||||
import { ArenaEventType } from "#enums/arena-event-type";
|
||||
// biome-ignore-end lint/correctness/noUnusedImports: TSDocs
|
||||
import { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||
import { BattlerIndex } from "#enums/battler-index";
|
||||
import { battlerIndexToFieldPosition, FieldPosition } from "#enums/field-position";
|
||||
import { FieldPosition } from "#enums/field-position";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { PositionalTagType } from "#enums/positional-tag-type";
|
||||
import { TextStyle } from "#enums/text-style";
|
||||
import { WeatherType } from "#enums/weather-type";
|
||||
import {
|
||||
ArenaEventType,
|
||||
type ArenaTagAddedEvent,
|
||||
type ArenaTagRemovedEvent,
|
||||
type PositionalTagAddedEvent,
|
||||
type PositionalTagRemovedEvent,
|
||||
type TerrainChangedEvent,
|
||||
type WeatherChangedEvent,
|
||||
import type {
|
||||
ArenaTagAddedEvent,
|
||||
ArenaTagRemovedEvent,
|
||||
PositionalTagAddedEvent,
|
||||
PositionalTagRemovedEvent,
|
||||
TerrainChangedEvent,
|
||||
WeatherChangedEvent,
|
||||
} from "#events/arena";
|
||||
import { BattleSceneEventType } from "#events/battle-scene";
|
||||
import { addTextObject } from "#ui/text";
|
||||
@ -92,7 +92,7 @@ interface PositionalTagInfo {
|
||||
* @param text - The raw text of the effect; assumed to be in `UPPER_SNAKE_CASE` from a reverse mapping.
|
||||
* @returns The localized text for the effect.
|
||||
*/
|
||||
function localizeEffectName(text: string): string {
|
||||
export function localizeEffectName(text: string): string {
|
||||
const effectName = toCamelCase(text);
|
||||
const i18nKey = `arenaFlyout:${effectName}`;
|
||||
const resultName = i18next.t(i18nKey);
|
||||
@ -103,11 +103,12 @@ function localizeEffectName(text: string): string {
|
||||
* Return the localized name of a given {@linkcode PositionalTag}.
|
||||
* @param tag - The raw serialized data for the given tag
|
||||
* @returns The localized text to be displayed on-screen.
|
||||
* @package
|
||||
*/
|
||||
function getPositionalTagDisplayName(tag: SerializedPositionalTag): string {
|
||||
export function getPositionalTagDisplayName(tag: SerializedPositionalTag): string {
|
||||
let tagName: string;
|
||||
if ("sourceMove" in tag) {
|
||||
// Delayed attacks will use the source move's name
|
||||
// Delayed attacks will use the source move's name; other effects rely on type
|
||||
tagName = MoveId[tag.sourceMove];
|
||||
} else {
|
||||
tagName = PositionalTagType[tag.tagType];
|
||||
@ -317,7 +318,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
private onTurnEnd() {
|
||||
// Remove all objects with positive max durations and whose durations have expired.
|
||||
this.arenaTags = this.arenaTags.filter(info => info.maxDuration === 0 || --info.duration >= 0);
|
||||
this.positionalTags = this.positionalTags.filter(info => --info.duration >= 0);
|
||||
this.positionalTags = this.positionalTags.filter(info => --info.duration > 0);
|
||||
|
||||
this.updateFieldText();
|
||||
}
|
||||
@ -354,9 +355,9 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
|
||||
/**
|
||||
* Update an existing trap tag with an updated layer count whenever one is overlapped.
|
||||
* @param existingTag - The existing {@linkcode ArenaTagInfo} to update text for
|
||||
* @param existingTag - The existing {@linkcode ArenaTagInfo} being updated
|
||||
* @param layers - The base number of layers of the new tag
|
||||
* @param maxLayers - The maximum number of layers of the new tag; will not show layer count if <=0
|
||||
* @param maxLayers - The maximum number of layers of the new tag; will not show layer count if `<=0`
|
||||
* @param name - The name of the tag.
|
||||
*/
|
||||
private updateTrapLayers(existingTag: ArenaTagInfo, [layers, maxLayers]: [number, number], name: string): void {
|
||||
@ -370,6 +371,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
*/
|
||||
private onArenaTagRemoved(event: ArenaTagRemovedEvent): void {
|
||||
const foundIndex = this.arenaTags.findIndex(info => info.tagType === event.tagType && info.side === event.side);
|
||||
console.log(this.positionalTags, event);
|
||||
|
||||
if (foundIndex > -1) {
|
||||
// If the tag was being tracked, remove it
|
||||
@ -513,10 +515,10 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
|
||||
// Weather and terrain go first
|
||||
if (this.weatherInfo) {
|
||||
this.updateTagText(this.weatherInfo);
|
||||
this.flyoutTextField.text += this.getTagText(this.weatherInfo);
|
||||
}
|
||||
if (this.terrainInfo) {
|
||||
this.updateTagText(this.terrainInfo);
|
||||
this.flyoutTextField.text += this.getTagText(this.terrainInfo);
|
||||
}
|
||||
|
||||
// Sort and add all positional tags
|
||||
@ -525,45 +527,48 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
(infoA, infoB) => infoA.name.localeCompare(infoB.name) || infoA.targetIndex - infoB.targetIndex,
|
||||
);
|
||||
for (const tag of this.positionalTags) {
|
||||
this.updatePosTagText(tag);
|
||||
this.getPositionalTagTextObj(tag).text += this.getPosTagText(tag);
|
||||
}
|
||||
|
||||
// Sort and update all arena tag text
|
||||
this.arenaTags.sort((infoA, infoB) => infoA.duration - infoB.duration);
|
||||
for (const tag of this.arenaTags) {
|
||||
this.updateTagText(tag);
|
||||
this.getArenaTagTargetObj(tag.side).text += this.getTagText(tag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to update the flyout box's text with a {@linkcode PositionalTag}'s info.
|
||||
* Helper method to retrieve the flyout text for a given {@linkcode PositionalTag}.
|
||||
* @param info - The {@linkcode PositionalTagInfo} whose text is being updated
|
||||
* @returns The text to be added to the container
|
||||
*/
|
||||
private updatePosTagText(info: PositionalTagInfo): void {
|
||||
const textObj = this.getPositionalTagTextObj(info);
|
||||
private getPosTagText(info: PositionalTagInfo): string {
|
||||
// Avoud showing slot target for single battles
|
||||
if (!globalScene.currentBattle.double) {
|
||||
return `${info.name} (${info.duration})\n`;
|
||||
}
|
||||
|
||||
const targetPos = battlerIndexToFieldPosition(info.targetIndex);
|
||||
const posText = localizeEffectName(FieldPosition[targetPos]);
|
||||
|
||||
// Ex: "Future Sight (Center, 2)"
|
||||
textObj.text += `${info.name} (${posText}, ${info.duration}\n`;
|
||||
return `${info.name} (${posText}, ${info.duration})\n`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to update the flyout box's text with an effect's info.
|
||||
* Helper method to retrieve the flyout text for a given effect's info.
|
||||
* @param info - The {@linkcode ArenaTagInfo}, {@linkcode TerrainInfo} or {@linkcode WeatherInfo} being updated
|
||||
* @returns The text to be added to the container
|
||||
*/
|
||||
private updateTagText(info: ArenaTagInfo | WeatherInfo | TerrainInfo): void {
|
||||
// Weathers and terrains use the "field" box by default
|
||||
const textObject = "tagType" in info ? this.getArenaTagTargetObj(info.side) : this.flyoutTextField;
|
||||
|
||||
textObject.text += info.name;
|
||||
private getTagText(info: ArenaTagInfo | WeatherInfo | TerrainInfo): string {
|
||||
let text = info.name;
|
||||
|
||||
if (info.maxDuration > 0) {
|
||||
textObject.text += ` ${info.duration}/ + ${info.maxDuration}`;
|
||||
text += ` ${info.duration}/${info.maxDuration}`;
|
||||
}
|
||||
|
||||
textObject.text += "\n";
|
||||
text += "\n";
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -600,7 +605,31 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
}
|
||||
}
|
||||
|
||||
private;
|
||||
|
||||
// # endregion Text display functions
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a {@linkcode BattlerIndex} into a field position.
|
||||
* @param index - The {@linkcode BattlerIndex} to convert
|
||||
* @returns The resultant field position.
|
||||
*/
|
||||
function battlerIndexToFieldPosition(index: BattlerIndex): FieldPosition {
|
||||
let pos: FieldPosition;
|
||||
switch (index) {
|
||||
case BattlerIndex.ATTACKER:
|
||||
throw new Error("Cannot convert BattlerIndex.ATTACKER to a field position!");
|
||||
case BattlerIndex.PLAYER:
|
||||
case BattlerIndex.ENEMY:
|
||||
pos = FieldPosition.LEFT;
|
||||
break;
|
||||
case BattlerIndex.PLAYER_2:
|
||||
case BattlerIndex.ENEMY_2:
|
||||
pos = FieldPosition.RIGHT;
|
||||
break;
|
||||
}
|
||||
// In single battles, left positions become center
|
||||
if (!globalScene.currentBattle.double && pos === FieldPosition.LEFT) {
|
||||
pos = FieldPosition.CENTER;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user