Merge pull request #4754 from pagefaultgames/main

Main -> Beta (1.1.6)
This commit is contained in:
Moka 2024-10-28 17:40:48 +01:00 committed by GitHub
commit fe7d156d2d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 280 additions and 418 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "pokemon-rogue-battle",
"version": "1.1.0",
"version": "1.1.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pokemon-rogue-battle",
"version": "1.1.0",
"version": "1.1.6",
"hasInstallScript": true,
"dependencies": {
"@material/material-color-utilities": "^0.2.7",

View File

@ -1,7 +1,7 @@
{
"name": "pokemon-rogue-battle",
"private": true,
"version": "1.1.0",
"version": "1.1.6",
"type": "module",
"scripts": {
"start": "vite",

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "658-ash.png",
"format": "RGBA8888",
"size": {
"w": 79,
"h": 79
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 79,
"h": 74
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 79,
"h": 74
},
"frame": {
"x": 0,
"y": 0,
"w": 79,
"h": 74
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:936f62fa49ba4d6e402bb2e2eaf2afd0:ed00ba047a44b4bf1309bc147dd000e3:bfbf521a5c7bd80bcd95a96d9789c0dd$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 79, "h": 74 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 },
"sourceSize": { "w": 79, "h": 74 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-x64",
"format": "I8",
"size": { "w": 79, "h": 74 },
"scale": "1"
}
}

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "658.png",
"format": "RGBA8888",
"size": {
"w": 75,
"h": 75
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 75,
"h": 65
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 75,
"h": 65
},
"frame": {
"x": 0,
"y": 0,
"w": 75,
"h": 65
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:e0b10df331bd4ce6760edab61dee144b:061561c45beff89a92bf0158d065204f:5affcab976148657d36bf4ff3410f92d$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 85, "h": 67 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 85, "h": 67 },
"sourceSize": { "w": 85, "h": 67 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-x64",
"format": "I8",
"size": { "w": 85, "h": 67 },
"scale": "1"
}
}

View File

@ -5,8 +5,7 @@
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 63 },
"sourceSize": { "w": 64, "h": 63 },
"duration": 100
"sourceSize": { "w": 64, "h": 63 }
}
],
"meta": {

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "658-ash.png",
"format": "RGBA8888",
"size": {
"w": 73,
"h": 73
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 73,
"h": 69
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 73,
"h": 69
},
"frame": {
"x": 0,
"y": 0,
"w": 73,
"h": 69
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:4f38801bb3afeda5faff04bdcf6a666f:0c78ce2715e7510bf55da0a92b42661c:bfbf521a5c7bd80bcd95a96d9789c0dd$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 73, "h": 73 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 },
"sourceSize": { "w": 73, "h": 73 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-x64",
"format": "I8",
"size": { "w": 73, "h": 73 },
"scale": "1"
}
}

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "658.png",
"format": "RGBA8888",
"size": {
"w": 77,
"h": 77
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 77,
"h": 65
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 77,
"h": 65
},
"frame": {
"x": 0,
"y": 0,
"w": 77,
"h": 65
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:acdb9925f3f23b947504eec7cc28c92d:1a13d9d418f6c107bb9e5d621d9154bb:5affcab976148657d36bf4ff3410f92d$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 77, "h": 77 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 },
"sourceSize": { "w": 77, "h": 77 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-x64",
"format": "I8",
"size": { "w": 77, "h": 77 },
"scale": "1"
}
}

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "688.png",
"format": "RGBA8888",
"size": {
"w": 52,
"h": 52
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 41,
"h": 52
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 41,
"h": 52
},
"frame": {
"x": 0,
"y": 0,
"w": 41,
"h": 52
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:ea462f2b1b46327e3b8fcb7ec5e44f08:2d2598cc03dec73182dbea237ad83b34:176060351d0044923af938ba7932a6ef$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 51, "h": 65 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 51, "h": 65 },
"sourceSize": { "w": 51, "h": 65 }
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-dev",
"image": "688.png",
"format": "I8",
"size": { "w": 51, "h": 65 },
"scale": "1"
}
}

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "658-ash.png",
"format": "RGBA8888",
"size": {
"w": 73,
"h": 73
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 73,
"h": 69
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 73,
"h": 69
},
"frame": {
"x": 0,
"y": 0,
"w": 73,
"h": 69
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:d474b821316a87dfe09b397bdc2db5ef:497de0c2ec59ceba163e870b3226c76c:bfbf521a5c7bd80bcd95a96d9789c0dd$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 73, "h": 73 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 73, "h": 73 },
"sourceSize": { "w": 73, "h": 73 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-x64",
"format": "I8",
"size": { "w": 73, "h": 73 },
"scale": "1"
}
}

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "658.png",
"format": "RGBA8888",
"size": {
"w": 77,
"h": 77
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 77,
"h": 65
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 77,
"h": 65
},
"frame": {
"x": 0,
"y": 0,
"w": 77,
"h": 65
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:5891f87a78022cde3402e7d9714cc7bf:756360084290e39c139e3fef91c81759:5affcab976148657d36bf4ff3410f92d$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 77, "h": 77 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 77, "h": 77 },
"sourceSize": { "w": 77, "h": 77 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-x64",
"format": "I8",
"size": { "w": 77, "h": 77 },
"scale": "1"
}
}

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "688.png",
"format": "RGBA8888",
"size": {
"w": 52,
"h": 52
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 41,
"h": 52
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 41,
"h": 52
},
"frame": {
"x": 0,
"y": 0,
"w": 41,
"h": 52
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:0261b6c9242bba728fcfbfc515875b27:de0d9ddceed9311b33ae50ba86e969d1:176060351d0044923af938ba7932a6ef$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 51, "h": 65 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 51, "h": 65 },
"sourceSize": { "w": 51, "h": 65 }
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-dev",
"image": "688.png",
"format": "I8",
"size": { "w": 51, "h": 65 },
"scale": "1"
}
}

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "658-ash.png",
"format": "RGBA8888",
"size": {
"w": 79,
"h": 79
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 79,
"h": 74
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 79,
"h": 74
},
"frame": {
"x": 0,
"y": 0,
"w": 79,
"h": 74
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:3dd081ba5490f090a73de8423aac2f6b:f088fafaea755476f2abf488e7340cab:bfbf521a5c7bd80bcd95a96d9789c0dd$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 79, "h": 74 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 79, "h": 74 },
"sourceSize": { "w": 79, "h": 74 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-x64",
"format": "I8",
"size": { "w": 79, "h": 74 },
"scale": "1"
}
}

