mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-21 06:49:35 +02:00
added source to damageAndUpdate and applyPostDamageAbAttrs, added Parental Bond logic + test, put applyPostDamageAbAttrs back in damageAndUpdate
This commit is contained in:
parent
38b7e6be68
commit
2d52b05b31
@ -4979,7 +4979,7 @@ function calculateShellBellRecovery(pokemon: Pokemon): number {
|
|||||||
* @extends AbAttr
|
* @extends AbAttr
|
||||||
*/
|
*/
|
||||||
export class PostDamageAbAttr extends AbAttr {
|
export class PostDamageAbAttr extends AbAttr {
|
||||||
public applyPostDamage(pokemon: Pokemon, damage: number, passive: boolean, simulated: boolean, args: any[]): boolean | Promise<boolean> {
|
public applyPostDamage(pokemon: Pokemon, damage: number, passive: boolean, simulated: boolean, args: any[], source?: Pokemon): boolean | Promise<boolean> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5011,9 +5011,10 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
|
|||||||
* @param passive N/A
|
* @param passive N/A
|
||||||
* @param simulated Whether the ability is being simulated.
|
* @param simulated Whether the ability is being simulated.
|
||||||
* @param args N/A
|
* @param args N/A
|
||||||
|
* @param source The Pokemon that dealt damage
|
||||||
* @returns `true` if the switch-out logic was successfully applied
|
* @returns `true` if the switch-out logic was successfully applied
|
||||||
*/
|
*/
|
||||||
public override applyPostDamage(pokemon: Pokemon, damage: number, passive: boolean, simulated: boolean, args: any[]): boolean | Promise<boolean> {
|
public override applyPostDamage(pokemon: Pokemon, damage: number, passive: boolean, simulated: boolean, args: any[], source?: Pokemon): boolean | Promise<boolean> {
|
||||||
const moveHistory = pokemon.getMoveHistory();
|
const moveHistory = pokemon.getMoveHistory();
|
||||||
// Will not activate when the Pokémon's HP is lowered by cutting its own HP
|
// Will not activate when the Pokémon's HP is lowered by cutting its own HP
|
||||||
const fordbiddenAttackingMoves = [ Moves.BELLY_DRUM, Moves.SUBSTITUTE, Moves.CURSE, Moves.PAIN_SPLIT ];
|
const fordbiddenAttackingMoves = [ Moves.BELLY_DRUM, Moves.SUBSTITUTE, Moves.CURSE, Moves.PAIN_SPLIT ];
|
||||||
@ -5027,22 +5028,21 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
|
|||||||
|
|
||||||
// Dragon Tail and Circle Throw switch out Pokémon before the Ability activates.
|
// Dragon Tail and Circle Throw switch out Pokémon before the Ability activates.
|
||||||
const fordbiddenDefendingMoves = [ Moves.DRAGON_TAIL, Moves.CIRCLE_THROW ];
|
const fordbiddenDefendingMoves = [ Moves.DRAGON_TAIL, Moves.CIRCLE_THROW ];
|
||||||
const getField = [ ...pokemon.getOpponents(), ...pokemon.getAlliedField() ];
|
if (source) {
|
||||||
for (const opponent of getField) {
|
const enemyMoveHistory = source.getMoveHistory();
|
||||||
const enemyMoveHistory = opponent.getMoveHistory();
|
|
||||||
if (enemyMoveHistory.length > 0) {
|
if (enemyMoveHistory.length > 0) {
|
||||||
const enemyLastMoveUsed = enemyMoveHistory[enemyMoveHistory.length - 1];
|
const enemyLastMoveUsed = enemyMoveHistory[enemyMoveHistory.length - 1];
|
||||||
if (fordbiddenDefendingMoves.includes(enemyLastMoveUsed.move) || enemyLastMoveUsed.move === Moves.SKY_DROP && enemyLastMoveUsed.result === MoveResult.OTHER) {
|
if (fordbiddenDefendingMoves.includes(enemyLastMoveUsed.move) || enemyLastMoveUsed.move === Moves.SKY_DROP && enemyLastMoveUsed.result === MoveResult.OTHER) {
|
||||||
return false;
|
return false;
|
||||||
// Will not activate if the Pokémon's HP falls below half by a move affected by Sheer Force.
|
// Will not activate if the Pokémon's HP falls below half by a move affected by Sheer Force.
|
||||||
} else if (allMoves[enemyLastMoveUsed.move].chance >= 0 && opponent.hasAbility(Abilities.SHEER_FORCE)) {
|
} else if (allMoves[enemyLastMoveUsed.move].chance >= 0 && source.hasAbility(Abilities.SHEER_FORCE)) {
|
||||||
return false;
|
return false;
|
||||||
// Activate only after the last hit of multistrike moves
|
// Activate only after the last hit of multistrike moves
|
||||||
} else if (opponent.turnData.hitsLeft > 1) {
|
} else if (source.turnData.hitsLeft > 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const multiHitModifier = opponent.getHeldItems().find(m => m instanceof PokemonMultiHitModifier);
|
const multiHitModifier = source.getHeldItems().find(m => m instanceof PokemonMultiHitModifier);
|
||||||
if (allMoves[enemyLastMoveUsed.move].hasAttr(MultiHitAttr) || multiHitModifier) {
|
if (allMoves[enemyLastMoveUsed.move].hasAttr(MultiHitAttr) || multiHitModifier || source.hasAbilityWithAttr(AddSecondStrikeAbAttr)) {
|
||||||
damage = pokemon.turnData.damageTaken;
|
damage = pokemon.turnData.damageTaken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5105,8 +5105,8 @@ export function applyPostSetStatusAbAttrs(attrType: Constructor<PostSetStatusAbA
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function applyPostDamageAbAttrs(attrType: Constructor<PostDamageAbAttr>,
|
export function applyPostDamageAbAttrs(attrType: Constructor<PostDamageAbAttr>,
|
||||||
pokemon: Pokemon, damage: number, passive: boolean, simulated: boolean = false, args: any[]): Promise<void> {
|
pokemon: Pokemon, damage: number, passive: boolean, simulated: boolean = false, args: any[], source?: Pokemon): Promise<void> {
|
||||||
return applyAbAttrsInternal<PostDamageAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostDamage(pokemon, damage, passive, simulated, args), args);
|
return applyAbAttrsInternal<PostDamageAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostDamage(pokemon, damage, passive, simulated, args, source), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2791,7 +2791,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* We explicitly require to ignore the faint phase here, as we want to show the messages
|
* We explicitly require to ignore the faint phase here, as we want to show the messages
|
||||||
* about the critical hit and the super effective/not very effective messages before the faint phase.
|
* about the critical hit and the super effective/not very effective messages before the faint phase.
|
||||||
*/
|
*/
|
||||||
const damage = this.damageAndUpdate(isBlockedBySubstitute ? 0 : dmg, result as DamageResult, isCritical, isOneHitKo, isOneHitKo, true);
|
const damage = this.damageAndUpdate(isBlockedBySubstitute ? 0 : dmg, result as DamageResult, isCritical, isOneHitKo, isOneHitKo, true, source);
|
||||||
|
|
||||||
if (damage > 0) {
|
if (damage > 0) {
|
||||||
if (source.isPlayer()) {
|
if (source.isPlayer()) {
|
||||||
@ -2805,11 +2805,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.turnData.damageTaken += damage;
|
this.turnData.damageTaken += damage;
|
||||||
this.battleData.hitCount++;
|
this.battleData.hitCount++;
|
||||||
|
|
||||||
// Multi-Lens check for Wimp Out/Emergency Exit
|
// Multi-Lens and Parental Bond check for Wimp Out/Emergency Exit
|
||||||
if (this.hasAbilityWithAttr(PostDamageForceSwitchAbAttr)) {
|
if (this.hasAbilityWithAttr(PostDamageForceSwitchAbAttr)) {
|
||||||
const multiHitModifier = source.getHeldItems().find(m => m instanceof PokemonMultiHitModifier);
|
const multiHitModifier = source.getHeldItems().find(m => m instanceof PokemonMultiHitModifier);
|
||||||
if (multiHitModifier) {
|
if (multiHitModifier || source.hasAbilityWithAttr(AddSecondStrikeAbAttr)) {
|
||||||
applyPostDamageAbAttrs(PostDamageAbAttr, this, damage, this.hasPassive(), false, []);
|
applyPostDamageAbAttrs(PostDamageAbAttr, this, damage, this.hasPassive(), false, [], source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2900,8 +2900,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.destroySubstitute();
|
this.destroySubstitute();
|
||||||
this.resetSummonData();
|
this.resetSummonData();
|
||||||
}
|
}
|
||||||
applyPostDamageAbAttrs(PostDamageAbAttr, this, damage, this.hasPassive(), false, []);
|
|
||||||
|
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2915,12 +2913,17 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @param ignoreFaintPhase boolean to ignore adding a FaintPhase, passsed to damage()
|
* @param ignoreFaintPhase boolean to ignore adding a FaintPhase, passsed to damage()
|
||||||
* @returns integer of damage done
|
* @returns integer of damage done
|
||||||
*/
|
*/
|
||||||
damageAndUpdate(damage: integer, result?: DamageResult, critical: boolean = false, ignoreSegments: boolean = false, preventEndure: boolean = false, ignoreFaintPhase: boolean = false): integer {
|
damageAndUpdate(damage: integer, result?: DamageResult, critical: boolean = false, ignoreSegments: boolean = false, preventEndure: boolean = false, ignoreFaintPhase: boolean = false, source?: Pokemon): integer {
|
||||||
const damagePhase = new DamagePhase(this.scene, this.getBattlerIndex(), damage, result as DamageResult, critical);
|
const damagePhase = new DamagePhase(this.scene, this.getBattlerIndex(), damage, result as DamageResult, critical);
|
||||||
this.scene.unshiftPhase(damagePhase);
|
this.scene.unshiftPhase(damagePhase);
|
||||||
damage = this.damage(damage, ignoreSegments, preventEndure, ignoreFaintPhase);
|
damage = this.damage(damage, ignoreSegments, preventEndure, ignoreFaintPhase);
|
||||||
// Damage amount may have changed, but needed to be queued before calling damage function
|
// Damage amount may have changed, but needed to be queued before calling damage function
|
||||||
damagePhase.updateAmount(damage);
|
damagePhase.updateAmount(damage);
|
||||||
|
if (source) {
|
||||||
|
applyPostDamageAbAttrs(PostDamageAbAttr, this, damage, this.hasPassive(), false, [], source);
|
||||||
|
} else {
|
||||||
|
applyPostDamageAbAttrs(PostDamageAbAttr, this, damage, this.hasPassive(), false, []);
|
||||||
|
}
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { applyAbAttrs, BlockNonDirectDamageAbAttr, BlockStatusDamageAbAttr, ReduceBurnDamageAbAttr } from "#app/data/ability";
|
import { applyAbAttrs, applyPostDamageAbAttrs, BlockNonDirectDamageAbAttr, BlockStatusDamageAbAttr, PostDamageAbAttr, ReduceBurnDamageAbAttr } from "#app/data/ability";
|
||||||
import { CommonBattleAnim, CommonAnim } from "#app/data/battle-anims";
|
import { CommonBattleAnim, CommonAnim } from "#app/data/battle-anims";
|
||||||
import { getStatusEffectActivationText } from "#app/data/status-effect";
|
import { getStatusEffectActivationText } from "#app/data/status-effect";
|
||||||
import { BattleSpec } from "#app/enums/battle-spec";
|
import { BattleSpec } from "#app/enums/battle-spec";
|
||||||
@ -41,6 +41,7 @@ export class PostTurnStatusEffectPhase extends PokemonPhase {
|
|||||||
// Set preventEndure flag to avoid pokemon surviving thanks to focus band, sturdy, endure ...
|
// Set preventEndure flag to avoid pokemon surviving thanks to focus band, sturdy, endure ...
|
||||||
this.scene.damageNumberHandler.add(this.getPokemon(), pokemon.damage(damage.value, false, true));
|
this.scene.damageNumberHandler.add(this.getPokemon(), pokemon.damage(damage.value, false, true));
|
||||||
pokemon.updateInfo();
|
pokemon.updateInfo();
|
||||||
|
applyPostDamageAbAttrs(PostDamageAbAttr, pokemon, damage.value, pokemon.hasPassive(), false, []);
|
||||||
}
|
}
|
||||||
new CommonBattleAnim(CommonAnim.POISON + (pokemon.status.effect - 1), pokemon).play(this.scene, false, () => this.end());
|
new CommonBattleAnim(CommonAnim.POISON + (pokemon.status.effect - 1), pokemon).play(this.scene, false, () => this.end());
|
||||||
} else {
|
} else {
|
||||||
|
@ -568,6 +568,26 @@ describe("Abilities - Wimp Out", () => {
|
|||||||
expect(enemyPokemon.turnData.hitCount).toBe(2);
|
expect(enemyPokemon.turnData.hitCount).toBe(2);
|
||||||
confirmSwitch();
|
confirmSwitch();
|
||||||
});
|
});
|
||||||
|
it("triggers after last hit of Parental Bond", async () => {
|
||||||
|
game.override
|
||||||
|
.enemyMoveset(Moves.TACKLE)
|
||||||
|
.enemyAbility(Abilities.PARENTAL_BOND);
|
||||||
|
await game.classicMode.startBattle([
|
||||||
|
Species.WIMPOD,
|
||||||
|
Species.TYRUNT
|
||||||
|
]);
|
||||||
|
|
||||||
|
game.scene.getPlayerPokemon()!.hp *= 0.51;
|
||||||
|
|
||||||
|
game.move.select(Moves.ENDURE);
|
||||||
|
game.doSelectPartyPokemon(1);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
|
|
||||||
|
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||||
|
expect(enemyPokemon.turnData.hitsLeft).toBe(0);
|
||||||
|
expect(enemyPokemon.turnData.hitCount).toBe(2);
|
||||||
|
confirmSwitch();
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: This interaction is not implemented yet
|
// TODO: This interaction is not implemented yet
|
||||||
it.todo("Wimp Out will not activate if the Pokémon's HP falls below half due to hurting itself in confusion", async () => {
|
it.todo("Wimp Out will not activate if the Pokémon's HP falls below half due to hurting itself in confusion", async () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user