Re-implement taunt as BattlerTag and add taunt immunities for oblivious and aroma veil abilities

This commit is contained in:
jatinkohli 2024-05-21 01:05:42 -07:00
parent dce73f6d7e
commit 2b23ac8140
7 changed files with 50 additions and 33 deletions

View File

@ -3009,6 +3009,7 @@ export function initAbilities() {
.ignorable(), .ignorable(),
new Ability(Abilities.OBLIVIOUS, 3) new Ability(Abilities.OBLIVIOUS, 3)
.attr(BattlerTagImmunityAbAttr, BattlerTagType.INFATUATED) .attr(BattlerTagImmunityAbAttr, BattlerTagType.INFATUATED)
.attr(BattlerTagImmunityAbAttr, BattlerTagType.TAUNT)
.attr(IntimidateImmunityAbAttr) .attr(IntimidateImmunityAbAttr)
.ignorable() .ignorable()
.partial(), .partial(),
@ -3450,7 +3451,10 @@ export function initAbilities() {
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a bursting aura!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a bursting aura!'))
.attr(MoveAbilityBypassAbAttr), .attr(MoveAbilityBypassAbAttr),
new Ability(Abilities.AROMA_VEIL, 6) new Ability(Abilities.AROMA_VEIL, 6)
.attr(BattlerTagImmunityAbAttr, BattlerTagType.INFATUATED)
.attr(BattlerTagImmunityAbAttr, BattlerTagType.TORMENT) .attr(BattlerTagImmunityAbAttr, BattlerTagType.TORMENT)
.attr(BattlerTagImmunityAbAttr, BattlerTagType.TAUNT)
.attr(BattlerTagImmunityAbAttr, BattlerTagType.ENCORE)
.ignorable() .ignorable()
.partial(), .partial(),
new Ability(Abilities.FLOWER_VEIL, 6) new Ability(Abilities.FLOWER_VEIL, 6)

View File

@ -514,6 +514,32 @@ export class TormentTag extends BattlerTag {
} }
} }
export class TauntTag extends BattlerTag {
public justTaunted: boolean = true;
constructor() {
super(BattlerTagType.TAUNT, BattlerTagLapseType.TURN_END, 4, Moves.TAUNT);
}
onAdd(pokemon: Pokemon) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' fell for the taunt!'));
}
onRemove(pokemon: Pokemon): void {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' shook off the taunt!'));
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType) {
const ret = super.lapse(pokemon, lapseType);
this.justTaunted = false;
return ret;
}
getDescriptor(): string {
return 'taunt';
}
}
export class HelpingHandTag extends BattlerTag { export class HelpingHandTag extends BattlerTag {
constructor(sourceId: integer) { constructor(sourceId: integer) {
super(BattlerTagType.HELPING_HAND, BattlerTagLapseType.TURN_END, 1, Moves.HELPING_HAND, sourceId); super(BattlerTagType.HELPING_HAND, BattlerTagLapseType.TURN_END, 1, Moves.HELPING_HAND, sourceId);
@ -1341,6 +1367,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc
return new EncoreTag(sourceId); return new EncoreTag(sourceId);
case BattlerTagType.TORMENT: case BattlerTagType.TORMENT:
return new TormentTag(); return new TormentTag();
case BattlerTagType.TAUNT:
return new TauntTag();
case BattlerTagType.HELPING_HAND: case BattlerTagType.HELPING_HAND:
return new HelpingHandTag(sourceId); return new HelpingHandTag(sourceId);
case BattlerTagType.INGRAIN: case BattlerTagType.INGRAIN:

View File

@ -12,6 +12,7 @@ export enum BattlerTagType {
CHARGING = "CHARGING", CHARGING = "CHARGING",
ENCORE = "ENCORE", ENCORE = "ENCORE",
TORMENT = "TORMENT", TORMENT = "TORMENT",
TAUNT = "TAUNT",
HELPING_HAND = "HELPING_HAND", HELPING_HAND = "HELPING_HAND",
INGRAIN = "INGRAIN", INGRAIN = "INGRAIN",
AQUA_RING = "AQUA_RING", AQUA_RING = "AQUA_RING",

View File

@ -2,7 +2,7 @@ import { Moves } from "./enums/moves";
import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims"; import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims";
import { BattleEndPhase, MoveEffectPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase, ToggleDoublePositionPhase } from "../phases"; import { BattleEndPhase, MoveEffectPhase, MovePhase, NewBattlePhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase, ToggleDoublePositionPhase } from "../phases";
import { BattleStat, getBattleStatName } from "./battle-stat"; import { BattleStat, getBattleStatName } from "./battle-stat";
import { EncoreTag, TormentTag } from "./battler-tags"; import { EncoreTag, TauntTag, TormentTag } from "./battler-tags";
import { BattlerTagType } from "./enums/battler-tag-type"; import { BattlerTagType } from "./enums/battler-tag-type";
import { getPokemonMessage } from "../messages"; import { getPokemonMessage } from "../messages";
import Pokemon, { AttackMoveResult, EnemyPokemon, HitResult, MoveResult, PlayerPokemon, PokemonMove, TurnMove } from "../field/pokemon"; import Pokemon, { AttackMoveResult, EnemyPokemon, HitResult, MoveResult, PlayerPokemon, PokemonMove, TurnMove } from "../field/pokemon";
@ -3359,6 +3359,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
case BattlerTagType.DROWSY: case BattlerTagType.DROWSY:
case BattlerTagType.NO_CRIT: case BattlerTagType.NO_CRIT:
case BattlerTagType.TORMENT: case BattlerTagType.TORMENT:
case BattlerTagType.TAUNT:
return -5; return -5;
case BattlerTagType.SEEDED: case BattlerTagType.SEEDED:
case BattlerTagType.SALT_CURED: case BattlerTagType.SALT_CURED:
@ -5493,8 +5494,8 @@ export function initMoves() {
.attr(StatChangeAttr, BattleStat.SPDEF, 1, true) .attr(StatChangeAttr, BattleStat.SPDEF, 1, true)
.attr(AddBattlerTagAttr, BattlerTagType.CHARGED, true, false), .attr(AddBattlerTagAttr, BattlerTagType.CHARGED, true, false),
new StatusMove(Moves.TAUNT, Type.DARK, 100, 20, -1, 0, 3) new StatusMove(Moves.TAUNT, Type.DARK, 100, 20, -1, 0, 3)
// .attr(TauntAttr) .attr(AddBattlerTagAttr, BattlerTagType.TAUNT)
.condition((user, target, move) => (!target.summonData.taunted)) .condition((user, target, move) => (target.findTag(t => t instanceof TauntTag) === undefined))
.partial(), .partial(),
new StatusMove(Moves.HELPING_HAND, Type.NORMAL, -1, 20, -1, 5, 3) new StatusMove(Moves.HELPING_HAND, Type.NORMAL, -1, 20, -1, 5, 3)
.attr(AddBattlerTagAttr, BattlerTagType.HELPING_HAND) .attr(AddBattlerTagAttr, BattlerTagType.HELPING_HAND)

View File

@ -19,7 +19,7 @@ import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEv
import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from '../data/tms'; import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from '../data/tms';
import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchPhase, SwitchSummonPhase, ToggleDoublePositionPhase } from '../phases'; import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchPhase, SwitchSummonPhase, ToggleDoublePositionPhase } from '../phases';
import { BattleStat } from '../data/battle-stat'; import { BattleStat } from '../data/battle-stat';
import { BattlerTag, BattlerTagLapseType, EncoreTag, HelpingHandTag, HighestStatBoostTag, TypeBoostTag, getBattlerTag } from '../data/battler-tags'; import { BattlerTag, BattlerTagLapseType, EncoreTag, HelpingHandTag, HighestStatBoostTag, TauntTag, TypeBoostTag, getBattlerTag } from '../data/battler-tags';
import { BattlerTagType } from "../data/enums/battler-tag-type"; import { BattlerTagType } from "../data/enums/battler-tag-type";
import { Species } from '../data/enums/species'; import { Species } from '../data/enums/species';
import { WeatherType } from '../data/weather'; import { WeatherType } from '../data/weather';
@ -3389,9 +3389,6 @@ export class PokemonSummonData {
public disabledTurns: integer = 0; public disabledTurns: integer = 0;
public tormented = false; public tormented = false;
public prevMove: Moves = undefined; // for torment, carry over between battles while summoned public prevMove: Moves = undefined; // for torment, carry over between battles while summoned
public justTaunted: boolean = false;
public taunted: boolean = false;
public tauntedTurns: integer = 0;
public tags: BattlerTag[] = []; public tags: BattlerTag[] = [];
public abilitySuppressed: boolean = false; public abilitySuppressed: boolean = false;
@ -3474,8 +3471,8 @@ export class PokemonMove {
isUsable(pokemon: Pokemon, ignorePp?: boolean): boolean { isUsable(pokemon: Pokemon, ignorePp?: boolean): boolean {
const isMoveDisabled = this.moveId && pokemon.summonData?.disabledMove === this.moveId; const isMoveDisabled = this.moveId && pokemon.summonData?.disabledMove === this.moveId;
// for taunt: check valid move, pokemon is taunted, // for taunt: check valid move, pokemon is taunted, and move is status
const isMoveDisabledTaunt = this.moveId && pokemon.summonData.taunted && this.getMove().category === MoveCategory.STATUS; const isMoveDisabledTaunt = this.moveId && (pokemon.findTag(t => t instanceof TauntTag) !== undefined) && this.getMove().category === MoveCategory.STATUS;
// for torment: check valid move, pokemon is tormented, pokemon has moved this summon, and selected move is the same as previous move // for torment: check valid move, pokemon is tormented, pokemon has moved this summon, and selected move is the same as previous move
const isMoveDisabledTorment = this.moveId && pokemon.summonData.tormented && pokemon.summonData.prevMove === this.moveId; const isMoveDisabledTorment = this.moveId && pokemon.summonData.tormented && pokemon.summonData.prevMove === this.moveId;

View File

@ -21,7 +21,7 @@ import { Biome } from "./data/enums/biome";
import { ModifierTier } from "./modifier/modifier-tier"; import { ModifierTier } from "./modifier/modifier-tier";
import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, RememberMoveModifierType, TmModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type"; import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, RememberMoveModifierType, TmModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TrappedTag } from "./data/battler-tags"; import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TauntTag, TrappedTag } from "./data/battler-tags";
import { BattlerTagType } from "./data/enums/battler-tag-type"; import { BattlerTagType } from "./data/enums/battler-tag-type";
import { getPokemonMessage, getPokemonPrefix } from "./messages"; import { getPokemonMessage, getPokemonPrefix } from "./messages";
import { Starter } from "./ui/starter-select-ui-handler"; import { Starter } from "./ui/starter-select-ui-handler";
@ -1743,7 +1743,7 @@ export class CommandPhase extends FieldPhase {
else if (playerPokemon.summonData.tormented && playerPokemon.summonData.prevMove === move.moveId) { else if (playerPokemon.summonData.tormented && playerPokemon.summonData.prevMove === move.moveId) {
errorMessage = getPokemonMessage(playerPokemon, ' can\'t use the same move twice in a row due to the torment!'); errorMessage = getPokemonMessage(playerPokemon, ' can\'t use the same move twice in a row due to the torment!');
canTranslate = false; canTranslate = false;
} else if (playerPokemon.summonData.taunted && move.getMove().category === MoveCategory.STATUS) { } else if ((playerPokemon.findTag(t => t instanceof TauntTag) !== undefined) && move.getMove().category === MoveCategory.STATUS) {
errorMessage = getPokemonMessage(playerPokemon, ' can\'t use ' + move.getName() + ' after the taunt!'); errorMessage = getPokemonMessage(playerPokemon, ' can\'t use ' + move.getName() + ' after the taunt!');
canTranslate = false; canTranslate = false;
} else } else
@ -2111,16 +2111,7 @@ export class TurnEndPhase extends FieldPhase {
pokemon.lapseTags(BattlerTagLapseType.TURN_END); pokemon.lapseTags(BattlerTagLapseType.TURN_END);
// For torment, keep track of last used move. This remains between battles while the pokemon is still on the field. // For torment, keep track of last used move. This remains between battles while the pokemon is still on the field.
pokemon.summonData.prevMove = pokemon.getLastXMoves(1)[0].move; pokemon.summonData.prevMove = pokemon.getLastXMoves(1)[0] ? pokemon.getLastXMoves(1)[0].move : undefined;
if (pokemon.summonData.justTaunted) {
pokemon.summonData.justTaunted = false;
}
if (pokemon.summonData.taunted && !--pokemon.summonData.tauntedTurns) {
this.scene.pushPhase(new MessagePhase(this.scene, getPokemonMessage(pokemon, " shook off the taunt!")));
pokemon.summonData.taunted = false;
}
if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) { if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) {
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, moveName: allMoves[pokemon.summonData.disabledMove].name }))); this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, moveName: allMoves[pokemon.summonData.disabledMove].name })));
@ -2269,12 +2260,16 @@ export class MovePhase extends BattlePhase {
console.log(Moves[this.move.moveId]); console.log(Moves[this.move.moveId]);
const tauntTag = this.pokemon.findTag(t => t instanceof TauntTag); // undefined if pokemon is not taunted
// decrement from taunt timer if target was taunted before moving
if (tauntTag && (tauntTag as TauntTag).justTaunted)
tauntTag.lapse(this.pokemon, BattlerTagLapseType.MOVE);
if (!this.canMove()) { if (!this.canMove()) {
if (this.move.moveId && this.pokemon.summonData.disabledMove === this.move.moveId) if (this.move.moveId && this.pokemon.summonData.disabledMove === this.move.moveId)
this.scene.queueMessage(`${this.move.getName()} is disabled!`); this.scene.queueMessage(`${this.move.getName()} is disabled!`);
else if (this.pokemon.summonData.taunted && this.move.getMove().category === MoveCategory.STATUS) { else if (tauntTag && this.move.getMove().category === MoveCategory.STATUS) {
if (this.pokemon.summonData.justTaunted)
this.pokemon.summonData.tauntedTurns--;
this.scene.queueMessage(getPokemonMessage(this.pokemon, ' can\'t use ' + this.move.getName() + ' after the taunt!')) this.scene.queueMessage(getPokemonMessage(this.pokemon, ' can\'t use ' + this.move.getName() + ' after the taunt!'))
} }
return this.end(); return this.end();
@ -2729,12 +2724,6 @@ export class MoveEndPhase extends PokemonPhase {
this.scene.arena.setIgnoreAbilities(false); this.scene.arena.setIgnoreAbilities(false);
// if pokemon was taunted this turn and moved after the pokemon who taunted it,
// decrement taunt duration by 1
if (pokemon.summonData.justTaunted) {
pokemon.summonData.tauntedTurns--;
}
this.end(); this.end();
} }
} }

View File

@ -118,9 +118,6 @@ export default class PokemonData {
this.summonData.abilitySuppressed = source.summonData.abilitySuppressed; this.summonData.abilitySuppressed = source.summonData.abilitySuppressed;
this.summonData.tormented = source.summonData.tormented; this.summonData.tormented = source.summonData.tormented;
this.summonData.prevMove = source.summonData.prevMove; this.summonData.prevMove = source.summonData.prevMove;
this.summonData.justTaunted = source.summonData.justTaunted;
this.summonData.taunted = source.summonData.taunted;
this.summonData.tauntedTurns = source.summonData.tauntedTurns;
this.summonData.ability = source.summonData.ability; this.summonData.ability = source.summonData.ability;
this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m)); this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m));