mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-05 16:02:20 +02:00
Merge branch 'pagefaultgames:beta' into fix_roar_whirlwind_failing_5010
This commit is contained in:
commit
1db67ce585
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "pokemon-rogue-battle",
|
"name": "pokemon-rogue-battle",
|
||||||
"version": "1.9.1",
|
"version": "1.9.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "pokemon-rogue-battle",
|
"name": "pokemon-rogue-battle",
|
||||||
"version": "1.9.1",
|
"version": "1.9.3",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material/material-color-utilities": "^0.2.7",
|
"@material/material-color-utilities": "^0.2.7",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "pokemon-rogue-battle",
|
"name": "pokemon-rogue-battle",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.9.1",
|
"version": "1.9.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "vite",
|
"start": "vite",
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit f4b8b7b737e47eaf7e7231855d0b59f8c7c7c0f8
|
Subproject commit ee6bb371afefe4c6d872cc7765f0e0d26e630d4e
|
@ -1045,7 +1045,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
y: number,
|
y: number,
|
||||||
originX = 0.5,
|
originX = 0.5,
|
||||||
originY = 0.5,
|
originY = 0.5,
|
||||||
ignoreOverride = false,
|
ignoreOverride = true,
|
||||||
useIllusion = false,
|
useIllusion = false,
|
||||||
): Phaser.GameObjects.Container {
|
): Phaser.GameObjects.Container {
|
||||||
const container = this.add.container(x, y);
|
const container = this.add.container(x, y);
|
||||||
@ -1053,9 +1053,9 @@ export default class BattleScene extends SceneBase {
|
|||||||
|
|
||||||
const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride, useIllusion));
|
const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride, useIllusion));
|
||||||
icon.setName(`sprite-${pokemon.name}-icon`);
|
icon.setName(`sprite-${pokemon.name}-icon`);
|
||||||
icon.setFrame(pokemon.getIconId(true, useIllusion));
|
icon.setFrame(pokemon.getIconId(ignoreOverride, useIllusion));
|
||||||
// Temporary fix to show pokemon's default icon if variant icon doesn't exist
|
// Temporary fix to show pokemon's default icon if variant icon doesn't exist
|
||||||
if (icon.frame.name !== pokemon.getIconId(true, useIllusion)) {
|
if (icon.frame.name !== pokemon.getIconId(ignoreOverride, useIllusion)) {
|
||||||
console.log(`${pokemon.name}'s variant icon does not exist. Replacing with default.`);
|
console.log(`${pokemon.name}'s variant icon does not exist. Replacing with default.`);
|
||||||
const temp = pokemon.shiny;
|
const temp = pokemon.shiny;
|
||||||
pokemon.shiny = false;
|
pokemon.shiny = false;
|
||||||
@ -1071,7 +1071,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
const fusionIcon = this.add.sprite(0, 0, pokemon.getFusionIconAtlasKey(ignoreOverride, useIllusion));
|
const fusionIcon = this.add.sprite(0, 0, pokemon.getFusionIconAtlasKey(ignoreOverride, useIllusion));
|
||||||
fusionIcon.setName("sprite-fusion-icon");
|
fusionIcon.setName("sprite-fusion-icon");
|
||||||
fusionIcon.setOrigin(0.5, 0);
|
fusionIcon.setOrigin(0.5, 0);
|
||||||
fusionIcon.setFrame(pokemon.getFusionIconId(true, useIllusion));
|
fusionIcon.setFrame(pokemon.getFusionIconId(ignoreOverride, useIllusion));
|
||||||
|
|
||||||
const originalWidth = icon.width;
|
const originalWidth = icon.width;
|
||||||
const originalHeight = icon.height;
|
const originalHeight = icon.height;
|
||||||
@ -2921,7 +2921,10 @@ export default class BattleScene extends SceneBase {
|
|||||||
instant?: boolean,
|
instant?: boolean,
|
||||||
cost?: number,
|
cost?: number,
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!modifier) {
|
// We check against modifier.type to stop a bug related to loading in a pokemon that has a form change item, which prior to some patch
|
||||||
|
// that changed form change modifiers worked, had previously set the `type` field to null.
|
||||||
|
// TODO: This is not the right place to check for this; it should ideally go in a session migrator.
|
||||||
|
if (!modifier || !modifier.type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let success = false;
|
let success = false;
|
||||||
|
@ -598,7 +598,7 @@ export class Egg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getEggTier(): EggTier {
|
private getEggTier(): EggTier {
|
||||||
return speciesEggTiers[this.species];
|
return speciesEggTiers[this.species] ?? EggTier.COMMON;
|
||||||
}
|
}
|
||||||
|
|
||||||
////
|
////
|
||||||
|
@ -186,6 +186,7 @@ import {
|
|||||||
applyAllyStatMultiplierAbAttrs,
|
applyAllyStatMultiplierAbAttrs,
|
||||||
AllyStatMultiplierAbAttr,
|
AllyStatMultiplierAbAttr,
|
||||||
MoveAbilityBypassAbAttr,
|
MoveAbilityBypassAbAttr,
|
||||||
|
PreSummonAbAttr,
|
||||||
} from "#app/data/abilities/ability";
|
} from "#app/data/abilities/ability";
|
||||||
import { allAbilities } from "#app/data/data-lists";
|
import { allAbilities } from "#app/data/data-lists";
|
||||||
import type PokemonData from "#app/system/pokemon-data";
|
import type PokemonData from "#app/system/pokemon-data";
|
||||||
@ -908,19 +909,22 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
const originalWarn = console.warn;
|
const originalWarn = console.warn;
|
||||||
// Ignore warnings for missing frames, because there will be a lot
|
// Ignore warnings for missing frames, because there will be a lot
|
||||||
console.warn = () => {};
|
console.warn = () => {};
|
||||||
const battleFrameNames = globalScene.anims.generateFrameNames(this.getBattleSpriteKey(), {
|
const battleSpriteKey = this.getBattleSpriteKey(this.isPlayer(), ignoreOverride);
|
||||||
|
const battleFrameNames = globalScene.anims.generateFrameNames(battleSpriteKey, {
|
||||||
zeroPad: 4,
|
zeroPad: 4,
|
||||||
suffix: ".png",
|
suffix: ".png",
|
||||||
start: 1,
|
start: 1,
|
||||||
end: 400,
|
end: 400,
|
||||||
});
|
});
|
||||||
console.warn = originalWarn;
|
console.warn = originalWarn;
|
||||||
globalScene.anims.create({
|
if (!globalScene.anims.exists(battleSpriteKey)) {
|
||||||
key: this.getBattleSpriteKey(),
|
globalScene.anims.create({
|
||||||
frames: battleFrameNames,
|
key: battleSpriteKey,
|
||||||
frameRate: 10,
|
frames: battleFrameNames,
|
||||||
repeat: -1,
|
frameRate: 10,
|
||||||
});
|
repeat: -1,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// With everything loaded, now begin playing the animation.
|
// With everything loaded, now begin playing the animation.
|
||||||
this.playAnim();
|
this.playAnim();
|
||||||
@ -2414,8 +2418,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
const suppressAbilitiesTag = arena.getTag(
|
const suppressAbilitiesTag = arena.getTag(
|
||||||
ArenaTagType.NEUTRALIZING_GAS,
|
ArenaTagType.NEUTRALIZING_GAS,
|
||||||
) as SuppressAbilitiesTag;
|
) as SuppressAbilitiesTag;
|
||||||
|
const suppressOffField = ability.hasAttr(PreSummonAbAttr);
|
||||||
if (
|
if (
|
||||||
this.isOnField() &&
|
(this.isOnField() || suppressOffField) &&
|
||||||
suppressAbilitiesTag &&
|
suppressAbilitiesTag &&
|
||||||
!suppressAbilitiesTag.isBeingRemoved()
|
!suppressAbilitiesTag.isBeingRemoved()
|
||||||
) {
|
) {
|
||||||
@ -7859,6 +7864,11 @@ export class PokemonSummonData {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key === "moveset") {
|
||||||
|
this.moveset = value?.map((m: any) => PokemonMove.loadMove(m));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (key === "tags") {
|
if (key === "tags") {
|
||||||
// load battler tags
|
// load battler tags
|
||||||
this.tags = value.map((t: BattlerTag) => loadBattlerTag(t));
|
this.tags = value.map((t: BattlerTag) => loadBattlerTag(t));
|
||||||
|
@ -3640,7 +3640,7 @@ function getNewModifierTypeOption(
|
|||||||
}
|
}
|
||||||
tier += upgradeCount;
|
tier += upgradeCount;
|
||||||
}
|
}
|
||||||
} else if (retryCount === 10 && tier) {
|
} else if (retryCount >= 100 && tier) {
|
||||||
retryCount = 0;
|
retryCount = 0;
|
||||||
tier--;
|
tier--;
|
||||||
}
|
}
|
||||||
|
@ -206,11 +206,13 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* @throws Error if there was an unexpected hit check result
|
* @throws Error if there was an unexpected hit check result
|
||||||
*/
|
*/
|
||||||
private applyToTargets(user: Pokemon, targets: Pokemon[]): void {
|
private applyToTargets(user: Pokemon, targets: Pokemon[]): void {
|
||||||
|
let firstHit = true;
|
||||||
for (const [i, target] of targets.entries()) {
|
for (const [i, target] of targets.entries()) {
|
||||||
const [hitCheckResult, effectiveness] = this.hitChecks[i];
|
const [hitCheckResult, effectiveness] = this.hitChecks[i];
|
||||||
switch (hitCheckResult) {
|
switch (hitCheckResult) {
|
||||||
case HitCheckResult.HIT:
|
case HitCheckResult.HIT:
|
||||||
this.applyMoveEffects(target, effectiveness);
|
this.applyMoveEffects(target, effectiveness, firstHit);
|
||||||
|
firstHit = false;
|
||||||
if (isFieldTargeted(this.move)) {
|
if (isFieldTargeted(this.move)) {
|
||||||
// Stop processing other targets if the move is a field move
|
// Stop processing other targets if the move is a field move
|
||||||
return;
|
return;
|
||||||
@ -763,15 +765,12 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
* - Invoking {@linkcode applyOnTargetEffects} if the move does not hit a substitute
|
* - Invoking {@linkcode applyOnTargetEffects} if the move does not hit a substitute
|
||||||
* - Triggering form changes and emergency exit / wimp out if this is the last hit
|
* - Triggering form changes and emergency exit / wimp out if this is the last hit
|
||||||
*
|
*
|
||||||
* @param target the {@linkcode Pokemon} hit by this phase's move.
|
* @param target - the {@linkcode Pokemon} hit by this phase's move.
|
||||||
* @param effectiveness the effectiveness of the move (as previously evaluated in {@linkcode hitCheck})
|
* @param effectiveness - The effectiveness of the move (as previously evaluated in {@linkcode hitCheck})
|
||||||
|
* @param firstTarget - Whether this is the first target successfully struck by the move
|
||||||
*/
|
*/
|
||||||
protected applyMoveEffects(target: Pokemon, effectiveness: TypeDamageMultiplier): void {
|
protected applyMoveEffects(target: Pokemon, effectiveness: TypeDamageMultiplier, firstTarget: boolean): void {
|
||||||
const user = this.getUserPokemon();
|
const user = this.getUserPokemon();
|
||||||
|
|
||||||
/** The first target hit by the move */
|
|
||||||
const firstTarget = target === this.getTargets().find((_, i) => this.hitChecks[i][1] > 0);
|
|
||||||
|
|
||||||
if (isNullOrUndefined(user)) {
|
if (isNullOrUndefined(user)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -905,6 +904,14 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
|
|
||||||
target.destroySubstitute();
|
target.destroySubstitute();
|
||||||
target.lapseTag(BattlerTagType.COMMANDED);
|
target.lapseTag(BattlerTagType.COMMANDED);
|
||||||
|
|
||||||
|
// Force `lastHit` to be true if this is a multi hit move with hits left
|
||||||
|
// `hitsLeft` must be left as-is in order for the message displaying the number of hits
|
||||||
|
// to display the proper number.
|
||||||
|
// Note: When Dragon Darts' smart targeting is implemented, this logic may need to be adjusted.
|
||||||
|
if (!this.lastHit && user.turnData.hitsLeft > 1) {
|
||||||
|
this.lastHit = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,6 +13,8 @@ export class SelectBiomePhase extends BattlePhase {
|
|||||||
start() {
|
start() {
|
||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
|
globalScene.resetSeed();
|
||||||
|
|
||||||
const currentBiome = globalScene.arena.biomeType;
|
const currentBiome = globalScene.arena.biomeType;
|
||||||
const nextWaveIndex = globalScene.currentBattle.waveIndex + 1;
|
const nextWaveIndex = globalScene.currentBattle.waveIndex + 1;
|
||||||
|
|
||||||
|
@ -1110,7 +1110,7 @@ export class GameData {
|
|||||||
for (const p of sessionData.party) {
|
for (const p of sessionData.party) {
|
||||||
const pokemon = p.toPokemon() as PlayerPokemon;
|
const pokemon = p.toPokemon() as PlayerPokemon;
|
||||||
pokemon.setVisible(false);
|
pokemon.setVisible(false);
|
||||||
loadPokemonAssets.push(pokemon.loadAssets());
|
loadPokemonAssets.push(pokemon.loadAssets(false));
|
||||||
party.push(pokemon);
|
party.push(pokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ export default class PokemonData {
|
|||||||
// when loading from saved session, recover summonData.speciesFrom and form index species object
|
// when loading from saved session, recover summonData.speciesFrom and form index species object
|
||||||
// used to stay transformed on reload session
|
// used to stay transformed on reload session
|
||||||
if (this.summonData.speciesForm) {
|
if (this.summonData.speciesForm) {
|
||||||
this.summonData.speciesForm = getPokemonSpeciesForm(
|
ret.summonData.speciesForm = getPokemonSpeciesForm(
|
||||||
this.summonData.speciesForm.speciesId,
|
this.summonData.speciesForm.speciesId,
|
||||||
this.summonDataSpeciesFormIndex,
|
this.summonDataSpeciesFormIndex,
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import type { SessionSaveMigrator } from "#app/@types/SessionSaveMigrator";
|
import type { SessionSaveMigrator } from "#app/@types/SessionSaveMigrator";
|
||||||
import { Status } from "#app/data/status-effect";
|
|
||||||
import { PokemonMove } from "#app/field/pokemon";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
import type { SessionSaveData } from "#app/system/game-data";
|
import type { SessionSaveData } from "#app/system/game-data";
|
||||||
import type PokemonData from "#app/system/pokemon-data";
|
import type PokemonData from "#app/system/pokemon-data";
|
||||||
|
@ -65,7 +65,7 @@ describe("Abilities - Illusion", () => {
|
|||||||
expect(!!zorua.summonData.illusion).equals(false);
|
expect(!!zorua.summonData.illusion).equals(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("break with neutralizing gas", async () => {
|
it("breaks with neutralizing gas", async () => {
|
||||||
game.override.enemyAbility(Abilities.NEUTRALIZING_GAS);
|
game.override.enemyAbility(Abilities.NEUTRALIZING_GAS);
|
||||||
await game.classicMode.startBattle([Species.KOFFING]);
|
await game.classicMode.startBattle([Species.KOFFING]);
|
||||||
|
|
||||||
@ -74,6 +74,20 @@ describe("Abilities - Illusion", () => {
|
|||||||
expect(!!zorua.summonData.illusion).equals(false);
|
expect(!!zorua.summonData.illusion).equals(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("does not activate if neutralizing gas is active", async () => {
|
||||||
|
game.override
|
||||||
|
.enemyAbility(Abilities.NEUTRALIZING_GAS)
|
||||||
|
.ability(Abilities.ILLUSION)
|
||||||
|
.moveset(Moves.SPLASH)
|
||||||
|
.enemyMoveset(Moves.SPLASH);
|
||||||
|
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS, Species.MAGIKARP]);
|
||||||
|
|
||||||
|
game.doSwitchPokemon(1);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(game.scene.getPlayerPokemon()!.summonData.illusion).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
it("causes enemy AI to consider the illusion's type instead of the actual type when considering move effectiveness", async () => {
|
it("causes enemy AI to consider the illusion's type instead of the actual type when considering move effectiveness", async () => {
|
||||||
game.override.enemyMoveset([Moves.FLAMETHROWER, Moves.PSYCHIC, Moves.TACKLE]);
|
game.override.enemyMoveset([Moves.FLAMETHROWER, Moves.PSYCHIC, Moves.TACKLE]);
|
||||||
await game.classicMode.startBattle([Species.ZOROARK, Species.FEEBAS]);
|
await game.classicMode.startBattle([Species.ZOROARK, Species.FEEBAS]);
|
||||||
|
Loading…
Reference in New Issue
Block a user