mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-17 22:02:18 +02:00
Faint bypass on canApplyAbility
This commit is contained in:
parent
83c00398fc
commit
7fb33b0542
@ -933,7 +933,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
if (resetArenaState)
|
if (resetArenaState)
|
||||||
{
|
{
|
||||||
pokemon.resetBattleData();
|
pokemon.resetBattleData();
|
||||||
this.resetPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
|
applyPostBattleInitAbAttrs(PostBattleInitFormChangeAbAttr, pokemon, true);
|
||||||
}
|
}
|
||||||
this.triggerPokemonFormChange(pokemon, SpeciesFormChangeTimeOfDayTrigger);
|
this.triggerPokemonFormChange(pokemon, SpeciesFormChangeTimeOfDayTrigger);
|
||||||
}
|
}
|
||||||
@ -1964,32 +1964,6 @@ export default class BattleScene extends SceneBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetPokemonFormChange(pokemon: Pokemon, formChangeTriggerType: {new( ... args: any[]): SpeciesFormChangeTrigger}, delayed: boolean = false, modal: boolean = false): boolean {
|
|
||||||
if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId)) {
|
|
||||||
|
|
||||||
// Find the base form that matches the same ability
|
|
||||||
const matchingFormChange = pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.findTrigger(formChangeTriggerType) &&
|
|
||||||
fc.formKey === pokemon.species.forms[0].formKey &&
|
|
||||||
fc.canChange(pokemon));
|
|
||||||
if (matchingFormChange) {
|
|
||||||
let phase: Phase;
|
|
||||||
if (pokemon instanceof PlayerPokemon && !matchingFormChange.quiet)
|
|
||||||
phase = new FormChangePhase(this, pokemon, matchingFormChange, modal);
|
|
||||||
else
|
|
||||||
phase = new QuietFormChangePhase(this, pokemon, matchingFormChange);
|
|
||||||
if (pokemon instanceof PlayerPokemon && !matchingFormChange.quiet && modal)
|
|
||||||
this.overridePhase(phase);
|
|
||||||
else if (delayed)
|
|
||||||
this.pushPhase(phase);
|
|
||||||
else
|
|
||||||
this.unshiftPhase(phase);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
validateAchvs(achvType: { new(...args: any[]): Achv }, ...args: any[]): void {
|
validateAchvs(achvType: { new(...args: any[]): Achv }, ...args: any[]): void {
|
||||||
const filteredAchvs = Object.values(achvs).filter(a => a instanceof achvType);
|
const filteredAchvs = Object.values(achvs).filter(a => a instanceof achvType);
|
||||||
for (let achv of filteredAchvs)
|
for (let achv of filteredAchvs)
|
||||||
|
@ -2783,7 +2783,7 @@ export class IgnoreTypeStatusEffectImmunityAbAttr extends AbAttr {
|
|||||||
function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any[]): TAttr },
|
function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any[]): TAttr },
|
||||||
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
|
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
if (!pokemon.canApplyAbility(passive)) {
|
if (!pokemon.canApplyAbility(passive, args[0])) {
|
||||||
if (!passive)
|
if (!passive)
|
||||||
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
|
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
|
||||||
else
|
else
|
||||||
@ -3436,7 +3436,7 @@ export function initAbilities() {
|
|||||||
.attr(PostDefendContactDamageAbAttr, 8)
|
.attr(PostDefendContactDamageAbAttr, 8)
|
||||||
.bypassFaint(),
|
.bypassFaint(),
|
||||||
new Ability(Abilities.ZEN_MODE, 5)
|
new Ability(Abilities.ZEN_MODE, 5)
|
||||||
.attr(PostBattleInitFormChangeAbAttr, p => p.getHpRatio() <= 0.5 ? 1 : 0)
|
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||||
.attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 ? 1 : 0)
|
.attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 ? 1 : 0)
|
||||||
.attr(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 ? 1 : 0)
|
.attr(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 ? 1 : 0)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
@ -3534,7 +3534,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.MERCILESS, 7)
|
new Ability(Abilities.MERCILESS, 7)
|
||||||
.attr(ConditionalCritAbAttr, (user, target, move) => target.status?.effect === StatusEffect.TOXIC || target.status?.effect === StatusEffect.POISON),
|
.attr(ConditionalCritAbAttr, (user, target, move) => target.status?.effect === StatusEffect.TOXIC || target.status?.effect === StatusEffect.POISON),
|
||||||
new Ability(Abilities.SHIELDS_DOWN, 7)
|
new Ability(Abilities.SHIELDS_DOWN, 7)
|
||||||
.attr(PostBattleInitFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
|
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||||
.attr(PostSummonFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
|
.attr(PostSummonFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
|
||||||
.attr(PostTurnFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
|
.attr(PostTurnFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
@ -3567,7 +3567,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.SURGE_SURFER, 7)
|
new Ability(Abilities.SURGE_SURFER, 7)
|
||||||
.conditionalAttr(getTerrainCondition(TerrainType.ELECTRIC), BattleStatMultiplierAbAttr, BattleStat.SPD, 2),
|
.conditionalAttr(getTerrainCondition(TerrainType.ELECTRIC), BattleStatMultiplierAbAttr, BattleStat.SPD, 2),
|
||||||
new Ability(Abilities.SCHOOLING, 7)
|
new Ability(Abilities.SCHOOLING, 7)
|
||||||
.attr(PostBattleInitFormChangeAbAttr, p => p.level < 20 || p.getHpRatio() <= 0.25 ? 0 : 1)
|
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||||
.attr(PostSummonFormChangeAbAttr, p => p.level < 20 || p.getHpRatio() <= 0.25 ? 0 : 1)
|
.attr(PostSummonFormChangeAbAttr, p => p.level < 20 || p.getHpRatio() <= 0.25 ? 0 : 1)
|
||||||
.attr(PostTurnFormChangeAbAttr, p => p.level < 20 || p.getHpRatio() <= 0.25 ? 0 : 1)
|
.attr(PostTurnFormChangeAbAttr, p => p.level < 20 || p.getHpRatio() <= 0.25 ? 0 : 1)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
@ -3577,7 +3577,7 @@ export function initAbilities() {
|
|||||||
new Ability(Abilities.DISGUISE, 7)
|
new Ability(Abilities.DISGUISE, 7)
|
||||||
.attr(PreDefendMovePowerToOneAbAttr, (target, user, move) => target.formIndex == 0 && target.getAttackTypeEffectiveness(move.type, user) > 0)
|
.attr(PreDefendMovePowerToOneAbAttr, (target, user, move) => target.formIndex == 0 && target.getAttackTypeEffectiveness(move.type, user) > 0)
|
||||||
.attr(PostSummonFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
.attr(PostSummonFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
||||||
.attr(PostBattleInitFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||||
.attr(PostDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
.attr(PostDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
||||||
.attr(PreDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
.attr(PreDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
||||||
.attr(PostDefendDisguiseAbAttr)
|
.attr(PostDefendDisguiseAbAttr)
|
||||||
@ -3589,15 +3589,16 @@ export function initAbilities() {
|
|||||||
.ignorable()
|
.ignorable()
|
||||||
.partial(),
|
.partial(),
|
||||||
new Ability(Abilities.BATTLE_BOND, 7)
|
new Ability(Abilities.BATTLE_BOND, 7)
|
||||||
.attr(PostVictoryFormChangeAbAttr, p => p.getFormKey() ? 2 : 1)
|
.attr(PostVictoryFormChangeAbAttr, () => 2)
|
||||||
|
.attr(PostBattleInitFormChangeAbAttr, () => 1)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(UnsuppressableAbilityAbAttr)
|
.attr(UnsuppressableAbilityAbAttr)
|
||||||
.attr(NoFusionAbilityAbAttr),
|
.attr(NoFusionAbilityAbAttr),
|
||||||
new Ability(Abilities.POWER_CONSTRUCT, 7) // TODO: 10% Power Construct Zygarde isn't accounted for yet. If changed, update Zygarde's getSpeciesFormIndex entry accordingly
|
new Ability(Abilities.POWER_CONSTRUCT, 7) // TODO: 10% Power Construct Zygarde isn't accounted for yet. If changed, update Zygarde's getSpeciesFormIndex entry accordingly
|
||||||
.attr(PostBattleInitFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 0)
|
.attr(PostBattleInitFormChangeAbAttr, () => 2)
|
||||||
.attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 0)
|
.attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 2)
|
||||||
.attr(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 0)
|
.attr(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 2)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(UnsuppressableAbilityAbAttr)
|
.attr(UnsuppressableAbilityAbAttr)
|
||||||
@ -3823,7 +3824,8 @@ export function initAbilities() {
|
|||||||
.attr(UnsuppressableAbilityAbAttr)
|
.attr(UnsuppressableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr)
|
.attr(NoTransformAbilityAbAttr)
|
||||||
.attr(NoFusionAbilityAbAttr)
|
.attr(NoFusionAbilityAbAttr)
|
||||||
.attr(PreSwitchOutFormChangeAbAttr, p => p.getFormKey() ? 1 : 0),
|
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||||
|
.attr(PreSwitchOutFormChangeAbAttr, () => 1),
|
||||||
new Ability(Abilities.COMMANDER, 9)
|
new Ability(Abilities.COMMANDER, 9)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
@ -3905,22 +3907,26 @@ export function initAbilities() {
|
|||||||
.attr(PostBattleInitStatChangeAbAttr, BattleStat.SPD, 1, true)
|
.attr(PostBattleInitStatChangeAbAttr, BattleStat.SPD, 1, true)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr),
|
.attr(NoTransformAbilityAbAttr)
|
||||||
|
.partial(),
|
||||||
new Ability(Abilities.EMBODY_ASPECT_WELLSPRING, 9)
|
new Ability(Abilities.EMBODY_ASPECT_WELLSPRING, 9)
|
||||||
.attr(PostBattleInitStatChangeAbAttr, BattleStat.SPDEF, 1, true)
|
.attr(PostBattleInitStatChangeAbAttr, BattleStat.SPDEF, 1, true)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr),
|
.attr(NoTransformAbilityAbAttr)
|
||||||
|
.partial(),
|
||||||
new Ability(Abilities.EMBODY_ASPECT_HEARTHFLAME, 9)
|
new Ability(Abilities.EMBODY_ASPECT_HEARTHFLAME, 9)
|
||||||
.attr(PostBattleInitStatChangeAbAttr, BattleStat.ATK, 1, true)
|
.attr(PostBattleInitStatChangeAbAttr, BattleStat.ATK, 1, true)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr),
|
.attr(NoTransformAbilityAbAttr)
|
||||||
|
.partial(),
|
||||||
new Ability(Abilities.EMBODY_ASPECT_CORNERSTONE, 9)
|
new Ability(Abilities.EMBODY_ASPECT_CORNERSTONE, 9)
|
||||||
.attr(PostBattleInitStatChangeAbAttr, BattleStat.DEF, 1, true)
|
.attr(PostBattleInitStatChangeAbAttr, BattleStat.DEF, 1, true)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
.attr(UnswappableAbilityAbAttr)
|
.attr(UnswappableAbilityAbAttr)
|
||||||
.attr(NoTransformAbilityAbAttr),
|
.attr(NoTransformAbilityAbAttr)
|
||||||
|
.partial(),
|
||||||
new Ability(Abilities.TERA_SHIFT, 9)
|
new Ability(Abilities.TERA_SHIFT, 9)
|
||||||
.attr(PostSummonFormChangeAbAttr, p => p.getFormKey() ? 0 : 1)
|
.attr(PostSummonFormChangeAbAttr, p => p.getFormKey() ? 0 : 1)
|
||||||
.attr(UncopiableAbilityAbAttr)
|
.attr(UncopiableAbilityAbAttr)
|
||||||
|
@ -890,7 +890,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @param {boolean} passive If true, check if passive can be applied instead of non-passive
|
* @param {boolean} passive If true, check if passive can be applied instead of non-passive
|
||||||
* @returns {Ability} The passive ability of the pokemon
|
* @returns {Ability} The passive ability of the pokemon
|
||||||
*/
|
*/
|
||||||
canApplyAbility(passive: boolean = false): boolean {
|
canApplyAbility(passive: boolean = false, forceBypass: boolean = false): boolean {
|
||||||
if (passive && !this.hasPassive())
|
if (passive && !this.hasPassive())
|
||||||
return false;
|
return false;
|
||||||
const ability = (!passive ? this.getAbility() : this.getPassiveAbility());
|
const ability = (!passive ? this.getAbility() : this.getPassiveAbility());
|
||||||
@ -911,7 +911,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
if (suppressed.value)
|
if (suppressed.value)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (this.hp || ability.isBypassFaint) && !ability.conditions.find(condition => !condition(this));
|
return (this.hp || ability.isBypassFaint || forceBypass) && !ability.conditions.find(condition => !condition(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -936,17 +936,13 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
if (!this.loaded) {
|
if (!this.loaded) {
|
||||||
const availablePartyMembers = this.scene.getParty().filter(p => !p.isFainted());
|
const availablePartyMembers = this.scene.getParty().filter(p => !p.isFainted());
|
||||||
|
|
||||||
if (availablePartyMembers[0].isOnField())
|
if (!availablePartyMembers[0].isOnField())
|
||||||
applyPostBattleInitAbAttrs(PostBattleInitAbAttr, availablePartyMembers[0]);
|
|
||||||
else
|
|
||||||
this.scene.pushPhase(new SummonPhase(this.scene, 0));
|
this.scene.pushPhase(new SummonPhase(this.scene, 0));
|
||||||
|
|
||||||
if (this.scene.currentBattle.double) {
|
if (this.scene.currentBattle.double) {
|
||||||
if (availablePartyMembers.length > 1) {
|
if (availablePartyMembers.length > 1) {
|
||||||
this.scene.pushPhase(new ToggleDoublePositionPhase(this.scene, true));
|
this.scene.pushPhase(new ToggleDoublePositionPhase(this.scene, true));
|
||||||
if (availablePartyMembers[1].isOnField())
|
if (!availablePartyMembers[1].isOnField())
|
||||||
applyPostBattleInitAbAttrs(PostBattleInitAbAttr, availablePartyMembers[1]);
|
|
||||||
else
|
|
||||||
this.scene.pushPhase(new SummonPhase(this.scene, 1));
|
this.scene.pushPhase(new SummonPhase(this.scene, 1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1397,8 +1393,6 @@ export class SwitchSummonPhase extends SummonPhase {
|
|||||||
if (!this.batonPass)
|
if (!this.batonPass)
|
||||||
(this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.removeTagsBySourceId(pokemon.id));
|
(this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.removeTagsBySourceId(pokemon.id));
|
||||||
|
|
||||||
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, pokemon);
|
|
||||||
|
|
||||||
this.scene.ui.showText(this.player ?
|
this.scene.ui.showText(this.player ?
|
||||||
i18next.t('battle:playerComeBack', { pokemonName: pokemon.name }) :
|
i18next.t('battle:playerComeBack', { pokemonName: pokemon.name }) :
|
||||||
i18next.t('battle:trainerComeBack', {
|
i18next.t('battle:trainerComeBack', {
|
||||||
@ -1427,6 +1421,7 @@ export class SwitchSummonPhase extends SummonPhase {
|
|||||||
const party = this.player ? this.getParty() : this.scene.getEnemyParty();
|
const party = this.player ? this.getParty() : this.scene.getEnemyParty();
|
||||||
const switchedPokemon = party[this.slotIndex];
|
const switchedPokemon = party[this.slotIndex];
|
||||||
this.lastPokemon = this.getPokemon();
|
this.lastPokemon = this.getPokemon();
|
||||||
|
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, this.lastPokemon);
|
||||||
if (this.batonPass && switchedPokemon) {
|
if (this.batonPass && switchedPokemon) {
|
||||||
(this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.transferTagsBySourceId(this.lastPokemon.id, switchedPokemon.id));
|
(this.player ? this.scene.getEnemyField() : this.scene.getPlayerField()).forEach(enemyPokemon => enemyPokemon.transferTagsBySourceId(this.lastPokemon.id, switchedPokemon.id));
|
||||||
if (!this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) {
|
if (!this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === switchedPokemon.id)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user