Merge remote-tracking branch 'upstream/beta' into init-session-from-data

This commit is contained in:
Bertie690 2025-09-18 17:28:39 -04:00
commit 9505bda720
9 changed files with 67 additions and 32 deletions

View File

@ -84,6 +84,10 @@ interface BaseArenaTag {
* The tag's remaining duration. Setting to any number `<=0` will make the tag's duration effectively infinite.
*/
turnCount: number;
/**
* The tag's max duration.
*/
maxDuration: number;
/**
* The {@linkcode MoveId} that created this tag, or `undefined` if not set by a move.
*/
@ -110,12 +114,14 @@ export abstract class ArenaTag implements BaseArenaTag {
/** The type of the arena tag */
public abstract readonly tagType: ArenaTagType;
public turnCount: number;
public maxDuration: number;
public sourceMove?: MoveId;
public sourceId: number | undefined;
public side: ArenaTagSide;
constructor(turnCount: number, sourceMove?: MoveId, sourceId?: number, side: ArenaTagSide = ArenaTagSide.BOTH) {
this.turnCount = turnCount;
this.maxDuration = turnCount;
this.sourceMove = sourceMove;
this.sourceId = sourceId;
this.side = side;
@ -164,6 +170,7 @@ export abstract class ArenaTag implements BaseArenaTag {
*/
loadTag<const T extends this>(source: BaseArenaTag & Pick<T, "tagType">): void {
this.turnCount = source.turnCount;
this.maxDuration = source.maxDuration;
this.sourceMove = source.sourceMove;
this.sourceId = source.sourceId;
this.side = source.side;

View File

@ -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.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]: {
[TimeOfDay.DAWN]: [],
[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 ]
},
[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 ] }
},
[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.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.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_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 ] }
},
[BiomeId.END]: {
@ -5627,10 +5627,12 @@ export function initBiomes() {
]
],
[ 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, [
[ BiomeId.LABORATORY, BiomePoolTier.ULTRA_RARE ],
[ BiomeId.LABORATORY, BiomePoolTier.BOSS_SUPER_RARE ]
]
],
@ -5773,10 +5775,12 @@ export function initBiomes() {
]
],
[ 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, [
[ BiomeId.SWAMP, BiomePoolTier.ULTRA_RARE ],
[ BiomeId.SWAMP, BiomePoolTier.BOSS_SUPER_RARE ]
]
],
@ -6165,10 +6169,12 @@ export function initBiomes() {
]
],
[ 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, [
[ BiomeId.DOJO, BiomePoolTier.ULTRA_RARE ],
[ BiomeId.DOJO, BiomePoolTier.BOSS_SUPER_RARE ]
]
],
@ -7209,7 +7215,8 @@ export function initBiomes() {
],
[ TrainerType.SCIENTIST, [
[ BiomeId.DESERT, BiomePoolTier.COMMON ],
[ BiomeId.RUINS, BiomePoolTier.COMMON ]
[ BiomeId.RUINS, BiomePoolTier.COMMON ],
[ BiomeId.LABORATORY, BiomePoolTier.COMMON ]
]
],
[ TrainerType.SMASHER, []],
@ -7224,7 +7231,8 @@ export function initBiomes() {
]
],
[ TrainerType.SWIMMER, [
[ BiomeId.SEA, BiomePoolTier.COMMON ]
[ BiomeId.SEA, BiomePoolTier.COMMON ],
[ BiomeId.SEABED, BiomePoolTier.COMMON ]
]
],
[ TrainerType.TWINS, [
@ -7590,11 +7598,13 @@ export function initBiomes() {
[ TrainerType.ALDER, []],
[ TrainerType.IRIS, []],
[ TrainerType.DIANTHA, []],
[ TrainerType.KUKUI, []],
[ TrainerType.HAU, []],
[ TrainerType.LEON, []],
[ TrainerType.MUSTARD, []],
[ TrainerType.GEETA, []],
[ TrainerType.NEMONA, []],
[ TrainerType.KIERAN, []],
[ TrainerType.LEON, []],
[ TrainerType.RIVAL, []]
];

View File

@ -22,10 +22,12 @@ export interface SerializedTerrain {
export class Terrain {
public terrainType: TerrainType;
public turnsLeft: number;
public maxDuration: number;
constructor(terrainType: TerrainType, turnsLeft?: number) {
constructor(terrainType: TerrainType, turnsLeft = 0, maxDuration: number = turnsLeft) {
this.terrainType = terrainType;
this.turnsLeft = turnsLeft || 0;
this.turnsLeft = turnsLeft;
this.maxDuration = maxDuration;
}
lapse(): boolean {

View File

@ -19,10 +19,12 @@ export interface SerializedWeather {
export class Weather {
public weatherType: WeatherType;
public turnsLeft: number;
public maxDuration: number;
constructor(weatherType: WeatherType, turnsLeft?: number) {
constructor(weatherType: WeatherType, turnsLeft = 0, maxDuration: number = turnsLeft) {
this.weatherType = weatherType;
this.turnsLeft = !this.isImmutable() ? turnsLeft || 0 : 0;
this.turnsLeft = this.isImmutable() ? 0 : turnsLeft;
this.maxDuration = this.isImmutable() ? 0 : maxDuration;
}
lapse(): boolean {

View File

@ -20,10 +20,13 @@ export enum ArenaEventType {
export class ArenaEvent extends Event {
/** The total duration of the {@linkcode ArenaEventType} */
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);
this.duration = duration;
this.maxDuration = maxDuration;
}
}
/** Container class for {@linkcode ArenaEventType.WEATHER_CHANGED} events */
@ -32,8 +35,8 @@ export class WeatherChangedEvent extends ArenaEvent {
public oldWeatherType: WeatherType;
/** The {@linkcode WeatherType} being set */
public newWeatherType: WeatherType;
constructor(oldWeatherType: WeatherType, newWeatherType: WeatherType, duration: number) {
super(ArenaEventType.WEATHER_CHANGED, duration);
constructor(oldWeatherType: WeatherType, newWeatherType: WeatherType, duration: number, maxDuration?: number) {
super(ArenaEventType.WEATHER_CHANGED, duration, maxDuration);
this.oldWeatherType = oldWeatherType;
this.newWeatherType = newWeatherType;
@ -45,8 +48,8 @@ export class TerrainChangedEvent extends ArenaEvent {
public oldTerrainType: TerrainType;
/** The {@linkcode TerrainType} being set */
public newTerrainType: TerrainType;
constructor(oldTerrainType: TerrainType, newTerrainType: TerrainType, duration: number) {
super(ArenaEventType.TERRAIN_CHANGED, duration);
constructor(oldTerrainType: TerrainType, newTerrainType: TerrainType, duration: number, maxDuration?: number) {
super(ArenaEventType.TERRAIN_CHANGED, duration, maxDuration);
this.oldTerrainType = oldTerrainType;
this.newTerrainType = newTerrainType;
@ -68,10 +71,11 @@ export class TagAddedEvent extends ArenaEvent {
arenaTagType: ArenaTagType,
arenaTagSide: ArenaTagSide,
duration: number,
maxDuration?: number,
arenaTagLayers?: number,
arenaTagMaxLayers?: number,
) {
super(ArenaEventType.TAG_ADDED, duration);
super(ArenaEventType.TAG_ADDED, duration, maxDuration);
this.arenaTagType = arenaTagType;
this.arenaTagSide = arenaTagSide;

View File

@ -344,7 +344,7 @@ export class Arena {
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(
new WeatherChangedEvent(oldWeatherType, this.weather?.weatherType!, this.weather?.turnsLeft!),
); // TODO: is this bang correct?
@ -425,7 +425,7 @@ export class Arena {
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(
new TerrainChangedEvent(oldTerrainType, this.terrain?.terrainType!, this.terrain?.turnsLeft!),
@ -705,8 +705,8 @@ export class Arena {
existingTag.onOverlap(this, globalScene.getPokemonById(sourceId));
if (existingTag instanceof EntryHazardTag) {
const { tagType, side, turnCount, layers, maxLayers } = existingTag as EntryHazardTag;
this.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, layers, maxLayers));
const { tagType, side, turnCount, maxDuration, layers, maxLayers } = existingTag as EntryHazardTag;
this.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, maxDuration, layers, maxLayers));
}
return false;
@ -721,7 +721,7 @@ export class Arena {
const { layers = 0, maxLayers = 0 } = newTag instanceof EntryHazardTag ? newTag : {};
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),
);
}

View File

@ -47,8 +47,12 @@ export class ArenaData {
}
this.biome = source.biome;
this.weather = source.weather ? new Weather(source.weather.weatherType, source.weather.turnsLeft) : null;
this.terrain = source.terrain ? new Terrain(source.terrain.terrainType, source.terrain.turnsLeft) : null;
this.weather = source.weather
? 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 ?? [];
}
}

View File

@ -1018,6 +1018,7 @@ export class GameData {
WeatherType.NONE,
globalScene.arena.weather?.weatherType!,
globalScene.arena.weather?.turnsLeft!,
globalScene.arena.weather?.maxDuration!,
),
); // TODO: is this bang correct?
@ -1027,6 +1028,7 @@ export class GameData {
TerrainType.NONE,
globalScene.arena.terrain?.terrainType!,
globalScene.arena.terrain?.turnsLeft!,
globalScene.arena.terrain?.maxDuration!,
),
); // TODO: is this bang correct?
@ -1036,10 +1038,14 @@ export class GameData {
if (globalScene.arena.tags) {
for (const tag of globalScene.arena.tags) {
if (tag instanceof EntryHazardTag) {
const { tagType, side, turnCount, layers, maxLayers } = tag as EntryHazardTag;
globalScene.arena.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, layers, maxLayers));
const { tagType, side, turnCount, maxDuration, layers, maxLayers } = tag as EntryHazardTag;
globalScene.arena.eventTarget.dispatchEvent(
new TagAddedEvent(tagType, side, turnCount, maxDuration, layers, maxLayers),
);
} 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),
);
}
}
}

View File

@ -317,7 +317,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
this.fieldEffectInfo.push({
name,
effectType: arenaEffectType,
maxDuration: tagAddedEvent.duration,
maxDuration: tagAddedEvent.maxDuration,
duration: tagAddedEvent.duration,
tagType: tagAddedEvent.arenaTagType,
});
@ -353,7 +353,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
),
effectType:
fieldEffectChangedEvent instanceof WeatherChangedEvent ? ArenaEffectType.WEATHER : ArenaEffectType.TERRAIN,
maxDuration: fieldEffectChangedEvent.duration,
maxDuration: fieldEffectChangedEvent.maxDuration,
duration: fieldEffectChangedEvent.duration,
};