[Feature] Add Mystery Encounters to the game (#3938)
* add .github/workflows/mystery-event.yml * update mystery-event.yml * mystery encounters: resolve review comments: Lost at Sea: -fix typo in handlePokemonGuidingYouPhase function Mysterious Chest: - remove obsolete commented code mystery-encounter.ts - remove unused `onDone` field from MysteryEncounterBuilder * fix typo in CanLearnMoveRequirementOptions * remove redundance from Pokemon.isAllowedInBattle() * chore: jsdoc formatting * fix lost-at-sea tests * add fallback for biomeMysteryEncounters if empty * lost-at-sea-encounter: fix and extend tests * move "battle:fainted" into `koPlayerPokemon` * add retries to quick-draw tests * fix lost-at-sea-encounter tests * clean up battle animation logic * Update and rename mystery-event.yml to mystery-events.yml * Update mystery-events.yml * Fix typo * Update mystery-events.yml Fix debug runs * clean up unit tests and utils * attach github issues to all encounter jsdocs * start dialogue refactor * update sleeping snorlax encounter * migrate encounters dialogue to new format * cleanup and add jsdocs * finish fiery fallout encounter * fix unit test breaks * add skeleton tests to fiery fallout * commit latest test changes * finish unit tests for fiery fallout * bug fix for empty modifier shop * stash working changes * stash changes * Update src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/test/utils/overridesHelper.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/test/utils/overridesHelper.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/test/utils/overridesHelper.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/test/utils/overridesHelper.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Update src/data/battle-anims.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * nit updates and cleanup * Update src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * add jsdocs and more cleanup * add more jsdoc * add the strong stuff encounter * add the strong stuff encounter and more unit tests * cleanup container length checks in ME ui * add retries to tests * add retries to tests * fix trainer wave disable override * add shuckle juice modifier * add dialogue bug fixes * add dialogue bug fixes * add pokemon salesman encounter and affects pokedex UI display * add unit tests for pokemon salesman * temp stash * add offer you can't refuse * add unit tests for offer you can't refuse encounter * remove unnecessary prompt handlers * add tests for disabled encounter options * add delibird-y encounter * add delibird-y encounter * add absolute avarice encounter * finish absolute avarice encounter * add unit tests and enhancements for item overrides in tests * fix unit test * cleanup absolute avarice PR * small bug fixes with latest sync from main * update visuals loading for safari and stat trainer visuals * update visuals loading for safari and stat trainer visuals * update a trainer's test encounter and add unit tests * add Trash to Treasure encounter * clean up trash to treasure encounter * clean up trash to treasure encounter * add berries abound encounter * start clowning around encounter * first implementation pass at clowning around * add unit tests for clowning around * add unit tests for clowning around * clean up ME unit tests * clean up unit tests * update unit tests * add part timer and dancing lessons encounters * add unit tests for Dancing Lessons and Part-Timer * reordered biome list and adjusted redirection for project and labels * Add Weird Dream encounter and slight reworks to Berries Abound/Fight or Flight * adjusting yml to match new labels * fix yml whoopsie * Expanded 'Weird Dream' banlist and fixed a bug with the BST bump range * adds Winstrate Challenge mystery encounter * small cleanup for winstrates * add unit tests for Winstrate Challenge * fix pokemon not returning after winstrate battle * commit latest beta merge updates * fix ME null checks and unit tests with beta update * fix ME null checks and unit tests with beta update * MEs to pokerogue beta branch * test dialogue changes * test patch fix * test patch fix * test patch fix * adds teleporting hijinks encounter * add unit tests for Teleporting Hijinks * small change to teleporting hijinks dialogue * migrate ME translations to json * add retries to berries-abound.Option1: should reward the player with X berries based on wave * add missing ME dialogue back in * revert template changes * add ME unique trainer dialogue to both dialogue jsons * fix hanging comma in json * fix broken imports * resolve lint issues * fix flaky test * balance tweaks to a few MEs, updates to bug superfan * add unit tests for Bug-Type Superfan and clean up dialogue * Adds Fun and Games mystery encounter * add unit tests for Fun and Games encounter * update jsdoc * small ME balance changes * small ME balance changes * Adds Uncommon Breed ME and misc. ME bug fixes * Update getFinalSessionData() to collect Mystery Encounter data * adds GTS encounter * various ME bug fixes and balance changes * latest ME bug fixes * clean up GTS Encounter and add unit tests * small cleanup to MEs branch * add BGM music names for ME music * bug fixes and balance changes for MEs * ME data schema updates * balance changes and bug fixes to MEs * balance changes and bug fixes to MEs * update tests for MEs * add jsdoc to party exp function * dialogue updates and test fixes for MEs * dialogue updates and test fixes for MEs * PR suggestions and fixees * stash PR feedback and bugfixes * fix all tests for MEs and cleanup * PR feedback * update flaky ME test * update tests, bug fix MEs, and sprite assets * remove unintentional console log * re-enable stubbed function for Phaser text styling * handle undefined introVisuals properly * PR feedback from NightKev * disable Uncommon Breed tests * locales updates and bug fixes for safari zone * more PR feedback and update field trip with Rarer Candy * fix unit test * Change how reroll button gets disabled in Modifier Shop Phase * update continue button text logic * Update src/ui/modifier-select-ui-handler.ts Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> * fix money formatting and some nits * more nits * more nits * update ME tsdocs with links * update ME tsdocs with links --------- Co-authored-by: Felix Staud <felix.staud@headwire.com> Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> Co-authored-by: ImperialSympathizer <imperialsympathizer@gmail.com> Co-authored-by: InnocentGameDev <asdargmng@gmail.com> Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>
|
@ -0,0 +1,951 @@
|
||||||
|
{
|
||||||
|
"id": 686,
|
||||||
|
"graphic": "PRAS- Dragon Dance",
|
||||||
|
"frames": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 4,
|
||||||
|
"y": -8,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 12,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 70,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -12,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 70,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 12,
|
||||||
|
"y": -12,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 16,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -16,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 24,
|
||||||
|
"y": -12,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -20,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 32,
|
||||||
|
"y": -8,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 24,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -24,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 36,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 28,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 70,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -28,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 70,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 36,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 36,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 32,
|
||||||
|
"y": -8,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 24,
|
||||||
|
"y": -12,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 12,
|
||||||
|
"y": -12,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 4,
|
||||||
|
"y": -8,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -4,
|
||||||
|
"y": -8,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 12,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 70,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -12,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 70,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -12,
|
||||||
|
"y": -12,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 16,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -16,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -24,
|
||||||
|
"y": -12,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -20,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -32,
|
||||||
|
"y": -8,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 24,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -24,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 155,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -36,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 28,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 70,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -28,
|
||||||
|
"y": -0.5,
|
||||||
|
"zoomX": 108,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"blendType": 1,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 70,
|
||||||
|
"tone": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -36,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -36,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -32,
|
||||||
|
"y": -8,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -24,
|
||||||
|
"y": -12,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -12,
|
||||||
|
"y": -12,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -4,
|
||||||
|
"y": -8,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 1,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"frameTimedEvents": {
|
||||||
|
"0": [
|
||||||
|
{
|
||||||
|
"frameIndex": 0,
|
||||||
|
"resourceName": "PRSFX- Attract.wav",
|
||||||
|
"volume": 100,
|
||||||
|
"pitch": 100,
|
||||||
|
"eventType": "AnimTimedSoundEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
{
|
||||||
|
"frameIndex": 0,
|
||||||
|
"resourceName": "PRSFX- Ally Switch.wav",
|
||||||
|
"volume": 80,
|
||||||
|
"pitch": 100,
|
||||||
|
"eventType": "AnimTimedSoundEvent"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"position": 4,
|
||||||
|
"hue": 0
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"frames": [
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
"frameTimedEvents": {
|
||||||
|
"0": [
|
||||||
|
{
|
||||||
|
"frameIndex": 0,
|
||||||
|
"resourceName": "PRAS- Fire BG",
|
||||||
|
"bgX": 0,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 0,
|
||||||
|
"duration": 35,
|
||||||
|
"eventType": "AnimTimedAddBgEvent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frameIndex": 0,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 0,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"duration": 12,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"25": [
|
||||||
|
{
|
||||||
|
"frameIndex": 25,
|
||||||
|
"resourceName": "",
|
||||||
|
"bgX": 0,
|
||||||
|
"bgY": 0,
|
||||||
|
"opacity": 0,
|
||||||
|
"duration": 8,
|
||||||
|
"eventType": "AnimTimedUpdateBgEvent"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"position": 1,
|
||||||
|
"hue": 0
|
||||||
|
}
|
|
@ -0,0 +1,902 @@
|
||||||
|
{
|
||||||
|
"graphic": "PRAS- Magma Storm",
|
||||||
|
"frames": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 3,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 3,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 3,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 7,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 7,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 7,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 120,
|
||||||
|
"y": -56,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 144,
|
||||||
|
"y": -84,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 100,
|
||||||
|
"y": -86.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 140,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 9,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 136,
|
||||||
|
"y": -92,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 9,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 108,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 9,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -76,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 10,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 116,
|
||||||
|
"y": -88,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 10,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -62.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 10,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 136,
|
||||||
|
"y": -96,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 7,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 100,
|
||||||
|
"y": -76,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 7,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 148,
|
||||||
|
"y": -66.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 7,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 108,
|
||||||
|
"y": -92,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 120,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 144,
|
||||||
|
"y": -86.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 100,
|
||||||
|
"y": -76,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 9,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 136,
|
||||||
|
"y": -68,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 9,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -94.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 9,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 100.5,
|
||||||
|
"y": -70,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 10,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 144,
|
||||||
|
"y": -66,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 10,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 126,
|
||||||
|
"y": -86.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 10,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 3,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 3,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 3,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 101,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 130,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 152,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 130,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 124.5,
|
||||||
|
"y": -78.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 140,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"frameTimedEvents": {
|
||||||
|
"0": [
|
||||||
|
{
|
||||||
|
"frameIndex": 0,
|
||||||
|
"resourceName": "PRSFX- Magma Storm1.wav",
|
||||||
|
"volume": 100,
|
||||||
|
"pitch": 100,
|
||||||
|
"eventType": "AnimTimedSoundEvent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"8": [
|
||||||
|
{
|
||||||
|
"frameIndex": 8,
|
||||||
|
"resourceName": "PRSFX- Magma Storm2.wav",
|
||||||
|
"volume": 100,
|
||||||
|
"pitch": 100,
|
||||||
|
"eventType": "AnimTimedSoundEvent"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"position": 1,
|
||||||
|
"hue": 0
|
||||||
|
}
|
|
@ -0,0 +1,822 @@
|
||||||
|
{
|
||||||
|
"graphic": "PRAS- Smokescreen",
|
||||||
|
"frames": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 15.5,
|
||||||
|
"y": 12.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 15.5,
|
||||||
|
"y": 8.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 15.5,
|
||||||
|
"y": 0.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -4,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 15.5,
|
||||||
|
"y": -3.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -4,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": 21.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 15.5,
|
||||||
|
"y": -7.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -8,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 7,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": 17.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 15.5,
|
||||||
|
"y": -11.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 3,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -12,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": 13.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": 21,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 15.5,
|
||||||
|
"y": -15.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -16,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": 5.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": 17,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 15.5,
|
||||||
|
"y": -19.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -20,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": 0.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": 13,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -12.5,
|
||||||
|
"y": 8.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 15.5,
|
||||||
|
"y": -23.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -24,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": -2.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": 9,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 7,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -12.5,
|
||||||
|
"y": 4.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": -6.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 3,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -28,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": 5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -12.5,
|
||||||
|
"y": 0.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 8,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": 23,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": -10.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -32,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": 1,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -12.5,
|
||||||
|
"y": -3.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 7,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": 19,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": -14.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": -36,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": -3,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -12.5,
|
||||||
|
"y": -7.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": 15,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -11,
|
||||||
|
"y": -18.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": -7,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -12.5,
|
||||||
|
"y": -11.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 6,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": 7,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 1,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -12.5,
|
||||||
|
"y": -15.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": -11,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": 3,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -12.5,
|
||||||
|
"y": -19.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 11,
|
||||||
|
"y": -15,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": -1,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 2,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": -12.5,
|
||||||
|
"y": -23.5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"mirror": true,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 5,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": -5,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 3,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": -9,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 150,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": -13,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 100,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 4.5,
|
||||||
|
"y": -17,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 2,
|
||||||
|
"graphicFrame": 4,
|
||||||
|
"opacity": 50,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 0,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 128,
|
||||||
|
"y": -64,
|
||||||
|
"zoomX": 100,
|
||||||
|
"zoomY": 100,
|
||||||
|
"visible": true,
|
||||||
|
"target": 1,
|
||||||
|
"graphicFrame": 0,
|
||||||
|
"opacity": 255,
|
||||||
|
"locked": true,
|
||||||
|
"priority": 4,
|
||||||
|
"focus": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
"frameTimedEvents": {
|
||||||
|
"0": [
|
||||||
|
{
|
||||||
|
"frameIndex": 0,
|
||||||
|
"resourceName": "PRSFX- Haze.wav",
|
||||||
|
"volume": 100,
|
||||||
|
"pitch": 85,
|
||||||
|
"eventType": "AnimTimedSoundEvent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frameIndex": 0,
|
||||||
|
"resourceName": "Explosion1.m4a",
|
||||||
|
"volume": 100,
|
||||||
|
"pitch": 85,
|
||||||
|
"eventType": "AnimTimedSoundEvent"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"position": 2,
|
||||||
|
"hue": 0
|
||||||
|
}
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 318 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 561 B |
After Width: | Height: | Size: 372 B |
After Width: | Height: | Size: 240 B |
|
@ -0,0 +1,734 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "b2w2_lady.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 399,
|
||||||
|
"h": 360
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 8,
|
||||||
|
"y": 8,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 8,
|
||||||
|
"y": 8,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 57,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 8,
|
||||||
|
"y": 8,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 114,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 9,
|
||||||
|
"y": 8,
|
||||||
|
"w": 55,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 171,
|
||||||
|
"y": 0,
|
||||||
|
"w": 55,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 8,
|
||||||
|
"w": 54,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 228,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 8,
|
||||||
|
"w": 54,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 285,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 14,
|
||||||
|
"y": 8,
|
||||||
|
"w": 52,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 342,
|
||||||
|
"y": 0,
|
||||||
|
"w": 52,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 8,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 72,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 47,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 57,
|
||||||
|
"y": 72,
|
||||||
|
"w": 47,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 47,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 114,
|
||||||
|
"y": 72,
|
||||||
|
"w": 47,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0010.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 171,
|
||||||
|
"y": 72,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0011.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 228,
|
||||||
|
"y": 72,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0012.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 285,
|
||||||
|
"y": 72,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0013.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 342,
|
||||||
|
"y": 72,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0014.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 49,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 144,
|
||||||
|
"w": 49,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0015.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 49,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 57,
|
||||||
|
"y": 144,
|
||||||
|
"w": 49,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0016.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 49,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 114,
|
||||||
|
"y": 144,
|
||||||
|
"w": 49,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0017.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 49,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 171,
|
||||||
|
"y": 144,
|
||||||
|
"w": 49,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0018.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 228,
|
||||||
|
"y": 144,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0019.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 285,
|
||||||
|
"y": 144,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0020.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 342,
|
||||||
|
"y": 144,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0021.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 8,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 216,
|
||||||
|
"w": 48,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0022.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 8,
|
||||||
|
"w": 50,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 57,
|
||||||
|
"y": 216,
|
||||||
|
"w": 50,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0023.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 18,
|
||||||
|
"y": 8,
|
||||||
|
"w": 51,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 114,
|
||||||
|
"y": 216,
|
||||||
|
"w": 51,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0024.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 18,
|
||||||
|
"y": 8,
|
||||||
|
"w": 51,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 171,
|
||||||
|
"y": 216,
|
||||||
|
"w": 51,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0025.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 15,
|
||||||
|
"y": 8,
|
||||||
|
"w": 53,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 228,
|
||||||
|
"y": 216,
|
||||||
|
"w": 53,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0026.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 8,
|
||||||
|
"w": 57,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 285,
|
||||||
|
"y": 216,
|
||||||
|
"w": 57,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0027.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 8,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 342,
|
||||||
|
"y": 216,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0028.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 8,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 288,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0029.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 9,
|
||||||
|
"y": 8,
|
||||||
|
"w": 55,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 57,
|
||||||
|
"y": 288,
|
||||||
|
"w": 55,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0030.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 8,
|
||||||
|
"y": 8,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 114,
|
||||||
|
"y": 288,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0031.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 8,
|
||||||
|
"y": 8,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 171,
|
||||||
|
"y": 288,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0032.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 8,
|
||||||
|
"y": 8,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 228,
|
||||||
|
"y": 288,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0033.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 8,
|
||||||
|
"y": 8,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 285,
|
||||||
|
"y": 288,
|
||||||
|
"w": 56,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:e7f062304401dbd7b3ec79512f0ff4cb:0136dac01331f88892a3df26aeab78f5:1ed1e22abb9b55d76337a5a599835c06$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 23 KiB |
|
@ -0,0 +1,797 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "b2w2_veteran_m.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 424,
|
||||||
|
"h": 390
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 53,
|
||||||
|
"y": 0,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 106,
|
||||||
|
"y": 0,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 159,
|
||||||
|
"y": 0,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 212,
|
||||||
|
"y": 0,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 265,
|
||||||
|
"y": 0,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 318,
|
||||||
|
"y": 0,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 371,
|
||||||
|
"y": 0,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 78,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 53,
|
||||||
|
"y": 78,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0010.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 48,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 106,
|
||||||
|
"y": 78,
|
||||||
|
"w": 48,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0011.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 50,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 159,
|
||||||
|
"y": 78,
|
||||||
|
"w": 50,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0012.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 212,
|
||||||
|
"y": 78,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0013.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 265,
|
||||||
|
"y": 78,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0014.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 52,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 318,
|
||||||
|
"y": 78,
|
||||||
|
"w": 52,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0015.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 51,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 371,
|
||||||
|
"y": 78,
|
||||||
|
"w": 51,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0016.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 52,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 156,
|
||||||
|
"w": 52,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0017.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 52,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 53,
|
||||||
|
"y": 156,
|
||||||
|
"w": 52,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0018.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 106,
|
||||||
|
"y": 156,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0019.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 159,
|
||||||
|
"y": 156,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0020.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 212,
|
||||||
|
"y": 156,
|
||||||
|
"w": 53,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0021.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 52,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 265,
|
||||||
|
"y": 156,
|
||||||
|
"w": 52,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0022.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 51,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 318,
|
||||||
|
"y": 156,
|
||||||
|
"w": 51,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0023.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 51,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 371,
|
||||||
|
"y": 156,
|
||||||
|
"w": 51,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0024.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 51,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 234,
|
||||||
|
"w": 51,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0025.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 50,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 53,
|
||||||
|
"y": 234,
|
||||||
|
"w": 50,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0026.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 48,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 106,
|
||||||
|
"y": 234,
|
||||||
|
"w": 48,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0027.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 46,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 159,
|
||||||
|
"y": 234,
|
||||||
|
"w": 46,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0028.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 46,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 212,
|
||||||
|
"y": 234,
|
||||||
|
"w": 46,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0029.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 265,
|
||||||
|
"y": 234,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0030.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 318,
|
||||||
|
"y": 234,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0031.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 371,
|
||||||
|
"y": 234,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0032.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 312,
|
||||||
|
"w": 44,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0033.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 53,
|
||||||
|
"y": 312,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0034.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 106,
|
||||||
|
"y": 312,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0035.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 159,
|
||||||
|
"y": 312,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0036.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 2,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 212,
|
||||||
|
"y": 312,
|
||||||
|
"w": 43,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:4deb068879a8ac195cb4f00c8b17b7f5:b32f0f90436649264b6f3c49b09ac06a:05e903aa75b8e50c28334d9b5e14c85a$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "bait.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 14,
|
||||||
|
"h": 43
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 12,
|
||||||
|
"h": 16
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 3,
|
||||||
|
"w": 12,
|
||||||
|
"h": 13
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 12,
|
||||||
|
"h": 13
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 12,
|
||||||
|
"h": 16
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 3,
|
||||||
|
"w": 12,
|
||||||
|
"h": 13
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 16,
|
||||||
|
"w": 12,
|
||||||
|
"h": 13
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 12,
|
||||||
|
"h": 16
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 5,
|
||||||
|
"w": 11,
|
||||||
|
"h": 11
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 31,
|
||||||
|
"w": 11,
|
||||||
|
"h": 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:f0ec04fcd67ac346dce973693711d032:b697e09191c4312b8faaa0a080a309b7:1af241a52e61fa01ca849aa03c112f85$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 277 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "berry_bush.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 49,
|
||||||
|
"h": 53
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 49,
|
||||||
|
"h": 53
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 49,
|
||||||
|
"h": 53
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 49,
|
||||||
|
"h": 53
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:d5f83625477b5f98b726343f4a3a396f:f4665258986e97345cfeee041b4b8bcf:e7781fcc447e6d12deb2af78c9493c7f$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 719 B |
|
@ -0,0 +1,19 @@
|
||||||
|
{ "frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 46, "h": 60 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"spriteSourceSize": { "x": 0, "y": 0, "w": 46, "h": 60 },
|
||||||
|
"sourceSize": { "w": 46, "h": 60 }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.aseprite.org/",
|
||||||
|
"version": "1.3.7-x64",
|
||||||
|
"image": "buoy-sheet.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": { "w": 46, "h": 60 },
|
||||||
|
"scale": "1"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "carnival_game.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 38,
|
||||||
|
"h": 82
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 38,
|
||||||
|
"h": 82
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 38,
|
||||||
|
"h": 82
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 38,
|
||||||
|
"h": 82
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:d40b6742392c2fe8ca0735b3f561e319:5dcda5410b12f0aa75eb0dd1fbcbe4f9:d171fb17d3017d1f655cd8dd14c252b7$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 517 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "carnival_man.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 50,
|
||||||
|
"h": 77
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 15,
|
||||||
|
"y": 3,
|
||||||
|
"w": 50,
|
||||||
|
"h": 77
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 50,
|
||||||
|
"h": 77
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:e80aa9a809a7cca6d05992cb82f6dbd9:ea9962edd1cdc1e503deecf2ce1863c1:55647352b6547cf03212506309f2abf5$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 833 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "carnival_wobbuffet.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 45,
|
||||||
|
"h": 55
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 45,
|
||||||
|
"h": 55
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 45,
|
||||||
|
"h": 55
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 45,
|
||||||
|
"h": 55
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:879de17da906ea52e5a71afacb88fcf6:90f64e8eaac4ff1e67373f60c3d98d36:a090cb3294ca1218a4f90ecb97df81d7$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 772 B |
|
@ -0,0 +1,209 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "chest_blue.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 492
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 47,
|
||||||
|
"h": 35
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 47,
|
||||||
|
"h": 35
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 39,
|
||||||
|
"w": 47,
|
||||||
|
"h": 35
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 74,
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 46,
|
||||||
|
"h": 46
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 46,
|
||||||
|
"h": 46
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 113,
|
||||||
|
"w": 46,
|
||||||
|
"h": 46
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 53,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 53,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 159,
|
||||||
|
"w": 53,
|
||||||
|
"h": 65
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 224,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 291,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 358,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 425,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:017ecc2437e580a185f9843f97e80da5:f44ef1c27a4a17183a5bcf1f7fc8ce6a:f4f3c064e6c93b8d1290f93bee927f60$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 2.5 KiB |
|
@ -0,0 +1,209 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "chest_red.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 492
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 47,
|
||||||
|
"h": 35
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 47,
|
||||||
|
"h": 35
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 39,
|
||||||
|
"w": 47,
|
||||||
|
"h": 35
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 74,
|
||||||
|
"w": 46,
|
||||||
|
"h": 39
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 46,
|
||||||
|
"h": 46
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 46,
|
||||||
|
"h": 46
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 113,
|
||||||
|
"w": 46,
|
||||||
|
"h": 46
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 53,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 53,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 159,
|
||||||
|
"w": 53,
|
||||||
|
"h": 65
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 224,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 291,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 358,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 425,
|
||||||
|
"w": 54,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:2a0b6c93c5be115efa635d40780603f0:b5fde49f991c2ecc49afedd80cc8a544:a163d960e9966469ae4dde4b53c13496$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 2.5 KiB |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "dark_deal_porygon.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 36,
|
||||||
|
"h": 45
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 36,
|
||||||
|
"h": 45
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 44,
|
||||||
|
"h": 44
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 36,
|
||||||
|
"h": 45
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:895f0a79b89fa0fb44167f4584fd9a22:357b46953b7e17c6b2f43a62d52855d8:cc1ed0e4f90aaa9dcf1b39a0af1283b0$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 255 B |
After Width: | Height: | Size: 378 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "global_trade_system.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 77,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 77,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 77,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 77,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:8a51d7a17b3d8c32f0e5e4a0f15daeb4:6eba29c5345847f735d8b69a05fc49d1:98ad8b8b8d8c4865d7d23ec97b516594$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "mad_scientist_m.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 46,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 44,
|
||||||
|
"h": 74
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 44,
|
||||||
|
"h": 74
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 74
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:a7f8ff2bbb362868f51125c254eb6681:cf76e61ddd31a8f46af67ced168c44a2:4fc09abe16c0608828269e5da81d0744$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 920 B |
|
@ -0,0 +1,104 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "mud.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 14,
|
||||||
|
"h": 68
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 12,
|
||||||
|
"h": 20
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 12,
|
||||||
|
"h": 13
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 12,
|
||||||
|
"h": 13
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 12,
|
||||||
|
"h": 20
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 12,
|
||||||
|
"h": 14
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 16,
|
||||||
|
"w": 12,
|
||||||
|
"h": 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 12,
|
||||||
|
"h": 20
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 1,
|
||||||
|
"w": 12,
|
||||||
|
"h": 16
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 32,
|
||||||
|
"w": 12,
|
||||||
|
"h": 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 12,
|
||||||
|
"h": 20
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 3,
|
||||||
|
"w": 12,
|
||||||
|
"h": 17
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 50,
|
||||||
|
"w": 12,
|
||||||
|
"h": 17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:4f18a8effb8f01eb70f9f25b8294c1bf:ad663a73c51f780bbf45d00a52519553:c64f6b8befc3d5e9f836246d2b9536be$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 375 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "pokemon_salesman.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 40,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 21,
|
||||||
|
"y": 2,
|
||||||
|
"w": 38,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 38,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:dd57e3db21f3933c15be65bec261f4c1:05c7ef32252a5c2d3ad007b7e26fabd7:ae82f52e471ed81e2558206f05476cd7$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 839 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "safari_zone.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 120,
|
||||||
|
"h": 84
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 118,
|
||||||
|
"h": 82
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 118,
|
||||||
|
"h": 82
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 118,
|
||||||
|
"h": 82
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:6fad7a61e47043b974153148b4fd3997:5ec4d0890f2f03446daf22c8ae8ba77b:87aa745cd95eef6cbf38935230f4e10f$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "teacher.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 43,
|
||||||
|
"h": 74
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 19,
|
||||||
|
"y": 8,
|
||||||
|
"w": 41,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:506e5a4ce79c134a7b4af90a90aef244:1b81d3d84bf12cedc419805eaff82548:59bc5dd000b5e72588320b473e31c312$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 727 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "teleporter.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 74,
|
||||||
|
"h": 79
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 74,
|
||||||
|
"h": 79
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 74,
|
||||||
|
"h": 79
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 74,
|
||||||
|
"h": 79
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:937d8502b98f79720118061b6021e108:2b4f9db00d5b0997b42a5466f808509b:ce1615396ce7b0a146766d50b319bb81$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "training_gear.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 76,
|
||||||
|
"h": 57
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 76,
|
||||||
|
"h": 57
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 3,
|
||||||
|
"w": 56,
|
||||||
|
"h": 54
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 8,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 54
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:895f0a79b89fa0fb44167f4584fd9a22:357b46953b7e17c6b2f43a62d52855d8:cc1ed0e4f90aaa9dcf1b39a0af1283b0$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "warehouse_crate.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 71,
|
||||||
|
"h": 52
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 56
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 5,
|
||||||
|
"y": 4,
|
||||||
|
"w": 71,
|
||||||
|
"h": 52
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 71,
|
||||||
|
"h": 52
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:c8df5f0b35fb9c2a69b0e4aaa9fa9f91:f1d4643c26f2aed86ad77d354e669aaf:0c073e3c2048ea0779db9429e5e1d8bc$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 868 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "weird_dream_woman.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 78,
|
||||||
|
"h": 87
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 87
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 0,
|
||||||
|
"w": 78,
|
||||||
|
"h": 87
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 78,
|
||||||
|
"h": 87
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:d3cce87ee0e3a880d840bffe9373d5d4:7c776d33b75abad1fe36b14a5e5734af:56468b7a2883e66dadcd2af13ebd8010$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,524 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "buck.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 120,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0010.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0011.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0014.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0015.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0018.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 18,
|
||||||
|
"y": 8,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0019.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 18,
|
||||||
|
"y": 8,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0020.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 15,
|
||||||
|
"y": 8,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0021.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 15,
|
||||||
|
"y": 8,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0022.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 8,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0023.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 8,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0012.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0013.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0016.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0017.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:033f3d363b4192f64c92e02c19622c15:0d06141bef5af87ef82da967253207cb:3347efe478119141b0e3e6eccdecd0f5$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 4.0 KiB |
|
@ -0,0 +1,398 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "cheryl.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 154,
|
||||||
|
"h": 83
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 25,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 25,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 26,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 26,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0010.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 44,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0011.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 44,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0012.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 24,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 44,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0013.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 24,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 44,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0014.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 0,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 87,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0015.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 0,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 87,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0016.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 26,
|
||||||
|
"y": 0,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 87,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0017.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 26,
|
||||||
|
"y": 0,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 87,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 21,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 21,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:dfcf7aedbd588c4e42427a2e17c171bf:206549943a0e3325d20a017ef01eefee:a233cd27590422717866c66e366b68fb$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,83 @@
|
||||||
|
{ "frames": [
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 31, "h": 77 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 26, "y": 2, "w": 31, "h": 77 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 31, "h": 77 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 26, "y": 2, "w": 31, "h": 77 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 31, "h": 77 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 26, "y": 2, "w": 31, "h": 77 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 31, "h": 77 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 26, "y": 2, "w": 31, "h": 77 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"frame": { "x": 32, "y": 0, "w": 28, "h": 78 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 28, "y": 1, "w": 28, "h": 78 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"frame": { "x": 32, "y": 0, "w": 28, "h": 78 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 28, "y": 1, "w": 28, "h": 78 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"frame": { "x": 0, "y": 78, "w": 31, "h": 77 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 28, "y": 2, "w": 31, "h": 77 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"frame": { "x": 0, "y": 78, "w": 31, "h": 77 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 28, "y": 2, "w": 31, "h": 77 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.pngprite.org/",
|
||||||
|
"version": "1.3.7-x64",
|
||||||
|
"image": "marley.png",
|
||||||
|
"format": "I8",
|
||||||
|
"size": { "w": 60, "h": 155 },
|
||||||
|
"scale": "1"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,209 @@
|
||||||
|
{ "frames": [
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"frame": { "x": 53, "y": 0, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 23, "y": 14, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"frame": { "x": 53, "y": 0, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 23, "y": 14, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"frame": { "x": 53, "y": 0, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 22, "y": 13, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"frame": { "x": 53, "y": 0, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 21, "y": 11, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 53, "h": 63 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 21, "y": 11, "w": 53, "h": 63 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 53, "h": 63 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 21, "y": 12, "w": 53, "h": 63 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"frame": { "x": 0, "y": 63, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 13, "y": 11, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"frame": { "x": 0, "y": 63, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 13, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"frame": { "x": 0, "y": 63, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 11, "y": 14, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"frame": { "x": 0, "y": 63, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 13, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0010.png",
|
||||||
|
"frame": { "x": 0, "y": 63, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 13, "y": 11, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0011.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 53, "h": 63 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 21, "y": 11, "w": 53, "h": 63 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0012.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 53, "h": 63 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 21, "y": 12, "w": 53, "h": 63 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0013.png",
|
||||||
|
"frame": { "x": 53, "y": 0, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 21, "y": 11, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0014.png",
|
||||||
|
"frame": { "x": 53, "y": 0, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 22, "y": 13, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0015.png",
|
||||||
|
"frame": { "x": 53, "y": 0, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 23, "y": 14, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0016.png",
|
||||||
|
"frame": { "x": 53, "y": 0, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 22, "y": 13, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0017.png",
|
||||||
|
"frame": { "x": 53, "y": 0, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 21, "y": 11, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0018.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 53, "h": 63 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 21, "y": 11, "w": 53, "h": 63 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0019.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 53, "h": 63 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 21, "y": 12, "w": 53, "h": 63 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0020.png",
|
||||||
|
"frame": { "x": 0, "y": 63, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 13, "y": 11, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0021.png",
|
||||||
|
"frame": { "x": 0, "y": 63, "w": 44, "h": 65 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 13, "w": 44, "h": 65 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.aseprite.org/",
|
||||||
|
"version": "1.3.7-x64",
|
||||||
|
"image": "mira.png",
|
||||||
|
"format": "I8",
|
||||||
|
"size": { "w": 97, "h": 128 },
|
||||||
|
"scale": "1"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,209 @@
|
||||||
|
{ "frames": [
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"frame": { "x": 55, "y": 80, "w": 37, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 31, "y": 0, "w": 37, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"frame": { "x": 55, "y": 80, "w": 37, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 31, "y": 0, "w": 37, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"frame": { "x": 55, "y": 80, "w": 37, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 30, "y": 0, "w": 37, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"frame": { "x": 55, "y": 80, "w": 37, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 30, "y": 0, "w": 37, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"frame": { "x": 55, "y": 80, "w": 37, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 28, "y": 0, "w": 37, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"frame": { "x": 55, "y": 80, "w": 37, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 28, "y": 0, "w": 37, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0010.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 10, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0011.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 10, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0012.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0013.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0014.png",
|
||||||
|
"frame": { "x": 55, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0015.png",
|
||||||
|
"frame": { "x": 55, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0016.png",
|
||||||
|
"frame": { "x": 0, "y": 80, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0017.png",
|
||||||
|
"frame": { "x": 0, "y": 80, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0018.png",
|
||||||
|
"frame": { "x": 55, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0019.png",
|
||||||
|
"frame": { "x": 55, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0020.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0021.png",
|
||||||
|
"frame": { "x": 0, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 },
|
||||||
|
"sourceSize": { "w": 80, "h": 80 },
|
||||||
|
"duration": 100
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.aseprite.org/",
|
||||||
|
"version": "1.3.7-x64",
|
||||||
|
"image": "riley.png",
|
||||||
|
"format": "I8",
|
||||||
|
"size": { "w": 110, "h": 160 },
|
||||||
|
"scale": "1"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "vicky.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 52,
|
||||||
|
"h": 53
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 27,
|
||||||
|
"w": 52,
|
||||||
|
"h": 53
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 52,
|
||||||
|
"h": 53
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:bf9d2d417a1982282dd711456ac71206:101e07828e3d6e2a2a7a80aebfa802ad:cabe44a4410c334298b1984a219f8160$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 765 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "victor.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 55,
|
||||||
|
"h": 53
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 12,
|
||||||
|
"y": 27,
|
||||||
|
"w": 55,
|
||||||
|
"h": 53
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 55,
|
||||||
|
"h": 53
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:64eff0f697754cdf9552b46342c9292a:611e0e2cacbd90c1229ce5443b2414f0:0cc0f5a2c1b2eedb46dd8318e8feb1d8$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 794 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "victoria.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 52,
|
||||||
|
"h": 54
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 14,
|
||||||
|
"y": 26,
|
||||||
|
"w": 52,
|
||||||
|
"h": 54
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 52,
|
||||||
|
"h": 54
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:4dafeae3674d63b12cc4d8044f67b5a3:7834687d784c31169256927f419c7958:cf0eb39e0a3f2e42f23ca29747d73c40$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 813 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "vito.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 41,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 2,
|
||||||
|
"w": 41,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 78
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:cb988be58fcd5381174e9d120b051e38:4d4723dbbcd9713ee0ed3c2d84ef4bfb:1c7723b536b218346e3138016d865ce9$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 765 B |
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "vivi.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 48,
|
||||||
|
"h": 69
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 11,
|
||||||
|
"w": 48,
|
||||||
|
"h": 69
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 48,
|
||||||
|
"h": 69
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:0a51b4df0b2ed0fed7e3bdb5dffd9e28:af1f3b1480023b3e3761c49e49faf5f1:4fc6bf2bec74c4bb8809df38231deb01$"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 713 B |
|
@ -2,18 +2,28 @@ import Phaser from "phaser";
|
||||||
import UI from "./ui/ui";
|
import UI from "./ui/ui";
|
||||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from "./field/pokemon";
|
import Pokemon, { PlayerPokemon, EnemyPokemon } from "./field/pokemon";
|
||||||
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies } from "./data/pokemon-species";
|
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies } from "./data/pokemon-species";
|
||||||
import { Constructor } from "#app/utils";
|
import { Constructor, isNullOrUndefined } from "#app/utils";
|
||||||
import * as Utils from "./utils";
|
import * as Utils from "./utils";
|
||||||
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, TurnHeldItemTransferModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, overrideModifiers, overrideHeldItems } from "./modifier/modifier";
|
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, TurnHeldItemTransferModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, overrideModifiers, overrideHeldItems, PokemonIncrementingStatModifier, ExpShareModifier, ExpBalanceModifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier } from "./modifier/modifier";
|
||||||
import { PokeballType } from "./data/pokeball";
|
import { PokeballType } from "./data/pokeball";
|
||||||
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims";
|
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims";
|
||||||
import { Phase } from "./phase";
|
import { Phase } from "./phase";
|
||||||
import { initGameSpeed } from "./system/game-speed";
|
import { initGameSpeed } from "./system/game-speed";
|
||||||
import { Arena, ArenaBase } from "./field/arena";
|
import { Arena, ArenaBase } from "./field/arena";
|
||||||
import { GameData } from "./system/game-data";
|
import { GameData } from "./system/game-data";
|
||||||
import { TextStyle, addTextObject, getTextColor } from "./ui/text";
|
import { addTextObject, getTextColor, TextStyle } from "./ui/text";
|
||||||
import { allMoves } from "./data/move";
|
import { allMoves } from "./data/move";
|
||||||
import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getModifierType, getPartyLuckValue, modifierTypes } from "./modifier/modifier-type";
|
import {
|
||||||
|
ModifierPoolType,
|
||||||
|
getDefaultModifierTypeForTier,
|
||||||
|
getEnemyModifierTypesForWave,
|
||||||
|
getLuckString,
|
||||||
|
getLuckTextTint,
|
||||||
|
getModifierPoolForType,
|
||||||
|
getModifierType,
|
||||||
|
getPartyLuckValue,
|
||||||
|
modifierTypes, PokemonHeldItemModifierType
|
||||||
|
} from "./modifier/modifier-type";
|
||||||
import AbilityBar from "./ui/ability-bar";
|
import AbilityBar from "./ui/ability-bar";
|
||||||
import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, ChangeMovePriorityAbAttr, PostBattleInitAbAttr, applyAbAttrs, applyPostBattleInitAbAttrs } from "./data/ability";
|
import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, ChangeMovePriorityAbAttr, PostBattleInitAbAttr, applyAbAttrs, applyPostBattleInitAbAttrs } from "./data/ability";
|
||||||
import { allAbilities } from "./data/ability";
|
import { allAbilities } from "./data/ability";
|
||||||
|
@ -22,14 +32,14 @@ import { GameMode, GameModes, getGameMode } from "./game-mode";
|
||||||
import FieldSpritePipeline from "./pipelines/field-sprite";
|
import FieldSpritePipeline from "./pipelines/field-sprite";
|
||||||
import SpritePipeline from "./pipelines/sprite";
|
import SpritePipeline from "./pipelines/sprite";
|
||||||
import PartyExpBar from "./ui/party-exp-bar";
|
import PartyExpBar from "./ui/party-exp-bar";
|
||||||
import { TrainerSlot, trainerConfigs } from "./data/trainer-config";
|
import { trainerConfigs, TrainerSlot } from "./data/trainer-config";
|
||||||
import Trainer, { TrainerVariant } from "./field/trainer";
|
import Trainer, { TrainerVariant } from "./field/trainer";
|
||||||
import TrainerData from "./system/trainer-data";
|
import TrainerData from "./system/trainer-data";
|
||||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||||
import { pokemonPrevolutions } from "./data/pokemon-evolutions";
|
import { pokemonPrevolutions } from "./data/pokemon-evolutions";
|
||||||
import PokeballTray from "./ui/pokeball-tray";
|
import PokeballTray from "./ui/pokeball-tray";
|
||||||
import InvertPostFX from "./pipelines/invert";
|
import InvertPostFX from "./pipelines/invert";
|
||||||
import { Achv, ModifierAchv, MoneyAchv, achvs } from "./system/achv";
|
import { Achv, achvs, ModifierAchv, MoneyAchv } from "./system/achv";
|
||||||
import { Voucher, vouchers } from "./system/voucher";
|
import { Voucher, vouchers } from "./system/voucher";
|
||||||
import { Gender } from "./data/gender";
|
import { Gender } from "./data/gender";
|
||||||
import UIPlugin from "phaser3-rex-plugins/templates/ui/ui-plugin";
|
import UIPlugin from "phaser3-rex-plugins/templates/ui/ui-plugin";
|
||||||
|
@ -86,6 +96,15 @@ import { TitlePhase } from "./phases/title-phase";
|
||||||
import { ToggleDoublePositionPhase } from "./phases/toggle-double-position-phase";
|
import { ToggleDoublePositionPhase } from "./phases/toggle-double-position-phase";
|
||||||
import { TurnInitPhase } from "./phases/turn-init-phase";
|
import { TurnInitPhase } from "./phases/turn-init-phase";
|
||||||
import { ShopCursorTarget } from "./enums/shop-cursor-target";
|
import { ShopCursorTarget } from "./enums/shop-cursor-target";
|
||||||
|
import MysteryEncounter from "./data/mystery-encounters/mystery-encounter";
|
||||||
|
import { allMysteryEncounters, ANTI_VARIANCE_WEIGHT_MODIFIER, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT, mysteryEncountersByBiome, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "./data/mystery-encounters/mystery-encounters";
|
||||||
|
import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||||
|
import { ExpPhase } from "#app/phases/exp-phase";
|
||||||
|
import { ShowPartyExpBarPhase } from "#app/phases/show-party-exp-bar-phase";
|
||||||
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
|
|
||||||
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
||||||
|
|
||||||
|
@ -246,6 +265,10 @@ export default class BattleScene extends SceneBase {
|
||||||
public money: integer;
|
public money: integer;
|
||||||
public pokemonInfoContainer: PokemonInfoContainer;
|
public pokemonInfoContainer: PokemonInfoContainer;
|
||||||
private party: PlayerPokemon[];
|
private party: PlayerPokemon[];
|
||||||
|
/** Session save data that pertains to Mystery Encounters */
|
||||||
|
public mysteryEncounterSaveData: MysteryEncounterSaveData = new MysteryEncounterSaveData();
|
||||||
|
/** If the previous wave was a MysteryEncounter, tracks the object with this variable. Mostly used for visual object cleanup */
|
||||||
|
public lastMysteryEncounter?: MysteryEncounter;
|
||||||
/** Combined Biome and Wave count text */
|
/** Combined Biome and Wave count text */
|
||||||
private biomeWaveText: Phaser.GameObjects.Text;
|
private biomeWaveText: Phaser.GameObjects.Text;
|
||||||
private moneyText: Phaser.GameObjects.Text;
|
private moneyText: Phaser.GameObjects.Text;
|
||||||
|
@ -884,6 +907,26 @@ export default class BattleScene extends SceneBase {
|
||||||
return pokemon;
|
return pokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a {@linkcode PlayerPokemon} from the party, and clears modifiers for that Pokemon's id
|
||||||
|
* Useful for MEs/Challenges that remove Pokemon from the player party temporarily or permanently
|
||||||
|
* @param pokemon
|
||||||
|
* @param destroy Default true. If true, will destroy the {@linkcode PlayerPokemon} after removing
|
||||||
|
*/
|
||||||
|
removePokemonFromPlayerParty(pokemon: PlayerPokemon, destroy: boolean = true) {
|
||||||
|
if (!pokemon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const partyIndex = this.party.indexOf(pokemon);
|
||||||
|
this.party.splice(partyIndex, 1);
|
||||||
|
if (destroy) {
|
||||||
|
this.field.remove(pokemon, true);
|
||||||
|
pokemon.destroy();
|
||||||
|
}
|
||||||
|
this.updateModifiers(true);
|
||||||
|
}
|
||||||
|
|
||||||
addPokemonIcon(pokemon: Pokemon, x: number, y: number, originX: number = 0.5, originY: number = 0.5, ignoreOverride: boolean = false): Phaser.GameObjects.Container {
|
addPokemonIcon(pokemon: Pokemon, x: number, y: number, originX: number = 0.5, originY: number = 0.5, ignoreOverride: boolean = false): Phaser.GameObjects.Container {
|
||||||
const container = this.add.container(x, y);
|
const container = this.add.container(x, y);
|
||||||
container.setName(`${pokemon.name}-icon`);
|
container.setName(`${pokemon.name}-icon`);
|
||||||
|
@ -1086,7 +1129,7 @@ export default class BattleScene extends SceneBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean): Battle | null {
|
newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean, mysteryEncounterType?: MysteryEncounterType): Battle | null {
|
||||||
const _startingWave = Overrides.STARTING_WAVE_OVERRIDE || startingWave;
|
const _startingWave = Overrides.STARTING_WAVE_OVERRIDE || startingWave;
|
||||||
const newWaveIndex = waveIndex || ((this.currentBattle?.waveIndex || (_startingWave - 1)) + 1);
|
const newWaveIndex = waveIndex || ((this.currentBattle?.waveIndex || (_startingWave - 1)) + 1);
|
||||||
let newDouble: boolean | undefined;
|
let newDouble: boolean | undefined;
|
||||||
|
@ -1135,6 +1178,36 @@ export default class BattleScene extends SceneBase {
|
||||||
newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, variant);
|
newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, variant);
|
||||||
this.field.add(newTrainer);
|
this.field.add(newTrainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for mystery encounter
|
||||||
|
// Can only occur in place of a standard (non-boss) wild battle, waves 10-180
|
||||||
|
const [lowestMysteryEncounterWave, highestMysteryEncounterWave] = this.gameMode.getMysteryEncounterLegalWaves();
|
||||||
|
if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(newWaveIndex) && newWaveIndex < highestMysteryEncounterWave && newWaveIndex > lowestMysteryEncounterWave) {
|
||||||
|
const roll = Utils.randSeedInt(MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT);
|
||||||
|
|
||||||
|
// Base spawn weight is BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT/256, and increases by WEIGHT_INCREMENT_ON_SPAWN_MISS/256 for each missed attempt at spawning an encounter on a valid floor
|
||||||
|
const sessionEncounterRate = this.mysteryEncounterSaveData.encounterSpawnChance;
|
||||||
|
const encounteredEvents = this.mysteryEncounterSaveData.encounteredEvents;
|
||||||
|
|
||||||
|
// If total number of encounters is lower than expected for the run, slightly favor a new encounter spawn (reverse as well)
|
||||||
|
// Reduces occurrence of runs with total encounters significantly different from AVERAGE_ENCOUNTERS_PER_RUN_TARGET
|
||||||
|
const expectedEncountersByFloor = AVERAGE_ENCOUNTERS_PER_RUN_TARGET / (highestMysteryEncounterWave - lowestMysteryEncounterWave) * (newWaveIndex - lowestMysteryEncounterWave);
|
||||||
|
const currentRunDiffFromAvg = expectedEncountersByFloor - encounteredEvents.length;
|
||||||
|
const favoredEncounterRate = sessionEncounterRate + currentRunDiffFromAvg * ANTI_VARIANCE_WEIGHT_MODIFIER;
|
||||||
|
|
||||||
|
const successRate = isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_RATE_OVERRIDE) ? favoredEncounterRate : Overrides.MYSTERY_ENCOUNTER_RATE_OVERRIDE!;
|
||||||
|
|
||||||
|
// If the most recent ME was 3 or fewer waves ago, can never spawn a ME
|
||||||
|
const canSpawn = encounteredEvents.length === 0 || (newWaveIndex - encounteredEvents[encounteredEvents.length - 1].waveIndex) > 3 || !isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_RATE_OVERRIDE);
|
||||||
|
|
||||||
|
if (canSpawn && roll < successRate) {
|
||||||
|
newBattleType = BattleType.MYSTERY_ENCOUNTER;
|
||||||
|
// Reset base spawn weight
|
||||||
|
this.mysteryEncounterSaveData.encounterSpawnChance = BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT;
|
||||||
|
} else {
|
||||||
|
this.mysteryEncounterSaveData.encounterSpawnChance = sessionEncounterRate + WEIGHT_INCREMENT_ON_SPAWN_MISS;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (double === undefined && newWaveIndex > 1) {
|
if (double === undefined && newWaveIndex > 1) {
|
||||||
|
@ -1167,12 +1240,21 @@ export default class BattleScene extends SceneBase {
|
||||||
const maxExpLevel = this.getMaxExpLevel();
|
const maxExpLevel = this.getMaxExpLevel();
|
||||||
|
|
||||||
this.lastEnemyTrainer = lastBattle?.trainer ?? null;
|
this.lastEnemyTrainer = lastBattle?.trainer ?? null;
|
||||||
|
this.lastMysteryEncounter = lastBattle?.mysteryEncounter;
|
||||||
|
|
||||||
this.executeWithSeedOffset(() => {
|
this.executeWithSeedOffset(() => {
|
||||||
this.currentBattle = new Battle(this.gameMode, newWaveIndex, newBattleType, newTrainer, newDouble);
|
this.currentBattle = new Battle(this.gameMode, newWaveIndex, newBattleType, newTrainer, newDouble);
|
||||||
}, newWaveIndex << 3, this.waveSeed);
|
}, newWaveIndex << 3, this.waveSeed);
|
||||||
this.currentBattle.incrementTurn(this);
|
this.currentBattle.incrementTurn(this);
|
||||||
|
|
||||||
|
if (newBattleType === BattleType.MYSTERY_ENCOUNTER) {
|
||||||
|
// Disable double battle on mystery encounters (it may be re-enabled as part of encounter)
|
||||||
|
this.currentBattle.double = false;
|
||||||
|
this.executeWithSeedOffset(() => {
|
||||||
|
this.currentBattle.mysteryEncounter = this.getMysteryEncounter(mysteryEncounterType);
|
||||||
|
}, this.currentBattle.waveIndex << 4);
|
||||||
|
}
|
||||||
|
|
||||||
//this.pushPhase(new TrainerMessageTestPhase(this, TrainerType.RIVAL, TrainerType.RIVAL_2, TrainerType.RIVAL_3, TrainerType.RIVAL_4, TrainerType.RIVAL_5, TrainerType.RIVAL_6));
|
//this.pushPhase(new TrainerMessageTestPhase(this, TrainerType.RIVAL, TrainerType.RIVAL_2, TrainerType.RIVAL_3, TrainerType.RIVAL_4, TrainerType.RIVAL_5, TrainerType.RIVAL_6));
|
||||||
|
|
||||||
if (!waveIndex && lastBattle) {
|
if (!waveIndex && lastBattle) {
|
||||||
|
@ -1181,7 +1263,7 @@ export default class BattleScene extends SceneBase {
|
||||||
const isEndlessFifthWave = this.gameMode.hasShortBiomes && (lastBattle.waveIndex % 5) === 0;
|
const isEndlessFifthWave = this.gameMode.hasShortBiomes && (lastBattle.waveIndex % 5) === 0;
|
||||||
const isWaveIndexMultipleOfFiftyMinusOne = (lastBattle.waveIndex % 50) === 49;
|
const isWaveIndexMultipleOfFiftyMinusOne = (lastBattle.waveIndex % 50) === 49;
|
||||||
const isNewBiome = isWaveIndexMultipleOfTen || isEndlessFifthWave || (isEndlessOrDaily && isWaveIndexMultipleOfFiftyMinusOne);
|
const isNewBiome = isWaveIndexMultipleOfTen || isEndlessFifthWave || (isEndlessOrDaily && isWaveIndexMultipleOfFiftyMinusOne);
|
||||||
const resetArenaState = isNewBiome || this.currentBattle.battleType === BattleType.TRAINER || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS;
|
const resetArenaState = isNewBiome || [BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.currentBattle.battleType) || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS;
|
||||||
this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy());
|
this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy());
|
||||||
this.trySpreadPokerus();
|
this.trySpreadPokerus();
|
||||||
if (!isNewBiome && (newWaveIndex % 10) === 5) {
|
if (!isNewBiome && (newWaveIndex % 10) === 5) {
|
||||||
|
@ -1189,15 +1271,22 @@ export default class BattleScene extends SceneBase {
|
||||||
}
|
}
|
||||||
if (resetArenaState) {
|
if (resetArenaState) {
|
||||||
this.arena.resetArenaEffects();
|
this.arena.resetArenaEffects();
|
||||||
playerField.forEach((_, p) => this.pushPhase(new ReturnPhase(this, p)));
|
|
||||||
|
playerField.forEach((pokemon, p) => {
|
||||||
|
if (pokemon.isOnField()) {
|
||||||
|
this.pushPhase(new ReturnPhase(this, p));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (const pokemon of this.getParty()) {
|
for (const pokemon of this.getParty()) {
|
||||||
pokemon.resetBattleData();
|
pokemon.resetBattleData();
|
||||||
applyPostBattleInitAbAttrs(PostBattleInitAbAttr, pokemon);
|
applyPostBattleInitAbAttrs(PostBattleInitAbAttr, pokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.trainer.visible) {
|
||||||
this.pushPhase(new ShowTrainerPhase(this));
|
this.pushPhase(new ShowTrainerPhase(this));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const pokemon of this.getParty()) {
|
for (const pokemon of this.getParty()) {
|
||||||
this.triggerPokemonFormChange(pokemon, SpeciesFormChangeTimeOfDayTrigger);
|
this.triggerPokemonFormChange(pokemon, SpeciesFormChangeTimeOfDayTrigger);
|
||||||
|
@ -1290,7 +1379,6 @@ export default class BattleScene extends SceneBase {
|
||||||
case Species.ZARUDE:
|
case Species.ZARUDE:
|
||||||
case Species.SQUAWKABILLY:
|
case Species.SQUAWKABILLY:
|
||||||
case Species.TATSUGIRI:
|
case Species.TATSUGIRI:
|
||||||
case Species.GIMMIGHOUL:
|
|
||||||
case Species.PALDEA_TAUROS:
|
case Species.PALDEA_TAUROS:
|
||||||
return Utils.randSeedInt(species.forms.length);
|
return Utils.randSeedInt(species.forms.length);
|
||||||
case Species.PIKACHU:
|
case Species.PIKACHU:
|
||||||
|
@ -1316,6 +1404,13 @@ export default class BattleScene extends SceneBase {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
case Species.GIMMIGHOUL:
|
||||||
|
// Chest form can only be found in Mysterious Chest Encounter, if this is a game mode with MEs
|
||||||
|
if (this.gameMode.hasMysteryEncounters) {
|
||||||
|
return 1; // Wandering form
|
||||||
|
} else {
|
||||||
|
return Utils.randSeedInt(species.forms.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignoreArena) {
|
if (ignoreArena) {
|
||||||
|
@ -2485,7 +2580,7 @@ export default class BattleScene extends SceneBase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
generateEnemyModifiers(): Promise<void> {
|
generateEnemyModifiers(heldModifiersConfigs?: HeldModifierConfig[][]): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
if (this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
|
if (this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) {
|
||||||
return resolve();
|
return resolve();
|
||||||
|
@ -2507,6 +2602,22 @@ export default class BattleScene extends SceneBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
party.forEach((enemyPokemon: EnemyPokemon, i: integer) => {
|
party.forEach((enemyPokemon: EnemyPokemon, i: integer) => {
|
||||||
|
if (heldModifiersConfigs && i < heldModifiersConfigs.length && heldModifiersConfigs[i] && heldModifiersConfigs[i].length > 0) {
|
||||||
|
heldModifiersConfigs[i].forEach(mt => {
|
||||||
|
let modifier: PokemonHeldItemModifier;
|
||||||
|
if (mt.modifier instanceof PokemonHeldItemModifierType) {
|
||||||
|
modifier = mt.modifier.newModifier(enemyPokemon);
|
||||||
|
} else {
|
||||||
|
modifier = mt.modifier as PokemonHeldItemModifier;
|
||||||
|
modifier.pokemonId = enemyPokemon.id;
|
||||||
|
}
|
||||||
|
const stackCount = mt.stackCount ?? 1;
|
||||||
|
modifier.stackCount = stackCount;
|
||||||
|
// TODO: set isTransferable
|
||||||
|
// modifier.isTransferrable = mt.isTransferable ?? true;
|
||||||
|
this.addEnemyModifier(modifier, true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
const isBoss = enemyPokemon.isBoss() || (this.currentBattle.battleType === BattleType.TRAINER && !!this.currentBattle.trainer?.config.isBoss);
|
const isBoss = enemyPokemon.isBoss() || (this.currentBattle.battleType === BattleType.TRAINER && !!this.currentBattle.trainer?.config.isBoss);
|
||||||
let upgradeChance = 32;
|
let upgradeChance = 32;
|
||||||
if (isBoss) {
|
if (isBoss) {
|
||||||
|
@ -2530,6 +2641,8 @@ export default class BattleScene extends SceneBase {
|
||||||
}
|
}
|
||||||
getEnemyModifierTypesForWave(difficultyWaveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance)
|
getEnemyModifierTypesForWave(difficultyWaveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance)
|
||||||
.map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false, this));
|
.map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false, this));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
this.updateModifiers(false).then(() => resolve());
|
this.updateModifiers(false).then(() => resolve());
|
||||||
});
|
});
|
||||||
|
@ -2837,4 +2950,220 @@ export default class BattleScene extends SceneBase {
|
||||||
|
|
||||||
this.shiftPhase();
|
this.shiftPhase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates Exp and level values for Player's party, adding new level up phases as required
|
||||||
|
* @param expValue raw value of exp to split among participants, OR the base multiplier to use with waveIndex
|
||||||
|
* @param pokemonDefeated If true, will increment Macho Brace stacks and give the party Pokemon friendship increases
|
||||||
|
* @param useWaveIndexMultiplier Default false. If true, will multiply expValue by a scaling waveIndex multiplier. Not needed if expValue is already scaled by level/wave
|
||||||
|
* @param pokemonParticipantIds Participants. If none are defined, no exp will be given. To spread evenly among the party, should pass all ids of party members.
|
||||||
|
*/
|
||||||
|
applyPartyExp(expValue: number, pokemonDefeated: boolean, useWaveIndexMultiplier?: boolean, pokemonParticipantIds?: Set<number>): void {
|
||||||
|
const participantIds = pokemonParticipantIds ?? this.currentBattle.playerParticipantIds;
|
||||||
|
const party = this.getParty();
|
||||||
|
const expShareModifier = this.findModifier(m => m instanceof ExpShareModifier) as ExpShareModifier;
|
||||||
|
const expBalanceModifier = this.findModifier(m => m instanceof ExpBalanceModifier) as ExpBalanceModifier;
|
||||||
|
const multipleParticipantExpBonusModifier = this.findModifier(m => m instanceof MultipleParticipantExpBonusModifier) as MultipleParticipantExpBonusModifier;
|
||||||
|
const nonFaintedPartyMembers = party.filter(p => p.hp);
|
||||||
|
const expPartyMembers = nonFaintedPartyMembers.filter(p => p.level < this.getMaxExpLevel());
|
||||||
|
const partyMemberExp: number[] = [];
|
||||||
|
// EXP value calculation is based off Pokemon.getExpValue
|
||||||
|
if (useWaveIndexMultiplier) {
|
||||||
|
expValue = Math.floor(expValue * this.currentBattle.waveIndex / 5 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (participantIds.size > 0) {
|
||||||
|
if (this.currentBattle.battleType === BattleType.TRAINER || this.currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
|
||||||
|
expValue = Math.floor(expValue * 1.5);
|
||||||
|
} else if (this.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && this.currentBattle.mysteryEncounter) {
|
||||||
|
expValue = Math.floor(expValue * this.currentBattle.mysteryEncounter.expMultiplier);
|
||||||
|
}
|
||||||
|
for (const partyMember of nonFaintedPartyMembers) {
|
||||||
|
const pId = partyMember.id;
|
||||||
|
const participated = participantIds.has(pId);
|
||||||
|
if (participated && pokemonDefeated) {
|
||||||
|
partyMember.addFriendship(2);
|
||||||
|
const machoBraceModifier = partyMember.getHeldItems().find(m => m instanceof PokemonIncrementingStatModifier);
|
||||||
|
if (machoBraceModifier && machoBraceModifier.stackCount < machoBraceModifier.getMaxStackCount(this)) {
|
||||||
|
machoBraceModifier.stackCount++;
|
||||||
|
this.updateModifiers(true, true);
|
||||||
|
partyMember.updateInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!expPartyMembers.includes(partyMember)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!participated && !expShareModifier) {
|
||||||
|
partyMemberExp.push(0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let expMultiplier = 0;
|
||||||
|
if (participated) {
|
||||||
|
expMultiplier += (1 / participantIds.size);
|
||||||
|
if (participantIds.size > 1 && multipleParticipantExpBonusModifier) {
|
||||||
|
expMultiplier += multipleParticipantExpBonusModifier.getStackCount() * 0.2;
|
||||||
|
}
|
||||||
|
} else if (expShareModifier) {
|
||||||
|
expMultiplier += (expShareModifier.getStackCount() * 0.2) / participantIds.size;
|
||||||
|
}
|
||||||
|
if (partyMember.pokerus) {
|
||||||
|
expMultiplier *= 1.5;
|
||||||
|
}
|
||||||
|
if (Overrides.XP_MULTIPLIER_OVERRIDE !== null) {
|
||||||
|
expMultiplier = Overrides.XP_MULTIPLIER_OVERRIDE;
|
||||||
|
}
|
||||||
|
const pokemonExp = new Utils.NumberHolder(expValue * expMultiplier);
|
||||||
|
this.applyModifiers(PokemonExpBoosterModifier, true, partyMember, pokemonExp);
|
||||||
|
partyMemberExp.push(Math.floor(pokemonExp.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expBalanceModifier) {
|
||||||
|
let totalLevel = 0;
|
||||||
|
let totalExp = 0;
|
||||||
|
expPartyMembers.forEach((expPartyMember, epm) => {
|
||||||
|
totalExp += partyMemberExp[epm];
|
||||||
|
totalLevel += expPartyMember.level;
|
||||||
|
});
|
||||||
|
|
||||||
|
const medianLevel = Math.floor(totalLevel / expPartyMembers.length);
|
||||||
|
|
||||||
|
const recipientExpPartyMemberIndexes: number[] = [];
|
||||||
|
expPartyMembers.forEach((expPartyMember, epm) => {
|
||||||
|
if (expPartyMember.level <= medianLevel) {
|
||||||
|
recipientExpPartyMemberIndexes.push(epm);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const splitExp = Math.floor(totalExp / recipientExpPartyMemberIndexes.length);
|
||||||
|
|
||||||
|
expPartyMembers.forEach((_partyMember, pm) => {
|
||||||
|
partyMemberExp[pm] = Phaser.Math.Linear(partyMemberExp[pm], recipientExpPartyMemberIndexes.indexOf(pm) > -1 ? splitExp : 0, 0.2 * expBalanceModifier.getStackCount());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let pm = 0; pm < expPartyMembers.length; pm++) {
|
||||||
|
const exp = partyMemberExp[pm];
|
||||||
|
|
||||||
|
if (exp) {
|
||||||
|
const partyMemberIndex = party.indexOf(expPartyMembers[pm]);
|
||||||
|
this.unshiftPhase(expPartyMembers[pm].isOnField() ? new ExpPhase(this, partyMemberIndex, exp) : new ShowPartyExpBarPhase(this, partyMemberIndex, exp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads or generates a mystery encounter
|
||||||
|
* @param encounterType used to load session encounter when restarting game, etc.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getMysteryEncounter(encounterType?: MysteryEncounterType): MysteryEncounter {
|
||||||
|
// Loading override or session encounter
|
||||||
|
let encounter: MysteryEncounter | null;
|
||||||
|
if (!isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_OVERRIDE) && allMysteryEncounters.hasOwnProperty(Overrides.MYSTERY_ENCOUNTER_OVERRIDE!)) {
|
||||||
|
encounter = allMysteryEncounters[Overrides.MYSTERY_ENCOUNTER_OVERRIDE!];
|
||||||
|
} else {
|
||||||
|
encounter = !isNullOrUndefined(encounterType) ? allMysteryEncounters[encounterType!] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for queued encounters first
|
||||||
|
if (!encounter && this.mysteryEncounterSaveData?.queuedEncounters && this.mysteryEncounterSaveData.queuedEncounters.length > 0) {
|
||||||
|
let i = 0;
|
||||||
|
while (i < this.mysteryEncounterSaveData.queuedEncounters.length && !!encounter) {
|
||||||
|
const candidate = this.mysteryEncounterSaveData.queuedEncounters[i];
|
||||||
|
const forcedChance = candidate.spawnPercent;
|
||||||
|
if (Utils.randSeedInt(100) < forcedChance) {
|
||||||
|
encounter = allMysteryEncounters[candidate.type];
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encounter) {
|
||||||
|
encounter = new MysteryEncounter(encounter);
|
||||||
|
encounter.populateDialogueTokensFromRequirements(this);
|
||||||
|
return encounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See Enum values for base tier weights
|
||||||
|
const tierWeights = [MysteryEncounterTier.COMMON, MysteryEncounterTier.GREAT, MysteryEncounterTier.ULTRA, MysteryEncounterTier.ROGUE];
|
||||||
|
|
||||||
|
// Adjust tier weights by previously encountered events to lower odds of only Common/Great in run
|
||||||
|
this.mysteryEncounterSaveData.encounteredEvents.forEach(seenEncounterData => {
|
||||||
|
if (seenEncounterData.tier === MysteryEncounterTier.COMMON) {
|
||||||
|
tierWeights[0] = tierWeights[0] - 6;
|
||||||
|
} else if (seenEncounterData.tier === MysteryEncounterTier.GREAT) {
|
||||||
|
tierWeights[1] = tierWeights[1] - 4;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalWeight = tierWeights.reduce((a, b) => a + b);
|
||||||
|
const tierValue = Utils.randSeedInt(totalWeight);
|
||||||
|
const commonThreshold = totalWeight - tierWeights[0];
|
||||||
|
const greatThreshold = totalWeight - tierWeights[0] - tierWeights[1];
|
||||||
|
const ultraThreshold = totalWeight - tierWeights[0] - tierWeights[1] - tierWeights[2];
|
||||||
|
let tier: MysteryEncounterTier | null = tierValue > commonThreshold ? MysteryEncounterTier.COMMON : tierValue > greatThreshold ? MysteryEncounterTier.GREAT : tierValue > ultraThreshold ? MysteryEncounterTier.ULTRA : MysteryEncounterTier.ROGUE;
|
||||||
|
|
||||||
|
if (!isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_TIER_OVERRIDE)) {
|
||||||
|
tier = Overrides.MYSTERY_ENCOUNTER_TIER_OVERRIDE!;
|
||||||
|
}
|
||||||
|
|
||||||
|
let availableEncounters: MysteryEncounter[] = [];
|
||||||
|
// New encounter should never be the same as the most recent encounter
|
||||||
|
const previousEncounter = this.mysteryEncounterSaveData.encounteredEvents.length > 0 ? this.mysteryEncounterSaveData.encounteredEvents[this.mysteryEncounterSaveData.encounteredEvents.length - 1].type : null;
|
||||||
|
const biomeMysteryEncounters = mysteryEncountersByBiome.get(this.arena.biomeType) ?? [];
|
||||||
|
// If no valid encounters exist at tier, checks next tier down, continuing until there are some encounters available
|
||||||
|
while (availableEncounters.length === 0 && tier !== null) {
|
||||||
|
availableEncounters = biomeMysteryEncounters
|
||||||
|
.filter((encounterType) => {
|
||||||
|
const encounterCandidate = allMysteryEncounters[encounterType];
|
||||||
|
if (!encounterCandidate) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (encounterCandidate.encounterTier !== tier) { // Encounter is in tier
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const disabledModes = encounterCandidate.disabledGameModes;
|
||||||
|
if (disabledModes && disabledModes.length > 0
|
||||||
|
&& disabledModes.includes(this.gameMode.modeId)) { // Encounter is enabled for game mode
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!encounterCandidate.meetsRequirements(this)) { // Meets encounter requirements
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (previousEncounter !== null && encounterType === previousEncounter) { // Previous encounter was not this one
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.mysteryEncounterSaveData.encounteredEvents.length > 0 && // Encounter has not exceeded max allowed encounters
|
||||||
|
(encounterCandidate.maxAllowedEncounters && encounterCandidate.maxAllowedEncounters > 0)
|
||||||
|
&& this.mysteryEncounterSaveData.encounteredEvents.filter(e => e.type === encounterType).length >= encounterCandidate.maxAllowedEncounters) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map((m) => (allMysteryEncounters[m]));
|
||||||
|
// Decrement tier
|
||||||
|
if (tier === MysteryEncounterTier.ROGUE) {
|
||||||
|
tier = MysteryEncounterTier.ULTRA;
|
||||||
|
} else if (tier === MysteryEncounterTier.ULTRA) {
|
||||||
|
tier = MysteryEncounterTier.GREAT;
|
||||||
|
} else if (tier === MysteryEncounterTier.GREAT) {
|
||||||
|
tier = MysteryEncounterTier.COMMON;
|
||||||
|
} else {
|
||||||
|
tier = null; // Ends loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If absolutely no encounters are available, spawn 0th encounter
|
||||||
|
if (availableEncounters.length === 0) {
|
||||||
|
console.log("No Mystery Encounters found, falling back to Mysterious Challengers.");
|
||||||
|
return allMysteryEncounters[MysteryEncounterType.MYSTERIOUS_CHALLENGERS];
|
||||||
|
}
|
||||||
|
encounter = availableEncounters[Utils.randSeedInt(availableEncounters.length)];
|
||||||
|
// New encounter object to not dirty flags
|
||||||
|
encounter = new MysteryEncounter(encounter);
|
||||||
|
encounter.populateDialogueTokensFromRequirements(this);
|
||||||
|
return encounter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,14 @@ import { PlayerGender } from "#enums/player-gender";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import i18next from "#app/plugins/i18n";
|
import i18next from "#app/plugins/i18n";
|
||||||
|
import MysteryEncounter from "./data/mystery-encounters/mystery-encounter";
|
||||||
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
|
|
||||||
export enum BattleType {
|
export enum BattleType {
|
||||||
WILD,
|
WILD,
|
||||||
TRAINER,
|
TRAINER,
|
||||||
CLEAR
|
CLEAR,
|
||||||
|
MYSTERY_ENCOUNTER
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum BattlerIndex {
|
export enum BattlerIndex {
|
||||||
|
@ -77,6 +80,9 @@ export default class Battle {
|
||||||
public playerFaintsHistory: FaintLogEntry[] = [];
|
public playerFaintsHistory: FaintLogEntry[] = [];
|
||||||
public enemyFaintsHistory: FaintLogEntry[] = [];
|
public enemyFaintsHistory: FaintLogEntry[] = [];
|
||||||
|
|
||||||
|
/** If the current battle is a Mystery Encounter, this will always be defined */
|
||||||
|
public mysteryEncounter?: MysteryEncounter;
|
||||||
|
|
||||||
private rngCounter: number = 0;
|
private rngCounter: number = 0;
|
||||||
|
|
||||||
constructor(gameMode: GameMode, waveIndex: number, battleType: BattleType, trainer?: Trainer, double?: boolean) {
|
constructor(gameMode: GameMode, waveIndex: number, battleType: BattleType, trainer?: Trainer, double?: boolean) {
|
||||||
|
@ -99,7 +105,7 @@ export default class Battle {
|
||||||
this.battleSpec = spec;
|
this.battleSpec = spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getLevelForWave(): number {
|
public getLevelForWave(): number {
|
||||||
const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
|
const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
|
||||||
const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
|
const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
|
||||||
const bossMultiplier = 1.2;
|
const bossMultiplier = 1.2;
|
||||||
|
@ -197,7 +203,11 @@ export default class Battle {
|
||||||
|
|
||||||
getBgmOverride(scene: BattleScene): string | null {
|
getBgmOverride(scene: BattleScene): string | null {
|
||||||
const battlers = this.enemyParty.slice(0, this.getBattlerCount());
|
const battlers = this.enemyParty.slice(0, this.getBattlerCount());
|
||||||
if (this.battleType === BattleType.TRAINER) {
|
if (this.battleType === BattleType.MYSTERY_ENCOUNTER && this.mysteryEncounter?.encounterMode === MysteryEncounterMode.DEFAULT) {
|
||||||
|
// Music is overridden for MEs during ME onInit()
|
||||||
|
// Should not use any BGM overrides before swapping from DEFAULT mode
|
||||||
|
return null;
|
||||||
|
} else if (this.battleType === BattleType.TRAINER || this.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
|
||||||
if (!this.started && this.trainer?.config.encounterBgm && this.trainer?.getEncounterMessages()?.length) {
|
if (!this.started && this.trainer?.config.encounterBgm && this.trainer?.getEncounterMessages()?.length) {
|
||||||
return `encounter_${this.trainer?.getEncounterBgm()}`;
|
return `encounter_${this.trainer?.getEncounterBgm()}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,9 @@ import { BattlerIndex } from "../battle";
|
||||||
import { Element } from "json-stable-stringify";
|
import { Element } from "json-stable-stringify";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { SubstituteTag } from "./battler-tags";
|
import { SubstituteTag } from "./battler-tags";
|
||||||
|
import { isNullOrUndefined } from "../utils";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { EncounterAnim } from "#enums/encounter-anims";
|
||||||
//import fs from 'vite-plugin-fs/browser';
|
//import fs from 'vite-plugin-fs/browser';
|
||||||
|
|
||||||
export enum AnimFrameTarget {
|
export enum AnimFrameTarget {
|
||||||
|
@ -304,7 +307,7 @@ abstract class AnimTimedEvent {
|
||||||
this.resourceName = resourceName;
|
this.resourceName = resourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract execute(scene: BattleScene, battleAnim: BattleAnim): integer;
|
abstract execute(scene: BattleScene, battleAnim: BattleAnim, priority?: number): integer;
|
||||||
|
|
||||||
abstract getEventType(): string;
|
abstract getEventType(): string;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +325,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) };
|
const soundConfig = { rate: (this.pitch * 0.01), volume: (this.volume * 0.01) };
|
||||||
if (this.resourceName) {
|
if (this.resourceName) {
|
||||||
try {
|
try {
|
||||||
|
@ -384,7 +387,7 @@ class AnimTimedUpdateBgEvent extends AnimTimedBgEvent {
|
||||||
super(frameIndex, resourceName, source);
|
super(frameIndex, resourceName, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(scene: BattleScene, moveAnim: MoveAnim): integer {
|
execute(scene: BattleScene, moveAnim: MoveAnim, priority?: number): integer {
|
||||||
const tweenProps = {};
|
const tweenProps = {};
|
||||||
if (this.bgX !== undefined) {
|
if (this.bgX !== undefined) {
|
||||||
tweenProps["x"] = (this.bgX * 0.5) - 320;
|
tweenProps["x"] = (this.bgX * 0.5) - 320;
|
||||||
|
@ -414,7 +417,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
|
||||||
super(frameIndex, resourceName, source);
|
super(frameIndex, resourceName, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(scene: BattleScene, moveAnim: MoveAnim): integer {
|
execute(scene: BattleScene, moveAnim: MoveAnim, priority?: number): integer {
|
||||||
if (moveAnim.bgSprite) {
|
if (moveAnim.bgSprite) {
|
||||||
moveAnim.bgSprite.destroy();
|
moveAnim.bgSprite.destroy();
|
||||||
}
|
}
|
||||||
|
@ -426,7 +429,9 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
|
||||||
moveAnim.bgSprite.setAlpha(this.opacity / 255);
|
moveAnim.bgSprite.setAlpha(this.opacity / 255);
|
||||||
scene.field.add(moveAnim.bgSprite);
|
scene.field.add(moveAnim.bgSprite);
|
||||||
const fieldPokemon = scene.getEnemyPokemon() || scene.getPlayerPokemon();
|
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);
|
scene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,6 +451,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
|
||||||
export const moveAnims = new Map<Moves, AnimConfig | [AnimConfig, AnimConfig] | null>();
|
export const moveAnims = new Map<Moves, AnimConfig | [AnimConfig, AnimConfig] | null>();
|
||||||
export const chargeAnims = new Map<ChargeAnim, AnimConfig | [AnimConfig, AnimConfig] | null>();
|
export const chargeAnims = new Map<ChargeAnim, AnimConfig | [AnimConfig, AnimConfig] | null>();
|
||||||
export const commonAnims = new Map<CommonAnim, AnimConfig>();
|
export const commonAnims = new Map<CommonAnim, AnimConfig>();
|
||||||
|
export const encounterAnims = new Map<EncounterAnim, AnimConfig>();
|
||||||
|
|
||||||
export function initCommonAnims(scene: BattleScene): Promise<void> {
|
export function initCommonAnims(scene: BattleScene): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
@ -516,6 +522,26 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches animation configs to be used in a Mystery Encounter
|
||||||
|
* @param scene
|
||||||
|
* @param encounterAnim one or more animations to fetch
|
||||||
|
*/
|
||||||
|
export async function initEncounterAnims(scene: BattleScene, encounterAnim: EncounterAnim | EncounterAnim[]): Promise<void> {
|
||||||
|
const anims = Array.isArray(encounterAnim) ? encounterAnim : [encounterAnim];
|
||||||
|
const encounterAnimNames = Utils.getEnumKeys(EncounterAnim);
|
||||||
|
const encounterAnimFetches: Promise<Map<EncounterAnim, AnimConfig>>[] = [];
|
||||||
|
for (const anim of anims) {
|
||||||
|
if (encounterAnims.has(anim) && !isNullOrUndefined(encounterAnims.get(anim))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
encounterAnimFetches.push(scene.cachedFetch(`./battle-anims/encounter-${encounterAnimNames[anim].toLowerCase().replace(/\_/g, "-")}.json`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(cas => encounterAnims.set(anim, new AnimConfig(cas))));
|
||||||
|
}
|
||||||
|
await Promise.allSettled(encounterAnimFetches);
|
||||||
|
}
|
||||||
|
|
||||||
export function initMoveChargeAnim(scene: BattleScene, chargeAnim: ChargeAnim): Promise<void> {
|
export function initMoveChargeAnim(scene: BattleScene, chargeAnim: ChargeAnim): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
if (chargeAnims.has(chargeAnim)) {
|
if (chargeAnims.has(chargeAnim)) {
|
||||||
|
@ -570,6 +596,16 @@ export function loadCommonAnimAssets(scene: BattleScene, startLoad?: boolean): P
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads encounter animation assets to scene
|
||||||
|
* MUST be called after {@linkcode initEncounterAnims()} to load all required animations properly
|
||||||
|
* @param scene
|
||||||
|
* @param startLoad
|
||||||
|
*/
|
||||||
|
export async function loadEncounterAnimAssets(scene: BattleScene, startLoad?: boolean): Promise<void> {
|
||||||
|
await loadAnimAssets(scene, Array.from(encounterAnims.values()), startLoad);
|
||||||
|
}
|
||||||
|
|
||||||
export function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLoad?: boolean): Promise<void> {
|
export function loadMoveAnimAssets(scene: BattleScene, moveIds: Moves[], startLoad?: boolean): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const moveAnimations = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat();
|
const moveAnimations = moveIds.map(m => moveAnims.get(m) as AnimConfig).flat();
|
||||||
|
@ -679,14 +715,16 @@ export abstract class BattleAnim {
|
||||||
public target: Pokemon | null;
|
public target: Pokemon | null;
|
||||||
public sprites: Phaser.GameObjects.Sprite[];
|
public sprites: Phaser.GameObjects.Sprite[];
|
||||||
public bgSprite: Phaser.GameObjects.TileSprite | Phaser.GameObjects.Rectangle;
|
public bgSprite: Phaser.GameObjects.TileSprite | Phaser.GameObjects.Rectangle;
|
||||||
|
public playOnEmptyField: boolean;
|
||||||
|
|
||||||
private srcLine: number[];
|
private srcLine: number[];
|
||||||
private dstLine: number[];
|
private dstLine: number[];
|
||||||
|
|
||||||
constructor(user?: Pokemon, target?: Pokemon) {
|
constructor(user?: Pokemon, target?: Pokemon, playOnEmptyField: boolean = false) {
|
||||||
this.user = user ?? null;
|
this.user = user ?? null;
|
||||||
this.target = target ?? null;
|
this.target = target ?? null;
|
||||||
this.sprites = [];
|
this.sprites = [];
|
||||||
|
this.playOnEmptyField = playOnEmptyField;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract getAnim(): AnimConfig | null;
|
abstract getAnim(): AnimConfig | null;
|
||||||
|
@ -761,9 +799,9 @@ export abstract class BattleAnim {
|
||||||
play(scene: BattleScene, onSubstitute?: boolean, callback?: Function) {
|
play(scene: BattleScene, onSubstitute?: boolean, callback?: Function) {
|
||||||
const isOppAnim = this.isOppAnim();
|
const isOppAnim = this.isOppAnim();
|
||||||
const user = !isOppAnim ? this.user! : this.target!; // TODO: are those bangs correct?
|
const user = !isOppAnim ? this.user! : this.target!; // TODO: are those bangs correct?
|
||||||
const target = !isOppAnim ? this.target : this.user;
|
const target = !isOppAnim ? this.target! : this.user!;
|
||||||
|
|
||||||
if (!target?.isOnField()) {
|
if (!target?.isOnField() && !this.playOnEmptyField) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
@ -866,6 +904,8 @@ export abstract class BattleAnim {
|
||||||
const isUser = frame.target === AnimFrameTarget.USER;
|
const isUser = frame.target === AnimFrameTarget.USER;
|
||||||
if (isUser && target === user) {
|
if (isUser && target === user) {
|
||||||
continue;
|
continue;
|
||||||
|
} else if (this.playOnEmptyField && frame.target === AnimFrameTarget.TARGET && !target.isOnField()) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
const sprites = spriteCache[isUser ? AnimFrameTarget.USER : AnimFrameTarget.TARGET];
|
const sprites = spriteCache[isUser ? AnimFrameTarget.USER : AnimFrameTarget.TARGET];
|
||||||
const spriteSource = isUser ? userSprite : targetSprite;
|
const spriteSource = isUser ? userSprite : targetSprite;
|
||||||
|
@ -1017,13 +1057,175 @@ export abstract class BattleAnim {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getGraphicFrameDataWithoutTarget(frames: AnimFrame[], targetInitialX: number, targetInitialY: number): Map<integer, Map<AnimFrameTarget, GraphicFrameData>> {
|
||||||
|
const ret: Map<integer, Map<AnimFrameTarget, GraphicFrameData>> = new Map([
|
||||||
|
[AnimFrameTarget.GRAPHIC, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
||||||
|
[AnimFrameTarget.USER, new Map<AnimFrameTarget, GraphicFrameData>() ],
|
||||||
|
[AnimFrameTarget.TARGET, new Map<AnimFrameTarget, GraphicFrameData>() ]
|
||||||
|
]);
|
||||||
|
|
||||||
|
let g = 0;
|
||||||
|
let u = 0;
|
||||||
|
let t = 0;
|
||||||
|
|
||||||
|
for (const frame of frames) {
|
||||||
|
let { x, y } = frame;
|
||||||
|
const scaleX = (frame.zoomX / 100) * (!frame.mirror ? 1 : -1);
|
||||||
|
const scaleY = (frame.zoomY / 100);
|
||||||
|
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 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @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]: [],
|
||||||
|
[AnimFrameTarget.TARGET]: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const cleanUpAndComplete = () => {
|
||||||
|
for (const ms of Object.values(spriteCache).flat()) {
|
||||||
|
if (ms) {
|
||||||
|
ms.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.bgSprite) {
|
||||||
|
this.bgSprite.destroy();
|
||||||
|
}
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!scene.moveAnimations) {
|
||||||
|
return cleanUpAndComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
const anim = this.getAnim();
|
||||||
|
|
||||||
|
this.srcLine = [ userFocusX, userFocusY, targetFocusX, targetFocusY ];
|
||||||
|
this.dstLine = [ 150, 75, targetInitialX, targetInitialY ];
|
||||||
|
|
||||||
|
let totalFrames = anim!.frames.length;
|
||||||
|
let frameCount = 0;
|
||||||
|
|
||||||
|
let existingFieldSprites = scene.field.getAll().slice(0);
|
||||||
|
|
||||||
|
scene.tweens.addCounter({
|
||||||
|
duration: Utils.getFrameMs(3) * frameTimeMult,
|
||||||
|
repeat: anim!.frames.length,
|
||||||
|
onRepeat: () => {
|
||||||
|
existingFieldSprites = scene.field.getAll().slice(0);
|
||||||
|
const spriteFrames = anim!.frames[frameCount];
|
||||||
|
const frameData = this.getGraphicFrameDataWithoutTarget(anim!.frames[frameCount], targetInitialX, targetInitialY);
|
||||||
|
let graphicFrameCount = 0;
|
||||||
|
for (const frame of spriteFrames) {
|
||||||
|
if (frame.target !== AnimFrameTarget.GRAPHIC) {
|
||||||
|
console.log("Encounter animations do not support targets");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sprites = spriteCache[AnimFrameTarget.GRAPHIC];
|
||||||
|
if (graphicFrameCount === sprites.length) {
|
||||||
|
const newSprite: Phaser.GameObjects.Sprite = scene.addFieldSprite(0, 0, anim!.graphic, 1);
|
||||||
|
sprites.push(newSprite);
|
||||||
|
scene.field.add(newSprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
const graphicIndex = graphicFrameCount++;
|
||||||
|
const moveSprite = sprites[graphicIndex];
|
||||||
|
if (!isNullOrUndefined(frame.priority)) {
|
||||||
|
const setSpritePriority = (priority: integer) => {
|
||||||
|
if (existingFieldSprites.length > priority) {
|
||||||
|
// Move to specified priority index
|
||||||
|
const index = scene.field.getIndex(existingFieldSprites[priority]);
|
||||||
|
scene.field.moveTo(moveSprite, index);
|
||||||
|
} else {
|
||||||
|
// Move to top of scene
|
||||||
|
scene.field.moveTo(moveSprite, scene.field.getAll().length - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setSpritePriority(frame.priority);
|
||||||
|
}
|
||||||
|
moveSprite.setFrame(frame.graphicFrame);
|
||||||
|
|
||||||
|
const graphicFrameData = frameData.get(frame.target)?.get(graphicIndex);
|
||||||
|
if (graphicFrameData) {
|
||||||
|
moveSprite.setPosition(graphicFrameData.x, graphicFrameData.y);
|
||||||
|
moveSprite.setAngle(graphicFrameData.angle);
|
||||||
|
moveSprite.setScale(graphicFrameData.scaleX, graphicFrameData.scaleY);
|
||||||
|
|
||||||
|
moveSprite.setAlpha(frame.opacity / 255);
|
||||||
|
moveSprite.setVisible(frame.visible);
|
||||||
|
moveSprite.setBlendMode(frame.blendType === AnimBlendType.NORMAL ? Phaser.BlendModes.NORMAL : frame.blendType === AnimBlendType.ADD ? Phaser.BlendModes.ADD : Phaser.BlendModes.DIFFERENCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (anim?.frameTimedEvents.get(frameCount)) {
|
||||||
|
for (const event of anim.frameTimedEvents.get(frameCount)!) {
|
||||||
|
totalFrames = Math.max((anim.frames.length - frameCount) + event.execute(scene, this, frameTimedEventPriority), totalFrames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const targets = Utils.getEnumValues(AnimFrameTarget);
|
||||||
|
for (const i of targets) {
|
||||||
|
const count = graphicFrameCount;
|
||||||
|
if (count < spriteCache[i].length) {
|
||||||
|
const spritesToRemove = spriteCache[i].slice(count, spriteCache[i].length);
|
||||||
|
for (const sprite of spritesToRemove) {
|
||||||
|
if (!sprite.getData("locked") as boolean) {
|
||||||
|
const spriteCacheIndex = spriteCache[i].indexOf(sprite);
|
||||||
|
spriteCache[i].splice(spriteCacheIndex, 1);
|
||||||
|
sprite.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frameCount++;
|
||||||
|
totalFrames--;
|
||||||
|
},
|
||||||
|
onComplete: () => {
|
||||||
|
for (const sprite of Object.values(spriteCache).flat()) {
|
||||||
|
if (sprite && !sprite.getData("locked")) {
|
||||||
|
sprite.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (totalFrames) {
|
||||||
|
scene.tweens.addCounter({
|
||||||
|
duration: Utils.getFrameMs(totalFrames),
|
||||||
|
onComplete: () => cleanUpAndComplete()
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cleanUpAndComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CommonBattleAnim extends BattleAnim {
|
export class CommonBattleAnim extends BattleAnim {
|
||||||
public commonAnim: CommonAnim | null;
|
public commonAnim: CommonAnim | null;
|
||||||
|
|
||||||
constructor(commonAnim: CommonAnim | null, user: Pokemon, target?: Pokemon) {
|
constructor(commonAnim: CommonAnim | null, user: Pokemon, target?: Pokemon, playOnEmptyField: boolean = false) {
|
||||||
super(user, target || user);
|
super(user, target || user, playOnEmptyField);
|
||||||
|
|
||||||
this.commonAnim = commonAnim;
|
this.commonAnim = commonAnim;
|
||||||
}
|
}
|
||||||
|
@ -1040,8 +1242,8 @@ export class CommonBattleAnim extends BattleAnim {
|
||||||
export class MoveAnim extends BattleAnim {
|
export class MoveAnim extends BattleAnim {
|
||||||
public move: Moves;
|
public move: Moves;
|
||||||
|
|
||||||
constructor(move: Moves, user: Pokemon, target: BattlerIndex) {
|
constructor(move: Moves, user: Pokemon, target: BattlerIndex, playOnEmptyField: boolean = false) {
|
||||||
super(user, user.scene.getField()[target]);
|
super(user, user.scene.getField()[target], playOnEmptyField);
|
||||||
|
|
||||||
this.move = move;
|
this.move = move;
|
||||||
}
|
}
|
||||||
|
@ -1085,6 +1287,26 @@ export class MoveChargeAnim extends MoveAnim {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class EncounterBattleAnim extends BattleAnim {
|
||||||
|
public encounterAnim: EncounterAnim;
|
||||||
|
public oppAnim: boolean;
|
||||||
|
|
||||||
|
constructor(encounterAnim: EncounterAnim, user: Pokemon, target?: Pokemon, oppAnim?: boolean) {
|
||||||
|
super(user, target ?? user, true);
|
||||||
|
|
||||||
|
this.encounterAnim = encounterAnim;
|
||||||
|
this.oppAnim = oppAnim ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAnim(): AnimConfig | null {
|
||||||
|
return encounterAnims.get(this.encounterAnim) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
isOppAnim(): boolean {
|
||||||
|
return this.oppAnim;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function populateAnims() {
|
export async function populateAnims() {
|
||||||
const commonAnimNames = Utils.getEnumKeys(CommonAnim).map(k => k.toLowerCase());
|
const commonAnimNames = Utils.getEnumKeys(CommonAnim).map(k => k.toLowerCase());
|
||||||
const commonAnimMatchNames = commonAnimNames.map(k => k.replace(/\_/g, ""));
|
const commonAnimMatchNames = commonAnimNames.map(k => k.replace(/\_/g, ""));
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { StatusEffect } from "./status-effect";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { ChargeAttr, MoveFlags, allMoves } from "./move";
|
import { ChargeAttr, MoveFlags, allMoves } from "./move";
|
||||||
import { Type } from "./type";
|
import { Type } from "./type";
|
||||||
import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, ReverseDrainAbAttr, applyAbAttrs } from "./ability";
|
import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, ReverseDrainAbAttr, applyAbAttrs, ProtectStatAbAttr } from "./ability";
|
||||||
import { TerrainType } from "./terrain";
|
import { TerrainType } from "./terrain";
|
||||||
import { WeatherType } from "./weather";
|
import { WeatherType } from "./weather";
|
||||||
import { allAbilities } from "./ability";
|
import { allAbilities } from "./ability";
|
||||||
|
@ -2304,6 +2304,45 @@ export class SubstituteTag extends BattlerTag {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag that adds extra post-summon effects to a battle for a specific Pokemon.
|
||||||
|
* These post-summon effects are performed through {@linkcode Pokemon.mysteryEncounterBattleEffects},
|
||||||
|
* and can be used to unshift special phases, etc.
|
||||||
|
* Currently used only in MysteryEncounters to provide start of fight stat buffs.
|
||||||
|
*/
|
||||||
|
export class MysteryEncounterPostSummonTag extends BattlerTag {
|
||||||
|
constructor() {
|
||||||
|
super(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON, BattlerTagLapseType.CUSTOM, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Event when tag is added */
|
||||||
|
onAdd(pokemon: Pokemon): void {
|
||||||
|
super.onAdd(pokemon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Performs post-summon effects through {@linkcode Pokemon.mysteryEncounterBattleEffects} */
|
||||||
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
|
const ret = super.lapse(pokemon, lapseType);
|
||||||
|
|
||||||
|
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
||||||
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
|
applyAbAttrs(ProtectStatAbAttr, pokemon, cancelled);
|
||||||
|
if (!cancelled.value) {
|
||||||
|
if (pokemon.mysteryEncounterBattleEffects) {
|
||||||
|
pokemon.mysteryEncounterBattleEffects(pokemon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Event when tag is removed */
|
||||||
|
onRemove(pokemon: Pokemon): void {
|
||||||
|
super.onRemove(pokemon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID.
|
* Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID.
|
||||||
*
|
*
|
||||||
|
@ -2465,6 +2504,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
||||||
return new GorillaTacticsTag();
|
return new GorillaTacticsTag();
|
||||||
case BattlerTagType.SUBSTITUTE:
|
case BattlerTagType.SUBSTITUTE:
|
||||||
return new SubstituteTag(sourceMove, sourceId);
|
return new SubstituteTag(sourceMove, sourceId);
|
||||||
|
case BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON:
|
||||||
|
return new MysteryEncounterPostSummonTag();
|
||||||
case BattlerTagType.NONE:
|
case BattlerTagType.NONE:
|
||||||
default:
|
default:
|
||||||
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
||||||
|
|
|
@ -1093,6 +1093,136 @@ export const trainerTypeDialogue: TrainerTypeDialogue = {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[TrainerType.BUCK]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_buck.encounter.1",
|
||||||
|
"dialogue:stat_trainer_buck.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_buck.victory.1",
|
||||||
|
"dialogue:stat_trainer_buck.victory.2"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_buck.defeat.1",
|
||||||
|
"dialogue:stat_trainer_buck.defeat.2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.CHERYL]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_cheryl.encounter.1",
|
||||||
|
"dialogue:stat_trainer_cheryl.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_cheryl.victory.1",
|
||||||
|
"dialogue:stat_trainer_cheryl.victory.2"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_cheryl.defeat.1",
|
||||||
|
"dialogue:stat_trainer_cheryl.defeat.2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.MARLEY]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_marley.encounter.1",
|
||||||
|
"dialogue:stat_trainer_marley.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_marley.victory.1",
|
||||||
|
"dialogue:stat_trainer_marley.victory.2"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_marley.defeat.1",
|
||||||
|
"dialogue:stat_trainer_marley.defeat.2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.MIRA]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_mira.encounter.1",
|
||||||
|
"dialogue:stat_trainer_mira.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_mira.victory.1",
|
||||||
|
"dialogue:stat_trainer_mira.victory.2"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_mira.defeat.1",
|
||||||
|
"dialogue:stat_trainer_mira.defeat.2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.RILEY]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_riley.encounter.1",
|
||||||
|
"dialogue:stat_trainer_riley.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_riley.victory.1",
|
||||||
|
"dialogue:stat_trainer_riley.victory.2"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_riley.defeat.1",
|
||||||
|
"dialogue:stat_trainer_riley.defeat.2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.VICTOR]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:winstrates_victor.encounter.1",
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:winstrates_victor.victory.1"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.VICTORIA]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:winstrates_victoria.encounter.1",
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:winstrates_victoria.victory.1"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.VIVI]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:winstrates_vivi.encounter.1",
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:winstrates_vivi.victory.1"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.VICKY]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:winstrates_vicky.encounter.1",
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:winstrates_vicky.victory.1"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.VITO]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:winstrates_vito.encounter.1",
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:winstrates_vito.victory.1"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
[TrainerType.BROCK]: {
|
[TrainerType.BROCK]: {
|
||||||
encounter: [
|
encounter: [
|
||||||
"dialogue:brock.encounter.1",
|
"dialogue:brock.encounter.1",
|
||||||
|
|
|
@ -61,7 +61,10 @@ export interface IEggOptions {
|
||||||
/** Defines if the egg will hatch with the hidden ability of this species.
|
/** Defines if the egg will hatch with the hidden ability of this species.
|
||||||
* If no hidden ability exist, a random one will get choosen.
|
* If no hidden ability exist, a random one will get choosen.
|
||||||
*/
|
*/
|
||||||
overrideHiddenAbility?: boolean
|
overrideHiddenAbility?: boolean,
|
||||||
|
|
||||||
|
/** Can customize the message displayed for where the egg was obtained */
|
||||||
|
eggDescriptor?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Egg {
|
export class Egg {
|
||||||
|
@ -83,6 +86,8 @@ export class Egg {
|
||||||
|
|
||||||
private _overrideHiddenAbility: boolean;
|
private _overrideHiddenAbility: boolean;
|
||||||
|
|
||||||
|
private _eggDescriptor?: string;
|
||||||
|
|
||||||
////
|
////
|
||||||
// #endregion
|
// #endregion
|
||||||
////
|
////
|
||||||
|
@ -191,6 +196,8 @@ export class Egg {
|
||||||
} else { // For legacy eggs without scene
|
} else { // For legacy eggs without scene
|
||||||
generateEggProperties(eggOptions);
|
generateEggProperties(eggOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._eggDescriptor = eggOptions?.eggDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
////
|
////
|
||||||
|
@ -292,13 +299,15 @@ export class Egg {
|
||||||
public getEggTypeDescriptor(scene: BattleScene): string {
|
public getEggTypeDescriptor(scene: BattleScene): string {
|
||||||
switch (this.sourceType) {
|
switch (this.sourceType) {
|
||||||
case EggSourceType.SAME_SPECIES_EGG:
|
case EggSourceType.SAME_SPECIES_EGG:
|
||||||
return i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName()});
|
return this._eggDescriptor ?? i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName()});
|
||||||
case EggSourceType.GACHA_LEGENDARY:
|
case EggSourceType.GACHA_LEGENDARY:
|
||||||
return `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp)).getName()})`;
|
return this._eggDescriptor ?? `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp)).getName()})`;
|
||||||
case EggSourceType.GACHA_SHINY:
|
case EggSourceType.GACHA_SHINY:
|
||||||
return i18next.t("egg:gachaTypeShiny");
|
return this._eggDescriptor ?? i18next.t("egg:gachaTypeShiny");
|
||||||
case EggSourceType.GACHA_MOVE:
|
case EggSourceType.GACHA_MOVE:
|
||||||
return i18next.t("egg:gachaTypeMove");
|
return this._eggDescriptor ?? i18next.t("egg:gachaTypeMove");
|
||||||
|
case EggSourceType.EVENT:
|
||||||
|
return this._eggDescriptor ?? i18next.t("egg:eventType");
|
||||||
default:
|
default:
|
||||||
console.warn("getEggTypeDescriptor case not defined. Returning default empty string");
|
console.warn("getEggTypeDescriptor case not defined. Returning default empty string");
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import { trainerConfigs, } from "#app/data/trainer-config";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { randSeedInt } from "#app/utils";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import { IEggOptions } from "#app/data/egg";
|
||||||
|
import { EggSourceType } from "#enums/egg-source-types";
|
||||||
|
import { EggTier } from "#enums/egg-type";
|
||||||
|
import { PartyHealPhase } from "#app/phases/party-heal-phase";
|
||||||
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
|
||||||
|
/** the i18n namespace for the encounter */
|
||||||
|
const namespace = "mysteryEncounter:aTrainersTest";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Trainer's Test encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3816 | GitHub Issue #3816}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const ATrainersTestEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.A_TRAINERS_TEST)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||||
|
.withSceneWaveRangeRequirement(100, 180)
|
||||||
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
// Randomly pick from 1 of the 5 stat trainers to spawn
|
||||||
|
let trainerType: TrainerType;
|
||||||
|
let spriteKeys;
|
||||||
|
let trainerNameKey: string;
|
||||||
|
switch (randSeedInt(5)) {
|
||||||
|
default:
|
||||||
|
case 0:
|
||||||
|
trainerType = TrainerType.BUCK;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.CLAYDOL);
|
||||||
|
trainerNameKey = "buck";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
trainerType = TrainerType.CHERYL;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.BLISSEY);
|
||||||
|
trainerNameKey = "cheryl";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
trainerType = TrainerType.MARLEY;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.ARCANINE);
|
||||||
|
trainerNameKey = "marley";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
trainerType = TrainerType.MIRA;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.ALAKAZAM, false, 1);
|
||||||
|
trainerNameKey = "mira";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
trainerType = TrainerType.RILEY;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.LUCARIO, false, 1);
|
||||||
|
trainerNameKey = "riley";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dialogue and tokens for trainer
|
||||||
|
encounter.dialogue.intro = [
|
||||||
|
{
|
||||||
|
speaker: `trainerNames:${trainerNameKey}`,
|
||||||
|
text: `${namespace}.${trainerNameKey}.intro_dialogue`
|
||||||
|
}
|
||||||
|
];
|
||||||
|
encounter.options[0].dialogue!.selected = [
|
||||||
|
{
|
||||||
|
speaker: `trainerNames:${trainerNameKey}`,
|
||||||
|
text: `${namespace}.${trainerNameKey}.accept`
|
||||||
|
}
|
||||||
|
];
|
||||||
|
encounter.options[1].dialogue!.selected = [
|
||||||
|
{
|
||||||
|
speaker: `trainerNames:${trainerNameKey}`,
|
||||||
|
text: `${namespace}.${trainerNameKey}.decline`
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
encounter.setDialogueToken("statTrainerName", i18next.t(`trainerNames:${trainerNameKey}`));
|
||||||
|
const eggDescription = i18next.t(`${namespace}.title`) + ":\n" + i18next.t(`trainerNames:${trainerNameKey}`);
|
||||||
|
encounter.misc = { trainerType, trainerNameKey, trainerEggDescription: eggDescription };
|
||||||
|
|
||||||
|
// Trainer config
|
||||||
|
const trainerConfig = trainerConfigs[trainerType].clone();
|
||||||
|
const trainerSpriteKey = trainerConfig.getSpriteKey();
|
||||||
|
encounter.enemyPartyConfigs.push({
|
||||||
|
levelAdditiveMultiplier: 1,
|
||||||
|
trainerConfig: trainerConfig
|
||||||
|
});
|
||||||
|
|
||||||
|
encounter.spriteConfigs = [
|
||||||
|
{
|
||||||
|
spriteKey: spriteKeys.spriteKey,
|
||||||
|
fileRoot: spriteKeys.fileRoot,
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
isPokemon: true,
|
||||||
|
x: 22,
|
||||||
|
y: -2,
|
||||||
|
yShadow: -2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: trainerSpriteKey,
|
||||||
|
fileRoot: "trainer",
|
||||||
|
hasShadow: true,
|
||||||
|
disableAnimation: true,
|
||||||
|
x: -24,
|
||||||
|
y: 4,
|
||||||
|
yShadow: 4
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withIntroDialogue()
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
// Battle the stat trainer for an Egg and great rewards
|
||||||
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
||||||
|
|
||||||
|
await transitionMysteryEncounterIntroVisuals(scene);
|
||||||
|
|
||||||
|
const eggOptions: IEggOptions = {
|
||||||
|
scene,
|
||||||
|
pulled: false,
|
||||||
|
sourceType: EggSourceType.EVENT,
|
||||||
|
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||||
|
tier: EggTier.ULTRA
|
||||||
|
};
|
||||||
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.epic`));
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SACRED_ASH], guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ULTRA], fillRemaining: true }, [eggOptions]);
|
||||||
|
|
||||||
|
return initBattleWithEnemyConfig(scene, config);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
// Full heal party
|
||||||
|
scene.unshiftPhase(new PartyHealPhase(scene, true));
|
||||||
|
|
||||||
|
const eggOptions: IEggOptions = {
|
||||||
|
scene,
|
||||||
|
pulled: false,
|
||||||
|
sourceType: EggSourceType.EVENT,
|
||||||
|
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||||
|
tier: EggTier.GREAT
|
||||||
|
};
|
||||||
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.rare`));
|
||||||
|
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [eggOptions]);
|
||||||
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withOutroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.outro`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.build();
|
|
@ -0,0 +1,521 @@
|
||||||
|
import { EnemyPartyConfig, generateModifierType, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import Pokemon, { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
|
import { BerryModifierType, modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||||
|
import { PersistentModifierRequirement } from "../mystery-encounter-requirements";
|
||||||
|
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { BerryModifier } from "#app/modifier/modifier";
|
||||||
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { randInt } from "#app/utils";
|
||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { applyModifierTypeToPlayerPokemon, catchPokemon, getHighestLevelPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { TrainerSlot } from "#app/data/trainer-config";
|
||||||
|
import { PokeballType } from "#app/data/pokeball";
|
||||||
|
import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||||
|
import { BerryType } from "#enums/berry-type";
|
||||||
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
|
import { Stat } from "#enums/stat";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** the i18n namespace for this encounter */
|
||||||
|
const namespace = "mysteryEncounter:absoluteAvarice";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Absolute Avarice encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3805 | GitHub Issue #3805}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const AbsoluteAvariceEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.ABSOLUTE_AVARICE)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Must have at least 4 berries to spawn
|
||||||
|
.withIntroSpriteConfigs([
|
||||||
|
{
|
||||||
|
// This sprite has the shadow
|
||||||
|
spriteKey: "",
|
||||||
|
fileRoot: "",
|
||||||
|
species: Species.GREEDENT,
|
||||||
|
hasShadow: true,
|
||||||
|
alpha: 0.001,
|
||||||
|
repeat: true,
|
||||||
|
x: -5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "",
|
||||||
|
fileRoot: "",
|
||||||
|
species: Species.GREEDENT,
|
||||||
|
hasShadow: false,
|
||||||
|
repeat: true,
|
||||||
|
x: -5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "lum_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 7,
|
||||||
|
y: -14,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "salac_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 2,
|
||||||
|
y: 4,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "lansat_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 32,
|
||||||
|
y: 5,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "liechi_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 6,
|
||||||
|
y: -5,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "sitrus_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 7,
|
||||||
|
y: 8,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "enigma_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 26,
|
||||||
|
y: -4,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "leppa_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 16,
|
||||||
|
y: -27,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "petaya_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 30,
|
||||||
|
y: -17,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "ganlon_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 16,
|
||||||
|
y: -11,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "apicot_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 14,
|
||||||
|
y: -2,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "starf_berry",
|
||||||
|
fileRoot: "items",
|
||||||
|
isItem: true,
|
||||||
|
x: 18,
|
||||||
|
y: 9,
|
||||||
|
hidden: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withHideWildIntroMessage(true)
|
||||||
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.withOnVisualsStart((scene: BattleScene) => {
|
||||||
|
doGreedentSpriteSteal(scene);
|
||||||
|
doBerrySpritePile(scene);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
scene.loadSe("PRSFX- Bug Bite", "battle_anims", "PRSFX- Bug Bite.wav");
|
||||||
|
scene.loadSe("Follow Me", "battle_anims", "Follow Me.mp3");
|
||||||
|
|
||||||
|
// Get all player berry items, remove from party, and store reference
|
||||||
|
const berryItems = scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
|
||||||
|
|
||||||
|
// Sort berries by party member ID to more easily re-add later if necessary
|
||||||
|
const berryItemsMap = new Map<number, BerryModifier[]>();
|
||||||
|
scene.getParty().forEach(pokemon => {
|
||||||
|
const pokemonBerries = berryItems.filter(b => b.pokemonId === pokemon.id);
|
||||||
|
if (pokemonBerries?.length > 0) {
|
||||||
|
berryItemsMap.set(pokemon.id, pokemonBerries);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
encounter.misc = { berryItemsMap };
|
||||||
|
|
||||||
|
// Generates copies of the stolen berries to put on the Greedent
|
||||||
|
const bossModifierConfigs: HeldModifierConfig[] = [];
|
||||||
|
berryItems.forEach(berryMod => {
|
||||||
|
// Can't define stack count on a ModifierType, have to just create separate instances for each stack
|
||||||
|
// Overflow berries will be "lost" on the boss, but it's un-catchable anyway
|
||||||
|
for (let i = 0; i < berryMod.stackCount; i++) {
|
||||||
|
const modifierType = generateModifierType(scene, modifierTypes.BERRY, [berryMod.berryType]) as PokemonHeldItemModifierType;
|
||||||
|
bossModifierConfigs.push({ modifier: modifierType });
|
||||||
|
}
|
||||||
|
|
||||||
|
scene.removeModifier(berryMod);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Calculate boss mon
|
||||||
|
const config: EnemyPartyConfig = {
|
||||||
|
levelAdditiveMultiplier: 1,
|
||||||
|
pokemonConfigs: [
|
||||||
|
{
|
||||||
|
species: getPokemonSpecies(Species.GREEDENT),
|
||||||
|
isBoss: true,
|
||||||
|
bossSegments: 3,
|
||||||
|
moveSet: [Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.SLACK_OFF],
|
||||||
|
modifierConfigs: bossModifierConfigs,
|
||||||
|
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||||
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
|
queueEncounterMessage(pokemon.scene, `${namespace}.option.1.boss_enraged`);
|
||||||
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD], 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
encounter.enemyPartyConfigs = [config];
|
||||||
|
encounter.setDialogueToken("greedentName", getPokemonSpecies(Species.GREEDENT).getName());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.1.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Pick battle
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
// Provides 1x Reviver Seed to each party member at end of battle
|
||||||
|
const revSeed = generateModifierType(scene, modifierTypes.REVIVER_SEED);
|
||||||
|
const givePartyPokemonReviverSeeds = () => {
|
||||||
|
const party = scene.getParty();
|
||||||
|
party.forEach(p => {
|
||||||
|
if (revSeed) {
|
||||||
|
const seedModifier = revSeed.newModifier(p);
|
||||||
|
if (seedModifier) {
|
||||||
|
encounter.setDialogueToken("foodReward", seedModifier.type.name);
|
||||||
|
}
|
||||||
|
scene.addModifier(seedModifier, false, false, false, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
queueEncounterMessage(scene, `${namespace}.option.1.food_stash`);
|
||||||
|
};
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, givePartyPokemonReviverSeeds);
|
||||||
|
encounter.startOfBattleEffects.push({
|
||||||
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
|
targets: [BattlerIndex.ENEMY],
|
||||||
|
move: new PokemonMove(Moves.STUFF_CHEEKS),
|
||||||
|
ignorePp: true
|
||||||
|
});
|
||||||
|
|
||||||
|
transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
|
||||||
|
await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.2.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const berryMap = encounter.misc.berryItemsMap;
|
||||||
|
|
||||||
|
// Returns 2/5 of the berries stolen from each Pokemon
|
||||||
|
const party = scene.getParty();
|
||||||
|
party.forEach(pokemon => {
|
||||||
|
const stolenBerries: BerryModifier[] = berryMap.get(pokemon.id);
|
||||||
|
const berryTypesAsArray: BerryType[] = [];
|
||||||
|
stolenBerries?.forEach(bMod => berryTypesAsArray.push(...new Array(bMod.stackCount).fill(bMod.berryType)));
|
||||||
|
const returnedBerryCount = Math.floor((berryTypesAsArray.length ?? 0) * 2 / 5);
|
||||||
|
|
||||||
|
if (returnedBerryCount > 0) {
|
||||||
|
for (let i = 0; i < returnedBerryCount; i++) {
|
||||||
|
// Shuffle remaining berry types and pop
|
||||||
|
Phaser.Math.RND.shuffle(berryTypesAsArray);
|
||||||
|
const randBerryType = berryTypesAsArray.pop();
|
||||||
|
|
||||||
|
const berryModType = generateModifierType(scene, modifierTypes.BERRY, [randBerryType]) as BerryModifierType;
|
||||||
|
applyModifierTypeToPlayerPokemon(scene, pokemon, berryModType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Animate berries being eaten
|
||||||
|
doGreedentEatBerries(scene);
|
||||||
|
doBerrySpritePile(scene, true);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Let it have the food
|
||||||
|
// Greedent joins the team, level equal to 2 below highest party member
|
||||||
|
const level = getHighestLevelPlayerPokemon(scene).level - 2;
|
||||||
|
const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false);
|
||||||
|
greedent.moveset = [new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF)];
|
||||||
|
greedent.passive = true;
|
||||||
|
|
||||||
|
transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
|
||||||
|
await catchPokemon(scene, greedent, null, PokeballType.POKEBALL, false);
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
function doGreedentSpriteSteal(scene: BattleScene) {
|
||||||
|
const shakeDelay = 50;
|
||||||
|
const slideDelay = 500;
|
||||||
|
|
||||||
|
const greedentSprites = scene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(1);
|
||||||
|
|
||||||
|
scene.playSound("battle_anims/Follow Me");
|
||||||
|
scene.tweens.chain({
|
||||||
|
targets: greedentSprites,
|
||||||
|
tweens: [
|
||||||
|
{ // Slide Greedent diagonally
|
||||||
|
duration: slideDelay,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
y: "+=75",
|
||||||
|
x: "-=65",
|
||||||
|
scale: 1.1
|
||||||
|
},
|
||||||
|
{ // Shake
|
||||||
|
duration: shakeDelay,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
yoyo: true,
|
||||||
|
x: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
y: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
},
|
||||||
|
{ // Shake
|
||||||
|
duration: shakeDelay,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
yoyo: true,
|
||||||
|
x: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
y: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
},
|
||||||
|
{ // Shake
|
||||||
|
duration: shakeDelay,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
yoyo: true,
|
||||||
|
x: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
y: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
},
|
||||||
|
{ // Shake
|
||||||
|
duration: shakeDelay,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
yoyo: true,
|
||||||
|
x: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
y: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
},
|
||||||
|
{ // Shake
|
||||||
|
duration: shakeDelay,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
yoyo: true,
|
||||||
|
x: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
y: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
},
|
||||||
|
{ // Shake
|
||||||
|
duration: shakeDelay,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
yoyo: true,
|
||||||
|
x: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
y: (randInt(2) > 0 ? "-=" : "+=") + 5,
|
||||||
|
},
|
||||||
|
{ // Slide Greedent diagonally
|
||||||
|
duration: slideDelay,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
y: "-=75",
|
||||||
|
x: "+=65",
|
||||||
|
scale: 1
|
||||||
|
},
|
||||||
|
{ // Bounce at the end
|
||||||
|
duration: 300,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
yoyo: true,
|
||||||
|
y: "-=20",
|
||||||
|
loop: 1,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function doGreedentEatBerries(scene: BattleScene) {
|
||||||
|
const greedentSprites = scene.currentBattle.mysteryEncounter!.introVisuals?.getSpriteAtIndex(1);
|
||||||
|
let index = 1;
|
||||||
|
scene.tweens.add({
|
||||||
|
targets: greedentSprites,
|
||||||
|
duration: 150,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
yoyo: true,
|
||||||
|
y: "-=8",
|
||||||
|
loop: 5,
|
||||||
|
onStart: () => {
|
||||||
|
scene.playSound("battle_anims/PRSFX- Bug Bite");
|
||||||
|
},
|
||||||
|
onLoop: () => {
|
||||||
|
if (index % 2 === 0) {
|
||||||
|
scene.playSound("battle_anims/PRSFX- Bug Bite");
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param scene
|
||||||
|
* @param isEat Default false. Will "create" pile when false, and remove pile when true.
|
||||||
|
*/
|
||||||
|
function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) {
|
||||||
|
const berryAddDelay = 150;
|
||||||
|
let animationOrder = ["starf", "sitrus", "lansat", "salac", "apicot", "enigma", "liechi", "ganlon", "lum", "petaya", "leppa"];
|
||||||
|
if (isEat) {
|
||||||
|
animationOrder = animationOrder.reverse();
|
||||||
|
}
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
animationOrder.forEach((berry, i) => {
|
||||||
|
const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey?.includes(berry));
|
||||||
|
let sprite: Phaser.GameObjects.Sprite, tintSprite: Phaser.GameObjects.Sprite;
|
||||||
|
const sprites = encounter.introVisuals?.getSpriteAtIndex(introVisualsIndex);
|
||||||
|
if (sprites) {
|
||||||
|
sprite = sprites[0];
|
||||||
|
tintSprite = sprites[1];
|
||||||
|
}
|
||||||
|
scene.time.delayedCall(berryAddDelay * i + 400, () => {
|
||||||
|
if (sprite) {
|
||||||
|
sprite.setVisible(!isEat);
|
||||||
|
}
|
||||||
|
if (tintSprite) {
|
||||||
|
tintSprite.setVisible(!isEat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animate Petaya berry falling off the pile
|
||||||
|
if (berry === "petaya" && sprite && tintSprite && !isEat) {
|
||||||
|
scene.time.delayedCall(200, () => {
|
||||||
|
doBerryBounce(scene, [sprite, tintSprite], 30, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function doBerryBounce(scene: BattleScene, berrySprites: Phaser.GameObjects.Sprite[], yd: number, baseBounceDuration: number) {
|
||||||
|
let bouncePower = 1;
|
||||||
|
let bounceYOffset = yd;
|
||||||
|
|
||||||
|
const doBounce = () => {
|
||||||
|
scene.tweens.add({
|
||||||
|
targets: berrySprites,
|
||||||
|
y: "+=" + bounceYOffset,
|
||||||
|
x: { value: "+=" + (bouncePower * bouncePower * 10), ease: "Linear" },
|
||||||
|
duration: bouncePower * baseBounceDuration,
|
||||||
|
ease: "Cubic.easeIn",
|
||||||
|
onComplete: () => {
|
||||||
|
bouncePower = bouncePower > 0.01 ? bouncePower * 0.5 : 0;
|
||||||
|
|
||||||
|
if (bouncePower) {
|
||||||
|
bounceYOffset = bounceYOffset * bouncePower;
|
||||||
|
|
||||||
|
scene.tweens.add({
|
||||||
|
targets: berrySprites,
|
||||||
|
y: "-=" + bounceYOffset,
|
||||||
|
x: { value: "+=" + (bouncePower * bouncePower * 10), ease: "Linear" },
|
||||||
|
duration: bouncePower * baseBounceDuration,
|
||||||
|
ease: "Cubic.easeOut",
|
||||||
|
onComplete: () => doBounce()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
doBounce();
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
import { leaveEncounterWithoutBattle, setEncounterExp, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||||
|
import { AbilityRequirement, CombinationPokemonRequirement, MoveRequirement } from "../mystery-encounter-requirements";
|
||||||
|
import { getHighestStatTotalPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { EXTORTION_ABILITIES, EXTORTION_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||||
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** the i18n namespace for this encounter */
|
||||||
|
const namespace = "mysteryEncounter:offerYouCantRefuse";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Offer You Can't Refuse encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3808 | GitHub Issue #3808}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party
|
||||||
|
.withIntroSpriteConfigs([
|
||||||
|
{
|
||||||
|
spriteKey: Species.LIEPARD.toString(),
|
||||||
|
fileRoot: "pokemon",
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
x: 0,
|
||||||
|
y: -4,
|
||||||
|
yShadow: -4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "rich_kid_m",
|
||||||
|
fileRoot: "trainer",
|
||||||
|
hasShadow: true,
|
||||||
|
x: 2,
|
||||||
|
y: 5,
|
||||||
|
yShadow: 5
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro_dialogue`,
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const pokemon = getHighestStatTotalPlayerPokemon(scene, false);
|
||||||
|
const price = scene.getWaveMoneyAmount(10);
|
||||||
|
|
||||||
|
encounter.setDialogueToken("strongestPokemon", pokemon.getNameToRender());
|
||||||
|
encounter.setDialogueToken("price", price.toString());
|
||||||
|
|
||||||
|
// Store pokemon and price
|
||||||
|
encounter.misc = {
|
||||||
|
pokemon: pokemon,
|
||||||
|
price: price
|
||||||
|
};
|
||||||
|
|
||||||
|
// If player meets the combo OR requirements for option 2, populate the token
|
||||||
|
const opt2Req = encounter.options[1].primaryPokemonRequirements[0];
|
||||||
|
if (opt2Req.meetsRequirement(scene)) {
|
||||||
|
const abilityToken = encounter.dialogueTokens["option2PrimaryAbility"];
|
||||||
|
const moveToken = encounter.dialogueTokens["option2PrimaryMove"];
|
||||||
|
if (abilityToken) {
|
||||||
|
encounter.setDialogueToken("moveOrAbility", abilityToken);
|
||||||
|
} else if (moveToken) {
|
||||||
|
encounter.setDialogueToken("moveOrAbility", moveToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
encounter.setDialogueToken("liepardName", getPokemonSpecies(Species.LIEPARD).getName());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.1.selected`,
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
// Update money and remove pokemon from party
|
||||||
|
updatePlayerMoney(scene, encounter.misc.price);
|
||||||
|
scene.removePokemonFromPlayerParty(encounter.misc.pokemon);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Give the player a Shiny charm
|
||||||
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.SHINY_CHARM));
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
|
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||||
|
new MoveRequirement(EXTORTION_MOVES),
|
||||||
|
new AbilityRequirement(EXTORTION_ABILITIES))
|
||||||
|
)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
disabledButtonTooltip: `${namespace}.option.2.tooltip_disabled`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.2.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Extort the rich kid for money
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
// Update money and remove pokemon from party
|
||||||
|
updatePlayerMoney(scene, encounter.misc.price);
|
||||||
|
|
||||||
|
setEncounterExp(scene, encounter.options[1].primaryPokemon!.id, getPokemonSpecies(Species.LIEPARD).baseExp, true);
|
||||||
|
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.3.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Leave encounter with no rewards or exp
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.build();
|
|
@ -0,0 +1,273 @@
|
||||||
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
|
import {
|
||||||
|
EnemyPartyConfig, generateModifierType, generateModifierTypeOption,
|
||||||
|
initBattleWithEnemyConfig,
|
||||||
|
leaveEncounterWithoutBattle, setEncounterExp,
|
||||||
|
setEncounterRewards
|
||||||
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import Pokemon, { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
|
||||||
|
import {
|
||||||
|
BerryModifierType,
|
||||||
|
getPartyLuckValue,
|
||||||
|
ModifierPoolType,
|
||||||
|
ModifierTypeOption, modifierTypes,
|
||||||
|
regenerateModifierPoolThresholds,
|
||||||
|
} from "#app/modifier/modifier-type";
|
||||||
|
import { randSeedInt } from "#app/utils";
|
||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { TrainerSlot } from "#app/data/trainer-config";
|
||||||
|
import { applyModifierTypeToPlayerPokemon, getHighestStatPlayerPokemon, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
|
import { BerryModifier } from "#app/modifier/modifier";
|
||||||
|
import i18next from "#app/plugins/i18n";
|
||||||
|
import { BerryType } from "#enums/berry-type";
|
||||||
|
import { PERMANENT_STATS, Stat } from "#enums/stat";
|
||||||
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** the i18n namespace for the encounter */
|
||||||
|
const namespace = "mysteryEncounter:berriesAbound";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Berries Abound encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3810 | GitHub Issue #3810}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const BerriesAboundEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.BERRIES_ABOUND)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withCatchAllowed(true)
|
||||||
|
.withHideWildIntroMessage(true)
|
||||||
|
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
// Calculate boss mon
|
||||||
|
const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0);
|
||||||
|
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true);
|
||||||
|
const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true);
|
||||||
|
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
|
||||||
|
const config: EnemyPartyConfig = {
|
||||||
|
levelAdditiveMultiplier: 1,
|
||||||
|
pokemonConfigs: [{
|
||||||
|
level: level,
|
||||||
|
species: bossSpecies,
|
||||||
|
dataSource: new PokemonData(bossPokemon),
|
||||||
|
isBoss: true
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
encounter.enemyPartyConfigs = [config];
|
||||||
|
|
||||||
|
// Calculate the number of extra berries that player receives
|
||||||
|
// 10-40: 2, 40-120: 4, 120-160: 5, 160-180: 7
|
||||||
|
const numBerries =
|
||||||
|
scene.currentBattle.waveIndex > 160 ? 7
|
||||||
|
: scene.currentBattle.waveIndex > 120 ? 5
|
||||||
|
: scene.currentBattle.waveIndex > 40 ? 4 : 2;
|
||||||
|
regenerateModifierPoolThresholds(scene.getParty(), ModifierPoolType.PLAYER, 0);
|
||||||
|
encounter.misc = { numBerries };
|
||||||
|
|
||||||
|
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(bossPokemon);
|
||||||
|
encounter.spriteConfigs = [
|
||||||
|
{
|
||||||
|
spriteKey: "berry_bush",
|
||||||
|
fileRoot: "mystery-encounters",
|
||||||
|
x: 25,
|
||||||
|
y: -6,
|
||||||
|
yShadow: -7,
|
||||||
|
disableAnimation: true,
|
||||||
|
hasShadow: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: spriteKey,
|
||||||
|
fileRoot: fileRoot,
|
||||||
|
hasShadow: true,
|
||||||
|
tint: 0.25,
|
||||||
|
x: -5,
|
||||||
|
repeat: true,
|
||||||
|
isPokemon: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Get fastest party pokemon for option 2
|
||||||
|
const fastestPokemon = getHighestStatPlayerPokemon(scene, PERMANENT_STATS[Stat.SPD], true);
|
||||||
|
encounter.misc.fastestPokemon = fastestPokemon;
|
||||||
|
encounter.misc.enemySpeed = bossPokemon.getStat(Stat.SPD);
|
||||||
|
encounter.setDialogueToken("fastestPokemon", fastestPokemon.getNameToRender());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.1.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Pick battle
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const numBerries = encounter.misc.numBerries;
|
||||||
|
|
||||||
|
const doBerryRewards = async () => {
|
||||||
|
const berryText = numBerries + " " + i18next.t(`${namespace}.berries`);
|
||||||
|
|
||||||
|
scene.playSound("item_fanfare");
|
||||||
|
queueEncounterMessage(scene, i18next.t("battle:rewardGain", { modifierName: berryText }));
|
||||||
|
|
||||||
|
// Generate a random berry and give it to the first Pokemon with room for it
|
||||||
|
for (let i = 0; i < numBerries; i++) {
|
||||||
|
await tryGiveBerry(scene);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const shopOptions: ModifierTypeOption[] = [];
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
// Generate shop berries
|
||||||
|
const mod = generateModifierTypeOption(scene, modifierTypes.BERRY);
|
||||||
|
if (mod) {
|
||||||
|
shopOptions.push(mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
|
||||||
|
await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Pick race for berries
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const fastestPokemon = encounter.misc.fastestPokemon;
|
||||||
|
const enemySpeed = encounter.misc.enemySpeed;
|
||||||
|
const speedDiff = fastestPokemon.getStat(Stat.SPD) / (enemySpeed * 1.1);
|
||||||
|
const numBerries = encounter.misc.numBerries;
|
||||||
|
|
||||||
|
const shopOptions: ModifierTypeOption[] = [];
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
// Generate shop berries
|
||||||
|
const mod = generateModifierTypeOption(scene, modifierTypes.BERRY);
|
||||||
|
if (mod) {
|
||||||
|
shopOptions.push(mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (speedDiff < 1) {
|
||||||
|
// Caught and attacked by boss, gets +1 to all stats at start of fight
|
||||||
|
const doBerryRewards = async () => {
|
||||||
|
const berryText = numBerries + " " + i18next.t(`${namespace}.berries`);
|
||||||
|
|
||||||
|
scene.playSound("item_fanfare");
|
||||||
|
queueEncounterMessage(scene, i18next.t("battle:rewardGain", { modifierName: berryText }));
|
||||||
|
|
||||||
|
// Generate a random berry and give it to the first Pokemon with room for it
|
||||||
|
for (let i = 0; i < numBerries; i++) {
|
||||||
|
await tryGiveBerry(scene);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const config = scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
|
||||||
|
config.pokemonConfigs![0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON];
|
||||||
|
config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
|
||||||
|
queueEncounterMessage(pokemon.scene, `${namespace}.option.2.boss_enraged`);
|
||||||
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD], 1));
|
||||||
|
};
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
|
||||||
|
await showEncounterText(scene, `${namespace}.option.2.selected_bad`);
|
||||||
|
await initBattleWithEnemyConfig(scene, config);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// Gains 1 berry for every 10% faster the player's pokemon is than the enemy, up to a max of numBerries, minimum of 2
|
||||||
|
const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1)/0.08), numBerries), 2);
|
||||||
|
encounter.setDialogueToken("numBerries", String(numBerriesGrabbed));
|
||||||
|
const doFasterBerryRewards = async () => {
|
||||||
|
const berryText = numBerriesGrabbed + " " + i18next.t(`${namespace}.berries`);
|
||||||
|
|
||||||
|
scene.playSound("item_fanfare");
|
||||||
|
queueEncounterMessage(scene, i18next.t("battle:rewardGain", { modifierName: berryText }));
|
||||||
|
|
||||||
|
// Generate a random berry and give it to the first Pokemon with room for it (trying to give to fastest first)
|
||||||
|
for (let i = 0; i < numBerriesGrabbed; i++) {
|
||||||
|
await tryGiveBerry(scene, fastestPokemon);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setEncounterExp(scene, fastestPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs![0].species.baseExp);
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doFasterBerryRewards);
|
||||||
|
await showEncounterText(scene, `${namespace}.option.2.selected`);
|
||||||
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Leave encounter with no rewards or exp
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
async function tryGiveBerry(scene: BattleScene, prioritizedPokemon?: PlayerPokemon) {
|
||||||
|
const berryType = randSeedInt(Object.keys(BerryType).filter(s => !isNaN(Number(s))).length) as BerryType;
|
||||||
|
const berry = generateModifierType(scene, modifierTypes.BERRY, [berryType]) as BerryModifierType;
|
||||||
|
|
||||||
|
const party = scene.getParty();
|
||||||
|
|
||||||
|
// Will try to apply to prioritized pokemon first, then do normal application method if it fails
|
||||||
|
if (prioritizedPokemon) {
|
||||||
|
const heldBerriesOfType = scene.findModifier(m => m instanceof BerryModifier
|
||||||
|
&& m.pokemonId === prioritizedPokemon.id && (m as BerryModifier).berryType === berryType, true) as BerryModifier;
|
||||||
|
|
||||||
|
if (!heldBerriesOfType || heldBerriesOfType.getStackCount() < heldBerriesOfType.getMaxStackCount(scene)) {
|
||||||
|
await applyModifierTypeToPlayerPokemon(scene, prioritizedPokemon, berry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over the party until berry was successfully given
|
||||||
|
for (const pokemon of party) {
|
||||||
|
const heldBerriesOfType = scene.findModifier(m => m instanceof BerryModifier
|
||||||
|
&& m.pokemonId === pokemon.id && (m as BerryModifier).berryType === berryType, true) as BerryModifier;
|
||||||
|
|
||||||
|
if (!heldBerriesOfType || heldBerriesOfType.getStackCount() < heldBerriesOfType.getMaxStackCount(scene)) {
|
||||||
|
await applyModifierTypeToPlayerPokemon(scene, pokemon, berry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,670 @@
|
||||||
|
import {
|
||||||
|
EnemyPartyConfig, generateModifierType,
|
||||||
|
generateModifierTypeOption,
|
||||||
|
initBattleWithEnemyConfig,
|
||||||
|
leaveEncounterWithoutBattle,
|
||||||
|
selectOptionThenPokemon,
|
||||||
|
selectPokemonForOption,
|
||||||
|
setEncounterRewards,
|
||||||
|
transitionMysteryEncounterIntroVisuals,
|
||||||
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import {
|
||||||
|
trainerConfigs,
|
||||||
|
TrainerPartyCompoundTemplate,
|
||||||
|
TrainerPartyTemplate,
|
||||||
|
TrainerSlot,
|
||||||
|
} from "#app/data/trainer-config";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import * as Utils from "#app/utils";
|
||||||
|
import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#app/utils";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { getEncounterText, showEncounterDialogue } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
|
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||||
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import {
|
||||||
|
AttackTypeBoosterHeldItemTypeRequirement,
|
||||||
|
CombinationPokemonRequirement,
|
||||||
|
HeldItemRequirement,
|
||||||
|
TypeRequirement
|
||||||
|
} from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||||
|
import { Type } from "#app/data/type";
|
||||||
|
import { AttackTypeBoosterModifierType, ModifierTypeOption, modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
import {
|
||||||
|
AttackTypeBoosterModifier,
|
||||||
|
BypassSpeedChanceModifier,
|
||||||
|
ContactHeldItemTransferChanceModifier,
|
||||||
|
PokemonHeldItemModifier
|
||||||
|
} from "#app/modifier/modifier";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import MoveInfoOverlay from "#app/ui/move-info-overlay";
|
||||||
|
import { allMoves } from "#app/data/move";
|
||||||
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** the i18n namespace for the encounter */
|
||||||
|
const namespace = "mysteryEncounter:bugTypeSuperfan";
|
||||||
|
|
||||||
|
const POOL_1_POKEMON = [
|
||||||
|
Species.PARASECT,
|
||||||
|
Species.VENOMOTH,
|
||||||
|
Species.LEDIAN,
|
||||||
|
Species.ARIADOS,
|
||||||
|
Species.YANMA,
|
||||||
|
Species.BEAUTIFLY,
|
||||||
|
Species.DUSTOX,
|
||||||
|
Species.MASQUERAIN,
|
||||||
|
Species.NINJASK,
|
||||||
|
Species.VOLBEAT,
|
||||||
|
Species.ILLUMISE,
|
||||||
|
Species.ANORITH,
|
||||||
|
Species.KRICKETUNE,
|
||||||
|
Species.WORMADAM,
|
||||||
|
Species.MOTHIM,
|
||||||
|
Species.SKORUPI,
|
||||||
|
Species.JOLTIK,
|
||||||
|
Species.LARVESTA,
|
||||||
|
Species.VIVILLON,
|
||||||
|
Species.CHARJABUG,
|
||||||
|
Species.RIBOMBEE,
|
||||||
|
Species.SPIDOPS,
|
||||||
|
Species.LOKIX
|
||||||
|
];
|
||||||
|
|
||||||
|
const POOL_2_POKEMON = [
|
||||||
|
Species.SCYTHER,
|
||||||
|
Species.PINSIR,
|
||||||
|
Species.HERACROSS,
|
||||||
|
Species.FORRETRESS,
|
||||||
|
Species.SCIZOR,
|
||||||
|
Species.SHUCKLE,
|
||||||
|
Species.SHEDINJA,
|
||||||
|
Species.ARMALDO,
|
||||||
|
Species.VESPIQUEN,
|
||||||
|
Species.DRAPION,
|
||||||
|
Species.YANMEGA,
|
||||||
|
Species.LEAVANNY,
|
||||||
|
Species.SCOLIPEDE,
|
||||||
|
Species.CRUSTLE,
|
||||||
|
Species.ESCAVALIER,
|
||||||
|
Species.ACCELGOR,
|
||||||
|
Species.GALVANTULA,
|
||||||
|
Species.VIKAVOLT,
|
||||||
|
Species.ARAQUANID,
|
||||||
|
Species.ORBEETLE,
|
||||||
|
Species.CENTISKORCH,
|
||||||
|
Species.FROSMOTH,
|
||||||
|
Species.KLEAVOR,
|
||||||
|
];
|
||||||
|
|
||||||
|
const POOL_3_POKEMON: { species: Species, formIndex?: number }[] = [
|
||||||
|
{
|
||||||
|
species: Species.PINSIR,
|
||||||
|
formIndex: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
species: Species.SCIZOR,
|
||||||
|
formIndex: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
species: Species.HERACROSS,
|
||||||
|
formIndex: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
species: Species.ORBEETLE,
|
||||||
|
formIndex: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
species: Species.CENTISKORCH,
|
||||||
|
formIndex: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
species: Species.DURANT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
species: Species.VOLCARONA,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
species: Species.GOLISOPOD,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const POOL_4_POKEMON = [
|
||||||
|
Species.GENESECT,
|
||||||
|
Species.SLITHER_WING,
|
||||||
|
Species.BUZZWOLE,
|
||||||
|
Species.PHEROMOSA
|
||||||
|
];
|
||||||
|
|
||||||
|
const PHYSICAL_TUTOR_MOVES = [
|
||||||
|
Moves.MEGAHORN,
|
||||||
|
Moves.X_SCISSOR,
|
||||||
|
Moves.ATTACK_ORDER,
|
||||||
|
Moves.PIN_MISSILE,
|
||||||
|
Moves.FIRST_IMPRESSION
|
||||||
|
];
|
||||||
|
|
||||||
|
const SPECIAL_TUTOR_MOVES = [
|
||||||
|
Moves.SILVER_WIND,
|
||||||
|
Moves.BUG_BUZZ,
|
||||||
|
Moves.SIGNAL_BEAM,
|
||||||
|
Moves.POLLEN_PUFF
|
||||||
|
];
|
||||||
|
|
||||||
|
const STATUS_TUTOR_MOVES = [
|
||||||
|
Moves.STRING_SHOT,
|
||||||
|
Moves.STICKY_WEB,
|
||||||
|
Moves.SILK_TRAP,
|
||||||
|
Moves.RAGE_POWDER,
|
||||||
|
Moves.HEAL_ORDER
|
||||||
|
];
|
||||||
|
|
||||||
|
const MISC_TUTOR_MOVES = [
|
||||||
|
Moves.BUG_BITE,
|
||||||
|
Moves.LEECH_LIFE,
|
||||||
|
Moves.DEFEND_ORDER,
|
||||||
|
Moves.QUIVER_DANCE,
|
||||||
|
Moves.TAIL_GLOW,
|
||||||
|
Moves.INFESTATION,
|
||||||
|
Moves.U_TURN
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bug Type Superfan encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3810 | GitHub Issue #3810}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const BugTypeSuperfanEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.BUG_TYPE_SUPERFAN)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
|
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||||
|
// Must have at least 1 Bug type on team, OR have a bug item somewhere on the team
|
||||||
|
new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1),
|
||||||
|
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
||||||
|
new TypeRequirement(Type.BUG, false, 1)
|
||||||
|
))
|
||||||
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.intro_dialogue`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
// Calculates what trainers are available for battle in the encounter
|
||||||
|
|
||||||
|
// Bug type superfan trainer config
|
||||||
|
const config = getTrainerConfigForWave(scene.currentBattle.waveIndex);
|
||||||
|
const spriteKey = config.getSpriteKey();
|
||||||
|
encounter.enemyPartyConfigs.push({
|
||||||
|
trainerConfig: config,
|
||||||
|
female: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
encounter.spriteConfigs = [
|
||||||
|
{
|
||||||
|
spriteKey: spriteKey,
|
||||||
|
fileRoot: "trainer",
|
||||||
|
hasShadow: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const requiredItems = [
|
||||||
|
generateModifierType(scene, modifierTypes.QUICK_CLAW),
|
||||||
|
generateModifierType(scene, modifierTypes.GRIP_CLAW),
|
||||||
|
generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.BUG]),
|
||||||
|
];
|
||||||
|
|
||||||
|
const requiredItemString = requiredItems.map(m => m?.name ?? "unknown").join("/");
|
||||||
|
encounter.setDialogueToken("requiredBugItems", requiredItemString);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.1.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Select battle the bug trainer
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
||||||
|
|
||||||
|
// Init the moves available for tutor
|
||||||
|
const moveTutorOptions: PokemonMove[] = [];
|
||||||
|
moveTutorOptions.push(new PokemonMove(PHYSICAL_TUTOR_MOVES[randSeedInt(PHYSICAL_TUTOR_MOVES.length)]));
|
||||||
|
moveTutorOptions.push(new PokemonMove(SPECIAL_TUTOR_MOVES[randSeedInt(SPECIAL_TUTOR_MOVES.length)]));
|
||||||
|
moveTutorOptions.push(new PokemonMove(STATUS_TUTOR_MOVES[randSeedInt(STATUS_TUTOR_MOVES.length)]));
|
||||||
|
moveTutorOptions.push(new PokemonMove(MISC_TUTOR_MOVES[randSeedInt(MISC_TUTOR_MOVES.length)]));
|
||||||
|
encounter.misc = {
|
||||||
|
moveTutorOptions
|
||||||
|
};
|
||||||
|
|
||||||
|
// Assigns callback that teaches move before continuing to rewards
|
||||||
|
encounter.onRewards = doBugTypeMoveTutor;
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { fillRemaining: true });
|
||||||
|
await transitionMysteryEncounterIntroVisuals(scene, true, true);
|
||||||
|
await initBattleWithEnemyConfig(scene, config);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withOption(MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
|
.withPrimaryPokemonRequirement(new TypeRequirement(Type.BUG, false, 1)) // Must have 1 Bug type on team
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Player shows off their bug types
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
// Player gets different rewards depending on the number of bug types they have
|
||||||
|
const numBugTypes = scene.getParty().filter(p => p.isOfType(Type.BUG, true)).length;
|
||||||
|
encounter.setDialogueToken("numBugTypes", numBugTypes.toString());
|
||||||
|
|
||||||
|
if (numBugTypes < 2) {
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL], fillRemaining: false });
|
||||||
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.2.selected_0_to_1`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
} else if (numBugTypes < 4) {
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL], fillRemaining: false });
|
||||||
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.2.selected_2_to_3`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
} else if (numBugTypes < 6) {
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL], fillRemaining: false });
|
||||||
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.2.selected_4_to_5`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// If player has any evolution/form change items that are valid for their party, will spawn one of those items in addition to a Master Ball
|
||||||
|
const modifierOptions: ModifierTypeOption[] = [generateModifierTypeOption(scene, modifierTypes.MASTER_BALL)!, generateModifierTypeOption(scene, modifierTypes.MAX_LURE)!];
|
||||||
|
const specialOptions: ModifierTypeOption[] = [];
|
||||||
|
|
||||||
|
const nonRareEvolutionModifier = generateModifierTypeOption(scene, modifierTypes.EVOLUTION_ITEM);
|
||||||
|
if (nonRareEvolutionModifier) {
|
||||||
|
specialOptions.push(nonRareEvolutionModifier);
|
||||||
|
}
|
||||||
|
const rareEvolutionModifier = generateModifierTypeOption(scene, modifierTypes.RARE_EVOLUTION_ITEM);
|
||||||
|
if (rareEvolutionModifier) {
|
||||||
|
specialOptions.push(rareEvolutionModifier);
|
||||||
|
}
|
||||||
|
const formChangeModifier = generateModifierTypeOption(scene, modifierTypes.FORM_CHANGE_ITEM);
|
||||||
|
if (formChangeModifier) {
|
||||||
|
specialOptions.push(formChangeModifier);
|
||||||
|
}
|
||||||
|
if (specialOptions.length > 0) {
|
||||||
|
modifierOptions.push(specialOptions[randSeedInt(specialOptions.length)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifierOptions, fillRemaining: false });
|
||||||
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.2.selected_6`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Player shows off their bug types
|
||||||
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
})
|
||||||
|
.build())
|
||||||
|
.withOption(MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
|
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||||
|
// Meets one or both of the below reqs
|
||||||
|
new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1),
|
||||||
|
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1)
|
||||||
|
))
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.3.selected_dialogue`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
secondOptionPrompt: `${namespace}.option.3.select_prompt`,
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
|
// Get Pokemon held items and filter for valid ones
|
||||||
|
const validItems = pokemon.getHeldItems().filter(item => {
|
||||||
|
return item instanceof BypassSpeedChanceModifier ||
|
||||||
|
item instanceof ContactHeldItemTransferChanceModifier ||
|
||||||
|
(item instanceof AttackTypeBoosterModifier && (item.type as AttackTypeBoosterModifierType).moveType === Type.BUG);
|
||||||
|
});
|
||||||
|
|
||||||
|
return validItems.map((modifier: PokemonHeldItemModifier) => {
|
||||||
|
const option: OptionSelectItem = {
|
||||||
|
label: modifier.type.name,
|
||||||
|
handler: () => {
|
||||||
|
// Pokemon and item selected
|
||||||
|
encounter.setDialogueToken("selectedItem", modifier.type.name);
|
||||||
|
encounter.misc = {
|
||||||
|
chosenPokemon: pokemon,
|
||||||
|
chosenModifier: modifier,
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
|
// If pokemon has valid item, it can be selected
|
||||||
|
const hasValidItem = pokemon.getHeldItems().some(item => {
|
||||||
|
return item instanceof BypassSpeedChanceModifier ||
|
||||||
|
item instanceof ContactHeldItemTransferChanceModifier ||
|
||||||
|
(item instanceof AttackTypeBoosterModifier && (item.type as AttackTypeBoosterModifierType).moveType === Type.BUG);
|
||||||
|
});
|
||||||
|
if (!hasValidItem) {
|
||||||
|
return getEncounterText(scene, `${namespace}.option.3.invalid_selection`) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const modifier = encounter.misc.chosenModifier;
|
||||||
|
|
||||||
|
// Remove the modifier if its stacks go to 0
|
||||||
|
modifier.stackCount -= 1;
|
||||||
|
if (modifier.stackCount === 0) {
|
||||||
|
scene.removeModifier(modifier);
|
||||||
|
}
|
||||||
|
scene.updateModifiers(true, true);
|
||||||
|
|
||||||
|
const bugNet = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!;
|
||||||
|
bugNet.type.tier = ModifierTier.ROGUE;
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [bugNet], guaranteedModifierTypeFuncs: [modifierTypes.REVIVER_SEED], fillRemaining: false });
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build())
|
||||||
|
.withOutroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.outro`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.build();
|
||||||
|
|
||||||
|
function getTrainerConfigForWave(waveIndex: number) {
|
||||||
|
// Bug type superfan trainer config
|
||||||
|
const config = trainerConfigs[TrainerType.BUG_TYPE_SUPERFAN].clone();
|
||||||
|
config.name = i18next.t("trainerNames:bug_type_superfan");
|
||||||
|
|
||||||
|
const pool3Copy = POOL_3_POKEMON.slice(0);
|
||||||
|
randSeedShuffle(pool3Copy);
|
||||||
|
const pool3Mon = pool3Copy.pop()!;
|
||||||
|
|
||||||
|
if (waveIndex < 30) {
|
||||||
|
// Use default template (2 AVG)
|
||||||
|
config
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true));
|
||||||
|
} else if (waveIndex < 50) {
|
||||||
|
config
|
||||||
|
.setPartyTemplates(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE))
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true));
|
||||||
|
} else if (waveIndex < 70) {
|
||||||
|
config
|
||||||
|
.setPartyTemplates(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE))
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true));
|
||||||
|
} else if (waveIndex < 100) {
|
||||||
|
config
|
||||||
|
.setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE))
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_1_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true));
|
||||||
|
} else if (waveIndex < 120) {
|
||||||
|
config
|
||||||
|
.setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE))
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||||
|
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||||
|
p.formIndex = pool3Mon.formIndex!;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} else if (waveIndex < 140) {
|
||||||
|
randSeedShuffle(pool3Copy);
|
||||||
|
const pool3Mon2 = pool3Copy.pop()!;
|
||||||
|
config
|
||||||
|
.setPartyTemplates(new TrainerPartyTemplate(5, PartyMemberStrength.AVERAGE))
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||||
|
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||||
|
p.formIndex = pool3Mon.formIndex!;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => {
|
||||||
|
if (!isNullOrUndefined(pool3Mon2.formIndex)) {
|
||||||
|
p.formIndex = pool3Mon2.formIndex!;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} else if (waveIndex < 160) {
|
||||||
|
config
|
||||||
|
.setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(1, PartyMemberStrength.STRONG)))
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||||
|
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||||
|
p.formIndex = pool3Mon.formIndex!;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_4_POKEMON, TrainerSlot.TRAINER, true));
|
||||||
|
} else {
|
||||||
|
config
|
||||||
|
.setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(4, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(1, PartyMemberStrength.STRONG)))
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BEEDRILL ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 2);
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.BUTTERFREE ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 2);
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||||
|
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||||
|
p.formIndex = pool3Mon.formIndex!;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
|
||||||
|
if (!isNullOrUndefined(pool3Mon.formIndex)) {
|
||||||
|
p.formIndex = pool3Mon.formIndex!;
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.generateName();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc(POOL_4_POKEMON, TrainerSlot.TRAINER, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRandomPartyMemberFunc(speciesPool: Species[], trainerSlot: TrainerSlot = TrainerSlot.TRAINER, ignoreEvolution: boolean = false, postProcess?: (enemyPokemon: EnemyPokemon) => void) {
|
||||||
|
return (scene: BattleScene, level: number, strength: PartyMemberStrength) => {
|
||||||
|
let species = Utils.randSeedItem(speciesPool);
|
||||||
|
if (!ignoreEvolution) {
|
||||||
|
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength);
|
||||||
|
}
|
||||||
|
return scene.addEnemyPokemon(getPokemonSpecies(species), level, trainerSlot, undefined, undefined, postProcess);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function doBugTypeMoveTutor(scene: BattleScene): Promise<void> {
|
||||||
|
return new Promise<void>(async resolve => {
|
||||||
|
const moveOptions = scene.currentBattle.mysteryEncounter!.misc.moveTutorOptions;
|
||||||
|
await showEncounterDialogue(scene, `${namespace}.battle_won`, `${namespace}.speaker`);
|
||||||
|
|
||||||
|
const overlayScale = 1;
|
||||||
|
const moveInfoOverlay = new MoveInfoOverlay(scene, {
|
||||||
|
delayVisibility: false,
|
||||||
|
scale: overlayScale,
|
||||||
|
onSide: true,
|
||||||
|
right: true,
|
||||||
|
x: 1,
|
||||||
|
y: -MoveInfoOverlay.getHeight(overlayScale, true) - 1,
|
||||||
|
width: (scene.game.canvas.width / 6) - 2,
|
||||||
|
});
|
||||||
|
scene.ui.add(moveInfoOverlay);
|
||||||
|
|
||||||
|
const optionSelectItems = moveOptions.map((move: PokemonMove) => {
|
||||||
|
const option: OptionSelectItem = {
|
||||||
|
label: move.getName(),
|
||||||
|
handler: () => {
|
||||||
|
moveInfoOverlay.active = false;
|
||||||
|
moveInfoOverlay.setVisible(false);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onHover: () => {
|
||||||
|
moveInfoOverlay.active = true;
|
||||||
|
moveInfoOverlay.show(allMoves[move.moveId]);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
|
||||||
|
const onHoverOverCancel = () => {
|
||||||
|
moveInfoOverlay.active = false;
|
||||||
|
moveInfoOverlay.setVisible(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.teach_move_prompt`, undefined, onHoverOverCancel);
|
||||||
|
// let forceExit = !!result;
|
||||||
|
if (!result) {
|
||||||
|
moveInfoOverlay.active = false;
|
||||||
|
moveInfoOverlay.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add menu to confirm player doesn't want to teach a move
|
||||||
|
// while (!result && !forceExit) {
|
||||||
|
// // Didn't teach a move, ask the player to confirm they don't want to teach a move
|
||||||
|
// await showEncounterDialogue(scene, `${namespace}.confirm_no_teach`, `${namespace}.speaker`);
|
||||||
|
// const confirm = await new Promise<boolean>(confirmResolve => {
|
||||||
|
// scene.ui.setMode(Mode.CONFIRM, () => confirmResolve(true), () => confirmResolve(false));
|
||||||
|
// });
|
||||||
|
// scene.ui.clearText();
|
||||||
|
// await scene.ui.setMode(Mode.MESSAGE);
|
||||||
|
// if (confirm) {
|
||||||
|
// // No teach, break out of loop
|
||||||
|
// forceExit = true;
|
||||||
|
// } else {
|
||||||
|
// // Re-show learn menu
|
||||||
|
// result = await selectOptionThenPokemon(scene, optionSelectItems, `${namespace}.teach_move_prompt`, undefined, onHoverOverCancel);
|
||||||
|
// if (!result) {
|
||||||
|
// moveInfoOverlay.active = false;
|
||||||
|
// moveInfoOverlay.setVisible(false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Option select complete, handle if they are learning a move
|
||||||
|
if (result && result.selectedOptionIndex < moveOptions.length) {
|
||||||
|
scene.unshiftPhase(new LearnMovePhase(scene, result.selectedPokemonIndex, moveOptions[result.selectedOptionIndex].moveId));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete battle and go to rewards
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,496 @@
|
||||||
|
import { EnemyPartyConfig, generateModifierType, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, loadCustomMovesForEncounter, selectPokemonForOption, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import { trainerConfigs, TrainerPartyCompoundTemplate, TrainerPartyTemplate, } from "#app/data/trainer-config";
|
||||||
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
|
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { Type } from "#app/data/type";
|
||||||
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { randSeedInt, randSeedShuffle } from "#app/utils";
|
||||||
|
import { showEncounterDialogue, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
|
import { Mode } from "#app/ui/ui";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import { OptionSelectConfig } from "#app/ui/abstact-option-select-ui-handler";
|
||||||
|
import { PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
|
import { Ability } from "#app/data/ability";
|
||||||
|
import { BerryModifier } from "#app/modifier/modifier";
|
||||||
|
import { BerryType } from "#enums/berry-type";
|
||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { EncounterBattleAnim } from "#app/data/battle-anims";
|
||||||
|
import { MoveCategory } from "#app/data/move";
|
||||||
|
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES, GameModes } from "#app/game-mode";
|
||||||
|
import { EncounterAnim } from "#enums/encounter-anims";
|
||||||
|
|
||||||
|
/** the i18n namespace for the encounter */
|
||||||
|
const namespace = "mysteryEncounter:clowningAround";
|
||||||
|
|
||||||
|
const RANDOM_ABILITY_POOL = [
|
||||||
|
Abilities.STURDY,
|
||||||
|
Abilities.PICKUP,
|
||||||
|
Abilities.INTIMIDATE,
|
||||||
|
Abilities.GUTS,
|
||||||
|
Abilities.DROUGHT,
|
||||||
|
Abilities.DRIZZLE,
|
||||||
|
Abilities.SNOW_WARNING,
|
||||||
|
Abilities.SAND_STREAM,
|
||||||
|
Abilities.ELECTRIC_SURGE,
|
||||||
|
Abilities.PSYCHIC_SURGE,
|
||||||
|
Abilities.GRASSY_SURGE,
|
||||||
|
Abilities.MISTY_SURGE,
|
||||||
|
Abilities.MAGICIAN,
|
||||||
|
Abilities.SHEER_FORCE,
|
||||||
|
Abilities.PRANKSTER
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clowning Around encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3807 | GitHub Issue #3807}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const ClowningAroundEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.CLOWNING_AROUND)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||||
|
.withDisabledGameModes(GameModes.CHALLENGE)
|
||||||
|
.withSceneWaveRangeRequirement(80, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
|
.withAnimations(EncounterAnim.SMOKESCREEN)
|
||||||
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.withIntroSpriteConfigs([
|
||||||
|
{
|
||||||
|
spriteKey: Species.MR_MIME.toString(),
|
||||||
|
fileRoot: "pokemon",
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
x: -25,
|
||||||
|
tint: 0.3,
|
||||||
|
y: -3,
|
||||||
|
yShadow: -3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: Species.BLACEPHALON.toString(),
|
||||||
|
fileRoot: "pokemon/exp",
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
x: 25,
|
||||||
|
tint: 0.3,
|
||||||
|
y: -3,
|
||||||
|
yShadow: -3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "harlequin",
|
||||||
|
fileRoot: "trainer",
|
||||||
|
hasShadow: true,
|
||||||
|
x: 0,
|
||||||
|
y: 2,
|
||||||
|
yShadow: 2
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro_dialogue`,
|
||||||
|
speaker: `${namespace}.speaker`
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
const clownTrainerType = TrainerType.HARLEQUIN;
|
||||||
|
const clownConfig = trainerConfigs[clownTrainerType].clone();
|
||||||
|
const clownPartyTemplate = new TrainerPartyCompoundTemplate(
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER));
|
||||||
|
clownConfig.setPartyTemplates(clownPartyTemplate);
|
||||||
|
clownConfig.setDoubleOnly();
|
||||||
|
// @ts-ignore
|
||||||
|
clownConfig.partyTemplateFunc = null; // Overrides party template func if it exists
|
||||||
|
|
||||||
|
// Generate random ability for Blacephalon from pool
|
||||||
|
const ability = RANDOM_ABILITY_POOL[randSeedInt(RANDOM_ABILITY_POOL.length)];
|
||||||
|
encounter.setDialogueToken("ability", new Ability(ability, 3).name);
|
||||||
|
encounter.misc = { ability };
|
||||||
|
|
||||||
|
encounter.enemyPartyConfigs.push({
|
||||||
|
trainerConfig: clownConfig,
|
||||||
|
pokemonConfigs: [ // Overrides first 2 pokemon to be Mr. Mime and Blacephalon
|
||||||
|
{
|
||||||
|
species: getPokemonSpecies(Species.MR_MIME),
|
||||||
|
isBoss: true,
|
||||||
|
moveSet: [Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC]
|
||||||
|
},
|
||||||
|
{ // Blacephalon has the random ability from pool, and 2 entirely random types to fit with the theme of the encounter
|
||||||
|
species: getPokemonSpecies(Species.BLACEPHALON),
|
||||||
|
mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ ability: ability, types: [randSeedInt(18), randSeedInt(18)] }),
|
||||||
|
isBoss: true,
|
||||||
|
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
doubleBattle: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load animations/sfx for start of fight moves
|
||||||
|
loadCustomMovesForEncounter(scene, [Moves.ROLE_PLAY, Moves.TAUNT]);
|
||||||
|
|
||||||
|
encounter.setDialogueToken("blacephalonName", getPokemonSpecies(Species.BLACEPHALON).getName());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.1.selected`,
|
||||||
|
speaker: `${namespace}.speaker`
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
// Spawn battle
|
||||||
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { fillRemaining: true });
|
||||||
|
|
||||||
|
// TODO: when Magic Room and Wonder Room are implemented, add those to start of battle
|
||||||
|
encounter.startOfBattleEffects.push(
|
||||||
|
{ // Mr. Mime copies the Blacephalon's random ability
|
||||||
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
|
targets: [BattlerIndex.ENEMY_2],
|
||||||
|
move: new PokemonMove(Moves.ROLE_PLAY),
|
||||||
|
ignorePp: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
||||||
|
targets: [BattlerIndex.PLAYER],
|
||||||
|
move: new PokemonMove(Moves.TAUNT),
|
||||||
|
ignorePp: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
||||||
|
targets: [BattlerIndex.PLAYER_2],
|
||||||
|
move: new PokemonMove(Moves.TAUNT),
|
||||||
|
ignorePp: true
|
||||||
|
});
|
||||||
|
|
||||||
|
await transitionMysteryEncounterIntroVisuals(scene);
|
||||||
|
await initBattleWithEnemyConfig(scene, config);
|
||||||
|
})
|
||||||
|
.withPostOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
|
// After the battle, offer the player the opportunity to permanently swap ability
|
||||||
|
const abilityWasSwapped = await handleSwapAbility(scene);
|
||||||
|
if (abilityWasSwapped) {
|
||||||
|
await showEncounterText(scene, `${namespace}.option.1.ability_gained`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play animations once ability swap is complete
|
||||||
|
// Trainer sprite that is shown at end of battle is not the same as mystery encounter intro visuals
|
||||||
|
scene.tweens.add({
|
||||||
|
targets: scene.currentBattle.trainer,
|
||||||
|
x: "+=16",
|
||||||
|
y: "-=16",
|
||||||
|
alpha: 0,
|
||||||
|
ease: "Sine.easeInOut",
|
||||||
|
duration: 250
|
||||||
|
});
|
||||||
|
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
|
background.playWithoutTargets(scene, 230, 40, 2);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.2.selected`,
|
||||||
|
speaker: `${namespace}.speaker`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.2.selected_2`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.2.selected_3`,
|
||||||
|
speaker: `${namespace}.speaker`
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Swap player's items on pokemon with the most items
|
||||||
|
// Item comparisons look at whichever Pokemon has the greatest number of TRANSFERABLE, non-berry items
|
||||||
|
// So Vitamins, form change items, etc. are not included
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
const party = scene.getParty();
|
||||||
|
let mostHeldItemsPokemon = party[0];
|
||||||
|
let count = mostHeldItemsPokemon.getHeldItems()
|
||||||
|
.filter(m => m.isTransferrable && !(m instanceof BerryModifier))
|
||||||
|
.reduce((v, m) => v + m.stackCount, 0);
|
||||||
|
|
||||||
|
party.forEach(pokemon => {
|
||||||
|
const nextCount = pokemon.getHeldItems()
|
||||||
|
.filter(m => m.isTransferrable && !(m instanceof BerryModifier))
|
||||||
|
.reduce((v, m) => v + m.stackCount, 0);
|
||||||
|
if (nextCount > count) {
|
||||||
|
mostHeldItemsPokemon = pokemon;
|
||||||
|
count = nextCount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
encounter.setDialogueToken("switchPokemon", mostHeldItemsPokemon.getNameToRender());
|
||||||
|
|
||||||
|
const items = mostHeldItemsPokemon.getHeldItems();
|
||||||
|
|
||||||
|
// Shuffles Berries (if they have any)
|
||||||
|
let numBerries = 0;
|
||||||
|
items.filter(m => m instanceof BerryModifier)
|
||||||
|
.forEach(m => {
|
||||||
|
numBerries += m.stackCount;
|
||||||
|
scene.removeModifier(m);
|
||||||
|
});
|
||||||
|
|
||||||
|
generateItemsOfTier(scene, mostHeldItemsPokemon, numBerries, "Berries");
|
||||||
|
|
||||||
|
// Shuffle Transferable held items in the same tier (only shuffles Ultra and Rogue atm)
|
||||||
|
let numUltra = 0;
|
||||||
|
let numRogue = 0;
|
||||||
|
items.filter(m => m.isTransferrable && !(m instanceof BerryModifier))
|
||||||
|
.forEach(m => {
|
||||||
|
const type = m.type.withTierFromPool();
|
||||||
|
const tier = type.tier ?? ModifierTier.ULTRA;
|
||||||
|
if (type.id === "GOLDEN_EGG" || tier === ModifierTier.ROGUE) {
|
||||||
|
numRogue += m.stackCount;
|
||||||
|
scene.removeModifier(m);
|
||||||
|
} else if (type.id === "LUCKY_EGG" || tier === ModifierTier.ULTRA) {
|
||||||
|
numUltra += m.stackCount;
|
||||||
|
scene.removeModifier(m);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
generateItemsOfTier(scene, mostHeldItemsPokemon, numUltra, ModifierTier.ULTRA);
|
||||||
|
generateItemsOfTier(scene, mostHeldItemsPokemon, numRogue, ModifierTier.ROGUE);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.withPostOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Play animations
|
||||||
|
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
|
background.playWithoutTargets(scene, 230, 40, 2);
|
||||||
|
await transitionMysteryEncounterIntroVisuals(scene, true, true, 200);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected`,
|
||||||
|
speaker: `${namespace}.speaker`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected_2`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected_3`,
|
||||||
|
speaker: `${namespace}.speaker`
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Randomize the second type of all player's pokemon
|
||||||
|
// If the pokemon does not normally have a second type, it will gain 1
|
||||||
|
for (const pokemon of scene.getParty()) {
|
||||||
|
const originalTypes = pokemon.getTypes(false, false, true);
|
||||||
|
|
||||||
|
// If the Pokemon has non-status moves that don't match the Pokemon's type, prioritizes those as the new type
|
||||||
|
// Makes the "randomness" of the shuffle slightly less punishing
|
||||||
|
let priorityTypes = pokemon.moveset
|
||||||
|
.filter(move => move && !originalTypes.includes(move.getMove().type) && move.getMove().category !== MoveCategory.STATUS)
|
||||||
|
.map(move => move!.getMove().type);
|
||||||
|
if (priorityTypes?.length > 0) {
|
||||||
|
priorityTypes = [...new Set(priorityTypes)];
|
||||||
|
randSeedShuffle(priorityTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newTypes = [originalTypes[0]];
|
||||||
|
let secondType: Type | null = null;
|
||||||
|
while (secondType === null || secondType === newTypes[0] || originalTypes.includes(secondType)) {
|
||||||
|
if (priorityTypes.length > 0) {
|
||||||
|
secondType = priorityTypes.pop() ?? null;
|
||||||
|
} else {
|
||||||
|
secondType = randSeedInt(18) as Type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newTypes.push(secondType);
|
||||||
|
if (!pokemon.mysteryEncounterPokemonData) {
|
||||||
|
pokemon.mysteryEncounterPokemonData = new MysteryEncounterPokemonData();
|
||||||
|
}
|
||||||
|
pokemon.mysteryEncounterPokemonData.types = newTypes;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.withPostOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Play animations
|
||||||
|
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
|
background.playWithoutTargets(scene, 230, 40, 2);
|
||||||
|
await transitionMysteryEncounterIntroVisuals(scene, true, true, 200);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOutroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.outro`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.build();
|
||||||
|
|
||||||
|
async function handleSwapAbility(scene: BattleScene) {
|
||||||
|
return new Promise<boolean>(async resolve => {
|
||||||
|
await showEncounterDialogue(scene, `${namespace}.option.1.apply_ability_dialogue`, `${namespace}.speaker`);
|
||||||
|
await showEncounterText(scene, `${namespace}.option.1.apply_ability_message`);
|
||||||
|
|
||||||
|
scene.ui.setMode(Mode.MESSAGE).then(() => {
|
||||||
|
displayYesNoOptions(scene, resolve);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayYesNoOptions(scene: BattleScene, resolve) {
|
||||||
|
showEncounterText(scene, `${namespace}.option.1.ability_prompt`, null, 500, false);
|
||||||
|
const fullOptions = [
|
||||||
|
{
|
||||||
|
label: i18next.t("menu:yes"),
|
||||||
|
handler: () => {
|
||||||
|
onYesAbilitySwap(scene, resolve);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: i18next.t("menu:no"),
|
||||||
|
handler: () => {
|
||||||
|
resolve(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const config: OptionSelectConfig = {
|
||||||
|
options: fullOptions,
|
||||||
|
maxOptions: 7,
|
||||||
|
yOffset: 0
|
||||||
|
};
|
||||||
|
scene.ui.setModeWithoutClear(Mode.OPTION_SELECT, config, null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onYesAbilitySwap(scene: BattleScene, resolve) {
|
||||||
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
|
// Do ability swap
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
if (!pokemon.mysteryEncounterPokemonData) {
|
||||||
|
pokemon.mysteryEncounterPokemonData = new MysteryEncounterPokemonData();
|
||||||
|
}
|
||||||
|
pokemon.mysteryEncounterPokemonData.ability = encounter.misc.ability;
|
||||||
|
encounter.setDialogueToken("chosenPokemon", pokemon.getNameToRender());
|
||||||
|
scene.ui.setMode(Mode.MESSAGE).then(() => resolve(true));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPokemonNotSelected = () => {
|
||||||
|
scene.ui.setMode(Mode.MESSAGE).then(() => {
|
||||||
|
displayYesNoOptions(scene, resolve);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
selectPokemonForOption(scene, onPokemonSelected, onPokemonNotSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItems: number, tier: ModifierTier | "Berries") {
|
||||||
|
// These pools have to be defined at runtime so that modifierTypes exist
|
||||||
|
// Pools have instances of the modifier type equal to the max stacks that modifier can be applied to any one pokemon
|
||||||
|
// This is to prevent "over-generating" a random item of a certain type during item swaps
|
||||||
|
const ultraPool = [
|
||||||
|
[modifierTypes.REVIVER_SEED, 1],
|
||||||
|
[modifierTypes.GOLDEN_PUNCH, 5],
|
||||||
|
[modifierTypes.ATTACK_TYPE_BOOSTER, 99],
|
||||||
|
[modifierTypes.QUICK_CLAW, 3],
|
||||||
|
[modifierTypes.WIDE_LENS, 3]
|
||||||
|
];
|
||||||
|
|
||||||
|
const roguePool = [
|
||||||
|
[modifierTypes.LEFTOVERS, 4],
|
||||||
|
[modifierTypes.SHELL_BELL, 4],
|
||||||
|
[modifierTypes.SOUL_DEW, 10],
|
||||||
|
[modifierTypes.SOOTHE_BELL, 3],
|
||||||
|
[modifierTypes.SCOPE_LENS, 1],
|
||||||
|
[modifierTypes.BATON, 1],
|
||||||
|
[modifierTypes.FOCUS_BAND, 5],
|
||||||
|
[modifierTypes.KINGS_ROCK, 3],
|
||||||
|
[modifierTypes.GRIP_CLAW, 5]
|
||||||
|
];
|
||||||
|
|
||||||
|
const berryPool = [
|
||||||
|
[BerryType.APICOT, 3],
|
||||||
|
[BerryType.ENIGMA, 2],
|
||||||
|
[BerryType.GANLON, 3],
|
||||||
|
[BerryType.LANSAT, 3],
|
||||||
|
[BerryType.LEPPA, 2],
|
||||||
|
[BerryType.LIECHI, 3],
|
||||||
|
[BerryType.LUM, 2],
|
||||||
|
[BerryType.PETAYA, 3],
|
||||||
|
[BerryType.SALAC, 2],
|
||||||
|
[BerryType.SITRUS, 2],
|
||||||
|
[BerryType.STARF, 3]
|
||||||
|
];
|
||||||
|
|
||||||
|
let pool: any[];
|
||||||
|
if (tier === "Berries") {
|
||||||
|
pool = berryPool;
|
||||||
|
} else {
|
||||||
|
pool = tier === ModifierTier.ULTRA ? ultraPool : roguePool;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < numItems; i++) {
|
||||||
|
const randIndex = randSeedInt(pool.length);
|
||||||
|
const newItemType = pool[randIndex];
|
||||||
|
let newMod;
|
||||||
|
if (tier === "Berries") {
|
||||||
|
newMod = generateModifierType(scene, modifierTypes.BERRY, [newItemType[0]]) as PokemonHeldItemModifierType;
|
||||||
|
} else {
|
||||||
|
newMod = generateModifierType(scene, newItemType[0]) as PokemonHeldItemModifierType;
|
||||||
|
}
|
||||||
|
applyModifierTypeToPlayerPokemon(scene, pokemon, newMod);
|
||||||
|
// Decrement max stacks and remove from pool if at max
|
||||||
|
newItemType[1]--;
|
||||||
|
if (newItemType[1] <= 0) {
|
||||||
|
pool.splice(randIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,325 @@
|
||||||
|
import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { TrainerSlot } from "#app/data/trainer-config";
|
||||||
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
|
import { Biome } from "#enums/biome";
|
||||||
|
import { EncounterBattleAnim } from "#app/data/battle-anims";
|
||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { getEncounterText, queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
|
import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||||
|
import { DANCING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||||
|
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { catchPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { PokeballType } from "#enums/pokeball";
|
||||||
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||||
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
|
import { Stat } from "#enums/stat";
|
||||||
|
import { EncounterAnim } from "#enums/encounter-anims";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** the i18n namespace for this encounter */
|
||||||
|
const namespace = "mysteryEncounter:dancingLessons";
|
||||||
|
|
||||||
|
// Fire form
|
||||||
|
const BAILE_STYLE_BIOMES = [
|
||||||
|
Biome.VOLCANO,
|
||||||
|
Biome.BEACH,
|
||||||
|
Biome.ISLAND,
|
||||||
|
Biome.WASTELAND,
|
||||||
|
Biome.MOUNTAIN,
|
||||||
|
Biome.BADLANDS,
|
||||||
|
Biome.DESERT
|
||||||
|
];
|
||||||
|
|
||||||
|
// Electric form
|
||||||
|
const POM_POM_STYLE_BIOMES = [
|
||||||
|
Biome.CONSTRUCTION_SITE,
|
||||||
|
Biome.POWER_PLANT,
|
||||||
|
Biome.FACTORY,
|
||||||
|
Biome.LABORATORY,
|
||||||
|
Biome.SLUM,
|
||||||
|
Biome.METROPOLIS,
|
||||||
|
Biome.DOJO
|
||||||
|
];
|
||||||
|
|
||||||
|
// Psychic form
|
||||||
|
const PAU_STYLE_BIOMES = [
|
||||||
|
Biome.JUNGLE,
|
||||||
|
Biome.FAIRY_CAVE,
|
||||||
|
Biome.MEADOW,
|
||||||
|
Biome.PLAINS,
|
||||||
|
Biome.GRASS,
|
||||||
|
Biome.TALL_GRASS,
|
||||||
|
Biome.FOREST
|
||||||
|
];
|
||||||
|
|
||||||
|
// Ghost form
|
||||||
|
const SENSU_STYLE_BIOMES = [
|
||||||
|
Biome.RUINS,
|
||||||
|
Biome.SWAMP,
|
||||||
|
Biome.CAVE,
|
||||||
|
Biome.ABYSS,
|
||||||
|
Biome.GRAVEYARD,
|
||||||
|
Biome.LAKE,
|
||||||
|
Biome.TEMPLE
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dancing Lessons encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3823 | GitHub Issue #3823}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const DancingLessonsEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DANCING_LESSONS)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withIntroSpriteConfigs([]) // Uses a real Pokemon sprite instead of ME Intro Visuals
|
||||||
|
.withAnimations(EncounterAnim.DANCE)
|
||||||
|
.withHideWildIntroMessage(true)
|
||||||
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.withCatchAllowed(true)
|
||||||
|
.withOnVisualsStart((scene: BattleScene) => {
|
||||||
|
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, scene.getEnemyPokemon()!, scene.getParty()[0]);
|
||||||
|
danceAnim.play(scene);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
const species = getPokemonSpecies(Species.ORICORIO);
|
||||||
|
const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0);
|
||||||
|
const enemyPokemon = new EnemyPokemon(scene, species, level, TrainerSlot.NONE, false);
|
||||||
|
if (!enemyPokemon.moveset.some(m => m && m.getMove().id === Moves.REVELATION_DANCE)) {
|
||||||
|
if (enemyPokemon.moveset.length < 4) {
|
||||||
|
enemyPokemon.moveset.push(new PokemonMove(Moves.REVELATION_DANCE));
|
||||||
|
} else {
|
||||||
|
enemyPokemon.moveset[0] = new PokemonMove(Moves.REVELATION_DANCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the form index based on the biome
|
||||||
|
// Defaults to Baile style if somehow nothing matches
|
||||||
|
const currentBiome = scene.arena.biomeType;
|
||||||
|
if (BAILE_STYLE_BIOMES.includes(currentBiome)) {
|
||||||
|
enemyPokemon.formIndex = 0;
|
||||||
|
} else if (POM_POM_STYLE_BIOMES.includes(currentBiome)) {
|
||||||
|
enemyPokemon.formIndex = 1;
|
||||||
|
} else if (PAU_STYLE_BIOMES.includes(currentBiome)) {
|
||||||
|
enemyPokemon.formIndex = 2;
|
||||||
|
} else if (SENSU_STYLE_BIOMES.includes(currentBiome)) {
|
||||||
|
enemyPokemon.formIndex = 3;
|
||||||
|
} else {
|
||||||
|
enemyPokemon.formIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oricorioData = new PokemonData(enemyPokemon);
|
||||||
|
const oricorio = scene.addEnemyPokemon(species, scene.currentBattle.enemyLevels![0], TrainerSlot.NONE, false, oricorioData);
|
||||||
|
|
||||||
|
// Adds a real Pokemon sprite to the field (required for the animation)
|
||||||
|
scene.getEnemyParty().forEach(enemyPokemon => {
|
||||||
|
scene.field.remove(enemyPokemon, true);
|
||||||
|
});
|
||||||
|
scene.currentBattle.enemyParty = [oricorio];
|
||||||
|
scene.field.add(oricorio);
|
||||||
|
// Spawns on offscreen field
|
||||||
|
oricorio.x -= 300;
|
||||||
|
encounter.loadAssets.push(oricorio.loadAssets());
|
||||||
|
|
||||||
|
const config: EnemyPartyConfig = {
|
||||||
|
levelAdditiveMultiplier: 1,
|
||||||
|
pokemonConfigs: [{
|
||||||
|
species: species,
|
||||||
|
dataSource: oricorioData,
|
||||||
|
isBoss: true,
|
||||||
|
// Gets +1 to all stats except SPD on battle start
|
||||||
|
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||||
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
|
queueEncounterMessage(pokemon.scene, `${namespace}.option.1.boss_enraged`);
|
||||||
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF], 1));
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
encounter.enemyPartyConfigs = [config];
|
||||||
|
encounter.misc = {
|
||||||
|
oricorioData
|
||||||
|
};
|
||||||
|
|
||||||
|
encounter.setDialogueToken("oricorioName", getPokemonSpecies(Species.ORICORIO).getName());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.1.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Pick battle
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
encounter.startOfBattleEffects.push({
|
||||||
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
|
targets: [BattlerIndex.PLAYER],
|
||||||
|
move: new PokemonMove(Moves.REVELATION_DANCE),
|
||||||
|
ignorePp: true
|
||||||
|
});
|
||||||
|
|
||||||
|
await hideOricorioPokemon(scene);
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.BATON], fillRemaining: true });
|
||||||
|
await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.2.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Learn its Dance
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
|
encounter.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
|
||||||
|
scene.unshiftPhase(new LearnMovePhase(scene, scene.getParty().indexOf(pokemon), Moves.REVELATION_DANCE));
|
||||||
|
|
||||||
|
// Play animation again to "learn" the dance
|
||||||
|
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, scene.getEnemyPokemon()!, scene.getPlayerPokemon());
|
||||||
|
danceAnim.play(scene);
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectPokemonForOption(scene, onPokemonSelected);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Learn its Dance
|
||||||
|
hideOricorioPokemon(scene);
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
|
.withPrimaryPokemonRequirement(new MoveRequirement(DANCING_MOVES)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
||||||
|
secondOptionPrompt: `${namespace}.option.3.select_prompt`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Open menu for selecting pokemon with a Dancing move
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
|
// Return the options for nature selection
|
||||||
|
return pokemon.moveset
|
||||||
|
.filter(move => move && DANCING_MOVES.includes(move.getMove().id))
|
||||||
|
.map((move: PokemonMove) => {
|
||||||
|
const option: OptionSelectItem = {
|
||||||
|
label: move.getName(),
|
||||||
|
handler: () => {
|
||||||
|
// Pokemon and second option selected
|
||||||
|
encounter.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
|
||||||
|
encounter.setDialogueToken("selectedMove", move.getName());
|
||||||
|
encounter.misc.selectedMove = move;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only Pokemon that have a Dancing move can be selected
|
||||||
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
|
// If pokemon meets primary pokemon reqs, it can be selected
|
||||||
|
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
|
if (!meetsReqs) {
|
||||||
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Show the Oricorio a dance, and recruit it
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const oricorio = encounter.misc.oricorioData.toPokemon(scene);
|
||||||
|
oricorio.passive = true;
|
||||||
|
|
||||||
|
// Ensure the Oricorio's moveset gains the Dance move the player used
|
||||||
|
const move = encounter.misc.selectedMove?.getMove().id;
|
||||||
|
if (!oricorio.moveset.some(m => m.getMove().id === move)) {
|
||||||
|
if (oricorio.moveset.length < 4) {
|
||||||
|
oricorio.moveset.push(new PokemonMove(move));
|
||||||
|
} else {
|
||||||
|
oricorio.moveset[3] = new PokemonMove(move);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hideOricorioPokemon(scene);
|
||||||
|
await catchPokemon(scene, oricorio, null, PokeballType.POKEBALL, false);
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
function hideOricorioPokemon(scene: BattleScene) {
|
||||||
|
return new Promise<void>(resolve => {
|
||||||
|
const oricorioSprite = scene.getEnemyParty()[0];
|
||||||
|
scene.tweens.add({
|
||||||
|
targets: oricorioSprite,
|
||||||
|
x: "+=16",
|
||||||
|
y: "-=16",
|
||||||
|
alpha: 0,
|
||||||
|
ease: "Sine.easeInOut",
|
||||||
|
duration: 750,
|
||||||
|
onComplete: () => {
|
||||||
|
scene.field.remove(oricorioSprite, true);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,197 @@
|
||||||
|
import { Type } from "#app/data/type";
|
||||||
|
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||||
|
import { EnemyPartyConfig, EnemyPokemonConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, } from "../utils/encounter-phase-utils";
|
||||||
|
import { getRandomPlayerPokemon, getRandomSpeciesByStarterTier } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
|
import { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** i18n namespace for encounter */
|
||||||
|
const namespace = "mysteryEncounter:darkDeal";
|
||||||
|
|
||||||
|
/** Exclude Ultra Beasts (inludes Cosmog/Solgaleo/Lunala/Necrozma), Paradox (includes Miraidon/Koraidon), Eternatus, and egg-locked mythicals */
|
||||||
|
const excludedBosses = [
|
||||||
|
Species.NECROZMA,
|
||||||
|
Species.COSMOG,
|
||||||
|
Species.COSMOEM,
|
||||||
|
Species.SOLGALEO,
|
||||||
|
Species.LUNALA,
|
||||||
|
Species.ETERNATUS,
|
||||||
|
Species.NIHILEGO,
|
||||||
|
Species.BUZZWOLE,
|
||||||
|
Species.PHEROMOSA,
|
||||||
|
Species.XURKITREE,
|
||||||
|
Species.CELESTEELA,
|
||||||
|
Species.KARTANA,
|
||||||
|
Species.GUZZLORD,
|
||||||
|
Species.POIPOLE,
|
||||||
|
Species.NAGANADEL,
|
||||||
|
Species.STAKATAKA,
|
||||||
|
Species.BLACEPHALON,
|
||||||
|
Species.GREAT_TUSK,
|
||||||
|
Species.SCREAM_TAIL,
|
||||||
|
Species.BRUTE_BONNET,
|
||||||
|
Species.FLUTTER_MANE,
|
||||||
|
Species.SLITHER_WING,
|
||||||
|
Species.SANDY_SHOCKS,
|
||||||
|
Species.ROARING_MOON,
|
||||||
|
Species.KORAIDON,
|
||||||
|
Species.WALKING_WAKE,
|
||||||
|
Species.GOUGING_FIRE,
|
||||||
|
Species.RAGING_BOLT,
|
||||||
|
Species.IRON_TREADS,
|
||||||
|
Species.IRON_BUNDLE,
|
||||||
|
Species.IRON_HANDS,
|
||||||
|
Species.IRON_JUGULIS,
|
||||||
|
Species.IRON_MOTH,
|
||||||
|
Species.IRON_THORNS,
|
||||||
|
Species.IRON_VALIANT,
|
||||||
|
Species.MIRAIDON,
|
||||||
|
Species.IRON_LEAVES,
|
||||||
|
Species.IRON_BOULDER,
|
||||||
|
Species.IRON_CROWN,
|
||||||
|
Species.MEW,
|
||||||
|
Species.CELEBI,
|
||||||
|
Species.DEOXYS,
|
||||||
|
Species.JIRACHI,
|
||||||
|
Species.PHIONE,
|
||||||
|
Species.MANAPHY,
|
||||||
|
Species.ARCEUS,
|
||||||
|
Species.VICTINI,
|
||||||
|
Species.MELTAN,
|
||||||
|
Species.PECHARUNT,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dark Deal encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3806 | GitHub Issue #3806}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const DarkDealEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DARK_DEAL)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||||
|
.withIntroSpriteConfigs([
|
||||||
|
{
|
||||||
|
spriteKey: "mad_scientist_m",
|
||||||
|
fileRoot: "mystery-encounters",
|
||||||
|
hasShadow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "dark_deal_porygon",
|
||||||
|
fileRoot: "mystery-encounters",
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.intro_dialogue`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withSceneWaveRangeRequirement(30, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
|
.withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party
|
||||||
|
.withCatchAllowed(true)
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.1.selected_dialogue`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.1.selected_message`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Removes random pokemon (including fainted) from party and adds name to dialogue data tokens
|
||||||
|
// Will never return last battle able mon and instead pick fainted/unable to battle
|
||||||
|
const removedPokemon = getRandomPlayerPokemon(scene, false, true);
|
||||||
|
// Get all the pokemon's held items
|
||||||
|
const modifiers = removedPokemon.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier));
|
||||||
|
scene.removePokemonFromPlayerParty(removedPokemon);
|
||||||
|
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
encounter.setDialogueToken("pokeName", removedPokemon.getNameToRender());
|
||||||
|
|
||||||
|
// Store removed pokemon types
|
||||||
|
encounter.misc = {
|
||||||
|
removedTypes: removedPokemon.getTypes(),
|
||||||
|
modifiers
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Give the player 5 Rogue Balls
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.ROGUE_BALL));
|
||||||
|
|
||||||
|
// Start encounter with random legendary (7-10 starter strength) that has level additive
|
||||||
|
const bossTypes: Type[] = encounter.misc.removedTypes;
|
||||||
|
const bossModifiers: PokemonHeldItemModifier[] = encounter.misc.modifiers;
|
||||||
|
// Starter egg tier, 35/50/10/5 %odds for tiers 6/7/8/9+
|
||||||
|
const roll = randSeedInt(100);
|
||||||
|
const starterTier: number | [number, number] =
|
||||||
|
roll > 65 ? 6 : roll > 15 ? 7 : roll > 5 ? 8 : [9, 10];
|
||||||
|
const bossSpecies = getPokemonSpecies(getRandomSpeciesByStarterTier(starterTier, excludedBosses, bossTypes));
|
||||||
|
const pokemonConfig: EnemyPokemonConfig = {
|
||||||
|
species: bossSpecies,
|
||||||
|
isBoss: true,
|
||||||
|
modifierConfigs: bossModifiers.map(m => {
|
||||||
|
return {
|
||||||
|
modifier: m
|
||||||
|
};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
if (!isNullOrUndefined(bossSpecies.forms) && bossSpecies.forms.length > 0) {
|
||||||
|
pokemonConfig.formIndex = 0;
|
||||||
|
}
|
||||||
|
const config: EnemyPartyConfig = {
|
||||||
|
pokemonConfigs: [pokemonConfig],
|
||||||
|
};
|
||||||
|
return initBattleWithEnemyConfig(scene, config);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
text: `${namespace}.option.2.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Leave encounter with no rewards or exp
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withOutroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.outro`
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.build();
|
|
@ -0,0 +1,309 @@
|
||||||
|
import { generateModifierType, leaveEncounterWithoutBattle, selectPokemonForOption, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
||||||
|
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||||
|
import { CombinationPokemonRequirement, HeldItemRequirement, MoneyRequirement } from "../mystery-encounter-requirements";
|
||||||
|
import { getEncounterText, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { HealingBoosterModifier, HiddenAbilityRateBoosterModifier, LevelIncrementBoosterModifier, PokemonHeldItemModifier, PreserveBerryModifier } from "#app/modifier/modifier";
|
||||||
|
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||||
|
import { applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import i18next from "#app/plugins/i18n";
|
||||||
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** the i18n namespace for this encounter */
|
||||||
|
const namespace = "mysteryEncounter:delibirdy";
|
||||||
|
|
||||||
|
/** Berries only */
|
||||||
|
const OPTION_2_ALLOWED_MODIFIERS = ["BerryModifier", "PokemonInstantReviveModifier"];
|
||||||
|
|
||||||
|
/** Disallowed items are berries, Reviver Seeds, and Vitamins (form change items and fusion items are not PokemonHeldItemModifiers) */
|
||||||
|
const OPTION_3_DISALLOWED_MODIFIERS = [
|
||||||
|
"BerryModifier",
|
||||||
|
"PokemonInstantReviveModifier",
|
||||||
|
"TerastallizeModifier",
|
||||||
|
"PokemonBaseStatModifier",
|
||||||
|
"PokemonBaseStatTotalModifier"
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delibird-y encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3804 | GitHub Issue #3804}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const DelibirdyEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DELIBIRDY)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withSceneRequirement(new MoneyRequirement(0, 2)) // Must have enough money for it to spawn at the very least
|
||||||
|
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement( // Must also have either option 2 or 3 available to spawn
|
||||||
|
new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS),
|
||||||
|
new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true)
|
||||||
|
))
|
||||||
|
.withIntroSpriteConfigs([
|
||||||
|
{
|
||||||
|
spriteKey: "",
|
||||||
|
fileRoot: "",
|
||||||
|
species: Species.DELIBIRD,
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
startFrame: 38,
|
||||||
|
scale: 0.94
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "",
|
||||||
|
fileRoot: "",
|
||||||
|
species: Species.DELIBIRD,
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
scale: 1.06
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "",
|
||||||
|
fileRoot: "",
|
||||||
|
species: Species.DELIBIRD,
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
startFrame: 65,
|
||||||
|
x: 1,
|
||||||
|
y: 5,
|
||||||
|
yShadow: 5
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withOutroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.outro`,
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
encounter.setDialogueToken("delibirdName", getPokemonSpecies(Species.DELIBIRD).getName());
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
|
.withSceneMoneyRequirement(0, 2) // Must have money to spawn
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.1.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
updatePlayerMoney(scene, -(encounter.options[0].requirements[0] as MoneyRequirement).requiredMoney, true, false);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Give the player an Ability Charm
|
||||||
|
// Check if the player has max stacks of that item already
|
||||||
|
const existing = scene.findModifier(m => m instanceof HiddenAbilityRateBoosterModifier) as HiddenAbilityRateBoosterModifier;
|
||||||
|
|
||||||
|
if (existing && existing.getStackCount() >= existing.getMaxStackCount(scene)) {
|
||||||
|
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||||
|
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||||
|
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||||
|
scene.playSound("item_fanfare");
|
||||||
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true);
|
||||||
|
} else {
|
||||||
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.ABILITY_CHARM));
|
||||||
|
}
|
||||||
|
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
|
.withPrimaryPokemonRequirement(new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS))
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
secondOptionPrompt: `${namespace}.option.2.select_prompt`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.2.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
|
// Get Pokemon held items and filter for valid ones
|
||||||
|
const validItems = pokemon.getHeldItems().filter((it) => {
|
||||||
|
return OPTION_2_ALLOWED_MODIFIERS.some(heldItem => it.constructor.name === heldItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
return validItems.map((modifier: PokemonHeldItemModifier) => {
|
||||||
|
const option: OptionSelectItem = {
|
||||||
|
label: modifier.type.name,
|
||||||
|
handler: () => {
|
||||||
|
// Pokemon and item selected
|
||||||
|
encounter.setDialogueToken("chosenItem", modifier.type.name);
|
||||||
|
encounter.misc = {
|
||||||
|
chosenPokemon: pokemon,
|
||||||
|
chosenModifier: modifier,
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only Pokemon that can gain benefits are above 1/3rd HP with no status
|
||||||
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
|
// If pokemon meets primary pokemon reqs, it can be selected
|
||||||
|
const meetsReqs = encounter.options[1].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
|
if (!meetsReqs) {
|
||||||
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const modifier = encounter.misc.chosenModifier;
|
||||||
|
|
||||||
|
// Give the player a Candy Jar if they gave a Berry, and a Healing Charm for Reviver Seed
|
||||||
|
if (modifier.type.name.includes("Berry")) {
|
||||||
|
// Check if the player has max stacks of that Candy Jar already
|
||||||
|
const existing = scene.findModifier(m => m instanceof LevelIncrementBoosterModifier) as LevelIncrementBoosterModifier;
|
||||||
|
|
||||||
|
if (existing && existing.getStackCount() >= existing.getMaxStackCount(scene)) {
|
||||||
|
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||||
|
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||||
|
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||||
|
scene.playSound("item_fanfare");
|
||||||
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true);
|
||||||
|
} else {
|
||||||
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.CANDY_JAR));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Check if the player has max stacks of that Healing Charm already
|
||||||
|
const existing = scene.findModifier(m => m instanceof HealingBoosterModifier) as HealingBoosterModifier;
|
||||||
|
|
||||||
|
if (existing && existing.getStackCount() >= existing.getMaxStackCount(scene)) {
|
||||||
|
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||||
|
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||||
|
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||||
|
scene.playSound("item_fanfare");
|
||||||
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true);
|
||||||
|
} else {
|
||||||
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.HEALING_CHARM));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the modifier if its stacks go to 0
|
||||||
|
modifier.stackCount -= 1;
|
||||||
|
if (modifier.stackCount === 0) {
|
||||||
|
scene.removeModifier(modifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
|
.withPrimaryPokemonRequirement(new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true))
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
secondOptionPrompt: `${namespace}.option.3.select_prompt`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
|
// Get Pokemon held items and filter for valid ones
|
||||||
|
const validItems = pokemon.getHeldItems().filter((it) => {
|
||||||
|
return !OPTION_3_DISALLOWED_MODIFIERS.some(heldItem => it.constructor.name === heldItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
return validItems.map((modifier: PokemonHeldItemModifier) => {
|
||||||
|
const option: OptionSelectItem = {
|
||||||
|
label: modifier.type.name,
|
||||||
|
handler: () => {
|
||||||
|
// Pokemon and item selected
|
||||||
|
encounter.setDialogueToken("chosenItem", modifier.type.name);
|
||||||
|
encounter.misc = {
|
||||||
|
chosenPokemon: pokemon,
|
||||||
|
chosenModifier: modifier,
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only Pokemon that can gain benefits are above 1/3rd HP with no status
|
||||||
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
|
// If pokemon meets primary pokemon reqs, it can be selected
|
||||||
|
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
|
if (!meetsReqs) {
|
||||||
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const modifier = encounter.misc.chosenModifier;
|
||||||
|
|
||||||
|
// Check if the player has max stacks of Berry Pouch already
|
||||||
|
const existing = scene.findModifier(m => m instanceof PreserveBerryModifier) as PreserveBerryModifier;
|
||||||
|
|
||||||
|
if (existing && existing.getStackCount() >= existing.getMaxStackCount(scene)) {
|
||||||
|
// At max stacks, give the first party pokemon a Shell Bell instead
|
||||||
|
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||||
|
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||||
|
scene.playSound("item_fanfare");
|
||||||
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, undefined, true);
|
||||||
|
} else {
|
||||||
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.BERRY_POUCH));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the modifier if its stacks go to 0
|
||||||
|
modifier.stackCount -= 1;
|
||||||
|
if (modifier.stackCount === 0) {
|
||||||
|
scene.removeModifier(modifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build();
|
|
@ -0,0 +1,164 @@
|
||||||
|
import {
|
||||||
|
leaveEncounterWithoutBattle,
|
||||||
|
setEncounterRewards,
|
||||||
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import { ModifierTypeFunc, modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
import { randSeedInt } from "#app/utils";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, {
|
||||||
|
MysteryEncounterBuilder,
|
||||||
|
} from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** i18n namespace for encounter */
|
||||||
|
const namespace = "mysteryEncounter:departmentStoreSale";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Department Store Sale encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3797 | GitHub Issue #3797}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DEPARTMENT_STORE_SALE)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
|
.withSceneWaveRangeRequirement(CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[0], 100)
|
||||||
|
.withIntroSpriteConfigs([
|
||||||
|
{
|
||||||
|
spriteKey: "b2w2_lady",
|
||||||
|
fileRoot: "mystery-encounters",
|
||||||
|
hasShadow: true,
|
||||||
|
x: -20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "",
|
||||||
|
fileRoot: "",
|
||||||
|
species: Species.FURFROU,
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
x: 30,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro_dialogue`,
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Choose TMs
|
||||||
|
const modifiers: ModifierTypeFunc[] = [];
|
||||||
|
let i = 0;
|
||||||
|
while (i < 4) {
|
||||||
|
// 2/2/1 weight on TM rarity
|
||||||
|
const roll = randSeedInt(5);
|
||||||
|
if (roll < 2) {
|
||||||
|
modifiers.push(modifierTypes.TM_COMMON);
|
||||||
|
} else if (roll < 4) {
|
||||||
|
modifiers.push(modifierTypes.TM_GREAT);
|
||||||
|
} else {
|
||||||
|
modifiers.push(modifierTypes.TM_ULTRA);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false, });
|
||||||
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Choose Vitamins
|
||||||
|
const modifiers: ModifierTypeFunc[] = [];
|
||||||
|
let i = 0;
|
||||||
|
while (i < 3) {
|
||||||
|
// 2/1 weight on base stat booster vs PP Up
|
||||||
|
const roll = randSeedInt(3);
|
||||||
|
if (roll === 0) {
|
||||||
|
modifiers.push(modifierTypes.PP_UP);
|
||||||
|
} else {
|
||||||
|
modifiers.push(modifierTypes.BASE_STAT_BOOSTER);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false, });
|
||||||
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Choose X Items
|
||||||
|
const modifiers: ModifierTypeFunc[] = [];
|
||||||
|
let i = 0;
|
||||||
|
while (i < 5) {
|
||||||
|
// 4/1 weight on base stat booster vs Dire Hit
|
||||||
|
const roll = randSeedInt(5);
|
||||||
|
if (roll === 0) {
|
||||||
|
modifiers.push(modifierTypes.DIRE_HIT);
|
||||||
|
} else {
|
||||||
|
modifiers.push(modifierTypes.TEMP_STAT_STAGE_BOOSTER);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false, });
|
||||||
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.4.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.4.tooltip`,
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Choose Pokeballs
|
||||||
|
const modifiers: ModifierTypeFunc[] = [];
|
||||||
|
let i = 0;
|
||||||
|
while (i < 4) {
|
||||||
|
// 10/30/20/5 weight on pokeballs
|
||||||
|
const roll = randSeedInt(65);
|
||||||
|
if (roll < 10) {
|
||||||
|
modifiers.push(modifierTypes.POKEBALL);
|
||||||
|
} else if (roll < 40) {
|
||||||
|
modifiers.push(modifierTypes.GREAT_BALL);
|
||||||
|
} else if (roll < 60) {
|
||||||
|
modifiers.push(modifierTypes.ULTRA_BALL);
|
||||||
|
} else {
|
||||||
|
modifiers.push(modifierTypes.ROGUE_BALL);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false, });
|
||||||
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withOutroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.outro`,
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.build();
|
|
@ -0,0 +1,235 @@
|
||||||
|
import { MoveCategory } from "#app/data/move";
|
||||||
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
|
import { generateModifierTypeOption, leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterExp, setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import { PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { Stat } from "#enums/stat";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** i18n namespace for the encounter */
|
||||||
|
const namespace = "mysteryEncounter:fieldTrip";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field Trip encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3794 | GitHub Issue #3794}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const FieldTripEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIELD_TRIP)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withIntroSpriteConfigs([
|
||||||
|
{
|
||||||
|
spriteKey: "preschooler_m",
|
||||||
|
fileRoot: "trainer",
|
||||||
|
hasShadow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "teacher",
|
||||||
|
fileRoot: "mystery-encounters",
|
||||||
|
hasShadow: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "preschooler_f",
|
||||||
|
fileRoot: "trainer",
|
||||||
|
hasShadow: true,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro_dialogue`,
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
secondOptionPrompt: `${namespace}.second_option_prompt`,
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
|
// Return the options for Pokemon move valid for this option
|
||||||
|
return pokemon.moveset.map((move: PokemonMove) => {
|
||||||
|
const option: OptionSelectItem = {
|
||||||
|
label: move.getName(),
|
||||||
|
handler: () => {
|
||||||
|
// Pokemon and move selected
|
||||||
|
encounter.setDialogueToken("moveCategory", i18next.t(`${namespace}.physical`));
|
||||||
|
pokemonAndMoveChosen(scene, pokemon, move, MoveCategory.PHYSICAL);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectPokemonForOption(scene, onPokemonSelected);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
if (encounter.misc.correctMove) {
|
||||||
|
const modifiers = [
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ATK])!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.DEF])!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||||
|
];
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
leaveEncounterWithoutBattle(scene, !encounter.misc.correctMove);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
secondOptionPrompt: `${namespace}.second_option_prompt`,
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
|
// Return the options for Pokemon move valid for this option
|
||||||
|
return pokemon.moveset.map((move: PokemonMove) => {
|
||||||
|
const option: OptionSelectItem = {
|
||||||
|
label: move.getName(),
|
||||||
|
handler: () => {
|
||||||
|
// Pokemon and move selected
|
||||||
|
encounter.setDialogueToken("moveCategory", i18next.t(`${namespace}.special`));
|
||||||
|
pokemonAndMoveChosen(scene, pokemon, move, MoveCategory.SPECIAL);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectPokemonForOption(scene, onPokemonSelected);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
if (encounter.misc.correctMove) {
|
||||||
|
const modifiers = [
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPATK])!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPDEF])!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||||
|
];
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
leaveEncounterWithoutBattle(scene, !encounter.misc.correctMove);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
secondOptionPrompt: `${namespace}.second_option_prompt`,
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
|
// Return the options for Pokemon move valid for this option
|
||||||
|
return pokemon.moveset.map((move: PokemonMove) => {
|
||||||
|
const option: OptionSelectItem = {
|
||||||
|
label: move.getName(),
|
||||||
|
handler: () => {
|
||||||
|
// Pokemon and move selected
|
||||||
|
encounter.setDialogueToken("moveCategory", i18next.t(`${namespace}.status`));
|
||||||
|
pokemonAndMoveChosen(scene, pokemon, move, MoveCategory.STATUS);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectPokemonForOption(scene, onPokemonSelected);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
if (encounter.misc.correctMove) {
|
||||||
|
const modifiers = [
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ACC])!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.GREAT_BALL)!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.IV_SCANNER)!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||||
|
];
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
leaveEncounterWithoutBattle(scene, !encounter.misc.correctMove);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
function pokemonAndMoveChosen(scene: BattleScene, pokemon: PlayerPokemon, move: PokemonMove, correctMoveCategory: MoveCategory) {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const correctMove = move.getMove().category === correctMoveCategory;
|
||||||
|
encounter.setDialogueToken("pokeName", pokemon.getNameToRender());
|
||||||
|
encounter.setDialogueToken("move", move.getName());
|
||||||
|
if (!correctMove) {
|
||||||
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.selected`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.incorrect`,
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.incorrect_exp`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
setEncounterExp(scene, scene.getParty().map((p) => p.id), 50);
|
||||||
|
} else {
|
||||||
|
encounter.selectedOption!.dialogue!.selected = [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.selected`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.correct`,
|
||||||
|
speaker: `${namespace}.speaker`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: `${namespace}.correct_exp`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
setEncounterExp(scene, [pokemon.id], 100);
|
||||||
|
}
|
||||||
|
encounter.misc = {
|
||||||
|
correctMove: correctMove,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,255 @@
|
||||||
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
|
import { EnemyPartyConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals, generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import { AttackTypeBoosterModifierType, modifierTypes, } from "#app/modifier/modifier-type";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { TypeRequirement } from "../mystery-encounter-requirements";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { Gender } from "#app/data/gender";
|
||||||
|
import { Type } from "#app/data/type";
|
||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { EncounterBattleAnim } from "#app/data/battle-anims";
|
||||||
|
import { WeatherType } from "#app/data/weather";
|
||||||
|
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||||
|
import { StatusEffect } from "#app/data/status-effect";
|
||||||
|
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
|
import { applyDamageToPokemon, applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { EncounterAnim } from "#enums/encounter-anims";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** the i18n namespace for the encounter */
|
||||||
|
const namespace = "mysteryEncounter:fieryFallout";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Damage percentage taken when suffering the heat.
|
||||||
|
* Can be a number between `0` - `100`.
|
||||||
|
* The higher the more damage taken (100% = instant KO).
|
||||||
|
*/
|
||||||
|
const DAMAGE_PERCENTAGE: number = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fiery Fallout encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3814 | GitHub Issue #3814}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const FieryFalloutEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIERY_FALLOUT)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
|
.withSceneWaveRangeRequirement(40, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
|
.withCatchAllowed(true)
|
||||||
|
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||||
|
.withAnimations(EncounterAnim.MAGMA_BG, EncounterAnim.MAGMA_SPOUT)
|
||||||
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
// Calculate boss mons
|
||||||
|
const volcaronaSpecies = getPokemonSpecies(Species.VOLCARONA);
|
||||||
|
const config: EnemyPartyConfig = {
|
||||||
|
pokemonConfigs: [
|
||||||
|
{
|
||||||
|
species: volcaronaSpecies,
|
||||||
|
isBoss: false,
|
||||||
|
gender: Gender.MALE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
species: volcaronaSpecies,
|
||||||
|
isBoss: false,
|
||||||
|
gender: Gender.FEMALE
|
||||||
|
}
|
||||||
|
],
|
||||||
|
doubleBattle: true,
|
||||||
|
disableSwitch: true
|
||||||
|
};
|
||||||
|
encounter.enemyPartyConfigs = [config];
|
||||||
|
|
||||||
|
// Load hidden Volcarona sprites
|
||||||
|
encounter.spriteConfigs = [
|
||||||
|
{
|
||||||
|
spriteKey: "",
|
||||||
|
fileRoot: "",
|
||||||
|
species: Species.VOLCARONA,
|
||||||
|
repeat: true,
|
||||||
|
hidden: true,
|
||||||
|
hasShadow: true,
|
||||||
|
x: -20,
|
||||||
|
startFrame: 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: "",
|
||||||
|
fileRoot: "",
|
||||||
|
species: Species.VOLCARONA,
|
||||||
|
repeat: true,
|
||||||
|
hidden: true,
|
||||||
|
hasShadow: true,
|
||||||
|
x: 20
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Load animations/sfx for Volcarona moves
|
||||||
|
loadCustomMovesForEncounter(scene, [Moves.FIRE_SPIN, Moves.QUIVER_DANCE]);
|
||||||
|
|
||||||
|
scene.arena.trySetWeather(WeatherType.SUNNY, true);
|
||||||
|
|
||||||
|
encounter.setDialogueToken("volcaronaName", getPokemonSpecies(Species.VOLCARONA).getName());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withOnVisualsStart((scene: BattleScene) => {
|
||||||
|
// Play animations
|
||||||
|
const background = new EncounterBattleAnim(EncounterAnim.MAGMA_BG, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
|
background.playWithoutTargets(scene, 200, 70, 2, 3);
|
||||||
|
const animation = new EncounterBattleAnim(EncounterAnim.MAGMA_SPOUT, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
|
animation.playWithoutTargets(scene, 80, 100, 2);
|
||||||
|
scene.time.delayedCall(600, () => {
|
||||||
|
animation.playWithoutTargets(scene, -20, 100, 2);
|
||||||
|
});
|
||||||
|
scene.time.delayedCall(1200, () => {
|
||||||
|
animation.playWithoutTargets(scene, 140, 150, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.1.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Pick battle
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, () => giveLeadPokemonCharcoal(scene));
|
||||||
|
|
||||||
|
encounter.startOfBattleEffects.push(
|
||||||
|
{
|
||||||
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
|
targets: [BattlerIndex.PLAYER],
|
||||||
|
move: new PokemonMove(Moves.FIRE_SPIN),
|
||||||
|
ignorePp: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
||||||
|
targets: [BattlerIndex.PLAYER_2],
|
||||||
|
move: new PokemonMove(Moves.FIRE_SPIN),
|
||||||
|
ignorePp: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
|
targets: [BattlerIndex.ENEMY],
|
||||||
|
move: new PokemonMove(Moves.QUIVER_DANCE),
|
||||||
|
ignorePp: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sourceBattlerIndex: BattlerIndex.ENEMY_2,
|
||||||
|
targets: [BattlerIndex.ENEMY_2],
|
||||||
|
move: new PokemonMove(Moves.QUIVER_DANCE),
|
||||||
|
ignorePp: true
|
||||||
|
});
|
||||||
|
await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.2.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Damage non-fire types and burn 1 random non-fire type member
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const nonFireTypes = scene.getParty().filter((p) => p.isAllowedInBattle() && !p.getTypes().includes(Type.FIRE));
|
||||||
|
|
||||||
|
for (const pkm of nonFireTypes) {
|
||||||
|
const percentage = DAMAGE_PERCENTAGE / 100;
|
||||||
|
const damage = Math.floor(pkm.getMaxHp() * percentage);
|
||||||
|
applyDamageToPokemon(scene, pkm, damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Burn random member
|
||||||
|
const burnable = nonFireTypes.filter(p => isNullOrUndefined(p.status) || isNullOrUndefined(p.status!.effect) || p.status?.effect === StatusEffect.BURN);
|
||||||
|
if (burnable?.length > 0) {
|
||||||
|
const roll = randSeedInt(burnable.length);
|
||||||
|
const chosenPokemon = burnable[roll];
|
||||||
|
if (chosenPokemon.trySetStatus(StatusEffect.BURN)) {
|
||||||
|
// Burn applied
|
||||||
|
encounter.setDialogueToken("burnedPokemon", chosenPokemon.getNameToRender());
|
||||||
|
queueEncounterMessage(scene, `${namespace}.option.2.target_burned`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No rewards
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
|
.withPrimaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3PrimaryName dialogue token automatically
|
||||||
|
.withSecondaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3SecondaryName dialogue token automatically
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
|
transitionMysteryEncounterIntroVisuals(scene, false, false, 2000);
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Fire types help calm the Volcarona
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
transitionMysteryEncounterIntroVisuals(scene);
|
||||||
|
setEncounterRewards(scene,
|
||||||
|
{ fillRemaining: true },
|
||||||
|
undefined,
|
||||||
|
() => {
|
||||||
|
giveLeadPokemonCharcoal(scene);
|
||||||
|
});
|
||||||
|
|
||||||
|
const primary = encounter.options[2].primaryPokemon!;
|
||||||
|
const secondary = encounter.options[2].secondaryPokemon![0];
|
||||||
|
|
||||||
|
setEncounterExp(scene, [primary.id, secondary.id], getPokemonSpecies(Species.VOLCARONA).baseExp * 2);
|
||||||
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
function giveLeadPokemonCharcoal(scene: BattleScene) {
|
||||||
|
// Give first party pokemon Charcoal for free at end of battle
|
||||||
|
const leadPokemon = scene.getParty()?.[0];
|
||||||
|
if (leadPokemon) {
|
||||||
|
const charcoal = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FIRE]) as AttackTypeBoosterModifierType;
|
||||||
|
applyModifierTypeToPlayerPokemon(scene, leadPokemon, charcoal);
|
||||||
|
scene.currentBattle.mysteryEncounter!.setDialogueToken("leadPokemon", leadPokemon.getNameToRender());
|
||||||
|
queueEncounterMessage(scene, `${namespace}.found_charcoal`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
|
import {
|
||||||
|
EnemyPartyConfig,
|
||||||
|
initBattleWithEnemyConfig,
|
||||||
|
leaveEncounterWithoutBattle, setEncounterExp,
|
||||||
|
setEncounterRewards
|
||||||
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||||
|
import Pokemon, { EnemyPokemon } from "#app/field/pokemon";
|
||||||
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
|
import {
|
||||||
|
getPartyLuckValue,
|
||||||
|
getPlayerModifierTypeOptions,
|
||||||
|
ModifierPoolType,
|
||||||
|
ModifierTypeOption,
|
||||||
|
regenerateModifierPoolThresholds,
|
||||||
|
} from "#app/modifier/modifier-type";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MoveRequirement } from "../mystery-encounter-requirements";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { TrainerSlot } from "#app/data/trainer-config";
|
||||||
|
import { getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
|
import { randSeedInt } from "#app/utils";
|
||||||
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
|
/** the i18n namespace for the encounter */
|
||||||
|
const namespace = "mysteryEncounter:fightOrFlight";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fight or Flight encounter.
|
||||||
|
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3795 | GitHub Issue #3795}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const FightOrFlightEncounter: MysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIGHT_OR_FLIGHT)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withCatchAllowed(true)
|
||||||
|
.withHideWildIntroMessage(true)
|
||||||
|
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}.intro`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
|
// Calculate boss mon
|
||||||
|
const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0);
|
||||||
|
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true);
|
||||||
|
const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true);
|
||||||
|
encounter.setDialogueToken("enemyPokemon", bossPokemon.getNameToRender());
|
||||||
|
const config: EnemyPartyConfig = {
|
||||||
|
levelAdditiveMultiplier: 1,
|
||||||
|
pokemonConfigs: [{
|
||||||
|
level: level,
|
||||||
|
species: bossSpecies,
|
||||||
|
dataSource: new PokemonData(bossPokemon),
|
||||||
|
isBoss: true,
|
||||||
|
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
|
||||||
|
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
|
||||||
|
queueEncounterMessage(pokemon.scene, `${namespace}.option.1.stat_boost`);
|
||||||
|
// Randomly boost 1 stat 2 stages
|
||||||
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [randSeedInt(5)], 2));
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
encounter.enemyPartyConfigs = [config];
|
||||||
|
|
||||||
|
// Calculate item
|
||||||
|
// Waves 10-40 GREAT, 60-120 ULTRA, 120-160 ROGUE, 160-180 MASTER
|
||||||
|
const tier =
|
||||||
|
scene.currentBattle.waveIndex > 160
|
||||||
|
? ModifierTier.MASTER
|
||||||
|
: scene.currentBattle.waveIndex > 120
|
||||||
|
? ModifierTier.ROGUE
|
||||||
|
: scene.currentBattle.waveIndex > 40
|
||||||
|
? ModifierTier.ULTRA
|
||||||
|
: ModifierTier.GREAT;
|
||||||
|
regenerateModifierPoolThresholds(scene.getParty(), ModifierPoolType.PLAYER, 0);
|
||||||
|
let item: ModifierTypeOption | null = null;
|
||||||
|
// TMs and Candy Jar excluded from possible rewards as they're too swingy in value for a singular item reward
|
||||||
|
while (!item || item.type.id.includes("TM_") || item.type.id === "CANDY_JAR") {
|
||||||
|
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0];
|
||||||
|
}
|
||||||
|
encounter.setDialogueToken("itemName", item.type.name);
|
||||||
|
encounter.misc = item;
|
||||||
|
|
||||||
|
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(bossPokemon);
|
||||||
|
encounter.spriteConfigs = [
|
||||||
|
{
|
||||||
|
spriteKey: item.type.iconImage,
|
||||||
|
fileRoot: "items",
|
||||||
|
hasShadow: false,
|
||||||
|
x: 35,
|
||||||
|
y: -5,
|
||||||
|
scale: 0.75,
|
||||||
|
isItem: true,
|
||||||
|
disableAnimation: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: spriteKey,
|
||||||
|
fileRoot: fileRoot,
|
||||||
|
hasShadow: true,
|
||||||
|
tint: 0.25,
|
||||||
|
x: -5,
|
||||||
|
repeat: true,
|
||||||
|
isPokemon: true
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withTitle(`${namespace}.title`)
|
||||||
|
.withDescription(`${namespace}.description`)
|
||||||
|
.withQuery(`${namespace}.query`)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.1.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Pick battle
|
||||||
|
// Pokemon will randomly boost 1 stat by 2 stages
|
||||||
|
const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
|
||||||
|
await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withOption(
|
||||||
|
MysteryEncounterOptionBuilder
|
||||||
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||||
|
.withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
|
||||||
|
.withDialogue({
|
||||||
|
buttonLabel: `${namespace}.option.2.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.2.tooltip`,
|
||||||
|
disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.2.selected`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
|
// Pick steal
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
|
||||||
|
|
||||||
|
// Use primaryPokemon to execute the thievery
|
||||||
|
const primaryPokemon = encounter.options[1].primaryPokemon!;
|
||||||
|
setEncounterExp(scene, primaryPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs![0].species.baseExp);
|
||||||
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}.option.3.label`,
|
||||||
|
buttonTooltip: `${namespace}.option.3.tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}.option.3.selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
// Leave encounter with no rewards or exp
|
||||||
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.build();
|