implement Costar ability, refactor TraceAbAttr to be more generic

This commit is contained in:
Dmitriy 2024-05-21 14:55:48 -04:00
parent 89494fa0c8
commit 6fc24b3ae8

View File

@ -1391,7 +1391,20 @@ export class PostIntimidateStatChangeAbAttr extends AbAttr {
}
}
/**
* Base class for defining all {@linkcode Ability} Attributes post summon
* @abstract
* @see {@linkcode applyPostSummon()}
*/
export class PostSummonAbAttr extends AbAttr {
/**
* Applies ability post summon (after switching in)
* @abstract
* @param pokemon {@linkcode Pokemon} with this ability
* @param passive Whether this ability is a passive
* @param args Set of unique arguments needed by this attribute
* @returns true if application of the ability succeeds
*/
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
return false;
}
@ -1612,8 +1625,57 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
}
}
export class TraceAbAttr extends PostSummonAbAttr {
/** Attempts to copy `copyTarget` after entering the battle */
export class PostSummonCopyAbAttr extends PostSummonAbAttr {
/**
* @param copyTarget what to attempt to copy
* @param test this is a test
*/
constructor(
private copyTarget: "OPP_ABILITY" | "ALLY_STAT_CHANGES", /** Extend this to add more options */
) {
super()
}
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
switch (this.copyTarget) {
case "OPP_ABILITY":
return this.copyAbility(pokemon)
case "ALLY_STAT_CHANGES":
return this.copyAllyStatChanges(pokemon)
default:
return false
}
}
/**
* Copy the stat changes on an ally pokemon
* @param pokemon - that will receive the stat changes
* @returns true if successful
*/
copyAllyStatChanges(pokemon: Pokemon): boolean {
if (!pokemon.scene.currentBattle.double) {
return false
}
const ally = pokemon.getAlly()
if (!ally || !ally.summonData.battleStats.some(change => change > 0)) {
return false
}
pokemon.summonData.battleStats = ally.summonData.battleStats
pokemon.updateInfo()
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` copied ${ally.name}'s stat changes!`))
return true
}
/**
* Copy the ability of an enemy pokemon post summon
* @param pokemon - that will receive the ability
* @returns true if successful
*/
copyAbility(pokemon: Pokemon): boolean {
const targets = pokemon.getOpponents();
if (!targets.length)
return false;
@ -1624,12 +1686,16 @@ export class TraceAbAttr extends PostSummonAbAttr {
else
target = targets[0];
// Wonder Guard is normally uncopiable so has the attribute, but trace specifically can copy it
if (target.getAbility().hasAttr(UncopiableAbilityAbAttr) && target.getAbility().id !== Abilities.WONDER_GUARD)
return false;
if (
target.getAbility().hasAttr(UncopiableAbilityAbAttr) &&
// Wonder Guard is normally uncopiable so has the attribute, but trace specifically can copy it
!(pokemon.hasAbility(Abilities.TRACE) && target.getAbility().id === Abilities.WONDER_GUARD)
) {
return false
}
pokemon.summonData.ability = target.getAbility().id;
pokemon.updateInfo()
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` traced ${target.name}'s\n${allAbilities[target.getAbility().id].name}!`));
return true;
@ -3107,7 +3173,7 @@ export function initAbilities() {
.attr(DoubleBattleChanceAbAttr)
.ignorable(),
new Ability(Abilities.TRACE, 3)
.attr(TraceAbAttr)
.attr(PostSummonCopyAbAttr, "OPP_ABILITY")
.attr(UncopiableAbilityAbAttr),
new Ability(Abilities.HUGE_POWER, 3)
.attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 2),
@ -3901,6 +3967,7 @@ export function initAbilities() {
new Ability(Abilities.SUPREME_OVERLORD, 9)
.unimplemented(),
new Ability(Abilities.COSTAR, 9)
.attr(PostSummonCopyAbAttr, "ALLY_STAT_CHANGES")
.unimplemented(),
new Ability(Abilities.TOXIC_DEBRIS, 9)
.attr(PostDefendApplyArenaTrapTagAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL, ArenaTagType.TOXIC_SPIKES)