got the basics working for moves like growl etc, need to check all sources of stat changes

pull/920/head
shayebeadlingkl 2024-05-15 13:17:14 -04:00
parent 7769c06393
commit 37244bc62f
4 changed files with 46 additions and 12 deletions

View File

@ -1702,7 +1702,7 @@ export class PreSwitchOutHealAbAttr extends PreSwitchOutAbAttr {
}
export class PreStatChangeAbAttr extends AbAttr {
applyPreStatChange(pokemon: Pokemon, passive: boolean, stat: BattleStat, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
applyPreStatChange(pokemon: Pokemon, user: Pokemon, passive: boolean, stat: BattleStat, levels: integer, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
return false;
}
}
@ -1716,7 +1716,7 @@ export class ProtectStatAbAttr extends PreStatChangeAbAttr {
this.protectedStat = protectedStat;
}
applyPreStatChange(pokemon: Pokemon, passive: boolean, stat: BattleStat, cancelled: Utils.BooleanHolder, args: any[]): boolean {
applyPreStatChange(pokemon: Pokemon, user: Pokemon, passive: boolean, stat: BattleStat, levels: integer, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (this.protectedStat === undefined || stat === this.protectedStat) {
cancelled.value = true;
return true;
@ -1730,6 +1730,28 @@ export class ProtectStatAbAttr extends PreStatChangeAbAttr {
}
}
export class ReflectStatAbAttr extends PreStatChangeAbAttr {
private reflectedStat: BattleStat;
constructor(reflectedStat?: BattleStat) {
super();
this.reflectedStat = reflectedStat;
}
applyPreStatChange(pokemon: Pokemon, sourcePokemon: Pokemon, passive: boolean, stat: BattleStat, levels: integer, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if ((this.reflectedStat === undefined || stat === this.reflectedStat) && pokemon !== sourcePokemon) {
cancelled.value = true;
const statChangePhase = new StatChangePhase(pokemon.scene, sourcePokemon.getBattlerIndex(), false, [stat], levels);
pokemon.scene.unshiftPhase(statChangePhase);
return true;
}
return false;
}
}
export class PreSetStatusAbAttr extends AbAttr {
applyPreSetStatus(pokemon: Pokemon, passive: boolean, effect: StatusEffect, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
return false;
@ -2813,8 +2835,8 @@ export function applyPreSwitchOutAbAttrs(attrType: { new(...args: any[]): PreSwi
}
export function applyPreStatChangeAbAttrs(attrType: { new(...args: any[]): PreStatChangeAbAttr },
pokemon: Pokemon, stat: BattleStat, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PreStatChangeAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreStatChange(pokemon, passive, stat, cancelled, args), args);
pokemon: Pokemon, sourcePokemon: Pokemon, stat: BattleStat, levels: integer, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PreStatChangeAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreStatChange(pokemon, sourcePokemon, passive, stat, levels, cancelled, args), args);
}
export function applyPostStatChangeAbAttrs(attrType: { new(...args: any[]): PostStatChangeAbAttr },
@ -3604,8 +3626,8 @@ export function initAbilities() {
new Ability(Abilities.PROPELLER_TAIL, 8)
.attr(BlockRedirectAbAttr),
new Ability(Abilities.MIRROR_ARMOR, 8)
.ignorable()
.unimplemented(),
.attr(ReflectStatAbAttr)
.ignorable(),
new Ability(Abilities.GULP_MISSILE, 8)
.attr(UnsuppressableAbilityAbAttr)
.attr(NoTransformAbilityAbAttr)

View File

@ -439,7 +439,7 @@ class StickyWebTag extends ArenaTrapTag {
if (!cancelled.value) {
pokemon.scene.queueMessage(`The opposing ${pokemon.name} was caught in a sticky web!`);
const statLevels = new Utils.NumberHolder(-1);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [BattleStat.SPD], statLevels.value));
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [BattleStat.SPD], statLevels.value, true, false, true, pokemon.scene.getPokemonById(this.sourceId)));
}
}

View File

@ -1733,7 +1733,7 @@ export class StatChangeAttr extends MoveEffectAttr {
if (move.chance < 0 || move.chance === 100 || user.randSeedInt(100) < move.chance) {
const levels = this.getLevels(user);
user.scene.unshiftPhase(new StatChangePhase(user.scene, (this.selfTarget ? user : target).getBattlerIndex(), this.selfTarget, this.stats, levels, this.showMessage));
user.scene.unshiftPhase(new StatChangePhase(user.scene, (this.selfTarget ? user : target).getBattlerIndex(), this.selfTarget, this.stats, levels, this.showMessage, false, true, user));
return true;
}
@ -1813,7 +1813,7 @@ export class AcupressureStatChangeAttr extends MoveEffectAttr {
randStats = randStats.filter(s => target.summonData.battleStats[s] < 6);
if (randStats.length > 0) {
let boostStat = [randStats[Utils.randInt(randStats.length)]];
user.scene.unshiftPhase(new StatChangePhase(user.scene, target.getBattlerIndex(), this.selfTarget, boostStat, 2));
user.scene.unshiftPhase(new StatChangePhase(user.scene, target.getBattlerIndex(), this.selfTarget, boostStat, 2, true, false, true, user));
return true;
}
return false;

View File

@ -30,7 +30,7 @@ import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, get
import { TempBattleStat } from "./data/temp-battle-stat";
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
import { ArenaTagType } from "./data/enums/arena-tag-type";
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr } from "./data/ability";
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr, PreStatChangeAbAttr } from "./data/ability";
import { Unlockables, getUnlockableName } from "./system/unlockables";
import { getBiomeKey } from "./field/arena";
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
@ -2739,8 +2739,19 @@ export class StatChangePhase extends PokemonPhase {
private showMessage: boolean;
private ignoreAbilities: boolean;
private canBeCopied: boolean;
private sourcePokemon: Pokemon;
constructor(scene: BattleScene, battlerIndex: BattlerIndex, selfTarget: boolean, stats: BattleStat[], levels: integer, showMessage: boolean = true, ignoreAbilities: boolean = false, canBeCopied: boolean = true) {
constructor(
scene: BattleScene,
battlerIndex: BattlerIndex,
selfTarget: boolean,
stats: BattleStat[],
levels: integer,
showMessage: boolean = true,
ignoreAbilities: boolean = false,
canBeCopied: boolean = true,
sourcePokemon?: Pokemon,
) {
super(scene, battlerIndex);
this.selfTarget = selfTarget;
@ -2749,6 +2760,7 @@ export class StatChangePhase extends PokemonPhase {
this.showMessage = showMessage;
this.ignoreAbilities = ignoreAbilities;
this.canBeCopied = canBeCopied;
this.sourcePokemon = sourcePokemon;
}
start() {
@ -2773,7 +2785,7 @@ export class StatChangePhase extends PokemonPhase {
this.scene.arena.applyTagsForSide(MistTag, pokemon.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY, cancelled);
if (!cancelled.value && !this.selfTarget && this.levels < 0)
applyPreStatChangeAbAttrs(ProtectStatAbAttr, this.getPokemon(), stat, cancelled);
applyPreStatChangeAbAttrs(PreStatChangeAbAttr, this.getPokemon(), this.sourcePokemon, stat, this.levels, cancelled);
return !cancelled.value;
});