[Bug] Fix uses of getAlly() (#5618)
* Fix plus/minus crash * Update getAlly() uses
This commit is contained in:
parent
c6721521ab
commit
4c8f81bb09
|
@ -854,7 +854,8 @@ export class PostDefendStatStageChangeAbAttr extends PostDefendAbAttr {
|
|||
}
|
||||
|
||||
if (this.allOthers) {
|
||||
const otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents();
|
||||
const ally = pokemon.getAlly();
|
||||
const otherPokemon = !Utils.isNullOrUndefined(ally) ? pokemon.getOpponents().concat([ ally ]) : pokemon.getOpponents();
|
||||
for (const other of otherPokemon) {
|
||||
globalScene.unshiftPhase(new StatStageChangePhase((other).getBattlerIndex(), false, [ this.stat ], this.stages));
|
||||
}
|
||||
|
@ -2460,12 +2461,12 @@ export class PostSummonAllyHealAbAttr extends PostSummonAbAttr {
|
|||
}
|
||||
|
||||
override canApplyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
||||
return pokemon.getAlly()?.isActive(true);
|
||||
return pokemon.getAlly()?.isActive(true) ?? false;
|
||||
}
|
||||
|
||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
const target = pokemon.getAlly();
|
||||
if (!simulated) {
|
||||
if (!simulated && !Utils.isNullOrUndefined(target)) {
|
||||
globalScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
|
||||
Utils.toDmgValue(pokemon.getMaxHp() / this.healRatio), i18next.t("abilityTriggers:postSummonAllyHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(target), pokemonName: pokemon.name }), true, !this.showAnim));
|
||||
}
|
||||
|
@ -2486,12 +2487,12 @@ export class PostSummonClearAllyStatStagesAbAttr extends PostSummonAbAttr {
|
|||
}
|
||||
|
||||
override canApplyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
||||
return pokemon.getAlly()?.isActive(true);
|
||||
return pokemon.getAlly()?.isActive(true) ?? false;
|
||||
}
|
||||
|
||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
const target = pokemon.getAlly();
|
||||
if (!simulated) {
|
||||
if (!simulated && !Utils.isNullOrUndefined(target)) {
|
||||
for (const s of BATTLE_STATS) {
|
||||
target.setStatStage(s, 0);
|
||||
}
|
||||
|
@ -2712,7 +2713,7 @@ export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr {
|
|||
}
|
||||
|
||||
const ally = pokemon.getAlly();
|
||||
if (!ally || ally.getStatStages().every(s => s === 0)) {
|
||||
if (Utils.isNullOrUndefined(ally) || ally.getStatStages().every(s => s === 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2721,7 +2722,7 @@ export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr {
|
|||
|
||||
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
const ally = pokemon.getAlly();
|
||||
if (!simulated) {
|
||||
if (!simulated && !Utils.isNullOrUndefined(ally)) {
|
||||
for (const s of BATTLE_STATS) {
|
||||
pokemon.setStatStage(s, ally.getStatStage(s));
|
||||
}
|
||||
|
@ -2866,8 +2867,9 @@ export class CommanderAbAttr extends AbAttr {
|
|||
// another Pokemon, this effect cannot apply.
|
||||
|
||||
// TODO: Should this work with X + Dondozo fusions?
|
||||
return globalScene.currentBattle?.double && pokemon.getAlly()?.species.speciesId === Species.DONDOZO
|
||||
&& !(pokemon.getAlly().isFainted() || pokemon.getAlly().getTag(BattlerTagType.COMMANDED));
|
||||
const ally = pokemon.getAlly();
|
||||
return globalScene.currentBattle?.double && !Utils.isNullOrUndefined(ally) && ally.species.speciesId === Species.DONDOZO
|
||||
&& !(ally.isFainted() || ally.getTag(BattlerTagType.COMMANDED));
|
||||
}
|
||||
|
||||
override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: null, args: any[]): void {
|
||||
|
@ -2877,7 +2879,7 @@ export class CommanderAbAttr extends AbAttr {
|
|||
// Play an animation of the source jumping into the ally Dondozo's mouth
|
||||
globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.COMMANDER_APPLY);
|
||||
// Apply boosts from this effect to the ally Dondozo
|
||||
pokemon.getAlly().addTag(BattlerTagType.COMMANDED, 0, Moves.NONE, pokemon.id);
|
||||
pokemon.getAlly()?.addTag(BattlerTagType.COMMANDED, 0, Moves.NONE, pokemon.id);
|
||||
// Cancel the source Pokemon's next move (if a move is queued)
|
||||
globalScene.tryRemovePhase((phase) => phase instanceof MovePhase && phase.pokemon === pokemon);
|
||||
}
|
||||
|
@ -4077,7 +4079,7 @@ export class PostTurnStatusHealAbAttr extends PostTurnAbAttr {
|
|||
*/
|
||||
export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
|
||||
private allyTarget: boolean;
|
||||
private target: Pokemon;
|
||||
private target: Pokemon | undefined;
|
||||
|
||||
constructor(allyTarget = false) {
|
||||
super(true);
|
||||
|
@ -4090,11 +4092,11 @@ export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
|
|||
} else {
|
||||
this.target = pokemon;
|
||||
}
|
||||
return !Utils.isNullOrUndefined(this.target.status);
|
||||
return !Utils.isNullOrUndefined(this.target?.status);
|
||||
}
|
||||
|
||||
override applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
|
||||
if (!simulated && this.target.status) {
|
||||
if (!simulated && this.target?.status) {
|
||||
globalScene.queueMessage(getStatusEffectHealText(this.target.status?.effect, getPokemonNameWithAffix(this.target)));
|
||||
this.target.resetStatus(false);
|
||||
this.target.updateInfo();
|
||||
|
@ -5440,6 +5442,8 @@ class ForceSwitchOutHelper {
|
|||
* It will not flee if it is a Mystery Encounter with fleeing disabled (checked in `getSwitchOutCondition()`) or if it is a wave 10x wild boss
|
||||
*/
|
||||
} else {
|
||||
const allyPokemon = switchOutTarget.getAlly();
|
||||
|
||||
if (!globalScene.currentBattle.waveIndex || globalScene.currentBattle.waveIndex % 10 === 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -5447,14 +5451,12 @@ class ForceSwitchOutHelper {
|
|||
if (switchOutTarget.hp > 0) {
|
||||
switchOutTarget.leaveField(false);
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
|
||||
|
||||
if (globalScene.currentBattle.double) {
|
||||
const allyPokemon = switchOutTarget.getAlly();
|
||||
if (globalScene.currentBattle.double && !Utils.isNullOrUndefined(allyPokemon)) {
|
||||
globalScene.redirectPokemonMoves(switchOutTarget, allyPokemon);
|
||||
}
|
||||
}
|
||||
|
||||
if (!switchOutTarget.getAlly()?.isActive(true)) {
|
||||
if (!allyPokemon?.isActive(true)) {
|
||||
globalScene.clearEnemyHeldItemModifiers();
|
||||
|
||||
if (switchOutTarget.hp) {
|
||||
|
@ -6440,9 +6442,9 @@ export function initAbilities() {
|
|||
new Ability(Abilities.CUTE_CHARM, 3)
|
||||
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
|
||||
new Ability(Abilities.PLUS, 3)
|
||||
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5),
|
||||
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => (p.getAlly()?.hasAbility(a) ?? false)), StatMultiplierAbAttr, Stat.SPATK, 1.5),
|
||||
new Ability(Abilities.MINUS, 3)
|
||||
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5),
|
||||
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => (p.getAlly()?.hasAbility(a) ?? false)), StatMultiplierAbAttr, Stat.SPATK, 1.5),
|
||||
new Ability(Abilities.FORECAST, 3)
|
||||
.uncopiable()
|
||||
.unreplaceable()
|
||||
|
@ -6669,7 +6671,7 @@ export function initAbilities() {
|
|||
.attr(PostDefendMoveDisableAbAttr, 30)
|
||||
.bypassFaint(),
|
||||
new Ability(Abilities.HEALER, 5)
|
||||
.conditionalAttr(pokemon => pokemon.getAlly() && Utils.randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true),
|
||||
.conditionalAttr(pokemon => !Utils.isNullOrUndefined(pokemon.getAlly()) && Utils.randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true),
|
||||
new Ability(Abilities.FRIEND_GUARD, 5)
|
||||
.attr(AlliedFieldDamageReductionAbAttr, 0.75)
|
||||
.ignorable(),
|
||||
|
|
|
@ -788,9 +788,9 @@ export default class Move implements Localizable {
|
|||
}
|
||||
|
||||
applyPreAttackAbAttrs(VariableMovePowerAbAttr, source, target, this, simulated, power);
|
||||
|
||||
if (source.getAlly()) {
|
||||
applyPreAttackAbAttrs(AllyMoveCategoryPowerBoostAbAttr, source.getAlly(), target, this, simulated, power);
|
||||
const ally = source.getAlly();
|
||||
if (!Utils.isNullOrUndefined(ally)) {
|
||||
applyPreAttackAbAttrs(AllyMoveCategoryPowerBoostAbAttr, ally, target, this, simulated, power);
|
||||
}
|
||||
|
||||
const fieldAuras = new Set(
|
||||
|
@ -911,7 +911,8 @@ export default class Move implements Localizable {
|
|||
];
|
||||
|
||||
// ...and cannot enhance Pollen Puff when targeting an ally.
|
||||
const exceptPollenPuffAlly: boolean = this.id === Moves.POLLEN_PUFF && targets.includes(user.getAlly()?.getBattlerIndex())
|
||||
const ally = user.getAlly();
|
||||
const exceptPollenPuffAlly: boolean = this.id === Moves.POLLEN_PUFF && !Utils.isNullOrUndefined(ally) && targets.includes(ally.getBattlerIndex())
|
||||
|
||||
return (!restrictSpread || !isMultiTarget)
|
||||
&& !this.isChargingMove()
|
||||
|
@ -1946,7 +1947,7 @@ export class FlameBurstAttr extends MoveEffectAttr {
|
|||
const targetAlly = target.getAlly();
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
|
||||
if (targetAlly) {
|
||||
if (!Utils.isNullOrUndefined(targetAlly)) {
|
||||
applyAbAttrs(BlockNonDirectDamageAbAttr, targetAlly, cancelled);
|
||||
}
|
||||
|
||||
|
@ -1959,7 +1960,7 @@ export class FlameBurstAttr extends MoveEffectAttr {
|
|||
}
|
||||
|
||||
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
|
||||
return target.getAlly() ? -5 : 0;
|
||||
return !Utils.isNullOrUndefined(target.getAlly()) ? -5 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4357,10 +4358,10 @@ export class LastMoveDoublePowerAttr extends VariablePowerAttr {
|
|||
const userAlly = user.getAlly();
|
||||
const enemyAlly = enemy?.getAlly();
|
||||
|
||||
if (userAlly && userAlly.turnData.acted) {
|
||||
if (!Utils.isNullOrUndefined(userAlly) && userAlly.turnData.acted) {
|
||||
pokemonActed.push(userAlly);
|
||||
}
|
||||
if (enemyAlly && enemyAlly.turnData.acted) {
|
||||
if (!Utils.isNullOrUndefined(enemyAlly) && enemyAlly.turnData.acted) {
|
||||
pokemonActed.push(enemyAlly);
|
||||
}
|
||||
}
|
||||
|
@ -6162,9 +6163,8 @@ export class RevivalBlessingAttr extends MoveEffectAttr {
|
|||
pokemon.resetStatus();
|
||||
pokemon.heal(Math.min(Utils.toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: getPokemonNameWithAffix(pokemon) }), 0, true);
|
||||
|
||||
if (globalScene.currentBattle.double && globalScene.getEnemyParty().length > 1) {
|
||||
const allyPokemon = user.getAlly();
|
||||
const allyPokemon = user.getAlly();
|
||||
if (globalScene.currentBattle.double && globalScene.getEnemyParty().length > 1 && !Utils.isNullOrUndefined(allyPokemon)) {
|
||||
// Handle cases where revived pokemon needs to get switched in on same turn
|
||||
if (allyPokemon.isFainted() || allyPokemon === pokemon) {
|
||||
// Enemy switch phase should be removed and replaced with the revived pkmn switching in
|
||||
|
@ -6343,18 +6343,19 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||
return false;
|
||||
}
|
||||
|
||||
const allyPokemon = switchOutTarget.getAlly();
|
||||
|
||||
if (switchOutTarget.hp > 0) {
|
||||
switchOutTarget.leaveField(false);
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
|
||||
|
||||
// in double battles redirect potential moves off fled pokemon
|
||||
if (globalScene.currentBattle.double) {
|
||||
const allyPokemon = switchOutTarget.getAlly();
|
||||
if (globalScene.currentBattle.double && !Utils.isNullOrUndefined(allyPokemon)) {
|
||||
globalScene.redirectPokemonMoves(switchOutTarget, allyPokemon);
|
||||
}
|
||||
}
|
||||
|
||||
if (!switchOutTarget.getAlly()?.isActive(true)) {
|
||||
if (!allyPokemon?.isActive(true)) {
|
||||
globalScene.clearEnemyHeldItemModifiers();
|
||||
|
||||
if (switchOutTarget.hp) {
|
||||
|
@ -7030,7 +7031,7 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
|||
const firstTarget = globalScene.getField()[moveTargets[0]];
|
||||
if (globalScene.currentBattle.double && moveTargets.length === 1 && firstTarget.isFainted() && firstTarget !== target.getAlly()) {
|
||||
const ally = firstTarget.getAlly();
|
||||
if (ally.isActive()) { // ally exists, is not dead and can sponge the blast
|
||||
if (!Utils.isNullOrUndefined(ally) && ally.isActive()) { // ally exists, is not dead and can sponge the blast
|
||||
moveTargets = [ ally.getBattlerIndex() ];
|
||||
}
|
||||
}
|
||||
|
@ -7404,10 +7405,11 @@ export class AbilityCopyAttr extends MoveEffectAttr {
|
|||
globalScene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
|
||||
|
||||
user.setTempAbility(target.getAbility());
|
||||
const ally = user.getAlly();
|
||||
|
||||
if (this.copyToPartner && globalScene.currentBattle?.double && user.getAlly().hp) {
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(user.getAlly()), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
|
||||
user.getAlly().setTempAbility(target.getAbility());
|
||||
if (this.copyToPartner && globalScene.currentBattle?.double && !Utils.isNullOrUndefined(ally) && ally.hp) { // TODO is this the best way to check that the ally is active?
|
||||
globalScene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(ally), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
|
||||
ally.setTempAbility(target.getAbility());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -7415,9 +7417,10 @@ export class AbilityCopyAttr extends MoveEffectAttr {
|
|||
|
||||
getCondition(): MoveConditionFunc {
|
||||
return (user, target, move) => {
|
||||
const ally = user.getAlly();
|
||||
let ret = target.getAbility().isCopiable && user.getAbility().isReplaceable;
|
||||
if (this.copyToPartner && globalScene.currentBattle?.double) {
|
||||
ret = ret && (!user.getAlly().hp || user.getAlly().getAbility().isReplaceable);
|
||||
ret = ret && (!ally?.hp || ally?.getAbility().isReplaceable);
|
||||
} else {
|
||||
ret = ret && user.getAbility().id !== target.getAbility().id;
|
||||
}
|
||||
|
@ -8188,6 +8191,7 @@ export function getMoveTargets(user: Pokemon, move: Moves, replaceTarget?: MoveT
|
|||
|
||||
let set: Pokemon[] = [];
|
||||
let multiple = false;
|
||||
const ally: Pokemon | undefined = user.getAlly();
|
||||
|
||||
switch (moveTarget) {
|
||||
case MoveTarget.USER:
|
||||
|
@ -8198,7 +8202,7 @@ export function getMoveTargets(user: Pokemon, move: Moves, replaceTarget?: MoveT
|
|||
case MoveTarget.OTHER:
|
||||
case MoveTarget.ALL_NEAR_OTHERS:
|
||||
case MoveTarget.ALL_OTHERS:
|
||||
set = (opponents.concat([ user.getAlly() ]));
|
||||
set = !Utils.isNullOrUndefined(ally) ? (opponents.concat([ ally ])) : opponents;
|
||||
multiple = moveTarget === MoveTarget.ALL_NEAR_OTHERS || moveTarget === MoveTarget.ALL_OTHERS;
|
||||
break;
|
||||
case MoveTarget.NEAR_ENEMY:
|
||||
|
@ -8215,21 +8219,22 @@ export function getMoveTargets(user: Pokemon, move: Moves, replaceTarget?: MoveT
|
|||
return { targets: [ -1 as BattlerIndex ], multiple: false };
|
||||
case MoveTarget.NEAR_ALLY:
|
||||
case MoveTarget.ALLY:
|
||||
set = [ user.getAlly() ];
|
||||
set = !Utils.isNullOrUndefined(ally) ? [ ally ] : [];
|
||||
break;
|
||||
case MoveTarget.USER_OR_NEAR_ALLY:
|
||||
case MoveTarget.USER_AND_ALLIES:
|
||||
case MoveTarget.USER_SIDE:
|
||||
set = [ user, user.getAlly() ];
|
||||
set = !Utils.isNullOrUndefined(ally) ? [ user, ally ] : [ user ];
|
||||
multiple = moveTarget !== MoveTarget.USER_OR_NEAR_ALLY;
|
||||
break;
|
||||
case MoveTarget.ALL:
|
||||
case MoveTarget.BOTH_SIDES:
|
||||
set = [ user, user.getAlly() ].concat(opponents);
|
||||
set = (!Utils.isNullOrUndefined(ally) ? [ user, ally ] : [ user ]).concat(opponents);
|
||||
multiple = true;
|
||||
break;
|
||||
case MoveTarget.CURSE:
|
||||
set = user.getTypes(true).includes(PokemonType.GHOST) ? (opponents.concat([ user.getAlly() ])) : [ user ];
|
||||
const extraTargets = !Utils.isNullOrUndefined(ally) ? [ ally ] : [];
|
||||
set = user.getTypes(true).includes(PokemonType.GHOST) ? (opponents.concat(extraTargets)) : [ user ];
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -10123,7 +10128,7 @@ export function initMoves() {
|
|||
.attr(StatStageChangeAttr, [ Stat.DEF, Stat.SPDEF ], 1, false, { condition: (user, target, move) => !![ Abilities.PLUS, Abilities.MINUS ].find(a => target.hasAbility(a, false)) })
|
||||
.ignoresSubstitute()
|
||||
.target(MoveTarget.USER_AND_ALLIES)
|
||||
.condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p.hasAbility(a, false)))),
|
||||
.condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p?.hasAbility(a, false)))),
|
||||
new StatusMove(Moves.HAPPY_HOUR, PokemonType.NORMAL, -1, 30, -1, 0, 6) // No animation
|
||||
.attr(AddArenaTagAttr, ArenaTagType.HAPPY_HOUR, null, true)
|
||||
.target(MoveTarget.USER_SIDE),
|
||||
|
@ -10313,7 +10318,7 @@ export function initMoves() {
|
|||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], 1, false, { condition: (user, target, move) => !![ Abilities.PLUS, Abilities.MINUS ].find(a => target.hasAbility(a, false)) })
|
||||
.ignoresSubstitute()
|
||||
.target(MoveTarget.USER_AND_ALLIES)
|
||||
.condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p.hasAbility(a, false)))),
|
||||
.condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p?.hasAbility(a, false)))),
|
||||
new AttackMove(Moves.THROAT_CHOP, PokemonType.DARK, MoveCategory.PHYSICAL, 80, 100, 15, 100, 0, 7)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.THROAT_CHOPPED),
|
||||
new AttackMove(Moves.POLLEN_PUFF, PokemonType.BUG, MoveCategory.SPECIAL, 90, 100, 15, -1, 0, 7)
|
||||
|
|
|
@ -1447,7 +1447,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
}
|
||||
|
||||
const ally = this.getAlly();
|
||||
if (ally) {
|
||||
if (!Utils.isNullOrUndefined(ally)) {
|
||||
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, stat, statValue, simulated, this, move?.hasFlag(MoveFlags.IGNORE_ABILITIES) || ignoreAllyAbility);
|
||||
}
|
||||
|
||||
|
@ -3714,7 +3714,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
: i18next.t("arenaTag:yourTeam");
|
||||
}
|
||||
|
||||
getAlly(): Pokemon {
|
||||
getAlly(): Pokemon | undefined {
|
||||
return (
|
||||
this.isPlayer()
|
||||
? globalScene.getPlayerField()
|
||||
|
@ -3900,7 +3900,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
);
|
||||
|
||||
const ally = this.getAlly();
|
||||
if (ally) {
|
||||
if (!isNullOrUndefined(ally)) {
|
||||
const ignore = this.hasAbilityWithAttr(MoveAbilityBypassAbAttr) || sourceMove.hasFlag(MoveFlags.IGNORE_ABILITIES);
|
||||
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, Stat.ACC, accuracyMultiplier, false, this, ignore);
|
||||
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, Stat.EVA, evasionMultiplier, false, this, ignore);
|
||||
|
@ -4336,11 +4336,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
damage,
|
||||
);
|
||||
|
||||
const ally = this.getAlly();
|
||||
/** Additionally apply friend guard damage reduction if ally has it. */
|
||||
if (globalScene.currentBattle.double && this.getAlly()?.isActive(true)) {
|
||||
if (globalScene.currentBattle.double && !isNullOrUndefined(ally) && ally.isActive(true)) {
|
||||
applyPreDefendAbAttrs(
|
||||
AlliedFieldDamageReductionAbAttr,
|
||||
this.getAlly(),
|
||||
ally,
|
||||
source,
|
||||
move,
|
||||
cancelled,
|
||||
|
|
|
@ -39,7 +39,7 @@ export class EnemyCommandPhase extends FieldPhase {
|
|||
if (
|
||||
battle.double &&
|
||||
enemyPokemon.hasAbility(Abilities.COMMANDER) &&
|
||||
enemyPokemon.getAlly().getTag(BattlerTagType.COMMANDED)
|
||||
enemyPokemon.getAlly()?.getTag(BattlerTagType.COMMANDED)
|
||||
) {
|
||||
this.skipTurn = true;
|
||||
}
|
||||
|
|
|
@ -209,8 +209,8 @@ export class FaintPhase extends PokemonPhase {
|
|||
}
|
||||
|
||||
// in double battles redirect potential moves off fainted pokemon
|
||||
if (globalScene.currentBattle.double) {
|
||||
const allyPokemon = pokemon.getAlly();
|
||||
const allyPokemon = pokemon.getAlly();
|
||||
if (globalScene.currentBattle.double && !isNullOrUndefined(allyPokemon)) {
|
||||
globalScene.redirectPokemonMoves(pokemon, allyPokemon);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,8 +42,12 @@ export class RevivalBlessingPhase extends BattlePhase {
|
|||
true,
|
||||
);
|
||||
|
||||
if (globalScene.currentBattle.double && globalScene.getPlayerParty().length > 1) {
|
||||
const allyPokemon = this.user.getAlly();
|
||||
const allyPokemon = this.user.getAlly();
|
||||
if (
|
||||
globalScene.currentBattle.double &&
|
||||
globalScene.getPlayerParty().length > 1 &&
|
||||
!Utils.isNullOrUndefined(allyPokemon)
|
||||
) {
|
||||
if (slotIndex <= 1) {
|
||||
// Revived ally pokemon
|
||||
globalScene.unshiftPhase(
|
||||
|
|
|
@ -17,7 +17,7 @@ import type Pokemon from "#app/field/pokemon";
|
|||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { ResetNegativeStatStageModifier } from "#app/modifier/modifier";
|
||||
import { handleTutorial, Tutorial } from "#app/tutorial";
|
||||
import { NumberHolder, BooleanHolder } from "#app/utils";
|
||||
import { NumberHolder, BooleanHolder, isNullOrUndefined } from "#app/utils";
|
||||
import i18next from "i18next";
|
||||
import { PokemonPhase } from "./pokemon-phase";
|
||||
import { Stat, type BattleStat, getStatKey, getStatStageChangeDescriptionKey } from "#enums/stat";
|
||||
|
@ -161,7 +161,7 @@ export class StatStageChangePhase extends PokemonPhase {
|
|||
pokemon,
|
||||
);
|
||||
const ally = pokemon.getAlly();
|
||||
if (ally) {
|
||||
if (!isNullOrUndefined(ally)) {
|
||||
applyPreStatStageChangeAbAttrs(
|
||||
ConditionalUserFieldProtectStatAbAttr,
|
||||
ally,
|
||||
|
|
Loading…
Reference in New Issue