Merge branch 'beta' into internal-pokedex

This commit is contained in:
Wlowscha 2025-01-31 00:12:49 +01:00 committed by GitHub
commit 7d4e383052
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 140 additions and 7 deletions

View File

@ -1491,6 +1491,8 @@ export default class BattleScene extends SceneBase {
return 0; // Don't give trainers Battle Bond Greninja return 0; // Don't give trainers Battle Bond Greninja
} }
return Utils.randSeedInt(2); return Utils.randSeedInt(2);
case Species.URSHIFU:
return Utils.randSeedInt(2);
case Species.ZYGARDE: case Species.ZYGARDE:
return Utils.randSeedInt(4); return Utils.randSeedInt(4);
case Species.MINIOR: case Species.MINIOR:

View File

@ -5943,12 +5943,14 @@ export function initAbilities() {
.attr(PostBattleInitFormChangeAbAttr, () => 0) .attr(PostBattleInitFormChangeAbAttr, () => 0)
.attr(PostSummonFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0)) .attr(PostSummonFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
.attr(PostTurnFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0)) .attr(PostTurnFormChangeAbAttr, p => p.formIndex % 7 + (p.getHpRatio() <= 0.5 ? 7 : 0))
.conditionalAttr(p => p.formIndex !== 7, StatusEffectImmunityAbAttr)
.conditionalAttr(p => p.formIndex !== 7, BattlerTagImmunityAbAttr, BattlerTagType.DROWSY)
.attr(UncopiableAbilityAbAttr) .attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr) .attr(UnswappableAbilityAbAttr)
.attr(UnsuppressableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr)
.attr(NoFusionAbilityAbAttr) .attr(NoFusionAbilityAbAttr)
.bypassFaint() .attr(NoTransformAbilityAbAttr)
.partial(), // Meteor form should protect against status effects and yawn .bypassFaint(),
new Ability(Abilities.STAKEOUT, 7) new Ability(Abilities.STAKEOUT, 7)
.attr(MovePowerBoostAbAttr, (user, target, move) => !!target?.turnData.switchedInThisTurn, 2), .attr(MovePowerBoostAbAttr, (user, target, move) => !!target?.turnData.switchedInThisTurn, 2),
new Ability(Abilities.WATER_BUBBLE, 7) new Ability(Abilities.WATER_BUBBLE, 7)

View File

@ -1892,7 +1892,8 @@ export class SacrificialFullRestoreAttr extends SacrificialAttr {
} }
// We don't know which party member will be chosen, so pick the highest max HP in the party // We don't know which party member will be chosen, so pick the highest max HP in the party
const maxPartyMemberHp = globalScene.getPlayerParty().map(p => p.getMaxHp()).reduce((maxHp: integer, hp: integer) => Math.max(hp, maxHp), 0); const party = user.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty();
const maxPartyMemberHp = party.map(p => p.getMaxHp()).reduce((maxHp: integer, hp: integer) => Math.max(hp, maxHp), 0);
globalScene.pushPhase( globalScene.pushPhase(
new PokemonHealPhase( new PokemonHealPhase(

View File

@ -2663,10 +2663,10 @@ export function initSpecies() {
new PokemonSpecies(Species.ROARING_MOON, 9, false, false, false, "Paradox Pokémon", Type.DRAGON, Type.DARK, 2, 380, Abilities.PROTOSYNTHESIS, Abilities.NONE, Abilities.NONE, 590, 105, 139, 71, 55, 101, 119, 10, 0, 295, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.ROARING_MOON, 9, false, false, false, "Paradox Pokémon", Type.DRAGON, Type.DARK, 2, 380, Abilities.PROTOSYNTHESIS, Abilities.NONE, Abilities.NONE, 590, 105, 139, 71, 55, 101, 119, 10, 0, 295, GrowthRate.SLOW, null, false),
new PokemonSpecies(Species.IRON_VALIANT, 9, false, false, false, "Paradox Pokémon", Type.FAIRY, Type.FIGHTING, 1.4, 35, Abilities.QUARK_DRIVE, Abilities.NONE, Abilities.NONE, 590, 74, 130, 90, 120, 60, 116, 10, 0, 295, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.IRON_VALIANT, 9, false, false, false, "Paradox Pokémon", Type.FAIRY, Type.FIGHTING, 1.4, 35, Abilities.QUARK_DRIVE, Abilities.NONE, Abilities.NONE, 590, 74, 130, 90, 120, 60, 116, 10, 0, 295, GrowthRate.SLOW, null, false),
new PokemonSpecies(Species.KORAIDON, 9, false, true, false, "Paradox Pokémon", Type.FIGHTING, Type.DRAGON, 2.5, 303, Abilities.ORICHALCUM_PULSE, Abilities.NONE, Abilities.NONE, 670, 100, 135, 115, 85, 100, 135, 3, 0, 335, GrowthRate.SLOW, null, false, false, new PokemonSpecies(Species.KORAIDON, 9, false, true, false, "Paradox Pokémon", Type.FIGHTING, Type.DRAGON, 2.5, 303, Abilities.ORICHALCUM_PULSE, Abilities.NONE, Abilities.NONE, 670, 100, 135, 115, 85, 100, 135, 3, 0, 335, GrowthRate.SLOW, null, false, false,
new PokemonForm("Apex Build", "apex-build", Type.FIGHTING, Type.DRAGON, 2.5, 303, Abilities.ORICHALCUM_PULSE, Abilities.NONE, Abilities.NONE, 670, 100, 135, 115, 85, 100, 135, 3, 0, 335, false, null, true) new PokemonForm("Apex Build", "apex-build", Type.FIGHTING, Type.DRAGON, 2.5, 303, Abilities.ORICHALCUM_PULSE, Abilities.NONE, Abilities.NONE, 670, 100, 135, 115, 85, 100, 135, 3, 0, 335, false, null, true),
), ),
new PokemonSpecies(Species.MIRAIDON, 9, false, true, false, "Paradox Pokémon", Type.ELECTRIC, Type.DRAGON, 3.5, 240, Abilities.HADRON_ENGINE, Abilities.NONE, Abilities.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, GrowthRate.SLOW, null, false, false, new PokemonSpecies(Species.MIRAIDON, 9, false, true, false, "Paradox Pokémon", Type.ELECTRIC, Type.DRAGON, 3.5, 240, Abilities.HADRON_ENGINE, Abilities.NONE, Abilities.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, GrowthRate.SLOW, null, false, false,
new PokemonForm("Ultimate Mode", "ultimate-mode", Type.ELECTRIC, Type.DRAGON, 3.5, 240, Abilities.HADRON_ENGINE, Abilities.NONE, Abilities.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, false, null, true) new PokemonForm("Ultimate Mode", "ultimate-mode", Type.ELECTRIC, Type.DRAGON, 3.5, 240, Abilities.HADRON_ENGINE, Abilities.NONE, Abilities.NONE, 670, 100, 85, 100, 135, 115, 135, 3, 0, 335, false, null, true),
), ),
new PokemonSpecies(Species.WALKING_WAKE, 9, false, false, false, "Paradox Pokémon", Type.WATER, Type.DRAGON, 3.5, 280, Abilities.PROTOSYNTHESIS, Abilities.NONE, Abilities.NONE, 590, 99, 83, 91, 125, 83, 109, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Gouging Fire and Raging Bolt new PokemonSpecies(Species.WALKING_WAKE, 9, false, false, false, "Paradox Pokémon", Type.WATER, Type.DRAGON, 3.5, 280, Abilities.PROTOSYNTHESIS, Abilities.NONE, Abilities.NONE, 590, 99, 83, 91, 125, 83, 109, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Gouging Fire and Raging Bolt
new PokemonSpecies(Species.IRON_LEAVES, 9, false, false, false, "Paradox Pokémon", Type.GRASS, Type.PSYCHIC, 1.5, 125, Abilities.QUARK_DRIVE, Abilities.NONE, Abilities.NONE, 590, 90, 130, 88, 70, 108, 104, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Iron Boulder and Iron Crown new PokemonSpecies(Species.IRON_LEAVES, 9, false, false, false, "Paradox Pokémon", Type.GRASS, Type.PSYCHIC, 1.5, 125, Abilities.QUARK_DRIVE, Abilities.NONE, Abilities.NONE, 590, 90, 130, 88, 70, 108, 104, 10, 0, 295, GrowthRate.SLOW, null, false), //Custom Catchrate, matching Iron Boulder and Iron Crown

View File

@ -1,4 +1,5 @@
import { Status } from "#app/data/status-effect"; import { Status } from "#app/data/status-effect";
import { BattlerTagType } from "#app/enums/battler-tag-type";
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { Abilities } from "#enums/abilities"; import { Abilities } from "#enums/abilities";
@ -29,7 +30,7 @@ describe("Abilities - SHIELDS DOWN", () => {
game.override.battleType("single"); game.override.battleType("single");
game.override.ability(Abilities.SHIELDS_DOWN); game.override.ability(Abilities.SHIELDS_DOWN);
game.override.moveset([ moveToUse ]); game.override.moveset([ moveToUse ]);
game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); game.override.enemyMoveset([ Moves.TACKLE ]);
}); });
test( test(
@ -42,7 +43,7 @@ describe("Abilities - SHIELDS DOWN", () => {
[Species.MINIOR]: coreForm, [Species.MINIOR]: coreForm,
}); });
await game.startBattle([ Species.MAGIKARP, Species.MINIOR ]); await game.classicMode.startBattle([ Species.MAGIKARP, Species.MINIOR ]);
const minior = game.scene.getPlayerParty().find((p) => p.species.speciesId === Species.MINIOR)!; const minior = game.scene.getPlayerParty().find((p) => p.species.speciesId === Species.MINIOR)!;
expect(minior).not.toBe(undefined); expect(minior).not.toBe(undefined);
@ -61,4 +62,131 @@ describe("Abilities - SHIELDS DOWN", () => {
expect(minior.formIndex).toBe(meteorForm); expect(minior.formIndex).toBe(meteorForm);
}, },
); );
test("should ignore non-volatile status moves",
async () => {
game.override.enemyMoveset([ Moves.SPORE ]);
await game.classicMode.startBattle([ Species.MINIOR ]);
game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
expect(game.scene.getPlayerPokemon()!.status).toBe(undefined);
}
);
test("should still ignore non-volatile status moves used by a pokemon with mold breaker",
async () => {
game.override.enemyAbility(Abilities.MOLD_BREAKER);
game.override.enemyMoveset([ Moves.SPORE ]);
await game.classicMode.startBattle([ Species.MINIOR ]);
game.move.select(Moves.SPLASH);
await game.forceEnemyMove(Moves.SPORE);
await game.phaseInterceptor.to(TurnEndPhase);
expect(game.scene.getPlayerPokemon()!.status).toBe(undefined);
}
);
test("should ignore non-volatile secondary status effects",
async() => {
game.override.enemyMoveset([ Moves.NUZZLE ]);
await game.classicMode.startBattle([ Species.MINIOR ]);
game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
expect(game.scene.getPlayerPokemon()!.status).toBe(undefined);
}
);
test("should ignore status moves even through mold breaker",
async () => {
game.override.enemyMoveset([ Moves.SPORE ]);
game.override.enemyAbility(Abilities.MOLD_BREAKER);
await game.classicMode.startBattle([ Species.MINIOR ]);
game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
expect(game.scene.getPlayerPokemon()!.status).toBe(undefined);
}
);
// toxic spikes currently does not poison flying types when gravity is in effect
test.todo("should become poisoned by toxic spikes when grounded",
async () => {
game.override.enemyMoveset([ Moves.GRAVITY, Moves.TOXIC_SPIKES, Moves.SPLASH ]);
game.override.moveset([ Moves.GRAVITY, Moves.SPLASH ]);
await game.classicMode.startBattle([ Species.MAGIKARP, Species.MINIOR ]);
// turn 1
game.move.select(Moves.GRAVITY);
await game.forceEnemyMove(Moves.TOXIC_SPIKES);
await game.toNextTurn();
// turn 2
game.doSwitchPokemon(1);
await game.forceEnemyMove(Moves.SPLASH);
await game.toNextTurn();
expect(game.scene.getPlayerPokemon()!.species.speciesId).toBe(Species.MINIOR);
expect(game.scene.getPlayerPokemon()!.species.formIndex).toBe(0);
expect(game.scene.getPlayerPokemon()!.status?.effect).toBe(StatusEffect.POISON);
}
);
test("should ignore yawn",
async () => {
game.override.enemyMoveset([ Moves.YAWN ]);
await game.classicMode.startBattle([ Species.MAGIKARP, Species.MINIOR ]);
game.move.select(Moves.SPLASH);
await game.forceEnemyMove(Moves.YAWN);
await game.phaseInterceptor.to(TurnEndPhase);
expect(game.scene.getPlayerPokemon()!.findTag( (tag ) => tag.tagType === BattlerTagType.DROWSY)).toBe(undefined);
}
);
test("should not ignore volatile status effects",
async () => {
game.override.enemyMoveset([ Moves.CONFUSE_RAY ]);
await game.classicMode.startBattle([ Species.MINIOR ]);
game.move.select(Moves.SPLASH);
await game.forceEnemyMove(Moves.CONFUSE_RAY);
await game.phaseInterceptor.to(TurnEndPhase);
expect(game.scene.getPlayerPokemon()!.findTag( (tag ) => tag.tagType === BattlerTagType.CONFUSED)).not.toBe(undefined);
}
);
// the `NoTransformAbilityAbAttr` attribute is not checked anywhere, so this test cannot pass.
test.todo("ditto should not be immune to status after transforming",
async () => {
game.override.enemySpecies(Species.DITTO);
game.override.enemyAbility(Abilities.IMPOSTER);
game.override.moveset([ Moves.SPLASH, Moves.SPORE ]);
await game.classicMode.startBattle([ Species.MINIOR ]);
game.move.select(Moves.SPORE);
await game.forceEnemyMove(Moves.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
expect(game.scene.getEnemyPokemon()!.status?.effect).toBe(StatusEffect.SLEEP);
}
);
}); });