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
|
* @sealed
|
||||||
*/
|
*/
|
||||||
export class ForewarnAbAttr extends PostSummonAbAttr {
|
export class ForewarnAbAttr extends PostSummonAbAttr {
|
||||||
@ -4338,46 +4343,77 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override apply({ simulated, pokemon }: AbAttrBaseParams): void {
|
override apply({ simulated, pokemon }: AbAttrBaseParams): void {
|
||||||
if (!simulated) {
|
if (simulated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let maxPowerSeen = 0;
|
let maxPowerSeen = 0;
|
||||||
let maxMove = "";
|
const movesAtMaxPower: string[] = [];
|
||||||
let movePower = 0;
|
|
||||||
for (const opponent of pokemon.getOpponents()) {
|
// Record all moves in all opponents' movesets seen at our max power threshold, clearing it if a new "highest power" is found
|
||||||
for (const move of opponent.moveset) {
|
// TODO: Change to `pokemon.getOpponents().flatMap(p => p.getMoveset())` if or when we upgrade to ES2025
|
||||||
if (move?.getMove().is("StatusMove")) {
|
for (const opp of pokemon.getOpponents()) {
|
||||||
movePower = 1;
|
for (const oppMove of opp.getMoveset()) {
|
||||||
} else if (move?.getMove().hasAttr("OneHitKOAttr")) {
|
const move = oppMove.getMove();
|
||||||
movePower = 150;
|
const movePower = getForewarnPower(move);
|
||||||
} else if (
|
if (movePower < maxPowerSeen) {
|
||||||
move?.getMove().id === MoveId.COUNTER
|
continue;
|
||||||
|| 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (movePower > maxPowerSeen) {
|
// Another move at current max found; add to tiebreaker array
|
||||||
maxPowerSeen = movePower;
|
if (movePower === maxPowerSeen) {
|
||||||
maxMove = move?.getName() ?? "";
|
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(
|
globalScene.phaseManager.queueMessage(
|
||||||
i18next.t("abilityTriggers:forewarn", {
|
i18next.t("abilityTriggers:forewarn", {
|
||||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
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.
|
* Ability attribute that reveals the abilities of all opposing Pokémon when the Pokémon with this ability is summoned.
|
||||||
* @sealed
|
* @sealed
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user