Properly implement Soul-Heart, Fix Opponent Stage boosts on faints (#53)

* Properly implement Soul-Heart, Fix Opponent Stage boosts on faints

add phases.ts

remove unused import

spacing

fix

* simplify alivePlayField
pull/57/head
LaukkaE 2024-04-08 00:20:24 +03:00 committed by GitHub
parent d41101083e
commit fb9f5dad11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 11 deletions

View File

@ -795,6 +795,33 @@ class PostVictoryStatChangeAbAttr extends PostVictoryAbAttr {
}
}
export class PostKnockOutAbAttr extends AbAttr {
applyPostKnockOut(pokemon: Pokemon, args: any[]): boolean | Promise<boolean> {
return false;
}
}
export class PostKnockOutStatChangeAbAttr extends PostKnockOutAbAttr {
private stat: BattleStat | ((p: Pokemon) => BattleStat);
private levels: integer;
constructor(stat: BattleStat | ((p: Pokemon) => BattleStat), levels: integer) {
super();
this.stat = stat;
this.levels = levels;
}
applyPostKnockOut(pokemon: Pokemon, args: any[]): boolean | Promise<boolean> {
const stat = typeof this.stat === 'function'
? this.stat(pokemon)
: this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
return true;
}
}
export class IgnoreOpponentStatChangesAbAttr extends AbAttr {
constructor() {
super(false);
@ -1696,6 +1723,11 @@ export function applyPostAttackAbAttrs(attrType: { new(...args: any[]): PostAtta
return applyAbAttrsInternal<PostAttackAbAttr>(attrType, pokemon, attr => attr.applyPostAttack(pokemon, defender, move, hitResult, args), args);
}
export function applyPostKnockOutAbAttrs(attrType: { new(...args: any[]): PostKnockOutAbAttr },
pokemon: Pokemon, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PostKnockOutAbAttr>(attrType, pokemon, attr => attr.applyPostKnockOut(pokemon, args), args);
}
export function applyPostVictoryAbAttrs(attrType: { new(...args: any[]): PostVictoryAbAttr },
pokemon: Pokemon, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PostVictoryAbAttr>(attrType, pokemon, attr => attr.applyPostVictory(pokemon, args), args);
@ -2571,8 +2603,8 @@ export function initAbilities() {
.ignorable(),
new Ability(Abilities.DAZZLING, "Dazzling (N)", "Surprises the opposing Pokémon, making it unable to attack using priority moves.", 7)
.ignorable(),
new Ability(Abilities.SOUL_HEART, "Soul-Heart (P)", "Boosts its Sp. Atk stat every time a Pokémon faints.", 7)
.attr(PostVictoryStatChangeAbAttr, BattleStat.SPATK, 1),
new Ability(Abilities.SOUL_HEART, "Soul-Heart", "Boosts its Sp. Atk stat every time a Pokémon faints.", 7)
.attr(PostKnockOutStatChangeAbAttr, BattleStat.SPATK, 1),
new Ability(Abilities.TANGLING_HAIR, "Tangling Hair", "Contact with the Pokémon lowers the attacker's Speed stat.", 7)
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), BattleStat.SPD, -1, false),
new Ability(Abilities.RECEIVER, "Receiver (N)", "The Pokémon copies the Ability of a defeated ally.", 7),

View File

@ -30,7 +30,7 @@ import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, get
import { TempBattleStat } from "./data/temp-battle-stat";
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
import { ArenaTagType } from "./data/enums/arena-tag-type";
import { Abilities, CheckTrappedAbAttr, MoveAbilityBypassAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr } from "./data/ability";
import { Abilities, CheckTrappedAbAttr, MoveAbilityBypassAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr } from "./data/ability";
import { Unlockables, getUnlockableName } from "./system/unlockables";
import { getBiomeKey } from "./field/arena";
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
@ -2869,6 +2869,14 @@ export class FaintPhase extends PokemonPhase {
this.scene.queueMessage(getPokemonMessage(pokemon, ' fainted!'), null, true);
const alivePlayField = this.scene.getField(true);
alivePlayField.forEach(p => applyPostKnockOutAbAttrs(PostKnockOutAbAttr, p));
if (pokemon.turnData?.attacksReceived?.length) {
const defeatSource = this.scene.getPokemonById(pokemon.turnData.attacksReceived[0].sourceId);
if (defeatSource?.isOnField())
applyPostVictoryAbAttrs(PostVictoryAbAttr, defeatSource);
}
if (this.player) {
const nonFaintedPartyMembers = this.scene.getParty().filter(p => !p.isFainted());
const nonFaintedPartyMemberCount = nonFaintedPartyMembers.length;
@ -3032,14 +3040,7 @@ export class VictoryPhase extends PokemonPhase {
}
}
}
const defeatedPokemon = this.getPokemon();
if (defeatedPokemon.turnData?.attacksReceived?.length) {
const defeatSource = this.scene.getPokemonById(defeatedPokemon.turnData.attacksReceived[0].sourceId);
if (defeatSource?.isOnField())
applyPostVictoryAbAttrs(PostVictoryAbAttr, defeatSource);
}
if (!this.scene.getEnemyParty().find(p => this.scene.currentBattle.battleType ? !p?.isFainted(true) : p.isOnField())) {
this.scene.pushPhase(new BattleEndPhase(this.scene));
if (this.scene.currentBattle.battleType === BattleType.TRAINER)