diff --git a/public/audio/bgm/mystery_encounter_weird_dream.mp3 b/public/audio/bgm/mystery_encounter_weird_dream.mp3 new file mode 100644 index 00000000000..a630fe549db Binary files /dev/null and b/public/audio/bgm/mystery_encounter_weird_dream.mp3 differ diff --git a/public/images/items.json b/public/images/items.json index ae9bbf39302..01d28e79e58 100644 --- a/public/images/items.json +++ b/public/images/items.json @@ -4,8 +4,8 @@ "image": "items.png", "format": "RGBA8888", "size": { - "w": 425, - "h": 425 + "w": 426, + "h": 426 }, "scale": 1, "frames": [ @@ -555,6 +555,27 @@ "h": 28 } }, + { + "filename": "ability_capsule", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 9, + "w": 24, + "h": 14 + }, + "frame": { + "x": 0, + "y": 412, + "w": 24, + "h": 14 + } + }, { "filename": "ability_charm", "rotated": false, @@ -787,7 +808,7 @@ } }, { - "filename": "elixir", + "filename": "lock_capsule", "rotated": false, "trimmed": true, "sourceSize": { @@ -796,15 +817,15 @@ }, "spriteSourceSize": { "x": 7, - "y": 4, - "w": 18, - "h": 24 + "y": 5, + "w": 19, + "h": 22 }, "frame": { "x": 407, "y": 0, - "w": 18, - "h": 24 + "w": 19, + "h": 22 } }, { @@ -1081,7 +1102,7 @@ } }, { - "filename": "coupon", + "filename": "icy_reins_of_unity", "rotated": false, "trimmed": true, "sourceSize": { @@ -1091,56 +1112,14 @@ "spriteSourceSize": { "x": 4, "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 22, - "y": 406, - "w": 23, - "h": 19 - } - }, - { - "filename": "golden_mystic_ticket", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 45, - "y": 406, - "w": 23, - "h": 19 - } - }, - { - "filename": "ability_capsule", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 9, "w": 24, - "h": 14 + "h": 20 }, "frame": { - "x": 135, - "y": 22, + "x": 24, + "y": 406, "w": 24, - "h": 14 + "h": 20 } }, { @@ -1157,11 +1136,32 @@ "w": 24, "h": 18 }, + "frame": { + "x": 135, + "y": 22, + "w": 24, + "h": 18 + } + }, + { + "filename": "clefairy_doll", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, "frame": { "x": 29, "y": 55, "w": 24, - "h": 18 + "h": 23 } }, { @@ -1179,12 +1179,54 @@ "h": 24 }, "frame": { - "x": 59, - "y": 27, + "x": 39, + "y": 78, "w": 16, "h": 24 } }, + { + "filename": "carbos", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 39, + "y": 102, + "w": 16, + "h": 24 + } + }, + { + "filename": "catching_charm", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 21, + "h": 24 + }, + "frame": { + "x": 39, + "y": 126, + "w": 21, + "h": 24 + } + }, { "filename": "fist_plate", "rotated": false, @@ -1200,8 +1242,8 @@ "h": 24 }, "frame": { - "x": 75, - "y": 26, + "x": 39, + "y": 150, "w": 24, "h": 24 } @@ -1221,75 +1263,12 @@ "h": 24 }, "frame": { - "x": 99, - "y": 26, + "x": 39, + "y": 174, "w": 24, "h": 24 } }, - { - "filename": "revive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 12, - "h": 17 - }, - "frame": { - "x": 123, - "y": 26, - "w": 12, - "h": 17 - } - }, - { - "filename": "clefairy_doll", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 135, - "y": 36, - "w": 24, - "h": 23 - } - }, - { - "filename": "carbos", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 159, - "y": 22, - "w": 16, - "h": 24 - } - }, { "filename": "focus_band", "rotated": false, @@ -1305,8 +1284,8 @@ "h": 24 }, "frame": { - "x": 175, - "y": 21, + "x": 44, + "y": 198, "w": 24, "h": 24 } @@ -1326,12 +1305,33 @@ "h": 24 }, "frame": { - "x": 199, - "y": 21, + "x": 44, + "y": 222, "w": 24, "h": 24 } }, + { + "filename": "silver_powder", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 11, + "w": 24, + "h": 15 + }, + "frame": { + "x": 44, + "y": 246, + "w": 24, + "h": 15 + } + }, { "filename": "gracidea", "rotated": false, @@ -1347,8 +1347,8 @@ "h": 24 }, "frame": { - "x": 223, - "y": 21, + "x": 45, + "y": 261, "w": 24, "h": 24 } @@ -1368,8 +1368,8 @@ "h": 24 }, "frame": { - "x": 247, - "y": 21, + "x": 46, + "y": 285, "w": 24, "h": 24 } @@ -1389,8 +1389,8 @@ "h": 24 }, "frame": { - "x": 271, - "y": 21, + "x": 46, + "y": 309, "w": 24, "h": 24 } @@ -1410,33 +1410,12 @@ "h": 24 }, "frame": { - "x": 295, - "y": 21, + "x": 46, + "y": 333, "w": 24, "h": 24 } }, - { - "filename": "catching_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 21, - "h": 24 - }, - "frame": { - "x": 319, - "y": 21, - "w": 21, - "h": 24 - } - }, { "filename": "iron_plate", "rotated": false, @@ -1452,8 +1431,8 @@ "h": 24 }, "frame": { - "x": 340, - "y": 20, + "x": 46, + "y": 357, "w": 24, "h": 24 } @@ -1473,14 +1452,14 @@ "h": 24 }, "frame": { - "x": 364, - "y": 20, + "x": 46, + "y": 381, "w": 24, "h": 24 } }, { - "filename": "lock_capsule", + "filename": "adamant_crystal", "rotated": false, "trimmed": true, "sourceSize": { @@ -1488,62 +1467,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 19, - "h": 22 + "x": 4, + "y": 6, + "w": 23, + "h": 21 }, "frame": { - "x": 388, - "y": 20, - "w": 19, - "h": 22 + "x": 48, + "y": 405, + "w": 23, + "h": 21 } }, { - "filename": "ether", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 18, - "h": 24 - }, - "frame": { - "x": 407, - "y": 24, - "w": 18, - "h": 24 - } - }, - { - "filename": "abomasite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 159, - "y": 46, - "w": 16, - "h": 16 - } - }, - { - "filename": "coin_case", + "filename": "berry_pouch", "rotated": false, "trimmed": true, "sourceSize": { @@ -1553,18 +1490,18 @@ "spriteSourceSize": { "x": 4, "y": 5, - "w": 24, + "w": 23, "h": 23 }, "frame": { - "x": 175, - "y": 45, - "w": 24, + "x": 53, + "y": 55, + "w": 23, "h": 23 } }, { - "filename": "expert_belt", + "filename": "kings_rock", "rotated": false, "trimmed": true, "sourceSize": { @@ -1572,58 +1509,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 4, + "x": 5, "y": 4, - "w": 24, - "h": 23 + "w": 23, + "h": 24 }, "frame": { - "x": 199, - "y": 45, - "w": 24, - "h": 23 - } - }, - { - "filename": "hearthflame_mask", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 23 - }, - "frame": { - "x": 223, - "y": 45, - "w": 24, - "h": 23 - } - }, - { - "filename": "leppa_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 247, - "y": 45, - "w": 24, - "h": 23 + "x": 55, + "y": 78, + "w": 23, + "h": 24 } }, { @@ -1641,8 +1536,8 @@ "h": 24 }, "frame": { - "x": 271, - "y": 45, + "x": 55, + "y": 102, "w": 24, "h": 24 } @@ -1662,33 +1557,12 @@ "h": 24 }, "frame": { - "x": 295, - "y": 45, + "x": 60, + "y": 126, "w": 24, "h": 24 } }, - { - "filename": "kings_rock", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 319, - "y": 45, - "w": 23, - "h": 24 - } - }, { "filename": "lucky_punch_ultra", "rotated": false, @@ -1704,8 +1578,8 @@ "h": 24 }, "frame": { - "x": 342, - "y": 44, + "x": 63, + "y": 150, "w": 24, "h": 24 } @@ -1725,14 +1599,56 @@ "h": 24 }, "frame": { - "x": 366, - "y": 44, + "x": 63, + "y": 174, "w": 24, "h": 24 } }, { - "filename": "lure", + "filename": "max_revive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 22, + "h": 24 + }, + "frame": { + "x": 68, + "y": 198, + "w": 22, + "h": 24 + } + }, + { + "filename": "meadow_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 68, + "y": 222, + "w": 24, + "h": 24 + } + }, + { + "filename": "candy_overlay", "rotated": false, "trimmed": true, "sourceSize": { @@ -1741,14 +1657,56 @@ }, "spriteSourceSize": { "x": 8, + "y": 12, + "w": 16, + "h": 15 + }, + "frame": { + "x": 68, + "y": 246, + "w": 16, + "h": 15 + } + }, + { + "filename": "elixir", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, "y": 4, - "w": 17, + "w": 18, "h": 24 }, "frame": { - "x": 390, - "y": 42, - "w": 17, + "x": 69, + "y": 261, + "w": 18, + "h": 24 + } + }, + { + "filename": "ether", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 70, + "y": 285, + "w": 18, "h": 24 } }, @@ -1767,600 +1725,12 @@ "h": 24 }, "frame": { - "x": 407, - "y": 48, + "x": 70, + "y": 309, "w": 18, "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": 412, - "w": 15, - "h": 11 - } - }, - { - "filename": "dragon_scale", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 24, - "h": 18 - }, - "frame": { - "x": 75, - "y": 50, - "w": 24, - "h": 18 - } - }, - { - "filename": "exp_balance", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 22 - }, - "frame": { - "x": 99, - "y": 50, - "w": 24, - "h": 22 - } - }, - { - "filename": "berry_juice", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 24, - "h": 23 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 22, - "h": 21 - }, - "frame": { - "x": 53, - "y": 55, - "w": 22, - "h": 21 - } - }, - { - "filename": "exp_share", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 22 - }, - "frame": { - "x": 75, - "y": 68, - "w": 24, - "h": 22 - } - }, - { - "filename": "icy_reins_of_unity", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 24, - "h": 20 - }, - "frame": { - "x": 99, - "y": 72, - "w": 24, - "h": 20 - } - }, - { - "filename": "meadow_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 123, - "y": 59, - "w": 24, - "h": 24 - } - }, - { - "filename": "metal_powder", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 24, - "h": 20 - }, - "frame": { - "x": 123, - "y": 83, - "w": 24, - "h": 20 - } - }, - { - "filename": "mind_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 147, - "y": 62, - "w": 24, - "h": 24 - } - }, - { - "filename": "muscle_band", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 147, - "y": 86, - "w": 24, - "h": 24 - } - }, - { - "filename": "pixie_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 171, - "y": 68, - "w": 24, - "h": 24 - } - }, - { - "filename": "salac_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 195, - "y": 68, - "w": 24, - "h": 24 - } - }, - { - "filename": "scanner", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 219, - "y": 68, - "w": 24, - "h": 24 - } - }, - { - "filename": "silk_scarf", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 243, - "y": 68, - "w": 24, - "h": 24 - } - }, - { - "filename": "scope_lens", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 267, - "y": 69, - "w": 24, - "h": 23 - } - }, - { - "filename": "sky_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 291, - "y": 69, - "w": 24, - "h": 24 - } - }, - { - "filename": "splash_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 315, - "y": 69, - "w": 24, - "h": 24 - } - }, - { - "filename": "peat_block", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 22 - }, - "frame": { - "x": 171, - "y": 92, - "w": 24, - "h": 22 - } - }, - { - "filename": "spooky_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 195, - "y": 92, - "w": 24, - "h": 24 - } - }, - { - "filename": "stone_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 219, - "y": 92, - "w": 24, - "h": 24 - } - }, - { - "filename": "sun_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 243, - "y": 92, - "w": 24, - "h": 24 - } - }, - { - "filename": "toxic_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 267, - "y": 92, - "w": 24, - "h": 24 - } - }, - { - "filename": "twisted_spoon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 24, - "h": 23 - }, - "frame": { - "x": 291, - "y": 93, - "w": 24, - "h": 23 - } - }, - { - "filename": "zap_plate", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 24 - }, - "frame": { - "x": 315, - "y": 93, - "w": 24, - "h": 24 - } - }, - { - "filename": "hp_up", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 339, - "y": 69, - "w": 16, - "h": 24 - } - }, - { - "filename": "reveal_glass", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 23, - "h": 24 - }, - "frame": { - "x": 355, - "y": 68, - "w": 23, - "h": 24 - } - }, - { - "filename": "iron", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 339, - "y": 93, - "w": 16, - "h": 24 - } - }, - { - "filename": "berry_pouch", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 355, - "y": 92, - "w": 23, - "h": 23 - } - }, { "filename": "max_elixir", "rotated": false, @@ -2376,138 +1746,12 @@ "h": 24 }, "frame": { - "x": 378, - "y": 68, + "x": 70, + "y": 333, "w": 18, "h": 24 } }, - { - "filename": "black_belt", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 378, - "y": 92, - "w": 22, - "h": 23 - } - }, - { - "filename": "quick_powder", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 24, - "h": 20 - }, - "frame": { - "x": 396, - "y": 72, - "w": 24, - "h": 20 - } - }, - { - "filename": "bug_tera_shard", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 22, - "h": 23 - }, - "frame": { - "x": 400, - "y": 92, - "w": 22, - "h": 23 - } - }, - { - "filename": "rusted_shield", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 24, - "h": 20 - }, - "frame": { - "x": 355, - "y": 115, - "w": 24, - "h": 20 - } - }, - { - "filename": "sacred_ash", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 24, - "h": 20 - }, - "frame": { - "x": 379, - "y": 115, - "w": 24, - "h": 20 - } - }, - { - "filename": "max_revive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 24 - }, - "frame": { - "x": 403, - "y": 115, - "w": 22, - "h": 24 - } - }, { "filename": "max_ether", "rotated": false, @@ -2523,8 +1767,8 @@ "h": 24 }, "frame": { - "x": 39, - "y": 90, + "x": 70, + "y": 357, "w": 18, "h": 24 } @@ -2544,12 +1788,159 @@ "h": 24 }, "frame": { - "x": 39, - "y": 114, + "x": 70, + "y": 381, "w": 18, "h": 24 } }, + { + "filename": "amulet_coin", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 23, + "h": 21 + }, + "frame": { + "x": 71, + "y": 405, + "w": 23, + "h": 21 + } + }, + { + "filename": "eviolite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 15, + "h": 15 + }, + "frame": { + "x": 59, + "y": 40, + "w": 15, + "h": 15 + } + }, + { + "filename": "mind_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 74, + "y": 26, + "w": 24, + "h": 24 + } + }, + { + "filename": "muscle_band", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 98, + "y": 26, + "w": 24, + "h": 24 + } + }, + { + "filename": "pixie_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 76, + "y": 50, + "w": 24, + "h": 24 + } + }, + { + "filename": "reveal_glass", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 23, + "h": 24 + }, + "frame": { + "x": 100, + "y": 50, + "w": 23, + "h": 24 + } + }, + { + "filename": "salac_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 78, + "y": 74, + "w": 24, + "h": 24 + } + }, { "filename": "oval_charm", "rotated": false, @@ -2565,14 +1956,14 @@ "h": 24 }, "frame": { - "x": 39, - "y": 138, + "x": 102, + "y": 74, "w": 21, "h": 24 } }, { - "filename": "shiny_charm", + "filename": "scanner", "rotated": false, "trimmed": true, "sourceSize": { @@ -2580,57 +1971,15 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, + "x": 4, "y": 4, - "w": 21, + "w": 24, "h": 24 }, "frame": { - "x": 39, - "y": 162, - "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": 39, - "y": 186, - "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": 44, - "y": 209, - "w": 17, + "x": 79, + "y": 98, + "w": 24, "h": 24 } }, @@ -2649,14 +1998,35 @@ "h": 24 }, "frame": { - "x": 44, - "y": 233, + "x": 103, + "y": 98, "w": 20, "h": 24 } }, { - "filename": "sachet", + "filename": "silk_scarf", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 84, + "y": 122, + "w": 24, + "h": 24 + } + }, + { + "filename": "shiny_charm", "rotated": false, "trimmed": true, "sourceSize": { @@ -2666,18 +2036,18 @@ "spriteSourceSize": { "x": 6, "y": 4, - "w": 18, - "h": 23 + "w": 21, + "h": 24 }, "frame": { - "x": 57, - "y": 76, - "w": 18, - "h": 23 + "x": 87, + "y": 146, + "w": 21, + "h": 24 } }, { - "filename": "dragon_fang", + "filename": "sky_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -2685,20 +2055,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 21, - "h": 23 + "x": 4, + "y": 4, + "w": 24, + "h": 24 }, "frame": { - "x": 57, - "y": 99, - "w": 21, - "h": 23 + "x": 87, + "y": 170, + "w": 24, + "h": 24 } }, { - "filename": "mega_bracelet", + "filename": "splash_plate", "rotated": false, "trimmed": true, "sourceSize": { @@ -2706,20 +2076,83 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 16 + "x": 4, + "y": 4, + "w": 24, + "h": 24 }, "frame": { - "x": 57, + "x": 90, + "y": 194, + "w": 24, + "h": 24 + } + }, + { + "filename": "spooky_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 92, + "y": 218, + "w": 24, + "h": 24 + } + }, + { + "filename": "hp_up", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 108, "y": 122, - "w": 20, - "h": 16 + "w": 16, + "h": 24 } }, { - "filename": "super_lure", + "filename": "iron", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 108, + "y": 146, + "w": 16, + "h": 24 + } + }, + { + "filename": "lure", "rotated": false, "trimmed": true, "sourceSize": { @@ -2733,8 +2166,29 @@ "h": 24 }, "frame": { - "x": 60, - "y": 138, + "x": 111, + "y": 170, + "w": 17, + "h": 24 + } + }, + { + "filename": "max_lure", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 17, + "h": 24 + }, + "frame": { + "x": 114, + "y": 194, "w": 17, "h": 24 } @@ -2754,12 +2208,369 @@ "h": 24 }, "frame": { - "x": 60, - "y": 162, + "x": 116, + "y": 218, "w": 16, "h": 24 } }, + { + "filename": "revive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 12, + "h": 17 + }, + "frame": { + "x": 122, + "y": 26, + "w": 12, + "h": 17 + } + }, + { + "filename": "coin_case", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 92, + "y": 242, + "w": 24, + "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": 87, + "y": 265, + "w": 24, + "h": 20 + } + }, + { + "filename": "stone_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 88, + "y": 285, + "w": 24, + "h": 24 + } + }, + { + "filename": "sun_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 88, + "y": 309, + "w": 24, + "h": 24 + } + }, + { + "filename": "toxic_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 88, + "y": 333, + "w": 24, + "h": 24 + } + }, + { + "filename": "zap_plate", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 24 + }, + "frame": { + "x": 88, + "y": 357, + "w": 24, + "h": 24 + } + }, + { + "filename": "expert_belt", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 23 + }, + "frame": { + "x": 88, + "y": 381, + "w": 24, + "h": 23 + } + }, + { + "filename": "exp_balance", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 22 + }, + "frame": { + "x": 94, + "y": 404, + "w": 24, + "h": 22 + } + }, + { + "filename": "black_belt", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 116, + "y": 242, + "w": 22, + "h": 23 + } + }, + { + "filename": "quick_powder", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 24, + "h": 20 + }, + "frame": { + "x": 111, + "y": 265, + "w": 24, + "h": 20 + } + }, + { + "filename": "dynamax_band", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 23, + "h": 23 + }, + "frame": { + "x": 112, + "y": 285, + "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": 112, + "y": 308, + "w": 23, + "h": 23 + } + }, + { + "filename": "hearthflame_mask", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 23 + }, + "frame": { + "x": 112, + "y": 331, + "w": 24, + "h": 23 + } + }, + { + "filename": "leppa_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 112, + "y": 354, + "w": 24, + "h": 23 + } + }, + { + "filename": "scope_lens", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 112, + "y": 377, + "w": 24, + "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": 118, + "y": 400, + "w": 22, + "h": 23 + } + }, { "filename": "pp_max", "rotated": false, @@ -2775,8 +2586,50 @@ "h": 24 }, "frame": { - "x": 61, - "y": 186, + "x": 123, + "y": 43, + "w": 16, + "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": 139, + "y": 40, + "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": 123, + "y": 67, "w": 16, "h": 24 } @@ -2796,14 +2649,14 @@ "h": 23 }, "frame": { - "x": 61, - "y": 210, + "x": 139, + "y": 63, "w": 22, "h": 23 } }, { - "filename": "dynamax_band", + "filename": "protein", "rotated": false, "trimmed": true, "sourceSize": { @@ -2811,16 +2664,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 4, + "x": 8, "y": 4, - "w": 23, - "h": 23 + "w": 16, + "h": 24 }, "frame": { - "x": 64, - "y": 233, - "w": 23, - "h": 23 + "x": 123, + "y": 91, + "w": 16, + "h": 24 } }, { @@ -2838,12 +2691,75 @@ "h": 23 }, "frame": { - "x": 45, - "y": 257, + "x": 139, + "y": 86, "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": 124, + "y": 115, + "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": 124, + "y": 139, + "w": 17, + "h": 24 + } + }, + { + "filename": "dragon_fang", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 21, + "h": 23 + }, + "frame": { + "x": 140, + "y": 109, + "w": 21, + "h": 23 + } + }, { "filename": "fairy_tera_shard", "rotated": false, @@ -2859,12 +2775,54 @@ "h": 23 }, "frame": { - "x": 67, - "y": 256, + "x": 141, + "y": 132, "w": 22, "h": 23 } }, + { + "filename": "auspicious_armor", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 21 + }, + "frame": { + "x": 141, + "y": 155, + "w": 23, + "h": 21 + } + }, + { + "filename": "dragon_scale", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 24, + "h": 18 + }, + "frame": { + "x": 128, + "y": 176, + "w": 24, + "h": 18 + } + }, { "filename": "fighting_tera_shard", "rotated": false, @@ -2880,8 +2838,8 @@ "h": 23 }, "frame": { - "x": 46, - "y": 280, + "x": 131, + "y": 194, "w": 22, "h": 23 } @@ -2901,12 +2859,54 @@ "h": 23 }, "frame": { - "x": 46, - "y": 303, + "x": 132, + "y": 217, "w": 22, "h": 23 } }, + { + "filename": "super_repel", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 138, + "y": 240, + "w": 16, + "h": 24 + } + }, + { + "filename": "baton", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 152, + "y": 176, + "w": 18, + "h": 18 + } + }, { "filename": "fire_tera_shard", "rotated": false, @@ -2922,8 +2922,8 @@ "h": 23 }, "frame": { - "x": 46, - "y": 326, + "x": 153, + "y": 194, "w": 22, "h": 23 } @@ -2943,8 +2943,8 @@ "h": 23 }, "frame": { - "x": 46, - "y": 349, + "x": 154, + "y": 217, "w": 22, "h": 23 } @@ -2964,12 +2964,75 @@ "h": 23 }, "frame": { - "x": 46, - "y": 372, + "x": 154, + "y": 240, "w": 22, "h": 23 } }, + { + "filename": "unknown", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 135, + "y": 265, + "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": 135, + "y": 289, + "w": 16, + "h": 24 + } + }, + { + "filename": "candy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 11, + "w": 18, + "h": 18 + }, + "frame": { + "x": 135, + "y": 313, + "w": 18, + "h": 18 + } + }, { "filename": "ghost_tera_shard", "rotated": false, @@ -2985,8 +3048,8 @@ "h": 23 }, "frame": { - "x": 68, - "y": 279, + "x": 136, + "y": 331, "w": 22, "h": 23 } @@ -3006,264 +3069,12 @@ "h": 23 }, "frame": { - "x": 68, - "y": 302, + "x": 136, + "y": 354, "w": 22, "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": 68, - "y": 325, - "w": 23, - "h": 23 - } - }, - { - "filename": "leek", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 68, - "y": 348, - "w": 23, - "h": 23 - } - }, - { - "filename": "rare_candy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 68, - "y": 371, - "w": 23, - "h": 23 - } - }, - { - "filename": "lansat_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 21, - "h": 23 - }, - "frame": { - "x": 78, - "y": 90, - "w": 21, - "h": 23 - } - }, - { - "filename": "shadow_reins_of_unity", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 24, - "h": 20 - }, - "frame": { - "x": 99, - "y": 92, - "w": 24, - "h": 20 - } - }, - { - "filename": "silver_powder", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 11, - "w": 24, - "h": 15 - }, - "frame": { - "x": 123, - "y": 103, - "w": 24, - "h": 15 - } - }, - { - "filename": "soft_sand", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 24, - "h": 20 - }, - "frame": { - "x": 147, - "y": 110, - "w": 24, - "h": 20 - } - }, - { - "filename": "adamant_crystal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 23, - "h": 21 - }, - "frame": { - "x": 171, - "y": 114, - "w": 23, - "h": 21 - } - }, - { - "filename": "amulet_coin", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 23, - "h": 21 - }, - "frame": { - "x": 194, - "y": 116, - "w": 23, - "h": 21 - } - }, - { - "filename": "auspicious_armor", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 21 - }, - "frame": { - "x": 217, - "y": 116, - "w": 23, - "h": 21 - } - }, - { - "filename": "healing_charm", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 23, - "h": 22 - }, - "frame": { - "x": 240, - "y": 116, - "w": 23, - "h": 22 - } - }, - { - "filename": "rarer_candy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 23 - }, - "frame": { - "x": 263, - "y": 116, - "w": 23, - "h": 23 - } - }, { "filename": "ground_tera_shard", "rotated": false, @@ -3279,54 +3090,12 @@ "h": 23 }, "frame": { - "x": 286, - "y": 116, + "x": 136, + "y": 377, "w": 22, "h": 23 } }, - { - "filename": "rusted_sword", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 5, - "w": 23, - "h": 22 - }, - "frame": { - "x": 308, - "y": 117, - "w": 23, - "h": 22 - } - }, - { - "filename": "blank_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 331, - "y": 117, - "w": 22, - "h": 22 - } - }, { "filename": "ice_tera_shard", "rotated": false, @@ -3342,14 +3111,182 @@ "h": 23 }, "frame": { - "x": 68, - "y": 394, + "x": 140, + "y": 400, "w": 22, "h": 23 } }, { - "filename": "binding_band", + "filename": "exp_share", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 22 + }, + "frame": { + "x": 330, + "y": 20, + "w": 24, + "h": 22 + } + }, + { + "filename": "peat_block", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 22 + }, + "frame": { + "x": 354, + "y": 20, + "w": 24, + "h": 22 + } + }, + { + "filename": "twisted_spoon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 24, + "h": 23 + }, + "frame": { + "x": 378, + "y": 20, + "w": 24, + "h": 23 + } + }, + { + "filename": "rusted_shield", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 6, + "w": 24, + "h": 20 + }, + "frame": { + "x": 402, + "y": 22, + "w": 24, + "h": 20 + } + }, + { + "filename": "sacred_ash", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 24, + "h": 20 + }, + "frame": { + "x": 402, + "y": 42, + "w": 24, + "h": 20 + } + }, + { + "filename": "full_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 9, + "y": 4, + "w": 15, + "h": 23 + }, + "frame": { + "x": 151, + "y": 264, + "w": 15, + "h": 23 + } + }, + { + "filename": "hyper_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 23 + }, + "frame": { + "x": 151, + "y": 287, + "w": 17, + "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": 153, + "y": 310, + "w": 22, + "h": 21 + } + }, + { + "filename": "lansat_berry", "rotated": false, "trimmed": true, "sourceSize": { @@ -3358,19 +3295,19 @@ }, "spriteSourceSize": { "x": 5, - "y": 6, - "w": 23, - "h": 20 + "y": 4, + "w": 21, + "h": 23 }, "frame": { - "x": 78, - "y": 113, - "w": 23, - "h": 20 + "x": 158, + "y": 331, + "w": 21, + "h": 23 } }, { - "filename": "bug_memory", + "filename": "leaf_stone", "rotated": false, "trimmed": true, "sourceSize": { @@ -3380,14 +3317,56 @@ "spriteSourceSize": { "x": 5, "y": 5, - "w": 22, - "h": 22 + "w": 21, + "h": 23 }, "frame": { - "x": 101, - "y": 112, - "w": 22, - "h": 22 + "x": 158, + "y": 354, + "w": 21, + "h": 23 + } + }, + { + "filename": "leek", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 158, + "y": 377, + "w": 23, + "h": 23 + } + }, + { + "filename": "mystic_water", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 20, + "h": 23 + }, + "frame": { + "x": 162, + "y": 400, + "w": 20, + "h": 23 } }, { @@ -3405,138 +3384,12 @@ "h": 23 }, "frame": { - "x": 77, - "y": 133, + "x": 166, + "y": 263, "w": 22, "h": 23 } }, - { - "filename": "charcoal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 99, - "y": 134, - "w": 22, - "h": 22 - } - }, - { - "filename": "black_glasses", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 123, - "y": 118, - "w": 23, - "h": 17 - } - }, - { - "filename": "moon_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 23, - "h": 21 - }, - "frame": { - "x": 121, - "y": 135, - "w": 23, - "h": 21 - } - }, - { - "filename": "burn_drive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 77, - "y": 156, - "w": 23, - "h": 17 - } - }, - { - "filename": "chill_drive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 100, - "y": 156, - "w": 23, - "h": 17 - } - }, - { - "filename": "black_sludge", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 24, - "h": 24 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 22, - "h": 19 - }, - "frame": { - "x": 123, - "y": 156, - "w": 22, - "h": 19 - } - }, { "filename": "normal_tera_shard", "rotated": false, @@ -3552,12 +3405,33 @@ "h": 23 }, "frame": { - "x": 77, - "y": 173, + "x": 168, + "y": 286, "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": 175, + "y": 309, + "w": 18, + "h": 22 + } + }, { "filename": "petaya_berry", "rotated": false, @@ -3573,33 +3447,12 @@ "h": 23 }, "frame": { - "x": 99, - "y": 173, + "x": 179, + "y": 331, "w": 22, "h": 23 } }, - { - "filename": "n_lunarizer", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 6, - "w": 23, - "h": 21 - }, - "frame": { - "x": 121, - "y": 175, - "w": 23, - "h": 21 - } - }, { "filename": "poison_tera_shard", "rotated": false, @@ -3615,8 +3468,8 @@ "h": 23 }, "frame": { - "x": 83, - "y": 196, + "x": 179, + "y": 354, "w": 22, "h": 23 } @@ -3636,14 +3489,14 @@ "h": 23 }, "frame": { - "x": 105, - "y": 196, + "x": 181, + "y": 377, "w": 22, "h": 23 } }, { - "filename": "hyper_potion", + "filename": "rare_candy", "rotated": false, "trimmed": true, "sourceSize": { @@ -3651,18 +3504,81 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, + "x": 4, "y": 5, - "w": 17, + "w": 23, "h": 23 }, "frame": { - "x": 127, - "y": 196, - "w": 17, + "x": 182, + "y": 400, + "w": 23, "h": 23 } }, + { + "filename": "shadow_reins_of_unity", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 24, + "h": 20 + }, + "frame": { + "x": 162, + "y": 21, + "w": 24, + "h": 20 + } + }, + { + "filename": "rarer_candy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 23 + }, + "frame": { + "x": 161, + "y": 41, + "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": 161, + "y": 64, + "w": 23, + "h": 22 + } + }, { "filename": "reaper_cloth", "rotated": false, @@ -3678,8 +3594,8 @@ "h": 23 }, "frame": { - "x": 87, - "y": 219, + "x": 161, + "y": 86, "w": 22, "h": 23 } @@ -3699,14 +3615,14 @@ "h": 23 }, "frame": { - "x": 109, - "y": 219, + "x": 161, + "y": 109, "w": 22, "h": 23 } }, { - "filename": "full_heal", + "filename": "sharp_beak", "rotated": false, "trimmed": true, "sourceSize": { @@ -3714,18 +3630,81 @@ "h": 32 }, "spriteSourceSize": { - "x": 9, - "y": 4, - "w": 15, + "x": 5, + "y": 5, + "w": 21, "h": 23 }, "frame": { - "x": 131, - "y": 219, - "w": 15, + "x": 163, + "y": 132, + "w": 21, "h": 23 } }, + { + "filename": "dawn_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 21 + }, + "frame": { + "x": 164, + "y": 155, + "w": 20, + "h": 21 + } + }, + { + "filename": "soft_sand", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 24, + "h": 20 + }, + "frame": { + "x": 186, + "y": 21, + "w": 24, + "h": 20 + } + }, + { + "filename": "rusted_sword", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 22 + }, + "frame": { + "x": 184, + "y": 41, + "w": 23, + "h": 22 + } + }, { "filename": "steel_tera_shard", "rotated": false, @@ -3741,8 +3720,8 @@ "h": 23 }, "frame": { - "x": 89, - "y": 242, + "x": 184, + "y": 63, "w": 22, "h": 23 } @@ -3762,33 +3741,12 @@ "h": 23 }, "frame": { - "x": 111, - "y": 242, + "x": 183, + "y": 86, "w": 22, "h": 23 } }, - { - "filename": "leaf_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 21, - "h": 23 - }, - "frame": { - "x": 133, - "y": 242, - "w": 21, - "h": 23 - } - }, { "filename": "water_tera_shard", "rotated": false, @@ -3804,159 +3762,12 @@ "h": 23 }, "frame": { - "x": 90, - "y": 265, + "x": 183, + "y": 109, "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": 90, - "y": 288, - "w": 22, - "h": 23 - } - }, - { - "filename": "dark_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 112, - "y": 265, - "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": 112, - "y": 287, - "w": 22, - "h": 22 - } - }, - { - "filename": "mystic_water", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 20, - "h": 23 - }, - "frame": { - "x": 134, - "y": 265, - "w": 20, - "h": 23 - } - }, - { - "filename": "dawn_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 21 - }, - "frame": { - "x": 134, - "y": 288, - "w": 20, - "h": 21 - } - }, - { - "filename": "sharp_beak", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 21, - "h": 23 - }, - "frame": { - "x": 91, - "y": 311, - "w": 21, - "h": 23 - } - }, - { - "filename": "dna_splicers", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 112, - "y": 309, - "w": 22, - "h": 22 - } - }, { "filename": "whipped_dream", "rotated": false, @@ -3972,140 +3783,14 @@ "h": 23 }, "frame": { - "x": 91, - "y": 334, + "x": 184, + "y": 132, "w": 21, "h": 23 } }, { - "filename": "dragon_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 112, - "y": 331, - "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": 91, - "y": 357, - "w": 22, - "h": 22 - } - }, - { - "filename": "electric_memory", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 134, - "y": 309, - "w": 22, - "h": 22 - } - }, - { - "filename": "enigma_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 134, - "y": 331, - "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": 113, - "y": 353, - "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": 135, - "y": 353, - "w": 22, - "h": 22 - } - }, - { - "filename": "blunder_policy", + "filename": "binding_band", "rotated": false, "trimmed": true, "sourceSize": { @@ -4115,18 +3800,18 @@ "spriteSourceSize": { "x": 5, "y": 6, - "w": 22, - "h": 19 + "w": 23, + "h": 20 }, "frame": { - "x": 91, - "y": 379, - "w": 22, - "h": 19 + "x": 210, + "y": 21, + "w": 23, + "h": 20 } }, { - "filename": "fire_memory", + "filename": "blank_memory", "rotated": false, "trimmed": true, "sourceSize": { @@ -4140,14 +3825,35 @@ "h": 22 }, "frame": { - "x": 113, - "y": 375, + "x": 207, + "y": 41, "w": 22, "h": 22 } }, { - "filename": "flying_memory", + "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": 63, + "w": 22, + "h": 23 + } + }, + { + "filename": "bug_memory", "rotated": false, "trimmed": true, "sourceSize": { @@ -4161,14 +3867,56 @@ "h": 22 }, "frame": { - "x": 135, - "y": 375, + "x": 205, + "y": 86, "w": 22, "h": 22 } }, { - "filename": "mystic_ticket", + "filename": "charcoal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 205, + "y": 108, + "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": 205, + "y": 130, + "w": 22, + "h": 22 + } + }, + { + "filename": "moon_stone", "rotated": false, "trimmed": true, "sourceSize": { @@ -4177,15 +3925,36 @@ }, "spriteSourceSize": { "x": 4, - "y": 7, + "y": 6, "w": 23, - "h": 19 + "h": 21 }, "frame": { - "x": 90, - "y": 398, + "x": 233, + "y": 21, "w": 23, - "h": 19 + "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": 256, + "y": 21, + "w": 23, + "h": 21 } }, { @@ -4203,8 +3972,29 @@ "h": 21 }, "frame": { - "x": 113, - "y": 397, + "x": 279, + "y": 21, + "w": 23, + "h": 21 + } + }, + { + "filename": "wellspring_mask", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 5, + "w": 23, + "h": 21 + }, + "frame": { + "x": 302, + "y": 21, "w": 23, "h": 21 } @@ -4224,75 +4014,12 @@ "h": 21 }, "frame": { - "x": 136, - "y": 397, + "x": 184, + "y": 155, "w": 22, "h": 21 } }, - { - "filename": "douse_drive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 146, - "y": 130, - "w": 23, - "h": 17 - } - }, - { - "filename": "ganlon_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 145, - "y": 147, - "w": 22, - "h": 22 - } - }, - { - "filename": "pair_of_tickets", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 169, - "y": 135, - "w": 23, - "h": 19 - } - }, { "filename": "relic_crown", "rotated": false, @@ -4308,14 +4035,35 @@ "h": 18 }, "frame": { - "x": 192, - "y": 137, + "x": 170, + "y": 176, "w": 23, "h": 18 } }, { - "filename": "reviver_seed", + "filename": "sachet", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 18, + "h": 23 + }, + "frame": { + "x": 175, + "y": 194, + "w": 18, + "h": 23 + } + }, + { + "filename": "dire_hit", "rotated": false, "trimmed": true, "sourceSize": { @@ -4324,57 +4072,267 @@ }, "spriteSourceSize": { "x": 5, - "y": 8, - "w": 23, - "h": 20 - }, - "frame": { - "x": 215, - "y": 137, - "w": 23, - "h": 20 - } - }, - { - "filename": "shell_bell", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 23, - "h": 20 - }, - "frame": { - "x": 238, - "y": 138, - "w": 23, - "h": 20 - } - }, - { - "filename": "wellspring_mask", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, "y": 5, - "w": 23, - "h": 21 + "w": 22, + "h": 22 }, "frame": { - "x": 261, - "y": 139, - "w": 23, - "h": 21 + "x": 206, + "y": 152, + "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": 176, + "y": 217, + "w": 17, + "h": 23 + } + }, + { + "filename": "super_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 23 + }, + "frame": { + "x": 176, + "y": 240, + "w": 17, + "h": 23 + } + }, + { + "filename": "dna_splicers", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 229, + "y": 42, + "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": 251, + "y": 42, + "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": 273, + "y": 42, + "w": 22, + "h": 22 + } + }, + { + "filename": "electric_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 295, + "y": 42, + "w": 22, + "h": 22 + } + }, + { + "filename": "enigma_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 228, + "y": 64, + "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": 227, + "y": 86, + "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": 250, + "y": 64, + "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": 227, + "y": 108, + "w": 22, + "h": 22 + } + }, + { + "filename": "flying_memory", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 227, + "y": 130, + "w": 22, + "h": 22 + } + }, + { + "filename": "ganlon_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 249, + "y": 86, + "w": 22, + "h": 22 } }, { @@ -4392,8 +4350,8 @@ "h": 22 }, "frame": { - "x": 284, - "y": 139, + "x": 272, + "y": 64, "w": 22, "h": 22 } @@ -4413,8 +4371,8 @@ "h": 22 }, "frame": { - "x": 306, - "y": 139, + "x": 249, + "y": 108, "w": 22, "h": 22 } @@ -4434,117 +4392,12 @@ "h": 22 }, "frame": { - "x": 328, - "y": 139, + "x": 271, + "y": 86, "w": 22, "h": 22 } }, - { - "filename": "shock_drive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 167, - "y": 154, - "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": 190, - "y": 155, - "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": 20 - }, - "frame": { - "x": 213, - "y": 157, - "w": 22, - "h": 20 - } - }, - { - "filename": "dubious_disc", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 19 - }, - "frame": { - "x": 235, - "y": 158, - "w": 22, - "h": 19 - } - }, - { - "filename": "fairy_feather", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 20 - }, - "frame": { - "x": 257, - "y": 160, - "w": 22, - "h": 20 - } - }, { "filename": "guard_spec", "rotated": false, @@ -4560,8 +4413,8 @@ "h": 22 }, "frame": { - "x": 279, - "y": 161, + "x": 294, + "y": 64, "w": 22, "h": 22 } @@ -4581,8 +4434,8 @@ "h": 22 }, "frame": { - "x": 301, - "y": 161, + "x": 249, + "y": 130, "w": 22, "h": 22 } @@ -4602,33 +4455,12 @@ "h": 22 }, "frame": { - "x": 323, - "y": 161, + "x": 228, + "y": 152, "w": 22, "h": 22 } }, - { - "filename": "liechi_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 145, - "y": 169, - "w": 22, - "h": 21 - } - }, { "filename": "magmarizer", "rotated": false, @@ -4644,33 +4476,12 @@ "h": 22 }, "frame": { - "x": 144, - "y": 190, + "x": 271, + "y": 108, "w": 22, "h": 22 } }, - { - "filename": "malicious_armor", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 20 - }, - "frame": { - "x": 167, - "y": 171, - "w": 22, - "h": 20 - } - }, { "filename": "mini_black_hole", "rotated": false, @@ -4686,8 +4497,8 @@ "h": 22 }, "frame": { - "x": 166, - "y": 191, + "x": 293, + "y": 86, "w": 22, "h": 22 } @@ -4707,8 +4518,8 @@ "h": 22 }, "frame": { - "x": 189, - "y": 172, + "x": 271, + "y": 130, "w": 22, "h": 22 } @@ -4728,8 +4539,8 @@ "h": 22 }, "frame": { - "x": 188, - "y": 194, + "x": 250, + "y": 152, "w": 22, "h": 22 } @@ -4749,8 +4560,8 @@ "h": 22 }, "frame": { - "x": 211, - "y": 177, + "x": 293, + "y": 108, "w": 22, "h": 22 } @@ -4770,8 +4581,8 @@ "h": 22 }, "frame": { - "x": 233, - "y": 177, + "x": 293, + "y": 130, "w": 22, "h": 22 } @@ -4791,8 +4602,8 @@ "h": 22 }, "frame": { - "x": 255, - "y": 180, + "x": 272, + "y": 152, "w": 22, "h": 22 } @@ -4812,8 +4623,8 @@ "h": 22 }, "frame": { - "x": 277, - "y": 183, + "x": 294, + "y": 152, "w": 22, "h": 22 } @@ -4833,8 +4644,8 @@ "h": 22 }, "frame": { - "x": 299, - "y": 183, + "x": 317, + "y": 42, "w": 22, "h": 22 } @@ -4854,8 +4665,8 @@ "h": 22 }, "frame": { - "x": 321, - "y": 183, + "x": 316, + "y": 64, "w": 22, "h": 22 } @@ -4875,8 +4686,8 @@ "h": 22 }, "frame": { - "x": 210, - "y": 199, + "x": 315, + "y": 86, "w": 22, "h": 22 } @@ -4896,75 +4707,12 @@ "h": 22 }, "frame": { - "x": 232, - "y": 199, + "x": 339, + "y": 42, "w": 22, "h": 22 } }, - { - "filename": "sweet_apple", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 254, - "y": 202, - "w": 22, - "h": 21 - } - }, - { - "filename": "syrupy_apple", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 276, - "y": 205, - "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": 298, - "y": 205, - "w": 22, - "h": 21 - } - }, { "filename": "thunder_stone", "rotated": false, @@ -4980,33 +4728,12 @@ "h": 22 }, "frame": { - "x": 320, - "y": 205, + "x": 338, + "y": 64, "w": 22, "h": 22 } }, - { - "filename": "hard_meteorite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 20, - "h": 22 - }, - "frame": { - "x": 146, - "y": 212, - "w": 20, - "h": 22 - } - }, { "filename": "tm_bug", "rotated": false, @@ -5022,33 +4749,12 @@ "h": 22 }, "frame": { - "x": 166, - "y": 213, + "x": 315, + "y": 108, "w": 22, "h": 22 } }, - { - "filename": "tera_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 20 - }, - "frame": { - "x": 188, - "y": 216, - "w": 22, - "h": 20 - } - }, { "filename": "tm_dark", "rotated": false, @@ -5064,8 +4770,8 @@ "h": 22 }, "frame": { - "x": 210, - "y": 221, + "x": 315, + "y": 130, "w": 22, "h": 22 } @@ -5085,8 +4791,8 @@ "h": 22 }, "frame": { - "x": 232, - "y": 221, + "x": 337, + "y": 86, "w": 22, "h": 22 } @@ -5106,8 +4812,8 @@ "h": 22 }, "frame": { - "x": 254, - "y": 223, + "x": 337, + "y": 108, "w": 22, "h": 22 } @@ -5127,8 +4833,8 @@ "h": 22 }, "frame": { - "x": 276, - "y": 226, + "x": 337, + "y": 130, "w": 22, "h": 22 } @@ -5148,8 +4854,8 @@ "h": 22 }, "frame": { - "x": 298, - "y": 226, + "x": 316, + "y": 152, "w": 22, "h": 22 } @@ -5169,14 +4875,14 @@ "h": 22 }, "frame": { - "x": 320, - "y": 227, + "x": 338, + "y": 152, "w": 22, "h": 22 } }, { - "filename": "berry_pot", + "filename": "metronome", "rotated": false, "trimmed": true, "sourceSize": { @@ -5186,18 +4892,18 @@ "spriteSourceSize": { "x": 7, "y": 5, - "w": 18, + "w": 17, "h": 22 }, "frame": { - "x": 345, - "y": 161, - "w": 18, + "x": 361, + "y": 42, + "w": 17, "h": 22 } }, { - "filename": "sitrus_berry", + "filename": "liechi_berry", "rotated": false, "trimmed": true, "sourceSize": { @@ -5205,16 +4911,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 20, - "h": 22 + "x": 5, + "y": 6, + "w": 22, + "h": 21 }, "frame": { - "x": 343, - "y": 183, - "w": 20, - "h": 22 + "x": 378, + "y": 43, + "w": 22, + "h": 21 } }, { @@ -5232,8 +4938,8 @@ "h": 22 }, "frame": { - "x": 342, - "y": 205, + "x": 360, + "y": 64, "w": 22, "h": 22 } @@ -5253,33 +4959,12 @@ "h": 22 }, "frame": { - "x": 342, - "y": 227, + "x": 359, + "y": 86, "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": 350, - "y": 139, - "w": 15, - "h": 22 - } - }, { "filename": "tm_grass", "rotated": false, @@ -5295,33 +4980,12 @@ "h": 22 }, "frame": { - "x": 365, - "y": 135, + "x": 359, + "y": 108, "w": 22, "h": 22 } }, - { - "filename": "pp_up", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 387, - "y": 135, - "w": 16, - "h": 24 - } - }, { "filename": "tm_ground", "rotated": false, @@ -5337,8 +5001,8 @@ "h": 22 }, "frame": { - "x": 403, - "y": 139, + "x": 359, + "y": 130, "w": 22, "h": 22 } @@ -5358,12 +5022,33 @@ "h": 22 }, "frame": { - "x": 365, - "y": 157, + "x": 360, + "y": 152, "w": 22, "h": 22 } }, + { + "filename": "hard_meteorite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 20, + "h": 22 + }, + "frame": { + "x": 382, + "y": 64, + "w": 20, + "h": 22 + } + }, { "filename": "tm_normal", "rotated": false, @@ -5379,8 +5064,8 @@ "h": 22 }, "frame": { - "x": 363, - "y": 179, + "x": 381, + "y": 86, "w": 22, "h": 22 } @@ -5400,8 +5085,8 @@ "h": 22 }, "frame": { - "x": 364, - "y": 201, + "x": 381, + "y": 108, "w": 22, "h": 22 } @@ -5421,14 +5106,161 @@ "h": 22 }, "frame": { - "x": 364, - "y": 223, + "x": 381, + "y": 130, "w": 22, "h": 22 } }, { - "filename": "protein", + "filename": "reviver_seed", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 8, + "w": 23, + "h": 20 + }, + "frame": { + "x": 403, + "y": 62, + "w": 23, + "h": 20 + } + }, + { + "filename": "shell_bell", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 23, + "h": 20 + }, + "frame": { + "x": 403, + "y": 82, + "w": 23, + "h": 20 + } + }, + { + "filename": "coupon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 403, + "y": 102, + "w": 23, + "h": 19 + } + }, + { + "filename": "golden_mystic_ticket", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 403, + "y": 121, + "w": 23, + "h": 19 + } + }, + { + "filename": "mystic_ticket", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 403, + "y": 140, + "w": 23, + "h": 19 + } + }, + { + "filename": "dusk_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 382, + "y": 152, + "w": 21, + "h": 21 + } + }, + { + "filename": "pair_of_tickets", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 403, + "y": 159, + "w": 23, + "h": 19 + } + }, + { + "filename": "leftovers", "rotated": false, "trimmed": true, "sourceSize": { @@ -5437,15 +5269,15 @@ }, "spriteSourceSize": { "x": 8, - "y": 4, - "w": 16, - "h": 24 + "y": 5, + "w": 15, + "h": 22 }, "frame": { - "x": 387, - "y": 159, - "w": 16, - "h": 24 + "x": 193, + "y": 176, + "w": 15, + "h": 22 } }, { @@ -5463,180 +5295,12 @@ "h": 22 }, "frame": { - "x": 403, - "y": 161, + "x": 208, + "y": 174, "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": 385, - "y": 183, - "w": 21, - "h": 18 - } - }, - { - "filename": "metal_coat", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 19, - "h": 22 - }, - "frame": { - "x": 406, - "y": 183, - "w": 19, - "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": 386, - "y": 201, - "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": 406, - "y": 205, - "w": 19, - "h": 21 - } - }, - { - "filename": "blue_orb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 386, - "y": 221, - "w": 20, - "h": 20 - } - }, - { - "filename": "spell_tag", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 19, - "h": 21 - }, - "frame": { - "x": 406, - "y": 226, - "w": 19, - "h": 21 - } - }, - { - "filename": "everstone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 17 - }, - "frame": { - "x": 386, - "y": 241, - "w": 20, - "h": 17 - } - }, - { - "filename": "apicot_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 20 - }, - "frame": { - "x": 406, - "y": 247, - "w": 19, - "h": 20 - } - }, { "filename": "tm_steel", "rotated": false, @@ -5652,54 +5316,12 @@ "h": 22 }, "frame": { - "x": 364, - "y": 245, + "x": 230, + "y": 174, "w": 22, "h": 22 } }, - { - "filename": "gb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 386, - "y": 258, - "w": 20, - "h": 20 - } - }, - { - "filename": "candy_jar", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 20 - }, - "frame": { - "x": 406, - "y": 267, - "w": 19, - "h": 20 - } - }, { "filename": "tm_water", "rotated": false, @@ -5715,8 +5337,8 @@ "h": 22 }, "frame": { - "x": 154, - "y": 235, + "x": 252, + "y": 174, "w": 22, "h": 22 } @@ -5736,8 +5358,8 @@ "h": 22 }, "frame": { - "x": 154, - "y": 257, + "x": 274, + "y": 174, "w": 22, "h": 22 } @@ -5757,8 +5379,8 @@ "h": 22 }, "frame": { - "x": 154, - "y": 279, + "x": 296, + "y": 174, "w": 22, "h": 22 } @@ -5778,8 +5400,8 @@ "h": 22 }, "frame": { - "x": 156, - "y": 301, + "x": 318, + "y": 174, "w": 22, "h": 22 } @@ -5799,12 +5421,96 @@ "h": 22 }, "frame": { - "x": 156, - "y": 323, + "x": 340, + "y": 174, "w": 22, "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": 362, + "y": 174, + "w": 20, + "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": 382, + "y": 173, + "w": 21, + "h": 21 + } + }, + { + "filename": "black_glasses", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 403, + "y": 178, + "w": 23, + "h": 17 + } + }, + { + "filename": "metal_coat", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 19, + "h": 22 + }, + "frame": { + "x": 193, + "y": 198, + "w": 19, + "h": 22 + } + }, { "filename": "x_defense", "rotated": false, @@ -5820,8 +5526,8 @@ "h": 22 }, "frame": { - "x": 157, - "y": 345, + "x": 212, + "y": 196, "w": 22, "h": 22 } @@ -5841,8 +5547,8 @@ "h": 22 }, "frame": { - "x": 157, - "y": 367, + "x": 234, + "y": 196, "w": 22, "h": 22 } @@ -5862,8 +5568,8 @@ "h": 22 }, "frame": { - "x": 158, - "y": 389, + "x": 256, + "y": 196, "w": 22, "h": 22 } @@ -5883,35 +5589,14 @@ "h": 22 }, "frame": { - "x": 176, - "y": 236, + "x": 278, + "y": 196, "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": 176, - "y": 258, - "w": 21, - "h": 21 - } - }, - { - "filename": "poison_barb", + "filename": "sweet_apple", "rotated": false, "trimmed": true, "sourceSize": { @@ -5921,18 +5606,18 @@ "spriteSourceSize": { "x": 5, "y": 6, - "w": 21, + "w": 22, "h": 21 }, "frame": { - "x": 176, - "y": 279, - "w": 21, + "x": 300, + "y": 196, + "w": 22, "h": 21 } }, { - "filename": "potion", + "filename": "syrupy_apple", "rotated": false, "trimmed": true, "sourceSize": { @@ -5940,83 +5625,83 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 178, - "y": 300, - "w": 17, - "h": 23 - } - }, - { - "filename": "metronome", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 5, - "w": 17, - "h": 22 - }, - "frame": { - "x": 178, - "y": 323, - "w": 17, - "h": 22 - } - }, - { - "filename": "repel", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 - }, - "frame": { - "x": 179, - "y": 345, - "w": 16, - "h": 24 - } - }, - { - "filename": "golden_egg", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, + "x": 5, "y": 6, - "w": 17, + "w": 22, + "h": 21 + }, + "frame": { + "x": 322, + "y": 196, + "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": 344, + "y": 196, + "w": 22, + "h": 21 + } + }, + { + "filename": "quick_claw", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 21 + }, + "frame": { + "x": 193, + "y": 220, + "w": 19, + "h": 21 + } + }, + { + "filename": "deep_sea_scale", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, "h": 20 }, "frame": { - "x": 179, - "y": 369, - "w": 17, + "x": 212, + "y": 218, + "w": 22, "h": 20 } }, { - "filename": "soothe_bell", + "filename": "fairy_feather", "rotated": false, "trimmed": true, "sourceSize": { @@ -6024,20 +5709,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 22 + "x": 5, + "y": 7, + "w": 22, + "h": 20 }, "frame": { - "x": 180, - "y": 389, - "w": 17, - "h": 22 + "x": 234, + "y": 218, + "w": 22, + "h": 20 } }, { - "filename": "super_repel", + "filename": "malicious_armor", "rotated": false, "trimmed": true, "sourceSize": { @@ -6045,20 +5730,20 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 + "x": 5, + "y": 6, + "w": 22, + "h": 20 }, "frame": { - "x": 195, - "y": 300, - "w": 16, - "h": 24 + "x": 256, + "y": 218, + "w": 22, + "h": 20 } }, { - "filename": "unknown", + "filename": "tera_orb", "rotated": false, "trimmed": true, "sourceSize": { @@ -6066,16 +5751,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 16, - "h": 24 + "x": 5, + "y": 6, + "w": 22, + "h": 20 }, "frame": { - "x": 195, - "y": 324, - "w": 16, - "h": 24 + "x": 278, + "y": 218, + "w": 22, + "h": 20 } }, { @@ -6093,33 +5778,12 @@ "h": 21 }, "frame": { - "x": 195, - "y": 348, + "x": 300, + "y": 217, "w": 21, "h": 21 } }, - { - "filename": "magnet", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 196, - "y": 369, - "w": 20, - "h": 20 - } - }, { "filename": "zoom_lens", "rotated": false, @@ -6135,35 +5799,35 @@ "h": 21 }, "frame": { - "x": 197, - "y": 389, + "x": 321, + "y": 217, "w": 21, "h": 21 } }, { - "filename": "candy_overlay", + "filename": "black_sludge", "rotated": false, "trimmed": true, "sourceSize": { - "w": 32, - "h": 32 + "w": 24, + "h": 24 }, "spriteSourceSize": { - "x": 8, - "y": 12, - "w": 16, - "h": 15 + "x": 1, + "y": 2, + "w": 22, + "h": 19 }, "frame": { - "x": 197, - "y": 410, - "w": 16, - "h": 15 + "x": 342, + "y": 217, + "w": 22, + "h": 19 } }, { - "filename": "eviolite", + "filename": "spell_tag", "rotated": false, "trimmed": true, "sourceSize": { @@ -6171,16 +5835,58 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 15, - "h": 15 + "x": 7, + "y": 6, + "w": 19, + "h": 21 }, "frame": { - "x": 213, - "y": 410, - "w": 15, - "h": 15 + "x": 193, + "y": 241, + "w": 19, + "h": 21 + } + }, + { + "filename": "blunder_policy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 19 + }, + "frame": { + "x": 212, + "y": 238, + "w": 22, + "h": 19 + } + }, + { + "filename": "dubious_disc", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 22, + "h": 19 + }, + "frame": { + "x": 234, + "y": 238, + "w": 22, + "h": 19 } }, { @@ -6198,12 +5904,243 @@ "h": 19 }, "frame": { - "x": 198, - "y": 243, + "x": 256, + "y": 238, "w": 22, "h": 19 } }, + { + "filename": "burn_drive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 278, + "y": 238, + "w": 23, + "h": 17 + } + }, + { + "filename": "chill_drive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 301, + "y": 238, + "w": 23, + "h": 17 + } + }, + { + "filename": "soothe_bell", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 366, + "y": 196, + "w": 17, + "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": 383, + "y": 194, + "w": 20, + "h": 20 + } + }, + { + "filename": "douse_drive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 403, + "y": 195, + "w": 23, + "h": 17 + } + }, + { + "filename": "shock_drive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 403, + "y": 212, + "w": 23, + "h": 17 + } + }, + { + "filename": "blue_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 383, + "y": 214, + "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": 364, + "y": 218, + "w": 19, + "h": 20 + } + }, + { + "filename": "wise_glasses", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 403, + "y": 229, + "w": 23, + "h": 17 + } + }, + { + "filename": "everstone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 17 + }, + "frame": { + "x": 383, + "y": 234, + "w": 20, + "h": 17 + } + }, + { + "filename": "big_mushroom", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 19 + }, + "frame": { + "x": 324, + "y": 238, + "w": 19, + "h": 19 + } + }, { "filename": "metal_alloy", "rotated": false, @@ -6219,14 +6156,35 @@ "h": 19 }, "frame": { - "x": 220, - "y": 243, + "x": 343, + "y": 236, "w": 21, "h": 19 } }, { - "filename": "mb", + "filename": "candy_jar", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 20 + }, + "frame": { + "x": 364, + "y": 238, + "w": 19, + "h": 20 + } + }, + { + "filename": "gb", "rotated": false, "trimmed": true, "sourceSize": { @@ -6240,12 +6198,75 @@ "h": 20 }, "frame": { - "x": 197, - "y": 262, + "x": 383, + "y": 251, "w": 20, "h": 20 } }, + { + "filename": "magnet", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 403, + "y": 246, + "w": 20, + "h": 20 + } + }, + { + "filename": "masterpiece_teacup", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 21, + "h": 18 + }, + "frame": { + "x": 212, + "y": 257, + "w": 21, + "h": 18 + } + }, + { + "filename": "old_gateau", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 21, + "h": 18 + }, + "frame": { + "x": 233, + "y": 257, + "w": 21, + "h": 18 + } + }, { "filename": "sharp_meteorite", "rotated": false, @@ -6261,138 +6282,12 @@ "h": 18 }, "frame": { - "x": 197, - "y": 282, + "x": 254, + "y": 257, "w": 21, "h": 18 } }, - { - "filename": "pb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 217, - "y": 262, - "w": 20, - "h": 20 - } - }, - { - "filename": "big_mushroom", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 19 - }, - "frame": { - "x": 218, - "y": 282, - "w": 19, - "h": 19 - } - }, - { - "filename": "pb_gold", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 211, - "y": 301, - "w": 20, - "h": 20 - } - }, - { - "filename": "rb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 211, - "y": 321, - "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": 216, - "y": 341, - "w": 16, - "h": 24 - } - }, - { - "filename": "super_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 216, - "y": 365, - "w": 17, - "h": 23 - } - }, { "filename": "hard_stone", "rotated": false, @@ -6408,14 +6303,35 @@ "h": 20 }, "frame": { - "x": 218, - "y": 388, + "x": 193, + "y": 262, "w": 19, "h": 20 } }, { - "filename": "lucky_egg", + "filename": "mb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 190, + "y": 282, + "w": 20, + "h": 20 + } + }, + { + "filename": "golden_egg", "rotated": false, "trimmed": true, "sourceSize": { @@ -6429,117 +6345,12 @@ "h": 20 }, "frame": { - "x": 231, - "y": 301, + "x": 193, + "y": 302, "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": 231, - "y": 321, - "w": 18, - "h": 20 - } - }, - { - "filename": "smooth_meteorite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 232, - "y": 341, - "w": 20, - "h": 20 - } - }, - { - "filename": "strange_ball", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 233, - "y": 361, - "w": 20, - "h": 20 - } - }, - { - "filename": "ub", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 237, - "y": 381, - "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": 237, - "y": 401, - "w": 20, - "h": 19 - } - }, { "filename": "unremarkable_teacup", "rotated": false, @@ -6555,12 +6366,75 @@ "h": 18 }, "frame": { - "x": 241, - "y": 245, + "x": 212, + "y": 275, "w": 21, "h": 18 } }, + { + "filename": "lum_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 20, + "h": 19 + }, + "frame": { + "x": 233, + "y": 275, + "w": 20, + "h": 19 + } + }, + { + "filename": "pb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 253, + "y": 275, + "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": 210, + "y": 293, + "w": 20, + "h": 20 + } + }, { "filename": "power_herb", "rotated": false, @@ -6576,8 +6450,8 @@ "h": 19 }, "frame": { - "x": 237, - "y": 263, + "x": 230, + "y": 294, "w": 20, "h": 19 } @@ -6597,8 +6471,155 @@ "h": 19 }, "frame": { - "x": 237, - "y": 282, + "x": 250, + "y": 295, + "w": 20, + "h": 19 + } + }, + { + "filename": "mega_bracelet", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 16 + }, + "frame": { + "x": 210, + "y": 313, + "w": 20, + "h": 16 + } + }, + { + "filename": "rb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 230, + "y": 313, + "w": 20, + "h": 20 + } + }, + { + "filename": "smooth_meteorite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 250, + "y": 314, + "w": 20, + "h": 20 + } + }, + { + "filename": "strange_ball", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 201, + "y": 329, + "w": 20, + "h": 20 + } + }, + { + "filename": "ub", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 201, + "y": 349, + "w": 20, + "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": 203, + "y": 369, + "w": 18, + "h": 20 + } + }, + { + "filename": "white_herb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 24, + "h": 24 + }, + "spriteSourceSize": { + "x": 2, + "y": 3, + "w": 20, + "h": 19 + }, + "frame": { + "x": 221, + "y": 333, "w": 20, "h": 19 } @@ -6618,54 +6639,12 @@ "h": 19 }, "frame": { - "x": 248, - "y": 301, + "x": 221, + "y": 352, "w": 19, "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": 249, - "y": 320, - "w": 18, - "h": 19 - } - }, - { - "filename": "white_herb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 24, - "h": 24 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 20, - "h": 19 - }, - "frame": { - "x": 252, - "y": 339, - "w": 20, - "h": 19 - } - }, { "filename": "wl_ability_urge", "rotated": false, @@ -6681,117 +6660,12 @@ "h": 18 }, "frame": { - "x": 253, - "y": 358, + "x": 221, + "y": 371, "w": 20, "h": 18 } }, - { - "filename": "baton", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 7, - "w": 18, - "h": 18 - }, - "frame": { - "x": 257, - "y": 376, - "w": 18, - "h": 18 - } - }, - { - "filename": "candy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 11, - "w": 18, - "h": 18 - }, - "frame": { - "x": 257, - "y": 394, - "w": 18, - "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": 257, - "y": 263, - "w": 18, - "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": 257, - "y": 281, - "w": 18, - "h": 18 - } - }, - { - "filename": "prism_scale", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 15, - "h": 15 - }, - "frame": { - "x": 262, - "y": 248, - "w": 15, - "h": 15 - } - }, { "filename": "wl_antidote", "rotated": false, @@ -6807,12 +6681,117 @@ "h": 18 }, "frame": { - "x": 277, - "y": 248, + "x": 241, + "y": 334, "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": 240, + "y": 352, + "w": 18, + "h": 19 + } + }, + { + "filename": "dark_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 241, + "y": 371, + "w": 18, + "h": 18 + } + }, + { + "filename": "relic_gold", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 9, + "y": 11, + "w": 15, + "h": 11 + }, + "frame": { + "x": 203, + "y": 389, + "w": 15, + "h": 11 + } + }, + { + "filename": "lucky_egg", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 17, + "h": 20 + }, + "frame": { + "x": 205, + "y": 400, + "w": 17, + "h": 20 + } + }, + { + "filename": "flame_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 7, + "w": 18, + "h": 18 + }, + "frame": { + "x": 261, + "y": 334, + "w": 18, + "h": 18 + } + }, { "filename": "wl_awakening", "rotated": false, @@ -6828,8 +6807,8 @@ "h": 18 }, "frame": { - "x": 297, - "y": 248, + "x": 258, + "y": 352, "w": 20, "h": 18 } @@ -6849,8 +6828,8 @@ "h": 18 }, "frame": { - "x": 275, - "y": 266, + "x": 259, + "y": 370, "w": 20, "h": 18 } @@ -6870,344 +6849,8 @@ "h": 18 }, "frame": { - "x": 295, - "y": 266, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_custom_thief", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 275, - "y": 284, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_elixir", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 295, - "y": 284, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_ether", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 317, - "y": 249, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_full_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 337, - "y": 249, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_full_restore", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 315, - "y": 267, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_guard_spec", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 335, - "y": 267, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_hyper_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 315, - "y": 285, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_ice_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 335, - "y": 285, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_item_drop", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 355, - "y": 267, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_item_urge", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 355, - "y": 285, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_max_elixir", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 267, - "y": 302, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_max_ether", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 287, - "y": 302, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_max_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 267, - "y": 320, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_max_revive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 287, - "y": 320, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_paralyze_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 272, - "y": 338, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 273, - "y": 356, + "x": 222, + "y": 389, "w": 20, "h": 18 } @@ -7227,12 +6870,54 @@ "h": 18 }, "frame": { - "x": 275, - "y": 374, + "x": 242, + "y": 389, "w": 18, "h": 18 } }, + { + "filename": "wl_custom_thief", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 260, + "y": 388, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_elixir", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 222, + "y": 407, + "w": 20, + "h": 18 + } + }, { "filename": "light_stone", "rotated": false, @@ -7248,12 +6933,201 @@ "h": 18 }, "frame": { - "x": 275, - "y": 392, + "x": 242, + "y": 407, "w": 18, "h": 18 } }, + { + "filename": "wl_ether", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 260, + "y": 406, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_full_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 403, + "y": 266, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_full_restore", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 343, + "y": 255, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_guard_spec", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 363, + "y": 258, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_hyper_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 383, + "y": 271, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_ice_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 403, + "y": 284, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_item_drop", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 278, + "y": 255, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_item_urge", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 298, + "y": 255, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_max_elixir", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 318, + "y": 257, + "w": 20, + "h": 18 + } + }, { "filename": "mystery_egg", "rotated": false, @@ -7269,8 +7143,8 @@ "h": 18 }, "frame": { - "x": 292, - "y": 338, + "x": 270, + "y": 295, "w": 16, "h": 18 } @@ -7290,12 +7164,117 @@ "h": 18 }, "frame": { - "x": 293, - "y": 356, + "x": 270, + "y": 313, "w": 18, "h": 18 } }, + { + "filename": "wl_max_ether", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 279, + "y": 331, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_max_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 279, + "y": 349, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_max_revive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 279, + "y": 367, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_paralyze_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 280, + "y": 385, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 280, + "y": 403, + "w": 20, + "h": 18 + } + }, { "filename": "wl_reset_urge", "rotated": false, @@ -7311,8 +7290,8 @@ "h": 18 }, "frame": { - "x": 293, - "y": 374, + "x": 273, + "y": 275, "w": 20, "h": 18 } @@ -7333,7 +7312,7 @@ }, "frame": { "x": 293, - "y": 392, + "y": 273, "w": 20, "h": 18 } @@ -7353,14 +7332,14 @@ "h": 18 }, "frame": { - "x": 307, - "y": 303, + "x": 313, + "y": 275, "w": 20, "h": 18 } }, { - "filename": "relic_band", + "filename": "abomasite", "rotated": false, "trimmed": true, "sourceSize": { @@ -7368,15 +7347,15 @@ "h": 32 }, "spriteSourceSize": { - "x": 7, - "y": 9, - "w": 17, + "x": 8, + "y": 8, + "w": 16, "h": 16 }, "frame": { - "x": 307, - "y": 321, - "w": 17, + "x": 286, + "y": 293, + "w": 16, "h": 16 } }, @@ -7395,12 +7374,33 @@ "h": 16 }, "frame": { - "x": 327, - "y": 303, + "x": 288, + "y": 309, "w": 16, "h": 16 } }, + { + "filename": "relic_band", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 9, + "w": 17, + "h": 16 + }, + "frame": { + "x": 302, + "y": 293, + "w": 17, + "h": 16 + } + }, { "filename": "aerodactylite", "rotated": false, @@ -7416,8 +7416,8 @@ "h": 16 }, "frame": { - "x": 343, - "y": 303, + "x": 304, + "y": 309, "w": 16, "h": 16 } @@ -7437,8 +7437,8 @@ "h": 16 }, "frame": { - "x": 359, - "y": 303, + "x": 319, + "y": 293, "w": 16, "h": 16 } @@ -7458,8 +7458,8 @@ "h": 16 }, "frame": { - "x": 308, - "y": 337, + "x": 320, + "y": 309, "w": 16, "h": 16 } @@ -7479,8 +7479,8 @@ "h": 16 }, "frame": { - "x": 311, - "y": 353, + "x": 299, + "y": 325, "w": 16, "h": 16 } @@ -7500,8 +7500,8 @@ "h": 16 }, "frame": { - "x": 313, - "y": 369, + "x": 299, + "y": 341, "w": 16, "h": 16 } @@ -7521,8 +7521,8 @@ "h": 16 }, "frame": { - "x": 313, - "y": 385, + "x": 315, + "y": 325, "w": 16, "h": 16 } @@ -7542,8 +7542,8 @@ "h": 16 }, "frame": { - "x": 313, - "y": 401, + "x": 299, + "y": 357, "w": 16, "h": 16 } @@ -7563,8 +7563,8 @@ "h": 16 }, "frame": { - "x": 375, - "y": 278, + "x": 315, + "y": 341, "w": 16, "h": 16 } @@ -7584,8 +7584,8 @@ "h": 16 }, "frame": { - "x": 375, - "y": 294, + "x": 315, + "y": 357, "w": 16, "h": 16 } @@ -7605,8 +7605,8 @@ "h": 16 }, "frame": { - "x": 375, - "y": 310, + "x": 333, + "y": 275, "w": 16, "h": 16 } @@ -7626,8 +7626,8 @@ "h": 16 }, "frame": { - "x": 324, - "y": 321, + "x": 335, + "y": 291, "w": 16, "h": 16 } @@ -7647,8 +7647,8 @@ "h": 16 }, "frame": { - "x": 324, - "y": 337, + "x": 336, + "y": 307, "w": 16, "h": 16 } @@ -7668,8 +7668,8 @@ "h": 16 }, "frame": { - "x": 327, - "y": 353, + "x": 331, + "y": 325, "w": 16, "h": 16 } @@ -7689,8 +7689,8 @@ "h": 16 }, "frame": { - "x": 340, - "y": 319, + "x": 331, + "y": 341, "w": 16, "h": 16 } @@ -7710,8 +7710,8 @@ "h": 16 }, "frame": { - "x": 340, - "y": 335, + "x": 331, + "y": 357, "w": 16, "h": 16 } @@ -7731,8 +7731,8 @@ "h": 16 }, "frame": { - "x": 356, - "y": 319, + "x": 300, + "y": 373, "w": 16, "h": 16 } @@ -7752,8 +7752,8 @@ "h": 16 }, "frame": { - "x": 356, - "y": 335, + "x": 300, + "y": 389, "w": 16, "h": 16 } @@ -7773,8 +7773,8 @@ "h": 16 }, "frame": { - "x": 329, - "y": 369, + "x": 316, + "y": 373, "w": 16, "h": 16 } @@ -7794,8 +7794,8 @@ "h": 16 }, "frame": { - "x": 329, - "y": 385, + "x": 300, + "y": 405, "w": 16, "h": 16 } @@ -7815,8 +7815,8 @@ "h": 16 }, "frame": { - "x": 329, - "y": 401, + "x": 316, + "y": 389, "w": 16, "h": 16 } @@ -7836,8 +7836,8 @@ "h": 16 }, "frame": { - "x": 343, - "y": 351, + "x": 316, + "y": 405, "w": 16, "h": 16 } @@ -7857,8 +7857,8 @@ "h": 16 }, "frame": { - "x": 372, - "y": 326, + "x": 332, + "y": 373, "w": 16, "h": 16 } @@ -7878,8 +7878,8 @@ "h": 16 }, "frame": { - "x": 359, - "y": 351, + "x": 332, + "y": 389, "w": 16, "h": 16 } @@ -7899,8 +7899,8 @@ "h": 16 }, "frame": { - "x": 345, - "y": 367, + "x": 332, + "y": 405, "w": 16, "h": 16 } @@ -7920,8 +7920,8 @@ "h": 16 }, "frame": { - "x": 345, - "y": 383, + "x": 347, + "y": 323, "w": 16, "h": 16 } @@ -7941,8 +7941,8 @@ "h": 16 }, "frame": { - "x": 345, - "y": 399, + "x": 347, + "y": 339, "w": 16, "h": 16 } @@ -7962,8 +7962,8 @@ "h": 16 }, "frame": { - "x": 361, - "y": 367, + "x": 347, + "y": 355, "w": 16, "h": 16 } @@ -7983,8 +7983,8 @@ "h": 16 }, "frame": { - "x": 361, - "y": 383, + "x": 348, + "y": 371, "w": 16, "h": 16 } @@ -8004,8 +8004,8 @@ "h": 16 }, "frame": { - "x": 361, - "y": 399, + "x": 348, + "y": 387, "w": 16, "h": 16 } @@ -8025,12 +8025,33 @@ "h": 16 }, "frame": { - "x": 375, - "y": 342, + "x": 348, + "y": 403, "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": 349, + "y": 276, + "w": 15, + "h": 15 + } + }, { "filename": "metagrossite", "rotated": false, @@ -8046,8 +8067,8 @@ "h": 16 }, "frame": { - "x": 388, - "y": 326, + "x": 364, + "y": 276, "w": 16, "h": 16 } @@ -8067,8 +8088,8 @@ "h": 16 }, "frame": { - "x": 391, - "y": 342, + "x": 364, + "y": 292, "w": 16, "h": 16 } @@ -8088,8 +8109,8 @@ "h": 16 }, "frame": { - "x": 377, - "y": 358, + "x": 380, + "y": 289, "w": 16, "h": 16 } @@ -8109,8 +8130,8 @@ "h": 16 }, "frame": { - "x": 377, - "y": 374, + "x": 380, + "y": 305, "w": 16, "h": 16 } @@ -8130,8 +8151,8 @@ "h": 16 }, "frame": { - "x": 377, - "y": 390, + "x": 364, + "y": 308, "w": 16, "h": 16 } @@ -8151,8 +8172,8 @@ "h": 16 }, "frame": { - "x": 393, - "y": 358, + "x": 363, + "y": 324, "w": 16, "h": 16 } @@ -8172,8 +8193,8 @@ "h": 16 }, "frame": { - "x": 409, - "y": 287, + "x": 363, + "y": 340, "w": 16, "h": 16 } @@ -8193,8 +8214,8 @@ "h": 16 }, "frame": { - "x": 393, - "y": 374, + "x": 396, + "y": 302, "w": 16, "h": 16 } @@ -8214,8 +8235,8 @@ "h": 16 }, "frame": { - "x": 409, - "y": 303, + "x": 380, + "y": 321, "w": 16, "h": 16 } @@ -8235,8 +8256,8 @@ "h": 16 }, "frame": { - "x": 393, - "y": 390, + "x": 396, + "y": 318, "w": 16, "h": 16 } @@ -8256,8 +8277,8 @@ "h": 16 }, "frame": { - "x": 409, - "y": 319, + "x": 379, + "y": 337, "w": 16, "h": 16 } @@ -8277,8 +8298,8 @@ "h": 16 }, "frame": { - "x": 409, - "y": 335, + "x": 396, + "y": 334, "w": 16, "h": 16 } @@ -8298,8 +8319,8 @@ "h": 16 }, "frame": { - "x": 409, - "y": 351, + "x": 379, + "y": 353, "w": 16, "h": 16 } @@ -8319,8 +8340,8 @@ "h": 16 }, "frame": { - "x": 409, - "y": 367, + "x": 395, + "y": 350, "w": 16, "h": 16 } @@ -8340,8 +8361,8 @@ "h": 16 }, "frame": { - "x": 409, - "y": 383, + "x": 395, + "y": 366, "w": 16, "h": 16 } @@ -8361,8 +8382,8 @@ "h": 16 }, "frame": { - "x": 409, - "y": 399, + "x": 364, + "y": 382, "w": 16, "h": 16 } @@ -8382,8 +8403,8 @@ "h": 16 }, "frame": { - "x": 377, - "y": 406, + "x": 364, + "y": 398, "w": 16, "h": 16 } @@ -8403,8 +8424,8 @@ "h": 16 }, "frame": { - "x": 393, - "y": 406, + "x": 380, + "y": 382, "w": 16, "h": 16 } @@ -8424,8 +8445,8 @@ "h": 16 }, "frame": { - "x": 391, - "y": 287, + "x": 380, + "y": 398, "w": 16, "h": 16 } @@ -8436,6 +8457,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4d7c13d737ed237c9bae1222ce873452:256c2ba728cb839ce479bac6b53a7ed1:110e074689c9edd2c54833ce2e4d9270$" + "smartupdate": "$TexturePacker:SmartUpdate:06a43a858ac0838c2d5400a7c8e124da:6c9201d0b6d07fc299c0fa41c226a22d:110e074689c9edd2c54833ce2e4d9270$" } } diff --git a/public/images/items.png b/public/images/items.png index 51cdae6cfe1..2bf9a012139 100644 Binary files a/public/images/items.png and b/public/images/items.png differ diff --git a/public/images/items/old_gateau.png b/public/images/items/old_gateau.png new file mode 100644 index 00000000000..c910e90f101 Binary files /dev/null and b/public/images/items/old_gateau.png differ diff --git a/public/images/mystery-encounters/buoy.png b/public/images/mystery-encounters/buoy.png index dee71943650..fb957ac29f0 100644 Binary files a/public/images/mystery-encounters/buoy.png and b/public/images/mystery-encounters/buoy.png differ diff --git a/public/images/mystery-encounters/girawitch.json b/public/images/mystery-encounters/girawitch.json new file mode 100644 index 00000000000..98830a00a72 --- /dev/null +++ b/public/images/mystery-encounters/girawitch.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "girawitch.png", + "format": "RGBA8888", + "size": { + "w": 46, + "h": 76 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 46, + "h": 76 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 46, + "h": 76 + }, + "frame": { + "x": 0, + "y": 0, + "w": 46, + "h": 76 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:e68bbc186f511d505c53b2beec3c3741:7108795fc29d953a1d3729ad93d70936:1661aeeeb2f0e4561c644aff254770b3$" + } +} diff --git a/public/images/mystery-encounters/girawitch.png b/public/images/mystery-encounters/girawitch.png new file mode 100644 index 00000000000..a1cc7e8448d Binary files /dev/null and b/public/images/mystery-encounters/girawitch.png differ diff --git a/public/images/mystery-encounters/starry_background.png b/public/images/mystery-encounters/starry_background.png new file mode 100644 index 00000000000..759c624ddc1 Binary files /dev/null and b/public/images/mystery-encounters/starry_background.png differ diff --git a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts index 5f0d180ccab..4f67905235e 100644 --- a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts +++ b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts @@ -6,8 +6,7 @@ import { leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups"; -import Pokemon, { EnemyPokemon } from "#app/field/pokemon"; +import Pokemon, { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon"; import { BerryModifierType, getPartyLuckValue, @@ -21,17 +20,17 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "#app/battle-scene"; import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter"; -import { MoveRequirement } from "../mystery-encounter-requirements"; import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { getPokemonNameWithAffix } from "#app/messages"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { TrainerSlot } from "#app/data/trainer-config"; -import { applyModifierTypeToPlayerPokemon, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { applyModifierTypeToPlayerPokemon, getHighestStatPlayerPokemon, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import PokemonData from "#app/system/pokemon-data"; import { BerryModifier } from "#app/modifier/modifier"; import i18next from "#app/plugins/i18n"; import { BerryType } from "#enums/berry-type"; +import { Stat } from "#enums/stat"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounter:berriesAbound"; @@ -148,6 +147,7 @@ export const BerriesAboundEncounter: IMysteryEncounter = // Calculate boss mon const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, scene.currentBattle.waveIndex, 0, getPartyLuckValue(scene.getParty()), true); const bossPokemon = new EnemyPokemon(scene, bossSpecies, scene.currentBattle.waveIndex, TrainerSlot.NONE, true, null); + encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon)); const config: EnemyPartyConfig = { levelAdditiveMultiplier: 1, pokemonConfigs: [{ @@ -159,11 +159,11 @@ export const BerriesAboundEncounter: IMysteryEncounter = encounter.enemyPartyConfigs = [config]; // Calculate the number of extra berries that player receives - // 10-60 GREAT, 60-110 ULTRA, 110-160 ROGUE, 160-180 MASTER + // 10-40: 2, 40-120: 4, 120-160: 5, 160-180: 7 const numBerries = scene.currentBattle.waveIndex > 160 ? 7 - : scene.currentBattle.waveIndex > 110 ? 5 - : scene.currentBattle.waveIndex > 60 ? 4 : 2; + : scene.currentBattle.waveIndex > 120 ? 5 + : scene.currentBattle.waveIndex > 40 ? 4 : 2; regenerateModifierPoolThresholds(scene.getParty(), ModifierPoolType.PLAYER, 0); encounter.misc = { numBerries }; @@ -178,15 +178,11 @@ export const BerriesAboundEncounter: IMysteryEncounter = isPokemon: true }); - // If player has a stealing move, they succeed automatically - encounter.options[1].meetsRequirements(scene); - const primaryPokemon = encounter.options[1].primaryPokemon; - if (primaryPokemon) { - // Use primaryPokemon to execute the thievery - encounter.options[1].dialogue.buttonTooltip = `${namespace}.option.2.tooltip_special`; - } else { - encounter.options[1].dialogue.buttonTooltip = `${namespace}.option.2.tooltip`; - } + // Get fastest party pokemon for option 2 + const fastestPokemon = getHighestStatPlayerPokemon(scene, Stat.SPD, true); + encounter.misc.fastestPokemon = fastestPokemon; + encounter.misc.enemySpeed = bossPokemon.getStat(Stat.SPD); + encounter.setDialogueToken("fastestPokemon", fastestPokemon.getNameToRender()); return true; }) @@ -232,63 +228,68 @@ export const BerriesAboundEncounter: IMysteryEncounter = ) .withOption( new MysteryEncounterOptionBuilder() - .withOptionMode(MysteryEncounterOptionMode.DEFAULT_OR_SPECIAL) - .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically + .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ buttonLabel: `${namespace}.option.2.label`, - buttonTooltip: `${namespace}.option.2.tooltip`, + buttonTooltip: `${namespace}.option.2.tooltip` }) .withOptionPhase(async (scene: BattleScene) => { - // Pick steal + // Pick race for berries const encounter = scene.currentBattle.mysteryEncounter; + const fastestPokemon = encounter.misc.fastestPokemon; + const enemySpeed = encounter.misc.enemySpeed; + const speedDiff = fastestPokemon.getStat(Stat.SPD) / enemySpeed; const numBerries = encounter.misc.numBerries; - const doBerryRewards = async () => { - const berryText = numBerries + " " + i18next.t(`${namespace}.berries`); - - scene.playSound("item_fanfare"); - queueEncounterMessage(scene, i18next.t("battle:rewardGain", { modifierName: berryText })); - - // Generate a random berry and give it to the first Pokemon with room for it - for (let i = 0; i < numBerries; i++) { - await tryGiveBerry(scene); - } - }; - const shopOptions: ModifierTypeOption[] = []; for (let i = 0; i < 5; i++) { // Generate shop berries shopOptions.push(generateModifierTypeOption(scene, modifierTypes.BERRY)); } - setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, null, doBerryRewards); + if (speedDiff < 1) { + // Caught and attacked by boss, gets +1 to all stats at start of fight + const doBerryRewards = async () => { + const berryText = numBerries + " " + i18next.t(`${namespace}.berries`); - // If player has a stealing move, they succeed automatically - const primaryPokemon = encounter.options[1].primaryPokemon; - if (primaryPokemon) { - // Use primaryPokemon to execute the thievery - await showEncounterText(scene, `${namespace}.option.2.special_result`); - setEncounterExp(scene, primaryPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs[0].species.baseExp, true); - leaveEncounterWithoutBattle(scene); - return; - } + scene.playSound("item_fanfare"); + queueEncounterMessage(scene, i18next.t("battle:rewardGain", { modifierName: berryText })); + + // Generate a random berry and give it to the first Pokemon with room for it + for (let i = 0; i < numBerries; i++) { + await tryGiveBerry(scene); + } + }; - const roll = randSeedInt(16); - if (roll > 6) { - // Noticed and attacked by boss, gets +1 to all stats at start of fight (62.5%) const config = scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]; config.pokemonConfigs[0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON]; config.pokemonConfigs[0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => { - pokemon.scene.currentBattle.mysteryEncounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(pokemon)); - queueEncounterMessage(pokemon.scene, `${namespace}option.2.boss_enraged`); + queueEncounterMessage(pokemon.scene, `${namespace}.option.2.boss_enraged`); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD], 1)); }; - await showEncounterText(scene, `${namespace}.option.2.bad_result`); + setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, null, doBerryRewards); + await showEncounterText(scene, `${namespace}.option.2.selected_bad`); await initBattleWithEnemyConfig(scene, config); + return; } else { - // Steal item (37.5%) - // Display result message then proceed to rewards - await showEncounterText(scene, `${namespace}.option.2.good_result`); + // Gains 1 berry for every 10% faster the player's pokemon is than the enemy, up to a max of numBerries, minimum of 1 + const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1)/0.1), numBerries), 1); + encounter.setDialogueToken("numBerries", String(numBerriesGrabbed)); + const doFasterBerryRewards = async () => { + const berryText = numBerriesGrabbed + " " + i18next.t(`${namespace}.berries`); + + scene.playSound("item_fanfare"); + queueEncounterMessage(scene, i18next.t("battle:rewardGain", { modifierName: berryText })); + + // Generate a random berry and give it to the first Pokemon with room for it (trying to give to fastest first) + for (let i = 0; i < numBerriesGrabbed; i++) { + await tryGiveBerry(scene, fastestPokemon); + } + }; + + setEncounterExp(scene, fastestPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs[0].species.baseExp); + setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, null, doFasterBerryRewards); + await showEncounterText(scene, `${namespace}.option.2.selected`); leaveEncounterWithoutBattle(scene); } }) @@ -312,12 +313,23 @@ export const BerriesAboundEncounter: IMysteryEncounter = ) .build(); -async function tryGiveBerry(scene: BattleScene) { +async function tryGiveBerry(scene: BattleScene, prioritizedPokemon?: PlayerPokemon) { const berryType = randSeedInt(Object.keys(BerryType).filter(s => !isNaN(Number(s))).length) as BerryType; const berry = generateModifierTypeOption(scene, modifierTypes.BERRY, [berryType]).type as BerryModifierType; const party = scene.getParty(); + // Will try to apply to prioritized pokemon first, then do normal application method if it fails + if (prioritizedPokemon) { + const heldBerriesOfType = scene.findModifier(m => m instanceof BerryModifier + && m.pokemonId === prioritizedPokemon.id && (m as BerryModifier).berryType === berryType, true) as BerryModifier; + + if (!heldBerriesOfType || heldBerriesOfType.getStackCount() < heldBerriesOfType.getMaxStackCount(scene)) { + await applyModifierTypeToPlayerPokemon(scene, prioritizedPokemon, berry); + return; + } + } + // Iterate over the party until berry was successfully given for (const pokemon of party) { const heldBerriesOfType = scene.findModifier(m => m instanceof BerryModifier 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 a60c4ff4c05..2f000742ea9 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts @@ -1,4 +1,3 @@ -import { BattleStat } from "#app/data/battle-stat"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; import { EnemyPartyConfig, @@ -7,7 +6,7 @@ import { setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups"; -import Pokemon, { EnemyPokemon } from "#app/field/pokemon"; +import { EnemyPokemon } from "#app/field/pokemon"; import { ModifierTier } from "#app/modifier/modifier-tier"; import { getPartyLuckValue, @@ -16,15 +15,10 @@ import { ModifierTypeOption, regenerateModifierPoolThresholds, } from "#app/modifier/modifier-type"; -import { StatChangePhase } from "#app/phases"; -import { randSeedInt } from "#app/utils"; -import { BattlerTagType } from "#enums/battler-tag-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "#app/battle-scene"; import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter"; import { MoveRequirement } from "../mystery-encounter-requirements"; -import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; -import { getPokemonNameWithAffix } from "#app/messages"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { TrainerSlot } from "#app/data/trainer-config"; @@ -68,17 +62,21 @@ export const FightOrFlightEncounter: IMysteryEncounter = encounter.enemyPartyConfigs = [config]; // Calculate item - // 10-60 GREAT, 60-110 ULTRA, 110-160 ROGUE, 160-180 MASTER + // 10-40 GREAT, 60-120 ULTRA, 120-160 ROGUE, 160-180 MASTER const tier = scene.currentBattle.waveIndex > 160 ? ModifierTier.MASTER - : scene.currentBattle.waveIndex > 110 + : scene.currentBattle.waveIndex > 120 ? ModifierTier.ROGUE - : scene.currentBattle.waveIndex > 60 + : scene.currentBattle.waveIndex > 40 ? ModifierTier.ULTRA : ModifierTier.GREAT; regenerateModifierPoolThresholds(scene.getParty(), ModifierPoolType.PLAYER, 0); - const item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier] })[0]; + let item: ModifierTypeOption; + // TMs excluded from possible rewards as they're too swingy in value for a singular item reward + while (!item || item.type.id.includes("TM_")) { + item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0]; + } encounter.setDialogueToken("itemName", item.type.name); encounter.misc = item; @@ -105,16 +103,6 @@ export const FightOrFlightEncounter: IMysteryEncounter = }, ]; - // If player has a stealing move, they succeed automatically - encounter.options[1].meetsRequirements(scene); - const primaryPokemon = encounter.options[1].primaryPokemon; - if (primaryPokemon) { - // Use primaryPokemon to execute the thievery - encounter.options[1].dialogue.buttonTooltip = `${namespace}.option.2.tooltip_special`; - } else { - encounter.options[1].dialogue.buttonTooltip = `${namespace}.option.2.tooltip`; - } - return true; }) .withTitle(`${namespace}.title`) @@ -140,11 +128,17 @@ export const FightOrFlightEncounter: IMysteryEncounter = ) .withOption( new MysteryEncounterOptionBuilder() - .withOptionMode(MysteryEncounterOptionMode.DEFAULT_OR_SPECIAL) + .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically .withDialogue({ buttonLabel: `${namespace}.option.2.label`, buttonTooltip: `${namespace}.option.2.tooltip`, + disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`, + selected: [ + { + text: `${namespace}.option.2.selected` + } + ] }) .withOptionPhase(async (scene: BattleScene) => { // Pick steal @@ -152,34 +146,10 @@ export const FightOrFlightEncounter: IMysteryEncounter = const item = scene.currentBattle.mysteryEncounter.misc as ModifierTypeOption; setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false }); - // If player has a stealing move, they succeed automatically + // Use primaryPokemon to execute the thievery const primaryPokemon = encounter.options[1].primaryPokemon; - if (primaryPokemon) { - // Use primaryPokemon to execute the thievery - await showEncounterText(scene, `${namespace}.option.2.special_result`); - setEncounterExp(scene, primaryPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs[0].species.baseExp, true); - leaveEncounterWithoutBattle(scene); - return; - } - - const roll = randSeedInt(16); - if (roll > 6) { - // Noticed and attacked by boss, gets +1 to all stats at start of fight (62.5%) - const config = scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]; - config.pokemonConfigs[0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON]; - config.pokemonConfigs[0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => { - pokemon.scene.currentBattle.mysteryEncounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(pokemon)); - queueEncounterMessage(pokemon.scene, `${namespace}option.2.boss_enraged`); - pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD], 1)); - }; - await showEncounterText(scene, `${namespace}.option.2.bad_result`); - await initBattleWithEnemyConfig(scene, config); - } else { - // Steal item (37.5%) - // Display result message then proceed to rewards - await showEncounterText(scene, `${namespace}.option.2.good_result`); - leaveEncounterWithoutBattle(scene); - } + setEncounterExp(scene, primaryPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs[0].species.baseExp); + leaveEncounterWithoutBattle(scene); }) .build() ) diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts new file mode 100644 index 00000000000..d556a3b0c82 --- /dev/null +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -0,0 +1,541 @@ +import { Type } from "#app/data/type"; +import { MysteryEncounterType } from "#enums/mystery-encounter-type"; +import { Species } from "#enums/species"; +import BattleScene from "#app/battle-scene"; +import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter"; +import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option"; +import { leaveEncounterWithoutBattle, setEncounterRewards, } from "../utils/encounter-phase-utils"; +import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; +import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; +import Pokemon, { PlayerPokemon, PokemonMove } from "#app/field/pokemon"; +import { IntegerHolder, randSeedInt, randSeedShuffle } from "#app/utils"; +import PokemonSpecies, { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species"; +import { HiddenAbilityRateBoosterModifier, PokemonBaseStatTotalModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier"; +import { achvs } from "#app/system/achv"; +import { speciesEggMoves } from "#app/data/egg-moves"; +import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data"; +import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; +import { modifierTypes } from "#app/modifier/modifier-type"; +import { Stat } from "#app/data/pokemon-stat"; +import i18next from "#app/plugins/i18n"; +import { doPokemonTransformationSequence, TransformationScreenPosition } from "#app/data/mystery-encounters/utils/encounter-transformation-sequence"; +import { getLevelTotalExp } from "#app/data/exp"; + +/** i18n namespace for encounter */ +const namespace = "mysteryEncounter:weirdDream"; + +/** Exclude Ultra Beasts (inludes Cosmog/Solgaleo/Lunala/Necrozma), Paradox (includes Miraidon/Koraidon), Eternatus, Urshifu, the Poison Chain trio, Ogerpon */ +const excludedPokemon = [ + Species.ETERNATUS, + /** UBs */ + Species.NIHILEGO, + Species.BUZZWOLE, + Species.PHEROMOSA, + Species.XURKITREE, + Species.CELESTEELA, + Species.KARTANA, + Species.GUZZLORD, + Species.POIPOLE, + Species.NAGANADEL, + Species.STAKATAKA, + Species.BLACEPHALON, + /** Paradox */ + Species.GREAT_TUSK, + Species.SCREAM_TAIL, + Species.BRUTE_BONNET, + Species.FLUTTER_MANE, + Species.SLITHER_WING, + Species.SANDY_SHOCKS, + Species.ROARING_MOON, + Species.WALKING_WAKE, + Species.GOUGING_FIRE, + Species.RAGING_BOLT, + Species.IRON_TREADS, + Species.IRON_BUNDLE, + Species.IRON_HANDS, + Species.IRON_JUGULIS, + Species.IRON_MOTH, + Species.IRON_THORNS, + Species.IRON_VALIANT, + Species.IRON_LEAVES, + Species.IRON_BOULDER, + Species.IRON_CROWN, + /** These are banned so they don't appear in the < 570 BST pool */ + Species.URSHIFU, + Species.CUBCHOO, + Species.OKIDOGI, + Species.MUNKIDORI, + Species.FEZANDIPITI, + Species.OGERPON, + Species.CALYREX, + Species.TYPE_NULL, + Species.TERAPAGOS, + Species.COSMOG, + Species.COSMOEM, +]; + +/** + * Weird Dream encounter. + * @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/137 | GitHub Issue #137} + * @see For biome requirements check {@linkcode mysteryEncountersByBiome} + */ +export const WeirdDreamEncounter: IMysteryEncounter = + MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.WEIRD_DREAM) + .withEncounterTier(MysteryEncounterTier.ROGUE) + .withIntroSpriteConfigs([ + { + spriteKey: "girawitch", + fileRoot: "mystery-encounters", + hasShadow: false, + y: 4 + }, + ]) + .withIntroDialogue([ + { + text: `${namespace}.intro`, + }, + { + speaker: `${namespace}.speaker`, + text: `${namespace}.intro_dialogue`, + }, + ]) + .withSceneWaveRangeRequirement(10, 180) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) + .withOnInit((scene: BattleScene) => { + scene.loadBgm("mystery_encounter_weird_dream", "mystery_encounter_weird_dream.mp3"); + return true; + }) + .withOnVisualsStart((scene: BattleScene) => { + // Change the bgm + scene.fadeOutBgm(3000, false); + scene.time.delayedCall(3000, () => { + scene.playBgm("mystery_encounter_weird_dream"); + }); + + return true; + }) + .withOption( + new MysteryEncounterOptionBuilder() + .withOptionMode(MysteryEncounterOptionMode.DEFAULT) + .withHasDexProgress(true) + .withDialogue({ + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, + selected: [ + { + text: `${namespace}.option.1.selected`, + } + ], + }) + .withPreOptionPhase(async (scene: BattleScene) => { + // Play the animation as the player goes through the dialogue + scene.time.delayedCall(1000, () => { + doShowDreamBackground(scene); + }); + + // Calculate all the newly transformed Pokemon and begin asset load + const teamTransformations = getTeamTransformations(scene); + const loadAssets = teamTransformations.map(t => (t.newPokemon as PlayerPokemon).loadAssets()); + scene.currentBattle.mysteryEncounter.misc = { + teamTransformations, + loadAssets + }; + }) + .withOptionPhase(async (scene: BattleScene) => { + // Starts cutscene dialogue, but does not await so that cutscene plays as player goes through dialogue + const cutsceneDialoguePromise = showEncounterText(scene, `${namespace}.option.1.cutscene`); + + // Change the entire player's party + // Wait for all new Pokemon assets to be loaded before showing transformation animations + await Promise.all(scene.currentBattle.mysteryEncounter.misc.loadAssets); + const transformations = scene.currentBattle.mysteryEncounter.misc.teamTransformations; + + // If there are 1-3 transformations, do them centered back to back + // Otherwise, the first 3 transformations are executed side-by-side, then any remaining 1-3 transformations occur in those same respective positions + if (transformations.length <= 3) { + for (const transformation of transformations) { + const pokemon1 = transformation.previousPokemon; + const pokemon2 = transformation.newPokemon; + + await doPokemonTransformationSequence(scene, pokemon1, pokemon2, TransformationScreenPosition.CENTER); + } + } else { + await doSideBySideTransformations(scene, transformations); + } + + // Make sure player has finished cutscene dialogue + await cutsceneDialoguePromise; + + doHideDreamBackground(scene); + await showEncounterText(scene, `${namespace}.option.1.dream_complete`); + + await doNewTeamPostProcess(scene, transformations); + setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.ROGUE_BALL, modifierTypes.MINT, modifierTypes.MINT]}); + leaveEncounterWithoutBattle(scene, true); + }) + .build() + ) + .withSimpleOption( + { + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + selected: [ + { + text: `${namespace}.option.2.selected`, + }, + ], + }, + async (scene: BattleScene) => { + // Reduce party levels by 20% + for (const pokemon of scene.getParty()) { + pokemon.level = Math.max(Math.ceil(0.8 * pokemon.level), 1); + pokemon.exp = getLevelTotalExp(pokemon.level, pokemon.species.growthRate); + pokemon.levelExp = 0; + + pokemon.calculateStats(); + pokemon.updateInfo(); + } + + leaveEncounterWithoutBattle(scene, true); + return true; + } + ) + .withOutroDialogue([ + { + text: `${namespace}.outro` + } + ]) + .build(); + +interface PokemonTransformation { + previousPokemon: PlayerPokemon; + newSpecies: PokemonSpecies; + newPokemon: PlayerPokemon; + heldItems: PokemonHeldItemModifier[]; +} + +function getTeamTransformations(scene: BattleScene): PokemonTransformation[] { + const party = scene.getParty(); + // Removes all pokemon from the party + const alreadyUsedSpecies: PokemonSpecies[] = []; + const pokemonTransformations: PokemonTransformation[] = party.map(p => { + return { + previousPokemon: p + } as PokemonTransformation; + }); + + // Only 1 Pokemon can be transformed into BST higher than 600 + let hasPokemonBstHigherThan600 = false; + // Only 1 other Pokemon can be transformed into BST between 570-600 + let hasPokemonBstBetween570And600 = false; + + // First, roll 2 of the party members to new Pokemon at a +90 to +110 BST difference + // Then, roll the remainder of the party members at a +40 to +50 BST difference + const numPokemon = party.length; + for (let i = 0; i < numPokemon; i++) { + const removed = party[randSeedInt(party.length)]; + const index = pokemonTransformations.findIndex(p => p.previousPokemon.id === removed.id); + pokemonTransformations[index].heldItems = removed.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier)); + scene.removePokemonFromPlayerParty(removed, false); + + const bst = getOriginalBst(scene, removed); + let newBstRange; + if (i < 2) { + newBstRange = [90, 110]; + } else { + newBstRange = [40, 50]; + } + + const newSpecies = getTransformedSpecies(bst, newBstRange, hasPokemonBstHigherThan600, hasPokemonBstBetween570And600, alreadyUsedSpecies); + + const newSpeciesBst = newSpecies.getBaseStatTotal(); + if (newSpeciesBst > 600) { + hasPokemonBstHigherThan600 = true; + } + if (newSpeciesBst <= 600 && newSpeciesBst >= 570) { + hasPokemonBstBetween570And600 = true; + } + + + pokemonTransformations[index].newSpecies = newSpecies; + alreadyUsedSpecies.push(newSpecies); + } + + for (const transformation of pokemonTransformations) { + const newAbilityIndex = randSeedInt(transformation.newSpecies.getAbilityCount()); + const newPlayerPokemon = scene.addPlayerPokemon(transformation.newSpecies, transformation.previousPokemon.level, newAbilityIndex, undefined); + transformation.newPokemon = newPlayerPokemon; + scene.getParty().push(newPlayerPokemon); + } + + return pokemonTransformations; +} + +async function doNewTeamPostProcess(scene: BattleScene, transformations: PokemonTransformation[]) { + let atLeastOneNewStarter = false; + for (const transformation of transformations) { + const previousPokemon = transformation.previousPokemon; + const newPokemon = transformation.newPokemon; + const speciesRootForm = newPokemon.species.getRootSpeciesId(); + + // Roll HA a second time + if (newPokemon.species.abilityHidden) { + const hiddenIndex = newPokemon.species.ability2 ? 2 : 1; + if (newPokemon.abilityIndex < hiddenIndex) { + const hiddenAbilityChance = new IntegerHolder(256); + scene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance); + + const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value); + + if (hasHiddenAbility) { + newPokemon.abilityIndex = hiddenIndex; + } + } + } + + // Roll IVs a second time + newPokemon.ivs = newPokemon.ivs.map(iv => { + const newValue = randSeedInt(31); + return newValue > iv ? newValue : iv; + }); + + + // For pokemon at/below 570 BST or any shiny pokemon, unlock it permanently as if you had caught it + if (newPokemon.getSpeciesForm().getBaseStatTotal() <= 570 || newPokemon.isShiny()) { + if (newPokemon.getSpeciesForm().abilityHidden && newPokemon.abilityIndex === newPokemon.getSpeciesForm().getAbilityCount() - 1) { + scene.validateAchv(achvs.HIDDEN_ABILITY); + } + + if (newPokemon.species.subLegendary) { + scene.validateAchv(achvs.CATCH_SUB_LEGENDARY); + } + + if (newPokemon.species.legendary) { + scene.validateAchv(achvs.CATCH_LEGENDARY); + } + + if (newPokemon.species.mythical) { + scene.validateAchv(achvs.CATCH_MYTHICAL); + } + + scene.gameData.updateSpeciesDexIvs(newPokemon.species.getRootSpeciesId(true), newPokemon.ivs); + const newStarterUnlocked = await scene.gameData.setPokemonCaught(newPokemon, true, false, false); + if (newStarterUnlocked) { + atLeastOneNewStarter = true; + queueEncounterMessage(scene, i18next.t("battle:addedAsAStarter", { pokemonName: getPokemonSpecies(speciesRootForm).getName() })); + } + } + + // If the previous pokemon had higher IVs, override to those (after updating dex IVs > prevents perfect 31s on a new unlock) + newPokemon.ivs = newPokemon.ivs.map((iv, index) => { + return previousPokemon.ivs[index] > iv ? previousPokemon.ivs[index] : iv; + }); + + // For pokemon that the player owns (including ones just caught), gain a candy + if (!!scene.gameData.dexData[speciesRootForm].caughtAttr) { + scene.gameData.addStarterCandy(getPokemonSpecies(speciesRootForm), 1); + } + + // Set the moveset of the new pokemon to be the same as previous, but with 1 egg move of the new species + newPokemon.moveset = previousPokemon.moveset; + if (speciesEggMoves.hasOwnProperty(speciesRootForm)) { + const eggMoves = speciesEggMoves[speciesRootForm]; + const eggMoveIndex = randSeedInt(4); + const randomEggMove = eggMoves[eggMoveIndex]; + if (newPokemon.moveset.length < 4) { + newPokemon.moveset.push(new PokemonMove(randomEggMove)); + } else { + newPokemon.moveset[randSeedInt(4)] = new PokemonMove(randomEggMove); + } + // For pokemon that the player owns (including ones just caught), unlock the egg move + if (!!scene.gameData.dexData[speciesRootForm].caughtAttr) { + await scene.gameData.setEggMoveUnlocked(getPokemonSpecies(speciesRootForm), eggMoveIndex, true); + } + } + + // Randomize the second type of the pokemon + // If the pokemon does not normally have a second type, it will gain 1 + const newTypes = [newPokemon.getTypes()[0]]; + let newType = randSeedInt(18) as Type; + while (newType === newTypes[0]) { + newType = randSeedInt(18) as Type; + } + newTypes.push(newType); + if (!newPokemon.mysteryEncounterData) { + newPokemon.mysteryEncounterData = new MysteryEncounterPokemonData(null, null, null, newTypes); + } else { + newPokemon.mysteryEncounterData.types = newTypes; + } + + for (const item of transformation.heldItems) { + item.pokemonId = newPokemon.id; + scene.addModifier(item, false, false, false, true); + } + + // Any pokemon that is at or below 450 BST gets +20 permanent BST to 3 stats: HP, lowest of Atk/SpAtk, and lowest of Def/SpDef + if (newPokemon.getSpeciesForm().getBaseStatTotal() <= 600) { + const stats: Stat[] = [Stat.HP]; + const baseStats = newPokemon.getSpeciesForm().baseStats.slice(0); + // Attack or SpAtk + stats.push(baseStats[Stat.ATK] < baseStats[Stat.SPATK] ? Stat.ATK : Stat.SPATK); + // Def or SpDef + stats.push(baseStats[Stat.DEF] < baseStats[Stat.SPDEF] ? Stat.DEF : Stat.SPDEF); + // const mod = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU().newModifier(newPokemon, 20, stats); + const modType = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU().generateType(null, [20, stats]); + const modifier = modType.newModifier(newPokemon); + scene.addModifier(modifier); + } + + // Enable passive if previous had it + newPokemon.passive = previousPokemon.passive; + + newPokemon.calculateStats(); + newPokemon.initBattleInfo(); + } + + // One random pokemon will get its passive unlocked + const passiveDisabledPokemon = scene.getParty().filter(p => !p.passive); + if (passiveDisabledPokemon?.length > 0) { + passiveDisabledPokemon[randSeedInt(passiveDisabledPokemon.length)].passive = true; + } + + // If at least one new starter was unlocked, play 1 fanfare + if (atLeastOneNewStarter) { + scene.playSound("level_up_fanfare"); + } +} + +function getOriginalBst(scene: BattleScene, pokemon: Pokemon) { + const baseStats = pokemon.getSpeciesForm().baseStats.slice(0); + scene.applyModifiers(PokemonBaseStatTotalModifier, true, pokemon, baseStats); + if (pokemon.fusionSpecies) { + const fusionBaseStats = pokemon.getFusionSpeciesForm().baseStats; + for (let s = 0; s < pokemon.stats.length; s++) { + baseStats[s] = Math.ceil((baseStats[s] + fusionBaseStats[s]) / 2); + } + } else if (scene.gameMode.isSplicedOnly) { + for (let s = 0; s < pokemon.stats.length; s++) { + baseStats[s] = Math.ceil(baseStats[s] / 2); + } + } + return baseStats.reduce((a, b) => a + b, 0); +} + +function getTransformedSpecies(originalBst: number, bstSearchRange: [number, number], hasPokemonBstHigherThan600: boolean, hasPokemonBstBetween570And600: boolean, alreadyUsedSpecies: PokemonSpecies[]): PokemonSpecies { + let newSpecies: PokemonSpecies; + while (!newSpecies) { + const bstCap = originalBst + bstSearchRange[1]; + const bstMin = Math.max(originalBst + bstSearchRange[0], 0); + + // Get any/all species that fall within the Bst range requirements + let validSpecies = allSpecies + .filter(s => { + const speciesBst = s.getBaseStatTotal(); + const bstInRange = speciesBst >= bstMin && speciesBst <= bstCap; + // Checks that a Pokemon has not already been added in the +600 or 570-600 slots; + const validBst = (!hasPokemonBstBetween570And600 || (speciesBst < 570 || speciesBst > 600)) && + (!hasPokemonBstHigherThan600 || speciesBst <= 600); + return bstInRange && validBst && !excludedPokemon.includes(s.speciesId); + }); + + // There must be at least 20 species available before it will choose one + if (validSpecies?.length > 20) { + validSpecies = randSeedShuffle(validSpecies); + newSpecies = validSpecies.pop(); + while (alreadyUsedSpecies.includes(newSpecies)) { + newSpecies = validSpecies.pop(); + } + } else { + // Expands search rand until a Pokemon is found + bstSearchRange[0] -= 10; + bstSearchRange[1] += 10; + } + } + + return newSpecies; +} + +function doShowDreamBackground(scene: BattleScene) { + const transformationContainer = scene.add.container(0, -scene.game.canvas.height / 6); + transformationContainer.name = "Dream Background"; + + // In case it takes a bit for video to load + const transformationStaticBg = scene.add.rectangle(0, 0, scene.game.canvas.width / 6, scene.game.canvas.height / 6, 0); + transformationStaticBg.setName("Black Background"); + transformationStaticBg.setOrigin(0, 0); + transformationContainer.add(transformationStaticBg); + transformationStaticBg.setVisible(true); + + const transformationVideoBg: Phaser.GameObjects.Video = scene.add.video(0, 0, "evo_bg").stop(); + transformationVideoBg.setLoop(true); + transformationVideoBg.setOrigin(0, 0); + transformationVideoBg.setScale(0.4359673025); + transformationContainer.add(transformationVideoBg); + + scene.fieldUI.add(transformationContainer); + scene.fieldUI.bringToTop(transformationContainer); + transformationVideoBg.play(); + + transformationContainer.setVisible(true); + transformationContainer.alpha = 0; + + scene.tweens.add({ + targets: transformationContainer, + alpha: 1, + duration: 3000, + ease: "Sine.easeInOut" + }); +} + +function doHideDreamBackground(scene: BattleScene) { + const transformationContainer = scene.fieldUI.getByName("Dream Background"); + + scene.tweens.add({ + targets: transformationContainer, + alpha: 0, + duration: 3000, + ease: "Sine.easeInOut", + onComplete: () => { + scene.fieldUI.remove(transformationContainer, true); + } + }); +} + +function doSideBySideTransformations(scene: BattleScene, transformations: PokemonTransformation[]) { + return new Promise(resolve => { + const allTransformationPromises = []; + for (let i = 0; i < 3; i++) { + const delay = i * 4000; + scene.time.delayedCall(delay, () => { + const transformation = transformations[i]; + const pokemon1 = transformation.previousPokemon; + const pokemon2 = transformation.newPokemon; + const screenPosition = i as TransformationScreenPosition; + + const transformationPromise = doPokemonTransformationSequence(scene, pokemon1, pokemon2, screenPosition) + .then(() => { + if (transformations.length > i + 3) { + const nextTransformationAtPosition = transformations[i + 3]; + const nextPokemon1 = nextTransformationAtPosition.previousPokemon; + const nextPokemon2 = nextTransformationAtPosition.newPokemon; + + allTransformationPromises.push(doPokemonTransformationSequence(scene, nextPokemon1, nextPokemon2, screenPosition)); + } + }); + allTransformationPromises.push(transformationPromise); + }); + } + + // Wait for all transformations to be loaded into promise array + const id = setInterval(checkAllPromisesExist, 500); + async function checkAllPromisesExist() { + if (allTransformationPromises.length === transformations.length) { + clearInterval(id); + await Promise.all(allTransformationPromises); + resolve(); + } + } + }); +} diff --git a/src/data/mystery-encounters/mystery-encounters.ts b/src/data/mystery-encounters/mystery-encounters.ts index 6c3c2dd6008..f73673706ea 100644 --- a/src/data/mystery-encounters/mystery-encounters.ts +++ b/src/data/mystery-encounters/mystery-encounters.ts @@ -24,6 +24,7 @@ import { BerriesAboundEncounter } from "#app/data/mystery-encounters/encounters/ import { ClowningAroundEncounter } from "#app/data/mystery-encounters/encounters/clowning-around-encounter"; import { PartTimerEncounter } from "#app/data/mystery-encounters/encounters/part-timer-encounter"; import { DancingLessonsEncounter } from "#app/data/mystery-encounters/encounters/dancing-lessons-encounter"; +import { WeirdDreamEncounter } from "#app/data/mystery-encounters/encounters/weird-dream-encounter"; // Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * ) / 256 export const BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT = 1; @@ -165,7 +166,8 @@ const anyBiomeEncounters: MysteryEncounterType[] = [ MysteryEncounterType.A_TRAINERS_TEST, MysteryEncounterType.TRASH_TO_TREASURE, MysteryEncounterType.BERRIES_ABOUND, - MysteryEncounterType.CLOWNING_AROUND + MysteryEncounterType.CLOWNING_AROUND, + MysteryEncounterType.WEIRD_DREAM ]; /** @@ -267,6 +269,7 @@ export function initMysteryEncounters() { allMysteryEncounters[MysteryEncounterType.CLOWNING_AROUND] = ClowningAroundEncounter; allMysteryEncounters[MysteryEncounterType.PART_TIMER] = PartTimerEncounter; allMysteryEncounters[MysteryEncounterType.DANCING_LESSONS] = DancingLessonsEncounter; + allMysteryEncounters[MysteryEncounterType.WEIRD_DREAM] = WeirdDreamEncounter; // Add extreme encounters to biome map extremeBiomeEncounters.forEach(encounter => { diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index 03066314a5b..307e0a095ff 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -19,6 +19,7 @@ import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-enco import { getPokemonNameWithAffix } from "#app/messages"; import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import { Gender } from "#app/data/gender"; +import { Stat } from "#enums/stat"; export function getSpriteKeysFromSpecies(species: Species, female?: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): { spriteKey: string, fileRoot: string } { const spriteKey = getPokemonSpecies(species).getSpriteKey(female ?? false, formIndex ?? 0, shiny ?? false, variant ?? 0); @@ -84,6 +85,28 @@ export function getHighestLevelPlayerPokemon(scene: BattleScene, unfainted: bool return pokemon; } +/** + * Ties are broken by whatever mon is closer to the front of the party + * @param scene + * @param stat - stat to search for + * @param unfainted - default false. If true, only picks from unfainted mons. + * @returns + */ +export function getHighestStatPlayerPokemon(scene: BattleScene, stat: Stat, unfainted: boolean = false): PlayerPokemon { + const party = scene.getParty(); + let pokemon: PlayerPokemon; + party.every(p => { + if (unfainted && p.isFainted()) { + return true; + } + + pokemon = pokemon ? pokemon.getStat(stat) < p?.getStat(stat) ? p : pokemon : p; + return true; + }); + + return pokemon; +} + /** * Ties are broken by whatever mon is closer to the front of the party * @param scene diff --git a/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts b/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts new file mode 100644 index 00000000000..271cdaf391e --- /dev/null +++ b/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts @@ -0,0 +1,330 @@ +import BattleScene from "#app/battle-scene"; +import { PlayerPokemon } from "#app/field/pokemon"; +import { getFrameMs } from "#app/utils"; +import { cos, sin } from "#app/field/anims"; +import { getTypeRgb } from "#app/data/type"; + +export enum TransformationScreenPosition { + CENTER, + LEFT, + RIGHT +} + +/** + * Initiates an "evolution-like" animation to transform a pokemon (presumably from the player's party) into a new one, not necessarily an evolution species. + * @param scene + * @param pokemon + * @param transformedPokemon + * @param screenPosition + */ +export function doPokemonTransformationSequence(scene: BattleScene, pokemon: PlayerPokemon, transformedPokemon: PlayerPokemon, screenPosition: TransformationScreenPosition) { + return new Promise(resolve => { + const transformationContainer = scene.fieldUI.getByName("Dream Background") as Phaser.GameObjects.Container; + const transformationBaseBg = scene.add.image(0, 0, "default_bg"); + transformationBaseBg.setOrigin(0, 0); + transformationBaseBg.setVisible(false); + transformationContainer.add(transformationBaseBg); + + let pokemonSprite: Phaser.GameObjects.Sprite; + let pokemonTintSprite: Phaser.GameObjects.Sprite; + let pokemonEvoSprite: Phaser.GameObjects.Sprite; + let pokemonEvoTintSprite: Phaser.GameObjects.Sprite; + + const xOffset = screenPosition === TransformationScreenPosition.CENTER ? 0 : + screenPosition === TransformationScreenPosition.RIGHT ? 100 : -100; + // Centered transformations occur at a lower y Position + const yOffset = screenPosition !== TransformationScreenPosition.CENTER ? -15 : 0; + + const getPokemonSprite = () => { + const ret = scene.addPokemonSprite(pokemon, transformationBaseBg.displayWidth / 2 + xOffset, transformationBaseBg.displayHeight / 2 + yOffset, "pkmn__sub"); + ret.setPipeline(scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true }); + return ret; + }; + + transformationContainer.add((pokemonSprite = getPokemonSprite())); + transformationContainer.add((pokemonTintSprite = getPokemonSprite())); + transformationContainer.add((pokemonEvoSprite = getPokemonSprite())); + transformationContainer.add((pokemonEvoTintSprite = getPokemonSprite())); + + pokemonSprite.setAlpha(0); + pokemonTintSprite.setAlpha(0); + pokemonTintSprite.setTintFill(0xFFFFFF); + pokemonEvoSprite.setVisible(false); + pokemonEvoTintSprite.setVisible(false); + pokemonEvoTintSprite.setTintFill(0xFFFFFF); + + [ pokemonSprite, pokemonTintSprite, pokemonEvoSprite, pokemonEvoTintSprite ].map(sprite => { + sprite.play(pokemon.getSpriteKey(true)); + sprite.setPipeline(scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(pokemon.getTeraType()) }); + sprite.setPipelineData("ignoreTimeTint", true); + sprite.setPipelineData("spriteKey", pokemon.getSpriteKey()); + sprite.setPipelineData("shiny", pokemon.shiny); + sprite.setPipelineData("variant", pokemon.variant); + [ "spriteColors", "fusionSpriteColors" ].map(k => { + if (pokemon.summonData?.speciesForm) { + k += "Base"; + } + sprite.pipelineData[k] = pokemon.getSprite().pipelineData[k]; + }); + }); + + [ pokemonEvoSprite, pokemonEvoTintSprite ].map(sprite => { + sprite.play(transformedPokemon.getSpriteKey(true)); + sprite.setPipelineData("ignoreTimeTint", true); + sprite.setPipelineData("spriteKey", transformedPokemon.getSpriteKey()); + sprite.setPipelineData("shiny", transformedPokemon.shiny); + sprite.setPipelineData("variant", transformedPokemon.variant); + [ "spriteColors", "fusionSpriteColors" ].map(k => { + if (transformedPokemon.summonData?.speciesForm) { + k += "Base"; + } + sprite.pipelineData[k] = transformedPokemon.getSprite().pipelineData[k]; + }); + }); + + scene.tweens.add({ + targets: pokemonSprite, + alpha: 1, + ease: "Cubic.easeInOut", + duration: 2000, + onComplete: () => { + doSpiralUpward(scene, transformationBaseBg, transformationContainer, xOffset, yOffset); + scene.tweens.addCounter({ + from: 0, + to: 1, + duration: 1000, + onUpdate: t => { + pokemonTintSprite.setAlpha(t.getValue()); + }, + onComplete: () => { + pokemonSprite.setVisible(false); + scene.time.delayedCall(700, () => { + doArcDownward(scene, transformationBaseBg, transformationContainer, xOffset, yOffset); + scene.time.delayedCall(1000, () => { + pokemonEvoTintSprite.setScale(0.25); + pokemonEvoTintSprite.setVisible(true); + doCycle(scene, 2, 6, pokemonTintSprite, pokemonEvoTintSprite).then(success => { + pokemonEvoSprite.setVisible(true); + doCircleInward(scene, transformationBaseBg, transformationContainer, xOffset, yOffset); + + scene.time.delayedCall(900, () => { + scene.tweens.add({ + targets: pokemonEvoTintSprite, + alpha: 0, + duration: 1500, + delay: 150, + easing: "Sine.easeIn", + onComplete: () => { + scene.time.delayedCall(2500, () => { + resolve(); + scene.tweens.add({ + targets: pokemonEvoSprite, + alpha: 0, + duration: 2000, + delay: 150, + easing: "Sine.easeIn", + // onComplete: () => { + // transformedPokemon.destroy(); + // } + }); + }); + } + }); + }); + }); + }); + }); + } + }); + } + }); + }); +} + +function doSpiralUpward(scene: BattleScene, transformationBaseBg, transformationContainer, xOffset: number, yOffset: number) { + let f = 0; + + scene.tweens.addCounter({ + repeat: 64, + duration: getFrameMs(1), + onRepeat: () => { + if (f < 64) { + if (!(f & 7)) { + for (let i = 0; i < 4; i++) { + doSpiralUpwardParticle(scene, (f & 120) * 2 + i * 64, transformationBaseBg, transformationContainer, xOffset, yOffset); + } + } + f++; + } + } + }); +} + +function doArcDownward(scene: BattleScene, transformationBaseBg, transformationContainer, xOffset: number, yOffset: number) { + let f = 0; + + scene.tweens.addCounter({ + repeat: 96, + duration: getFrameMs(1), + onRepeat: () => { + if (f < 96) { + if (f < 6) { + for (let i = 0; i < 9; i++) { + doArcDownParticle(scene, i * 16, transformationBaseBg, transformationContainer, xOffset, yOffset); + } + } + f++; + } + } + }); +} + +function doCycle(scene: BattleScene, l: number, lastCycle: integer, pokemonTintSprite, pokemonEvoTintSprite): Promise { + return new Promise(resolve => { + const isLastCycle = l === lastCycle; + scene.tweens.add({ + targets: pokemonTintSprite, + scale: 0.25, + ease: "Cubic.easeInOut", + duration: 500 / l, + yoyo: !isLastCycle + }); + scene.tweens.add({ + targets: pokemonEvoTintSprite, + scale: 1, + ease: "Cubic.easeInOut", + duration: 500 / l, + yoyo: !isLastCycle, + onComplete: () => { + if (l < lastCycle) { + doCycle(scene, l + 0.5, lastCycle, pokemonTintSprite, pokemonEvoTintSprite).then(success => resolve(success)); + } else { + pokemonTintSprite.setVisible(false); + resolve(true); + } + } + }); + }); +} + +function doCircleInward(scene: BattleScene, transformationBaseBg, transformationContainer, xOffset: number, yOffset: number) { + let f = 0; + + scene.tweens.addCounter({ + repeat: 48, + duration: getFrameMs(1), + onRepeat: () => { + if (!f) { + for (let i = 0; i < 16; i++) { + doCircleInwardParticle(scene, i * 16, 4, transformationBaseBg, transformationContainer, xOffset, yOffset); + } + } else if (f === 32) { + for (let i = 0; i < 16; i++) { + doCircleInwardParticle(scene, i * 16, 8, transformationBaseBg, transformationContainer, xOffset, yOffset); + } + } + f++; + } + }); +} + +function doSpiralUpwardParticle(scene: BattleScene, trigIndex: integer, transformationBaseBg, transformationContainer, xOffset: number, yOffset: number) { + const initialX = transformationBaseBg.displayWidth / 2 + xOffset; + const particle = scene.add.image(initialX, 0, "evo_sparkle"); + transformationContainer.add(particle); + + let f = 0; + let amp = 48; + + const particleTimer = scene.tweens.addCounter({ + repeat: -1, + duration: getFrameMs(1), + onRepeat: () => { + updateParticle(); + } + }); + + const updateParticle = () => { + if (!f || particle.y > 8) { + particle.setPosition(initialX, 88 - (f * f) / 80 + yOffset); + particle.y += sin(trigIndex, amp) / 4; + particle.x += cos(trigIndex, amp); + particle.setScale(1 - (f / 80)); + trigIndex += 4; + if (f & 1) { + amp--; + } + f++; + } else { + particle.destroy(); + particleTimer.remove(); + } + }; + + updateParticle(); +} + +function doArcDownParticle(scene: BattleScene, trigIndex: integer, transformationBaseBg, transformationContainer, xOffset: number, yOffset: number) { + const initialX = transformationBaseBg.displayWidth / 2 + xOffset; + const particle = scene.add.image(initialX, 0, "evo_sparkle"); + particle.setScale(0.5); + transformationContainer.add(particle); + + let f = 0; + let amp = 8; + + const particleTimer = scene.tweens.addCounter({ + repeat: -1, + duration: getFrameMs(1), + onRepeat: () => { + updateParticle(); + } + }); + + const updateParticle = () => { + if (!f || particle.y < 88) { + particle.setPosition(initialX, 8 + (f * f) / 5 + yOffset); + particle.y += sin(trigIndex, amp) / 4; + particle.x += cos(trigIndex, amp); + amp = 8 + sin(f * 4, 40); + f++; + } else { + particle.destroy(); + particleTimer.remove(); + } + }; + + updateParticle(); +} + +function doCircleInwardParticle(scene: BattleScene, trigIndex: integer, speed: integer, transformationBaseBg, transformationContainer, xOffset: number, yOffset: number) { + const initialX = transformationBaseBg.displayWidth / 2 + xOffset; + const initialY = transformationBaseBg.displayHeight / 2 + yOffset; + const particle = scene.add.image(initialX, initialY, "evo_sparkle"); + transformationContainer.add(particle); + + let amp = 120; + + const particleTimer = scene.tweens.addCounter({ + repeat: -1, + duration: getFrameMs(1), + onRepeat: () => { + updateParticle(); + } + }); + + const updateParticle = () => { + if (amp > 8) { + particle.setPosition(initialX, initialY); + particle.y += sin(trigIndex, amp); + particle.x += cos(trigIndex, amp); + amp -= speed; + trigIndex += 4; + } else { + particle.destroy(); + particleTimer.remove(); + } + }; + + updateParticle(); +} diff --git a/src/enums/mystery-encounter-type.ts b/src/enums/mystery-encounter-type.ts index b3d4fd8be6f..0db41e71ac5 100644 --- a/src/enums/mystery-encounter-type.ts +++ b/src/enums/mystery-encounter-type.ts @@ -21,5 +21,6 @@ export enum MysteryEncounterType { BERRIES_ABOUND, CLOWNING_AROUND, PART_TIMER, - DANCING_LESSONS + DANCING_LESSONS, + WEIRD_DREAM } diff --git a/src/locales/en/modifier-type.ts b/src/locales/en/modifier-type.ts index 662d4d10e76..1266f6442e9 100644 --- a/src/locales/en/modifier-type.ts +++ b/src/locales/en/modifier-type.ts @@ -76,6 +76,10 @@ export const modifierType: ModifierTypeTranslationEntries = { "cursed": "cursed" }, }, + "PokemonBaseStatFlatModifierType": { + name: "Old Gateau", + description: "Increases the holder's {{stats}} base stats by {{statValue}}. Found after a strange dream.", + }, "AllPokemonFullHpRestoreModifierType": { description: "Restores 100% HP for all Pokémon.", }, @@ -258,6 +262,7 @@ export const modifierType: ModifierTypeTranslationEntries = { "MYSTERY_ENCOUNTER_SHUCKLE_JUICE": { name: "Shuckle Juice" }, "MYSTERY_ENCOUNTER_BLACK_SLUDGE": { name: "Black Sludge", description: "The stench is so powerful that healing items are no longer available to purchase in shops." }, + "MYSTERY_ENCOUNTER_OLD_GATEAU": { name: "Old Gateau", description: "Increases the holder's {{stats}} stats by {{statValue}}." }, }, 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 9821971b11e..1358c8949a0 100644 --- a/src/locales/en/mystery-encounter.ts +++ b/src/locales/en/mystery-encounter.ts @@ -21,6 +21,7 @@ import { berriesAboundDialogue } from "#app/locales/en/mystery-encounters/berrie import { clowningAroundDialogue } from "#app/locales/en/mystery-encounters/clowning-around-dialogue"; import { partTimerDialogue } from "#app/locales/en/mystery-encounters/part-timer-dialogue"; import { dancingLessonsDialogue } from "#app/locales/en/mystery-encounters/dancing-lessons-dialogue"; +import { weirdDreamDialogue } from "#app/locales/en/mystery-encounters/weird-dream-dialogue"; /** * Injection patterns that can be used: @@ -69,5 +70,6 @@ export const mysteryEncounter = { berriesAbound: berriesAboundDialogue, clowningAround: clowningAroundDialogue, partTimer: partTimerDialogue, - dancingLessons: dancingLessonsDialogue + dancingLessons: dancingLessonsDialogue, + weirdDream: weirdDreamDialogue } as const; diff --git a/src/locales/en/mystery-encounters/berries-abound-dialogue.ts b/src/locales/en/mystery-encounters/berries-abound-dialogue.ts index 803da26406d..c17a989821d 100644 --- a/src/locales/en/mystery-encounters/berries-abound-dialogue.ts +++ b/src/locales/en/mystery-encounters/berries-abound-dialogue.ts @@ -1,26 +1,23 @@ export const berriesAboundDialogue = { intro: "There's a huge berry bush\nnear that Pokémon!", title: "Berries Abound", - description: "It looks like there's a strong Pokémon guarding a berry bush. Battling is the straightforward approach, but this Pokémon looks strong. You could also try to sneak around, though the Pokémon might catch you.", + description: "It looks like there's a strong Pokémon guarding a berry bush. Battling is the straightforward approach, but this Pokémon looks strong. Maybe a fast Pokémon would be able to grab some without getting caught?", query: "What will you do?", berries: "Berries!", option: { 1: { label: "Battle the Pokémon", - tooltip: "(-) Hard Battle\n(+) New Item", + tooltip: "(-) Hard Battle\n(+) Gain Berries", selected: "You approach the\nPokémon without fear.", }, 2: { - label: "Steal the Berries", - 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} - $You manage to sneak your way\npast and grab the berries!`, - special_result: `.@d{32}.@d{32}.@d{32} - $Your {{option2PrimaryName}} helps you out and uses {{option2PrimaryMove}}! - $You nabbed the berries!`, - bad_result: `.@d{32}.@d{32}.@d{32} - $The Pokémon catches you\nas you try to sneak around!`, + label: "Race to the Bush", + tooltip: "(-) {{fastestPokemon}} Uses its Speed\n(+) Gain Berries", + selected: `Your {{fastestPokemon}} races for the berry bush! + $It manages to nab {{numBerries}} before the {{enemyPokemon}} can react! + $You quickly retreat with your newfound prize.`, + selected_bad: `Your {{fastestPokemon}} races for the berry bush! + $Oh no! The {{enemyPokemon}} was faster and blocked off the approach!`, boss_enraged: "The opposing {{enemyPokemon}} has become enraged!" }, 3: { 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 1eb4a984b21..7ce80b42d9b 100644 --- a/src/locales/en/mystery-encounters/fight-or-flight-dialogue.ts +++ b/src/locales/en/mystery-encounters/fight-or-flight-dialogue.ts @@ -11,16 +11,11 @@ export const fightOrFlightDialogue = { }, 2: { 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} - $You manage to sneak your way\npast and grab the item!`, - special_result: `.@d{32}.@d{32}.@d{32} + disabled_tooltip: "Your Pokémon need to know certain moves to choose this", + tooltip: "(+) {{option2PrimaryName}} uses {{option2PrimaryMove}}", + selected: `.@d{32}.@d{32}.@d{32} $Your {{option2PrimaryName}} helps you out and uses {{option2PrimaryMove}}! $You nabbed the item!`, - bad_result: `.@d{32}.@d{32}.@d{32} - $The Pokémon catches you\nas you try to sneak around!`, - boss_enraged: "The opposing {{enemyPokemon}} has become enraged!" }, 3: { label: "Leave", diff --git a/src/locales/en/mystery-encounters/weird-dream-dialogue.ts b/src/locales/en/mystery-encounters/weird-dream-dialogue.ts new file mode 100644 index 00000000000..2def3b50d05 --- /dev/null +++ b/src/locales/en/mystery-encounters/weird-dream-dialogue.ts @@ -0,0 +1,29 @@ +export const weirdDreamDialogue = { + intro: "A shadowy woman blocks your path.\nSomething about her is unsettling...", + speaker: "Woman", + intro_dialogue: `I have seen your futures, your pasts... + $Child, do you see them too?`, + title: "???", + description: "The woman's words echo in your head. It wasn't just a singular voice, but a vast multitude, from all timelines and realities. You begin to feel dizzy, the question lingering on your mind...\n\n@[TOOLTIP_TITLE]{\"I have seen your futures, your pasts... Child, do you see them too?\"}", + query: "What will you do?", + option: { + 1: { + label: "\"I See Them\"", + tooltip: "@[SUMMARY_GREEN]{(?) Affects your Pokémon}", + selected: `Her hand reaches out to touch you,\nand everything goes black. + $Then...@d{64} You see everything.\nEvery timeline, all your different selves,\n past and future. + $Everything that has made you,\neverything you will become...@d{64}`, + cutscene: "You see your Pokémon,@d{32} converging from\nevery reality to become something new...@d{64}", + dream_complete: `When you awaken, the woman - was it a woman or a ghost? - is gone... + $.@d{32}.@d{32}.@d{32} + $Your Pokémon team has changed...\nOr is it the same team you've always had?` + }, + 2: { + label: "Quickly Leave", + tooltip: "(-) Affects your Pokémon", + selected: `You tear your mind from a numbing grip, and hastily depart. + $When you finally stop to collect yourself, you check the Pokémon in your team. + $For some reason, all of their levels have decreased!`, + } + }, +}; diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index f430a0a118b..f783e2baa99 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1,27 +1,27 @@ import * as Modifiers from "./modifier"; -import { AttackMove, allMoves, selfStatLowerMoves } from "../data/move"; -import { MAX_PER_TYPE_POKEBALLS, PokeballType, getPokeballCatchMultiplier, getPokeballName } from "../data/pokeball"; +import { MoneyMultiplierModifier } from "./modifier"; +import { allMoves, AttackMove, selfStatLowerMoves } from "../data/move"; +import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS, PokeballType } from "../data/pokeball"; import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "../field/pokemon"; import { EvolutionItem, pokemonEvolutions } from "../data/pokemon-evolutions"; -import { Stat, getStatName } from "../data/pokemon-stat"; +import { getStatName, Stat } from "../data/pokemon-stat"; import { tmPoolTiers, tmSpecies } from "../data/tms"; import { Type } from "../data/type"; import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from "../ui/party-ui-handler"; import * as Utils from "../utils"; -import { TempBattleStat, getTempBattleStatBoosterItemName, getTempBattleStatName } from "../data/temp-battle-stat"; +import { getTempBattleStatBoosterItemName, getTempBattleStatName, TempBattleStat } from "../data/temp-battle-stat"; import { getBerryEffectDescription, getBerryName } from "../data/berry"; import { Unlockables } from "../system/unlockables"; -import { StatusEffect, getStatusEffectDescriptor } from "../data/status-effect"; +import { getStatusEffectDescriptor, StatusEffect } from "../data/status-effect"; import { SpeciesFormKey } from "../data/pokemon-species"; import BattleScene from "../battle-scene"; -import { VoucherType, getVoucherTypeIcon, getVoucherTypeName } from "../system/voucher"; -import { FormChangeItem, SpeciesFormChangeCondition, SpeciesFormChangeItemTrigger, pokemonFormChanges } from "../data/pokemon-forms"; +import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "../system/voucher"; +import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeCondition, SpeciesFormChangeItemTrigger } from "../data/pokemon-forms"; import { ModifierTier } from "./modifier-tier"; -import { Nature, getNatureName, getNatureStatMultiplier } from "#app/data/nature"; +import { getNatureName, getNatureStatMultiplier, Nature } from "#app/data/nature"; import i18next from "i18next"; import { getModifierTierTextTint } from "#app/ui/text"; import Overrides from "#app/overrides"; -import { MoneyMultiplierModifier } from "./modifier"; import { Abilities } from "#enums/abilities"; import { BattlerTagType } from "#enums/battler-tag-type"; import { BerryType } from "#enums/berry-type"; @@ -680,6 +680,28 @@ export class PokemonBaseStatTotalModifierType extends PokemonHeldItemModifierTyp } } +export class PokemonBaseStatFlatModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType { + private readonly statModifier: integer; + private readonly stats: Stat[]; + + constructor(statModifier: integer, stats: Stat[]) { + super("modifierType:ModifierType.MYSTERY_ENCOUNTER_OLD_GATEAU", "old_gateau", (_type, args) => new Modifiers.PokemonBaseStatFlatModifier(this, (args[0] as Pokemon).id, this.statModifier, this.stats)); + this.statModifier = statModifier; + this.stats = stats; + } + + getDescription(scene: BattleScene): string { + return i18next.t("modifierType:ModifierType.PokemonBaseStatFlatModifierType.description", { + stats: this.stats.map(stat => getStatName(stat)).join("/"), + statValue: this.statModifier, + }); + } + + getPregenArgs(): any[] { + return [ this.statModifier, this.stats ]; + } +} + class AllPokemonFullHpRestoreModifierType extends ModifierType { private descriptionKey: string; @@ -1477,7 +1499,12 @@ export const modifierTypes = { } return new PokemonBaseStatTotalModifierType(Utils.randSeedInt(20)); }), - + MYSTERY_ENCOUNTER_OLD_GATEAU: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { + if (pregenArgs) { + return new PokemonBaseStatFlatModifierType(pregenArgs[0] as integer, pregenArgs[1] as Stat[]); + } + return new PokemonBaseStatFlatModifierType(Utils.randSeedInt(20), [Stat.HP, Stat.ATK, Stat.DEF]); + }), MYSTERY_ENCOUNTER_BLACK_SLUDGE: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new Modifiers.RemoveHealShopModifier(type)), }; @@ -1948,6 +1975,7 @@ export interface CustomModifierSettings { guaranteedModifierTypeFuncs?: ModifierTypeFunc[]; fillRemaining?: boolean; rerollMultiplier?: number; + allowLuckUpgrades?: boolean; } export function getModifierTypeFuncById(id: string): ModifierTypeFunc { @@ -1968,6 +1996,7 @@ export function getModifierTypeFuncById(id: string): ModifierTypeFunc { * - The first item in the shop will be `GREAT` tier, and the remaining 3 items will be generated normally. * - If `fillRemaining = false` in the same scenario, only 1 `GREAT` tier item will appear in the shop (regardless of `count` value). * - `rerollMultiplier?: number` - If specified, can adjust the amount of money required for a shop reroll. If set to 0, the shop will not allow rerolls at all. + * - `allowLuckUpgrades?: boolean` - Default true, if false will prevent set item tiers from upgrading via luck */ export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemon[], modifierTiers?: ModifierTier[], customModifierSettings?: CustomModifierSettings): ModifierTypeOption[] { const options: ModifierTypeOption[] = []; @@ -2001,8 +2030,9 @@ export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemo // Guaranteed tiers third if (customModifierSettings?.guaranteedModifierTiers?.length > 0) { - customModifierSettings?.guaranteedModifierTiers.forEach((tier) => { - options.push(getModifierTypeOptionWithRetry(options, retryCount, party, tier)); + const allowLuckUpgrades = customModifierSettings.allowLuckUpgrades ?? true; + customModifierSettings.guaranteedModifierTiers.forEach((tier) => { + options.push(getModifierTypeOptionWithRetry(options, retryCount, party, tier, allowLuckUpgrades)); }); } @@ -2028,11 +2058,12 @@ export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemo return options; } -function getModifierTypeOptionWithRetry(existingOptions: ModifierTypeOption[], retryCount: integer, party: PlayerPokemon[], tier?: ModifierTier): ModifierTypeOption { - let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, tier); +function getModifierTypeOptionWithRetry(existingOptions: ModifierTypeOption[], retryCount: integer, party: PlayerPokemon[], tier?: ModifierTier, allowLuckUpgrades?: boolean): ModifierTypeOption { + allowLuckUpgrades = allowLuckUpgrades ?? true; + let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, tier, undefined, 0, allowLuckUpgrades); let r = 0; while (existingOptions.length && ++r < retryCount && existingOptions.filter(o => o.type.name === candidate.type.name || o.type.group === candidate.type.group).length) { - candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate.type.tier, candidate.upgradeCount); + candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate.type.tier, candidate.upgradeCount, 0, allowLuckUpgrades); } return candidate; } @@ -2112,7 +2143,7 @@ export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.P return ret; } -function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer, retryCount: integer = 0): ModifierTypeOption { +function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer, retryCount: integer = 0, allowLuckUpgrades: boolean = true): ModifierTypeOption { const player = !poolType; const pool = getModifierPoolForType(poolType); let thresholds: object; @@ -2138,7 +2169,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, if (!upgradeCount) { upgradeCount = 0; } - if (player && tierValue) { + if (player && tierValue && allowLuckUpgrades) { const partyLuckValue = getPartyLuckValue(party); const upgradeOdds = Math.floor(128 / ((partyLuckValue + 4) / 4)); let upgraded = false; @@ -2163,7 +2194,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, } } else if (upgradeCount === undefined && player) { upgradeCount = 0; - if (tier < ModifierTier.MASTER) { + if (tier < ModifierTier.MASTER && allowLuckUpgrades) { const partyShinyCount = party.filter(p => p.isShiny() && !p.isFainted()).length; const upgradeOdds = Math.floor(32 / ((partyShinyCount + 2) / 2)); while (modifierPool.hasOwnProperty(tier + upgradeCount + 1) && modifierPool[tier + upgradeCount + 1].length) { diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 07aa1ea803f..3778310c8f5 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -702,6 +702,7 @@ export class PokemonBaseStatModifier extends PokemonHeldItemModifier { export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { private statModifier: integer; + readonly isTransferrable: boolean = false; constructor(type: ModifierTypes.PokemonBaseStatTotalModifierType, pokemonId: integer, statModifier: integer, stackCount?: integer) { super(type, pokemonId, stackCount); @@ -709,10 +710,7 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { } matchType(modifier: Modifier): boolean { - if (modifier instanceof PokemonBaseStatTotalModifier) { - return (modifier as PokemonBaseStatTotalModifier).statModifier === this.statModifier; - } - return false; + return modifier instanceof PokemonBaseStatTotalModifier; } clone(): PersistentModifier { @@ -728,6 +726,7 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { } apply(args: any[]): boolean { + // Modifies the passed in baseStats[] array args[1].forEach((v, i) => { const newVal = Math.floor(v + this.statModifier); args[1][i] = Math.min(Math.max(newVal, 1), 999999); @@ -736,10 +735,6 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { return true; } - getTransferrable(_withinParty: boolean): boolean { - return false; - } - getScoreMultiplier(): number { return 1.2; } @@ -749,6 +744,55 @@ export class PokemonBaseStatTotalModifier extends PokemonHeldItemModifier { } } +export class PokemonBaseStatFlatModifier extends PokemonHeldItemModifier { + private statModifier: integer; + private stats: Stat[]; + readonly isTransferrable: boolean = false; + + constructor (type: ModifierType, pokemonId: integer, statModifier: integer, stats: Stat[], stackCount?: integer) { + super(type, pokemonId, stackCount); + + this.statModifier = statModifier; + this.stats = stats; + } + + matchType(modifier: Modifier): boolean { + return modifier instanceof PokemonBaseStatFlatModifier; + } + + clone(): PersistentModifier { + return new PokemonBaseStatFlatModifier(this.type, this.pokemonId, this.statModifier, this.stats, this.stackCount); + } + + getArgs(): any[] { + return super.getArgs().concat(this.statModifier, this.stats); + } + + shouldApply(args: any[]): boolean { + return super.shouldApply(args) && args.length === 2 && args[1] instanceof Array; + } + + apply(args: any[]): boolean { + // Modifies the passed in baseStats[] array by a flat value, only if the stat is specified in this.stats + args[1].forEach((v, i) => { + if (this.stats.includes(i)) { + const newVal = Math.floor(v + this.statModifier); + args[1][i] = Math.min(Math.max(newVal, 1), 999999); + } + }); + + return true; + } + + getScoreMultiplier(): number { + return 1.1; + } + + getMaxHeldItemCount(pokemon: Pokemon): integer { + return 1; + } +} + /** * Modifier used for held items that apply {@linkcode Stat} boost(s) * using a multiplier. diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 9662a685af7..af465278e39 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1444,12 +1444,20 @@ export class GameData { } } - setPokemonCaught(pokemon: Pokemon, incrementCount: boolean = true, fromEgg: boolean = false): Promise { - return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg); + /** + * + * @param pokemon + * @param incrementCount + * @param fromEgg + * @param showNewStarterMessage + * @returns - true if Pokemon catch unlocked a new starter, false if Pokemon catch did not unlock a starter + */ + setPokemonCaught(pokemon: Pokemon, incrementCount: boolean = true, fromEgg: boolean = false, showNewStarterMessage: boolean = true): Promise { + return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg, showNewStarterMessage); } - setPokemonSpeciesCaught(pokemon: Pokemon, species: PokemonSpecies, incrementCount: boolean = true, fromEgg: boolean = false): Promise { - return new Promise(resolve => { + setPokemonSpeciesCaught(pokemon: Pokemon, species: PokemonSpecies, incrementCount: boolean = true, fromEgg: boolean = false, showNewStarterMessage: boolean = true): Promise { + return new Promise(resolve => { const dexEntry = this.dexData[species.speciesId]; const caughtAttr = dexEntry.caughtAttr; const formIndex = pokemon.formIndex; @@ -1504,20 +1512,20 @@ export class GameData { } } - const checkPrevolution = () => { + const checkPrevolution = (newStarter: boolean) => { if (hasPrevolution) { const prevolutionSpecies = pokemonPrevolutions[species.speciesId]; - return this.setPokemonSpeciesCaught(pokemon, getPokemonSpecies(prevolutionSpecies), incrementCount, fromEgg).then(() => resolve()); + return this.setPokemonSpeciesCaught(pokemon, getPokemonSpecies(prevolutionSpecies), incrementCount, fromEgg, showNewStarterMessage).then(result => resolve(result)); } else { - resolve(); + resolve(newStarter); } }; - if (newCatch && speciesStarters.hasOwnProperty(species.speciesId)) { + if (newCatch && speciesStarters.hasOwnProperty(species.speciesId) && showNewStarterMessage) { this.scene.playSound("level_up_fanfare"); - this.scene.ui.showText(i18next.t("battle:addedAsAStarter", { pokemonName: species.name }), null, () => checkPrevolution(), null, true); + this.scene.ui.showText(i18next.t("battle:addedAsAStarter", { pokemonName: species.name }), null, () => checkPrevolution(true), null, true); } else { - checkPrevolution(); + checkPrevolution(false); } }); } @@ -1559,7 +1567,7 @@ export class GameData { this.starterData[species.speciesId].candyCount += count; } - setEggMoveUnlocked(species: PokemonSpecies, eggMoveIndex: integer): Promise { + setEggMoveUnlocked(species: PokemonSpecies, eggMoveIndex: integer, prependSpeciesToMessage: boolean = false): Promise { return new Promise(resolve => { const speciesId = species.speciesId; if (!speciesEggMoves.hasOwnProperty(speciesId) || !speciesEggMoves[speciesId][eggMoveIndex]) { @@ -1583,7 +1591,10 @@ export class GameData { this.scene.playSound("level_up_fanfare"); const moveName = allMoves[speciesEggMoves[speciesId][eggMoveIndex]].name; - this.scene.ui.showText(eggMoveIndex === 3 ? i18next.t("egg:rareEggMoveUnlock", { moveName: moveName }) : i18next.t("egg:eggMoveUnlock", { moveName: moveName }), null, () => resolve(true), null, true); + let message = prependSpeciesToMessage ? species.getName() + " " : ""; + message += eggMoveIndex === 3 ? i18next.t("egg:rareEggMoveUnlock", { moveName: moveName }) : i18next.t("egg:eggMoveUnlock", { moveName: moveName }); + + this.scene.ui.showText(message, null, () => resolve(true), null, true); }); } diff --git a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts index 6164c32418c..435f890b857 100644 --- a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -6,9 +6,7 @@ import GameManager from "#app/test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; import { CommandPhase, SelectModifierPhase } from "#app/phases"; -import { Moves } from "#enums/moves"; import BattleScene from "#app/battle-scene"; -import { PokemonMove } from "#app/field/pokemon"; import { Mode } from "#app/ui/ui"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; import { BerryModifier } from "#app/modifier/modifier"; @@ -16,13 +14,11 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; import { BerriesAboundEncounter } from "#app/data/mystery-encounters/encounters/berries-abound-encounter"; -import * as Utils from "utils"; -import { isNullOrUndefined } from "utils"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import * as EncounterDialogueUtils from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; const namespace = "mysteryEncounter:berriesAbound"; -const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultParty = [Species.PYUKUMUKU]; const defaultBiome = Biome.CAVE; const defaultWave = 45; @@ -105,10 +101,10 @@ describe("Berries Abound - Mystery Encounter", () => { describe("Option 1 - Fight", () => { it("should have the correct properties", () => { - const option1 = BerriesAboundEncounter.options[0]; - expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); - expect(option1.dialogue).toBeDefined(); - expect(option1.dialogue).toStrictEqual({ + const option = BerriesAboundEncounter.options[0]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ buttonLabel: `${namespace}.option.1.label`, buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ @@ -166,32 +162,25 @@ describe("Berries Abound - Mystery Encounter", () => { }); }); - describe("Option 2 - Attempt to Steal", () => { + describe("Option 2 - Race to the Bush", () => { it("should have the correct properties", () => { - const option1 = BerriesAboundEncounter.options[1]; - expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT_OR_SPECIAL); - expect(option1.dialogue).toBeDefined(); - expect(option1.dialogue).toStrictEqual({ + const option = BerriesAboundEncounter.options[1]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ buttonLabel: `${namespace}.option.2.label`, buttonTooltip: `${namespace}.option.2.tooltip`, }); }); - it("should start battle on failing to steal", async () => { + it("should start battle if fastest pokemon is slower than boss", async () => { + const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText"); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); const config = game.scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]; const speciesToSpawn = config.pokemonConfigs[0].species.speciesId; - - const realFn = Utils.randSeedInt; - vi.spyOn(Utils, "randSeedInt").mockImplementation((range, min) => { - if (range === 16 && isNullOrUndefined(min)) { - // Mock the steal roll - return 12; - } else { - return realFn(range, min); - } - }); + // Setting enemy's level arbitrarily high to outspeed + config.pokemonConfigs[0].dataSource.level = 1000; await runMysteryEncounterToEnd(game, 2, null, true); @@ -202,60 +191,33 @@ describe("Berries Abound - Mystery Encounter", () => { // Should be enraged expect(enemyField[0].summonData.battleStats).toEqual([1, 1, 1, 1, 1, 0, 0]); + expect(encounterTextSpy).toHaveBeenCalledWith(expect.any(BattleScene), `${namespace}.option.2.selected_bad`); }); - it("Should skip battle when succeed on steal", async () => { - const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); - - await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); - - const realFn = Utils.randSeedInt; - vi.spyOn(Utils, "randSeedInt").mockImplementation((range, min) => { - if (range === 16 && isNullOrUndefined(min)) { - // Mock the steal roll - return 6; - } else { - return realFn(range, min); - } - }); - - await runMysteryEncounterToEnd(game, 2); - await game.phaseInterceptor.to(SelectModifierPhase, false); - expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name); - await game.phaseInterceptor.run(SelectModifierPhase); - - expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); - const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; - expect(modifierSelectHandler.options.length).toEqual(5); - for (const option of modifierSelectHandler.options) { - expect(option.modifierTypeOption.type.id).toContain("BERRY"); - } - - expect(leaveEncounterWithoutBattleSpy).toBeCalled(); - }); - - it("Should skip fight when special requirements are met", async () => { + it("Should skip battle when fastest pokemon is faster than boss", async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText"); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); - // Mock moveset - scene.getParty()[0].moveset = [new PokemonMove(Moves.KNOCK_OFF)]; + // Setting party pokemon's level arbitrarily high to outspeed + const fastestPokemon = scene.getParty()[0]; + fastestPokemon.level = 1000; + fastestPokemon.calculateStats(); await runMysteryEncounterToEnd(game, 2); await game.phaseInterceptor.to(SelectModifierPhase, false); expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name); await game.phaseInterceptor.run(SelectModifierPhase); - expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); + expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; expect(modifierSelectHandler.options.length).toEqual(5); for (const option of modifierSelectHandler.options) { expect(option.modifierTypeOption.type.id).toContain("BERRY"); } - expect(encounterTextSpy).toHaveBeenCalledWith(expect.any(BattleScene), `${namespace}.option.2.special_result`); + expect(encounterTextSpy).toHaveBeenCalledWith(expect.any(BattleScene), `${namespace}.option.2.selected`); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); }); }); diff --git a/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts b/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts index b44acc6d027..1c8cee8f8c3 100644 --- a/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/fight-or-flight-encounter.test.ts @@ -4,7 +4,7 @@ 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 { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; import { CommandPhase, SelectModifierPhase } from "#app/phases"; import { Moves } from "#enums/moves"; import BattleScene from "#app/battle-scene"; @@ -14,11 +14,9 @@ import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; -import * as Utils from "utils"; -import { isNullOrUndefined } from "utils"; import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import * as EncounterDialogueUtils from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { FightOrFlightEncounter } from "#app/data/mystery-encounters/encounters/fight-or-flight-encounter"; +import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases"; const namespace = "mysteryEncounter:fightOrFlight"; const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; @@ -104,10 +102,10 @@ describe("Fight or Flight - Mystery Encounter", () => { describe("Option 1 - Fight", () => { it("should have the correct properties", () => { - const option1 = FightOrFlightEncounter.options[0]; - expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); - expect(option1.dialogue).toBeDefined(); - expect(option1.dialogue).toStrictEqual({ + const option = FightOrFlightEncounter.options[0]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ buttonLabel: `${namespace}.option.1.label`, buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ @@ -152,77 +150,46 @@ describe("Fight or Flight - Mystery Encounter", () => { describe("Option 2 - Attempt to Steal", () => { it("should have the correct properties", () => { - const option1 = FightOrFlightEncounter.options[1]; - expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT_OR_SPECIAL); - expect(option1.dialogue).toBeDefined(); - expect(option1.dialogue).toStrictEqual({ + const option = FightOrFlightEncounter.options[1]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ buttonLabel: `${namespace}.option.2.label`, buttonTooltip: `${namespace}.option.2.tooltip`, + disabledButtonTooltip: `${namespace}.option.2.disabled_tooltip`, + selected: [ + { + text: `${namespace}.option.2.selected`, + } + ], }); }); - it("should start battle on failing to steal", async () => { + it("should NOT be selectable if the player doesn't have a Stealing move", async () => { await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty); + scene.getParty().forEach(p => p.moveset = []); + await game.phaseInterceptor.to(MysteryEncounterPhase, false); - const config = game.scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]; - const speciesToSpawn = config.pokemonConfigs[0].species.speciesId; + const encounterPhase = scene.getCurrentPhase(); + expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name); + const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase; + vi.spyOn(mysteryEncounterPhase, "continueEncounter"); + vi.spyOn(mysteryEncounterPhase, "handleOptionSelect"); + vi.spyOn(scene.ui, "playError"); - const realFn = Utils.randSeedInt; - vi.spyOn(Utils, "randSeedInt").mockImplementation((range, min) => { - if (range === 16 && isNullOrUndefined(min)) { - // Mock the steal roll - return 12; - } else { - return realFn(range, min); - } - }); + await runSelectMysteryEncounterOption(game, 2); - await runMysteryEncounterToEnd(game, 2, null, true); - - const enemyField = scene.getEnemyField(); - expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name); - expect(enemyField.length).toBe(1); - expect(enemyField[0].species.speciesId).toBe(speciesToSpawn); - - // Should be enraged - expect(enemyField[0].summonData.battleStats).toEqual([1, 1, 1, 1, 1, 0, 0]); + expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name); + expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled + expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled(); + expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled(); }); - it("Should skip battle when succeed on steal", async () => { + it("Should skip fight when player meets requirements", async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty); - const item = game.scene.currentBattle.mysteryEncounter.misc; - const realFn = Utils.randSeedInt; - vi.spyOn(Utils, "randSeedInt").mockImplementation((range, min) => { - if (range === 16 && isNullOrUndefined(min)) { - // Mock the steal roll - return 6; - } else { - return realFn(range, min); - } - }); - - await runMysteryEncounterToEnd(game, 2); - await game.phaseInterceptor.to(SelectModifierPhase, false); - expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name); - await game.phaseInterceptor.run(SelectModifierPhase); - expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); - - const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; - expect(modifierSelectHandler.options.length).toEqual(1); - expect(item.type.name).toBe(modifierSelectHandler.options[0].modifierTypeOption.type.name); - - expect(leaveEncounterWithoutBattleSpy).toBeCalled(); - }); - - it("Should skip fight when special requirements are met", async () => { - const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); - const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText"); - - await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty); - // Mock moveset scene.getParty()[0].moveset = [new PokemonMove(Moves.KNOCK_OFF)]; const item = game.scene.currentBattle.mysteryEncounter.misc; @@ -237,7 +204,6 @@ describe("Fight or Flight - Mystery Encounter", () => { expect(modifierSelectHandler.options.length).toEqual(1); expect(item.type.name).toBe(modifierSelectHandler.options[0].modifierTypeOption.type.name); - expect(encounterTextSpy).toHaveBeenCalledWith(expect.any(BattleScene), `${namespace}.option.2.special_result`); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); }); }); diff --git a/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts b/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts new file mode 100644 index 00000000000..0650b3b0ad4 --- /dev/null +++ b/src/test/mystery-encounter/encounters/weird-dream-encounter.test.ts @@ -0,0 +1,219 @@ +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 * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounterTestUtils"; +import { SelectModifierPhase } from "#app/phases"; +import BattleScene from "#app/battle-scene"; +import { Mode } from "#app/ui/ui"; +import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; +import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; +import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; +import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; +import { WeirdDreamEncounter } from "#app/data/mystery-encounters/encounters/weird-dream-encounter"; +import * as EncounterTransformationSequence from "#app/data/mystery-encounters/utils/encounter-transformation-sequence"; + +const namespace = "mysteryEncounter:weirdDream"; +const defaultParty = [Species.MAGBY, Species.HAUNTER, Species.ABRA]; +const defaultBiome = Biome.CAVE; +const defaultWave = 45; + +describe("Weird Dream - 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.startingWave(defaultWave); + game.override.startingBiome(defaultBiome); + game.override.disableTrainerWaves(true); + vi.spyOn(EncounterTransformationSequence, "doPokemonTransformationSequence").mockImplementation(() => new Promise(resolve => resolve())); + + vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( + new Map([ + [Biome.CAVE, [MysteryEncounterType.WEIRD_DREAM]], + ]) + ); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + vi.clearAllMocks(); + vi.resetAllMocks(); + }); + + it("should have the correct properties", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); + + expect(WeirdDreamEncounter.encounterType).toBe(MysteryEncounterType.WEIRD_DREAM); + expect(WeirdDreamEncounter.encounterTier).toBe(MysteryEncounterTier.ROGUE); + expect(WeirdDreamEncounter.dialogue).toBeDefined(); + expect(WeirdDreamEncounter.dialogue.intro).toStrictEqual([ + { + text: `${namespace}.intro` + }, + { + speaker: `${namespace}.speaker`, + text: `${namespace}.intro_dialogue`, + }, + ]); + expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); + expect(WeirdDreamEncounter.options.length).toBe(2); + }); + + it("should not run below wave 10", async () => { + game.override.startingWave(9); + + await game.runToMysteryEncounter(); + + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.WEIRD_DREAM); + }); + + 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 () => { + initSceneWithoutEncounterPhase(scene, defaultParty); + scene.currentBattle.mysteryEncounter = WeirdDreamEncounter; + const loadBgmSpy = vi.spyOn(scene, "loadBgm"); + + const { onInit } = WeirdDreamEncounter; + + expect(WeirdDreamEncounter.onInit).toBeDefined(); + + WeirdDreamEncounter.populateDialogueTokensFromRequirements(scene); + const onInitResult = onInit(scene); + + expect(loadBgmSpy).toHaveBeenCalled(); + expect(onInitResult).toBe(true); + }); + + describe("Option 1 - Accept Transformation", () => { + it("should have the correct properties", () => { + const option = WeirdDreamEncounter.options[0]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, + selected: [ + { + text: `${namespace}.option.1.selected`, + }, + ], + }); + }); + + it("should transform the new party into new species, 2 at +90/+110, the rest at +40/50 BST", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); + + const pokemonPrior = scene.getParty().map(pokemon => pokemon); + const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal()); + + await runMysteryEncounterToEnd(game, 1); + await game.phaseInterceptor.to(SelectModifierPhase, false); + expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name); + + const pokemonAfter = scene.getParty(); + const bstsAfter = pokemonAfter.map(pokemon => pokemon.getSpeciesForm().getBaseStatTotal()); + const bstDiff = bstsAfter.map((bst, index) => bst - bstsPrior[index]); + + for (let i = 0; i < pokemonAfter.length; i++) { + const newPokemon = pokemonAfter[i]; + expect(newPokemon.getSpeciesForm().speciesId).not.toBe(pokemonPrior[i].getSpeciesForm().speciesId); + expect(newPokemon.mysteryEncounterData.types.length).toBe(2); + } + + const plus90To110 = bstDiff.filter(bst => bst > 80); + const plus40To50 = bstDiff.filter(bst => bst < 80); + + expect(plus90To110.length).toBe(2); + expect(plus40To50.length).toBe(1); + }); + + it("should have 1 Memory Mushroom, 5 Rogue Balls, and 2 Mints in rewards", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); + await runMysteryEncounterToEnd(game, 1); + await game.phaseInterceptor.to(SelectModifierPhase, false); + expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name); + await game.phaseInterceptor.run(SelectModifierPhase); + + expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT); + const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler; + expect(modifierSelectHandler.options.length).toEqual(4); + expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toEqual("MEMORY_MUSHROOM"); + expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toEqual("ROGUE_BALL"); + expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toEqual("MINT"); + expect(modifierSelectHandler.options[3].modifierTypeOption.type.id).toEqual("MINT"); + }); + + it("should leave encounter without battle", async () => { + const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); + + await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); + await runMysteryEncounterToEnd(game, 1); + + expect(leaveEncounterWithoutBattleSpy).toBeCalled(); + }); + }); + + describe("Option 2 - Leave", () => { + it("should have the correct properties", () => { + const option = WeirdDreamEncounter.options[1]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue).toStrictEqual({ + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + selected: [ + { + text: `${namespace}.option.2.selected`, + }, + ], + }); + }); + + it("should reduce party levels by 20%", async () => { + const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); + + await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); + const levelsPrior = scene.getParty().map(p => p.level); + await runMysteryEncounterToEnd(game, 2); + + const levelsAfter = scene.getParty().map(p => p.level); + + for (let i = 0; i < levelsPrior.length; i++) { + expect(Math.max(Math.ceil(0.8 * levelsPrior[i]), 1)).toBe(levelsAfter[i]); + expect(scene.getParty()[i].levelExp).toBe(0); + } + + expect(leaveEncounterWithoutBattleSpy).toBeCalled(); + }); + + it("should leave encounter without battle", async () => { + const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); + + await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty); + await runMysteryEncounterToEnd(game, 2); + + expect(leaveEncounterWithoutBattleSpy).toBeCalled(); + }); + }); +}); diff --git a/src/test/utils/mocks/mockTextureManager.ts b/src/test/utils/mocks/mockTextureManager.ts index e207f96b722..eab0e3c6449 100644 --- a/src/test/utils/mocks/mockTextureManager.ts +++ b/src/test/utils/mocks/mockTextureManager.ts @@ -5,6 +5,7 @@ import MockNineslice from "#app/test/utils/mocks/mocksContainer/mockNineslice"; import MockImage from "#app/test/utils/mocks/mocksContainer/mockImage"; import MockText from "#app/test/utils/mocks/mocksContainer/mockText"; import MockPolygon from "#app/test/utils/mocks/mocksContainer/mockPolygon"; +import MockVideo from "#test/utils/mocks/mocksContainer/mockVideo"; export default class MockTextureManager { @@ -30,6 +31,7 @@ export default class MockTextureManager { text: this.text.bind(this), bitmapText: this.text.bind(this), displayList: this.displayList, + video: this.video.bind(this) }; } @@ -82,4 +84,10 @@ export default class MockTextureManager { this.list.push(polygon); return polygon; } + + video(x: number, y: number, key?: string) { + const video = new MockVideo(this, x, y, key); + this.list.push(video); + return video; + } } diff --git a/src/test/utils/mocks/mocksContainer/mockContainer.ts b/src/test/utils/mocks/mocksContainer/mockContainer.ts index ea06c9de326..a61a04af5a1 100644 --- a/src/test/utils/mocks/mocksContainer/mockContainer.ts +++ b/src/test/utils/mocks/mocksContainer/mockContainer.ts @@ -212,4 +212,8 @@ export default class MockContainer { return this.list; } + getByName(key: string) { + return this.list.find(v => v.name === key) ?? new MockContainer(this.textureManager, 0, 0); + } + } diff --git a/src/test/utils/mocks/mocksContainer/mockVideo.ts b/src/test/utils/mocks/mocksContainer/mockVideo.ts new file mode 100644 index 00000000000..8f9457b70ac --- /dev/null +++ b/src/test/utils/mocks/mocksContainer/mockVideo.ts @@ -0,0 +1,26 @@ +import MockContainer from "#test/utils/mocks/mocksContainer/mockContainer"; + +export default class MockVideo extends MockContainer { + private video: HTMLVideoElement | null; + private videoTexture: Phaser.Textures.Texture | null; + private videoTextureSource: Phaser.Textures.TextureSource | null; + + constructor(textureManager, x: number, y: number, key?: string) { + super(textureManager, x, y); + this.video = null; + this.videoTexture = null; + this.videoTextureSource = null; + } + + stop(): this { + return this; + } + + play(): this { + return this; + } + + setLoop(value?: boolean): this { + return this; + } +} diff --git a/src/ui/mystery-encounter-ui-handler.ts b/src/ui/mystery-encounter-ui-handler.ts index 04642bec37b..78eac8a3982 100644 --- a/src/ui/mystery-encounter-ui-handler.ts +++ b/src/ui/mystery-encounter-ui-handler.ts @@ -85,12 +85,6 @@ export default class MysteryEncounterUiHandler extends UiHandler { dexProgressIndicator.setScale(0.80); 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 { @@ -555,7 +549,15 @@ export default class MysteryEncounterUiHandler extends UiHandler { targets: this.dexProgressContainer, y: -63, ease: "Sine.easeInOut", - duration: 750 + duration: 750, + onComplete: () => { + 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(); + }); + } }); } else if (!show && this.showDexProgress) { this.showDexProgress = false; @@ -565,6 +567,10 @@ export default class MysteryEncounterUiHandler extends UiHandler { y: -43, ease: "Sine.easeInOut", duration: 750, + onComplete: () => { + this.dexProgressContainer.off("pointerover"); + this.dexProgressContainer.off("pointerout"); + } }); } }