[P2] Fixes Transform/Imposter not updating type/battle stat changes immediately; set move PP to 5 when transforming (#3462)
* Adds updateInfo to transform move/ability, mirrors Transform functionality in Imposter * Implements functionality for reducing pp to 5 or less for each move when transforming * Refactors to async/await pattern, adds back removed anims/sounds from last commit * Eslint fix attempt * Update src/data/ability.ts per DayKev's suggestion Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Merge and fix conflicts * Adds unit tests for pp-change with transform/imposter * Updates to consistency in syntax/deprecated code --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
This commit is contained in:
parent
fd38ab4cb4
commit
958d79140c
|
@ -1 +1 @@
|
|||
Subproject commit fc4a1effd5170def3c8314208a52cd0d8e6913ef
|
||||
Subproject commit 3ccef8472dd7cc7c362538489954cb8fdad27e5f
|
|
@ -2422,11 +2422,12 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
|
|||
super(true);
|
||||
}
|
||||
|
||||
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
||||
async applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): Promise<boolean> {
|
||||
const targets = pokemon.getOpponents();
|
||||
if (simulated || !targets.length) {
|
||||
return simulated;
|
||||
}
|
||||
const promises: Promise<void>[] = [];
|
||||
|
||||
let target: Pokemon;
|
||||
if (targets.length > 1) {
|
||||
|
@ -2435,7 +2436,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
|
|||
target = targets[0];
|
||||
}
|
||||
|
||||
target = target!; // compiler doesn't know its guranteed to be defined
|
||||
target = target!;
|
||||
pokemon.summonData.speciesForm = target.getSpeciesForm();
|
||||
pokemon.summonData.fusionSpeciesForm = target.getFusionSpeciesForm();
|
||||
pokemon.summonData.ability = target.getAbility().id;
|
||||
|
@ -2452,18 +2453,23 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
|
|||
pokemon.setStatStage(s, target.getStatStage(s));
|
||||
}
|
||||
|
||||
pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m?.moveId ?? Moves.NONE, m?.ppUsed, m?.ppUp));
|
||||
pokemon.summonData.moveset = target.getMoveset().map(m => {
|
||||
const pp = m?.getMove().pp ?? 0;
|
||||
// if PP value is less than 5, do nothing. If greater, we need to reduce the value to 5 using a negative ppUp value.
|
||||
const ppUp = pp <= 5 ? 0 : (5 - pp) / Math.max(Math.floor(pp / 5), 1);
|
||||
return new PokemonMove(m?.moveId ?? Moves.NONE, 0, ppUp);
|
||||
});
|
||||
pokemon.summonData.types = target.getTypes();
|
||||
promises.push(pokemon.updateInfo());
|
||||
|
||||
|
||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:postSummonTransform", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), targetName: target!.name, }));
|
||||
pokemon.scene.playSound("battle_anims/PRSFX- Transform");
|
||||
|
||||
pokemon.loadAssets(false).then(() => {
|
||||
promises.push(pokemon.loadAssets(false).then(() => {
|
||||
pokemon.playAnim();
|
||||
pokemon.updateInfo();
|
||||
});
|
||||
}));
|
||||
|
||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:postSummonTransform", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), targetName: target.name, }));
|
||||
await Promise.all(promises);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6643,42 +6643,49 @@ export class SuppressAbilitiesIfActedAttr extends MoveEffectAttr {
|
|||
}
|
||||
|
||||
export class TransformAttr extends MoveEffectAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
|
||||
return new Promise(resolve => {
|
||||
if (!super.apply(user, target, move, args)) {
|
||||
return resolve(false);
|
||||
}
|
||||
async apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
|
||||
if (!super.apply(user, target, move, args)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
user.summonData.speciesForm = target.getSpeciesForm();
|
||||
user.summonData.fusionSpeciesForm = target.getFusionSpeciesForm();
|
||||
user.summonData.ability = target.getAbility().id;
|
||||
user.summonData.gender = target.getGender();
|
||||
user.summonData.fusionGender = target.getFusionGender();
|
||||
const promises: Promise<void>[] = [];
|
||||
user.summonData.speciesForm = target.getSpeciesForm();
|
||||
user.summonData.fusionSpeciesForm = target.getFusionSpeciesForm();
|
||||
user.summonData.ability = target.getAbility().id;
|
||||
user.summonData.gender = target.getGender();
|
||||
user.summonData.fusionGender = target.getFusionGender();
|
||||
|
||||
// Power Trick's effect will not preserved after using Transform
|
||||
user.removeTag(BattlerTagType.POWER_TRICK);
|
||||
// Power Trick's effect will not preserved after using Transform
|
||||
user.removeTag(BattlerTagType.POWER_TRICK);
|
||||
|
||||
// Copy all stats (except HP)
|
||||
for (const s of EFFECTIVE_STATS) {
|
||||
user.setStat(s, target.getStat(s, false), false);
|
||||
}
|
||||
// Copy all stats (except HP)
|
||||
for (const s of EFFECTIVE_STATS) {
|
||||
user.setStat(s, target.getStat(s, false), false);
|
||||
}
|
||||
|
||||
// Copy all stat stages
|
||||
for (const s of BATTLE_STATS) {
|
||||
user.setStatStage(s, target.getStatStage(s));
|
||||
}
|
||||
// Copy all stat stages
|
||||
for (const s of BATTLE_STATS) {
|
||||
user.setStatStage(s, target.getStatStage(s));
|
||||
}
|
||||
|
||||
user.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m?.moveId!, m?.ppUsed, m?.ppUp)); // TODO: is this bang correct?
|
||||
user.summonData.types = target.getTypes();
|
||||
|
||||
user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoTarget", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
user.loadAssets(false).then(() => {
|
||||
user.playAnim();
|
||||
user.updateInfo();
|
||||
resolve(true);
|
||||
});
|
||||
user.summonData.moveset = target.getMoveset().map(m => {
|
||||
const pp = m?.getMove().pp ?? 0;
|
||||
// if PP value is less than 5, do nothing. If greater, we need to reduce the value to 5 using a negative ppUp value.
|
||||
const ppUp = pp <= 5 ? 0 : (5 - pp) / Math.max(Math.floor(pp / 5), 1);
|
||||
return new PokemonMove(m?.moveId!, 0, ppUp);
|
||||
});
|
||||
user.summonData.types = target.getTypes();
|
||||
promises.push(user.updateInfo());
|
||||
|
||||
user.scene.queueMessage(i18next.t("moveTriggers:transformedIntoTarget", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target) }));
|
||||
|
||||
promises.push(user.loadAssets(false).then(() => {
|
||||
user.playAnim();
|
||||
user.updateInfo();
|
||||
}));
|
||||
|
||||
await Promise.all(promises);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,7 @@ describe("Abilities - Imposter", () => {
|
|||
});
|
||||
|
||||
it("should copy species, ability, gender, all stats except HP, all stat stages, moveset, and types of target", async () => {
|
||||
await game.startBattle([
|
||||
Species.DITTO
|
||||
]);
|
||||
await game.classicMode.startBattle([ Species.DITTO ]);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
@ -78,9 +76,7 @@ describe("Abilities - Imposter", () => {
|
|||
it("should copy in-battle overridden stats", async () => {
|
||||
game.override.enemyMoveset([ Moves.POWER_SPLIT ]);
|
||||
|
||||
await game.startBattle([
|
||||
Species.DITTO
|
||||
]);
|
||||
await game.classicMode.startBattle([ Species.DITTO ]);
|
||||
|
||||
const player = game.scene.getPlayerPokemon()!;
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
|
@ -97,4 +93,18 @@ describe("Abilities - Imposter", () => {
|
|||
expect(player.getStat(Stat.SPATK, false)).toBe(avgSpAtk);
|
||||
expect(enemy.getStat(Stat.SPATK, false)).toBe(avgSpAtk);
|
||||
});
|
||||
|
||||
it("should set each move's pp to a maximum of 5", async () => {
|
||||
game.override.enemyMoveset([ Moves.SWORDS_DANCE, Moves.GROWL, Moves.SKETCH, Moves.RECOVER ]);
|
||||
|
||||
await game.classicMode.startBattle([ Species.DITTO ]);
|
||||
const player = game.scene.getPlayerPokemon()!;
|
||||
|
||||
game.move.select(Moves.TACKLE);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
player.getMoveset().forEach(move => {
|
||||
expect(move!.getMovePp()).toBeLessThanOrEqual(5);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -36,9 +36,7 @@ describe("Moves - Transform", () => {
|
|||
});
|
||||
|
||||
it("should copy species, ability, gender, all stats except HP, all stat stages, moveset, and types of target", async () => {
|
||||
await game.startBattle([
|
||||
Species.DITTO
|
||||
]);
|
||||
await game.classicMode.startBattle([ Species.DITTO ]);
|
||||
|
||||
game.move.select(Moves.TRANSFORM);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
@ -78,9 +76,7 @@ describe("Moves - Transform", () => {
|
|||
it("should copy in-battle overridden stats", async () => {
|
||||
game.override.enemyMoveset([ Moves.POWER_SPLIT ]);
|
||||
|
||||
await game.startBattle([
|
||||
Species.DITTO
|
||||
]);
|
||||
await game.classicMode.startBattle([ Species.DITTO ]);
|
||||
|
||||
const player = game.scene.getPlayerPokemon()!;
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
|
@ -97,4 +93,18 @@ describe("Moves - Transform", () => {
|
|||
expect(player.getStat(Stat.SPATK, false)).toBe(avgSpAtk);
|
||||
expect(enemy.getStat(Stat.SPATK, false)).toBe(avgSpAtk);
|
||||
});
|
||||
|
||||
it ("should set each move's pp to a maximum of 5", async () => {
|
||||
game.override.enemyMoveset([ Moves.SWORDS_DANCE, Moves.GROWL, Moves.SKETCH, Moves.RECOVER ]);
|
||||
|
||||
await game.classicMode.startBattle([ Species.DITTO ]);
|
||||
const player = game.scene.getPlayerPokemon()!;
|
||||
|
||||
game.move.select(Moves.TRANSFORM);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
player.getMoveset().forEach(move => {
|
||||
expect(move!.getMovePp()).toBeLessThanOrEqual(5);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue