mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-23 07:49:36 +02:00
Merge branch 'beta' into versioning
This commit is contained in:
commit
90b28cdaa6
@ -5484,37 +5484,38 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||||||
*/
|
*/
|
||||||
const switchOutTarget = this.selfSwitch ? user : target;
|
const switchOutTarget = this.selfSwitch ? user : target;
|
||||||
if (switchOutTarget instanceof PlayerPokemon) {
|
if (switchOutTarget instanceof PlayerPokemon) {
|
||||||
|
// Switch out logic for the player's Pokemon
|
||||||
if (switchOutTarget.scene.getParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) {
|
if (switchOutTarget.scene.getParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
|
||||||
|
|
||||||
if (switchOutTarget.hp > 0) {
|
if (switchOutTarget.hp > 0) {
|
||||||
|
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||||
user.scene.prependToPhase(new SwitchPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(), true, true), MoveEndPhase);
|
user.scene.prependToPhase(new SwitchPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(), true, true), MoveEndPhase);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else if (user.scene.currentBattle.battleType !== BattleType.WILD) {
|
} else if (user.scene.currentBattle.battleType !== BattleType.WILD) {
|
||||||
|
// Switch out logic for trainer battles
|
||||||
if (switchOutTarget.scene.getEnemyParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) {
|
if (switchOutTarget.scene.getEnemyParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Switch out logic for trainer battles
|
|
||||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
|
||||||
|
|
||||||
if (switchOutTarget.hp > 0) {
|
if (switchOutTarget.hp > 0) {
|
||||||
// for opponent switching out
|
// for opponent switching out
|
||||||
|
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||||
user.scene.prependToPhase(new SwitchSummonPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(),
|
user.scene.prependToPhase(new SwitchSummonPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(),
|
||||||
(user.scene.currentBattle.trainer ? user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot) : 0),
|
(user.scene.currentBattle.trainer ? user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot) : 0),
|
||||||
false, false), MoveEndPhase);
|
false, false), MoveEndPhase);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Switch out logic for everything else (eg: WILD battles)
|
||||||
if (user.scene.currentBattle.waveIndex % 10 === 0) {
|
if (user.scene.currentBattle.waveIndex % 10 === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Switch out logic for everything else (eg: WILD battles)
|
|
||||||
switchOutTarget.leaveField(false);
|
|
||||||
|
|
||||||
if (switchOutTarget.hp) {
|
if (switchOutTarget.hp > 0) {
|
||||||
|
switchOutTarget.leaveField(false);
|
||||||
user.scene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
|
user.scene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
|
||||||
|
|
||||||
// in double battles redirect potential moves off fled pokemon
|
// in double battles redirect potential moves off fled pokemon
|
||||||
|
@ -383,7 +383,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
const battle = this.scene.currentBattle;
|
const battle = this.scene.currentBattle;
|
||||||
const template = this.getPartyTemplate();
|
const template = this.getPartyTemplate();
|
||||||
|
|
||||||
let species: PokemonSpecies;
|
let baseSpecies: PokemonSpecies;
|
||||||
if (this.config.speciesPools) {
|
if (this.config.speciesPools) {
|
||||||
const tierValue = Utils.randSeedInt(512);
|
const tierValue = Utils.randSeedInt(512);
|
||||||
let tier = tierValue >= 156 ? TrainerPoolTier.COMMON : tierValue >= 32 ? TrainerPoolTier.UNCOMMON : tierValue >= 6 ? TrainerPoolTier.RARE : tierValue >= 1 ? TrainerPoolTier.SUPER_RARE : TrainerPoolTier.ULTRA_RARE;
|
let tier = tierValue >= 156 ? TrainerPoolTier.COMMON : tierValue >= 32 ? TrainerPoolTier.UNCOMMON : tierValue >= 6 ? TrainerPoolTier.RARE : tierValue >= 1 ? TrainerPoolTier.SUPER_RARE : TrainerPoolTier.ULTRA_RARE;
|
||||||
@ -393,17 +393,17 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
tier--;
|
tier--;
|
||||||
}
|
}
|
||||||
const tierPool = this.config.speciesPools[tier];
|
const tierPool = this.config.speciesPools[tier];
|
||||||
species = getPokemonSpecies(Utils.randSeedItem(tierPool));
|
baseSpecies = getPokemonSpecies(Utils.randSeedItem(tierPool));
|
||||||
} else {
|
} else {
|
||||||
species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
|
baseSpecies = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex));
|
let ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex));
|
||||||
let retry = false;
|
let retry = false;
|
||||||
|
|
||||||
console.log(ret.getName());
|
console.log(ret.getName());
|
||||||
|
|
||||||
if (pokemonPrevolutions.hasOwnProperty(species.speciesId) && ret.speciesId !== species.speciesId) {
|
if (pokemonPrevolutions.hasOwnProperty(baseSpecies.speciesId) && ret.speciesId !== baseSpecies.speciesId) {
|
||||||
retry = true;
|
retry = true;
|
||||||
} else if (template.isBalanced(battle.enemyParty.length)) {
|
} else if (template.isBalanced(battle.enemyParty.length)) {
|
||||||
const partyMemberTypes = battle.enemyParty.map(p => p.getTypes(true)).flat();
|
const partyMemberTypes = battle.enemyParty.map(p => p.getTypes(true)).flat();
|
||||||
@ -417,7 +417,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
console.log("Attempting reroll of species evolution to fit specialty type...");
|
console.log("Attempting reroll of species evolution to fit specialty type...");
|
||||||
let evoAttempt = 0;
|
let evoAttempt = 0;
|
||||||
while (retry && evoAttempt++ < 10) {
|
while (retry && evoAttempt++ < 10) {
|
||||||
ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex));
|
ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex));
|
||||||
console.log(ret.name);
|
console.log(ret.name);
|
||||||
if (this.config.specialtyTypes.find(t => ret.isOfType(t))) {
|
if (this.config.specialtyTypes.find(t => ret.isOfType(t))) {
|
||||||
retry = false;
|
retry = false;
|
||||||
@ -426,7 +426,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prompts reroll of party member species if species already present in the enemy party
|
// Prompts reroll of party member species if species already present in the enemy party
|
||||||
if (this.checkDuplicateSpecies(ret)) {
|
if (this.checkDuplicateSpecies(ret, baseSpecies)) {
|
||||||
console.log("Duplicate species detected, prompting reroll...");
|
console.log("Duplicate species detected, prompting reroll...");
|
||||||
retry = true;
|
retry = true;
|
||||||
}
|
}
|
||||||
@ -442,13 +442,16 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
|||||||
/**
|
/**
|
||||||
* Checks if the enemy trainer already has the Pokemon species in their party
|
* Checks if the enemy trainer already has the Pokemon species in their party
|
||||||
* @param {PokemonSpecies} species {@linkcode PokemonSpecies}
|
* @param {PokemonSpecies} species {@linkcode PokemonSpecies}
|
||||||
|
* @param {PokemonSpecies} baseSpecies {@linkcode PokemonSpecies} - baseSpecies of the Pokemon if species is forced to evolve
|
||||||
* @returns `true` if the species is already present in the party
|
* @returns `true` if the species is already present in the party
|
||||||
*/
|
*/
|
||||||
checkDuplicateSpecies(species: PokemonSpecies): boolean {
|
checkDuplicateSpecies(species: PokemonSpecies, baseSpecies: PokemonSpecies): boolean {
|
||||||
|
const staticPartyPokemon = (signatureSpecies[TrainerType[this.config.trainerType]] ?? []).flat(1);
|
||||||
|
|
||||||
const currentPartySpecies = this.scene.getEnemyParty().map(p => {
|
const currentPartySpecies = this.scene.getEnemyParty().map(p => {
|
||||||
return p.species.speciesId;
|
return p.species.speciesId;
|
||||||
});
|
});
|
||||||
return currentPartySpecies.includes(species.speciesId);
|
return currentPartySpecies.includes(species.speciesId) || staticPartyPokemon.includes(baseSpecies.speciesId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPartyMemberMatchupScores(trainerSlot: TrainerSlot = TrainerSlot.NONE, forSwitch: boolean = false): [integer, integer][] {
|
getPartyMemberMatchupScores(trainerSlot: TrainerSlot = TrainerSlot.NONE, forSwitch: boolean = false): [integer, integer][] {
|
||||||
|
@ -139,4 +139,58 @@ describe("Moves - Dragon Tail", () => {
|
|||||||
|
|
||||||
expect(enemy.isFullHp()).toBe(false);
|
expect(enemy.isFullHp()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should force a switch upon fainting an opponent normally", async () => {
|
||||||
|
game.override.startingWave(5)
|
||||||
|
.startingLevel(1000); // To make sure Dragon Tail KO's the opponent
|
||||||
|
await game.classicMode.startBattle([ Species.DRATINI ]);
|
||||||
|
|
||||||
|
game.move.select(Moves.DRAGON_TAIL);
|
||||||
|
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
// Make sure the enemy switched to a healthy Pokemon
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
expect(enemy).toBeDefined();
|
||||||
|
expect(enemy.isFullHp()).toBe(true);
|
||||||
|
|
||||||
|
// Make sure the enemy has a fainted Pokemon in their party and not on the field
|
||||||
|
const faintedEnemy = game.scene.getEnemyParty().find(p => !p.isAllowedInBattle());
|
||||||
|
expect(faintedEnemy).toBeDefined();
|
||||||
|
expect(game.scene.getEnemyField().length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not cause a softlock when activating an opponent trainer's reviver seed", async () => {
|
||||||
|
game.override.startingWave(5)
|
||||||
|
.enemyHeldItems([{ name: "REVIVER_SEED" }])
|
||||||
|
.startingLevel(1000); // To make sure Dragon Tail KO's the opponent
|
||||||
|
await game.classicMode.startBattle([ Species.DRATINI ]);
|
||||||
|
|
||||||
|
game.move.select(Moves.DRAGON_TAIL);
|
||||||
|
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
// Make sure the enemy field is not empty and has a revived Pokemon
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
expect(enemy).toBeDefined();
|
||||||
|
expect(enemy.hp).toBe(Math.floor(enemy.getMaxHp() / 2));
|
||||||
|
expect(game.scene.getEnemyField().length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not cause a softlock when activating a player's reviver seed", async () => {
|
||||||
|
game.override.startingHeldItems([{ name: "REVIVER_SEED" }])
|
||||||
|
.enemyMoveset(Moves.DRAGON_TAIL)
|
||||||
|
.enemyLevel(1000); // To make sure Dragon Tail KO's the player
|
||||||
|
await game.classicMode.startBattle([ Species.DRATINI, Species.BULBASAUR ]);
|
||||||
|
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
// Make sure the player's field is not empty and has a revived Pokemon
|
||||||
|
const dratini = game.scene.getPlayerPokemon()!;
|
||||||
|
expect(dratini).toBeDefined();
|
||||||
|
expect(dratini.hp).toBe(Math.floor(dratini.getMaxHp() / 2));
|
||||||
|
expect(game.scene.getPlayerField().length).toBe(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -96,4 +96,23 @@ describe("Moves - U-turn", () => {
|
|||||||
expect(game.scene.getEnemyPokemon()!.battleData.abilityRevealed).toBe(true); // proxy for asserting ability activated
|
expect(game.scene.getEnemyPokemon()!.battleData.abilityRevealed).toBe(true); // proxy for asserting ability activated
|
||||||
expect(game.phaseInterceptor.log).not.toContain("SwitchSummonPhase");
|
expect(game.phaseInterceptor.log).not.toContain("SwitchSummonPhase");
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
|
it("still forces a switch if u-turn KO's the opponent", async () => {
|
||||||
|
game.override.startingLevel(1000); // Ensure that U-Turn KO's the opponent
|
||||||
|
await game.classicMode.startBattle([
|
||||||
|
Species.RAICHU,
|
||||||
|
Species.SHUCKLE
|
||||||
|
]);
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
// KO the opponent with U-Turn
|
||||||
|
game.move.select(Moves.U_TURN);
|
||||||
|
game.doSelectPartyPokemon(1);
|
||||||
|
await game.phaseInterceptor.to(TurnEndPhase);
|
||||||
|
expect(enemy.isFainted()).toBe(true);
|
||||||
|
|
||||||
|
// Check that U-Turn forced a switch
|
||||||
|
expect(game.phaseInterceptor.log).toContain("SwitchSummonPhase");
|
||||||
|
expect(game.scene.getPlayerPokemon()!.species.speciesId).toBe(Species.SHUCKLE);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user