mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-12-16 14:55:22 +01:00
[Bug/Ability] Fix Forewarn not triggering + add randomized selection (#6623)
* [Ability] Fix Forewarn not triggering + add randomized selection * Fix typo * Comment fix * Fix name oops * Fix `slice` instead of `splice` * Fix missing continue Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Apply Biome --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
This commit is contained in:
parent
54918f6145
commit
d32e112194
@ -4330,6 +4330,11 @@ function getOncePerBattleCondition(ability: AbilityId): AbAttrCondition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ability attribute used by {@linkcode AbilityId.FOREWARN}.
|
||||
*
|
||||
* Displays a message on switch-in containing the highest power Move known by the user's opponents,
|
||||
* picking randomly in the case of a tie.
|
||||
* @see {@link https://www.smogon.com/dex/sv/abilities/forewarn/}
|
||||
* @sealed
|
||||
*/
|
||||
export class ForewarnAbAttr extends PostSummonAbAttr {
|
||||
@ -4338,46 +4343,77 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
|
||||
}
|
||||
|
||||
override apply({ simulated, pokemon }: AbAttrBaseParams): void {
|
||||
if (!simulated) {
|
||||
if (simulated) {
|
||||
return;
|
||||
}
|
||||
|
||||
let maxPowerSeen = 0;
|
||||
let maxMove = "";
|
||||
let movePower = 0;
|
||||
for (const opponent of pokemon.getOpponents()) {
|
||||
for (const move of opponent.moveset) {
|
||||
if (move?.getMove().is("StatusMove")) {
|
||||
movePower = 1;
|
||||
} else if (move?.getMove().hasAttr("OneHitKOAttr")) {
|
||||
movePower = 150;
|
||||
} else if (
|
||||
move?.getMove().id === MoveId.COUNTER
|
||||
|| move?.getMove().id === MoveId.MIRROR_COAT
|
||||
|| move?.getMove().id === MoveId.METAL_BURST
|
||||
) {
|
||||
movePower = 120;
|
||||
} else if (move?.getMove().power === -1) {
|
||||
movePower = 80;
|
||||
} else {
|
||||
movePower = move?.getMove().power ?? 0;
|
||||
const movesAtMaxPower: string[] = [];
|
||||
|
||||
// Record all moves in all opponents' movesets seen at our max power threshold, clearing it if a new "highest power" is found
|
||||
// TODO: Change to `pokemon.getOpponents().flatMap(p => p.getMoveset())` if or when we upgrade to ES2025
|
||||
for (const opp of pokemon.getOpponents()) {
|
||||
for (const oppMove of opp.getMoveset()) {
|
||||
const move = oppMove.getMove();
|
||||
const movePower = getForewarnPower(move);
|
||||
if (movePower < maxPowerSeen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (movePower > maxPowerSeen) {
|
||||
maxPowerSeen = movePower;
|
||||
maxMove = move?.getName() ?? "";
|
||||
// Another move at current max found; add to tiebreaker array
|
||||
if (movePower === maxPowerSeen) {
|
||||
movesAtMaxPower.push(move.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// New max reached; clear prior results and update tracker
|
||||
maxPowerSeen = movePower;
|
||||
movesAtMaxPower.splice(0, movesAtMaxPower.length, move.name);
|
||||
}
|
||||
}
|
||||
|
||||
// Pick a random move in our list.
|
||||
if (movesAtMaxPower.length === 0) {
|
||||
// NB: The ONLY way this can happen is if both opponents have 0 moves in their moveset
|
||||
throw new Error("Forewarn ability found 0 valid moves!");
|
||||
}
|
||||
const chosenMove = movesAtMaxPower[pokemon.randBattleSeedInt(movesAtMaxPower.length)];
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("abilityTriggers:forewarn", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
moveName: maxMove,
|
||||
moveName: chosenMove,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return the estimated power used by Forewarn's "highest power" ranking.
|
||||
* @param move - The `Move` being checked
|
||||
* @returns The "forewarned" power of the move.
|
||||
* @see {@link https://www.smogon.com/dex/sv/abilities/forewarn/}
|
||||
*/
|
||||
function getForewarnPower(move: Move): number {
|
||||
if (move.is("StatusMove")) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (move.hasAttr("OneHitKOAttr")) {
|
||||
return 150;
|
||||
}
|
||||
|
||||
// NB: Mainline doesn't count Comeuppance in its "counter move exceptions" list, which is dumb
|
||||
if (move.hasAttr("CounterDamageAttr")) {
|
||||
return 120;
|
||||
}
|
||||
|
||||
// All damaging moves with unlisted powers use 80 as a fallback
|
||||
if (move.power === -1) {
|
||||
return 80;
|
||||
}
|
||||
return move.power;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ability attribute that reveals the abilities of all opposing Pokémon when the Pokémon with this ability is summoned.
|
||||
* @sealed
|
||||
|
||||
Loading…
Reference in New Issue
Block a user