Merge branch 'beta' into rogue-ball-balance-fix
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
|
@ -1 +1 @@
|
|||
Subproject commit 87615556d8a2bd7eef7abac818f84423a8a13b03
|
||||
Subproject commit 71390cba88f4103d0d2273d59a6dd8340a4fa54f
|
|
@ -2453,16 +2453,19 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
|
|||
pokemon.setStatStage(s, target.getStatStage(s));
|
||||
}
|
||||
|
||||
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.moveset = target.getMoveset().map((m) => {
|
||||
if (m) {
|
||||
// If PP value is less than 5, do nothing. If greater, we need to reduce the value to 5.
|
||||
return new PokemonMove(m.moveId, 0, 0, false, Math.min(m.getMove().pp, 5));
|
||||
} else {
|
||||
console.warn(`Imposter: somehow iterating over a ${m} value when copying moveset!`);
|
||||
return new PokemonMove(Moves.NONE);
|
||||
}
|
||||
});
|
||||
pokemon.summonData.types = target.getTypes();
|
||||
promises.push(pokemon.updateInfo());
|
||||
|
||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:postSummonTransform", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), targetName: target!.name, }));
|
||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:postSummonTransform", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), targetName: target.name, }));
|
||||
pokemon.scene.playSound("battle_anims/PRSFX- Transform");
|
||||
promises.push(pokemon.loadAssets(false).then(() => {
|
||||
pokemon.playAnim();
|
||||
|
|
|
@ -6668,11 +6668,14 @@ export class TransformAttr extends MoveEffectAttr {
|
|||
user.setStatStage(s, target.getStatStage(s));
|
||||
}
|
||||
|
||||
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.moveset = target.getMoveset().map((m) => {
|
||||
if (m) {
|
||||
// If PP value is less than 5, do nothing. If greater, we need to reduce the value to 5.
|
||||
return new PokemonMove(m.moveId, 0, 0, false, Math.min(m.getMove().pp, 5));
|
||||
} else {
|
||||
console.warn(`Transform: somehow iterating over a ${m} value when copying moveset!`);
|
||||
return new PokemonMove(Moves.NONE);
|
||||
}
|
||||
});
|
||||
user.summonData.types = target.getTypes();
|
||||
promises.push(user.updateInfo());
|
||||
|
|
|
@ -1864,7 +1864,7 @@ export function initSpecies() {
|
|||
new PokemonSpecies(Species.ALOMOMOLA, 5, false, false, false, "Caring Pokémon", Type.WATER, null, 1.2, 31.6, Abilities.HEALER, Abilities.HYDRATION, Abilities.REGENERATOR, 470, 165, 75, 80, 40, 45, 65, 75, 70, 165, GrowthRate.FAST, 50, false),
|
||||
new PokemonSpecies(Species.JOLTIK, 5, false, false, false, "Attaching Pokémon", Type.BUG, Type.ELECTRIC, 0.1, 0.6, Abilities.COMPOUND_EYES, Abilities.UNNERVE, Abilities.SWARM, 319, 50, 47, 50, 57, 50, 65, 190, 50, 64, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.GALVANTULA, 5, false, false, false, "EleSpider Pokémon", Type.BUG, Type.ELECTRIC, 0.8, 14.3, Abilities.COMPOUND_EYES, Abilities.UNNERVE, Abilities.SWARM, 472, 70, 77, 60, 97, 60, 108, 75, 50, 165, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.FERROSEED, 5, false, false, false, "Thorn Seed Pokémon", Type.GRASS, Type.STEEL, 0.6, 18.8, Abilities.IRON_BARBS, Abilities.NONE, Abilities.IRON_BARBS, 305, 44, 50, 91, 24, 86, 10, 255, 50, 61, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.FERROSEED, 5, false, false, false, "Thorn Seed Pokémon", Type.GRASS, Type.STEEL, 0.6, 18.8, Abilities.IRON_BARBS, Abilities.NONE, Abilities.ANTICIPATION, 305, 44, 50, 91, 24, 86, 10, 255, 50, 61, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.FERROTHORN, 5, false, false, false, "Thorn Pod Pokémon", Type.GRASS, Type.STEEL, 1, 110, Abilities.IRON_BARBS, Abilities.NONE, Abilities.ANTICIPATION, 489, 74, 94, 131, 54, 116, 20, 90, 50, 171, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.KLINK, 5, false, false, false, "Gear Pokémon", Type.STEEL, null, 0.3, 21, Abilities.PLUS, Abilities.MINUS, Abilities.CLEAR_BODY, 300, 40, 55, 70, 45, 60, 30, 130, 50, 60, GrowthRate.MEDIUM_SLOW, null, false),
|
||||
new PokemonSpecies(Species.KLANG, 5, false, false, false, "Gear Pokémon", Type.STEEL, null, 0.6, 51, Abilities.PLUS, Abilities.MINUS, Abilities.CLEAR_BODY, 440, 60, 80, 95, 70, 85, 50, 60, 50, 154, GrowthRate.MEDIUM_SLOW, null, false),
|
||||
|
|
|
@ -4453,7 +4453,7 @@ export class PlayerPokemon extends Pokemon {
|
|||
this.scene.removePartyMemberModifiers(fusedPartyMemberIndex);
|
||||
this.scene.getParty().splice(fusedPartyMemberIndex, 1)[0];
|
||||
const newPartyMemberIndex = this.scene.getParty().indexOf(this);
|
||||
pokemon.getMoveset(true).map(m => this.scene.unshiftPhase(new LearnMovePhase(this.scene, newPartyMemberIndex, m!.getMove().id))); // TODO: is the bang correct?
|
||||
pokemon.getMoveset(true).map((m: PokemonMove) => this.scene.unshiftPhase(new LearnMovePhase(this.scene, newPartyMemberIndex, m.getMove().id)));
|
||||
pokemon.destroy();
|
||||
this.updateFusionPalette();
|
||||
resolve();
|
||||
|
@ -4474,8 +4474,12 @@ export class PlayerPokemon extends Pokemon {
|
|||
/** Returns a deep copy of this Pokemon's moveset array */
|
||||
copyMoveset(): PokemonMove[] {
|
||||
const newMoveset : PokemonMove[] = [];
|
||||
this.moveset.forEach(move =>
|
||||
newMoveset.push(new PokemonMove(move!.moveId, 0, move!.ppUp, move!.virtual))); // TODO: are those bangs correct?
|
||||
this.moveset.forEach((move) => {
|
||||
// TODO: refactor `moveset` to not accept `null`s
|
||||
if (move) {
|
||||
newMoveset.push(new PokemonMove(move.moveId, 0, move.ppUp, move.virtual, move.maxPpOverride));
|
||||
}
|
||||
});
|
||||
|
||||
return newMoveset;
|
||||
}
|
||||
|
@ -5202,15 +5206,22 @@ export interface DamageCalculationResult {
|
|||
**/
|
||||
export class PokemonMove {
|
||||
public moveId: Moves;
|
||||
public ppUsed: integer;
|
||||
public ppUp: integer;
|
||||
public ppUsed: number;
|
||||
public ppUp: number;
|
||||
public virtual: boolean;
|
||||
|
||||
constructor(moveId: Moves, ppUsed?: integer, ppUp?: integer, virtual?: boolean) {
|
||||
/**
|
||||
* If defined and nonzero, overrides the maximum PP of the move (e.g., due to move being copied by Transform).
|
||||
* This also nullifies all effects of `ppUp`.
|
||||
*/
|
||||
public maxPpOverride?: number;
|
||||
|
||||
constructor(moveId: Moves, ppUsed: number = 0, ppUp: number = 0, virtual: boolean = false, maxPpOverride?: number) {
|
||||
this.moveId = moveId;
|
||||
this.ppUsed = ppUsed || 0;
|
||||
this.ppUp = ppUp || 0;
|
||||
this.virtual = !!virtual;
|
||||
this.ppUsed = ppUsed;
|
||||
this.ppUp = ppUp;
|
||||
this.virtual = virtual;
|
||||
this.maxPpOverride = maxPpOverride;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5247,7 +5258,7 @@ export class PokemonMove {
|
|||
}
|
||||
|
||||
getMovePp(): integer {
|
||||
return this.getMove().pp + this.ppUp * Utils.toDmgValue(this.getMove().pp / 5);
|
||||
return this.maxPpOverride || (this.getMove().pp + this.ppUp * Utils.toDmgValue(this.getMove().pp / 5));
|
||||
}
|
||||
|
||||
getPpRatio(): number {
|
||||
|
@ -5264,6 +5275,6 @@ export class PokemonMove {
|
|||
* @return {PokemonMove} A valid pokemonmove object
|
||||
*/
|
||||
static loadMove(source: PokemonMove | any): PokemonMove {
|
||||
return new PokemonMove(source.moveId, source.ppUsed, source.ppUp, source.virtual);
|
||||
return new PokemonMove(source.moveId, source.ppUsed, source.ppUp, source.virtual, source.maxPpOverride);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -402,7 +402,7 @@ export class PokemonPpUpModifierType extends PokemonMoveModifierType {
|
|||
(_pokemon: PlayerPokemon) => {
|
||||
return null;
|
||||
}, (pokemonMove: PokemonMove) => {
|
||||
if (pokemonMove.getMove().pp < 5 || pokemonMove.ppUp >= 3) {
|
||||
if (pokemonMove.getMove().pp < 5 || pokemonMove.ppUp >= 3 || pokemonMove.maxPpOverride) {
|
||||
return PartyUiHandler.NoEffectMessage;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -2166,7 +2166,7 @@ export class PokemonPpUpModifier extends ConsumablePokemonMoveModifier {
|
|||
override apply(playerPokemon: PlayerPokemon): boolean {
|
||||
const move = playerPokemon.getMoveset()[this.moveIndex];
|
||||
|
||||
if (move) {
|
||||
if (move && !move.maxPpOverride) {
|
||||
move.ppUp = Math.min(move.ppUp + this.upPoints, 3);
|
||||
}
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ export default class PokemonData {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
this.moveset = (source.moveset || [ new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL) ]).filter(m => m).map((m: any) => new PokemonMove(m.moveId, m.ppUsed, m.ppUp));
|
||||
this.moveset = (source.moveset || [ new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL) ]).filter(m => m).map((m: any) => new PokemonMove(m.moveId, m.ppUsed, m.ppUp, m.virtual, m.maxPpOverride));
|
||||
if (!forHistory) {
|
||||
this.status = source.status
|
||||
? new Status(source.status.effect, source.status.toxicTurnCount, source.status.sleepTurnsRemaining)
|
||||
|
|
|
@ -60,18 +60,19 @@ describe("Abilities - Imposter", () => {
|
|||
const playerMoveset = player.getMoveset();
|
||||
const enemyMoveset = player.getMoveset();
|
||||
|
||||
expect(playerMoveset.length).toBe(enemyMoveset.length);
|
||||
for (let i = 0; i < playerMoveset.length && i < enemyMoveset.length; i++) {
|
||||
// TODO: Checks for 5 PP should be done here when that gets addressed
|
||||
expect(playerMoveset[i]?.moveId).toBe(enemyMoveset[i]?.moveId);
|
||||
}
|
||||
|
||||
const playerTypes = player.getTypes();
|
||||
const enemyTypes = enemy.getTypes();
|
||||
|
||||
expect(playerTypes.length).toBe(enemyTypes.length);
|
||||
for (let i = 0; i < playerTypes.length && i < enemyTypes.length; i++) {
|
||||
expect(playerTypes[i]).toBe(enemyTypes[i]);
|
||||
}
|
||||
}, 20000);
|
||||
});
|
||||
|
||||
it("should copy in-battle overridden stats", async () => {
|
||||
game.override.enemyMoveset([ Moves.POWER_SPLIT ]);
|
||||
|
@ -104,7 +105,15 @@ describe("Abilities - Imposter", () => {
|
|||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
player.getMoveset().forEach(move => {
|
||||
expect(move!.getMovePp()).toBeLessThanOrEqual(5);
|
||||
// Should set correct maximum PP without touching `ppUp`
|
||||
if (move) {
|
||||
if (move.moveId === Moves.SKETCH) {
|
||||
expect(move.getMovePp()).toBe(1);
|
||||
} else {
|
||||
expect(move.getMovePp()).toBe(5);
|
||||
}
|
||||
expect(move.ppUp).toBe(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -60,18 +60,19 @@ describe("Moves - Transform", () => {
|
|||
const playerMoveset = player.getMoveset();
|
||||
const enemyMoveset = player.getMoveset();
|
||||
|
||||
expect(playerMoveset.length).toBe(enemyMoveset.length);
|
||||
for (let i = 0; i < playerMoveset.length && i < enemyMoveset.length; i++) {
|
||||
// TODO: Checks for 5 PP should be done here when that gets addressed
|
||||
expect(playerMoveset[i]?.moveId).toBe(enemyMoveset[i]?.moveId);
|
||||
}
|
||||
|
||||
const playerTypes = player.getTypes();
|
||||
const enemyTypes = enemy.getTypes();
|
||||
|
||||
expect(playerTypes.length).toBe(enemyTypes.length);
|
||||
for (let i = 0; i < playerTypes.length && i < enemyTypes.length; i++) {
|
||||
expect(playerTypes[i]).toBe(enemyTypes[i]);
|
||||
}
|
||||
}, 20000);
|
||||
});
|
||||
|
||||
it("should copy in-battle overridden stats", async () => {
|
||||
game.override.enemyMoveset([ Moves.POWER_SPLIT ]);
|
||||
|
@ -94,7 +95,7 @@ describe("Moves - Transform", () => {
|
|||
expect(enemy.getStat(Stat.SPATK, false)).toBe(avgSpAtk);
|
||||
});
|
||||
|
||||
it ("should set each move's pp to a maximum of 5", async () => {
|
||||
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 ]);
|
||||
|
@ -104,7 +105,15 @@ describe("Moves - Transform", () => {
|
|||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
player.getMoveset().forEach(move => {
|
||||
expect(move!.getMovePp()).toBeLessThanOrEqual(5);
|
||||
// Should set correct maximum PP without touching `ppUp`
|
||||
if (move) {
|
||||
if (move.moveId === Moves.SKETCH) {
|
||||
expect(move.getMovePp()).toBe(1);
|
||||
} else {
|
||||
expect(move.getMovePp()).toBe(5);
|
||||
}
|
||||
expect(move.ppUp).toBe(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|