diff --git a/public/battle-anims/encounter-magma-spout.json b/public/battle-anims/encounter-magma-spout.json index 961c5ab86bf..9e0acea61fa 100644 --- a/public/battle-anims/encounter-magma-spout.json +++ b/public/battle-anims/encounter-magma-spout.json @@ -2,32 +2,6 @@ "graphic": "PRAS- Magma Storm", "frames": [ [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -37,7 +11,7 @@ "target": 2, "graphicFrame": 0, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -49,7 +23,7 @@ "target": 2, "graphicFrame": 0, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -65,32 +39,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -100,7 +48,7 @@ "target": 2, "graphicFrame": 1, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -112,7 +60,7 @@ "target": 2, "graphicFrame": 1, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -128,32 +76,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -163,7 +85,7 @@ "target": 2, "graphicFrame": 2, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -175,7 +97,7 @@ "target": 2, "graphicFrame": 2, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -191,32 +113,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -226,7 +122,7 @@ "target": 2, "graphicFrame": 3, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -238,7 +134,7 @@ "target": 2, "graphicFrame": 3, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -254,32 +150,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -289,7 +159,7 @@ "target": 2, "graphicFrame": 4, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -301,7 +171,7 @@ "target": 2, "graphicFrame": 4, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -317,32 +187,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -352,7 +196,7 @@ "target": 2, "graphicFrame": 5, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -364,7 +208,7 @@ "target": 2, "graphicFrame": 5, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -380,38 +224,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 28, - -29, - -29, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -421,7 +233,7 @@ "target": 2, "graphicFrame": 6, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -433,7 +245,7 @@ "target": 2, "graphicFrame": 6, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -449,38 +261,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 56, - -57, - -57, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -490,7 +270,7 @@ "target": 2, "graphicFrame": 7, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -502,7 +282,7 @@ "target": 2, "graphicFrame": 7, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -518,38 +298,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 85, - -85, - -85, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 120, "y": -56, @@ -559,7 +307,7 @@ "target": 2, "graphicFrame": 8, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -586,38 +334,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 113, - -114, - -114, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 140, "y": -64, @@ -627,7 +343,7 @@ "target": 2, "graphicFrame": 9, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -650,43 +366,11 @@ "target": 2, "graphicFrame": 9, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 141, - -142, - -142, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 152, "y": -76, @@ -718,43 +402,11 @@ "target": 2, "graphicFrame": 10, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 170, - -170, - -170, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 136, "y": -96, @@ -775,7 +427,7 @@ "target": 2, "graphicFrame": 7, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -787,43 +439,11 @@ "target": 2, "graphicFrame": 7, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 198, - -199, - -199, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 108, "y": -92, @@ -833,7 +453,7 @@ "target": 2, "graphicFrame": 8, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -845,7 +465,7 @@ "target": 2, "graphicFrame": 8, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -861,38 +481,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 226, - -227, - -227, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 100, "y": -76, @@ -902,7 +490,7 @@ "target": 2, "graphicFrame": 9, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -929,38 +517,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 255, - -255, - -255, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 100.5, "y": -70, @@ -970,7 +526,7 @@ "target": 2, "graphicFrame": 10, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -993,43 +549,11 @@ "target": 2, "graphicFrame": 10, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 223, - -224, - -224, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -1039,7 +563,7 @@ "target": 2, "graphicFrame": 6, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1051,7 +575,7 @@ "target": 2, "graphicFrame": 6, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1067,38 +591,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 191, - -192, - -192, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -1108,7 +600,7 @@ "target": 2, "graphicFrame": 5, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1120,7 +612,7 @@ "target": 2, "graphicFrame": 5, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1136,38 +628,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 159, - -160, - -160, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -1177,7 +637,7 @@ "target": 2, "graphicFrame": 4, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1189,7 +649,7 @@ "target": 2, "graphicFrame": 4, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1205,38 +665,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 127, - -128, - -128, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -1246,7 +674,7 @@ "target": 2, "graphicFrame": 3, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1258,7 +686,7 @@ "target": 2, "graphicFrame": 3, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1274,38 +702,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 95, - -96, - -96, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -1315,7 +711,7 @@ "target": 2, "graphicFrame": 2, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1327,7 +723,7 @@ "target": 2, "graphicFrame": 2, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1343,38 +739,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 63, - -64, - -64, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -1384,7 +748,7 @@ "target": 2, "graphicFrame": 1, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1396,7 +760,7 @@ "target": 2, "graphicFrame": 1, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1412,38 +776,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "tone": [ - 31, - -32, - -32, - 0 - ], - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -1453,7 +785,7 @@ "target": 2, "graphicFrame": 0, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1465,7 +797,7 @@ "target": 2, "graphicFrame": 0, "opacity": 255, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1481,32 +813,6 @@ } ], [ - { - "x": 0, - "y": 0, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 0, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 2 - }, - { - "x": 128, - "y": -64, - "zoomX": 100, - "zoomY": 100, - "visible": true, - "target": 1, - "graphicFrame": 0, - "opacity": 255, - "locked": true, - "priority": 0, - "focus": 1 - }, { "x": 101, "y": -64, @@ -1516,7 +822,7 @@ "target": 2, "graphicFrame": 0, "opacity": 130, - "priority": 0, + "priority": 1, "focus": 1 }, { @@ -1528,7 +834,7 @@ "target": 2, "graphicFrame": 0, "opacity": 130, - "priority": 0, + "priority": 1, "focus": 1 }, { diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 4ebdafd3752..c0a3f0b090a 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -7,7 +7,7 @@ import {Constructor, isNullOrUndefined} from "#app/utils"; import * as Utils from "./utils"; import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, overrideModifiers, overrideHeldItems } from "./modifier/modifier"; import { PokeballType } from "./data/pokeball"; -import { initCommonAnims, initEncounterAnims, initMoveAnim, loadCommonAnimAssets, loadEncounterAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims"; +import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims"; import { Phase } from "./phase"; import { initGameSpeed } from "./system/game-speed"; import { Arena, ArenaBase } from "./field/arena"; @@ -555,7 +555,6 @@ export default class BattleScene extends SceneBase { Promise.all([ Promise.all(loadPokemonAssets), initCommonAnims(this).then(() => loadCommonAnimAssets(this, true)), - initEncounterAnims(this).then(() => loadEncounterAnimAssets(this, true)), Promise.all([ Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE ].map(m => initMoveAnim(this, m))).then(() => loadMoveAnimAssets(this, defaultMoves, true)), this.initStarterColors() ]).then(() => { diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index 1643852f922..f832318fc4b 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -6,6 +6,7 @@ import * as Utils from "../utils"; import { BattlerIndex } from "../battle"; import { Element } from "json-stable-stringify"; import { Moves } from "#enums/moves"; +import { isNullOrUndefined } from "../utils"; //import fs from 'vite-plugin-fs/browser'; export enum AnimFrameTarget { @@ -307,7 +308,7 @@ abstract class AnimTimedEvent { this.resourceName = resourceName; } - abstract execute(scene: BattleScene, battleAnim: BattleAnim): integer; + abstract execute(scene: BattleScene, battleAnim: BattleAnim, priority?: number): integer; abstract getEventType(): string; } @@ -325,7 +326,7 @@ class AnimTimedSoundEvent extends AnimTimedEvent { } } - execute(scene: BattleScene, battleAnim: BattleAnim): integer { + execute(scene: BattleScene, battleAnim: BattleAnim, priority?: number): integer { const soundConfig = { rate: (this.pitch * 0.01), volume: (this.volume * 0.01) }; if (this.resourceName) { try { @@ -387,7 +388,7 @@ class AnimTimedUpdateBgEvent extends AnimTimedBgEvent { super(frameIndex, resourceName, source); } - execute(scene: BattleScene, moveAnim: MoveAnim): integer { + execute(scene: BattleScene, moveAnim: MoveAnim, priority?: number): integer { const tweenProps = {}; if (this.bgX !== undefined) { tweenProps["x"] = (this.bgX * 0.5) - 320; @@ -417,7 +418,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent { super(frameIndex, resourceName, source); } - execute(scene: BattleScene, moveAnim: MoveAnim): integer { + execute(scene: BattleScene, moveAnim: MoveAnim, priority?: number): integer { if (moveAnim.bgSprite) { moveAnim.bgSprite.destroy(); } @@ -429,7 +430,9 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent { moveAnim.bgSprite.setAlpha(this.opacity / 255); scene.field.add(moveAnim.bgSprite); const fieldPokemon = scene.getEnemyPokemon() || scene.getPlayerPokemon(); - if (fieldPokemon?.isOnField()) { + if (!isNullOrUndefined(priority)) { + scene.field.moveTo(moveAnim.bgSprite as Phaser.GameObjects.GameObject, priority); + } else if (fieldPokemon?.isOnField()) { scene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon); } @@ -517,14 +520,18 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise { }); } -export function initEncounterAnims(scene: BattleScene): Promise { +export function initEncounterAnims(scene: BattleScene, anims: EncounterAnim | EncounterAnim[]): Promise { + anims = anims instanceof Array ? anims : [anims]; return new Promise(resolve => { const encounterAnimNames = Utils.getEnumKeys(EncounterAnim); const encounterAnimIds = Utils.getEnumValues(EncounterAnim); const encounterAnimFetches = []; - for (let ea = 0; ea < encounterAnimIds.length; ea++) { - const encounterAnimId = encounterAnimIds[ea]; - encounterAnimFetches.push(scene.cachedFetch(`./battle-anims/encounter-${encounterAnimNames[ea].toLowerCase().replace(/\_/g, "-")}.json`) + for (const anim of anims) { + if (encounterAnims.has(anim) && !isNullOrUndefined(encounterAnims.get(anim))) { + continue; + } + const encounterAnimId = encounterAnimIds[anim]; + encounterAnimFetches.push(scene.cachedFetch(`./battle-anims/encounter-${encounterAnimNames[anim].toLowerCase().replace(/\_/g, "-")}.json`) .then(response => response.json()) .then(cas => encounterAnims.set(encounterAnimId, new AnimConfig(cas)))); } @@ -1005,18 +1012,13 @@ export abstract class BattleAnim { }); } - private getGraphicFrameDataWithoutTarget(scene: BattleScene, frames: AnimFrame[], targetInitialX: number, targetInitialY: number): Map> { + private getGraphicFrameDataWithoutTarget(frames: AnimFrame[], targetInitialX: number, targetInitialY: number): Map> { const ret: Map> = new Map([ [AnimFrameTarget.GRAPHIC, new Map() ], [AnimFrameTarget.USER, new Map() ], [AnimFrameTarget.TARGET, new Map() ] ]); - const userInitialX = 0; - const userInitialY = 0; - const userHalfHeight = 30; - const targetHalfHeight = 30; - let g = 0; let u = 0; let t = 0; @@ -1024,27 +1026,10 @@ export abstract class BattleAnim { for (const frame of frames) { let x = frame.x; let y = frame.y; - let scaleX = (frame.zoomX / 100) * (!frame.mirror ? 1 : -1); + const scaleX = (frame.zoomX / 100) * (!frame.mirror ? 1 : -1); const scaleY = (frame.zoomY / 100); - switch (frame.focus) { - case AnimFocus.TARGET: - x += targetInitialX - targetFocusX; - y += (targetInitialY - targetHalfHeight) - targetFocusY; - break; - case AnimFocus.USER: - x += userInitialX - userFocusX; - y += (userInitialY - userHalfHeight) - userFocusY; - break; - case AnimFocus.USER_TARGET: - const point = transformPoint(this.srcLine[0], this.srcLine[1], this.srcLine[2], this.srcLine[3], - this.dstLine[0], this.dstLine[1] - userHalfHeight, this.dstLine[2], this.dstLine[3] - targetHalfHeight, x, y); - x = point[0]; - y = point[1]; - if (frame.target === AnimFrameTarget.GRAPHIC && isReversed(this.srcLine[0], this.srcLine[2], this.dstLine[0], this.dstLine[2])) { - scaleX = scaleX * -1; - } - break; - } + x += targetInitialX; + y += targetInitialY; const angle = -frame.angle; const key = frame.target === AnimFrameTarget.GRAPHIC ? g++ : frame.target === AnimFrameTarget.USER ? u++ : t++; ret.get(frame.target).set(key, { x: x, y: y, scaleX: scaleX, scaleY: scaleY, angle: angle }); @@ -1053,7 +1038,20 @@ export abstract class BattleAnim { return ret; } - playWithoutTargets(scene: BattleScene, targetInitialX: number, targetInitialY: number, frameTimeMult: number, callback?: Function) { + /** + * + * @param scene + * @param targetInitialX + * @param targetInitialY + * @param frameTimeMult + * @param frameTimedEventPriority + * - 0 is behind all other sprites (except BG) + * - 1 on top of player field + * - 3 is on top of both fields + * - 5 is on top of player sprite + * @param callback + */ + playWithoutTargets(scene: BattleScene, targetInitialX: number, targetInitialY: number, frameTimeMult: number, frameTimedEventPriority?: 0 | 1 | 3 | 5, callback?: Function) { const spriteCache: SpriteCache = { [AnimFrameTarget.GRAPHIC]: [], [AnimFrameTarget.USER]: [], @@ -1087,12 +1085,17 @@ export abstract class BattleAnim { let r = anim.frames.length; let f = 0; + const fieldSprites = scene.field.getAll(); + const playerFieldSprite = fieldSprites[1]; + const enemyFieldSprite = fieldSprites[3]; + const trainerSprite = fieldSprites[5]; + scene.tweens.addCounter({ duration: Utils.getFrameMs(3) * frameTimeMult, repeat: anim.frames.length, onRepeat: () => { const spriteFrames = anim.frames[f]; - const frameData = this.getGraphicFrameDataWithoutTarget(scene, anim.frames[f], targetInitialX, targetInitialY); + const frameData = this.getGraphicFrameDataWithoutTarget(anim.frames[f], targetInitialX, targetInitialY); const u = 0; const t = 0; let g = 0; @@ -1116,13 +1119,29 @@ export abstract class BattleAnim { spritePriorities[graphicIndex] = frame.priority; const setSpritePriority = (priority: integer) => { if (priority < 0) { - // Move to top of scene + // Move to top of scene scene.field.moveTo(moveSprite, scene.field.getAll().length - 1); - } else if (priority < scene.field.getAll().length) { - // Indexes of field: - // 0 is scene background - // 1 is enemy field - scene.field.moveTo(moveSprite, priority); + } else if (priority === 1) { + // Move above player field + if (playerFieldSprite) { + scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, playerFieldSprite); + } else { + setSpritePriority(-1); + } + } else if (priority === 3) { + // Move above player enemy field + if (enemyFieldSprite) { + scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, enemyFieldSprite); + } else { + setSpritePriority(-1); + } + } else if (priority === 5) { + // Move above player trainer sprite + if (trainerSprite) { + scene.field.moveAbove(moveSprite as Phaser.GameObjects.GameObject, trainerSprite); + } else { + setSpritePriority(-1); + } } else { setSpritePriority(-1); } @@ -1143,7 +1162,7 @@ export abstract class BattleAnim { } if (anim.frameTimedEvents.has(f)) { for (const event of anim.frameTimedEvents.get(f)) { - r = Math.max((anim.frames.length - f) + event.execute(scene, this), r); + r = Math.max((anim.frames.length - f) + event.execute(scene, this, frameTimedEventPriority), r); } } const targets = Utils.getEnumValues(AnimFrameTarget); diff --git a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts index 84cf0d9ae7f..df637aa4cfd 100644 --- a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts +++ b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts @@ -1,5 +1,5 @@ import { EncounterOptionMode, MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; -import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, initCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { modifierTypes, } from "#app/modifier/modifier-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "../../../battle-scene"; @@ -12,7 +12,7 @@ import { Type } from "#app/data/type"; import { BattlerIndex } from "#app/battle"; import { PokemonMove } from "#app/field/pokemon"; import { Moves } from "#enums/moves"; -import { EncounterAnim, EncounterBattleAnim, initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; +import { EncounterAnim, EncounterBattleAnim } from "#app/data/battle-anims"; import { WeatherType } from "#app/data/weather"; import { randSeedInt } from "#app/utils"; @@ -27,6 +27,7 @@ export const FieryFalloutEncounter: IMysteryEncounter = .withSceneWaveRangeRequirement(40, 180) // waves 10 to 180 .withCatchAllowed(true) .withIntroSpriteConfigs([]) // Set in onInit() + .withAnimations(EncounterAnim.MAGMA_BG, EncounterAnim.MAGMA_SPOUT) .withIntroDialogue([ { text: `${namespace}_intro_message`, @@ -60,21 +61,20 @@ export const FieryFalloutEncounter: IMysteryEncounter = scene.arena.trySetWeather(WeatherType.SUNNY, true); // Load animations/sfx for Volcarona moves - Promise.all([initMoveAnim(scene, Moves.QUIVER_DANCE), initMoveAnim(scene, Moves.FIRE_SPIN)]) - .then(() => loadMoveAnimAssets(scene, [Moves.QUIVER_DANCE, Moves.FIRE_SPIN])); + initCustomMovesForEncounter(scene, [Moves.FIRE_SPIN, Moves.QUIVER_DANCE]); return true; }) .withOnVisualsStart((scene: BattleScene) => { // Play animations const background = new EncounterBattleAnim(EncounterAnim.MAGMA_BG, scene.getPlayerPokemon(), scene.getPlayerPokemon()); - background.playWithoutTargets(scene, 200, 70, 2); + background.playWithoutTargets(scene, 200, 70, 2, 3); const animation = new EncounterBattleAnim(EncounterAnim.MAGMA_SPOUT, scene.getPlayerPokemon(), scene.getPlayerPokemon()); - animation.playWithoutTargets(scene, 200, 70, 2); + animation.playWithoutTargets(scene, 100, 100, 2); const increment = 600; for (let i = 3; i < 6; i++) { scene.time.delayedCall((increment) * (i - 2), () => { - animation.playWithoutTargets(scene, 100 + randSeedInt(12) * 20, 110 - randSeedInt(10) * 15, 2); + animation.playWithoutTargets(scene, randSeedInt(12) * 15, 150 - randSeedInt(10) * 15, 2); }); } diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts index d68e912fdff..efad93e2f28 100644 --- a/src/data/mystery-encounters/mystery-encounter.ts +++ b/src/data/mystery-encounters/mystery-encounter.ts @@ -19,6 +19,7 @@ import { WaveRangeRequirement } from "./mystery-encounter-requirements"; import { BattlerIndex } from "#app/battle"; +import { EncounterAnim } from "#app/data/battle-anims"; export enum MysteryEncounterVariant { DEFAULT, @@ -57,6 +58,7 @@ export default interface IMysteryEncounter { * Optional params */ encounterTier?: MysteryEncounterTier; + encounterAnimations?: EncounterAnim[]; hideBattleIntroMessage?: boolean; hideIntroVisuals?: boolean; catchAllowed?: boolean; @@ -193,13 +195,6 @@ export default class IMysteryEncounter implements IMysteryEncounter { const secReqs = this.meetsSecondaryRequirementAndSecondaryPokemonSelected(scene); // secondary is checked first to handle cases of primary overlapping with secondary const priReqs = this.meetsPrimaryRequirementAndPrimaryPokemonSelected(scene); - // console.log("-------" + MysteryEncounterType[this.encounterType] + " Encounter Check -------"); - // console.log(this); - // console.log( "sceneCheck: " + sceneReq); - // console.log( "primaryCheck: " + priReqs); - // console.log( "secondaryCheck: " + secReqs); - // console.log(MysteryEncounterTier[this.encounterTier]); - return sceneReq && secReqs && priReqs; } @@ -377,6 +372,7 @@ export class MysteryEncounterBuilder implements Partial { dialogue?: MysteryEncounterDialogue; encounterTier?: MysteryEncounterTier; + encounterAnimations?: EncounterAnim[]; requirements?: EncounterSceneRequirement[] = []; primaryPokemonRequirements?: EncounterPokemonRequirement[] = []; secondaryPokemonRequirements ?: EncounterPokemonRequirement[] = []; @@ -471,6 +467,16 @@ export class MysteryEncounterBuilder implements Partial { return Object.assign(this, { encounterTier: encounterTier }); } + /** + * Defines any EncounterAnim animations that are intended to be used during the encounter + * @param encounterAnimations + * @returns + */ + withAnimations(...encounterAnimations: EncounterAnim[]): this & Required> { + encounterAnimations = encounterAnimations instanceof Array ? encounterAnimations : [encounterAnimations]; + return Object.assign(this, { encounterAnimations: encounterAnimations }); + } + /** * Sets the maximum number of times that an encounter can spawn in a given Classic run * @param maxAllowedEncounters diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index 0aae84a7a8a..ba6a154abd9 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -26,6 +26,8 @@ import * as Overrides from "#app/overrides"; import MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option"; import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { Gender } from "#app/data/gender"; +import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; +import { Moves } from "#enums/moves"; export class EnemyPokemonConfig { species: PokemonSpecies; @@ -230,6 +232,20 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig: } } +/** + * Load special move animations/sfx for hard-coded encounter-specific moves that a pokemon uses at the start of an encounter + * See: [startOfBattleEffects](IMysteryEncounter.startOfBattleEffects) for more details + * + * This promise does not need to be awaited on if called in an encounter onInit (will just load lazily) + * @param scene + * @param moves + */ +export function initCustomMovesForEncounter(scene: BattleScene, moves: Moves | Moves[]) { + moves = moves instanceof Array ? moves : [moves]; + return Promise.all(moves.map(move => initMoveAnim(scene, move))) + .then(() => loadMoveAnimAssets(scene, moves)); +} + /** * Will update player money, and animate change (sound optional) * @param scene - Battle Scene diff --git a/src/phases.ts b/src/phases.ts index 6465d573622..015a97ca115 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -9,7 +9,7 @@ import { Stat } from "./data/pokemon-stat"; import { BerryModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HitHealModifier, IvScannerModifier, LapsingPersistentModifier, LapsingPokemonHeldItemModifier, MapModifier, Modifier, MoneyInterestModifier, MoneyMultiplierModifier, MultipleParticipantExpBonusModifier, overrideHeldItems, overrideModifiers, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, TurnStatusEffectModifier } from "./modifier/modifier"; import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler"; import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball"; -import { CommonAnim, CommonBattleAnim, initMoveAnim, loadMoveAnimAssets, MoveAnim } from "./data/battle-anims"; +import { CommonAnim, CommonBattleAnim, initEncounterAnims, initMoveAnim, loadEncounterAnimAssets, loadMoveAnimAssets, MoveAnim } from "./data/battle-anims"; import { getStatusEffectActivationText, getStatusEffectCatchRateMultiplier, getStatusEffectHealText, getStatusEffectObtainText, getStatusEffectOverlapText, StatusEffect } from "./data/status-effect"; import { SummaryUiMode } from "./ui/summary-ui-handler"; import EvolutionSceneHandler from "./ui/evolution-scene-handler"; @@ -832,6 +832,11 @@ export class EncounterPhase extends BattlePhase { mysteryEncounter.populateDialogueTokensFromRequirements(this.scene); }, this.scene.currentBattle.waveIndex); + // Add any special encounter animations to load + if (mysteryEncounter.encounterAnimations && mysteryEncounter.encounterAnimations.length > 0) { + loadEnemyAssets.push(initEncounterAnims(this.scene, mysteryEncounter.encounterAnimations).then(() => loadEncounterAnimAssets(this.scene, true))); + } + // Add intro visuals for mystery encounter mysteryEncounter.initIntroVisuals(this.scene); this.scene.field.add(mysteryEncounter.introVisuals); diff --git a/src/test/phases/mystery-encounter-phase.test.ts b/src/test/phases/mystery-encounter-phase.test.ts index 0ae9ad35ed7..eef252bfff2 100644 --- a/src/test/phases/mystery-encounter-phase.test.ts +++ b/src/test/phases/mystery-encounter-phase.test.ts @@ -89,8 +89,8 @@ describe("Mystery Encounter Phases", () => { expect(dialogueSpy).toHaveBeenCalledTimes(1); expect(messageSpy).toHaveBeenCalledTimes(2); expect(dialogueSpy).toHaveBeenCalledWith("What's this?", "???", null, expect.any(Function)); - expect(messageSpy).toHaveBeenCalledWith("Mysterious challengers have appeared!", null, expect.any(Function), 750, true); - expect(messageSpy).toHaveBeenCalledWith("The trainer steps forward...", null, expect.any(Function), 750, true); + expect(messageSpy).toHaveBeenCalledWith("Mysterious challengers have appeared!", null, expect.any(Function), 300, true); + expect(messageSpy).toHaveBeenCalledWith("The trainer steps forward...", null, expect.any(Function), 300, true); }); });