From 7623e72db1a907a1fec4928dc09783f52cd55c9e Mon Sep 17 00:00:00 2001 From: Xavion3 Date: Fri, 7 Feb 2025 14:22:51 +1100 Subject: [PATCH] Implement stellar tera damage boost --- src/data/move.ts | 25 +++++++++++++++++++++++++ src/field/pokemon.ts | 24 +++++++++++++++++++----- src/phases/move-effect-phase.ts | 6 ++++++ src/system/pokemon-data.ts | 2 ++ 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index efd1e3e67bd..9a1ae926fd2 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4918,6 +4918,30 @@ export class TeraBlastTypeAttr extends VariableMoveTypeAttr { } } +/** + * Attribute used for Tera Starstorm that changes the move type to Stellar + * @extends VariableMoveTypeAttr + */ +export class TeraStarstormTypeAttr extends VariableMoveTypeAttr { + /** + * + * @param user the {@linkcode Pokemon} using the move + * @param target n/a + * @param move n/a + * @param args[0] {@linkcode Utils.NumberHolder} the move type + * @returns `true` if the move type is changed to {@linkcode Type.STELLAR}, `false` otherwise + */ + override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (user.isTerastallized && user.hasSpecies(Species.TERAPAGOS)) { + const moveType = args[0] as Utils.NumberHolder; + + moveType.value = Type.STELLAR; + return true; + } + return false; + } +} + export class MatchUserTypeAttr extends VariableMoveTypeAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const moveType = args[0]; @@ -11078,6 +11102,7 @@ export function initMoves() { .chargeAttr(WeatherInstantChargeAttr, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), new AttackMove(Moves.TERA_STARSTORM, Type.NORMAL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9) .attr(TeraMoveCategoryAttr) + .attr(TeraStarstormTypeAttr) .attr(VariableTargetAttr, (user, target, move) => user.hasSpecies(Species.TERAPAGOS) && user.isTerastallized ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER) .partial(), /** Does not ignore abilities that affect stats, relevant in determining the move's category {@see TeraMoveCategoryAttr} */ new AttackMove(Moves.FICKLE_BEAM, Type.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 11a1453841a..d24b64272c0 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -132,6 +132,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public evoCounter: number; public teraType: Type; public isTerastallized: boolean; + public stellarTypesBoosted: Type[]; public fusionSpecies: PokemonSpecies | null; public fusionFormIndex: number; @@ -244,6 +245,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.customPokemonData = new CustomPokemonData(dataSource.customPokemonData); this.teraType = dataSource.teraType; this.isTerastallized = dataSource.isTerastallized; + this.stellarTypesBoosted = dataSource.stellarTypesBoosted; } else { this.id = Utils.randSeedInt(4294967296); this.ivs = ivs || Utils.getIvsFromId(this.id); @@ -295,6 +297,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.teraType = Utils.randSeedItem(this.getTypes(false, false, true)); this.isTerastallized = false; + this.stellarTypesBoosted = []; } this.generateName(); @@ -2759,11 +2762,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const matchesSourceType = sourceTypes.includes(moveType); /** A damage multiplier for when the attack is of the attacker's type and/or Tera type. */ const stabMultiplier = new Utils.NumberHolder(1); - if (matchesSourceType) { - stabMultiplier.value += 0.5; - } - applyMoveAttrs(CombinedPledgeStabBoostAttr, source, this, move, stabMultiplier); - if (source.isTerastallized && sourceTeraType === moveType) { + if (matchesSourceType && moveType !== Type.STELLAR) { stabMultiplier.value += 0.5; } @@ -2771,6 +2770,20 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { applyAbAttrs(StabBoostAbAttr, source, null, simulated, stabMultiplier); } + applyMoveAttrs(CombinedPledgeStabBoostAttr, source, this, move, stabMultiplier); + + if (source.isTerastallized && sourceTeraType === moveType && moveType !== Type.STELLAR) { + stabMultiplier.value += 0.5; + } + + if (source.isTerastallized && source.teraType === Type.STELLAR && (!source.stellarTypesBoosted.includes(moveType) || source.hasSpecies(Species.TERAPAGOS))) { + if (matchesSourceType) { + stabMultiplier.value += 0.5; + } else { + stabMultiplier.value += 0.2; + } + } + stabMultiplier.value = Math.min(stabMultiplier.value, 2.25); /** Halves damage if the attacker is using a physical attack while burned */ @@ -3808,6 +3821,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { resetTera(): void { const wasTerastallized = this.isTerastallized; this.isTerastallized = false; + this.stellarTypesBoosted = []; if (wasTerastallized) { this.updateSpritePipelineData(); globalScene.triggerPokemonFormChange(this, SpeciesFormChangeLapseTeraTrigger); diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index fff8caf38b5..3c72fd580fa 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -390,6 +390,12 @@ export class MoveEffectPhase extends PokemonPhase { target.lapseTag(BattlerTagType.SUBSTITUTE); } }); + + const moveType = user.getMoveType(move, true); + if (move.category !== MoveCategory.STATUS && !user.stellarTypesBoosted.includes(moveType)) { + user.stellarTypesBoosted.push(moveType); + } + this.end(); }); }); diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 9132433ae29..287e381d96f 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -48,6 +48,7 @@ export default class PokemonData { public evoCounter: number; public teraType: Type; public isTerastallized: boolean; + public stellarTypesBoosted: Type[]; public fusionSpecies: Species; public fusionFormIndex: number; @@ -108,6 +109,7 @@ export default class PokemonData { this.pokerus = !!source.pokerus; this.teraType = (source.teraType || 0) as Type; this.isTerastallized = source.isTerastallized || false; + this.stellarTypesBoosted = source.stellarTypesBoosted || []; this.fusionSpecies = sourcePokemon ? sourcePokemon.fusionSpecies?.speciesId : source.fusionSpecies; this.fusionFormIndex = source.fusionFormIndex;