View File

@ -1,41 +1,19 @@
{
"textures": [
{
"image": "658.png",
"format": "RGBA8888",
"size": {
"w": 75,
"h": 75
},
"scale": 1,
"frames": [
{
"filename": "0001.png",
"rotated": false,
"trimmed": false,
"sourceSize": {
"w": 75,
"h": 65
},
"spriteSourceSize": {
"x": 0,
"y": 0,
"w": 75,
"h": 65
},
"frame": {
"x": 0,
"y": 0,
"w": 75,
"h": 65
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:be07c062265a19e890f1e2d2d1b5527d:ad4583a5a0498c496e9a93574c55ee03:5affcab976148657d36bf4ff3410f92d$"
}
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 85, "h": 67 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 85, "h": 67 },
"sourceSize": { "w": 85, "h": 67 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.7-x64",
"format": "I8",
"size": { "w": 85, "h": 67 },
"scale": "1"
}
}

View File

@ -5,8 +5,7 @@
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 63 },
"sourceSize": { "w": 64, "h": 63 },
"duration": 100
"sourceSize": { "w": 64, "h": 63 }
}
],
"meta": {

View File

@ -126,6 +126,7 @@ export class MistTag extends ArenaTag {
* Cancels the lowering of stats
* @param arena the {@linkcode Arena} containing this effect
* @param simulated `true` if the effect should be applied quietly
* @param attacker the {@linkcode Pokemon} using a move into this effect.
* @param cancelled a {@linkcode BooleanHolder} whose value is set to `true`
* to flag the stat reduction as cancelled
* @returns `true` if a stat reduction was cancelled; `false` otherwise

View File

@ -497,7 +497,7 @@ export const speciesEggTiers = {
[Species.DREEPY]: EggTier.RARE,
[Species.ZACIAN]: EggTier.LEGENDARY,
[Species.ZAMAZENTA]: EggTier.LEGENDARY,
[Species.ETERNATUS]: EggTier.COMMON,
[Species.ETERNATUS]: EggTier.LEGENDARY,
[Species.KUBFU]: EggTier.EPIC,
[Species.ZARUDE]: EggTier.EPIC,
[Species.REGIELEKI]: EggTier.EPIC,

View File

@ -544,11 +544,15 @@ export class Egg {
////
}
export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species {
const legendarySpecies = Object.entries(speciesEggTiers)
export function getValidLegendaryGachaSpecies() : Species[] {
return Object.entries(speciesEggTiers)
.filter(s => s[1] === EggTier.LEGENDARY)
.map(s => parseInt(s[0]))
.filter(s => getPokemonSpecies(s).isObtainable());
.filter(s => getPokemonSpecies(s).isObtainable() && s !== Species.ETERNATUS);
}
export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species {
const legendarySpecies = getValidLegendaryGachaSpecies();
let ret: Species;

View File

@ -44,7 +44,7 @@ document.fonts.load("16px emerald").then(() => document.fonts.load("10px pkmnems
let game;
const startGame = async () => {
const startGame = async (manifest?: any) => {
await initI18n();
const LoadingScene = (await import("./loading-scene")).LoadingScene;
const BattleScene = (await import("./battle-scene")).default;
@ -94,13 +94,15 @@ const startGame = async () => {
version: version
});
game.sound.pauseOnBlur = false;
if (manifest) {
game["manifest"] = manifest;
}
};
fetch("/manifest.json")
.then(res => res.json())
.then(jsonResponse => {
startGame();
game["manifest"] = jsonResponse.manifest;
startGame(jsonResponse.manifest);
}).catch(() => {
// Manifest not found (likely local build)
startGame();

View File

@ -65,7 +65,7 @@ export class StatStageChangePhase extends PokemonPhase {
if (!this.selfTarget && stages.value < 0) {
// TODO: add a reference to the source of the stat change to fix Infiltrator interaction
this.scene.arena.applyTagsForSide(MistTag, pokemon.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY, false, null, false, cancelled);
this.scene.arena.applyTagsForSide(MistTag, pokemon.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY, false, null, cancelled);
}
if (!cancelled.value && !this.selfTarget && stages.value < 0) {

View File

@ -205,11 +205,11 @@ export class TurnStartPhase extends FieldPhase {
}
this.scene.pushPhase(new WeatherEffectPhase(this.scene));
this.scene.pushPhase(new BerryPhase(this.scene));
/** Add a new phase to check who should be taking status damage */
this.scene.pushPhase(new CheckStatusEffectPhase(this.scene, moveOrder));
this.scene.pushPhase(new BerryPhase(this.scene));
this.scene.pushPhase(new TurnEndPhase(this.scene));
/**

View File

@ -164,7 +164,7 @@ export async function initI18n(): Promise<void> {
} else {
fileName = camelCaseToKebabCase(ns);
}
return `/locales/${lng}/${fileName}.json?v=${pkg.version}`;
return `./locales/${lng}/${fileName}.json?v=${pkg.version}`;
},
},
defaultNS: "menu",

View File

@ -1,4 +1,7 @@
import { Egg, getLegendaryGachaSpeciesForTimestamp } from "#app/data/egg";
import { speciesEggTiers } from "#app/data/balance/species-egg-tiers";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { Egg, getLegendaryGachaSpeciesForTimestamp, getValidLegendaryGachaSpecies } from "#app/data/egg";
import { allSpecies } from "#app/data/pokemon-species";
import { EggSourceType } from "#app/enums/egg-source-types";
import { EggTier } from "#app/enums/egg-type";
import { VariantTier } from "#app/enums/variant-tier";
@ -64,6 +67,12 @@ describe("Egg Generation Tests", () => {
expect(gachaSpeciesCount).toBeGreaterThan(0.4 * EGG_HATCH_COUNT);
expect(gachaSpeciesCount).toBeLessThan(0.6 * EGG_HATCH_COUNT);
});
it("should never be allowed to generate Eternatus via the legendary gacha", () => {
const validLegendaryGachaSpecies = getValidLegendaryGachaSpecies();
expect(validLegendaryGachaSpecies.every(s => speciesEggTiers[s] === EggTier.LEGENDARY)).toBe(true);
expect(validLegendaryGachaSpecies.every(s => allSpecies[s].isObtainable())).toBe(true);
expect(validLegendaryGachaSpecies.includes(Species.ETERNATUS)).toBe(false);
});
it("should hatch an Arceus. Set from species", () => {
const scene = game.scene;
const expectedSpecies = Species.ARCEUS;
@ -376,4 +385,23 @@ describe("Egg Generation Tests", () => {
expect(diffShiny).toBe(true);
expect(diffAbility).toBe(true);
});
// For now, we are using this test to detect oversights in egg tiers.
// Delete this test if the balance team rebalances species costs independently of egg tiers.
it("should have correct egg tiers based on species costs", () => {
const getExpectedEggTier = (starterCost) =>
starterCost <= 3 ? EggTier.COMMON
: starterCost <= 5 ? EggTier.RARE
: starterCost <= 7 ? EggTier.EPIC
: EggTier.LEGENDARY;
allSpecies.forEach(pokemonSpecies => {
const rootSpecies = pokemonSpecies.getRootSpeciesId();
const speciesCost = speciesStarterCosts[rootSpecies];
const expectedEggTier = getExpectedEggTier(speciesCost);
const actualEggTier = speciesEggTiers[rootSpecies];
expect(actualEggTier).toBe(expectedEggTier);
});
});
});

View File

@ -0,0 +1,49 @@
import { Stat } from "#enums/stat";
import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("Moves - Mist", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([ Moves.MIST, Moves.SPLASH ])
.ability(Abilities.BALL_FETCH)
.battleType("double")
.disableCrits()
.enemySpecies(Species.SNORLAX)
.enemyAbility(Abilities.BALL_FETCH)
.enemyMoveset(Moves.GROWL);
});
it("should prevent the user's side from having stats lowered", async () => {
await game.classicMode.startBattle([ Species.MAGIKARP, Species.FEEBAS ]);
const playerPokemon = game.scene.getPlayerField();
game.move.select(Moves.MIST, 0);
game.move.select(Moves.SPLASH, 1);
await game.phaseInterceptor.to("BerryPhase");
playerPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(0));
});
it.todo("should be ignored by opponents with Infiltrator");
});