mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-01 22:12:16 +02:00
Move application to applyPostSummonAbAttrs and stop assuming no other phases in queue
This commit is contained in:
parent
ca05b94dbe
commit
6995c8c0c0
@ -5164,6 +5164,7 @@ function applySingleAbAttrs<TAttr extends AbAttr>(
|
|||||||
args: any[],
|
args: any[],
|
||||||
gainedMidTurn = false,
|
gainedMidTurn = false,
|
||||||
simulated = false,
|
simulated = false,
|
||||||
|
priorityCondition?: (p: number) => boolean,
|
||||||
showAbilityInstant = false,
|
showAbilityInstant = false,
|
||||||
messages: string[] = []
|
messages: string[] = []
|
||||||
) {
|
) {
|
||||||
@ -5172,7 +5173,10 @@ function applySingleAbAttrs<TAttr extends AbAttr>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ability = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
|
const ability = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
|
||||||
if (gainedMidTurn && ability.getAttrs(attrType).some(attr => attr instanceof PostSummonAbAttr && !attr.shouldActivateOnGain())) {
|
if (
|
||||||
|
gainedMidTurn && ability.getAttrs(attrType).some(attr => attr instanceof PostSummonAbAttr && !attr.shouldActivateOnGain())
|
||||||
|
|| (priorityCondition && !priorityCondition(ability.postSummonPriority))
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5453,6 +5457,19 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
|
|||||||
return this.helper.getFailedText(target);
|
return this.helper.getFailedText(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main Function for handling ability application. Applies both the normal ability and passive of the Pokemon
|
||||||
|
* @param attrType The type of {@linkcode AbAttr} to apply
|
||||||
|
* @param pokemon The {@linkcode Pokemon} whose abilities should be applied
|
||||||
|
* @param applyFunc The {@linkcode AbAttrApplyFunc} corresponding to {@linkcode attrType}
|
||||||
|
* @param args Extra arguments, handled by individual {@linkcode AbAttr}s
|
||||||
|
* @param showAbilityInstant If `true`, show the ability bar instantly instead of queuing it
|
||||||
|
* @param simulated `true` if the call is simulated and the battle state should not be changes
|
||||||
|
* @param messages Array of messages which will be added to if the ability displays a message
|
||||||
|
* @param gainedMidTurn `true` if the ability is activating because it was gained during the battle
|
||||||
|
* @param priorityCondition If defined, only abilities with priority that meets the condition will be applied
|
||||||
|
*/
|
||||||
function applyAbAttrsInternal<TAttr extends AbAttr>(
|
function applyAbAttrsInternal<TAttr extends AbAttr>(
|
||||||
attrType: Constructor<TAttr>,
|
attrType: Constructor<TAttr>,
|
||||||
pokemon: Pokemon | null,
|
pokemon: Pokemon | null,
|
||||||
@ -5461,11 +5478,12 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(
|
|||||||
showAbilityInstant = false,
|
showAbilityInstant = false,
|
||||||
simulated = false,
|
simulated = false,
|
||||||
messages: string[] = [],
|
messages: string[] = [],
|
||||||
gainedMidTurn = false
|
gainedMidTurn = false,
|
||||||
|
priorityCondition?: (p: number) => boolean
|
||||||
) {
|
) {
|
||||||
for (const passive of [ false, true ]) {
|
for (const passive of [ false, true ]) {
|
||||||
if (pokemon) {
|
if (pokemon) {
|
||||||
applySingleAbAttrs(pokemon, passive, attrType, applyFunc, args, gainedMidTurn, simulated, showAbilityInstant, messages);
|
applySingleAbAttrs(pokemon, passive, attrType, applyFunc, args, gainedMidTurn, simulated, priorityCondition, showAbilityInstant, messages);
|
||||||
globalScene.clearPhaseQueueSplice();
|
globalScene.clearPhaseQueueSplice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5714,6 +5732,7 @@ export function applyPostSummonAbAttrs(
|
|||||||
attrType: Constructor<PostSummonAbAttr>,
|
attrType: Constructor<PostSummonAbAttr>,
|
||||||
pokemon: Pokemon,
|
pokemon: Pokemon,
|
||||||
simulated = false,
|
simulated = false,
|
||||||
|
priorityCondition?: (p: number) => boolean,
|
||||||
...args: any[]
|
...args: any[]
|
||||||
): void {
|
): void {
|
||||||
applyAbAttrsInternal<PostSummonAbAttr>(
|
applyAbAttrsInternal<PostSummonAbAttr>(
|
||||||
@ -5723,6 +5742,9 @@ export function applyPostSummonAbAttrs(
|
|||||||
args,
|
args,
|
||||||
false,
|
false,
|
||||||
simulated,
|
simulated,
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
priorityCondition
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6002,20 +6024,6 @@ export function applyOnLoseAbAttrs(pokemon: Pokemon, passive = false, simulated
|
|||||||
applySingleAbAttrs<PreLeaveFieldAbAttr>(pokemon, passive, PreLeaveFieldAbAttr, (attr, passive) => attr.applyPreLeaveField(pokemon, passive, simulated, [ ...args, true ]), args, true, simulated);
|
applySingleAbAttrs<PreLeaveFieldAbAttr>(pokemon, passive, PreLeaveFieldAbAttr, (attr, passive) => attr.applyPreLeaveField(pokemon, passive, simulated, [ ...args, true ]), args, true, simulated);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies only abilities whose priority meets a condition
|
|
||||||
*
|
|
||||||
* @param condition Apply to abilities whose priority meets the condition
|
|
||||||
*/
|
|
||||||
export function applyPriorityBasedAbAttrs(pokemon: Pokemon, condition: (p: number) => boolean, simulated: boolean = false, ...args: any[]) {
|
|
||||||
for (const passive of [ false, true ]) {
|
|
||||||
const ability: Ability = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
|
|
||||||
if (condition(ability.postSummonPriority)) {
|
|
||||||
applySingleAbAttrs<PostSummonAbAttr>(pokemon, passive, PostSummonAbAttr, (attr, passive) => attr.applyPostSummon(pokemon, passive, simulated, args), args, false, simulated)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function queueShowAbility(pokemon: Pokemon, passive: boolean): void {
|
function queueShowAbility(pokemon: Pokemon, passive: boolean): void {
|
||||||
globalScene.unshiftPhase(new ShowAbilityPhase(pokemon.id, passive));
|
globalScene.unshiftPhase(new ShowAbilityPhase(pokemon.id, passive));
|
||||||
globalScene.clearPhaseQueueSplice();
|
globalScene.clearPhaseQueueSplice();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { BattlerIndex } from "#app/battle";
|
import type { BattlerIndex } from "#app/battle";
|
||||||
import { applyPriorityBasedAbAttrs } from "#app/data/ability";
|
import { applyPostSummonAbAttrs, PostSummonAbAttr } from "#app/data/ability";
|
||||||
import { PokemonPhase } from "#app/phases/pokemon-phase";
|
import { PokemonPhase } from "#app/phases/pokemon-phase";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +20,7 @@ export class PostSummonActivateAbilityPhase extends PokemonPhase {
|
|||||||
start() {
|
start() {
|
||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
applyPriorityBasedAbAttrs(this.getPokemon(), (p: number) => p === this.priority);
|
applyPostSummonAbAttrs(PostSummonAbAttr, this.getPokemon(), false, (p: number) => p === this.priority);
|
||||||
|
|
||||||
this.end();
|
this.end();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type { BattlerIndex } from "#app/battle";
|
import type { BattlerIndex } from "#app/battle";
|
||||||
import { applyAbAttrs, applyPriorityBasedAbAttrs, CommanderAbAttr, PostSummonAbAttr } from "#app/data/ability";
|
import { applyAbAttrs, applyPostSummonAbAttrs, CommanderAbAttr, PostSummonAbAttr } from "#app/data/ability";
|
||||||
import { ArenaTrapTag } from "#app/data/arena-tag";
|
import { ArenaTrapTag } from "#app/data/arena-tag";
|
||||||
import { StatusEffect } from "#app/enums/status-effect";
|
import { StatusEffect } from "#app/enums/status-effect";
|
||||||
import { PokemonPhase } from "./pokemon-phase";
|
import { PokemonPhase } from "./pokemon-phase";
|
||||||
@ -23,21 +23,24 @@ export class PostSummonPhase extends PokemonPhase {
|
|||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
const pokemon = this.getPokemon();
|
const pokemon = this.getPokemon();
|
||||||
|
let indexAfterPostSummon = globalScene.phaseQueue.findIndex(phase => !(phase instanceof PostSummonPhase));
|
||||||
|
indexAfterPostSummon = indexAfterPostSummon === -1 ? globalScene.phaseQueue.length : indexAfterPostSummon;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!this.ordered &&
|
!this.ordered &&
|
||||||
globalScene.findPhase(phase => phase instanceof PostSummonPhase && phase.getPokemon() !== pokemon)
|
globalScene.findPhase(phase => phase instanceof PostSummonPhase && phase.getPokemon() !== pokemon)
|
||||||
) {
|
) {
|
||||||
globalScene.pushPhase(new PostSummonPhase(pokemon.getBattlerIndex(), true));
|
globalScene.phaseQueue.splice(indexAfterPostSummon++, 0, new PostSummonPhase(pokemon.getBattlerIndex(), true));
|
||||||
|
|
||||||
this.orderPostSummonPhases();
|
this.orderPostSummonPhases();
|
||||||
|
this.queueAbilityActivationPhases(indexAfterPostSummon);
|
||||||
|
|
||||||
this.end();
|
this.end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.ordered) {
|
if (!this.ordered) {
|
||||||
applyPriorityBasedAbAttrs(pokemon, (p: number) => p > 0);
|
applyPostSummonAbAttrs(PostSummonAbAttr, pokemon, false, (p: number) => p > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pokemon.status?.effect === StatusEffect.TOXIC) {
|
if (pokemon.status?.effect === StatusEffect.TOXIC) {
|
||||||
@ -52,9 +55,11 @@ export class PostSummonPhase extends PokemonPhase {
|
|||||||
) {
|
) {
|
||||||
pokemon.lapseTag(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON);
|
pokemon.lapseTag(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.ordered) {
|
if (!this.ordered) {
|
||||||
applyPriorityBasedAbAttrs(pokemon, (p: number) => p <= 0);
|
applyPostSummonAbAttrs(PostSummonAbAttr, pokemon, false, (p: number) => p <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const field = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
const field = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||||
for (const p of field) {
|
for (const p of field) {
|
||||||
applyAbAttrs(CommanderAbAttr, p, null, false);
|
applyAbAttrs(CommanderAbAttr, p, null, false);
|
||||||
@ -63,6 +68,9 @@ export class PostSummonPhase extends PokemonPhase {
|
|||||||
this.end();
|
this.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts the {@linkcode PostSummonPhase}s in the queue by effective speed
|
||||||
|
*/
|
||||||
private orderPostSummonPhases() {
|
private orderPostSummonPhases() {
|
||||||
globalScene.sortPhaseType(
|
globalScene.sortPhaseType(
|
||||||
PostSummonPhase,
|
PostSummonPhase,
|
||||||
@ -70,28 +78,37 @@ export class PostSummonPhase extends PokemonPhase {
|
|||||||
phaseB.getPokemon().getEffectiveStat(Stat.SPD) - phaseA.getPokemon().getEffectiveStat(Stat.SPD),
|
phaseB.getPokemon().getEffectiveStat(Stat.SPD) - phaseA.getPokemon().getEffectiveStat(Stat.SPD),
|
||||||
);
|
);
|
||||||
|
|
||||||
const positivePriorityPhases: PostSummonActivateAbilityPhase[] = [];
|
for (let i = 0; i < globalScene.phaseQueue.length && globalScene.phaseQueue[i] instanceof PostSummonPhase; i++) {
|
||||||
const zeroNegativePriorityPhases: PostSummonActivateAbilityPhase[] = [];
|
(globalScene.phaseQueue[i] as PostSummonPhase).ordered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
globalScene.phaseQueue.forEach((phase: PostSummonPhase) => {
|
/**
|
||||||
phase.ordered = true;
|
* Adds {@linkcode PostSummonActivateAbilityPhase}s for all {@linkcode PostSummonPhase}s in the queue
|
||||||
|
* @param endIndex The index of the first non-{@linkcode PostSummonPhase} Phase in the queue, or the length if none exists
|
||||||
|
*/
|
||||||
|
private queueAbilityActivationPhases(endIndex: number) {
|
||||||
|
const abilityPhases: PostSummonActivateAbilityPhase[] = [];
|
||||||
|
|
||||||
|
globalScene.phaseQueue.slice(0, endIndex).forEach((phase: PostSummonPhase) => {
|
||||||
const phasePokemon = phase.getPokemon();
|
const phasePokemon = phase.getPokemon();
|
||||||
|
|
||||||
for (const priority of phasePokemon.getAbilityPriorities()) {
|
phasePokemon
|
||||||
(priority > 0 ? positivePriorityPhases : zeroNegativePriorityPhases).push(
|
.getAbilityPriorities()
|
||||||
new PostSummonActivateAbilityPhase(phasePokemon.getBattlerIndex(), priority),
|
.forEach(priority =>
|
||||||
|
abilityPhases.push(new PostSummonActivateAbilityPhase(phasePokemon.getBattlerIndex(), priority)),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const phaseList of [positivePriorityPhases, zeroNegativePriorityPhases]) {
|
abilityPhases.sort(
|
||||||
phaseList.sort(
|
|
||||||
(phaseA: PostSummonActivateAbilityPhase, phaseB: PostSummonActivateAbilityPhase) =>
|
(phaseA: PostSummonActivateAbilityPhase, phaseB: PostSummonActivateAbilityPhase) =>
|
||||||
phaseB.getPriority() - phaseA.getPriority(),
|
phaseB.getPriority() - phaseA.getPriority(),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
globalScene.unshiftPhase(...positivePriorityPhases);
|
let zeroIndex = abilityPhases.findIndex(phase => phase.getPriority() === 0);
|
||||||
zeroNegativePriorityPhases.forEach(phase => globalScene.pushPhase(phase));
|
zeroIndex = zeroIndex === -1 ? abilityPhases.length : zeroIndex;
|
||||||
|
|
||||||
|
globalScene.unshiftPhase(...abilityPhases.slice(0, zeroIndex));
|
||||||
|
globalScene.phaseQueue.splice(endIndex, 0, ...abilityPhases.slice(zeroIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user