diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 5d4c1c94d89..c856fa05d3f 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1017,6 +1017,39 @@ export class SaltCuredTag extends BattlerTag { } } +export class CursedTag extends BattlerTag { + private sourceIndex: integer; + + constructor(sourceId: integer) { + super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId); + } + + onAdd(pokemon: Pokemon): void { + super.onAdd(pokemon); + + pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' has been cursed!')); + this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); + } + + lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { + const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); + + if (ret) { + pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.SALT_CURE)); + + const cancelled = new Utils.BooleanHolder(false); + applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); + + if (!cancelled.value) { + pokemon.damageAndUpdate(Math.floor(pokemon.getMaxHp() / 4)); + pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` is hurt by the ${this.getMoveName()}!`)); + } + } + + return ret; + } +} + export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves, sourceId: integer): BattlerTag { switch (tagType) { case BattlerTagType.RECHARGING: @@ -1114,6 +1147,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount - 1, sourceMove); case BattlerTagType.SALT_CURED: return new SaltCuredTag(sourceId); + case BattlerTagType.CURSED: + return new CursedTag(sourceId); case BattlerTagType.CHARGED: return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true); case BattlerTagType.NONE: diff --git a/src/data/enums/battler-tag-type.ts b/src/data/enums/battler-tag-type.ts index b0fb7c2cc75..9c740ef4629 100644 --- a/src/data/enums/battler-tag-type.ts +++ b/src/data/enums/battler-tag-type.ts @@ -49,6 +49,7 @@ export enum BattlerTagType { BYPASS_SLEEP = "BYPASS_SLEEP", IGNORE_FLYING = "IGNORE_FLYING", SALT_CURED = "SALT_CURED", + CURSED = "CURSED", CHARGED = "CHARGED", GROUNDED = "GROUNDED" } diff --git a/src/data/move.ts b/src/data/move.ts index d5bd71ad2e1..03fd53ec29f 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2493,6 +2493,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr { return -5; case BattlerTagType.SEEDED: case BattlerTagType.SALT_CURED: + case BattlerTagType.CURSED: case BattlerTagType.FRENZY: case BattlerTagType.TRAPPED: case BattlerTagType.BIND: @@ -2527,6 +2528,34 @@ export class AddBattlerTagAttr extends MoveEffectAttr { } } +export class CurseAttr extends MoveEffectAttr { + + apply(user: Pokemon, target: Pokemon, move:Move, args: any[]): boolean { + // Determine the correct target based on the user's type + if (!user.getTypes(true).includes(Type.GHOST)) { + // For non-Ghost types, target the user itself + target = user; + } + + if (user.getTypes(true).includes(Type.GHOST)) { + if (target.getTag(BattlerTagType.CURSED)) { + user.scene.queueMessage('But it failed!'); + return false; + } + let curseRecoilDamage = Math.floor(user.getMaxHp() / 2); + user.damageAndUpdate(curseRecoilDamage, HitResult.OTHER, false, true, true); + user.scene.queueMessage(getPokemonMessage(user, ' cut its own HP!')); + target.addTag(BattlerTagType.CURSED, 0, move.id, user.id); + return true; + } else { + target = user; + user.scene.unshiftPhase(new StatChangePhase(user.scene, user.getBattlerIndex(), this.selfTarget, [BattleStat.ATK, BattleStat.DEF], 1)); + user.scene.unshiftPhase(new StatChangePhase(user.scene, user.getBattlerIndex(), this.selfTarget, [BattleStat.SPD], -1)); + return true; + } + } +} + export class LapseBattlerTagAttr extends MoveEffectAttr { public tagTypes: BattlerTagType[]; diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index fca8dbd76ca..68369389066 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -917,7 +917,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.TRUMBEAK, 14, null, null) ], [Species.TRUMBEAK]: [ - new SpeciesEvolution(Species.TOUCANNON, 36, null, null) + new SpeciesEvolution(Species.TOUCANNON, 28, null, null) ], [Species.YUNGOOS]: [ new SpeciesEvolution(Species.GUMSHOOS, 20, null, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.SHORT) diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 3cf586057b1..30622fb033d 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -1473,7 +1473,7 @@ export function initSpecies() { new PokemonSpecies(Species.PORYGON_Z, "Porygon-Z", 4, false, false, false, "Virtual Pokémon", Type.NORMAL, null, 0.9, 34, Abilities.ADAPTABILITY, Abilities.DOWNLOAD, Abilities.ANALYTIC, 535, 85, 80, 70, 135, 75, 90, 30, 50, 268, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.GALLADE, "Gallade", 4, false, false, false, "Blade Pokémon", Type.PSYCHIC, Type.FIGHTING, 1.6, 52, Abilities.STEADFAST, Abilities.SHARPNESS, Abilities.JUSTIFIED, 518, 68, 125, 65, 65, 115, 80, 45, 35, 259, GrowthRate.SLOW, 100, false, true, new PokemonForm("Normal", "", Type.PSYCHIC, Type.FIGHTING, 1.6, 52, Abilities.STEADFAST, Abilities.SHARPNESS, Abilities.JUSTIFIED, 518, 68, 125, 65, 65, 115, 80, 45, 35, 259), - new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.PSYCHIC, Type.FIGHTING, 1.6, 56.4, Abilities.INNER_FOCUS, Abilities.INNER_FOCUS, Abilities.INNER_FOCUS, 618, 68, 165, 95, 65, 115, 110, 45, 35, 259), + new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.PSYCHIC, Type.FIGHTING, 1.6, 56.4, Abilities.SHARPNESS, Abilities.SHARPNESS, Abilities.SHARPNESS, 618, 68, 165, 95, 65, 115, 110, 45, 35, 259), ), new PokemonSpecies(Species.PROBOPASS, "Probopass", 4, false, false, false, "Compass Pokémon", Type.ROCK, Type.STEEL, 1.4, 340, Abilities.STURDY, Abilities.MAGNET_PULL, Abilities.SAND_FORCE, 525, 60, 55, 145, 75, 150, 40, 60, 70, 184, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DUSKNOIR, "Dusknoir", 4, false, false, false, "Gripper Pokémon", Type.GHOST, null, 2.2, 106.6, Abilities.PRESSURE, Abilities.NONE, Abilities.FRISK, 525, 45, 100, 135, 65, 135, 45, 45, 35, 263, GrowthRate.FAST, 50, false),