diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 5d4c1c94d..c856fa05d 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 b0fb7c2cc..9c740ef46 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 d5bd71ad2..03fd53ec2 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 fca8dbd76..683693890 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 3cf586057..30622fb03 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),