diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000..7941254e48a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,115 @@ +name: Bug Report +description: Create a report to help us improve +title: "[Bug] " +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: textarea + id: description + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. + validations: + required: true + - type: markdown + attributes: + value: | + --- + - type: textarea + id: session-file + attributes: + label: User data export file + description: Open Menu → ManageData → Export Session → Select slot. The file should now be in your `/Downloads` directory. Change the file extension type from `.prsv` to `.txt` (How to [Windows](https://www.guidingtech.com/how-to-change-file-type-on-windows/) | [Mac](https://support.apple.com/guide/mac-help/show-or-hide-filename-extensions-on-mac-mchlp2304/mac) | [iOS](https://www.guidingtech.com/change-file-type-extension-on-iphone/)). + placeholder: Focus me and then drop your file here (or use the upload button at the bottom) + validations: + required: false + - type: textarea + id: data-file + attributes: + label: Session export file + description: Open Menu → ManageData → Export Data. The file should now be in your `/Downloads` directory. Change the file extension type from `.prsv` to `.txt` (How to [Windows](https://www.guidingtech.com/how-to-change-file-type-on-windows/) | [Mac](https://support.apple.com/guide/mac-help/show-or-hide-filename-extensions-on-mac-mchlp2304/mac) | [iOS](https://www.guidingtech.com/change-file-type-extension-on-iphone/)). + placeholder: Focus me and then drop your file here (or use the upload button at the bottom) + validations: + required: false + - type: markdown + attributes: + value: | + --- + - type: textarea + id: expected-behavior + attributes: + label: Expected behavior + description: A clear and concise description of what you expected to happen. If it is an existing move or ability + validations: + required: true + - type: markdown + attributes: + value: | + --- + - type: textarea + id: media + attributes: + label: Screenshots / Videos + description: If applicable, add screenshots or videos to help explain your problem. + validations: + required: false + - type: markdown + attributes: + value: | + --- + - type: dropdown + id: os + attributes: + label: What OS did you observe the bug on? + multiple: true + options: + - PC/Windows + - Mac/OSX + - Linux + - iOS + - Android + - Other + validations: + required: true + - type: input + id: os-other + attributes: + label: If other please specify + validations: + required: false + - type: markdown + attributes: + value: | + --- + - type: dropdown + id: browser + attributes: + label: Which browser do you use? + multiple: true + options: + - Chrome + - Firefox + - Safari + - Edge + - Opera + - Other + validations: + required: true + - type: input + id: browser-other + attributes: + label: If other please specify + validations: + required: false + - type: markdown + attributes: + value: | + --- + - type: textarea + id: additional-context + attributes: + label: Additional context + description: Add any other context about the problem here. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index d3130a73ab8..158ac312a50 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -28,7 +28,8 @@ - [ ] There is no overlap with another PR? - [ ] The PR is self-contained and cannot be split into smaller PRs? - [ ] Have I provided a clear explanation of the changes? +- [ ] Have I considered writing automated tests for the issue? - [ ] Have I tested the changes (manually)? - [ ] Are all unit tests still passing? (`npm run test`) - [ ] Are the changes visual? - - [ ] Have I provided screenshots/videos of the changes? \ No newline at end of file + - [ ] Have I provided screenshots/videos of the changes? diff --git a/public/images/items.json b/public/images/items.json index 33dcf8f5e9a..a09aa42374f 100644 --- a/public/images/items.json +++ b/public/images/items.json @@ -4,8 +4,8 @@ "image": "items.png", "format": "RGBA8888", "size": { - "w": 415, - "h": 415 + "w": 416, + "h": 416 }, "scale": 1, "frames": [ @@ -744,27 +744,6 @@ "h": 24 } }, - { - "filename": "relic_gold", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 15, - "h": 11 - }, - "frame": { - "x": 0, - "y": 404, - "w": 15, - "h": 11 - } - }, { "filename": "calcium", "rotated": false, @@ -1165,7 +1144,7 @@ } }, { - "filename": "clefairy_doll", + "filename": "mind_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -1174,15 +1153,15 @@ }, "spriteSourceSize": { "x": 4, - "y": 5, + "y": 4, "w": 24, - "h": 23 + "h": 24 }, "frame": { "x": 24, "y": 392, "w": 24, - "h": 23 + "h": 24 } }, { @@ -1249,7 +1228,7 @@ } }, { - "filename": "mind_plate", + "filename": "muscle_band", "rotated": false, "trimmed": true, "sourceSize": { @@ -1270,7 +1249,7 @@ } }, { - "filename": "muscle_band", + "filename": "pixie_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -1291,7 +1270,7 @@ } }, { - "filename": "pixie_plate", + "filename": "salac_berry", "rotated": false, "trimmed": true, "sourceSize": { @@ -1312,7 +1291,7 @@ } }, { - "filename": "salac_berry", + "filename": "scanner", "rotated": false, "trimmed": true, "sourceSize": { @@ -1333,7 +1312,7 @@ } }, { - "filename": "scanner", + "filename": "silk_scarf", "rotated": false, "trimmed": true, "sourceSize": { @@ -1354,7 +1333,7 @@ } }, { - "filename": "coin_case", + "filename": "sky_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -1363,15 +1342,15 @@ }, "spriteSourceSize": { "x": 4, - "y": 5, + "y": 4, "w": 24, - "h": 23 + "h": 24 }, "frame": { "x": 48, "y": 392, "w": 24, - "h": 23 + "h": 24 } }, { @@ -1417,7 +1396,7 @@ } }, { - "filename": "silk_scarf", + "filename": "splash_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -1438,7 +1417,7 @@ } }, { - "filename": "sky_plate", + "filename": "spooky_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -1459,7 +1438,7 @@ } }, { - "filename": "splash_plate", + "filename": "stone_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -1480,7 +1459,7 @@ } }, { - "filename": "spooky_plate", + "filename": "sun_stone", "rotated": false, "trimmed": true, "sourceSize": { @@ -1501,7 +1480,7 @@ } }, { - "filename": "stone_plate", + "filename": "toxic_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -1522,7 +1501,7 @@ } }, { - "filename": "sun_stone", + "filename": "zap_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -1564,7 +1543,7 @@ } }, { - "filename": "toxic_plate", + "filename": "clefairy_doll", "rotated": false, "trimmed": true, "sourceSize": { @@ -1573,19 +1552,19 @@ }, "spriteSourceSize": { "x": 4, - "y": 4, + "y": 5, "w": 24, - "h": 24 + "h": 23 }, "frame": { "x": 339, "y": 20, "w": 24, - "h": 24 + "h": 23 } }, { - "filename": "zap_plate", + "filename": "coin_case", "rotated": false, "trimmed": true, "sourceSize": { @@ -1594,19 +1573,19 @@ }, "spriteSourceSize": { "x": 4, - "y": 4, + "y": 5, "w": 24, - "h": 24 + "h": 23 }, "frame": { "x": 363, "y": 20, "w": 24, - "h": 24 + "h": 23 } }, { - "filename": "max_revive", + "filename": "berry_pouch", "rotated": false, "trimmed": true, "sourceSize": { @@ -1614,16 +1593,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 24 + "x": 4, + "y": 5, + "w": 23, + "h": 23 }, "frame": { "x": 387, "y": 20, - "w": 22, - "h": 24 + "w": 23, + "h": 23 } }, { @@ -1774,7 +1753,7 @@ } }, { - "filename": "berry_pouch", + "filename": "black_belt", "rotated": false, "trimmed": true, "sourceSize": { @@ -1782,15 +1761,15 @@ "h": 32 }, "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, + "x": 5, + "y": 4, + "w": 22, "h": 23 }, "frame": { "x": 327, "y": 45, - "w": 23, + "w": 22, "h": 23 } }, @@ -1809,8 +1788,8 @@ "h": 24 }, "frame": { - "x": 350, - "y": 44, + "x": 349, + "y": 43, "w": 23, "h": 24 } @@ -1830,14 +1809,14 @@ "h": 23 }, "frame": { - "x": 373, - "y": 44, + "x": 372, + "y": 43, "w": 24, "h": 23 } }, { - "filename": "max_ether", + "filename": "red_orb", "rotated": false, "trimmed": true, "sourceSize": { @@ -1845,15 +1824,15 @@ "h": 32 }, "spriteSourceSize": { - "x": 7, + "x": 6, "y": 4, - "w": 18, + "w": 20, "h": 24 }, "frame": { - "x": 397, - "y": 44, - "w": 18, + "x": 396, + "y": 43, + "w": 20, "h": 24 } }, @@ -1872,14 +1851,14 @@ "h": 18 }, "frame": { - "x": 373, - "y": 67, + "x": 372, + "y": 66, "w": 24, "h": 18 } }, { - "filename": "max_potion", + "filename": "mystic_water", "rotated": false, "trimmed": true, "sourceSize": { @@ -1887,16 +1866,37 @@ "h": 32 }, "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 18, - "h": 24 + "x": 6, + "y": 5, + "w": 20, + "h": 23 }, "frame": { - "x": 397, - "y": 68, - "w": 18, - "h": 24 + "x": 396, + "y": 67, + "w": 20, + "h": 23 + } + }, + { + "filename": "amulet_coin", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 23, + "h": 21 + }, + "frame": { + "x": 349, + "y": 67, + "w": 23, + "h": 21 } }, { @@ -1914,12 +1914,54 @@ "h": 18 }, "frame": { - "x": 67, - "y": 50, + "x": 372, + "y": 84, "w": 24, "h": 18 } }, + { + "filename": "hard_meteorite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 20, + "h": 22 + }, + "frame": { + "x": 396, + "y": 90, + "w": 20, + "h": 22 + } + }, + { + "filename": "relic_gold", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 9, + "y": 11, + "w": 15, + "h": 11 + }, + "frame": { + "x": 0, + "y": 404, + "w": 15, + "h": 11 + } + }, { "filename": "icy_reins_of_unity", "rotated": false, @@ -1934,6 +1976,27 @@ "w": 24, "h": 20 }, + "frame": { + "x": 67, + "y": 50, + "w": 24, + "h": 20 + } + }, + { + "filename": "metal_powder", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 24, + "h": 20 + }, "frame": { "x": 91, "y": 50, @@ -1962,27 +2025,6 @@ "h": 23 } }, - { - "filename": "metal_powder", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 24, - "h": 20 - }, - "frame": { - "x": 136, - "y": 60, - "w": 24, - "h": 20 - } - }, { "filename": "peat_block", "rotated": false, @@ -1998,180 +2040,12 @@ "h": 22 }, "frame": { - "x": 160, - "y": 67, + "x": 136, + "y": 60, "w": 24, "h": 22 } }, - { - "filename": "dynamax_band", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 23, - "h": 23 - }, - "frame": { - "x": 184, - "y": 67, - "w": 23, - "h": 23 - } - }, - { - "filename": "griseous_core", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 207, - "y": 67, - "w": 23, - "h": 23 - } - }, - { - "filename": "healing_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 23, - "h": 22 - }, - "frame": { - "x": 230, - "y": 68, - "w": 23, - "h": 22 - } - }, - { - "filename": "rare_candy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 253, - "y": 68, - "w": 23, - "h": 23 - } - }, - { - "filename": "rarer_candy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 276, - "y": 68, - "w": 23, - "h": 23 - } - }, - { - "filename": "stick", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 299, - "y": 68, - "w": 23, - "h": 23 - } - }, - { - "filename": "black_belt", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 322, - "y": 68, - "w": 22, - "h": 23 - } - }, - { - "filename": "bug_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 344, - "y": 68, - "w": 22, - "h": 23 - } - }, { "filename": "quick_powder", "rotated": false, @@ -2187,75 +2061,12 @@ "h": 20 }, "frame": { - "x": 60, - "y": 68, + "x": 160, + "y": 67, "w": 24, "h": 20 } }, - { - "filename": "dark_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 57, - "y": 88, - "w": 22, - "h": 23 - } - }, - { - "filename": "dragon_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 57, - "y": 111, - "w": 22, - "h": 23 - } - }, - { - "filename": "electric_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 57, - "y": 134, - "w": 22, - "h": 23 - } - }, { "filename": "rusted_shield", "rotated": false, @@ -2271,222 +2082,12 @@ "h": 20 }, "frame": { - "x": 84, - "y": 70, + "x": 184, + "y": 67, "w": 24, "h": 20 } }, - { - "filename": "fairy_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 79, - "y": 90, - "w": 22, - "h": 23 - } - }, - { - "filename": "fighting_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 79, - "y": 113, - "w": 22, - "h": 23 - } - }, - { - "filename": "amulet_coin", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 23, - "h": 21 - }, - "frame": { - "x": 79, - "y": 136, - "w": 23, - "h": 21 - } - }, - { - "filename": "coupon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 63, - "y": 157, - "w": 23, - "h": 19 - } - }, - { - "filename": "fire_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 64, - "y": 176, - "w": 22, - "h": 23 - } - }, - { - "filename": "fire_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 64, - "y": 199, - "w": 22, - "h": 23 - } - }, - { - "filename": "flying_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 64, - "y": 222, - "w": 22, - "h": 23 - } - }, - { - "filename": "max_lure", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 17, - "h": 24 - }, - "frame": { - "x": 86, - "y": 157, - "w": 17, - "h": 24 - } - }, - { - "filename": "oval_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 21, - "h": 24 - }, - "frame": { - "x": 86, - "y": 181, - "w": 21, - "h": 24 - } - }, - { - "filename": "shiny_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 21, - "h": 24 - }, - "frame": { - "x": 86, - "y": 205, - "w": 21, - "h": 24 - } - }, { "filename": "auspicious_armor", "rotated": false, @@ -2502,54 +2103,12 @@ "h": 21 }, "frame": { - "x": 86, - "y": 229, + "x": 208, + "y": 67, "w": 23, "h": 21 } }, - { - "filename": "full_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 9, - "y": 4, - "w": 15, - "h": 23 - }, - "frame": { - "x": 71, - "y": 245, - "w": 15, - "h": 23 - } - }, - { - "filename": "binding_band", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 23, - "h": 20 - }, - "frame": { - "x": 86, - "y": 250, - "w": 23, - "h": 20 - } - }, { "filename": "sacred_ash", "rotated": false, @@ -2565,222 +2124,12 @@ "h": 20 }, "frame": { - "x": 108, - "y": 73, + "x": 231, + "y": 68, "w": 24, "h": 20 } }, - { - "filename": "focus_sash", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 101, - "y": 93, - "w": 22, - "h": 23 - } - }, - { - "filename": "deep_sea_scale", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 20 - }, - "frame": { - "x": 101, - "y": 116, - "w": 22, - "h": 20 - } - }, - { - "filename": "deep_sea_tooth", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 102, - "y": 136, - "w": 22, - "h": 21 - } - }, - { - "filename": "red_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 20, - "h": 24 - }, - "frame": { - "x": 103, - "y": 157, - "w": 20, - "h": 24 - } - }, - { - "filename": "max_repel", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 107, - "y": 181, - "w": 16, - "h": 24 - } - }, - { - "filename": "pp_max", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 107, - "y": 205, - "w": 16, - "h": 24 - } - }, - { - "filename": "pp_up", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 109, - "y": 229, - "w": 16, - "h": 24 - } - }, - { - "filename": "apicot_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 20 - }, - "frame": { - "x": 109, - "y": 253, - "w": 19, - "h": 20 - } - }, - { - "filename": "protein", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 123, - "y": 93, - "w": 16, - "h": 24 - } - }, - { - "filename": "lansat_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 21, - "h": 23 - }, - "frame": { - "x": 139, - "y": 80, - "w": 21, - "h": 23 - } - }, { "filename": "shadow_reins_of_unity", "rotated": false, @@ -2796,8 +2145,8 @@ "h": 20 }, "frame": { - "x": 160, - "y": 89, + "x": 255, + "y": 68, "w": 24, "h": 20 } @@ -2817,35 +2166,14 @@ "h": 20 }, "frame": { - "x": 184, - "y": 90, + "x": 279, + "y": 68, "w": 24, "h": 20 } }, { - "filename": "moon_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 23, - "h": 21 - }, - "frame": { - "x": 208, - "y": 90, - "w": 23, - "h": 21 - } - }, - { - "filename": "blank_memory", + "filename": "binding_band", "rotated": false, "trimmed": true, "sourceSize": { @@ -2854,19 +2182,19 @@ }, "spriteSourceSize": { "x": 5, - "y": 5, - "w": 22, - "h": 22 + "y": 6, + "w": 23, + "h": 20 }, "frame": { - "x": 231, - "y": 90, - "w": 22, - "h": 22 + "x": 303, + "y": 68, + "w": 23, + "h": 20 } }, { - "filename": "n_lunarizer", + "filename": "dynamax_band", "rotated": false, "trimmed": true, "sourceSize": { @@ -2875,141 +2203,15 @@ }, "spriteSourceSize": { "x": 4, - "y": 6, + "y": 4, "w": 23, - "h": 21 + "h": 23 }, "frame": { - "x": 253, - "y": 91, + "x": 326, + "y": 68, "w": 23, - "h": 21 - } - }, - { - "filename": "n_solarizer", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 23, - "h": 21 - }, - "frame": { - "x": 276, - "y": 91, - "w": 23, - "h": 21 - } - }, - { - "filename": "rusted_sword", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 22 - }, - "frame": { - "x": 299, - "y": 91, - "w": 23, - "h": 22 - } - }, - { - "filename": "bug_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 322, - "y": 91, - "w": 22, - "h": 22 - } - }, - { - "filename": "charcoal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 344, - "y": 91, - "w": 22, - "h": 22 - } - }, - { - "filename": "dusk_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 139, - "y": 103, - "w": 21, - "h": 21 - } - }, - { - "filename": "mystery_egg", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 18 - }, - "frame": { - "x": 123, - "y": 117, - "w": 16, - "h": 18 + "h": 23 } }, { @@ -3027,8 +2229,8 @@ "h": 17 }, "frame": { - "x": 160, - "y": 109, + "x": 349, + "y": 88, "w": 23, "h": 17 } @@ -3048,14 +2250,56 @@ "h": 17 }, "frame": { - "x": 183, - "y": 110, + "x": 60, + "y": 70, "w": 23, "h": 17 } }, { - "filename": "ghost_tera_shard", + "filename": "griseous_core", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 57, + "y": 87, + "w": 23, + "h": 23 + } + }, + { + "filename": "max_revive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 22, + "h": 24 + }, + "frame": { + "x": 57, + "y": 110, + "w": 22, + "h": 24 + } + }, + { + "filename": "bug_tera_shard", "rotated": false, "trimmed": true, "sourceSize": { @@ -3069,8 +2313,8 @@ "h": 23 }, "frame": { - "x": 366, - "y": 85, + "x": 57, + "y": 134, "w": 22, "h": 23 } @@ -3090,14 +2334,14 @@ "h": 17 }, "frame": { - "x": 206, - "y": 111, + "x": 83, + "y": 70, "w": 23, "h": 17 } }, { - "filename": "douse_drive", + "filename": "rare_candy", "rotated": false, "trimmed": true, "sourceSize": { @@ -3106,15 +2350,540 @@ }, "spriteSourceSize": { "x": 4, - "y": 8, + "y": 5, "w": 23, - "h": 17 + "h": 23 }, "frame": { - "x": 229, - "y": 112, + "x": 80, + "y": 87, "w": 23, - "h": 17 + "h": 23 + } + }, + { + "filename": "rarer_candy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 79, + "y": 110, + "w": 23, + "h": 23 + } + }, + { + "filename": "stick", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 79, + "y": 133, + "w": 23, + "h": 23 + } + }, + { + "filename": "big_mushroom", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 19 + }, + "frame": { + "x": 63, + "y": 157, + "w": 19, + "h": 19 + } + }, + { + "filename": "max_ether", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 64, + "y": 176, + "w": 18, + "h": 24 + } + }, + { + "filename": "oval_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 21, + "h": 24 + }, + "frame": { + "x": 82, + "y": 156, + "w": 21, + "h": 24 + } + }, + { + "filename": "max_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 64, + "y": 200, + "w": 18, + "h": 24 + } + }, + { + "filename": "shiny_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 21, + "h": 24 + }, + "frame": { + "x": 64, + "y": 224, + "w": 21, + "h": 24 + } + }, + { + "filename": "dark_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 82, + "y": 180, + "w": 22, + "h": 23 + } + }, + { + "filename": "berry_juice", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 24, + "h": 23 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 22, + "h": 21 + }, + "frame": { + "x": 82, + "y": 203, + "w": 22, + "h": 21 + } + }, + { + "filename": "dragon_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 85, + "y": 224, + "w": 22, + "h": 23 + } + }, + { + "filename": "max_lure", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 17, + "h": 24 + }, + "frame": { + "x": 71, + "y": 248, + "w": 17, + "h": 24 + } + }, + { + "filename": "electric_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 88, + "y": 247, + "w": 22, + "h": 23 + } + }, + { + "filename": "max_repel", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 72, + "y": 272, + "w": 16, + "h": 24 + } + }, + { + "filename": "fairy_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 88, + "y": 270, + "w": 22, + "h": 23 + } + }, + { + "filename": "pp_max", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 72, + "y": 296, + "w": 16, + "h": 24 + } + }, + { + "filename": "fighting_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 88, + "y": 293, + "w": 22, + "h": 23 + } + }, + { + "filename": "pp_up", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 72, + "y": 320, + "w": 16, + "h": 24 + } + }, + { + "filename": "fire_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 88, + "y": 316, + "w": 22, + "h": 23 + } + }, + { + "filename": "protein", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 72, + "y": 344, + "w": 16, + "h": 24 + } + }, + { + "filename": "fire_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 88, + "y": 339, + "w": 22, + "h": 23 + } + }, + { + "filename": "repel", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 72, + "y": 368, + "w": 16, + "h": 24 + } + }, + { + "filename": "super_lure", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 17, + "h": 24 + }, + "frame": { + "x": 72, + "y": 392, + "w": 17, + "h": 24 + } + }, + { + "filename": "flying_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 88, + "y": 362, + "w": 22, + "h": 23 + } + }, + { + "filename": "focus_sash", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 89, + "y": 385, + "w": 22, + "h": 23 + } + }, + { + "filename": "coupon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 106, + "y": 73, + "w": 23, + "h": 19 } }, { @@ -3132,14 +2901,14 @@ "h": 19 }, "frame": { - "x": 252, - "y": 112, + "x": 103, + "y": 92, "w": 23, "h": 19 } }, { - "filename": "mystic_ticket", + "filename": "ghost_tera_shard", "rotated": false, "trimmed": true, "sourceSize": { @@ -3147,62 +2916,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 + "x": 6, + "y": 4, + "w": 22, + "h": 23 }, "frame": { - "x": 275, - "y": 112, - "w": 23, - "h": 19 + "x": 102, + "y": 111, + "w": 22, + "h": 23 } }, { - "filename": "pair_of_tickets", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 298, - "y": 113, - "w": 23, - "h": 19 - } - }, - { - "filename": "reviver_seed", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 8, - "w": 23, - "h": 20 - }, - "frame": { - "x": 321, - "y": 113, - "w": 23, - "h": 20 - } - }, - { - "filename": "dark_memory", + "filename": "blank_memory", "rotated": false, "trimmed": true, "sourceSize": { @@ -3216,8 +2943,8 @@ "h": 22 }, "frame": { - "x": 344, - "y": 113, + "x": 102, + "y": 134, "w": 22, "h": 22 } @@ -3237,33 +2964,12 @@ "h": 23 }, "frame": { - "x": 366, - "y": 108, + "x": 103, + "y": 156, "w": 22, "h": 23 } }, - { - "filename": "berry_pot", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 18, - "h": 22 - }, - "frame": { - "x": 124, - "y": 135, - "w": 18, - "h": 22 - } - }, { "filename": "ground_tera_shard", "rotated": false, @@ -3279,12 +2985,33 @@ "h": 23 }, "frame": { - "x": 123, - "y": 157, + "x": 104, + "y": 179, "w": 22, "h": 23 } }, + { + "filename": "bug_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 104, + "y": 202, + "w": 22, + "h": 22 + } + }, { "filename": "ice_tera_shard", "rotated": false, @@ -3300,14 +3027,14 @@ "h": 23 }, "frame": { - "x": 123, - "y": 180, + "x": 107, + "y": 224, "w": 22, "h": 23 } }, { - "filename": "never_melt_ice", + "filename": "lansat_berry", "rotated": false, "trimmed": true, "sourceSize": { @@ -3316,14 +3043,14 @@ }, "spriteSourceSize": { "x": 5, - "y": 5, - "w": 22, + "y": 4, + "w": 21, "h": 23 }, "frame": { - "x": 123, - "y": 203, - "w": 22, + "x": 110, + "y": 247, + "w": 21, "h": 23 } }, @@ -3342,14 +3069,14 @@ "h": 23 }, "frame": { - "x": 125, - "y": 226, + "x": 110, + "y": 270, "w": 21, "h": 23 } }, { - "filename": "mystic_water", + "filename": "never_melt_ice", "rotated": false, "trimmed": true, "sourceSize": { @@ -3357,15 +3084,15 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, + "x": 5, "y": 5, - "w": 20, + "w": 22, "h": 23 }, "frame": { - "x": 128, - "y": 249, - "w": 20, + "x": 110, + "y": 293, + "w": 22, "h": 23 } }, @@ -3384,243 +3111,12 @@ "h": 23 }, "frame": { - "x": 388, - "y": 92, + "x": 110, + "y": 316, "w": 22, "h": 23 } }, - { - "filename": "blunder_policy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 19 - }, - "frame": { - "x": 388, - "y": 115, - "w": 22, - "h": 19 - } - }, - { - "filename": "sachet", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 18, - "h": 23 - }, - "frame": { - "x": 142, - "y": 124, - "w": 18, - "h": 23 - } - }, - { - "filename": "wellspring_mask", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 21 - }, - "frame": { - "x": 160, - "y": 126, - "w": 23, - "h": 21 - } - }, - { - "filename": "shell_bell", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 23, - "h": 20 - }, - "frame": { - "x": 183, - "y": 127, - "w": 23, - "h": 20 - } - }, - { - "filename": "relic_crown", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 18 - }, - "frame": { - "x": 206, - "y": 128, - "w": 23, - "h": 18 - } - }, - { - "filename": "shock_drive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 229, - "y": 129, - "w": 23, - "h": 17 - } - }, - { - "filename": "wise_glasses", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 252, - "y": 131, - "w": 23, - "h": 17 - } - }, - { - "filename": "dire_hit", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 275, - "y": 131, - "w": 22, - "h": 22 - } - }, - { - "filename": "dna_splicers", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 297, - "y": 132, - "w": 22, - "h": 22 - } - }, - { - "filename": "dragon_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 319, - "y": 133, - "w": 22, - "h": 22 - } - }, - { - "filename": "electirizer", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 341, - "y": 135, - "w": 22, - "h": 22 - } - }, { "filename": "petaya_berry", "rotated": false, @@ -3636,8 +3132,8 @@ "h": 23 }, "frame": { - "x": 145, - "y": 147, + "x": 110, + "y": 339, "w": 22, "h": 23 } @@ -3657,8 +3153,8 @@ "h": 23 }, "frame": { - "x": 167, - "y": 147, + "x": 110, + "y": 362, "w": 22, "h": 23 } @@ -3678,12 +3174,348 @@ "h": 23 }, "frame": { - "x": 145, - "y": 170, + "x": 111, + "y": 385, "w": 22, "h": 23 } }, + { + "filename": "douse_drive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 372, + "y": 102, + "w": 23, + "h": 17 + } + }, + { + "filename": "sharp_beak", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 21, + "h": 23 + }, + "frame": { + "x": 395, + "y": 112, + "w": 21, + "h": 23 + } + }, + { + "filename": "healing_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 23, + "h": 22 + }, + "frame": { + "x": 129, + "y": 82, + "w": 23, + "h": 22 + } + }, + { + "filename": "moon_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 23, + "h": 21 + }, + "frame": { + "x": 152, + "y": 87, + "w": 23, + "h": 21 + } + }, + { + "filename": "n_lunarizer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 23, + "h": 21 + }, + "frame": { + "x": 175, + "y": 87, + "w": 23, + "h": 21 + } + }, + { + "filename": "n_solarizer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 23, + "h": 21 + }, + "frame": { + "x": 198, + "y": 88, + "w": 23, + "h": 21 + } + }, + { + "filename": "rusted_sword", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 22 + }, + "frame": { + "x": 221, + "y": 88, + "w": 23, + "h": 22 + } + }, + { + "filename": "charcoal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 244, + "y": 88, + "w": 22, + "h": 22 + } + }, + { + "filename": "dark_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 266, + "y": 88, + "w": 22, + "h": 22 + } + }, + { + "filename": "dire_hit", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 288, + "y": 88, + "w": 22, + "h": 22 + } + }, + { + "filename": "super_repel", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 310, + "y": 88, + "w": 16, + "h": 24 + } + }, + { + "filename": "wellspring_mask", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 21 + }, + "frame": { + "x": 326, + "y": 91, + "w": 23, + "h": 21 + } + }, + { + "filename": "mystic_ticket", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 349, + "y": 105, + "w": 23, + "h": 19 + } + }, + { + "filename": "pair_of_tickets", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 372, + "y": 119, + "w": 23, + "h": 19 + } + }, + { + "filename": "whipped_dream", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 21, + "h": 23 + }, + "frame": { + "x": 395, + "y": 135, + "w": 21, + "h": 23 + } + }, + { + "filename": "relic_crown", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 18 + }, + "frame": { + "x": 126, + "y": 104, + "w": 23, + "h": 18 + } + }, { "filename": "reaper_cloth", "rotated": false, @@ -3699,14 +3531,14 @@ "h": 23 }, "frame": { - "x": 145, - "y": 193, + "x": 124, + "y": 122, "w": 22, "h": 23 } }, { - "filename": "rock_tera_shard", + "filename": "reviver_seed", "rotated": false, "trimmed": true, "sourceSize": { @@ -3714,20 +3546,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 + "x": 5, + "y": 8, + "w": 23, + "h": 20 }, "frame": { - "x": 167, - "y": 170, - "w": 22, - "h": 23 + "x": 149, + "y": 108, + "w": 23, + "h": 20 } }, { - "filename": "steel_tera_shard", + "filename": "shell_bell", "rotated": false, "trimmed": true, "sourceSize": { @@ -3735,20 +3567,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 + "x": 5, + "y": 7, + "w": 23, + "h": 20 }, "frame": { - "x": 167, - "y": 193, - "w": 22, - "h": 23 + "x": 172, + "y": 108, + "w": 23, + "h": 20 } }, { - "filename": "super_lure", + "filename": "blunder_policy", "rotated": false, "trimmed": true, "sourceSize": { @@ -3756,20 +3588,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 17, - "h": 24 + "x": 5, + "y": 6, + "w": 22, + "h": 19 }, "frame": { - "x": 189, - "y": 147, - "w": 17, - "h": 24 + "x": 195, + "y": 109, + "w": 22, + "h": 19 } }, { - "filename": "stellar_tera_shard", + "filename": "shock_drive", "rotated": false, "trimmed": true, "sourceSize": { @@ -3777,20 +3609,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 + "x": 4, + "y": 8, + "w": 23, + "h": 17 }, "frame": { - "x": 206, - "y": 146, - "w": 22, - "h": 23 + "x": 146, + "y": 128, + "w": 23, + "h": 17 } }, { - "filename": "water_tera_shard", + "filename": "wise_glasses", "rotated": false, "trimmed": true, "sourceSize": { @@ -3798,16 +3630,121 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 + "x": 4, + "y": 8, + "w": 23, + "h": 17 }, "frame": { - "x": 228, - "y": 146, + "x": 169, + "y": 128, + "w": 23, + "h": 17 + } + }, + { + "filename": "deep_sea_scale", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, "w": 22, - "h": 23 + "h": 20 + }, + "frame": { + "x": 192, + "y": 128, + "w": 22, + "h": 20 + } + }, + { + "filename": "deep_sea_tooth", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 21 + }, + "frame": { + "x": 217, + "y": 110, + "w": 22, + "h": 21 + } + }, + { + "filename": "dna_splicers", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 239, + "y": 110, + "w": 22, + "h": 22 + } + }, + { + "filename": "dragon_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 261, + "y": 110, + "w": 22, + "h": 22 + } + }, + { + "filename": "electirizer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 283, + "y": 110, + "w": 22, + "h": 22 } }, { @@ -3825,54 +3762,12 @@ "h": 22 }, "frame": { - "x": 250, - "y": 148, + "x": 305, + "y": 112, "w": 22, "h": 22 } }, - { - "filename": "hyper_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 189, - "y": 171, - "w": 17, - "h": 23 - } - }, - { - "filename": "wide_lens", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 206, - "y": 169, - "w": 22, - "h": 23 - } - }, { "filename": "enigma_berry", "rotated": false, @@ -3888,71 +3783,8 @@ "h": 22 }, "frame": { - "x": 228, - "y": 169, - "w": 22, - "h": 22 - } - }, - { - "filename": "fairy_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 250, - "y": 170, - "w": 22, - "h": 22 - } - }, - { - "filename": "fighting_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 272, - "y": 153, - "w": 22, - "h": 22 - } - }, - { - "filename": "fire_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 294, - "y": 154, + "x": 327, + "y": 112, "w": 22, "h": 22 } @@ -3972,8 +3804,8 @@ "h": 19 }, "frame": { - "x": 272, - "y": 175, + "x": 214, + "y": 131, "w": 22, "h": 19 } @@ -3993,12 +3825,75 @@ "h": 20 }, "frame": { - "x": 294, - "y": 176, + "x": 236, + "y": 132, "w": 22, "h": 20 } }, + { + "filename": "fairy_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 258, + "y": 132, + "w": 22, + "h": 22 + } + }, + { + "filename": "fighting_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 280, + "y": 132, + "w": 22, + "h": 22 + } + }, + { + "filename": "fire_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 302, + "y": 134, + "w": 22, + "h": 22 + } + }, { "filename": "flying_memory", "rotated": false, @@ -4014,12 +3909,75 @@ "h": 22 }, "frame": { - "x": 316, - "y": 155, + "x": 324, + "y": 134, "w": 22, "h": 22 } }, + { + "filename": "rock_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 125, + "y": 145, + "w": 22, + "h": 23 + } + }, + { + "filename": "steel_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 147, + "y": 145, + "w": 22, + "h": 23 + } + }, + { + "filename": "stellar_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 169, + "y": 145, + "w": 22, + "h": 23 + } + }, { "filename": "ganlon_berry", "rotated": false, @@ -4035,8 +3993,8 @@ "h": 22 }, "frame": { - "x": 316, - "y": 177, + "x": 191, + "y": 148, "w": 22, "h": 22 } @@ -4056,8 +4014,8 @@ "h": 22 }, "frame": { - "x": 338, - "y": 157, + "x": 213, + "y": 150, "w": 22, "h": 22 } @@ -4077,8 +4035,8 @@ "h": 22 }, "frame": { - "x": 338, - "y": 179, + "x": 235, + "y": 152, "w": 22, "h": 22 } @@ -4098,33 +4056,12 @@ "h": 22 }, "frame": { - "x": 189, - "y": 194, + "x": 257, + "y": 154, "w": 22, "h": 22 } }, - { - "filename": "potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 211, - "y": 192, - "w": 17, - "h": 23 - } - }, { "filename": "guard_spec", "rotated": false, @@ -4140,8 +4077,8 @@ "h": 22 }, "frame": { - "x": 228, - "y": 191, + "x": 279, + "y": 154, "w": 22, "h": 22 } @@ -4161,8 +4098,8 @@ "h": 22 }, "frame": { - "x": 250, - "y": 192, + "x": 301, + "y": 156, "w": 22, "h": 22 } @@ -4182,8 +4119,113 @@ "h": 22 }, "frame": { - "x": 272, - "y": 194, + "x": 323, + "y": 156, + "w": 22, + "h": 22 + } + }, + { + "filename": "water_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 126, + "y": 168, + "w": 22, + "h": 23 + } + }, + { + "filename": "wide_lens", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 148, + "y": 168, + "w": 22, + "h": 23 + } + }, + { + "filename": "dusk_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 170, + "y": 168, + "w": 21, + "h": 21 + } + }, + { + "filename": "magmarizer", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 126, + "y": 191, + "w": 22, + "h": 22 + } + }, + { + "filename": "mini_black_hole", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 148, + "y": 191, "w": 22, "h": 22 } @@ -4203,14 +4245,14 @@ "h": 21 }, "frame": { - "x": 294, - "y": 196, + "x": 191, + "y": 170, "w": 22, "h": 21 } }, { - "filename": "magmarizer", + "filename": "poison_barb", "rotated": false, "trimmed": true, "sourceSize": { @@ -4219,15 +4261,15 @@ }, "spriteSourceSize": { "x": 5, - "y": 5, - "w": 22, - "h": 22 + "y": 6, + "w": 21, + "h": 21 }, "frame": { - "x": 316, - "y": 199, - "w": 22, - "h": 22 + "x": 170, + "y": 189, + "w": 21, + "h": 21 } }, { @@ -4245,33 +4287,12 @@ "h": 20 }, "frame": { - "x": 338, - "y": 201, + "x": 213, + "y": 172, "w": 22, "h": 20 } }, - { - "filename": "mini_black_hole", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 146, - "y": 216, - "w": 22, - "h": 22 - } - }, { "filename": "poison_memory", "rotated": false, @@ -4287,8 +4308,8 @@ "h": 22 }, "frame": { - "x": 168, - "y": 216, + "x": 235, + "y": 174, "w": 22, "h": 22 } @@ -4308,33 +4329,12 @@ "h": 22 }, "frame": { - "x": 190, - "y": 216, + "x": 191, + "y": 191, "w": 22, "h": 22 } }, - { - "filename": "repel", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 212, - "y": 215, - "w": 16, - "h": 24 - } - }, { "filename": "psychic_memory", "rotated": false, @@ -4350,8 +4350,8 @@ "h": 22 }, "frame": { - "x": 228, - "y": 213, + "x": 213, + "y": 192, "w": 22, "h": 22 } @@ -4371,8 +4371,8 @@ "h": 22 }, "frame": { - "x": 250, - "y": 214, + "x": 257, + "y": 176, "w": 22, "h": 22 } @@ -4392,8 +4392,8 @@ "h": 22 }, "frame": { - "x": 272, - "y": 216, + "x": 279, + "y": 176, "w": 22, "h": 22 } @@ -4413,8 +4413,8 @@ "h": 22 }, "frame": { - "x": 294, - "y": 217, + "x": 235, + "y": 196, "w": 22, "h": 22 } @@ -4434,8 +4434,8 @@ "h": 22 }, "frame": { - "x": 316, - "y": 221, + "x": 301, + "y": 178, "w": 22, "h": 22 } @@ -4455,33 +4455,12 @@ "h": 22 }, "frame": { - "x": 338, - "y": 221, + "x": 323, + "y": 178, "w": 22, "h": 22 } }, - { - "filename": "sharp_beak", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 21, - "h": 23 - }, - "frame": { - "x": 148, - "y": 238, - "w": 21, - "h": 23 - } - }, { "filename": "steel_memory", "rotated": false, @@ -4497,75 +4476,12 @@ "h": 22 }, "frame": { - "x": 169, - "y": 238, + "x": 257, + "y": 198, "w": 22, "h": 22 } }, - { - "filename": "whipped_dream", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 21, - "h": 23 - }, - "frame": { - "x": 191, - "y": 238, - "w": 21, - "h": 23 - } - }, - { - "filename": "hard_meteorite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 20, - "h": 22 - }, - "frame": { - "x": 212, - "y": 239, - "w": 20, - "h": 22 - } - }, - { - "filename": "super_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 232, - "y": 235, - "w": 17, - "h": 23 - } - }, { "filename": "thick_club", "rotated": false, @@ -4581,8 +4497,8 @@ "h": 22 }, "frame": { - "x": 249, - "y": 236, + "x": 279, + "y": 198, "w": 22, "h": 22 } @@ -4602,8 +4518,8 @@ "h": 21 }, "frame": { - "x": 271, - "y": 238, + "x": 301, + "y": 200, "w": 22, "h": 21 } @@ -4623,29 +4539,8 @@ "h": 21 }, "frame": { - "x": 293, - "y": 239, - "w": 22, - "h": 21 - } - }, - { - "filename": "tart_apple", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 315, - "y": 243, + "x": 323, + "y": 200, "w": 22, "h": 21 } @@ -4665,71 +4560,8 @@ "h": 22 }, "frame": { - "x": 337, - "y": 243, - "w": 22, - "h": 22 - } - }, - { - "filename": "masterpiece_teacup", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 21, - "h": 18 - }, - "frame": { - "x": 148, - "y": 261, - "w": 21, - "h": 18 - } - }, - { - "filename": "tera_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 20 - }, - "frame": { - "x": 169, - "y": 260, - "w": 22, - "h": 20 - } - }, - { - "filename": "tm_bug", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 191, - "y": 261, + "x": 129, + "y": 213, "w": 22, "h": 22 } @@ -4749,12 +4581,96 @@ "h": 22 }, "frame": { - "x": 213, - "y": 261, + "x": 151, + "y": 213, "w": 19, "h": 22 } }, + { + "filename": "shiny_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 170, + "y": 210, + "w": 21, + "h": 21 + } + }, + { + "filename": "tart_apple", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 21 + }, + "frame": { + "x": 191, + "y": 213, + "w": 22, + "h": 21 + } + }, + { + "filename": "tera_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 20 + }, + "frame": { + "x": 213, + "y": 214, + "w": 22, + "h": 20 + } + }, + { + "filename": "tm_bug", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 235, + "y": 218, + "w": 22, + "h": 22 + } + }, { "filename": "tm_dark", "rotated": false, @@ -4770,33 +4686,12 @@ "h": 22 }, "frame": { - "x": 232, - "y": 258, + "x": 257, + "y": 220, "w": 22, "h": 22 } }, - { - "filename": "metronome", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 17, - "h": 22 - }, - "frame": { - "x": 254, - "y": 258, - "w": 17, - "h": 22 - } - }, { "filename": "tm_dragon", "rotated": false, @@ -4812,8 +4707,8 @@ "h": 22 }, "frame": { - "x": 271, - "y": 259, + "x": 279, + "y": 220, "w": 22, "h": 22 } @@ -4833,8 +4728,8 @@ "h": 22 }, "frame": { - "x": 293, - "y": 260, + "x": 301, + "y": 221, "w": 22, "h": 22 } @@ -4854,8 +4749,8 @@ "h": 22 }, "frame": { - "x": 315, - "y": 264, + "x": 323, + "y": 221, "w": 22, "h": 22 } @@ -4875,8 +4770,8 @@ "h": 22 }, "frame": { - "x": 337, - "y": 265, + "x": 349, + "y": 124, "w": 22, "h": 22 } @@ -4896,8 +4791,8 @@ "h": 22 }, "frame": { - "x": 366, - "y": 131, + "x": 131, + "y": 235, "w": 22, "h": 22 } @@ -4917,14 +4812,14 @@ "h": 22 }, "frame": { - "x": 388, - "y": 134, + "x": 131, + "y": 257, "w": 22, "h": 22 } }, { - "filename": "big_nugget", + "filename": "hyper_potion", "rotated": false, "trimmed": true, "sourceSize": { @@ -4932,20 +4827,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 + "x": 8, + "y": 5, + "w": 17, + "h": 23 }, "frame": { - "x": 128, - "y": 272, - "w": 20, - "h": 20 + "x": 153, + "y": 235, + "w": 17, + "h": 23 } }, { - "filename": "metal_alloy", + "filename": "zoom_lens", "rotated": false, "trimmed": true, "sourceSize": { @@ -4953,16 +4848,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, - "y": 7, + "x": 5, + "y": 6, "w": 21, - "h": 19 + "h": 21 }, "frame": { - "x": 148, - "y": 279, + "x": 170, + "y": 231, "w": 21, - "h": 19 + "h": 21 } }, { @@ -4980,8 +4875,8 @@ "h": 22 }, "frame": { - "x": 169, - "y": 280, + "x": 191, + "y": 234, "w": 22, "h": 22 } @@ -5000,31 +4895,10 @@ "w": 22, "h": 22 }, - "frame": { - "x": 191, - "y": 283, - "w": 22, - "h": 22 - } - }, - { - "filename": "metal_coat", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 19, - "h": 22 - }, "frame": { "x": 213, - "y": 283, - "w": 19, + "y": 234, + "w": 22, "h": 22 } }, @@ -5043,33 +4917,12 @@ "h": 22 }, "frame": { - "x": 232, - "y": 280, + "x": 235, + "y": 240, "w": 22, "h": 22 } }, - { - "filename": "soothe_bell", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 22 - }, - "frame": { - "x": 254, - "y": 280, - "w": 17, - "h": 22 - } - }, { "filename": "tm_ice", "rotated": false, @@ -5085,8 +4938,8 @@ "h": 22 }, "frame": { - "x": 271, - "y": 281, + "x": 257, + "y": 242, "w": 22, "h": 22 } @@ -5106,8 +4959,8 @@ "h": 22 }, "frame": { - "x": 293, - "y": 282, + "x": 279, + "y": 242, "w": 22, "h": 22 } @@ -5127,8 +4980,8 @@ "h": 22 }, "frame": { - "x": 315, - "y": 286, + "x": 301, + "y": 243, "w": 22, "h": 22 } @@ -5148,12 +5001,54 @@ "h": 22 }, "frame": { - "x": 337, - "y": 287, + "x": 323, + "y": 243, "w": 22, "h": 22 } }, + { + "filename": "berry_pot", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 18, + "h": 22 + }, + "frame": { + "x": 153, + "y": 258, + "w": 18, + "h": 22 + } + }, + { + "filename": "sitrus_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 20, + "h": 22 + }, + "frame": { + "x": 171, + "y": 252, + "w": 20, + "h": 22 + } + }, { "filename": "tm_rock", "rotated": false, @@ -5169,8 +5064,8 @@ "h": 22 }, "frame": { - "x": 72, - "y": 270, + "x": 191, + "y": 256, "w": 22, "h": 22 } @@ -5190,8 +5085,8 @@ "h": 22 }, "frame": { - "x": 72, - "y": 292, + "x": 213, + "y": 256, "w": 22, "h": 22 } @@ -5211,8 +5106,8 @@ "h": 22 }, "frame": { - "x": 72, - "y": 314, + "x": 235, + "y": 262, "w": 22, "h": 22 } @@ -5232,8 +5127,8 @@ "h": 22 }, "frame": { - "x": 72, - "y": 336, + "x": 257, + "y": 264, "w": 22, "h": 22 } @@ -5253,8 +5148,8 @@ "h": 22 }, "frame": { - "x": 72, - "y": 358, + "x": 279, + "y": 264, "w": 22, "h": 22 } @@ -5274,54 +5169,12 @@ "h": 22 }, "frame": { - "x": 72, - "y": 380, + "x": 301, + "y": 265, "w": 22, "h": 22 } }, - { - "filename": "leftovers", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 15, - "h": 22 - }, - "frame": { - "x": 94, - "y": 270, - "w": 15, - "h": 22 - } - }, - { - "filename": "big_mushroom", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 19 - }, - "frame": { - "x": 109, - "y": 273, - "w": 19, - "h": 19 - } - }, { "filename": "x_attack", "rotated": false, @@ -5337,12 +5190,54 @@ "h": 22 }, "frame": { - "x": 94, - "y": 292, + "x": 323, + "y": 265, "w": 22, "h": 22 } }, + { + "filename": "big_nugget", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 171, + "y": 274, + "w": 20, + "h": 20 + } + }, + { + "filename": "upgrade", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 22, + "h": 19 + }, + "frame": { + "x": 191, + "y": 278, + "w": 22, + "h": 19 + } + }, { "filename": "x_defense", "rotated": false, @@ -5358,8 +5253,8 @@ "h": 22 }, "frame": { - "x": 116, - "y": 292, + "x": 213, + "y": 278, "w": 22, "h": 22 } @@ -5379,8 +5274,8 @@ "h": 22 }, "frame": { - "x": 94, - "y": 314, + "x": 235, + "y": 284, "w": 22, "h": 22 } @@ -5400,8 +5295,8 @@ "h": 22 }, "frame": { - "x": 94, - "y": 336, + "x": 257, + "y": 286, "w": 22, "h": 22 } @@ -5421,138 +5316,12 @@ "h": 22 }, "frame": { - "x": 116, - "y": 314, + "x": 279, + "y": 286, "w": 22, "h": 22 } }, - { - "filename": "poison_barb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 94, - "y": 358, - "w": 21, - "h": 21 - } - }, - { - "filename": "shiny_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 116, - "y": 336, - "w": 21, - "h": 21 - } - }, - { - "filename": "sitrus_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 20, - "h": 22 - }, - "frame": { - "x": 94, - "y": 379, - "w": 20, - "h": 22 - } - }, - { - "filename": "zoom_lens", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 138, - "y": 298, - "w": 21, - "h": 21 - } - }, - { - "filename": "sharp_meteorite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 21, - "h": 18 - }, - "frame": { - "x": 138, - "y": 319, - "w": 21, - "h": 18 - } - }, - { - "filename": "upgrade", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 19 - }, - "frame": { - "x": 137, - "y": 337, - "w": 22, - "h": 19 - } - }, { "filename": "dawn_stone", "rotated": false, @@ -5568,8 +5337,8 @@ "h": 21 }, "frame": { - "x": 159, - "y": 302, + "x": 301, + "y": 287, "w": 20, "h": 21 } @@ -5589,14 +5358,35 @@ "h": 20 }, "frame": { - "x": 159, - "y": 323, + "x": 321, + "y": 287, "w": 20, "h": 20 } }, { - "filename": "everstone", + "filename": "masterpiece_teacup", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 21, + "h": 18 + }, + "frame": { + "x": 346, + "y": 146, + "w": 21, + "h": 18 + } + }, + { + "filename": "metal_coat", "rotated": false, "trimmed": true, "sourceSize": { @@ -5605,19 +5395,19 @@ }, "spriteSourceSize": { "x": 6, - "y": 8, - "w": 20, - "h": 17 + "y": 5, + "w": 19, + "h": 22 }, "frame": { - "x": 159, - "y": 343, - "w": 20, - "h": 17 + "x": 345, + "y": 164, + "w": 19, + "h": 22 } }, { - "filename": "revive", + "filename": "sachet", "rotated": false, "trimmed": true, "sourceSize": { @@ -5625,20 +5415,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 12, - "h": 17 + "x": 6, + "y": 4, + "w": 18, + "h": 23 }, "frame": { - "x": 179, - "y": 302, - "w": 12, - "h": 17 + "x": 345, + "y": 186, + "w": 18, + "h": 23 } }, { - "filename": "super_repel", + "filename": "potion", "rotated": false, "trimmed": true, "sourceSize": { @@ -5647,19 +5437,19 @@ }, "spriteSourceSize": { "x": 8, - "y": 4, - "w": 16, - "h": 24 + "y": 5, + "w": 17, + "h": 23 }, "frame": { - "x": 179, - "y": 319, - "w": 16, - "h": 24 + "x": 345, + "y": 209, + "w": 17, + "h": 23 } }, { - "filename": "candy", + "filename": "super_potion", "rotated": false, "trimmed": true, "sourceSize": { @@ -5667,16 +5457,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 7, - "y": 11, - "w": 18, - "h": 18 + "x": 8, + "y": 5, + "w": 17, + "h": 23 }, "frame": { - "x": 179, - "y": 343, - "w": 18, - "h": 18 + "x": 345, + "y": 232, + "w": 17, + "h": 23 } }, { @@ -5694,35 +5484,14 @@ "h": 24 }, "frame": { - "x": 360, - "y": 157, + "x": 345, + "y": 255, "w": 16, "h": 24 } }, { - "filename": "zinc", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 360, - "y": 181, - "w": 16, - "h": 24 - } - }, - { - "filename": "quick_claw", + "filename": "metal_alloy", "rotated": false, "trimmed": true, "sourceSize": { @@ -5731,36 +5500,15 @@ }, "spriteSourceSize": { "x": 6, - "y": 6, - "w": 19, - "h": 21 + "y": 7, + "w": 21, + "h": 19 }, "frame": { - "x": 360, - "y": 205, - "w": 19, - "h": 21 - } - }, - { - "filename": "candy_jar", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 20 - }, - "frame": { - "x": 360, - "y": 226, - "w": 19, - "h": 20 + "x": 371, + "y": 138, + "w": 21, + "h": 19 } }, { @@ -5778,12 +5526,33 @@ "h": 20 }, "frame": { - "x": 359, - "y": 246, + "x": 132, + "y": 279, "w": 20, "h": 20 } }, + { + "filename": "apicot_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 20 + }, + "frame": { + "x": 152, + "y": 280, + "w": 19, + "h": 20 + } + }, { "filename": "magnet", "rotated": false, @@ -5799,8 +5568,8 @@ "h": 20 }, "frame": { - "x": 359, - "y": 266, + "x": 132, + "y": 299, "w": 20, "h": 20 } @@ -5820,8 +5589,8 @@ "h": 20 }, "frame": { - "x": 359, - "y": 286, + "x": 132, + "y": 319, "w": 20, "h": 20 } @@ -5841,8 +5610,71 @@ "h": 20 }, "frame": { - "x": 376, - "y": 156, + "x": 132, + "y": 339, + "w": 20, + "h": 20 + } + }, + { + "filename": "pb_gold", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 132, + "y": 359, + "w": 20, + "h": 20 + } + }, + { + "filename": "quick_claw", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 21 + }, + "frame": { + "x": 152, + "y": 300, + "w": 19, + "h": 21 + } + }, + { + "filename": "rb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 171, + "y": 294, "w": 20, "h": 20 } @@ -5862,14 +5694,35 @@ "h": 21 }, "frame": { - "x": 396, - "y": 156, + "x": 152, + "y": 321, "w": 19, "h": 21 } }, { - "filename": "pb_gold", + "filename": "smooth_meteorite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 171, + "y": 314, + "w": 20, + "h": 20 + } + }, + { + "filename": "strange_ball", "rotated": false, "trimmed": true, "sourceSize": { @@ -5883,12 +5736,117 @@ "h": 20 }, "frame": { - "x": 376, - "y": 176, + "x": 191, + "y": 297, "w": 20, "h": 20 } }, + { + "filename": "zinc", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 152, + "y": 342, + "w": 16, + "h": 24 + } + }, + { + "filename": "everstone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 17 + }, + "frame": { + "x": 191, + "y": 317, + "w": 20, + "h": 17 + } + }, + { + "filename": "ub", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 211, + "y": 300, + "w": 20, + "h": 20 + } + }, + { + "filename": "lum_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 20, + "h": 19 + }, + "frame": { + "x": 211, + "y": 320, + "w": 20, + "h": 19 + } + }, + { + "filename": "candy_jar", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 20 + }, + "frame": { + "x": 231, + "y": 306, + "w": 19, + "h": 20 + } + }, { "filename": "hard_stone", "rotated": false, @@ -5904,287 +5862,14 @@ "h": 20 }, "frame": { - "x": 396, - "y": 177, + "x": 133, + "y": 379, "w": 19, "h": 20 } }, { - "filename": "golden_egg", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 17, - "h": 20 - }, - "frame": { - "x": 379, - "y": 196, - "w": 17, - "h": 20 - } - }, - { - "filename": "miracle_seed", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 19, - "h": 19 - }, - "frame": { - "x": 396, - "y": 197, - "w": 19, - "h": 19 - } - }, - { - "filename": "rb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 379, - "y": 216, - "w": 20, - "h": 20 - } - }, - { - "filename": "abomasite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 399, - "y": 216, - "w": 16, - "h": 16 - } - }, - { - "filename": "smooth_meteorite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 379, - "y": 236, - "w": 20, - "h": 20 - } - }, - { - "filename": "absolite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 399, - "y": 232, - "w": 16, - "h": 16 - } - }, - { - "filename": "aerodactylite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 399, - "y": 248, - "w": 16, - "h": 16 - } - }, - { - "filename": "strange_ball", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 379, - "y": 256, - "w": 20, - "h": 20 - } - }, - { - "filename": "aggronite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 399, - "y": 264, - "w": 16, - "h": 16 - } - }, - { - "filename": "ub", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 379, - "y": 276, - "w": 20, - "h": 20 - } - }, - { - "filename": "alakazite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 399, - "y": 280, - "w": 16, - "h": 16 - } - }, - { - "filename": "unremarkable_teacup", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 21, - "h": 18 - }, - "frame": { - "x": 379, - "y": 296, - "w": 21, - "h": 18 - } - }, - { - "filename": "eviolite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 15, - "h": 15 - }, - "frame": { - "x": 400, - "y": 296, - "w": 15, - "h": 15 - } - }, - { - "filename": "prism_scale", + "filename": "full_heal", "rotated": false, "trimmed": true, "sourceSize": { @@ -6193,19 +5878,19 @@ }, "spriteSourceSize": { "x": 9, - "y": 8, + "y": 4, "w": 15, - "h": 15 + "h": 23 }, "frame": { - "x": 400, - "y": 311, + "x": 152, + "y": 366, "w": 15, - "h": 15 + "h": 23 } }, { - "filename": "lum_berry", + "filename": "revive", "rotated": false, "trimmed": true, "sourceSize": { @@ -6213,16 +5898,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 20, - "h": 19 + "x": 10, + "y": 8, + "w": 12, + "h": 17 }, "frame": { - "x": 359, - "y": 306, - "w": 20, - "h": 19 + "x": 133, + "y": 399, + "w": 12, + "h": 17 } }, { @@ -6240,14 +5925,14 @@ "h": 16 }, "frame": { - "x": 379, - "y": 314, + "x": 231, + "y": 326, "w": 20, "h": 16 } }, { - "filename": "altarianite", + "filename": "sharp_meteorite", "rotated": false, "trimmed": true, "sourceSize": { @@ -6255,16 +5940,37 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, + "x": 6, "y": 8, - "w": 16, - "h": 16 + "w": 21, + "h": 18 }, "frame": { - "x": 399, - "y": 326, - "w": 16, - "h": 16 + "x": 250, + "y": 308, + "w": 21, + "h": 18 + } + }, + { + "filename": "unremarkable_teacup", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 21, + "h": 18 + }, + "frame": { + "x": 271, + "y": 308, + "w": 21, + "h": 18 } }, { @@ -6282,75 +5988,12 @@ "h": 19 }, "frame": { - "x": 195, - "y": 305, + "x": 292, + "y": 308, "w": 20, "h": 19 } }, - { - "filename": "oval_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 19 - }, - "frame": { - "x": 195, - "y": 324, - "w": 18, - "h": 19 - } - }, - { - "filename": "lucky_egg", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 17, - "h": 20 - }, - "frame": { - "x": 215, - "y": 305, - "w": 17, - "h": 20 - } - }, - { - "filename": "razor_fang", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 18, - "h": 20 - }, - "frame": { - "x": 232, - "y": 302, - "w": 18, - "h": 20 - } - }, { "filename": "wl_ability_urge", "rotated": false, @@ -6366,8 +6009,8 @@ "h": 18 }, "frame": { - "x": 250, - "y": 302, + "x": 251, + "y": 326, "w": 20, "h": 18 } @@ -6387,8 +6030,8 @@ "h": 18 }, "frame": { - "x": 270, - "y": 303, + "x": 271, + "y": 326, "w": 20, "h": 18 } @@ -6408,12 +6051,96 @@ "h": 18 }, "frame": { - "x": 213, - "y": 325, + "x": 291, + "y": 327, "w": 20, "h": 18 } }, + { + "filename": "golden_egg", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 17, + "h": 20 + }, + "frame": { + "x": 312, + "y": 308, + "w": 17, + "h": 20 + } + }, + { + "filename": "candy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 11, + "w": 18, + "h": 18 + }, + "frame": { + "x": 311, + "y": 328, + "w": 18, + "h": 18 + } + }, + { + "filename": "leftovers", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 15, + "h": 22 + }, + "frame": { + "x": 329, + "y": 307, + "w": 15, + "h": 22 + } + }, + { + "filename": "dark_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 329, + "y": 329, + "w": 18, + "h": 18 + } + }, { "filename": "wl_burn_heal", "rotated": false, @@ -6429,33 +6156,12 @@ "h": 18 }, "frame": { - "x": 197, - "y": 343, + "x": 171, + "y": 334, "w": 20, "h": 18 } }, - { - "filename": "dark_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 217, - "y": 343, - "w": 18, - "h": 18 - } - }, { "filename": "wl_custom_spliced", "rotated": false, @@ -6471,54 +6177,12 @@ "h": 18 }, "frame": { - "x": 290, - "y": 304, + "x": 191, + "y": 334, "w": 20, "h": 18 } }, - { - "filename": "flame_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 233, - "y": 322, - "w": 18, - "h": 18 - } - }, - { - "filename": "light_ball", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 251, - "y": 320, - "w": 18, - "h": 18 - } - }, { "filename": "wl_custom_thief", "rotated": false, @@ -6534,8 +6198,8 @@ "h": 18 }, "frame": { - "x": 269, - "y": 321, + "x": 211, + "y": 339, "w": 20, "h": 18 } @@ -6555,54 +6219,12 @@ "h": 18 }, "frame": { - "x": 289, - "y": 322, + "x": 231, + "y": 342, "w": 20, "h": 18 } }, - { - "filename": "light_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 235, - "y": 340, - "w": 18, - "h": 18 - } - }, - { - "filename": "ampharosite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 253, - "y": 338, - "w": 16, - "h": 16 - } - }, { "filename": "wl_ether", "rotated": false, @@ -6618,8 +6240,8 @@ "h": 18 }, "frame": { - "x": 269, - "y": 339, + "x": 251, + "y": 344, "w": 20, "h": 18 } @@ -6639,8 +6261,8 @@ "h": 18 }, "frame": { - "x": 289, - "y": 340, + "x": 271, + "y": 344, "w": 20, "h": 18 } @@ -6660,12 +6282,54 @@ "h": 18 }, "frame": { - "x": 310, - "y": 308, + "x": 291, + "y": 345, "w": 20, "h": 18 } }, + { + "filename": "flame_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 311, + "y": 346, + "w": 18, + "h": 18 + } + }, + { + "filename": "light_ball", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 329, + "y": 347, + "w": 18, + "h": 18 + } + }, { "filename": "wl_guard_spec", "rotated": false, @@ -6681,8 +6345,8 @@ "h": 18 }, "frame": { - "x": 309, - "y": 326, + "x": 168, + "y": 352, "w": 20, "h": 18 } @@ -6702,12 +6366,33 @@ "h": 18 }, "frame": { - "x": 309, - "y": 344, + "x": 188, + "y": 352, "w": 20, "h": 18 } }, + { + "filename": "miracle_seed", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 19, + "h": 19 + }, + "frame": { + "x": 167, + "y": 370, + "w": 19, + "h": 19 + } + }, { "filename": "wl_ice_heal", "rotated": false, @@ -6723,8 +6408,8 @@ "h": 18 }, "frame": { - "x": 330, - "y": 309, + "x": 186, + "y": 370, "w": 20, "h": 18 } @@ -6744,12 +6429,54 @@ "h": 18 }, "frame": { - "x": 329, - "y": 327, + "x": 152, + "y": 389, "w": 20, "h": 18 } }, + { + "filename": "light_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 172, + "y": 389, + "w": 18, + "h": 18 + } + }, + { + "filename": "lucky_egg", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 17, + "h": 20 + }, + "frame": { + "x": 190, + "y": 388, + "w": 17, + "h": 20 + } + }, { "filename": "wl_item_urge", "rotated": false, @@ -6765,33 +6492,12 @@ "h": 18 }, "frame": { - "x": 329, - "y": 345, + "x": 208, + "y": 357, "w": 20, "h": 18 } }, - { - "filename": "audinite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 253, - "y": 354, - "w": 16, - "h": 16 - } - }, { "filename": "wl_max_elixir", "rotated": false, @@ -6807,8 +6513,8 @@ "h": 18 }, "frame": { - "x": 269, - "y": 357, + "x": 228, + "y": 360, "w": 20, "h": 18 } @@ -6828,8 +6534,8 @@ "h": 18 }, "frame": { - "x": 289, - "y": 358, + "x": 248, + "y": 362, "w": 20, "h": 18 } @@ -6849,7 +6555,7 @@ "h": 18 }, "frame": { - "x": 309, + "x": 268, "y": 362, "w": 20, "h": 18 @@ -6870,54 +6576,12 @@ "h": 18 }, "frame": { - "x": 329, + "x": 288, "y": 363, "w": 20, "h": 18 } }, - { - "filename": "toxic_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 235, - "y": 358, - "w": 18, - "h": 18 - } - }, - { - "filename": "banettite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 253, - "y": 370, - "w": 16, - "h": 16 - } - }, { "filename": "wl_paralyze_heal", "rotated": false, @@ -6933,8 +6597,8 @@ "h": 18 }, "frame": { - "x": 269, - "y": 375, + "x": 308, + "y": 364, "w": 20, "h": 18 } @@ -6954,12 +6618,75 @@ "h": 18 }, "frame": { - "x": 289, - "y": 376, + "x": 328, + "y": 365, "w": 20, "h": 18 } }, + { + "filename": "razor_fang", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 18, + "h": 20 + }, + "frame": { + "x": 341, + "y": 287, + "w": 18, + "h": 20 + } + }, + { + "filename": "metronome", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 344, + "y": 307, + "w": 17, + "h": 22 + } + }, + { + "filename": "soothe_bell", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 347, + "y": 329, + "w": 17, + "h": 22 + } + }, { "filename": "wl_reset_urge", "rotated": false, @@ -6975,8 +6702,8 @@ "h": 18 }, "frame": { - "x": 309, - "y": 380, + "x": 207, + "y": 375, "w": 20, "h": 18 } @@ -6996,8 +6723,8 @@ "h": 18 }, "frame": { - "x": 329, - "y": 381, + "x": 207, + "y": 393, "w": 20, "h": 18 } @@ -7017,12 +6744,75 @@ "h": 18 }, "frame": { - "x": 116, - "y": 357, + "x": 227, + "y": 378, "w": 20, "h": 18 } }, + { + "filename": "oval_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 19 + }, + "frame": { + "x": 247, + "y": 380, + "w": 18, + "h": 19 + } + }, + { + "filename": "toxic_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 265, + "y": 380, + "w": 18, + "h": 18 + } + }, + { + "filename": "mystery_egg", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 18 + }, + "frame": { + "x": 265, + "y": 398, + "w": 16, + "h": 18 + } + }, { "filename": "relic_band", "rotated": false, @@ -7038,12 +6828,201 @@ "h": 16 }, "frame": { - "x": 115, - "y": 375, + "x": 227, + "y": 396, "w": 17, "h": 16 } }, + { + "filename": "abomasite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 283, + "y": 381, + "w": 16, + "h": 16 + } + }, + { + "filename": "absolite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 244, + "y": 399, + "w": 16, + "h": 16 + } + }, + { + "filename": "aerodactylite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 299, + "y": 382, + "w": 16, + "h": 16 + } + }, + { + "filename": "aggronite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 364, + "y": 164, + "w": 16, + "h": 16 + } + }, + { + "filename": "alakazite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 364, + "y": 180, + "w": 16, + "h": 16 + } + }, + { + "filename": "altarianite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 363, + "y": 196, + "w": 16, + "h": 16 + } + }, + { + "filename": "ampharosite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 362, + "y": 212, + "w": 16, + "h": 16 + } + }, + { + "filename": "audinite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 362, + "y": 228, + "w": 16, + "h": 16 + } + }, + { + "filename": "banettite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 362, + "y": 244, + "w": 16, + "h": 16 + } + }, { "filename": "beedrillite", "rotated": false, @@ -7059,12 +7038,33 @@ "h": 16 }, "frame": { - "x": 114, - "y": 391, + "x": 361, + "y": 260, "w": 16, "h": 16 } }, + { + "filename": "eviolite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 15, + "h": 15 + }, + "frame": { + "x": 380, + "y": 157, + "w": 15, + "h": 15 + } + }, { "filename": "blastoisinite", "rotated": false, @@ -7080,8 +7080,8 @@ "h": 16 }, "frame": { - "x": 130, - "y": 399, + "x": 380, + "y": 172, "w": 16, "h": 16 } @@ -7101,8 +7101,8 @@ "h": 16 }, "frame": { - "x": 146, - "y": 399, + "x": 380, + "y": 188, "w": 16, "h": 16 } @@ -7122,8 +7122,8 @@ "h": 16 }, "frame": { - "x": 162, - "y": 399, + "x": 379, + "y": 204, "w": 16, "h": 16 } @@ -7143,8 +7143,8 @@ "h": 16 }, "frame": { - "x": 178, - "y": 399, + "x": 378, + "y": 220, "w": 16, "h": 16 } @@ -7164,218 +7164,8 @@ "h": 16 }, "frame": { - "x": 194, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "diancite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 210, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "galladite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 226, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "garchompite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 242, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "gardevoirite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 258, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "gengarite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 274, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "glalitite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 290, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "gyaradosite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 306, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "heracronite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 322, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "houndoominite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 338, - "y": 399, - "w": 16, - "h": 16 - } - }, - { - "filename": "kangaskhanite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 132, - "y": 375, + "x": 378, + "y": 236, "w": 16, "h": 16 } @@ -7395,12 +7185,243 @@ "h": 15 }, "frame": { - "x": 136, - "y": 360, + "x": 378, + "y": 252, "w": 16, "h": 15 } }, + { + "filename": "diancite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 377, + "y": 267, + "w": 16, + "h": 16 + } + }, + { + "filename": "galladite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 361, + "y": 276, + "w": 16, + "h": 16 + } + }, + { + "filename": "prism_scale", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 9, + "y": 8, + "w": 15, + "h": 15 + }, + "frame": { + "x": 359, + "y": 292, + "w": 15, + "h": 15 + } + }, + { + "filename": "garchompite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 361, + "y": 307, + "w": 16, + "h": 16 + } + }, + { + "filename": "gardevoirite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 377, + "y": 283, + "w": 16, + "h": 16 + } + }, + { + "filename": "gengarite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 377, + "y": 299, + "w": 16, + "h": 16 + } + }, + { + "filename": "glalitite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 377, + "y": 315, + "w": 16, + "h": 16 + } + }, + { + "filename": "gyaradosite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 364, + "y": 331, + "w": 16, + "h": 16 + } + }, + { + "filename": "heracronite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 380, + "y": 331, + "w": 16, + "h": 16 + } + }, + { + "filename": "houndoominite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 364, + "y": 347, + "w": 16, + "h": 16 + } + }, + { + "filename": "kangaskhanite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 380, + "y": 347, + "w": 16, + "h": 16 + } + }, { "filename": "latiasite", "rotated": false, @@ -7416,8 +7437,8 @@ "h": 16 }, "frame": { - "x": 152, - "y": 360, + "x": 348, + "y": 351, "w": 16, "h": 16 } @@ -7437,8 +7458,8 @@ "h": 16 }, "frame": { - "x": 148, - "y": 376, + "x": 348, + "y": 367, "w": 16, "h": 16 } @@ -7458,8 +7479,8 @@ "h": 16 }, "frame": { - "x": 168, - "y": 361, + "x": 364, + "y": 363, "w": 16, "h": 16 } @@ -7479,8 +7500,8 @@ "h": 16 }, "frame": { - "x": 184, - "y": 361, + "x": 380, + "y": 363, "w": 16, "h": 16 } @@ -7500,8 +7521,8 @@ "h": 16 }, "frame": { - "x": 200, - "y": 361, + "x": 364, + "y": 379, "w": 16, "h": 16 } @@ -7521,8 +7542,8 @@ "h": 16 }, "frame": { - "x": 216, - "y": 361, + "x": 380, + "y": 379, "w": 16, "h": 16 } @@ -7542,8 +7563,8 @@ "h": 16 }, "frame": { - "x": 164, - "y": 377, + "x": 281, + "y": 398, "w": 16, "h": 16 } @@ -7563,8 +7584,8 @@ "h": 16 }, "frame": { - "x": 180, - "y": 377, + "x": 297, + "y": 398, "w": 16, "h": 16 } @@ -7584,8 +7605,8 @@ "h": 16 }, "frame": { - "x": 196, - "y": 377, + "x": 396, + "y": 158, "w": 16, "h": 16 } @@ -7605,8 +7626,8 @@ "h": 16 }, "frame": { - "x": 212, - "y": 377, + "x": 396, + "y": 174, "w": 16, "h": 16 } @@ -7626,8 +7647,8 @@ "h": 16 }, "frame": { - "x": 228, - "y": 377, + "x": 396, + "y": 190, "w": 16, "h": 16 } @@ -7647,8 +7668,8 @@ "h": 16 }, "frame": { - "x": 349, - "y": 327, + "x": 395, + "y": 206, "w": 16, "h": 16 } @@ -7668,8 +7689,8 @@ "h": 16 }, "frame": { - "x": 349, - "y": 343, + "x": 394, + "y": 222, "w": 16, "h": 16 } @@ -7689,8 +7710,8 @@ "h": 16 }, "frame": { - "x": 349, - "y": 359, + "x": 394, + "y": 238, "w": 16, "h": 16 } @@ -7710,8 +7731,8 @@ "h": 16 }, "frame": { - "x": 349, - "y": 375, + "x": 394, + "y": 254, "w": 16, "h": 16 } @@ -7731,8 +7752,8 @@ "h": 16 }, "frame": { - "x": 354, - "y": 391, + "x": 393, + "y": 270, "w": 16, "h": 16 } @@ -7752,8 +7773,8 @@ "h": 16 }, "frame": { - "x": 365, - "y": 330, + "x": 393, + "y": 286, "w": 16, "h": 16 } @@ -7773,8 +7794,8 @@ "h": 16 }, "frame": { - "x": 381, - "y": 330, + "x": 393, + "y": 302, "w": 16, "h": 16 } @@ -7794,8 +7815,8 @@ "h": 16 }, "frame": { - "x": 365, - "y": 346, + "x": 315, + "y": 383, "w": 16, "h": 16 } @@ -7815,8 +7836,8 @@ "h": 16 }, "frame": { - "x": 365, - "y": 362, + "x": 331, + "y": 383, "w": 16, "h": 16 } @@ -7836,8 +7857,8 @@ "h": 16 }, "frame": { - "x": 381, - "y": 346, + "x": 347, + "y": 383, "w": 16, "h": 16 } @@ -7857,8 +7878,8 @@ "h": 16 }, "frame": { - "x": 381, - "y": 362, + "x": 313, + "y": 399, "w": 16, "h": 16 } @@ -7878,8 +7899,8 @@ "h": 16 }, "frame": { - "x": 397, - "y": 342, + "x": 329, + "y": 399, "w": 16, "h": 16 } @@ -7899,8 +7920,8 @@ "h": 16 }, "frame": { - "x": 397, - "y": 358, + "x": 345, + "y": 399, "w": 16, "h": 16 } @@ -7920,8 +7941,8 @@ "h": 16 }, "frame": { - "x": 397, - "y": 374, + "x": 363, + "y": 395, "w": 16, "h": 16 } @@ -7941,8 +7962,8 @@ "h": 16 }, "frame": { - "x": 370, - "y": 378, + "x": 379, + "y": 395, "w": 16, "h": 16 } @@ -7953,6 +7974,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:60db8f4653a650759cd9189e91c38a40:439307cbef9c000f6c45603b2d82d107:110e074689c9edd2c54833ce2e4d9270$" + "smartupdate": "$TexturePacker:SmartUpdate:1b6e262a772654e8b35b755bf9f72b4b:d747988c68896024764564ae07a7c2a2:110e074689c9edd2c54833ce2e4d9270$" } } diff --git a/public/images/items.png b/public/images/items.png index 6d9434d0454..4857c4a66e4 100644 Binary files a/public/images/items.png and b/public/images/items.png differ diff --git a/public/images/mystery-encounters/berry_juice.png b/public/images/items/berry_juice.png similarity index 100% rename from public/images/mystery-encounters/berry_juice.png rename to public/images/items/berry_juice.png diff --git a/public/images/mystery-encounters/encounter_radar.json b/public/images/mystery-encounters/encounter_radar.json new file mode 100644 index 00000000000..82f16af59f6 --- /dev/null +++ b/public/images/mystery-encounters/encounter_radar.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "encounter_radar.png", + "format": "RGBA8888", + "size": { + "w": 17, + "h": 16 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 15, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 15, + "h": 14 + }, + "frame": { + "x": 1, + "y": 1, + "w": 15, + "h": 14 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:eb3445f19546ab36edb2909c89b8aa86:c8de156a28ef70ee4ddf70cffe1ba3ba:e7008b81ccf0cb0325145a809afa6165$" + } +} diff --git a/public/images/mystery-encounters/encounter_radar.png b/public/images/mystery-encounters/encounter_radar.png new file mode 100644 index 00000000000..deb9426c269 Binary files /dev/null and b/public/images/mystery-encounters/encounter_radar.png differ diff --git a/public/images/mystery-encounters/berry_juice.json b/public/images/mystery-encounters/pokemon_salesman.json similarity index 57% rename from public/images/mystery-encounters/berry_juice.json rename to public/images/mystery-encounters/pokemon_salesman.json index 1a5331368ad..23d9df44f2b 100644 --- a/public/images/mystery-encounters/berry_juice.json +++ b/public/images/mystery-encounters/pokemon_salesman.json @@ -1,11 +1,11 @@ { "textures": [ { - "image": "berry_juice.png", + "image": "pokemon_salesman.png", "format": "RGBA8888", "size": { - "w": 24, - "h": 23 + "w": 40, + "h": 80 }, "scale": 1, "frames": [ @@ -14,20 +14,20 @@ "rotated": false, "trimmed": true, "sourceSize": { - "w": 24, - "h": 24 + "w": 80, + "h": 80 }, "spriteSourceSize": { - "x": 1, + "x": 21, "y": 2, - "w": 22, - "h": 21 + "w": 38, + "h": 78 }, "frame": { "x": 1, "y": 1, - "w": 22, - "h": 21 + "w": 38, + "h": 78 } } ] @@ -36,6 +36,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:04685a0eb6ef9095824b65408ec1b38f:9891674d538df100fcddde29330c21ae:927f117bdb1c2a27226a5540ce00ee8b$" + "smartupdate": "$TexturePacker:SmartUpdate:dd57e3db21f3933c15be65bec261f4c1:05c7ef32252a5c2d3ad007b7e26fabd7:ae82f52e471ed81e2558206f05476cd7$" } } diff --git a/public/images/mystery-encounters/pokemon_salesman.png b/public/images/mystery-encounters/pokemon_salesman.png new file mode 100644 index 00000000000..1251dd8eda7 Binary files /dev/null and b/public/images/mystery-encounters/pokemon_salesman.png differ diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 4c0f31b051e..a017b8eb49e 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -67,7 +67,7 @@ import { UiTheme } from "#enums/ui-theme"; import { TimedEventManager } from "#app/timed-event-manager.js"; import i18next from "i18next"; import IMysteryEncounter, { MysteryEncounterTier, MysteryEncounterVariant } from "./data/mystery-encounters/mystery-encounter"; -import { allMysteryEncounters, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, mysteryEncountersByBiome, WIGHT_INCREMENT_ON_SPAWN_MISS } from "./data/mystery-encounters/mystery-encounters"; +import { allMysteryEncounters, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, mysteryEncountersByBiome, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "./data/mystery-encounters/mystery-encounters"; import { MysteryEncounterData } from "#app/data/mystery-encounters/mystery-encounter-data"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; @@ -1074,7 +1074,7 @@ export default class BattleScene extends SceneBase { // let testStartingWeight = 0; // while (testStartingWeight < 3) { // calculateMEAggregateStats(this, testStartingWeight); - // testStartingWeight += 1; + // testStartingWeight += 2; // } // Check for mystery encounter // Can only occur in place of a standard wild battle, waves 10-180 @@ -1098,7 +1098,7 @@ export default class BattleScene extends SceneBase { // Reset base spawn weight this.mysteryEncounterData.encounterSpawnChance = BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT; } else { - this.mysteryEncounterData.encounterSpawnChance = sessionEncounterRate + WIGHT_INCREMENT_ON_SPAWN_MISS; + this.mysteryEncounterData.encounterSpawnChance = sessionEncounterRate + WEIGHT_INCREMENT_ON_SPAWN_MISS; } } } diff --git a/src/data/mystery-encounters/encounters/field-trip-encounter.ts b/src/data/mystery-encounters/encounters/field-trip-encounter.ts index 21db15ac7e0..525e2b91f8b 100644 --- a/src/data/mystery-encounters/encounters/field-trip-encounter.ts +++ b/src/data/mystery-encounters/encounters/field-trip-encounter.ts @@ -87,11 +87,17 @@ export const FieldTripEncounter: IMysteryEncounter = if (!correctMove) { encounter.options[0].dialogue.selected = [ { - text: `${namespace}:incorrect`, - speaker: `${namespace}:speaker`, + text: `${namespace}:option:incorrect`, + speaker: `${namespace}:option:speaker`, }, { - text: `${namespace}:lesson_learned`, + text: `${namespace}:option:lesson_learned`, + }, + ]; + encounter.dialogue.outro = [ + { + text: `${namespace}:outro_bad`, + speaker: `${namespace}:speaker`, }, ]; setEncounterExp(scene, scene.getParty().map((p) => p.id), 50); @@ -103,6 +109,12 @@ export const FieldTripEncounter: IMysteryEncounter = text: `${namespace}:option:selected`, }, ]; + encounter.dialogue.outro = [ + { + text: `${namespace}:outro_good`, + speaker: `${namespace}:speaker`, + }, + ]; setEncounterExp(scene, [pokemon.id], 100); } encounter.misc = { @@ -161,11 +173,23 @@ export const FieldTripEncounter: IMysteryEncounter = if (!correctMove) { encounter.options[1].dialogue.selected = [ { - text: `${namespace}:incorrect`, - speaker: `${namespace}:speaker`, + text: `${namespace}:option:incorrect`, + speaker: `${namespace}:option:speaker`, }, { - text: `${namespace}:lesson_learned`, + text: `${namespace}:option:lesson_learned`, + }, + ]; + encounter.dialogue.outro = [ + { + text: `${namespace}:outro_bad`, + speaker: `${namespace}:speaker`, + }, + ]; + encounter.dialogue.outro = [ + { + text: `${namespace}:outro_bad`, + speaker: `${namespace}:speaker`, }, ]; setEncounterExp(scene, scene.getParty().map((p) => p.id), 50); @@ -177,6 +201,12 @@ export const FieldTripEncounter: IMysteryEncounter = text: `${namespace}:option:selected`, }, ]; + encounter.dialogue.outro = [ + { + text: `${namespace}:outro_good`, + speaker: `${namespace}:speaker`, + }, + ]; setEncounterExp(scene, [pokemon.id], 100); } encounter.misc = { @@ -235,18 +265,20 @@ export const FieldTripEncounter: IMysteryEncounter = if (!correctMove) { encounter.options[2].dialogue.selected = [ { - text: `${namespace}:incorrect`, - speaker: `${namespace}:speaker`, + text: `${namespace}:option:incorrect`, + speaker: `${namespace}:option:speaker`, }, { - text: `${namespace}:lesson_learned`, + text: `${namespace}:option:lesson_learned`, }, ]; - setEncounterExp( - scene, - scene.getParty().map((p) => p.id), - 50 - ); + encounter.dialogue.outro = [ + { + text: `${namespace}:outro_bad`, + speaker: `${namespace}:speaker`, + }, + ]; + setEncounterExp(scene, scene.getParty().map((p) => p.id), 50); } else { encounter.setDialogueToken("pokeName", pokemon.name); encounter.setDialogueToken("move", move.getName()); @@ -255,6 +287,12 @@ export const FieldTripEncounter: IMysteryEncounter = text: `${namespace}:option:selected`, }, ]; + encounter.dialogue.outro = [ + { + text: `${namespace}:outro_good`, + speaker: `${namespace}:speaker`, + }, + ]; setEncounterExp(scene, [pokemon.id], 100); } encounter.misc = { diff --git a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts index 2d142f46d4e..5e7d3704fc0 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts @@ -48,7 +48,7 @@ export const FightOrFlightEncounter: IMysteryEncounter = .withIntroSpriteConfigs([]) // Set in onInit() .withIntroDialogue([ { - text: `${namespace}_intro_message`, + text: `${namespace}:intro`, }, ]) .withOnInit((scene: BattleScene) => { @@ -87,6 +87,7 @@ export const FightOrFlightEncounter: IMysteryEncounter = y: -5, scale: 0.75, isItem: true, + disableAnimation: true }, { spriteKey: bossSpriteKey, @@ -149,7 +150,7 @@ export const FightOrFlightEncounter: IMysteryEncounter = const primaryPokemon = encounter.options[1].primaryPokemon; if (primaryPokemon) { // Use primaryPokemon to execute the thievery - await showEncounterText(scene, `${namespace}:option:2:steal_result`); + await showEncounterText(scene, `${namespace}:option:2:special_result`); leaveEncounterWithoutBattle(scene); return; } diff --git a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts index 382dc1f212e..f18d7655936 100644 --- a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts @@ -169,7 +169,7 @@ export const MysteriousChallengersEncounter: IMysteryEncounter = // Spawn hard fight with ULTRA/GREAT reward (can improve with luck) const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1]; - setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], fillRemaining: true }); + setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], fillRemaining: true }); // Seed offsets to remove possibility of different trainers having exact same teams let ret; @@ -197,7 +197,7 @@ export const MysteriousChallengersEncounter: IMysteryEncounter = // To avoid player level snowballing from picking this option encounter.expMultiplier = 0.9; - setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true }); + setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true }); // Seed offsets to remove possibility of different trainers having exact same teams let ret; diff --git a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts index e8db89a6961..13c5b9cc1e4 100644 --- a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts @@ -34,8 +34,8 @@ export const MysteriousChestEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: "${namespace}:intro:message", - }, + text: `${namespace}:intro`, + } ]) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) diff --git a/src/data/mystery-encounters/encounters/pokemon-salesman-encounter.ts b/src/data/mystery-encounters/encounters/pokemon-salesman-encounter.ts new file mode 100644 index 00000000000..9c8ee2ac91c --- /dev/null +++ b/src/data/mystery-encounters/encounters/pokemon-salesman-encounter.ts @@ -0,0 +1,156 @@ +import { leaveEncounterWithoutBattle, transitionMysteryEncounterIntroVisuals, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { isNullOrUndefined, randSeedInt } from "#app/utils"; +import { MysteryEncounterType } from "#enums/mystery-encounter-type"; +import BattleScene from "../../../battle-scene"; +import IMysteryEncounter, { MysteryEncounterBuilder, MysteryEncounterTier, } from "../mystery-encounter"; +import { MoneyRequirement } from "../mystery-encounter-requirements"; +import { catchPokemon, getRandomSpeciesByStarterTier } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species"; +import { Species } from "#enums/species"; +import { PokeballType } from "#app/data/pokeball"; +import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon"; +import { EncounterOptionMode, MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; +import { showEncounterDialogue } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; +import PokemonData from "#app/system/pokemon-data"; + +/** the i18n namespace for this encounter */ +const namespace = "mysteryEncounter:pokemonSalesman"; + +const MAX_POKEMON_PRICE_MULTIPLIER = 6; + +/** + * Pokemon Salesman encounter. + * @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/36 | GitHub Issue #36} + * @see For biome requirements check {@linkcode mysteryEncountersByBiome} + */ +export const PokemonSalesmanEncounter: IMysteryEncounter = + MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.POKEMON_SALESMAN) + .withEncounterTier(MysteryEncounterTier.ULTRA) + .withSceneWaveRangeRequirement(10, 180) + .withSceneRequirement(new MoneyRequirement(null, MAX_POKEMON_PRICE_MULTIPLIER)) // Some costs may not be as significant, this is the max you'd pay + .withAutoHideIntroVisuals(false) + .withIntroSpriteConfigs([ + { + spriteKey: "pokemon_salesman", + fileRoot: "mystery-encounters", + hasShadow: true + } + ]) + .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; + + let species = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5])); + const tries = 0; + + // Reroll any species that don't have HAs + while (isNullOrUndefined(species.abilityHidden) && tries < 5) { + species = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5])); + } + + let pokemon: PlayerPokemon; + if (isNullOrUndefined(species.abilityHidden) || randSeedInt(100) === 0) { + // If no HA mon found or you roll 1%, give shiny Magikarp + species = getPokemonSpecies(Species.MAGIKARP); + const hiddenIndex = species.ability2 ? 2 : 1; + pokemon = scene.addPlayerPokemon(species, 5, hiddenIndex, species.formIndex, null, true); + } else { + const hiddenIndex = species.ability2 ? 2 : 1; + pokemon = scene.addPlayerPokemon(species, 5, hiddenIndex, species.formIndex); + } + + const spriteKey = pokemon.getSpriteId(); + const spriteRoot = pokemon.getSpriteAtlasPath(); + encounter.spriteConfigs.push({ + spriteKey: spriteKey, + fileRoot: spriteRoot, + hasShadow: true, + repeat: true, + isPokemon: true + }); + + const starterTier = speciesStarters[species.speciesId]; + // Prices decrease by starter tier less than 5, but only reduces cost by half at max + let priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER * (Math.max(starterTier, 2.5) / 5); + if (pokemon.shiny) { + // Always max price for shiny (flip HA back to normal), and add special messaging + priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER; + pokemon.abilityIndex = 0; + encounter.dialogue.encounterOptionsDialogue.description = `${namespace}:description_shiny`; + encounter.options[0].dialogue.buttonTooltip = `${namespace}:option:1:tooltip_shiny`; + } + const price = scene.getWaveMoneyAmount(priceMultiplier); + encounter.setDialogueToken("purchasePokemon", pokemon.name); + encounter.setDialogueToken("price", price.toString()); + encounter.misc = { + price: price, + pokemon: pokemon + }; + + pokemon.calculateStats(); + + return true; + }) + .withOption( + new MysteryEncounterOptionBuilder() + .withOptionMode(EncounterOptionMode.DEFAULT_OR_SPECIAL) + .withHasDexProgress(true) + .withSceneMoneyRequirement(null, MAX_POKEMON_PRICE_MULTIPLIER) // Wave scaling money multiplier of 2 + .withDialogue({ + buttonLabel: `${namespace}:option:1:label`, + buttonTooltip: `${namespace}:option:1:tooltip`, + selected: [ + { + text: `${namespace}:option:1:selected_message`, + } + ], + }) + .withOptionPhase(async (scene: BattleScene) => { + const encounter = scene.currentBattle.mysteryEncounter; + const price = encounter.misc.price; + const purchasedPokemon = encounter.misc.pokemon as PlayerPokemon; + + // Update money + updatePlayerMoney(scene, -price, true, false); + + // Show dialogue + await showEncounterDialogue(scene, `${namespace}:option:1:selected_dialogue`, `${namespace}:speaker`); + await transitionMysteryEncounterIntroVisuals(scene); + + // "Catch" purchased pokemon + const data = new PokemonData(purchasedPokemon); + data.player = false; + await catchPokemon(scene, data.toPokemon(scene) as EnemyPokemon, null, PokeballType.POKEBALL, true); + + leaveEncounterWithoutBattle(scene, true); + }) + .build() + ) + .withSimpleOption( + { + buttonLabel: `${namespace}:option:2:label`, + buttonTooltip: `${namespace}:option:2:tooltip`, + selected: [ + { + text: `${namespace}:option:2:selected`, + }, + ], + }, + async (scene: BattleScene) => { + // Leave encounter with no rewards or exp + leaveEncounterWithoutBattle(scene, true); + return true; + } + ) + .build(); diff --git a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts index b199b43e952..05c34ba6973 100644 --- a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts @@ -19,6 +19,11 @@ import { BerryType } from "#enums/berry-type"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounter:theStrongStuff"; +/** + * The Strong Stuff encounter. + * @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/54 | GitHub Issue #54} + * @see For biome requirements check {@linkcode mysteryEncountersByBiome} + */ export const TheStrongStuffEncounter: IMysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_STRONG_STUFF) .withEncounterTier(MysteryEncounterTier.COMMON) @@ -28,12 +33,13 @@ export const TheStrongStuffEncounter: IMysteryEncounter = .withIntroSpriteConfigs([ { spriteKey: "berry_juice", - fileRoot: "mystery-encounters", + fileRoot: "items", hasShadow: true, + isItem: true, scale: 1.5, x: -15, y: 3, - yShadow: 0 + disableAnimation: true }, { spriteKey: Species.SHUCKLE.toString(), diff --git a/src/data/mystery-encounters/encounters/training-session-encounter.ts b/src/data/mystery-encounters/encounters/training-session-encounter.ts index 2c09b0a01c7..a3f18395fe2 100644 --- a/src/data/mystery-encounters/encounters/training-session-encounter.ts +++ b/src/data/mystery-encounters/encounters/training-session-encounter.ts @@ -3,7 +3,7 @@ import { EnemyPartyConfig, initBattleWithEnemyConfig, selectPokemonForOption, se import { getNatureName, Nature } from "#app/data/nature"; import { speciesStarters } from "#app/data/pokemon-species"; import { Stat } from "#app/data/pokemon-stat"; -import { PlayerPokemon } from "#app/field/pokemon"; +import Pokemon, { PlayerPokemon } from "#app/field/pokemon"; import { pokemonInfo } from "#app/locales/en/pokemon-info"; import { PokemonHeldItemModifier } from "#app/modifier/modifier"; import { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; @@ -16,7 +16,7 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "../../../battle-scene"; import IMysteryEncounter, { MysteryEncounterBuilder, MysteryEncounterTier, } from "../mystery-encounter"; import { EncounterOptionMode, MysteryEncounterOptionBuilder } from "../mystery-encounter-option"; -import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; +import { getEncounterText, queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; /** The i18n namespace for the encounter */ const namespace = "mysteryEncounter:trainingSession"; @@ -27,11 +27,10 @@ const namespace = "mysteryEncounter:trainingSession"; * @see For biome requirements check {@linkcode mysteryEncountersByBiome} */ export const TrainingSessionEncounter: IMysteryEncounter = - MysteryEncounterBuilder.withEncounterType( - MysteryEncounterType.TRAINING_SESSION - ) + MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TRAINING_SESSION) .withEncounterTier(MysteryEncounterTier.ULTRA) .withSceneWaveRangeRequirement(10, 180) // waves 10 to 180 + .withScenePartySizeRequirement(2, 6, true) // Must have at least 2 unfainted pokemon in party .withHideWildIntroMessage(true) .withIntroSpriteConfigs([ { @@ -46,7 +45,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = .withIntroDialogue([ { text: `${namespace}:intro`, - }, + } ]) .withTitle(`${namespace}:title`) .withDescription(`${namespace}:description`) @@ -54,6 +53,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = .withOption( new MysteryEncounterOptionBuilder() .withOptionMode(EncounterOptionMode.DEFAULT) + .withHasDexProgress(true) .withDialogue({ buttonLabel: `${namespace}:option:1:label`, buttonTooltip: `${namespace}:option:1:tooltip`, @@ -71,7 +71,17 @@ export const TrainingSessionEncounter: IMysteryEncounter = }; }; - return selectPokemonForOption(scene, onPokemonSelected); + // Only Pokemon that are not KOed/legal can be trained + const selectableFilter = (pokemon: Pokemon) => { + const meetsReqs = pokemon.isAllowedInBattle(); + if (!meetsReqs) { + return getEncounterText(scene, `${namespace}:invalid_selection`); + } + + return null; + }; + + return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter); }) .withOptionPhase(async (scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; @@ -187,6 +197,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = .withOption( new MysteryEncounterOptionBuilder() .withOptionMode(EncounterOptionMode.DEFAULT) + .withHasDexProgress(true) .withDialogue({ buttonLabel: `${namespace}:option:2:label`, buttonTooltip: `${namespace}:option:2:tooltip`, @@ -220,7 +231,17 @@ export const TrainingSessionEncounter: IMysteryEncounter = }); }; - return selectPokemonForOption(scene, onPokemonSelected); + // Only Pokemon that are not KOed/legal can be trained + const selectableFilter = (pokemon: Pokemon) => { + const meetsReqs = pokemon.isAllowedInBattle(); + if (!meetsReqs) { + return getEncounterText(scene, `${namespace}:invalid_selection`); + } + + return null; + }; + + return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter); }) .withOptionPhase(async (scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; @@ -269,6 +290,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = .withOption( new MysteryEncounterOptionBuilder() .withOptionMode(EncounterOptionMode.DEFAULT) + .withHasDexProgress(true) .withDialogue({ buttonLabel: `${namespace}:option:3:label`, buttonTooltip: `${namespace}:option:3:tooltip`, @@ -311,7 +333,17 @@ export const TrainingSessionEncounter: IMysteryEncounter = }); }; - return selectPokemonForOption(scene, onPokemonSelected); + // Only Pokemon that are not KOed/legal can be trained + const selectableFilter = (pokemon: Pokemon) => { + const meetsReqs = pokemon.isAllowedInBattle(); + if (!meetsReqs) { + return getEncounterText(scene, `${namespace}:invalid_selection`); + } + + return null; + }; + + return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter); }) .withOptionPhase(async (scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; @@ -393,23 +425,12 @@ export const TrainingSessionEncounter: IMysteryEncounter = ) .build(); -function getEnemyConfig( - scene: BattleScene, - playerPokemon: PlayerPokemon, - segments: number, - modifiers: ModifiersHolder -): EnemyPartyConfig { +function getEnemyConfig(scene: BattleScene, playerPokemon: PlayerPokemon,segments: number,modifiers: ModifiersHolder): EnemyPartyConfig { playerPokemon.resetSummonData(); // Passes modifiers by reference - modifiers.value = scene.findModifiers( - (m) => - m instanceof PokemonHeldItemModifier && - (m as PokemonHeldItemModifier).pokemonId === playerPokemon.id - ) as PokemonHeldItemModifier[]; - const modifierTypes = modifiers.value.map( - (mod) => mod.type - ) as PokemonHeldItemModifierType[]; + modifiers.value = scene.findModifiers((m) => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).pokemonId === playerPokemon.id) as PokemonHeldItemModifier[]; + const modifierTypes = modifiers.value.map((mod) => mod.type) as PokemonHeldItemModifierType[]; const data = new PokemonData(playerPokemon); return { diff --git a/src/data/mystery-encounters/mystery-encounter-option.ts b/src/data/mystery-encounters/mystery-encounter-option.ts index c7feb2688c3..8b9b26e2f95 100644 --- a/src/data/mystery-encounters/mystery-encounter-option.ts +++ b/src/data/mystery-encounters/mystery-encounter-option.ts @@ -6,6 +6,7 @@ import * as Utils from "../../utils"; import { Type } from "../type"; import { EncounterPokemonRequirement, EncounterSceneRequirement, MoneyRequirement, TypeRequirement } from "./mystery-encounter-requirements"; import { CanLearnMoveRequirement, CanLearnMoveRequirementOptions } from "./requirements/can-learn-move-requirement"; +import { isNullOrUndefined } from "../../utils"; export enum EncounterOptionMode { /** Default style */ @@ -23,6 +24,9 @@ export type OptionPhaseCallback = (scene: BattleScene) => Promise> { + return Object.assign(this, { hasDexProgress: hasDexProgress }); + } + withSceneRequirement(requirement: EncounterSceneRequirement): this & Required> { this.requirements.push(requirement); return Object.assign(this, { requirements: this.requirements }); diff --git a/src/data/mystery-encounters/mystery-encounter-requirements.ts b/src/data/mystery-encounters/mystery-encounter-requirements.ts index ac1d49c919e..6f0b408e1d9 100644 --- a/src/data/mystery-encounters/mystery-encounter-requirements.ts +++ b/src/data/mystery-encounters/mystery-encounter-requirements.ts @@ -144,20 +144,23 @@ export class WeatherRequirement extends EncounterSceneRequirement { export class PartySizeRequirement extends EncounterSceneRequirement { partySizeRange: [number, number]; + excludeFainted: boolean; /** * Used for specifying a party size requirement * If min and max are equivalent, will check for exact size * @param partySizeRange - [min, max] + * @param excludeFainted */ - constructor(partySizeRange: [number, number]) { + constructor(partySizeRange: [number, number], excludeFainted: boolean) { super(); this.partySizeRange = partySizeRange; + this.excludeFainted = excludeFainted; } meetsRequirement(scene: BattleScene): boolean { if (!isNullOrUndefined(this?.partySizeRange) && this.partySizeRange?.[0] <= this.partySizeRange?.[1]) { - const partySize = scene.getParty().length; + const partySize = this.excludeFainted ? scene.getParty().filter(p => p.isAllowedInBattle()).length : scene.getParty().length; if (partySize >= 0 && (this?.partySizeRange?.[0] >= 0 && this.partySizeRange?.[0] > partySize) || (this?.partySizeRange?.[1] >= 0 && this.partySizeRange?.[1] < partySize)) { return false; } diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts index b18707968a3..aa9d4ef0997 100644 --- a/src/data/mystery-encounters/mystery-encounter.ts +++ b/src/data/mystery-encounters/mystery-encounter.ts @@ -403,7 +403,7 @@ export class MysteryEncounterBuilder implements Partial { options?: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]] = [null, null]; spriteConfigs?: MysteryEncounterSpriteConfig[]; - dialogue?: MysteryEncounterDialogue; + dialogue?: MysteryEncounterDialogue = {}; encounterTier?: MysteryEncounterTier; encounterAnimations?: EncounterAnim[]; requirements?: EncounterSceneRequirement[] = []; @@ -460,6 +460,7 @@ export class MysteryEncounterBuilder implements Partial { * There should be at least 2 options defined and no more than 4. * If complex use {@linkcode MysteryEncounterBuilder.withOption} * + * @param hasDexProgress - * @param dialogue - {@linkcode OptionTextDisplay} * @param callback - {@linkcode OptionPhaseCallback} * @returns @@ -468,6 +469,24 @@ export class MysteryEncounterBuilder implements Partial { return this.withOption(new MysteryEncounterOptionBuilder().withOptionMode(EncounterOptionMode.DEFAULT).withDialogue(dialogue).withOptionPhase(callback).build()); } + /** + * Defines an option + phasefor the encounter. + * Use for easy/streamlined options. + * There should be at least 2 options defined and no more than 4. + * If complex use {@linkcode MysteryEncounterBuilder.withOption} + * + * @param dialogue - {@linkcode OptionTextDisplay} + * @param callback - {@linkcode OptionPhaseCallback} + * @returns + */ + withSimpleDexProgressOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback): this & Pick { + return this.withOption(new MysteryEncounterOptionBuilder() + .withOptionMode(EncounterOptionMode.DEFAULT) + .withHasDexProgress(true) + .withDialogue(dialogue) + .withOptionPhase(callback).build()); + } + /** * Defines the sprites that will be shown on the enemy field when the encounter spawns * Can be one or more sprites, recommended not to exceed 4 @@ -478,7 +497,7 @@ export class MysteryEncounterBuilder implements Partial { return Object.assign(this, { spriteConfigs: spriteConfigs }); } - withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []) { + withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []): this { this.dialogue = {...this.dialogue, intro: dialogue }; return this; } @@ -550,7 +569,7 @@ export class MysteryEncounterBuilder implements Partial { * @param max optional max wave. If not given, defaults to min => exact wave * @returns */ - withSceneWaveRangeRequirement(min: number, max?: number) { + withSceneWaveRangeRequirement(min: number, max?: number): this & Required> { return this.withSceneRequirement(new WaveRangeRequirement([min, max ?? min])); } @@ -559,10 +578,11 @@ export class MysteryEncounterBuilder implements Partial { * * @param min min wave (or exact size if only min is given) * @param max optional max size. If not given, defaults to min => exact wave + * @param excludeFainted - if true, only counts unfainted mons * @returns */ - withScenePartySizeRequirement(min: number, max?: number) { - return this.withSceneRequirement(new PartySizeRequirement([min, max ?? min])); + withScenePartySizeRequirement(min: number, max?: number, excludeFainted?: boolean): this & Required> { + return this.withSceneRequirement(new PartySizeRequirement([min, max ?? min], excludeFainted)); } /** @@ -700,7 +720,7 @@ export class MysteryEncounterBuilder implements Partial { * @param title - title of the encounter * @returns */ - withTitle(title: string) { + withTitle(title: string): this { const encounterOptionsDialogue = this.dialogue.encounterOptionsDialogue ?? {}; this.dialogue = { @@ -720,7 +740,7 @@ export class MysteryEncounterBuilder implements Partial { * @param description - description of the encounter * @returns */ - withDescription(description: string) { + withDescription(description: string): this { const encounterOptionsDialogue = this.dialogue.encounterOptionsDialogue ?? {}; this.dialogue = { @@ -740,7 +760,7 @@ export class MysteryEncounterBuilder implements Partial { * @param query - query to use for the encounter * @returns */ - withQuery(query: string) { + withQuery(query: string): this { const encounterOptionsDialogue = this.dialogue.encounterOptionsDialogue ?? {}; this.dialogue = { @@ -760,7 +780,7 @@ export class MysteryEncounterBuilder implements Partial { * @param dialogue - outro dialogue/s * @returns */ - withOutroDialogue(dialogue: MysteryEncounterDialogue["outro"] = []) { + withOutroDialogue(dialogue: MysteryEncounterDialogue["outro"] = []): this { this.dialogue = {...this.dialogue, outro: dialogue }; return this; } @@ -768,10 +788,9 @@ export class MysteryEncounterBuilder implements Partial { /** * Builds the mystery encounter * - * @param this - MysteryEncounter * @returns */ - build(this: IMysteryEncounter) { + build(this: IMysteryEncounter): IMysteryEncounter { return new IMysteryEncounter(this); } } diff --git a/src/data/mystery-encounters/mystery-encounters.ts b/src/data/mystery-encounters/mystery-encounters.ts index 7679ab20d58..9c26f54a128 100644 --- a/src/data/mystery-encounters/mystery-encounters.ts +++ b/src/data/mystery-encounters/mystery-encounters.ts @@ -14,10 +14,11 @@ import IMysteryEncounter from "./mystery-encounter"; import { SafariZoneEncounter } from "#app/data/mystery-encounters/encounters/safari-zone-encounter"; import { FieryFalloutEncounter } from "#app/data/mystery-encounters/encounters/fiery-fallout-encounter"; import { TheStrongStuffEncounter } from "#app/data/mystery-encounters/encounters/the-strong-stuff-encounter"; +import { PokemonSalesmanEncounter } from "#app/data/mystery-encounters/encounters/pokemon-salesman-encounter"; // Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * ) / 256 export const BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT = 1; -export const WIGHT_INCREMENT_ON_SPAWN_MISS = 5; +export const WEIGHT_INCREMENT_ON_SPAWN_MISS = 5; export const AVERAGE_ENCOUNTERS_PER_RUN_TARGET = 15; export const EXTREME_ENCOUNTER_BIOMES = [ @@ -132,14 +133,14 @@ const nonExtremeBiomeEncounters: MysteryEncounterType[] = [ const humanTransitableBiomeEncounters: MysteryEncounterType[] = [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS, - MysteryEncounterType.SHADY_VITAMIN_DEALER + MysteryEncounterType.SHADY_VITAMIN_DEALER, + MysteryEncounterType.POKEMON_SALESMAN ]; const civilizationBiomeEncounters: MysteryEncounterType[] = [ MysteryEncounterType.DEPARTMENT_STORE_SALE ]; - /** * To add an encounter to every biome possible, use this array */ @@ -225,6 +226,7 @@ export function initMysteryEncounters() { allMysteryEncounters[MysteryEncounterType.LOST_AT_SEA] = LostAtSeaEncounter; allMysteryEncounters[MysteryEncounterType.FIERY_FALLOUT] = FieryFalloutEncounter; allMysteryEncounters[MysteryEncounterType.THE_STRONG_STUFF] = TheStrongStuffEncounter; + allMysteryEncounters[MysteryEncounterType.POKEMON_SALESMAN] = PokemonSalesmanEncounter; // Add extreme encounters to biome map extremeBiomeEncounters.forEach(encounter => { diff --git a/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts b/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts index 1042984533d..382b2c7dde8 100644 --- a/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-dialogue-utils.ts @@ -63,10 +63,12 @@ export function showEncounterText(scene: BattleScene, contentKey: string, callba * @param scene * @param textContentKey * @param speakerContentKey - * @param callback + * @param callbackDelay */ -export function showEncounterDialogue(scene: BattleScene, textContentKey: string, speakerContentKey: string, callback?: Function) { - const text: string = getEncounterText(scene, textContentKey); - const speaker: string = getEncounterText(scene, speakerContentKey); - scene.ui.showDialogue(text, speaker, null, callback, 0, 0); +export function showEncounterDialogue(scene: BattleScene, textContentKey: string, speakerContentKey: string, callbackDelay: number = 0): Promise { + return new Promise(resolve => { + const text: string = getEncounterText(scene, textContentKey); + const speaker: string = getEncounterText(scene, speakerContentKey); + scene.ui.showDialogue(text, speaker, null, () => resolve(), callbackDelay); + }); } diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index 40763358b89..9178747500f 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -1,7 +1,7 @@ import { BattlerIndex, BattleType } from "#app/battle"; import { biomeLinks } from "#app/data/biomes"; import MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option"; -import { WIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters"; +import { WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters"; import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import Pokemon, { FieldPosition, PlayerPokemon, PokemonMove } from "#app/field/pokemon"; import { ExpBalanceModifier, ExpShareModifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier } from "#app/modifier/modifier"; @@ -316,18 +316,21 @@ export function initCustomMovesForEncounter(scene: BattleScene, moves: Moves | M * @param scene - Battle Scene * @param changeValue * @param playSound + * @param showMessage */ -export function updatePlayerMoney(scene: BattleScene, changeValue: number, playSound: boolean = true) { - scene.money += changeValue; +export function updatePlayerMoney(scene: BattleScene, changeValue: number, playSound: boolean = true, showMessage: boolean = true) { + scene.money = Math.min(Math.max(scene.money + changeValue, 0), Number.MAX_SAFE_INTEGER); scene.updateMoneyText(); scene.animateMoneyChanged(false); if (playSound) { scene.playSound("buy"); } - if (changeValue < 0) { - scene.queueMessage(i18next.t("mysteryEncounter:paid_money", { amount: -changeValue }), null, true); - } else { - scene.queueMessage(i18next.t("mysteryEncounter:receive_money", { amount: changeValue }), null, true); + if (showMessage) { + if (changeValue < 0) { + scene.queueMessage(i18next.t("mysteryEncounter:paid_money", { amount: -changeValue }), null, true); + } else { + scene.queueMessage(i18next.t("mysteryEncounter:receive_money", { amount: changeValue }), null, true); + } } } @@ -399,6 +402,7 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p }).concat({ label: i18next.t("menu:cancel"), handler: () => { + scene.ui.clearText(); scene.ui.setMode(Mode.MYSTERY_ENCOUNTER); resolve(false); return true; @@ -730,12 +734,18 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n const numRuns = 1000; let run = 0; const targetEncountersPerRun = 15; // AVERAGE_ENCOUNTERS_PER_RUN_TARGET + const biomes = Object.keys(Biome).filter(key => isNaN(Number(key))); + const alwaysPickTheseBiomes = [Biome.ISLAND, Biome.ABYSS, Biome.WASTELAND, Biome.FAIRY_CAVE, Biome.TEMPLE, Biome.LABORATORY, Biome.SPACE, Biome.WASTELAND]; - const calculateNumEncounters = (): number[] => { + const calculateNumEncounters = (): any[] => { let encounterRate = baseSpawnWeight; // BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT const numEncounters = [0, 0, 0, 0]; + const encountersByBiome = new Map(biomes.map(b => [b, 0])); + const validMEfloorsByBiome = new Map(biomes.map(b => [b, 0])); let currentBiome = Biome.TOWN; let currentArena = scene.newArena(currentBiome); + scene.setSeed(Utils.randomString(24)); + scene.resetSeed(); for (let i = 10; i < 180; i++) { // Boss if (i % 10 === 0) { @@ -748,10 +758,17 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n let biomes: Biome[]; scene.executeWithSeedOffset(() => { biomes = (biomeLinks[currentBiome] as (Biome | [Biome, integer])[]) - .filter(b => !Array.isArray(b) || !Utils.randSeedInt(b[1])) + .filter(b => { + return !Array.isArray(b) || !Utils.randSeedInt(b[1]); + }) .map(b => !Array.isArray(b) ? b : b[0]); - }, i); - currentBiome = biomes[Utils.randSeedInt(biomes.length)]; + }, i * 100); + const specialBiomes = biomes.filter(b => alwaysPickTheseBiomes.includes(b)); + if (specialBiomes.length > 0) { + currentBiome = specialBiomes[Utils.randSeedInt(specialBiomes.length)]; + } else { + currentBiome = biomes[Utils.randSeedInt(biomes.length)]; + } } else if (biomeLinks.hasOwnProperty(currentBiome)) { currentBiome = (biomeLinks[currentBiome] as Biome); } else { @@ -778,6 +795,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n // Otherwise, roll encounter const roll = Utils.randSeedInt(256); + validMEfloorsByBiome.set(Biome[currentBiome], validMEfloorsByBiome.get(Biome[currentBiome]) + 1); // If total number of encounters is lower than expected for the run, slightly favor a new encounter // Do the reverse as well @@ -803,31 +821,63 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n const rareThreshold = totalWeight - tierWeights[0] - tierWeights[1] - tierWeights[2]; // 64 - 32 - 16 - 10 = 6 tierValue > commonThreshold ? ++numEncounters[0] : tierValue > uncommonThreshold ? ++numEncounters[1] : tierValue > rareThreshold ? ++numEncounters[2] : ++numEncounters[3]; + encountersByBiome.set(Biome[currentBiome], encountersByBiome.get(Biome[currentBiome]) + 1); } else { - encounterRate += WIGHT_INCREMENT_ON_SPAWN_MISS; + encounterRate += WEIGHT_INCREMENT_ON_SPAWN_MISS; } } - return numEncounters; + return [numEncounters, encountersByBiome, validMEfloorsByBiome]; }; - const runs = []; + const encounterRuns: number[][] = []; + const encountersByBiomeRuns: Map[] = []; + const validFloorsByBiome: Map[] = []; while (run < numRuns) { scene.executeWithSeedOffset(() => { - const numEncounters = calculateNumEncounters(); - runs.push(numEncounters); + const [numEncounters, encountersByBiome, validMEfloorsByBiome] = calculateNumEncounters(); + encounterRuns.push(numEncounters); + encountersByBiomeRuns.push(encountersByBiome); + validFloorsByBiome.push(validMEfloorsByBiome); }, 1000 * run); run++; } - const n = runs.length; - const totalEncountersInRun = runs.map(run => run.reduce((a, b) => a + b)); + const n = encounterRuns.length; + const totalEncountersInRun = encounterRuns.map(run => run.reduce((a, b) => a + b)); const totalMean = totalEncountersInRun.reduce((a, b) => a + b) / n; const totalStd = Math.sqrt(totalEncountersInRun.map(x => Math.pow(x - totalMean, 2)).reduce((a, b) => a + b) / n); - const commonMean = runs.reduce((a, b) => a + b[0], 0) / n; - const uncommonMean = runs.reduce((a, b) => a + b[1], 0) / n; - const rareMean = runs.reduce((a, b) => a + b[2], 0) / n; - const superRareMean = runs.reduce((a, b) => a + b[3], 0) / n; + const commonMean = encounterRuns.reduce((a, b) => a + b[0], 0) / n; + const uncommonMean = encounterRuns.reduce((a, b) => a + b[1], 0) / n; + const rareMean = encounterRuns.reduce((a, b) => a + b[2], 0) / n; + const superRareMean = encounterRuns.reduce((a, b) => a + b[3], 0) / n; - console.log(`Starting weight: ${baseSpawnWeight}\nAverage MEs per run: ${totalMean}\nStandard Deviation: ${totalStd}\nAvg Commons: ${commonMean}\nAvg Uncommons: ${uncommonMean}\nAvg Rares: ${rareMean}\nAvg Super Rares: ${superRareMean}`); + const encountersPerRunPerBiome = encountersByBiomeRuns.reduce((a, b) => { + for (const biome of a.keys()) { + a.set(biome, a.get(biome) + b.get(biome)); + } + return a; + }); + const meanEncountersPerRunPerBiome: Map = new Map(); + encountersPerRunPerBiome.forEach((value, key) => { + meanEncountersPerRunPerBiome.set(key, value / n); + }); + + const validMEFloorsPerRunPerBiome = validFloorsByBiome.reduce((a, b) => { + for (const biome of a.keys()) { + a.set(biome, a.get(biome) + b.get(biome)); + } + return a; + }); + const meanMEFloorsPerRunPerBiome: Map = new Map(); + validMEFloorsPerRunPerBiome.forEach((value, key) => { + meanMEFloorsPerRunPerBiome.set(key, value / n); + }); + + let stats = `Starting weight: ${baseSpawnWeight}\nAverage MEs per run: ${totalMean}\nStandard Deviation: ${totalStd}\nAvg Commons: ${commonMean}\nAvg Greats: ${uncommonMean}\nAvg Ultras: ${rareMean}\nAvg Rogues: ${superRareMean}\n`; + + const meanEncountersPerRunPerBiomeSorted = [...meanEncountersPerRunPerBiome.entries()].sort((e1, e2) => e2[1] - e1[1]); + meanEncountersPerRunPerBiomeSorted.forEach(value => stats = stats + `${value[0]}: avg valid floors ${meanMEFloorsPerRunPerBiome.get(value[0])}, avg MEs ${value[1]},\n`); + + console.log(stats); } diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index 2dbbe9f55a1..43e25793f86 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -17,6 +17,7 @@ import { Type } from "#app/data/type"; import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species"; import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { getPokemonNameWithAffix } from "#app/messages"; +import { modifierTypes } from "#app/modifier/modifier-type"; export interface MysteryEncounterPokemonData { spriteScale?: number @@ -204,13 +205,11 @@ export function applyHealToPokemon(scene: BattleScene, pokemon: PlayerPokemon, h * @param pokemon * @param value */ -export function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: number) { - pokemon.getSpeciesForm().baseStats = [...pokemon.getSpeciesForm().baseStats].map(v => { - const newVal = Math.floor(v + value); - return Math.max(newVal, 1); - }); +export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: number) { + const modType = modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE().generateType(null, [value]); + const modifier = modType.newModifier(pokemon); + await pokemon.scene.addModifier(modifier, false, false, false, true); pokemon.calculateStats(); - pokemon.updateInfo(); } /** @@ -387,7 +386,7 @@ function failCatch(scene: BattleScene, pokemon: EnemyPokemon, originalY: number, }); } -function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, pokeball: Phaser.GameObjects.Sprite, pokeballType: PokeballType): Promise { +export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, pokeball: Phaser.GameObjects.Sprite, pokeballType: PokeballType, isObtain: boolean = false): Promise { scene.unshiftPhase(new VictoryPhase(scene, BattlerIndex.ENEMY)); const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm(); @@ -413,14 +412,16 @@ function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, pokeball: Phase scene.gameData.updateSpeciesDexIvs(pokemon.species.getRootSpeciesId(true), pokemon.ivs); return new Promise(resolve => { - scene.ui.showText(i18next.t("battle:pokemonCaught", { pokemonName: pokemon.name }), null, () => { + scene.ui.showText(i18next.t(isObtain ? "battle:pokemonObtained" : "battle:pokemonCaught", { pokemonName: pokemon.name }), null, () => { const end = () => { scene.pokemonInfoContainer.hide(); removePb(scene, pokeball); resolve(); }; const removePokemon = () => { - scene.field.remove(pokemon, true); + if (pokemon) { + scene.field.remove(pokemon, true); + } }; const addToParty = () => { const newPokemon = pokemon.addToParty(pokeballType); @@ -471,14 +472,18 @@ function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, pokeball: Phase } function removePb(scene: BattleScene, pokeball: Phaser.GameObjects.Sprite) { - scene.tweens.add({ - targets: pokeball, - duration: 250, - delay: 250, - ease: "Sine.easeIn", - alpha: 0, - onComplete: () => pokeball.destroy() - }); + if (pokeball) { + scene.tweens.add({ + targets: pokeball, + duration: 250, + delay: 250, + ease: "Sine.easeIn", + alpha: 0, + onComplete: () => { + pokeball.destroy(); + } + }); + } } export async function doPokemonFlee(scene: BattleScene, pokemon: EnemyPokemon): Promise { diff --git a/src/enums/mystery-encounter-type.ts b/src/enums/mystery-encounter-type.ts index d4d0b479f9c..f13f246bac0 100644 --- a/src/enums/mystery-encounter-type.ts +++ b/src/enums/mystery-encounter-type.ts @@ -11,5 +11,6 @@ export enum MysteryEncounterType { SAFARI_ZONE, LOST_AT_SEA, //might be generalized later on FIERY_FALLOUT, - THE_STRONG_STUFF + THE_STRONG_STUFF, + POKEMON_SALESMAN } diff --git a/src/field/mystery-encounter-intro.ts b/src/field/mystery-encounter-intro.ts index 84f6488c439..d97c267b095 100644 --- a/src/field/mystery-encounter-intro.ts +++ b/src/field/mystery-encounter-intro.ts @@ -17,6 +17,13 @@ type KnownFileRoot = | "mystery-encounters" | "pokeball" | "pokemon" + | "pokemon/back" + | "pokemon/exp" + | "pokemon/female" + | "pokemon/icons" + | "pokemon/input" + | "pokemon/shiny" + | "pokemon/variant" | "statuses" | "trainer" | "ui"; @@ -25,7 +32,7 @@ export class MysteryEncounterSpriteConfig { /** The sprite key (which is the image file name). e.g. "ace_trainer_f" */ spriteKey: string; /** Refer to [/public/images](../../public/images) directorty for all folder names */ - fileRoot: KnownFileRoot & string; + fileRoot: KnownFileRoot & string | string; /** Enable shadow. Defaults to `false` */ hasShadow?: boolean = false; /** Disable animation. Defaults to `false` */ @@ -44,6 +51,8 @@ export class MysteryEncounterSpriteConfig { yShadow?: number; /** Sprite scale. `0` - `n` */ scale?: number; + /** If you are using a Pokemon sprite, set to `true`. This will ensure variant, form, gender, shiny sprites are loaded properly */ + isPokemon?: boolean; /** If you are using an item sprite, set to `true` */ isItem?: boolean; /** The sprites alpha. `0` - `1` The lower the number, the more transparent */ @@ -155,13 +164,18 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con } this.spriteConfigs.forEach((config) => { - if (!config.isItem) { - this.scene.loadAtlas(config.spriteKey, config.fileRoot); - } else { + if (config.isPokemon) { + this.scene.loadPokemonAtlas(config.spriteKey, config.fileRoot); + } else if (config.isItem) { this.scene.loadAtlas("items", ""); + } else { + this.scene.loadAtlas(config.spriteKey, config.fileRoot); } }); + // Load dex progress icon + this.scene.loadAtlas("encounter_radar", "mystery-encounters"); + this.scene.load.once(Phaser.Loader.Events.COMPLETE, () => { this.spriteConfigs.every((config) => { if (config.isItem) { diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8b2e65e4abb..a234719bf69 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -10,7 +10,7 @@ import * as Utils from "../utils"; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type"; import { getLevelTotalExp } from "../data/exp"; import { Stat } from "../data/pokemon-stat"; -import { AttackTypeBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonMultiHitModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempBattleStatBoosterModifier, StatBoosterModifier, TerastallizeModifier } from "../modifier/modifier"; +import { AttackTypeBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonMultiHitModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempBattleStatBoosterModifier, StatBoosterModifier, TerastallizeModifier, PokemonBaseStatTotalModifier } from "../modifier/modifier"; import { PokeballType } from "../data/pokeball"; import { Gender } from "../data/gender"; import { initMoveAnim, loadMoveAnimAssets } from "../data/battle-anims"; @@ -731,6 +731,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.stats = [ 0, 0, 0, 0, 0, 0 ]; } const baseStats = this.getSpeciesForm().baseStats.slice(0); + this.scene.applyModifiers(PokemonBaseStatTotalModifier, this.isPlayer(), this, baseStats); if (this.fusionSpecies) { const fusionBaseStats = this.getFusionSpeciesForm().baseStats; for (let s = 0; s < this.stats.length; s++) { diff --git a/src/locales/en/battle.ts b/src/locales/en/battle.ts index 6deaf4496a0..d4dfb9ba525 100644 --- a/src/locales/en/battle.ts +++ b/src/locales/en/battle.ts @@ -16,6 +16,7 @@ export const battle: SimpleTranslationEntries = { "moneyWon": "You got\n₽{{moneyAmount}} for winning!", "moneyPickedUp": "You picked up ₽{{moneyAmount}}!", "pokemonCaught": "{{pokemonName}} was caught!", + "pokemonObtained": "You got {{pokemonName}}!", "pokemonBrokeFree": "Oh no!\nThe Pokémon broke free!", "pokemonFled": "The wild {{pokemonName}} fled!", "playerFled": "You fled from the {{pokemonName}}!", diff --git a/src/locales/en/modifier-type.ts b/src/locales/en/modifier-type.ts index 7bbf89388c4..7f8ca139e77 100644 --- a/src/locales/en/modifier-type.ts +++ b/src/locales/en/modifier-type.ts @@ -66,6 +66,16 @@ export const modifierType: ModifierTypeTranslationEntries = { "PokemonBaseStatBoosterModifierType": { description: "Increases the holder's base {{statName}} by 10%. The higher your IVs, the higher the stack limit.", }, + "PokemonBaseStatTotalModifierType": { + name: "Shuckle Juice", + description: "{{increaseDecrease}} all of the holder's base stats by {{statValue}}. You were {{blessCurse}} by the Shuckle.", + extra: { + "increase": "Increases", + "decrease": "Decreases", + "blessed": "blessed", + "cursed": "cursed" + }, + }, "AllPokemonFullHpRestoreModifierType": { description: "Restores 100% HP for all Pokémon.", }, @@ -240,6 +250,8 @@ export const modifierType: ModifierTypeTranslationEntries = { "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { name: "Full Heal Token", description: "Adds a 2.5% chance every turn to heal a status condition." }, "ENEMY_ENDURE_CHANCE": { name: "Endure Token" }, "ENEMY_FUSED_CHANCE": { name: "Fusion Token", description: "Adds a 1% chance that a wild Pokémon will be a fusion." }, + + "MYSTERY_ENCOUNTER_SHUCKLE_JUICE": { name: "Shuckle Juice" }, }, SpeciesBoosterItem: { "LIGHT_BALL": { name: "Light Ball", description: "It's a mysterious orb that boosts Pikachu's Attack and Sp. Atk stats." }, diff --git a/src/locales/en/mystery-encounter.ts b/src/locales/en/mystery-encounter.ts index 891d6dc299b..f58f18dd65a 100644 --- a/src/locales/en/mystery-encounter.ts +++ b/src/locales/en/mystery-encounter.ts @@ -11,6 +11,7 @@ import { shadyVitaminDealerDialogue } from "#app/locales/en/mystery-encounters/s import { slumberingSnorlaxDialogue } from "#app/locales/en/mystery-encounters/slumbering-snorlax-dialogue"; import { trainingSessionDialogue } from "#app/locales/en/mystery-encounters/training-session-dialogue"; import { theStrongStuffDialogue } from "#app/locales/en/mystery-encounters/the-strong-stuff-dialogue"; +import { pokemonSalesmanDialogue } from "#app/locales/en/mystery-encounters/pokemon-salesman-dialogue"; /** * Patterns that can be used: @@ -32,6 +33,7 @@ export const mysteryEncounter = { // General use content "paid_money": "You paid ₽{{amount, number}}.", "receive_money": "You received ₽{{amount, number}}!", + "affects_pokedex": "Affects Pokédex Data", mysteriousChallengers: mysteriousChallengersDialogue, mysteriousChest: mysteriousChestDialogue, @@ -46,4 +48,5 @@ export const mysteryEncounter = { lostAtSea: lostAtSeaDialogue, fieryFallout: fieryFalloutDialogue, theStrongStuff: theStrongStuffDialogue, + pokemonSalesman: pokemonSalesmanDialogue } as const; diff --git a/src/locales/en/mystery-encounters/fight-or-flight-dialogue.ts b/src/locales/en/mystery-encounters/fight-or-flight-dialogue.ts index 2ef9d31a821..a7b8b03aab5 100644 --- a/src/locales/en/mystery-encounters/fight-or-flight-dialogue.ts +++ b/src/locales/en/mystery-encounters/fight-or-flight-dialogue.ts @@ -10,7 +10,7 @@ export const fightOrFlightDialogue = { selected: "You approach the\nPokémon without fear.", }, 2: { - label: "{{option2PrimaryName}} can help", + label: "Steal the item", tooltip: "@[SUMMARY_GREEN]{(35%) Steal Item}\n@[SUMMARY_BLUE]{(65%) Harder Battle}", tooltip_special: "(+) {{option2PrimaryName}} uses {{option2PrimaryMove}}", good_result: `.@d{32}.@d{32}.@d{32} diff --git a/src/locales/en/mystery-encounters/pokemon-salesman-dialogue.ts b/src/locales/en/mystery-encounters/pokemon-salesman-dialogue.ts new file mode 100644 index 00000000000..d35e3947a42 --- /dev/null +++ b/src/locales/en/mystery-encounters/pokemon-salesman-dialogue.ts @@ -0,0 +1,26 @@ +export const pokemonSalesmanDialogue = { + intro: "A chipper elderly man approaches you.", + speaker: "Gentleman", + intro_dialogue: "Hello there! Have I got a deal just for YOU!", + title: "The Pokémon Salesman", + description: "\"This {{purchasePokemon}} is extremely unique and carries an ability not normally found in its species! I'll let you have this swell {{purchasePokemon}} for just {{price, money}}!\"\n\n\"What do you say?\"", + description_shiny: "\"This {{purchasePokemon}} is extremely unique and has a pigment not normally found in its species! I'll let you have this swell {{purchasePokemon}} for just {{price, money}}!\"\n\n\"What do you say?\"", + query: "What will you do?", + option: { + 1: { + label: "Accept", + tooltip: "(-) Pay {{price, money}}\n(+) Gain a {{purchasePokemon}} with its Hidden Ability", + tooltip_shiny: "(-) Pay {{price, money}}\n(+) Gain a shiny {{purchasePokemon}}", + selected_message: "You paid an outrageous sum and bought the {{purchasePokemon}}.", + selected_dialogue: `Excellent choice! + $I can see you've a keen eye for business. + $Oh, yeah...@d{64} Returns not accepted, got that?`, + }, + 2: { + label: "Refuse", + tooltip: "(-) No Rewards", + selected: `No?@d{32} You say no? + $I'm only doing this as a favor to you!`, + }, + }, +}; diff --git a/src/locales/en/mystery-encounters/training-session-dialogue.ts b/src/locales/en/mystery-encounters/training-session-dialogue.ts index 12e84dd8d0d..66e9d7c9498 100644 --- a/src/locales/en/mystery-encounters/training-session-dialogue.ts +++ b/src/locales/en/mystery-encounters/training-session-dialogue.ts @@ -3,6 +3,7 @@ export const trainingSessionDialogue = { title: "Training Session", description: "These supplies look like they could be used to train a member of your party! There are a few ways you could train your Pokémon, by battling against it with the rest of your team.", query: "How should you train?", + invalid_selection: "Pokémon must be healthy enough.", option: { 1: { label: "Light Training", @@ -19,7 +20,7 @@ export const trainingSessionDialogue = { }, 3: { label: "Heavy Training", - tooltip: "(-) Each of your Pokémon lose {{damagePercentage}}% of their total HP", + tooltip: "(-) Harsh Battle\n(+) Change Pokémon's Ability", select_prompt: "Select a new ability\nto train your Pokémon in.", finished: `{{selectedPokemon}} returns, feeling\nworn out but accomplished! $Its ability was changed to {{ability}}!`, diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 250b2953fdf..ae5b1ba0ee8 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -621,6 +621,27 @@ export class PokemonBaseStatBoosterModifierType extends PokemonHeldItemModifierT } } +export class PokemonBaseStatTotalModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType { + private readonly statModifier: integer; + + constructor(statModifier: integer) { + super("modifierType:ModifierType.MYSTERY_ENCOUNTER_SHUCKLE_JUICE", "berry_juice", (_type, args) => new Modifiers.PokemonBaseStatTotalModifier(this, (args[0] as Pokemon).id, this.statModifier)); + this.statModifier = statModifier; + } + + getDescription(scene: BattleScene): string { + return i18next.t("modifierType:ModifierType.PokemonBaseStatTotalModifierType.description", { + increaseDecrease: i18next.t(this.statModifier >= 0 ? "modifierType:ModifierType.PokemonBaseStatTotalModifierType.extra.increase" : "modifierType:ModifierType.PokemonBaseStatTotalModifierType.extra.decrease"), + blessCurse: i18next.t(this.statModifier >= 0 ? "modifierType:ModifierType.PokemonBaseStatTotalModifierType.extra.blessed" : "modifierType:ModifierType.PokemonBaseStatTotalModifierType.extra.cursed"), + statValue: this.statModifier, + }); + } + + getPregenArgs(): any[] { + return [ this.statModifier ]; + } +} + class AllPokemonFullHpRestoreModifierType extends ModifierType { private descriptionKey: string; @@ -1354,6 +1375,13 @@ export const modifierTypes = { ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new Modifiers.EnemyStatusEffectHealChanceModifier(type, 2.5, 10)), ENEMY_ENDURE_CHANCE: () => new EnemyEndureChanceModifierType("modifierType:ModifierType.ENEMY_ENDURE_CHANCE", "wl_reset_urge", 2), ENEMY_FUSED_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_FUSED_CHANCE", "wl_custom_spliced", (type, _args) => new Modifiers.EnemyFusionChanceModifier(type, 1)), + + MYSTERY_ENCOUNTER_SHUCKLE_JUICE: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { + if (pregenArgs) { + return new PokemonBaseStatTotalModifierType(pregenArgs[0] as integer); + } + return new PokemonBaseStatTotalModifierType(Utils.randSeedInt(20)); + }), }; interface ModifierPool { diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 6f098ade124..72aaf6cbb41 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -708,6 +708,55 @@ export class PokemonBaseStatModifier extends PokemonHeldItemModifier { } } +export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { + private statModifier: integer; + + constructor(type: ModifierTypes.PokemonBaseStatTotalModifierType, pokemonId: integer, statModifier: integer, stackCount?: integer) { + super(type, pokemonId, stackCount); + this.statModifier = statModifier; + } + + matchType(modifier: Modifier): boolean { + if (modifier instanceof PokemonBaseStatTotalModifier) { + return (modifier as PokemonBaseStatTotalModifier).statModifier === this.statModifier; + } + return false; + } + + clone(): PersistentModifier { + return new PokemonBaseStatTotalModifier(this.type as ModifierTypes.PokemonBaseStatTotalModifierType, this.pokemonId, this.statModifier, this.stackCount); + } + + getArgs(): any[] { + return super.getArgs().concat(this.statModifier); + } + + shouldApply(args: any[]): boolean { + return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array; + } + + apply(args: any[]): boolean { + args[1].forEach((v, i) => { + const newVal = Math.floor(v + this.statModifier); + args[1][i] = Math.min(Math.max(newVal, 1), 999999); + }); + + return true; + } + + getTransferrable(_withinParty: boolean): boolean { + return false; + } + + getScoreMultiplier(): number { + return 1.2; + } + + getMaxHeldItemCount(pokemon: Pokemon): integer { + return 2; + } +} + /** * Modifier used for held items that apply {@linkcode Stat} boost(s) * using a multiplier. diff --git a/src/test/mystery-encounter/encounters/pokemon-salesman-encounter.test.ts b/src/test/mystery-encounter/encounters/pokemon-salesman-encounter.test.ts new file mode 100644 index 00000000000..c3045b599eb --- /dev/null +++ b/src/test/mystery-encounter/encounters/pokemon-salesman-encounter.test.ts @@ -0,0 +1,171 @@ +import * as MysteryEncounters from "#app/data/mystery-encounters/mystery-encounters"; +import { Biome } from "#app/enums/biome"; +import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; +import { Species } from "#app/enums/species"; +import GameManager from "#app/test/utils/gameManager"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import Battle from "#app/battle"; +import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { EncounterOptionMode } from "#app/data/mystery-encounters/mystery-encounter-option"; +import { runSelectMysteryEncounterOption } from "#test/mystery-encounter/encounterTestUtils"; +import BattleScene from "#app/battle-scene"; +import { MysteryEncounterTier } from "#app/data/mystery-encounters/mystery-encounter"; +import { PlayerPokemon } from "#app/field/pokemon"; +import { HUMAN_TRANSITABLE_BIOMES } from "#app/data/mystery-encounters/mystery-encounters"; +import { PokemonSalesmanEncounter } from "#app/data/mystery-encounters/encounters/pokemon-salesman-encounter"; + +const namespace = "mysteryEncounter:pokemonSalesman"; +const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultBiome = Biome.CAVE; +const defaultWave = 45; + +describe("The Pokemon Salesman - Mystery Encounter", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + let scene: BattleScene; + + beforeAll(() => { + phaserGame = new Phaser.Game({ type: Phaser.HEADLESS }); + }); + + beforeEach(async () => { + game = new GameManager(phaserGame); + scene = game.scene; + game.override.mysteryEncounterChance(100); + game.override.mysteryEncounterTier(MysteryEncounterTier.COMMON); + game.override.startingWave(defaultWave); + game.override.startingBiome(defaultBiome); + + const biomeMap = new Map([ + [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + ]); + HUMAN_TRANSITABLE_BIOMES.forEach(biome => { + biomeMap.set(biome, [MysteryEncounterType.POKEMON_SALESMAN]); + }); + vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + vi.clearAllMocks(); + vi.resetAllMocks(); + }); + + it("should have the correct properties", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + + expect(PokemonSalesmanEncounter.encounterType).toBe(MysteryEncounterType.POKEMON_SALESMAN); + expect(PokemonSalesmanEncounter.encounterTier).toBe(MysteryEncounterTier.ULTRA); + expect(PokemonSalesmanEncounter.dialogue).toBeDefined(); + expect(PokemonSalesmanEncounter.dialogue.intro).toStrictEqual([ + { text: `${namespace}:intro` }, + { speaker: "mysteryEncounter:pokemonSalesman:speaker", text: "mysteryEncounter:pokemonSalesman:intro_dialogue" } + ]); + expect(PokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`); + expect(PokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}:description`); + expect(PokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}:query`); + expect(PokemonSalesmanEncounter.options.length).toBe(2); + }); + + it("should not spawn outside of HUMAN_TRANSITABLE_BIOMES", async () => { + game.override.startingBiome(Biome.VOLCANO); + await game.runToMysteryEncounter(); + + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.POKEMON_SALESMAN); + }); + + it("should not run below wave 10", async () => { + game.override.startingWave(9); + + await game.runToMysteryEncounter(); + + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.POKEMON_SALESMAN); + }); + + it("should not run above wave 179", async () => { + game.override.startingWave(181); + + await game.runToMysteryEncounter(); + + expect(scene.currentBattle.mysteryEncounter).toBeUndefined(); + }); + + it("should initialize fully ", async () => { + vi.spyOn(scene, "currentBattle", "get").mockReturnValue({ mysteryEncounter: PokemonSalesmanEncounter } as Battle); + + const { onInit } = PokemonSalesmanEncounter; + + expect(PokemonSalesmanEncounter.onInit).toBeDefined(); + + const onInitResult = onInit(scene); + + expect(PokemonSalesmanEncounter.dialogueTokens?.purchasePokemon).toBeDefined(); + expect(PokemonSalesmanEncounter.dialogueTokens?.price).toBeDefined(); + expect(PokemonSalesmanEncounter.misc.pokemon instanceof PlayerPokemon).toBeTruthy(); + expect(PokemonSalesmanEncounter.misc?.price?.toString()).toBe(PokemonSalesmanEncounter.dialogueTokens?.price); + expect(onInitResult).toBe(true); + }); + + describe("Option 1 - Purchase the pokemon", () => { + it("should have the correct properties", () => { + const option1 = PokemonSalesmanEncounter.options[0]; + expect(option1.optionMode).toBe(EncounterOptionMode.DEFAULT_OR_SPECIAL); + expect(option1.dialogue).toBeDefined(); + expect(option1.dialogue).toStrictEqual({ + buttonLabel: `${namespace}:option:1:label`, + buttonTooltip: `${namespace}:option:1:tooltip`, + selected: [ + { + text: `${namespace}:option:1:selected_message`, + }, + ], + }); + }); + + it("Should update the player's money properly", async () => { + const initialMoney = 20000; + scene.money = initialMoney; + const updateMoneySpy = vi.spyOn(EncounterPhaseUtils, "updatePlayerMoney"); + + await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + await runSelectMysteryEncounterOption(game, 1); + + const price = scene.currentBattle.mysteryEncounter.misc.price; + + expect(updateMoneySpy).toHaveBeenCalledWith(scene, -price, true, false); + expect(scene.money).toBe(initialMoney - price); + }); + + it("Should add the Pokemon to the party", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + + const initialPartySize = scene.getParty().length; + const pokemonName = scene.currentBattle.mysteryEncounter.misc.pokemon.name; + + await runSelectMysteryEncounterOption(game, 1); + + expect(scene.getParty().length).toBe(initialPartySize + 1); + expect(scene.getParty().find(p => p.name === pokemonName) instanceof PlayerPokemon).toBeTruthy(); + }); + + it("should leave encounter without battle", async () => { + const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); + + await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + await runSelectMysteryEncounterOption(game, 1); + + expect(leaveEncounterWithoutBattleSpy).toBeCalled(); + }); + }); + + describe("Option 2 - Leave", () => { + it("should leave encounter without battle", async () => { + const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); + + await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + await runSelectMysteryEncounterOption(game, 2); + + expect(leaveEncounterWithoutBattleSpy).toBeCalled(); + }); + }); +}); diff --git a/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts b/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts index ed15380b8c9..b57683d3165 100644 --- a/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts @@ -22,6 +22,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { PokemonMove } from "#app/field/pokemon"; import { Mode } from "#app/ui/ui"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; +import { PokemonBaseStatTotalModifier } from "#app/modifier/modifier"; const namespace = "mysteryEncounter:theStrongStuff"; const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; @@ -153,7 +154,9 @@ describe("The Strong Stuff - Mystery Encounter", () => { await runSelectMysteryEncounterOption(game, 1); const bstsAfter = scene.getParty().map(p => { - return p.getSpeciesForm().getBaseStatTotal(); + const baseStats = p.getSpeciesForm().baseStats.slice(0); + scene.applyModifiers(PokemonBaseStatTotalModifier, true, p, baseStats); + return baseStats.reduce((a, b) => a + b); }); expect(bstsAfter[0]).toEqual(bstsPrior[0] - 20 * 6); diff --git a/src/test/mystery-encounter/mystery-encounter-utils.test.ts b/src/test/mystery-encounter/mystery-encounter-utils.test.ts index cdc7eda180f..a336af41b6b 100644 --- a/src/test/mystery-encounter/mystery-encounter-utils.test.ts +++ b/src/test/mystery-encounter/mystery-encounter-utils.test.ts @@ -298,7 +298,7 @@ describe("Mystery Encounter Utils", () => { const spy = vi.spyOn(game.scene.ui, "showDialogue"); showEncounterDialogue(scene, "mysteryEncounter:unit_test_dialogue", "mysteryEncounter:unit_test_dialogue"); - expect(spy).toHaveBeenCalledWith("valuevalue {{testvalue}} {{test1}} {{test}} {{test\\}} {{test\\}} {test}}", "valuevalue {{testvalue}} {{test1}} {{test}} {{test\\}} {{test\\}} {test}}", null, undefined, 0, 0); + expect(spy).toHaveBeenCalledWith("valuevalue {{testvalue}} {{test1}} {{test}} {{test\\}} {{test\\}} {test}}", "valuevalue {{testvalue}} {{test1}} {{test}} {{test\\}} {{test\\}} {test}}", null, expect.any(Function), 0); }); }); diff --git a/src/test/utils/mocks/mocksContainer/mockText.ts b/src/test/utils/mocks/mocksContainer/mockText.ts index 2e6ed67f21f..2509c38b182 100644 --- a/src/test/utils/mocks/mocksContainer/mockText.ts +++ b/src/test/utils/mocks/mocksContainer/mockText.ts @@ -248,6 +248,14 @@ export default class MockText { }; } + disableInteractive() { + // Disables interaction with this Game Object. + } + + clearTint() { + // Clears tint on this Game Object. + } + add(obj) { // Adds a child to this Game Object. this.list.push(obj); diff --git a/src/ui/mystery-encounter-ui-handler.ts b/src/ui/mystery-encounter-ui-handler.ts index 72cce41d55f..e6bcbfd697c 100644 --- a/src/ui/mystery-encounter-ui-handler.ts +++ b/src/ui/mystery-encounter-ui-handler.ts @@ -13,6 +13,7 @@ import { getPokeballAtlasKey } from "../data/pokeball"; import { OptionSelectSettings } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { MysteryEncounterTier } from "#app/data/mystery-encounters/mystery-encounter"; +import i18next from "i18next"; export default class MysteryEncounterUiHandler extends UiHandler { private cursorContainer: Phaser.GameObjects.Container; @@ -29,6 +30,10 @@ export default class MysteryEncounterUiHandler extends UiHandler { private descriptionScrollTween: Phaser.Tweens.Tween; private rarityBall: Phaser.GameObjects.Sprite; + private dexProgressWindow: Phaser.GameObjects.NineSlice; + private dexProgressContainer: Phaser.GameObjects.Container; + private showDexProgress: boolean = false; + private overrideSettings: OptionSelectSettings; private encounterOptions: MysteryEncounterOption[] = []; private optionsMeetsReqs: boolean[]; @@ -50,6 +55,9 @@ export default class MysteryEncounterUiHandler extends UiHandler { this.optionsContainer = this.scene.add.container(12, -38.7); this.optionsContainer.setVisible(false); ui.add(this.optionsContainer); + this.dexProgressContainer = this.scene.add.container(214, -43); + this.dexProgressContainer.setVisible(false); + ui.add(this.dexProgressContainer); this.descriptionContainer = this.scene.add.container(0, -152); this.descriptionContainer.setVisible(false); ui.add(this.descriptionContainer); @@ -65,9 +73,23 @@ export default class MysteryEncounterUiHandler extends UiHandler { this.tooltipWindow = addWindow(this.scene, 0, 0, 110, 48, false, false, 0, 0, WindowVariant.THIN); this.tooltipContainer.add(this.tooltipWindow); + this.dexProgressWindow = addWindow(this.scene, 0, 0, 24, 28, false, false, 0, 0, WindowVariant.THIN); + this.dexProgressContainer.add(this.dexProgressWindow); + this.rarityBall = this.scene.add.sprite(141, 9, "pb"); this.rarityBall.setScale(0.75); this.descriptionContainer.add(this.rarityBall); + + const dexProgressIndicator = this.scene.add.sprite(12, 9, "encounter_radar"); + dexProgressIndicator.setScale(0.85); + this.dexProgressContainer.add(dexProgressIndicator); + this.dexProgressContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, 24, 28), Phaser.Geom.Rectangle.Contains); + this.dexProgressContainer.on("pointerover", () => { + (this.scene as BattleScene).ui.showTooltip(null, i18next.t("mysteryEncounter:affects_pokedex"), true); + }); + this.dexProgressContainer.on("pointerout", () => { + (this.scene as BattleScene).ui.hideTooltip(); + }); } show(args: any[]): boolean { @@ -81,6 +103,7 @@ export default class MysteryEncounterUiHandler extends UiHandler { this.cursorContainer.setVisible(true); this.descriptionContainer.setVisible(showDescriptionContainer); this.optionsContainer.setVisible(true); + this.dexProgressContainer.setVisible(true); this.displayEncounterOptions(slideInDescription); const cursor = this.getCursor(); if (cursor === (this?.optionsContainer?.length || 0) - 1) { @@ -317,7 +340,7 @@ export default class MysteryEncounterUiHandler extends UiHandler { const queryText: string = getEncounterText(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue.query, TextStyle.TOOLTIP_CONTENT); // Clear options container (except cursor) - this.optionsContainer.removeAll(); + this.optionsContainer.removeAll(true); // Options Window for (let i = 0; i < this.encounterOptions.length; i++) { @@ -437,6 +460,8 @@ export default class MysteryEncounterUiHandler extends UiHandler { if (isNullOrUndefined(cursor) || cursor > this.optionsContainer.length - 2) { // Ignore hovers on view party button + // Hide dex progress if visible + this.showHideDexProgress(false); return; } @@ -487,6 +512,13 @@ export default class MysteryEncounterUiHandler extends UiHandler { }); } } + + // Dex progress indicator + if (cursorOption.hasDexProgress && !this.showDexProgress) { + this.showHideDexProgress(true); + } else if (!cursorOption.hasDexProgress) { + this.showHideDexProgress(false); + } } clear(): void { @@ -494,6 +526,7 @@ export default class MysteryEncounterUiHandler extends UiHandler { this.overrideSettings = null; this.optionsContainer.setVisible(false); this.optionsContainer.removeAll(true); + this.dexProgressContainer.setVisible(false); this.descriptionContainer.setVisible(false); this.tooltipContainer.setVisible(false); // Keeps container background and pokeball @@ -508,4 +541,30 @@ export default class MysteryEncounterUiHandler extends UiHandler { } this.cursorObj = null; } + + /** + * + * @param show - if true does show, if false does hide + */ + showHideDexProgress(show: boolean) { + if (show && !this.showDexProgress) { + this.showDexProgress = true; + this.scene.tweens.killTweensOf(this.dexProgressContainer); + this.scene.tweens.add({ + targets: this.dexProgressContainer, + y: -63, + ease: "Sine.easeInOut", + duration: 750 + }); + } else if (!show && this.showDexProgress) { + this.showDexProgress = false; + this.scene.tweens.killTweensOf(this.dexProgressContainer); + this.scene.tweens.add({ + targets: this.dexProgressContainer, + y: -43, + ease: "Sine.easeInOut", + duration: 750, + }); + } + } }