Updated ForceSwitchOutAttr

Should fix issue #83
This commit is contained in:
EmoUsedHM01 2024-04-11 19:29:08 +01:00 committed by GitHub
parent 2c38849aa1
commit f0c2e62883
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -12,7 +12,7 @@ import * as Utils from "../utils";
import { WeatherType } from "./weather"; import { WeatherType } from "./weather";
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
import { ArenaTagType } from "./enums/arena-tag-type"; import { ArenaTagType } from "./enums/arena-tag-type";
import { ProtectAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr } from "./ability"; import { ProtectAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPreSwitchOutAbAttrs, PreSwitchOutAbAttr, PostDefendContactApplyStatusEffectAbAttr } from "./ability";
import { Abilities } from "./enums/abilities"; import { Abilities } from "./enums/abilities";
import { PokemonHeldItemModifier } from "../modifier/modifier"; import { PokemonHeldItemModifier } from "../modifier/modifier";
import { BattlerIndex } from "../battle"; import { BattlerIndex } from "../battle";
@ -2469,88 +2469,112 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
constructor(user?: boolean, batonPass?: boolean) { constructor(user?: boolean, batonPass?: boolean) {
super(false, MoveEffectTrigger.HIT, true); super(false, MoveEffectTrigger.HIT, true);
this.user = !!user; this.user = !!user;
this.batonPass = !!batonPass; this.batonPass = !!batonPass;
} }
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
return new Promise(resolve => { return new Promise(resolve => {
if (move.category !== MoveCategory.STATUS && !this.getSwitchOutCondition()(user, target, move)) // Check if the move category is not STATUS or if the switch out condition is not met
return resolve(false); if (move.category !== MoveCategory.STATUS && !this.getSwitchOutCondition()(user, target, move)) {
// Apply effects that need to be executed before switch out
// For example, applying poison or any other status condition
this.applyEffectsBeforeSwitchOut(user, target, move);
// Resolve the Promise after the switch out is complete
return resolve(false);
}
// Move the switch out logic inside the conditional block
// This ensures that the switch out only happens when the conditions are met
const switchOutTarget = this.user ? user : target; const switchOutTarget = this.user ? user : target;
if (switchOutTarget instanceof PlayerPokemon) { if (switchOutTarget instanceof PlayerPokemon) {
if (switchOutTarget.hp) { // Switch out logic for PlayerPokemon
applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, switchOutTarget); // This includes applying any necessary effects before switching out
(switchOutTarget as PlayerPokemon).switchOut(this.batonPass, true).then(() => resolve(true)); if (switchOutTarget.hp) {
} applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, switchOutTarget);
else (switchOutTarget as PlayerPokemon).switchOut(this.batonPass, true).then(() => resolve(true));
resolve(false); }
return; else {
} else if (user.scene.currentBattle.battleType) { resolve(false);
switchOutTarget.resetTurnData(); }
switchOutTarget.resetSummonData(); return;
switchOutTarget.hideInfo(); }
switchOutTarget.setVisible(false); else if (user.scene.currentBattle.battleType) {
switchOutTarget.scene.field.remove(switchOutTarget); // Switch out logic for the battle type
user.scene.triggerPokemonFormChange(switchOutTarget, SpeciesFormChangeActiveTrigger, true); switchOutTarget.resetTurnData();
switchOutTarget.resetSummonData();
switchOutTarget.hideInfo();
switchOutTarget.setVisible(false);
switchOutTarget.scene.field.remove(switchOutTarget);
user.scene.triggerPokemonFormChange(switchOutTarget, SpeciesFormChangeActiveTrigger, true);
if (switchOutTarget.hp) if (switchOutTarget.hp)
user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, switchOutTarget.getFieldIndex(), user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot), false, this.batonPass, false)); user.scene.unshiftPhase(new SwitchSummonPhase(user.scene, switchOutTarget.getFieldIndex(), user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot), false, this.batonPass, false));
} else { }
switchOutTarget.setVisible(false); else {
// Switch out logic for everything else
switchOutTarget.setVisible(false);
if (switchOutTarget.hp) { if (switchOutTarget.hp) {
switchOutTarget.hideInfo().then(() => switchOutTarget.destroy()); switchOutTarget.hideInfo().then(() => switchOutTarget.destroy());
switchOutTarget.scene.field.remove(switchOutTarget); switchOutTarget.scene.field.remove(switchOutTarget);
user.scene.queueMessage(getPokemonMessage(switchOutTarget, ' fled!'), null, true, 500); user.scene.queueMessage(getPokemonMessage(switchOutTarget, ' fled!'), null, true, 500);
} }
if (!switchOutTarget.getAlly()?.isActive(true)) { if (!switchOutTarget.getAlly()?.isActive(true)) {
user.scene.clearEnemyHeldItemModifiers(); user.scene.clearEnemyHeldItemModifiers();
if (switchOutTarget.hp) { if (switchOutTarget.hp) {
user.scene.pushPhase(new BattleEndPhase(user.scene)); user.scene.pushPhase(new BattleEndPhase(user.scene));
user.scene.pushPhase(new NewBattlePhase(user.scene)); user.scene.pushPhase(new NewBattlePhase(user.scene));
} }
}
} }
}
resolve(true); resolve(true);
}); });
} }
// Function to apply any effects to the user/target before switching out
applyEffectsBeforeSwitchOut(user: Pokemon, target: Pokemon, move: Move) {
// Create an instance of PostDefendContactApplyStatusEffectAbAttr
const postDefendAttr = new PostDefendContactApplyStatusEffectAbAttr();
// Apply the effects based on the logic in PostDefendContactApplyStatusEffectAbAttr
postDefendAttr.applyPostDefend(user, target, move);
}
getCondition(): MoveConditionFunc { getCondition(): MoveConditionFunc {
return (user, target, move) => move.category !== MoveCategory.STATUS || this.getSwitchOutCondition()(user, target, move); return (user, target, move) => move.category !== MoveCategory.STATUS || this.getSwitchOutCondition()(user, target, move);
} }
getSwitchOutCondition(): MoveConditionFunc { getSwitchOutCondition(): MoveConditionFunc {
return (user, target, move) => { return (user, target, move) => {
const switchOutTarget = (this.user ? user : target); const switchOutTarget = (this.user ? user : target);
const player = switchOutTarget instanceof PlayerPokemon; const player = switchOutTarget instanceof PlayerPokemon;
if (!player && !user.scene.currentBattle.battleType) { if (!player && !user.scene.currentBattle.battleType) {
if (this.batonPass) if (this.batonPass)
return false; return false;
// Don't allow wild opponents to flee on the boss stage since it can ruin a run early on // Don't allow wild opponents to flee on the boss stage since it can ruin a run early on
if (!(user.scene.currentBattle.waveIndex % 10)) if (!(user.scene.currentBattle.waveIndex % 10))
return false; return false;
} }
const party = player ? user.scene.getParty() : user.scene.getEnemyParty(); const party = player ? user.scene.getParty() : user.scene.getEnemyParty();
return (!player && !user.scene.currentBattle.battleType) || party.filter(p => !p.isFainted() && (player || (p as EnemyPokemon).trainerSlot === (switchOutTarget as EnemyPokemon).trainerSlot)).length > user.scene.currentBattle.getBattlerCount(); return (!player && !user.scene.currentBattle.battleType) || party.filter(p => !p.isFainted() && (player || (p as EnemyPokemon).trainerSlot === (switchOutTarget as EnemyPokemon).trainerSlot)).length > user.scene.currentBattle.getBattlerCount();
}; };
} }
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
if (!user.scene.getEnemyParty().find(p => p.isActive() && !p.isOnField())) if (!user.scene.getEnemyParty().find(p => p.isActive() && !p.isOnField()))
return -20; return -20;
let ret = this.user ? Math.floor((1 - user.getHpRatio()) * 20) : super.getUserBenefitScore(user, target, move); let ret = this.user ? Math.floor((1 - user.getHpRatio()) * 20) : super.getUserBenefitScore(user, target, move);
if (this.user && this.batonPass) { if (this.user && this.batonPass) {
const battleStatTotal = user.summonData.battleStats.reduce((bs: integer, total: integer) => total += bs, 0); const battleStatTotal = user.summonData.battleStats.reduce((bs: integer, total: integer) => total += bs, 0);
ret = ret / 2 + (Phaser.Tweens.Builders.GetEaseFunction('Sine.easeOut')(Math.min(Math.abs(battleStatTotal), 10) / 10) * (battleStatTotal >= 0 ? 10 : -10)); ret = ret / 2 + (Phaser.Tweens.Builders.GetEaseFunction('Sine.easeOut')(Math.min(Math.abs(battleStatTotal), 10) / 10) * (battleStatTotal >= 0 ? 10 : -10));
} }
return ret; return ret;
} }
} }