Implement Aftermath (#71)
* Implement Aftermath * Clean up unused imports & Consistency * Minor changes --------- Co-authored-by: Flashfyre <flashfireex@gmail.com>pull/73/head
parent
8ec7333b1e
commit
3e5a0d5c9c
|
@ -1558,6 +1558,35 @@ export class PostBattleLootAbAttr extends PostBattleAbAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PostFaintAbAttr extends AbAttr {
|
||||||
|
applyPostFaint(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
|
||||||
|
private damageRatio: integer;
|
||||||
|
|
||||||
|
constructor(damageRatio: integer) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.damageRatio = damageRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyPostFaint(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||||
|
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
|
||||||
|
attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTriggerMessage(pokemon: Pokemon, ...args: any[]): string {
|
||||||
|
return getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name} hurt\nits attacker!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class RedirectMoveAbAttr extends AbAttr {
|
export class RedirectMoveAbAttr extends AbAttr {
|
||||||
apply(pokemon: Pokemon, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
apply(pokemon: Pokemon, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
if (this.canRedirect(args[0] as Moves)) {
|
if (this.canRedirect(args[0] as Moves)) {
|
||||||
|
@ -1860,6 +1889,11 @@ export function applyPostBattleAbAttrs(attrType: { new(...args: any[]): PostBatt
|
||||||
return applyAbAttrsInternal<PostBattleAbAttr>(attrType, pokemon, attr => attr.applyPostBattle(pokemon, args), args);
|
return applyAbAttrsInternal<PostBattleAbAttr>(attrType, pokemon, attr => attr.applyPostBattle(pokemon, args), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function applyPostFaintAbAttrs(attrType: { new(...args: any[]): PostFaintAbAttr },
|
||||||
|
pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, ...args: any[]): Promise<void> {
|
||||||
|
return applyAbAttrsInternal<PostFaintAbAttr>(attrType, pokemon, attr => attr.applyPostFaint(pokemon, attacker, move, hitResult, args), args);
|
||||||
|
}
|
||||||
|
|
||||||
function canApplyAttr(pokemon: Pokemon, attr: AbAttr): boolean {
|
function canApplyAttr(pokemon: Pokemon, attr: AbAttr): boolean {
|
||||||
const condition = attr.getCondition();
|
const condition = attr.getCondition();
|
||||||
return !condition || condition(pokemon);
|
return !condition || condition(pokemon);
|
||||||
|
@ -2250,7 +2284,8 @@ export function initAbilities() {
|
||||||
.attr(ArenaTrapAbAttr),
|
.attr(ArenaTrapAbAttr),
|
||||||
new Ability(Abilities.ROUGH_SKIN, "Rough Skin", "This Pokémon inflicts damage with its rough skin to the attacker on contact.", 3)
|
new Ability(Abilities.ROUGH_SKIN, "Rough Skin", "This Pokémon inflicts damage with its rough skin to the attacker on contact.", 3)
|
||||||
.attr(PostDefendContactDamageAbAttr, 8)
|
.attr(PostDefendContactDamageAbAttr, 8)
|
||||||
.ignorable(),
|
.ignorable()
|
||||||
|
.passive(),
|
||||||
new Ability(Abilities.WONDER_GUARD, "Wonder Guard", "Its mysterious power only lets supereffective moves hit the Pokémon.", 3)
|
new Ability(Abilities.WONDER_GUARD, "Wonder Guard", "Its mysterious power only lets supereffective moves hit the Pokémon.", 3)
|
||||||
.attr(NonSuperEffectiveImmunityAbAttr)
|
.attr(NonSuperEffectiveImmunityAbAttr)
|
||||||
.attr(ProtectAbilityAbAttr)
|
.attr(ProtectAbilityAbAttr)
|
||||||
|
@ -2439,7 +2474,9 @@ export function initAbilities() {
|
||||||
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' breaks the mold!'))
|
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' breaks the mold!'))
|
||||||
.attr(MoveAbilityBypassAbAttr),
|
.attr(MoveAbilityBypassAbAttr),
|
||||||
new Ability(Abilities.SUPER_LUCK, "Super Luck (N)", "The Pokémon is so lucky that the critical-hit ratios of its moves are boosted.", 4),
|
new Ability(Abilities.SUPER_LUCK, "Super Luck (N)", "The Pokémon is so lucky that the critical-hit ratios of its moves are boosted.", 4),
|
||||||
new Ability(Abilities.AFTERMATH, "Aftermath (N)", "Damages the attacker if it contacts the Pokémon with a finishing hit.", 4),
|
new Ability(Abilities.AFTERMATH, "Aftermath", "Damages the attacker if it contacts the Pokémon with a finishing hit.", 4)
|
||||||
|
.attr(PostFaintContactDamageAbAttr,4)
|
||||||
|
.passive(),
|
||||||
new Ability(Abilities.ANTICIPATION, "Anticipation (N)", "The Pokémon can sense an opposing Pokémon's dangerous moves.", 4),
|
new Ability(Abilities.ANTICIPATION, "Anticipation (N)", "The Pokémon can sense an opposing Pokémon's dangerous moves.", 4),
|
||||||
new Ability(Abilities.FOREWARN, "Forewarn (N)", "When it enters a battle, the Pokémon can tell one of the moves an opposing Pokémon has.", 4),
|
new Ability(Abilities.FOREWARN, "Forewarn (N)", "When it enters a battle, the Pokémon can tell one of the moves an opposing Pokémon has.", 4),
|
||||||
new Ability(Abilities.UNAWARE, "Unaware", "When attacking, the Pokémon ignores the target Pokémon's stat changes.", 4)
|
new Ability(Abilities.UNAWARE, "Unaware", "When attacking, the Pokémon ignores the target Pokémon's stat changes.", 4)
|
||||||
|
@ -2558,7 +2595,8 @@ export function initAbilities() {
|
||||||
.attr(BlockWeatherDamageAttr, WeatherType.SANDSTORM)
|
.attr(BlockWeatherDamageAttr, WeatherType.SANDSTORM)
|
||||||
.condition(getWeatherCondition(WeatherType.SANDSTORM)),
|
.condition(getWeatherCondition(WeatherType.SANDSTORM)),
|
||||||
new Ability(Abilities.IRON_BARBS, "Iron Barbs", "Inflicts damage on the attacker upon contact with iron barbs.", 5)
|
new Ability(Abilities.IRON_BARBS, "Iron Barbs", "Inflicts damage on the attacker upon contact with iron barbs.", 5)
|
||||||
.attr(PostDefendContactDamageAbAttr, 8),
|
.attr(PostDefendContactDamageAbAttr, 8)
|
||||||
|
.passive(),
|
||||||
new Ability(Abilities.ZEN_MODE, "Zen Mode", "Changes the Pokémon's shape when HP is half or less.", 5)
|
new Ability(Abilities.ZEN_MODE, "Zen Mode", "Changes the Pokémon's shape when HP is half or less.", 5)
|
||||||
.attr(PostBattleInitFormChangeAbAttr, p => p.getHpRatio() >= 0.5 ? 0 : 1)
|
.attr(PostBattleInitFormChangeAbAttr, p => p.getHpRatio() >= 0.5 ? 0 : 1)
|
||||||
.attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() >= 0.5 ? 0 : 1)
|
.attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() >= 0.5 ? 0 : 1)
|
||||||
|
|
|
@ -30,7 +30,7 @@ import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, get
|
||||||
import { TempBattleStat } from "./data/temp-battle-stat";
|
import { TempBattleStat } from "./data/temp-battle-stat";
|
||||||
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
|
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
|
||||||
import { ArenaTagType } from "./data/enums/arena-tag-type";
|
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, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr } 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, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr } from "./data/ability";
|
||||||
import { Unlockables, getUnlockableName } from "./system/unlockables";
|
import { Unlockables, getUnlockableName } from "./system/unlockables";
|
||||||
import { getBiomeKey } from "./field/arena";
|
import { getBiomeKey } from "./field/arena";
|
||||||
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
|
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
|
||||||
|
@ -2876,6 +2876,13 @@ export class FaintPhase extends PokemonPhase {
|
||||||
|
|
||||||
this.scene.queueMessage(getPokemonMessage(pokemon, ' fainted!'), null, true);
|
this.scene.queueMessage(getPokemonMessage(pokemon, ' fainted!'), null, true);
|
||||||
|
|
||||||
|
if (pokemon.getAbility().hasAttr(PostFaintAbAttr)) {
|
||||||
|
if (pokemon.turnData?.attacksReceived?.length) {
|
||||||
|
const lastAttack = pokemon.turnData.attacksReceived[0];
|
||||||
|
applyPostFaintAbAttrs(PostFaintAbAttr,pokemon, this.scene.getPokemonById(lastAttack.sourceId), new PokemonMove(lastAttack.move), lastAttack.result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const alivePlayField = this.scene.getField(true);
|
const alivePlayField = this.scene.getField(true);
|
||||||
alivePlayField.forEach(p => applyPostKnockOutAbAttrs(PostKnockOutAbAttr, p));
|
alivePlayField.forEach(p => applyPostKnockOutAbAttrs(PostKnockOutAbAttr, p));
|
||||||
if (pokemon.turnData?.attacksReceived?.length) {
|
if (pokemon.turnData?.attacksReceived?.length) {
|
||||||
|
|
Loading…
Reference in New Issue