diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index ba00b0906..a380be86e 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1100,6 +1100,26 @@ export class MagnetRisenTag extends TypeImmuneTag { } } +export class IdentifyTag extends BattlerTag { + public type: Type; + constructor(tagType: BattlerTagType, sourceMove: Moves, type: Type, length: number) { + super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove); + this.type = type; + } + + /** + * When given a battler tag or json representing one, load the data for it. + * @param {BattlerTag | any} source A battler tag + */ + loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.type = source.type as Type; + } + lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { + return true; + } +} + export class TypeBoostTag extends BattlerTag { public boostedType: Type; public boostValue: number; @@ -1358,6 +1378,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true); case BattlerTagType.MAGNET_RISEN: return new MagnetRisenTag(tagType, sourceMove); + case BattlerTagType.ODOR_SLEUTH: + return new IdentifyTag(tagType, sourceMove, Type.GHOST, turnCount); case BattlerTagType.NONE: default: return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); diff --git a/src/data/enums/battler-tag-type.ts b/src/data/enums/battler-tag-type.ts index d18ccf1c5..e06e4283e 100644 --- a/src/data/enums/battler-tag-type.ts +++ b/src/data/enums/battler-tag-type.ts @@ -55,5 +55,6 @@ export enum BattlerTagType { CURSED = "CURSED", CHARGED = "CHARGED", GROUNDED = "GROUNDED", - MAGNET_RISEN = "MAGNET_RISEN" + MAGNET_RISEN = "MAGNET_RISEN", + ODOR_SLEUTH = "ODOR_SLEUTH" } diff --git a/src/data/move.ts b/src/data/move.ts index 36254320f..65c313ef3 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1772,7 +1772,21 @@ export class ResetStatsAttr extends MoveEffectAttr { target.scene.queueMessage(getPokemonMessage(target, `'s stat changes\nwere eliminated!`)); return true; - } + } +} + +export class IdentifyAttr extends MoveEffectAttr { + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (!super.apply(user, target, move, args)) + return false; + + target.summonData.battleStats[BattleStat.EVA] = 0; + target.updateInfo(); + + target.scene.queueMessage(`${getPokemonMessage(user, " identified\n")}${getPokemonMessage(target, "!")}`); + + return true; + } } /** @@ -4656,7 +4670,7 @@ export function initMoves() { new AttackMove(Moves.ZAP_CANNON, Type.ELECTRIC, MoveCategory.SPECIAL, 120, 50, 5, 100, 0, 2) .attr(StatusEffectAttr, StatusEffect.PARALYSIS) .ballBombMove(), - new StatusMove(Moves.FORESIGHT, Type.NORMAL, -1, 40, -1, 0, 2) + new StatusMove(Moves.FORESIGHT, Type.NORMAL, -1, 40, -1, 0, 2) // TODO .unimplemented(), new SelfStatusMove(Moves.DESTINY_BOND, Type.GHOST, -1, 5, -1, 0, 2) .ignoresProtect() @@ -5007,7 +5021,9 @@ export function initMoves() { .attr(StatChangeAttr, BattleStat.SPATK, -2, true) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE), new StatusMove(Moves.ODOR_SLEUTH, Type.NORMAL, -1, 40, -1, 0, 3) - .unimplemented(), + .attr(IdentifyAttr) + .attr(AddBattlerTagAttr, BattlerTagType.ODOR_SLEUTH, false, false, 20) + .partial(), new AttackMove(Moves.ROCK_TOMB, Type.ROCK, MoveCategory.PHYSICAL, 60, 95, 15, 100, 0, 3) .attr(StatChangeAttr, BattleStat.SPD, -1) .makesContact(false), @@ -5114,7 +5130,7 @@ export function initMoves() { new StatusMove(Moves.GRAVITY, Type.PSYCHIC, -1, 5, -1, 0, 4) .attr(AddArenaTagAttr, ArenaTagType.GRAVITY, 5) .target(MoveTarget.BOTH_SIDES), - new StatusMove(Moves.MIRACLE_EYE, Type.PSYCHIC, -1, 40, -1, 0, 4) + new StatusMove(Moves.MIRACLE_EYE, Type.PSYCHIC, -1, 40, -1, 0, 4) // TODO .unimplemented(), new AttackMove(Moves.WAKE_UP_SLAP, Type.FIGHTING, MoveCategory.PHYSICAL, 70, 100, 10, -1, 0, 4) .attr(MovePowerMultiplierAttr, (user, target, move) => target.status?.effect === StatusEffect.SLEEP ? 2 : 1) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 3864afe20..ff4dcca5d 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4,7 +4,7 @@ import { Variant, VariantSet, variantColorCache } from '#app/data/variant'; import { variantData } from '#app/data/variant'; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info'; import { Moves } from "../data/enums/moves"; -import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr } from "../data/move"; +import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveTypeAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, IdentifyAttr } from "../data/move"; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from '../data/pokemon-species'; import * as Utils from '../utils'; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type'; @@ -19,7 +19,7 @@ import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEv import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from '../data/tms'; import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchSummonPhase } from '../phases'; import { BattleStat } from '../data/battle-stat'; -import { BattlerTag, BattlerTagLapseType, EncoreTag, HelpingHandTag, HighestStatBoostTag, TypeBoostTag, getBattlerTag } from '../data/battler-tags'; +import { BattlerTag, BattlerTagLapseType, EncoreTag, HelpingHandTag, HighestStatBoostTag, IdentifyTag, TypeBoostTag, getBattlerTag } from '../data/battler-tags'; import { BattlerTagType } from "../data/enums/battler-tag-type"; import { Species } from '../data/enums/species'; import { WeatherType } from '../data/weather'; @@ -779,6 +779,17 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { types.splice(flyingIndex, 1); } + const identifyTags = this.findTags(t => t instanceof IdentifyTag); + console.log(identifyTags); + if (forDefend && identifyTags.length) { + identifyTags.forEach(tag => { + const type = (tag as IdentifyTag).type; + const typeIndex = types.indexOf(type); + if (typeIndex > -1) + types.splice(typeIndex, 1); + }); + } + if (!types.length) // become UNKNOWN if no types are present types.push(Type.UNKNOWN); @@ -789,6 +800,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } + console.log(types); return types; }