mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-24 01:02:19 +02:00
Add passive support
This commit is contained in:
parent
8a482fecc7
commit
ad7522b956
@ -4868,55 +4868,72 @@ async function applyAbAttrsInternal<TAttr extends AbAttr>(
|
|||||||
showAbilityInstant: boolean = false,
|
showAbilityInstant: boolean = false,
|
||||||
simulated: boolean = false,
|
simulated: boolean = false,
|
||||||
messages: string[] = [],
|
messages: string[] = [],
|
||||||
gainedMidTurn: boolean = false /** Ignore passives and abilities with {@linkcode NoOnGainActivationAttr} */
|
gainedMidTurn: boolean = false
|
||||||
) {
|
) {
|
||||||
for (const passive of [ false, true ]) {
|
for (const passive of [ false, true ]) {
|
||||||
if (!pokemon?.canApplyAbility(passive) || (passive && (pokemon.getPassiveAbility().id === pokemon.getAbility().id || gainedMidTurn))
|
if (!pokemon?.canApplyAbility(passive) || (passive && (pokemon.getPassiveAbility().id === pokemon.getAbility().id))) {
|
||||||
|| (gainedMidTurn && pokemon.getAbility().getAttrs(PostSummonAbAttr).some(a => !a.shouldActivateOnGain()))) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ability = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
|
applySingleAbAttrs(pokemon, passive, attrType, applyFunc, args, gainedMidTurn, simulated, showAbilityInstant, messages);
|
||||||
for (const attr of ability.getAttrs(attrType)) {
|
|
||||||
const condition = attr.getCondition();
|
|
||||||
if (condition && !condition(pokemon)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
globalScene.setPhaseQueueSplice();
|
|
||||||
|
|
||||||
let result = applyFunc(attr, passive);
|
|
||||||
// TODO Remove this when promises get reworked
|
|
||||||
if (result instanceof Promise) {
|
|
||||||
result = await result;
|
|
||||||
}
|
|
||||||
if (result) {
|
|
||||||
if (pokemon.summonData && !pokemon.summonData.abilitiesApplied.includes(ability.id)) {
|
|
||||||
pokemon.summonData.abilitiesApplied.push(ability.id);
|
|
||||||
}
|
|
||||||
if (pokemon.battleData && !simulated && !pokemon.battleData.abilitiesApplied.includes(ability.id)) {
|
|
||||||
pokemon.battleData.abilitiesApplied.push(ability.id);
|
|
||||||
}
|
|
||||||
if (attr.showAbility && !simulated) {
|
|
||||||
if (showAbilityInstant) {
|
|
||||||
globalScene.abilityBar.showAbility(pokemon, passive);
|
|
||||||
} else {
|
|
||||||
queueShowAbility(pokemon, passive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const message = attr.getTriggerMessage(pokemon, ability.name, args);
|
|
||||||
if (message) {
|
|
||||||
if (!simulated) {
|
|
||||||
globalScene.queueMessage(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
messages.push(message!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
globalScene.clearPhaseQueueSplice();
|
globalScene.clearPhaseQueueSplice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function applySingleAbAttrs<TAttr extends AbAttr>(
|
||||||
|
pokemon: Pokemon,
|
||||||
|
passive: boolean,
|
||||||
|
attrType: Constructor<TAttr>,
|
||||||
|
applyFunc: AbAttrApplyFunc<TAttr>,
|
||||||
|
args: any[],
|
||||||
|
gainedMidTurn: boolean = false,
|
||||||
|
simulated: boolean = false,
|
||||||
|
showAbilityInstant: boolean = false,
|
||||||
|
messages: string[] = []
|
||||||
|
) {
|
||||||
|
const ability = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
|
||||||
|
if (gainedMidTurn && ability.getAttrs(attrType).some(attr => attr instanceof PostSummonAbAttr && !attr.shouldActivateOnGain())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const attr of ability.getAttrs(attrType)) {
|
||||||
|
const condition = attr.getCondition();
|
||||||
|
if ((condition && !condition(pokemon))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
globalScene.setPhaseQueueSplice();
|
||||||
|
|
||||||
|
let result = applyFunc(attr, passive);
|
||||||
|
// TODO Remove this when promises get reworked
|
||||||
|
if (result instanceof Promise) {
|
||||||
|
result = await result;
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
if (pokemon.summonData && !pokemon.summonData.abilitiesApplied.includes(ability.id)) {
|
||||||
|
pokemon.summonData.abilitiesApplied.push(ability.id);
|
||||||
|
}
|
||||||
|
if (pokemon.battleData && !simulated && !pokemon.battleData.abilitiesApplied.includes(ability.id)) {
|
||||||
|
pokemon.battleData.abilitiesApplied.push(ability.id);
|
||||||
|
}
|
||||||
|
if (attr.showAbility && !simulated) {
|
||||||
|
if (showAbilityInstant) {
|
||||||
|
globalScene.abilityBar.showAbility(pokemon, passive);
|
||||||
|
} else {
|
||||||
|
queueShowAbility(pokemon, passive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const message = attr.getTriggerMessage(pokemon, ability.name, args);
|
||||||
|
if (message) {
|
||||||
|
if (!simulated) {
|
||||||
|
globalScene.queueMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
messages.push(message!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ForceSwitchOutHelper {
|
class ForceSwitchOutHelper {
|
||||||
constructor(private switchType: SwitchType) {}
|
constructor(private switchType: SwitchType) {}
|
||||||
|
|
||||||
@ -5308,15 +5325,15 @@ export function applyPostItemLostAbAttrs(attrType: Constructor<PostItemLostAbAtt
|
|||||||
*
|
*
|
||||||
* Ignores passives as they don't change and shouldn't be reapplied when main abilities change
|
* Ignores passives as they don't change and shouldn't be reapplied when main abilities change
|
||||||
*/
|
*/
|
||||||
export function applyOnGainAbAttrs(pokemon: Pokemon, simulated: boolean = false, ...args: any[]): Promise<void> {
|
export function applyOnGainAbAttrs(pokemon: Pokemon, passive: boolean = false, simulated: boolean = false, ...args: any[]): void {
|
||||||
return applyAbAttrsInternal<PostSummonAbAttr>(PostSummonAbAttr, pokemon, (attr, passive) => attr.applyPostSummon(pokemon, passive, simulated, args), args, false, simulated, [], true);
|
applySingleAbAttrs<PostSummonAbAttr>(pokemon, passive, PostSummonAbAttr, (attr, passive) => attr.applyPostSummon(pokemon, passive, simulated, args), args, true, simulated);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears primal weather during the turn if {@linkcode pokemon}'s ability corresponds to one
|
* Clears primal weather during the turn if {@linkcode pokemon}'s ability corresponds to one
|
||||||
*/
|
*/
|
||||||
export function applyOnGainClearWeatherAbAttrs(pokemon: Pokemon, simulated: boolean = false, ...args: any[]): Promise<void> {
|
export function applyOnLoseClearWeatherAbAttrs(pokemon: Pokemon, passive: boolean = false, simulated: boolean = false, ...args: any[]): void {
|
||||||
return applyAbAttrsInternal<PreLeaveFieldClearWeatherAbAttr>(PreLeaveFieldClearWeatherAbAttr, pokemon, (attr, passive) => attr.applyPreLeaveField(pokemon, passive, simulated, [ ...args, true ]), args, true, simulated, [], true);
|
applySingleAbAttrs<PreLeaveFieldClearWeatherAbAttr>(pokemon, passive, PreLeaveFieldClearWeatherAbAttr, (attr, passive) => attr.applyPreLeaveField(pokemon, passive, simulated, [ ...args, true ]), args, true, 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));
|
||||||
|
@ -64,7 +64,7 @@ import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoo
|
|||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "#app/data/arena-tag";
|
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "#app/data/arena-tag";
|
||||||
import type { Ability, AbAttr } from "#app/data/ability";
|
import type { Ability, AbAttr } from "#app/data/ability";
|
||||||
import { StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs, InfiltratorAbAttr, AlliedFieldDamageReductionAbAttr, PostDamageAbAttr, applyPostDamageAbAttrs, CommanderAbAttr, applyPostItemLostAbAttrs, PostItemLostAbAttr, applyOnGainAbAttrs, PreLeaveFieldAbAttr, applyPreLeaveFieldAbAttrs, applyOnGainClearWeatherAbAttrs } from "#app/data/ability";
|
import { StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs, InfiltratorAbAttr, AlliedFieldDamageReductionAbAttr, PostDamageAbAttr, applyPostDamageAbAttrs, CommanderAbAttr, applyPostItemLostAbAttrs, PostItemLostAbAttr, applyOnGainAbAttrs, PreLeaveFieldAbAttr, applyPreLeaveFieldAbAttrs, applyOnLoseClearWeatherAbAttrs } from "#app/data/ability";
|
||||||
import type PokemonData from "#app/system/pokemon-data";
|
import type PokemonData from "#app/system/pokemon-data";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
@ -1487,10 +1487,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* Also clears primal weather if it is from the ability being changed
|
* Also clears primal weather if it is from the ability being changed
|
||||||
* @param ability New Ability
|
* @param ability New Ability
|
||||||
*/
|
*/
|
||||||
public setTempAbility(ability: Ability): void {
|
public setTempAbility(ability: Ability, passive: boolean = false): void {
|
||||||
applyOnGainClearWeatherAbAttrs(this);
|
applyOnLoseClearWeatherAbAttrs(this, passive);
|
||||||
this.summonData.ability = ability.id;
|
if (passive) {
|
||||||
applyOnGainAbAttrs(this);
|
this.summonData.passiveAbility = ability.id;
|
||||||
|
} else {
|
||||||
|
this.summonData.ability = ability.id;
|
||||||
|
}
|
||||||
|
applyOnGainAbAttrs(this, passive);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user