diff --git a/public/images/effects/tera.png b/public/images/effects/tera.png new file mode 100644 index 000000000..e378d1c05 Binary files /dev/null and b/public/images/effects/tera.png differ diff --git a/public/images/effects/tera_sparkle.json b/public/images/effects/tera_sparkle.json new file mode 100644 index 000000000..6e8714e19 --- /dev/null +++ b/public/images/effects/tera_sparkle.json @@ -0,0 +1,293 @@ +{ + "textures": [ + { + "image": "tera_sparkle.png", + "format": "RGBA8888", + "size": { + "w": 14, + "h": 19 + }, + "scale": 1, + "frames": [ + { + "filename": "0", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 2, + "y": 2, + "w": 3, + "h": 3 + }, + "frame": { + "x": 0, + "y": 0, + "w": 3, + "h": 3 + } + }, + { + "filename": "12", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 2, + "y": 2, + "w": 3, + "h": 3 + }, + "frame": { + "x": 0, + "y": 0, + "w": 3, + "h": 3 + } + }, + { + "filename": "1", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 5, + "h": 5 + }, + "frame": { + "x": 3, + "y": 0, + "w": 5, + "h": 5 + } + }, + { + "filename": "11", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 5, + "h": 5 + }, + "frame": { + "x": 3, + "y": 0, + "w": 5, + "h": 5 + } + }, + { + "filename": "2", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 5, + "h": 5 + }, + "frame": { + "x": 8, + "y": 0, + "w": 5, + "h": 5 + } + }, + { + "filename": "10", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 1, + "y": 1, + "w": 5, + "h": 5 + }, + "frame": { + "x": 8, + "y": 0, + "w": 5, + "h": 5 + } + }, + { + "filename": "3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 7, + "h": 7 + }, + "frame": { + "x": 0, + "y": 5, + "w": 7, + "h": 7 + } + }, + { + "filename": "9", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 7, + "h": 7 + }, + "frame": { + "x": 0, + "y": 5, + "w": 7, + "h": 7 + } + }, + { + "filename": "4", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 7, + "h": 7 + }, + "frame": { + "x": 7, + "y": 5, + "w": 7, + "h": 7 + } + }, + { + "filename": "8", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 7, + "h": 7 + }, + "frame": { + "x": 7, + "y": 5, + "w": 7, + "h": 7 + } + }, + { + "filename": "5", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 7, + "h": 7 + }, + "frame": { + "x": 0, + "y": 12, + "w": 7, + "h": 7 + } + }, + { + "filename": "7", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 7, + "h": 7 + }, + "frame": { + "x": 0, + "y": 12, + "w": 7, + "h": 7 + } + }, + { + "filename": "6", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 7, + "h": 7 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 7, + "h": 7 + }, + "frame": { + "x": 7, + "y": 12, + "w": 7, + "h": 7 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:6f9430b9e2e68d62275dbdf2e06fddbf:15e62f334efdea197e83a90f915a48ba:8d978bad4c3f82a9eaac116b284e702d$" + } +} diff --git a/public/images/effects/tera_sparkle.png b/public/images/effects/tera_sparkle.png new file mode 100644 index 000000000..3385aaf23 Binary files /dev/null and b/public/images/effects/tera_sparkle.png differ diff --git a/public/images/items.json b/public/images/items.json index 77b7ed7f3..a09745d70 100644 --- a/public/images/items.json +++ b/public/images/items.json @@ -4,8 +4,8 @@ "image": "items.png", "format": "RGBA8888", "size": { - "w": 342, - "h": 342 + "w": 356, + "h": 356 }, "scale": 1, "frames": [ @@ -388,7 +388,7 @@ } }, { - "filename": "elixir", + "filename": "muscle_band", "rotated": false, "trimmed": true, "sourceSize": { @@ -396,15 +396,15 @@ "h": 32 }, "spriteSourceSize": { - "x": 7, + "x": 4, "y": 4, - "w": 18, + "w": 24, "h": 24 }, "frame": { "x": 324, "y": 0, - "w": 18, + "w": 24, "h": 24 } }, @@ -493,7 +493,7 @@ } }, { - "filename": "muscle_band", + "filename": "reveal_glass", "rotated": false, "trimmed": true, "sourceSize": { @@ -503,13 +503,13 @@ "spriteSourceSize": { "x": 4, "y": 4, - "w": 24, + "w": 23, "h": 24 }, "frame": { "x": 0, "y": 246, - "w": 24, + "w": 23, "h": 24 } }, @@ -576,6 +576,27 @@ "h": 24 } }, + { + "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": 342, + "w": 24, + "h": 14 + } + }, { "filename": "calcium", "rotated": false, @@ -661,7 +682,7 @@ } }, { - "filename": "ether", + "filename": "elixir", "rotated": false, "trimmed": true, "sourceSize": { @@ -682,7 +703,7 @@ } }, { - "filename": "full_restore", + "filename": "ether", "rotated": false, "trimmed": true, "sourceSize": { @@ -703,7 +724,7 @@ } }, { - "filename": "max_elixir", + "filename": "full_restore", "rotated": false, "trimmed": true, "sourceSize": { @@ -723,6 +744,27 @@ "h": 24 } }, + { + "filename": "max_elixir", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 4, + "w": 18, + "h": 24 + }, + "frame": { + "x": 23, + "y": 245, + "w": 18, + "h": 24 + } + }, { "filename": "lure", "rotated": false, @@ -739,7 +781,7 @@ }, "frame": { "x": 24, - "y": 245, + "y": 269, "w": 17, "h": 24 } @@ -760,7 +802,7 @@ }, "frame": { "x": 24, - "y": 269, + "y": 293, "w": 18, "h": 24 } @@ -781,13 +823,13 @@ }, "frame": { "x": 24, - "y": 293, + "y": 317, "w": 18, "h": 24 } }, { - "filename": "max_revive", + "filename": "silver_powder", "rotated": false, "trimmed": true, "sourceSize": { @@ -795,16 +837,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 22, - "h": 24 + "x": 4, + "y": 11, + "w": 24, + "h": 15 }, "frame": { "x": 24, - "y": 317, - "w": 22, - "h": 24 + "y": 341, + "w": 24, + "h": 15 } }, { @@ -829,7 +871,7 @@ } }, { - "filename": "reveal_glass", + "filename": "max_revive", "rotated": false, "trimmed": true, "sourceSize": { @@ -837,15 +879,15 @@ "h": 32 }, "spriteSourceSize": { - "x": 4, + "x": 5, "y": 4, - "w": 23, + "w": 22, "h": 24 }, "frame": { "x": 33, "y": 73, - "w": 23, + "w": 22, "h": 24 } }, @@ -996,6 +1038,27 @@ "h": 23 } }, + { + "filename": "expert_belt", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 4, + "w": 24, + "h": 23 + }, + "frame": { + "x": 41, + "y": 262, + "w": 24, + "h": 23 + } + }, { "filename": "dynamax_band", "rotated": false, @@ -1012,34 +1075,13 @@ }, "frame": { "x": 42, - "y": 262, + "y": 285, "w": 23, "h": 23 } }, { - "filename": "expert_belt", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 4, - "w": 24, - "h": 23 - }, - "frame": { - "x": 42, - "y": 285, - "w": 24, - "h": 23 - } - }, - { - "filename": "black_belt", + "filename": "griseous_core", "rotated": false, "trimmed": true, "sourceSize": { @@ -1048,19 +1090,19 @@ }, "spriteSourceSize": { "x": 5, - "y": 4, - "w": 22, + "y": 5, + "w": 23, "h": 23 }, "frame": { - "x": 46, + "x": 42, "y": 308, - "w": 22, + "w": 23, "h": 23 } }, { - "filename": "relic_gold", + "filename": "max_lure", "rotated": false, "trimmed": true, "sourceSize": { @@ -1068,16 +1110,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 9, - "y": 11, - "w": 15, - "h": 11 + "x": 8, + "y": 4, + "w": 17, + "h": 24 }, "frame": { - "x": 46, + "x": 48, "y": 331, - "w": 15, - "h": 11 + "w": 17, + "h": 24 } }, { @@ -1249,7 +1291,7 @@ } }, { - "filename": "griseous_core", + "filename": "healing_charm", "rotated": false, "trimmed": true, "sourceSize": { @@ -1260,13 +1302,13 @@ "x": 5, "y": 5, "w": 23, - "h": 23 + "h": 22 }, "frame": { "x": 234, "y": 24, "w": 23, - "h": 23 + "h": 22 } }, { @@ -1333,7 +1375,7 @@ } }, { - "filename": "pp_max", + "filename": "black_belt", "rotated": false, "trimmed": true, "sourceSize": { @@ -1341,37 +1383,16 @@ "h": 32 }, "spriteSourceSize": { - "x": 8, + "x": 5, "y": 4, - "w": 16, - "h": 24 + "w": 22, + "h": 23 }, "frame": { "x": 326, "y": 24, - "w": 16, - "h": 24 - } - }, - { - "filename": "ability_capsule", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 9, - "w": 24, - "h": 14 - }, - "frame": { - "x": 136, - "y": 44, - "w": 24, - "h": 14 + "w": 22, + "h": 23 } }, { @@ -1389,8 +1410,8 @@ "h": 18 }, "frame": { - "x": 160, - "y": 46, + "x": 88, + "y": 47, "w": 24, "h": 18 } @@ -1410,12 +1431,33 @@ "h": 18 }, "frame": { - "x": 184, - "y": 46, + "x": 112, + "y": 47, "w": 24, "h": 18 } }, + { + "filename": "amulet_coin", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 23, + "h": 21 + }, + "frame": { + "x": 136, + "y": 44, + "w": 23, + "h": 21 + } + }, { "filename": "sacred_ash", "rotated": false, @@ -1431,7 +1473,7 @@ "h": 20 }, "frame": { - "x": 208, + "x": 159, "y": 46, "w": 24, "h": 20 @@ -1452,33 +1494,12 @@ "h": 20 }, "frame": { - "x": 232, - "y": 47, + "x": 183, + "y": 46, "w": 24, "h": 20 } }, - { - "filename": "amulet_coin", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 23, - "h": 21 - }, - "frame": { - "x": 256, - "y": 47, - "w": 23, - "h": 21 - } - }, { "filename": "auspicious_armor", "rotated": false, @@ -1494,159 +1515,12 @@ "h": 21 }, "frame": { - "x": 279, - "y": 47, + "x": 207, + "y": 46, "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": 302, - "y": 47, - "w": 23, - "h": 22 - } - }, - { - "filename": "max_lure", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 17, - "h": 24 - }, - "frame": { - "x": 325, - "y": 48, - "w": 17, - "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": 88, - "y": 47, - "w": 24, - "h": 15 - } - }, - { - "filename": "binding_band", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 23, - "h": 20 - }, - "frame": { - "x": 112, - "y": 47, - "w": 23, - "h": 20 - } - }, - { - "filename": "black_glasses", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 135, - "y": 58, - "w": 23, - "h": 17 - } - }, - { - "filename": "coupon", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 158, - "y": 64, - "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": 181, - "y": 64, - "w": 23, - "h": 19 - } - }, { "filename": "moon_stone", "rotated": false, @@ -1662,12 +1536,33 @@ "h": 21 }, "frame": { - "x": 204, - "y": 66, + "x": 230, + "y": 46, "w": 23, "h": 21 } }, + { + "filename": "binding_band", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 23, + "h": 20 + }, + "frame": { + "x": 253, + "y": 47, + "w": 23, + "h": 20 + } + }, { "filename": "reviver_seed", "rotated": false, @@ -1683,75 +1578,12 @@ "h": 20 }, "frame": { - "x": 227, - "y": 67, + "x": 276, + "y": 47, "w": 23, "h": 20 } }, - { - "filename": "mystic_ticket", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 250, - "y": 68, - "w": 23, - "h": 19 - } - }, - { - "filename": "pair_of_tickets", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 19 - }, - "frame": { - "x": 273, - "y": 68, - "w": 23, - "h": 19 - } - }, - { - "filename": "relic_crown", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 7, - "w": 23, - "h": 18 - }, - "frame": { - "x": 296, - "y": 69, - "w": 23, - "h": 18 - } - }, { "filename": "shell_bell", "rotated": false, @@ -1767,12 +1599,54 @@ "h": 20 }, "frame": { - "x": 319, - "y": 72, + "x": 299, + "y": 47, "w": 23, "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": 322, + "y": 47, + "w": 22, + "h": 23 + } + }, + { + "filename": "revive", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 10, + "y": 8, + "w": 12, + "h": 17 + }, + "frame": { + "x": 344, + "y": 47, + "w": 12, + "h": 17 + } + }, { "filename": "abomasite", "rotated": false, @@ -1795,28 +1669,7 @@ } }, { - "filename": "golden_egg", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 7, - "y": 6, - "w": 17, - "h": 20 - }, - "frame": { - "x": 55, - "y": 53, - "w": 17, - "h": 20 - } - }, - { - "filename": "pp_up", + "filename": "super_lure", "rotated": false, "trimmed": true, "sourceSize": { @@ -1826,18 +1679,39 @@ "spriteSourceSize": { "x": 8, "y": 4, - "w": 16, + "w": 17, "h": 24 }, "frame": { - "x": 56, - "y": 73, - "w": 16, + "x": 55, + "y": 53, + "w": 17, "h": 24 } }, { - "filename": "protein", + "filename": "apicot_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 19, + "h": 20 + }, + "frame": { + "x": 55, + "y": 77, + "w": 19, + "h": 20 + } + }, + { + "filename": "pp_max", "rotated": false, "trimmed": true, "sourceSize": { @@ -1858,70 +1732,7 @@ } }, { - "filename": "super_lure", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 4, - "w": 17, - "h": 24 - }, - "frame": { - "x": 72, - "y": 66, - "w": 17, - "h": 24 - } - }, - { - "filename": "fire_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 89, - "y": 62, - "w": 22, - "h": 23 - } - }, - { - "filename": "blunder_policy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 19 - }, - "frame": { - "x": 111, - "y": 67, - "w": 22, - "h": 19 - } - }, - { - "filename": "unknown", + "filename": "pp_up", "rotated": false, "trimmed": true, "sourceSize": { @@ -1942,7 +1753,7 @@ } }, { - "filename": "zinc", + "filename": "protein", "rotated": false, "trimmed": true, "sourceSize": { @@ -1962,6 +1773,48 @@ "h": 24 } }, + { + "filename": "unknown", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 4, + "w": 16, + "h": 24 + }, + "frame": { + "x": 61, + "y": 169, + "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": 64, + "y": 193, + "w": 22, + "h": 23 + } + }, { "filename": "dragon_fang", "rotated": false, @@ -1977,12 +1830,201 @@ "h": 23 }, "frame": { - "x": 61, - "y": 169, + "x": 65, + "y": 216, "w": 21, "h": 23 } }, + { + "filename": "dragon_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 65, + "y": 239, + "w": 22, + "h": 23 + } + }, + { + "filename": "electric_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 65, + "y": 262, + "w": 22, + "h": 23 + } + }, + { + "filename": "fairy_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 65, + "y": 285, + "w": 22, + "h": 23 + } + }, + { + "filename": "fighting_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 65, + "y": 308, + "w": 22, + "h": 23 + } + }, + { + "filename": "fire_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 65, + "y": 331, + "w": 22, + "h": 23 + } + }, + { + "filename": "relic_gold", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 9, + "y": 11, + "w": 15, + "h": 11 + }, + "frame": { + "x": 72, + "y": 66, + "w": 15, + "h": 11 + } + }, + { + "filename": "big_nugget", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 74, + "y": 77, + "w": 20, + "h": 20 + } + }, + { + "filename": "fire_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 73, + "y": 97, + "w": 22, + "h": 23 + } + }, + { + "filename": "flying_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 75, + "y": 120, + "w": 22, + "h": 23 + } + }, { "filename": "focus_sash", "rotated": false, @@ -1998,8 +2040,71 @@ "h": 23 }, "frame": { - "x": 64, - "y": 192, + "x": 76, + "y": 143, + "w": 22, + "h": 23 + } + }, + { + "filename": "ghost_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 77, + "y": 166, + "w": 22, + "h": 23 + } + }, + { + "filename": "grass_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 94, + "y": 65, + "w": 22, + "h": 23 + } + }, + { + "filename": "ground_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 116, + "y": 65, "w": 22, "h": 23 } @@ -2019,134 +2124,8 @@ "h": 23 }, "frame": { - "x": 65, - "y": 215, - "w": 21, - "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": 65, - "y": 238, - "w": 21, - "h": 23 - } - }, - { - "filename": "never_melt_ice", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 65, - "y": 261, - "w": 22, - "h": 23 - } - }, - { - "filename": "petaya_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 66, - "y": 284, - "w": 22, - "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": 68, - "y": 307, - "w": 20, - "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": 73, - "y": 90, - "w": 17, - "h": 23 - } - }, - { - "filename": "sharp_beak", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 21, - "h": 23 - }, - "frame": { - "x": 90, - "y": 85, + "x": 138, + "y": 65, "w": 21, "h": 23 } @@ -2166,96 +2145,12 @@ "h": 22 }, "frame": { - "x": 111, - "y": 86, + "x": 159, + "y": 66, "w": 22, "h": 22 } }, - { - "filename": "reaper_cloth", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 23 - }, - "frame": { - "x": 133, - "y": 75, - "w": 22, - "h": 23 - } - }, - { - "filename": "wise_glasses", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 4, - "y": 8, - "w": 23, - "h": 17 - }, - "frame": { - "x": 155, - "y": 83, - "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": 178, - "y": 83, - "w": 22, - "h": 20 - } - }, - { - "filename": "deep_sea_tooth", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 133, - "y": 98, - "w": 22, - "h": 21 - } - }, { "filename": "dire_hit", "rotated": false, @@ -2271,12 +2166,33 @@ "h": 22 }, "frame": { - "x": 155, - "y": 100, + "x": 181, + "y": 66, "w": 22, "h": 22 } }, + { + "filename": "deep_sea_tooth", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 21 + }, + "frame": { + "x": 203, + "y": 67, + "w": 22, + "h": 21 + } + }, { "filename": "dna_splicers", "rotated": false, @@ -2292,33 +2208,12 @@ "h": 22 }, "frame": { - "x": 177, - "y": 103, + "x": 225, + "y": 67, "w": 22, "h": 22 } }, - { - "filename": "dubious_disc", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 19 - }, - "frame": { - "x": 200, - "y": 87, - "w": 22, - "h": 19 - } - }, { "filename": "electirizer", "rotated": false, @@ -2334,8 +2229,8 @@ "h": 22 }, "frame": { - "x": 222, - "y": 87, + "x": 247, + "y": 67, "w": 22, "h": 22 } @@ -2355,8 +2250,8 @@ "h": 22 }, "frame": { - "x": 244, - "y": 87, + "x": 269, + "y": 67, "w": 22, "h": 22 } @@ -2376,12 +2271,138 @@ "h": 22 }, "frame": { - "x": 266, - "y": 87, + "x": 291, + "y": 67, "w": 22, "h": 22 } }, + { + "filename": "ice_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 95, + "y": 88, + "w": 22, + "h": 23 + } + }, + { + "filename": "never_melt_ice", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 117, + "y": 88, + "w": 22, + "h": 23 + } + }, + { + "filename": "normal_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 139, + "y": 88, + "w": 22, + "h": 23 + } + }, + { + "filename": "petaya_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 161, + "y": 88, + "w": 22, + "h": 23 + } + }, + { + "filename": "poison_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 183, + "y": 88, + "w": 22, + "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": 205, + "y": 88, + "w": 20, + "h": 23 + } + }, { "filename": "guard_spec", "rotated": false, @@ -2397,33 +2418,12 @@ "h": 22 }, "frame": { - "x": 288, - "y": 87, + "x": 225, + "y": 89, "w": 22, "h": 22 } }, - { - "filename": "fairy_feather", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 20 - }, - "frame": { - "x": 199, - "y": 106, - "w": 22, - "h": 20 - } - }, { "filename": "ice_stone", "rotated": false, @@ -2439,8 +2439,8 @@ "h": 22 }, "frame": { - "x": 221, - "y": 109, + "x": 247, + "y": 89, "w": 22, "h": 22 } @@ -2460,8 +2460,8 @@ "h": 22 }, "frame": { - "x": 243, - "y": 109, + "x": 269, + "y": 89, "w": 22, "h": 22 } @@ -2481,12 +2481,201 @@ "h": 22 }, "frame": { - "x": 265, - "y": 109, + "x": 291, + "y": 89, "w": 22, "h": 22 } }, + { + "filename": "psychic_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 313, + "y": 70, + "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": 335, + "y": 70, + "w": 21, + "h": 23 + } + }, + { + "filename": "coupon", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 313, + "y": 93, + "w": 23, + "h": 19 + } + }, + { + "filename": "sitrus_berry", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 20, + "h": 22 + }, + "frame": { + "x": 336, + "y": 93, + "w": 20, + "h": 22 + } + }, + { + "filename": "reaper_cloth", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 23 + }, + "frame": { + "x": 97, + "y": 111, + "w": 22, + "h": 23 + } + }, + { + "filename": "rock_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 119, + "y": 111, + "w": 22, + "h": 23 + } + }, + { + "filename": "steel_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 141, + "y": 111, + "w": 22, + "h": 23 + } + }, + { + "filename": "stellar_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 163, + "y": 111, + "w": 22, + "h": 23 + } + }, + { + "filename": "water_tera_shard", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 22, + "h": 23 + }, + "frame": { + "x": 185, + "y": 111, + "w": 22, + "h": 23 + } + }, { "filename": "protector", "rotated": false, @@ -2502,33 +2691,12 @@ "h": 22 }, "frame": { - "x": 287, - "y": 109, + "x": 207, + "y": 111, "w": 22, "h": 22 } }, - { - "filename": "full_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 9, - "y": 4, - "w": 15, - "h": 23 - }, - "frame": { - "x": 75, - "y": 113, - "w": 15, - "h": 23 - } - }, { "filename": "scroll_of_darkness", "rotated": false, @@ -2544,75 +2712,12 @@ "h": 22 }, "frame": { - "x": 90, - "y": 108, + "x": 229, + "y": 111, "w": 22, "h": 22 } }, - { - "filename": "whipped_dream", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 4, - "w": 21, - "h": 23 - }, - "frame": { - "x": 112, - "y": 108, - "w": 21, - "h": 23 - } - }, - { - "filename": "liechi_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 133, - "y": 119, - "w": 22, - "h": 21 - } - }, - { - "filename": "malicious_armor", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 20 - }, - "frame": { - "x": 155, - "y": 122, - "w": 22, - "h": 20 - } - }, { "filename": "scroll_of_waters", "rotated": false, @@ -2628,8 +2733,8 @@ "h": 22 }, "frame": { - "x": 177, - "y": 125, + "x": 251, + "y": 111, "w": 22, "h": 22 } @@ -2649,12 +2754,96 @@ "h": 22 }, "frame": { - "x": 199, - "y": 126, + "x": 273, + "y": 111, "w": 22, "h": 22 } }, + { + "filename": "sachet", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 4, + "w": 18, + "h": 23 + }, + "frame": { + "x": 295, + "y": 111, + "w": 18, + "h": 23 + } + }, + { + "filename": "golden_mystic_ticket", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 313, + "y": 112, + "w": 23, + "h": 19 + } + }, + { + "filename": "dawn_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 21 + }, + "frame": { + "x": 336, + "y": 115, + "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": 98, + "y": 134, + "w": 21, + "h": 23 + } + }, { "filename": "starf_berry", "rotated": false, @@ -2670,8 +2859,8 @@ "h": 22 }, "frame": { - "x": 221, - "y": 131, + "x": 119, + "y": 134, "w": 22, "h": 22 } @@ -2691,8 +2880,8 @@ "h": 22 }, "frame": { - "x": 243, - "y": 131, + "x": 141, + "y": 134, "w": 22, "h": 22 } @@ -2712,8 +2901,8 @@ "h": 22 }, "frame": { - "x": 265, - "y": 131, + "x": 163, + "y": 134, "w": 22, "h": 22 } @@ -2733,33 +2922,12 @@ "h": 22 }, "frame": { - "x": 287, - "y": 131, + "x": 185, + "y": 134, "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": 310, - "y": 92, - "w": 22, - "h": 21 - } - }, { "filename": "tm_dragon", "rotated": false, @@ -2775,75 +2943,12 @@ "h": 22 }, "frame": { - "x": 309, - "y": 113, + "x": 207, + "y": 133, "w": 22, "h": 22 } }, - { - "filename": "syrupy_apple", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 22, - "h": 21 - }, - "frame": { - "x": 309, - "y": 135, - "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": 90, - "y": 130, - "w": 22, - "h": 21 - } - }, - { - "filename": "dusk_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 112, - "y": 131, - "w": 21, - "h": 21 - } - }, { "filename": "tm_electric", "rotated": false, @@ -2859,8 +2964,8 @@ "h": 22 }, "frame": { - "x": 133, - "y": 140, + "x": 229, + "y": 133, "w": 22, "h": 22 } @@ -2880,8 +2985,8 @@ "h": 22 }, "frame": { - "x": 155, - "y": 142, + "x": 251, + "y": 133, "w": 22, "h": 22 } @@ -2901,539 +3006,14 @@ "h": 22 }, "frame": { - "x": 177, - "y": 147, + "x": 273, + "y": 133, "w": 22, "h": 22 } }, { - "filename": "tm_fire", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 199, - "y": 148, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_flying", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 221, - "y": 153, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_ghost", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 243, - "y": 153, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_grass", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 265, - "y": 153, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_ground", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 287, - "y": 153, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_ice", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 309, - "y": 156, - "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": 76, - "y": 151, - "w": 21, - "h": 18 - } - }, - { - "filename": "potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 82, - "y": 169, - "w": 17, - "h": 23 - } - }, - { - "filename": "sachet", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 4, - "w": 18, - "h": 23 - }, - "frame": { - "x": 86, - "y": 192, - "w": 18, - "h": 23 - } - }, - { - "filename": "metal_coat", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 5, - "w": 19, - "h": 22 - }, - "frame": { - "x": 86, - "y": 215, - "w": 19, - "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": 86, - "y": 237, - "w": 20, - "h": 22 - } - }, - { - "filename": "tm_normal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 87, - "y": 259, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_poison", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 88, - "y": 281, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_psychic", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 88, - "y": 303, - "w": 22, - "h": 22 - } - }, - { - "filename": "everstone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 17 - }, - "frame": { - "x": 88, - "y": 325, - "w": 20, - "h": 17 - } - }, - { - "filename": "prism_scale", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 9, - "y": 8, - "w": 15, - "h": 15 - }, - "frame": { - "x": 97, - "y": 151, - "w": 15, - "h": 15 - } - }, - { - "filename": "metal_alloy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, - "w": 21, - "h": 19 - }, - "frame": { - "x": 112, - "y": 152, - "w": 21, - "h": 19 - } - }, - { - "filename": "poison_barb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 99, - "y": 171, - "w": 21, - "h": 21 - } - }, - { - "filename": "super_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 23 - }, - "frame": { - "x": 104, - "y": 192, - "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": 105, - "y": 215, - "w": 17, - "h": 22 - } - }, - { - "filename": "soothe_bell", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 17, - "h": 22 - }, - "frame": { - "x": 106, - "y": 237, - "w": 17, - "h": 22 - } - }, - { - "filename": "leftovers", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 5, - "w": 15, - "h": 22 - }, - "frame": { - "x": 109, - "y": 259, - "w": 15, - "h": 22 - } - }, - { - "filename": "tm_rock", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 110, - "y": 281, - "w": 22, - "h": 22 - } - }, - { - "filename": "tm_steel", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 110, - "y": 303, - "w": 22, - "h": 22 - } - }, - { - "filename": "revive", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 10, - "y": 8, - "w": 12, - "h": 17 - }, - "frame": { - "x": 108, - "y": 325, - "w": 12, - "h": 17 - } - }, - { - "filename": "dawn_stone", + "filename": "dusk_stone", "rotated": false, "trimmed": true, "sourceSize": { @@ -3443,352 +3023,16 @@ "spriteSourceSize": { "x": 6, "y": 6, - "w": 20, - "h": 21 - }, - "frame": { - "x": 120, - "y": 171, - "w": 20, - "h": 21 - } - }, - { - "filename": "tm_water", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 121, - "y": 192, - "w": 22, - "h": 22 - } - }, - { - "filename": "water_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 122, - "y": 214, - "w": 22, - "h": 22 - } - }, - { - "filename": "x_accuracy", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 123, - "y": 236, - "w": 22, - "h": 22 - } - }, - { - "filename": "x_attack", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 124, - "y": 258, - "w": 22, - "h": 22 - } - }, - { - "filename": "x_defense", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 132, - "y": 280, - "w": 22, - "h": 22 - } - }, - { - "filename": "x_sp_atk", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 132, - "y": 302, - "w": 22, - "h": 22 - } - }, - { - "filename": "unremarkable_teacup", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 21, - "h": 18 - }, - "frame": { - "x": 132, - "y": 324, - "w": 21, - "h": 18 - } - }, - { - "filename": "wl_ability_urge", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 153, - "y": 324, - "w": 20, - "h": 18 - } - }, - { - "filename": "x_sp_def", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 140, - "y": 170, - "w": 22, - "h": 22 - } - }, - { - "filename": "x_speed", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 22, - "h": 22 - }, - "frame": { - "x": 143, - "y": 192, - "w": 22, - "h": 22 - } - }, - { - "filename": "shiny_stone", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, "w": 21, "h": 21 }, "frame": { - "x": 144, - "y": 214, + "x": 295, + "y": 134, "w": 21, "h": 21 } }, - { - "filename": "zoom_lens", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 6, - "w": 21, - "h": 21 - }, - "frame": { - "x": 145, - "y": 235, - "w": 21, - "h": 21 - } - }, - { - "filename": "big_nugget", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 146, - "y": 256, - "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": 154, - "y": 276, - "w": 19, - "h": 21 - } - }, - { - "filename": "apicot_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 19, - "h": 20 - }, - "frame": { - "x": 154, - "y": 297, - "w": 19, - "h": 20 - } - }, - { - "filename": "upgrade", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 5, - "y": 7, - "w": 22, - "h": 19 - }, - "frame": { - "x": 162, - "y": 169, - "w": 22, - "h": 19 - } - }, { "filename": "blue_orb", "rotated": false, @@ -3804,8 +3048,8 @@ "h": 20 }, "frame": { - "x": 165, - "y": 188, + "x": 316, + "y": 131, "w": 20, "h": 20 } @@ -3825,8 +3069,1205 @@ "h": 20 }, "frame": { - "x": 165, - "y": 208, + "x": 336, + "y": 136, + "w": 20, + "h": 20 + } + }, + { + "filename": "whipped_dream", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 4, + "w": 21, + "h": 23 + }, + "frame": { + "x": 99, + "y": 157, + "w": 21, + "h": 23 + } + }, + { + "filename": "tm_fire", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 120, + "y": 156, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_flying", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 142, + "y": 156, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_ghost", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 164, + "y": 156, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_grass", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 186, + "y": 156, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_ground", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 208, + "y": 155, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_ice", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 230, + "y": 155, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_normal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 252, + "y": 155, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_poison", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 274, + "y": 155, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_psychic", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 296, + "y": 155, + "w": 22, + "h": 22 + } + }, + { + "filename": "razor_fang", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 18, + "h": 20 + }, + "frame": { + "x": 318, + "y": 151, + "w": 18, + "h": 20 + } + }, + { + "filename": "magnet", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 336, + "y": 156, + "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": 86, + "y": 189, + "w": 16, + "h": 24 + } + }, + { + "filename": "hyper_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 23 + }, + "frame": { + "x": 86, + "y": 213, + "w": 17, + "h": 23 + } + }, + { + "filename": "potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 23 + }, + "frame": { + "x": 87, + "y": 236, + "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": 87, + "y": 259, + "w": 17, + "h": 23 + } + }, + { + "filename": "metal_coat", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 5, + "w": 19, + "h": 22 + }, + "frame": { + "x": 87, + "y": 282, + "w": 19, + "h": 22 + } + }, + { + "filename": "tm_rock", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 87, + "y": 304, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_steel", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 87, + "y": 326, + "w": 22, + "h": 22 + } + }, + { + "filename": "tm_water", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 102, + "y": 180, + "w": 22, + "h": 22 + } + }, + { + "filename": "water_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 124, + "y": 178, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_accuracy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 146, + "y": 178, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_attack", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 168, + "y": 178, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_defense", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 190, + "y": 178, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_sp_atk", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 212, + "y": 177, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_sp_def", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 234, + "y": 177, + "w": 22, + "h": 22 + } + }, + { + "filename": "x_speed", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 5, + "w": 22, + "h": 22 + }, + "frame": { + "x": 256, + "y": 177, + "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": 278, + "y": 177, + "w": 22, + "h": 21 + } + }, + { + "filename": "poison_barb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 300, + "y": 177, + "w": 21, + "h": 21 + } + }, + { + "filename": "full_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 9, + "y": 4, + "w": 15, + "h": 23 + }, + "frame": { + "x": 321, + "y": 171, + "w": 15, + "h": 23 + } + }, + { + "filename": "mb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 336, + "y": 176, + "w": 20, + "h": 20 + } + }, + { + "filename": "shiny_stone", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 103, + "y": 202, + "w": 21, + "h": 21 + } + }, + { + "filename": "sweet_apple", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 21 + }, + "frame": { + "x": 124, + "y": 200, + "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": 146, + "y": 200, + "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": 168, + "y": 200, + "w": 22, + "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": 190, + "y": 200, + "w": 22, + "h": 20 + } + }, + { + "filename": "fairy_feather", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 22, + "h": 20 + }, + "frame": { + "x": 212, + "y": 199, + "w": 22, + "h": 20 + } + }, + { + "filename": "malicious_armor", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 20 + }, + "frame": { + "x": 234, + "y": 199, + "w": 22, + "h": 20 + } + }, + { + "filename": "tera_orb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 20 + }, + "frame": { + "x": 256, + "y": 199, + "w": 22, + "h": 20 + } + }, + { + "filename": "mystic_ticket", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 278, + "y": 198, + "w": 23, + "h": 19 + } + }, + { + "filename": "blunder_policy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 22, + "h": 19 + }, + "frame": { + "x": 301, + "y": 198, + "w": 22, + "h": 19 + } + }, + { + "filename": "zoom_lens", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 6, + "w": 21, + "h": 21 + }, + "frame": { + "x": 104, + "y": 223, + "w": 21, + "h": 21 + } + }, + { + "filename": "dubious_disc", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 22, + "h": 19 + }, + "frame": { + "x": 104, + "y": 244, + "w": 22, + "h": 19 + } + }, + { + "filename": "pair_of_tickets", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 19 + }, + "frame": { + "x": 104, + "y": 263, + "w": 23, + "h": 19 + } + }, + { + "filename": "metronome", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 106, + "y": 282, + "w": 17, + "h": 22 + } + }, + { + "filename": "relic_crown", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 7, + "w": 23, + "h": 18 + }, + "frame": { + "x": 125, + "y": 221, + "w": 23, + "h": 18 + } + }, + { + "filename": "black_glasses", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 148, + "y": 221, + "w": 23, + "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": 171, + "y": 221, + "w": 19, + "h": 19 + } + }, + { + "filename": "upgrade", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 22, + "h": 19 + }, + "frame": { + "x": 190, + "y": 220, + "w": 22, + "h": 19 + } + }, + { + "filename": "metal_alloy", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 7, + "w": 21, + "h": 19 + }, + "frame": { + "x": 212, + "y": 219, + "w": 21, + "h": 19 + } + }, + { + "filename": "wise_glasses", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 4, + "y": 8, + "w": 23, + "h": 17 + }, + "frame": { + "x": 233, + "y": 219, + "w": 23, + "h": 17 + } + }, + { + "filename": "masterpiece_teacup", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 21, + "h": 18 + }, + "frame": { + "x": 256, + "y": 219, + "w": 21, + "h": 18 + } + }, + { + "filename": "leftovers", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 15, + "h": 22 + }, + "frame": { + "x": 109, + "y": 304, + "w": 15, + "h": 22 + } + }, + { + "filename": "soothe_bell", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 5, + "w": 17, + "h": 22 + }, + "frame": { + "x": 109, + "y": 326, + "w": 17, + "h": 22 + } + }, + { + "filename": "pb", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 126, + "y": 239, + "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": 127, + "y": 259, + "w": 19, + "h": 21 + } + }, + { + "filename": "pb_gold", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 6, + "w": 20, + "h": 20 + }, + "frame": { + "x": 323, + "y": 196, "w": 20, "h": 20 } @@ -3846,8 +4287,8 @@ "h": 20 }, "frame": { - "x": 166, - "y": 228, + "x": 123, + "y": 282, "w": 19, "h": 20 } @@ -3867,12 +4308,75 @@ "h": 20 }, "frame": { - "x": 166, - "y": 248, + "x": 124, + "y": 302, "w": 19, "h": 20 } }, + { + "filename": "golden_egg", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 7, + "y": 6, + "w": 17, + "h": 20 + }, + "frame": { + "x": 126, + "y": 322, + "w": 17, + "h": 20 + } + }, + { + "filename": "unremarkable_teacup", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 5, + "y": 7, + "w": 21, + "h": 18 + }, + "frame": { + "x": 278, + "y": 217, + "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": 299, + "y": 217, + "w": 20, + "h": 19 + } + }, { "filename": "lucky_egg", "rotated": false, @@ -3888,117 +4392,12 @@ "h": 20 }, "frame": { - "x": 173, - "y": 268, + "x": 319, + "y": 217, "w": 17, "h": 20 } }, - { - "filename": "magnet", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 173, - "y": 288, - "w": 20, - "h": 20 - } - }, - { - "filename": "mb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 173, - "y": 308, - "w": 20, - "h": 20 - } - }, - { - "filename": "wl_antidote", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 184, - "y": 170, - "w": 20, - "h": 18 - } - }, - { - "filename": "pb", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 6, - "w": 20, - "h": 20 - }, - "frame": { - "x": 185, - "y": 188, - "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": 185, - "y": 208, - "w": 20, - "h": 20 - } - }, { "filename": "strange_ball", "rotated": false, @@ -4014,8 +4413,8 @@ "h": 20 }, "frame": { - "x": 185, - "y": 228, + "x": 336, + "y": 216, "w": 20, "h": 20 } @@ -4035,35 +4434,14 @@ "h": 20 }, "frame": { - "x": 185, - "y": 248, + "x": 336, + "y": 236, "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": 190, - "y": 268, - "w": 18, - "h": 20 - } - }, - { - "filename": "big_mushroom", + "filename": "everstone", "rotated": false, "trimmed": true, "sourceSize": { @@ -4072,36 +4450,15 @@ }, "spriteSourceSize": { "x": 6, - "y": 6, - "w": 19, - "h": 19 + "y": 8, + "w": 20, + "h": 17 }, "frame": { - "x": 193, - "y": 288, - "w": 19, - "h": 19 - } - }, - { - "filename": "lum_berry", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 7, + "x": 233, + "y": 236, "w": 20, - "h": 19 - }, - "frame": { - "x": 193, - "y": 307, - "w": 20, - "h": 19 + "h": 17 } }, { @@ -4119,33 +4476,12 @@ "h": 16 }, "frame": { - "x": 193, - "y": 326, + "x": 253, + "y": 237, "w": 20, "h": 16 } }, - { - "filename": "absolite", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 8, - "y": 8, - "w": 16, - "h": 16 - }, - "frame": { - "x": 204, - "y": 170, - "w": 16, - "h": 16 - } - }, { "filename": "miracle_seed", "rotated": false, @@ -4161,8 +4497,8 @@ "h": 19 }, "frame": { - "x": 205, - "y": 186, + "x": 146, + "y": 239, "w": 19, "h": 19 } @@ -4182,14 +4518,14 @@ "h": 19 }, "frame": { - "x": 205, - "y": 205, + "x": 146, + "y": 258, "w": 20, "h": 19 } }, { - "filename": "wl_awakening", + "filename": "wl_ability_urge", "rotated": false, "trimmed": true, "sourceSize": { @@ -4203,29 +4539,8 @@ "h": 18 }, "frame": { - "x": 205, - "y": 224, - "w": 20, - "h": 18 - } - }, - { - "filename": "wl_burn_heal", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 205, - "y": 242, + "x": 165, + "y": 240, "w": 20, "h": 18 } @@ -4245,12 +4560,75 @@ "h": 19 }, "frame": { - "x": 208, - "y": 260, + "x": 166, + "y": 258, "w": 18, "h": 19 } }, + { + "filename": "wl_antidote", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 146, + "y": 277, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_awakening", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 166, + "y": 277, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_burn_heal", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 143, + "y": 295, + "w": 20, + "h": 18 + } + }, { "filename": "wl_ether", "rotated": false, @@ -4266,8 +4644,8 @@ "h": 18 }, "frame": { - "x": 224, - "y": 175, + "x": 143, + "y": 313, "w": 20, "h": 18 } @@ -4287,8 +4665,8 @@ "h": 18 }, "frame": { - "x": 244, - "y": 175, + "x": 163, + "y": 295, "w": 20, "h": 18 } @@ -4308,8 +4686,8 @@ "h": 18 }, "frame": { - "x": 264, - "y": 175, + "x": 163, + "y": 313, "w": 20, "h": 18 } @@ -4329,8 +4707,8 @@ "h": 18 }, "frame": { - "x": 284, - "y": 175, + "x": 143, + "y": 331, "w": 20, "h": 18 } @@ -4350,8 +4728,8 @@ "h": 18 }, "frame": { - "x": 304, - "y": 178, + "x": 163, + "y": 331, "w": 20, "h": 18 } @@ -4371,8 +4749,8 @@ "h": 18 }, "frame": { - "x": 225, - "y": 193, + "x": 185, + "y": 240, "w": 20, "h": 18 } @@ -4392,8 +4770,8 @@ "h": 18 }, "frame": { - "x": 225, - "y": 211, + "x": 184, + "y": 258, "w": 20, "h": 18 } @@ -4413,8 +4791,8 @@ "h": 18 }, "frame": { - "x": 245, - "y": 193, + "x": 186, + "y": 276, "w": 20, "h": 18 } @@ -4434,8 +4812,8 @@ "h": 18 }, "frame": { - "x": 225, - "y": 229, + "x": 205, + "y": 239, "w": 20, "h": 18 } @@ -4455,8 +4833,8 @@ "h": 18 }, "frame": { - "x": 245, - "y": 211, + "x": 277, + "y": 235, "w": 20, "h": 18 } @@ -4476,12 +4854,33 @@ "h": 18 }, "frame": { - "x": 265, - "y": 193, + "x": 297, + "y": 236, "w": 20, "h": 18 } }, + { + "filename": "absolite", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 8, + "y": 8, + "w": 16, + "h": 16 + }, + "frame": { + "x": 317, + "y": 237, + "w": 16, + "h": 16 + } + }, { "filename": "wl_potion", "rotated": false, @@ -4497,8 +4896,8 @@ "h": 18 }, "frame": { - "x": 245, - "y": 229, + "x": 183, + "y": 295, "w": 20, "h": 18 } @@ -4518,8 +4917,8 @@ "h": 18 }, "frame": { - "x": 265, - "y": 211, + "x": 183, + "y": 313, "w": 20, "h": 18 } @@ -4539,8 +4938,29 @@ "h": 18 }, "frame": { - "x": 265, - "y": 229, + "x": 183, + "y": 331, + "w": 20, + "h": 18 + } + }, + { + "filename": "wl_super_potion", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 32, + "h": 32 + }, + "spriteSourceSize": { + "x": 6, + "y": 8, + "w": 20, + "h": 18 + }, + "frame": { + "x": 204, + "y": 258, "w": 20, "h": 18 } @@ -4560,33 +4980,12 @@ "h": 16 }, "frame": { - "x": 285, - "y": 193, + "x": 206, + "y": 276, "w": 16, "h": 16 } }, - { - "filename": "wl_super_potion", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 32 - }, - "spriteSourceSize": { - "x": 6, - "y": 8, - "w": 20, - "h": 18 - }, - "frame": { - "x": 285, - "y": 209, - "w": 20, - "h": 18 - } - }, { "filename": "aggronite", "rotated": false, @@ -4602,8 +5001,8 @@ "h": 16 }, "frame": { - "x": 285, - "y": 227, + "x": 203, + "y": 294, "w": 16, "h": 16 } @@ -4623,8 +5022,8 @@ "h": 16 }, "frame": { - "x": 324, - "y": 178, + "x": 203, + "y": 310, "w": 16, "h": 16 } @@ -4644,8 +5043,8 @@ "h": 16 }, "frame": { - "x": 212, - "y": 279, + "x": 203, + "y": 326, "w": 16, "h": 16 } @@ -4665,8 +5064,8 @@ "h": 16 }, "frame": { - "x": 285, - "y": 243, + "x": 222, + "y": 276, "w": 16, "h": 16 } @@ -4686,8 +5085,8 @@ "h": 16 }, "frame": { - "x": 301, - "y": 227, + "x": 219, + "y": 292, "w": 16, "h": 16 } @@ -4707,8 +5106,8 @@ "h": 16 }, "frame": { - "x": 301, - "y": 243, + "x": 219, + "y": 308, "w": 16, "h": 16 } @@ -4728,8 +5127,8 @@ "h": 16 }, "frame": { - "x": 213, - "y": 295, + "x": 219, + "y": 324, "w": 16, "h": 16 } @@ -4749,8 +5148,8 @@ "h": 16 }, "frame": { - "x": 213, - "y": 311, + "x": 219, + "y": 340, "w": 16, "h": 16 } @@ -4770,8 +5169,8 @@ "h": 16 }, "frame": { - "x": 226, - "y": 247, + "x": 235, + "y": 292, "w": 16, "h": 16 } @@ -4791,8 +5190,8 @@ "h": 16 }, "frame": { - "x": 226, - "y": 263, + "x": 235, + "y": 308, "w": 16, "h": 16 } @@ -4812,8 +5211,8 @@ "h": 16 }, "frame": { - "x": 242, - "y": 247, + "x": 235, + "y": 324, "w": 16, "h": 16 } @@ -4833,8 +5232,8 @@ "h": 16 }, "frame": { - "x": 242, - "y": 263, + "x": 235, + "y": 340, "w": 16, "h": 16 } @@ -4854,8 +5253,8 @@ "h": 16 }, "frame": { - "x": 228, - "y": 279, + "x": 317, + "y": 253, "w": 16, "h": 16 } @@ -4875,8 +5274,8 @@ "h": 16 }, "frame": { - "x": 258, - "y": 247, + "x": 333, + "y": 256, "w": 16, "h": 16 } @@ -4896,8 +5295,8 @@ "h": 16 }, "frame": { - "x": 258, - "y": 263, + "x": 238, + "y": 253, "w": 16, "h": 16 } @@ -4917,8 +5316,8 @@ "h": 16 }, "frame": { - "x": 244, - "y": 279, + "x": 254, + "y": 253, "w": 16, "h": 16 } @@ -4938,8 +5337,8 @@ "h": 16 }, "frame": { - "x": 229, - "y": 295, + "x": 270, + "y": 253, "w": 16, "h": 16 } @@ -4959,8 +5358,8 @@ "h": 16 }, "frame": { - "x": 229, - "y": 311, + "x": 238, + "y": 269, "w": 16, "h": 16 } @@ -4980,8 +5379,8 @@ "h": 16 }, "frame": { - "x": 245, - "y": 295, + "x": 254, + "y": 269, "w": 16, "h": 16 } @@ -5001,8 +5400,8 @@ "h": 16 }, "frame": { - "x": 245, - "y": 311, + "x": 270, + "y": 269, "w": 16, "h": 16 } @@ -5022,8 +5421,8 @@ "h": 16 }, "frame": { - "x": 260, - "y": 279, + "x": 251, + "y": 285, "w": 16, "h": 16 } @@ -5043,8 +5442,8 @@ "h": 16 }, "frame": { - "x": 261, - "y": 295, + "x": 251, + "y": 301, "w": 16, "h": 16 } @@ -5064,8 +5463,8 @@ "h": 16 }, "frame": { - "x": 261, - "y": 311, + "x": 267, + "y": 285, "w": 16, "h": 16 } @@ -5085,8 +5484,8 @@ "h": 16 }, "frame": { - "x": 274, - "y": 259, + "x": 251, + "y": 317, "w": 16, "h": 16 } @@ -5106,8 +5505,8 @@ "h": 16 }, "frame": { - "x": 290, - "y": 259, + "x": 267, + "y": 301, "w": 16, "h": 16 } @@ -5127,8 +5526,8 @@ "h": 16 }, "frame": { - "x": 276, - "y": 275, + "x": 251, + "y": 333, "w": 16, "h": 16 } @@ -5148,8 +5547,8 @@ "h": 16 }, "frame": { - "x": 292, - "y": 275, + "x": 267, + "y": 317, "w": 16, "h": 16 } @@ -5169,8 +5568,8 @@ "h": 16 }, "frame": { - "x": 306, - "y": 259, + "x": 267, + "y": 333, "w": 16, "h": 16 } @@ -5190,12 +5589,33 @@ "h": 16 }, "frame": { - "x": 308, - "y": 275, + "x": 286, + "y": 254, "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": 302, + "y": 254, + "w": 15, + "h": 15 + } + }, { "filename": "metagrossite", "rotated": false, @@ -5211,8 +5631,8 @@ "h": 16 }, "frame": { - "x": 277, - "y": 291, + "x": 286, + "y": 270, "w": 16, "h": 16 } @@ -5232,8 +5652,8 @@ "h": 16 }, "frame": { - "x": 277, - "y": 307, + "x": 302, + "y": 269, "w": 16, "h": 16 } @@ -5253,8 +5673,8 @@ "h": 16 }, "frame": { - "x": 293, - "y": 291, + "x": 283, + "y": 286, "w": 16, "h": 16 } @@ -5274,8 +5694,8 @@ "h": 16 }, "frame": { - "x": 293, - "y": 307, + "x": 283, + "y": 302, "w": 16, "h": 16 } @@ -5295,8 +5715,8 @@ "h": 16 }, "frame": { - "x": 309, - "y": 291, + "x": 283, + "y": 318, "w": 16, "h": 16 } @@ -5316,8 +5736,8 @@ "h": 16 }, "frame": { - "x": 309, - "y": 307, + "x": 283, + "y": 334, "w": 16, "h": 16 } @@ -5337,8 +5757,8 @@ "h": 16 }, "frame": { - "x": 277, - "y": 323, + "x": 299, + "y": 286, "w": 16, "h": 16 } @@ -5358,8 +5778,8 @@ "h": 16 }, "frame": { - "x": 293, - "y": 323, + "x": 299, + "y": 302, "w": 16, "h": 16 } @@ -5379,8 +5799,8 @@ "h": 16 }, "frame": { - "x": 309, - "y": 323, + "x": 299, + "y": 318, "w": 16, "h": 16 } @@ -5400,8 +5820,8 @@ "h": 16 }, "frame": { - "x": 305, - "y": 196, + "x": 299, + "y": 334, "w": 16, "h": 16 } @@ -5421,8 +5841,8 @@ "h": 16 }, "frame": { - "x": 321, - "y": 196, + "x": 315, + "y": 285, "w": 16, "h": 16 } @@ -5442,8 +5862,8 @@ "h": 16 }, "frame": { - "x": 317, - "y": 212, + "x": 315, + "y": 301, "w": 16, "h": 16 } @@ -5463,8 +5883,8 @@ "h": 16 }, "frame": { - "x": 317, - "y": 228, + "x": 315, + "y": 317, "w": 16, "h": 16 } @@ -5484,8 +5904,8 @@ "h": 16 }, "frame": { - "x": 322, - "y": 244, + "x": 315, + "y": 333, "w": 16, "h": 16 } @@ -5505,8 +5925,8 @@ "h": 16 }, "frame": { - "x": 324, - "y": 260, + "x": 331, + "y": 272, "w": 16, "h": 16 } @@ -5526,8 +5946,8 @@ "h": 16 }, "frame": { - "x": 325, - "y": 276, + "x": 331, + "y": 288, "w": 16, "h": 16 } @@ -5547,8 +5967,8 @@ "h": 16 }, "frame": { - "x": 325, - "y": 292, + "x": 331, + "y": 304, "w": 16, "h": 16 } @@ -5568,8 +5988,8 @@ "h": 16 }, "frame": { - "x": 325, - "y": 308, + "x": 331, + "y": 320, "w": 16, "h": 16 } @@ -5589,8 +6009,8 @@ "h": 16 }, "frame": { - "x": 325, - "y": 324, + "x": 331, + "y": 336, "w": 16, "h": 16 } @@ -5601,6 +6021,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:6ebdeaa256dae3c85615b653f5f4467a:7739977ebe25a40fef999e70ae9591a6:110e074689c9edd2c54833ce2e4d9270$" + "smartupdate": "$TexturePacker:SmartUpdate:2497ac4c2655c9964bdd1688037f70ad:afe1c3244c4d1319915c5dba32e71a8e:110e074689c9edd2c54833ce2e4d9270$" } } diff --git a/public/images/items.png b/public/images/items.png index 51e425a4a..8814e579a 100644 Binary files a/public/images/items.png and b/public/images/items.png differ diff --git a/public/images/items/bug_tera_shard.png b/public/images/items/bug_tera_shard.png new file mode 100644 index 000000000..c08a3f29f Binary files /dev/null and b/public/images/items/bug_tera_shard.png differ diff --git a/public/images/items/dark_tera_shard.png b/public/images/items/dark_tera_shard.png new file mode 100644 index 000000000..4060f9142 Binary files /dev/null and b/public/images/items/dark_tera_shard.png differ diff --git a/public/images/items/dragon_tera_shard.png b/public/images/items/dragon_tera_shard.png new file mode 100644 index 000000000..8c16e2f8e Binary files /dev/null and b/public/images/items/dragon_tera_shard.png differ diff --git a/public/images/items/electric_tera_shard.png b/public/images/items/electric_tera_shard.png new file mode 100644 index 000000000..e4e1003ed Binary files /dev/null and b/public/images/items/electric_tera_shard.png differ diff --git a/public/images/items/fairy_tera_shard.png b/public/images/items/fairy_tera_shard.png new file mode 100644 index 000000000..83e19aeae Binary files /dev/null and b/public/images/items/fairy_tera_shard.png differ diff --git a/public/images/items/fighting_tera_shard.png b/public/images/items/fighting_tera_shard.png new file mode 100644 index 000000000..4241a9019 Binary files /dev/null and b/public/images/items/fighting_tera_shard.png differ diff --git a/public/images/items/fire_tera_shard.png b/public/images/items/fire_tera_shard.png new file mode 100644 index 000000000..74a04df16 Binary files /dev/null and b/public/images/items/fire_tera_shard.png differ diff --git a/public/images/items/flying_tera_shard.png b/public/images/items/flying_tera_shard.png new file mode 100644 index 000000000..bee186379 Binary files /dev/null and b/public/images/items/flying_tera_shard.png differ diff --git a/public/images/items/ghost_tera_shard.png b/public/images/items/ghost_tera_shard.png new file mode 100644 index 000000000..fd3557e55 Binary files /dev/null and b/public/images/items/ghost_tera_shard.png differ diff --git a/public/images/items/grass_tera_shard.png b/public/images/items/grass_tera_shard.png new file mode 100644 index 000000000..01bf4bde6 Binary files /dev/null and b/public/images/items/grass_tera_shard.png differ diff --git a/public/images/items/ground_tera_shard.png b/public/images/items/ground_tera_shard.png new file mode 100644 index 000000000..153bbd905 Binary files /dev/null and b/public/images/items/ground_tera_shard.png differ diff --git a/public/images/items/ice_tera_shard.png b/public/images/items/ice_tera_shard.png new file mode 100644 index 000000000..3e07acee3 Binary files /dev/null and b/public/images/items/ice_tera_shard.png differ diff --git a/public/images/items/normal_tera_shard.png b/public/images/items/normal_tera_shard.png new file mode 100644 index 000000000..fe2b9b93f Binary files /dev/null and b/public/images/items/normal_tera_shard.png differ diff --git a/public/images/items/poison_tera_shard.png b/public/images/items/poison_tera_shard.png new file mode 100644 index 000000000..b124fa051 Binary files /dev/null and b/public/images/items/poison_tera_shard.png differ diff --git a/public/images/items/psychic_tera_shard.png b/public/images/items/psychic_tera_shard.png new file mode 100644 index 000000000..0a5656cce Binary files /dev/null and b/public/images/items/psychic_tera_shard.png differ diff --git a/public/images/items/rock_tera_shard.png b/public/images/items/rock_tera_shard.png new file mode 100644 index 000000000..b4e6f8a29 Binary files /dev/null and b/public/images/items/rock_tera_shard.png differ diff --git a/public/images/items/steel_tera_shard.png b/public/images/items/steel_tera_shard.png new file mode 100644 index 000000000..b0b2ccb17 Binary files /dev/null and b/public/images/items/steel_tera_shard.png differ diff --git a/public/images/items/stellar_tera_shard.png b/public/images/items/stellar_tera_shard.png new file mode 100644 index 000000000..b6625066e Binary files /dev/null and b/public/images/items/stellar_tera_shard.png differ diff --git a/public/images/items/tera_orb.png b/public/images/items/tera_orb.png new file mode 100644 index 000000000..f4b6e4739 Binary files /dev/null and b/public/images/items/tera_orb.png differ diff --git a/public/images/items/water_tera_shard.png b/public/images/items/water_tera_shard.png new file mode 100644 index 000000000..c00c1b5c1 Binary files /dev/null and b/public/images/items/water_tera_shard.png differ diff --git a/public/images/types.json b/public/images/types.json index d8ca3cc41..2a15e6665 100644 --- a/public/images/types.json +++ b/public/images/types.json @@ -5,7 +5,7 @@ "format": "RGBA8888", "size": { "w": 32, - "h": 266 + "h": 280 }, "scale": 1, "frames": [ @@ -407,6 +407,27 @@ "w": 32, "h": 14 } + }, + { + "filename": "stellar", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 32, + "h": 14 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 32, + "h": 14 + }, + "frame": { + "x": 0, + "y": 266, + "w": 32, + "h": 14 + } } ] } @@ -414,6 +435,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:194223c9662d1ecd87e27433f731e65a:63fb5df5cbaa3edbf6f88332a579bdac:5961efbfbf4c56b8745347e7a663a32f$" + "smartupdate": "$TexturePacker:SmartUpdate:f14cf47d9a8f1d40c8e03aa6ba00fff3:6fc4227b57a95d429a1faad4280f7ec8:5961efbfbf4c56b8745347e7a663a32f$" } } diff --git a/public/images/types.png b/public/images/types.png index 0e07620b7..619a370a7 100644 Binary files a/public/images/types.png and b/public/images/types.png differ diff --git a/public/images/types/stellar.png b/public/images/types/stellar.png new file mode 100644 index 000000000..d10d1babe Binary files /dev/null and b/public/images/types/stellar.png differ diff --git a/public/images/ui/icon_tera.png b/public/images/ui/icon_tera.png new file mode 100644 index 000000000..c66a7ffc9 Binary files /dev/null and b/public/images/ui/icon_tera.png differ diff --git a/public/images/ui/type_tera.png b/public/images/ui/type_tera.png new file mode 100644 index 000000000..5c35966a6 Binary files /dev/null and b/public/images/ui/type_tera.png differ diff --git a/src/battle-phases.ts b/src/battle-phases.ts index 9f9c296f3..2bc918b79 100644 --- a/src/battle-phases.ts +++ b/src/battle-phases.ts @@ -6,7 +6,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMov import { Mode } from './ui/ui'; import { Command } from "./ui/command-ui-handler"; import { Stat } from "./data/pokemon-stat"; -import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyInstantReviveChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, PokemonFriendshipBoosterModifier } from "./modifier/modifier"; +import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyInstantReviveChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, PokemonFriendshipBoosterModifier, LapsingPokemonHeldItemModifier } from "./modifier/modifier"; import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler"; import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball"; import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims"; @@ -585,7 +585,7 @@ export class EncounterPhase extends BattlePhase { doSummon(); else { let message: string; - this.scene.executeWithSeedOffset(() => message = Phaser.Math.RND.pick(encounterMessages), this.scene.currentBattle.waveIndex); + this.scene.executeWithSeedOffset(() => message = Utils.randSeedItem(encounterMessages), this.scene.currentBattle.waveIndex); this.scene.ui.showDialogue(message, trainer.getName(), null, doSummon); } } @@ -1699,9 +1699,12 @@ export class BattleEndPhase extends BattlePhase { this.scene.clearEnemyHeldItemModifiers(); - const lapsingModifiers = this.scene.findModifiers(m => m instanceof LapsingPersistentModifier) as LapsingPersistentModifier[]; + const lapsingModifiers = this.scene.findModifiers(m => m instanceof LapsingPersistentModifier || m instanceof LapsingPokemonHeldItemModifier) as (LapsingPersistentModifier | LapsingPokemonHeldItemModifier)[]; for (let m of lapsingModifiers) { - if (!m.lapse()) + const args: any[] = []; + if (m instanceof LapsingPokemonHeldItemModifier) + args.push(this.scene.getPokemonById(m.pokemonId)); + if (!m.lapse(args)) this.scene.removeModifier(m); } @@ -2322,7 +2325,7 @@ export class WeatherEffectPhase extends CommonAnimPhase { }; this.executeForAll((pokemon: Pokemon) => { - const immune = !pokemon || !!pokemon.getTypes().filter(t => this.weather.isTypeDamageImmune(t)).length; + const immune = !pokemon || !!pokemon.getTypes(true).filter(t => this.weather.isTypeDamageImmune(t)).length; if (!immune) inflictDamage(pokemon); }); @@ -2753,7 +2756,7 @@ export class TrainerVictoryPhase extends BattlePhase { let showMessageAndEnd = () => this.end(); if (victoryMessages?.length) { let message: string; - this.scene.executeWithSeedOffset(() => message = Phaser.Math.RND.pick(victoryMessages), this.scene.currentBattle.waveIndex); + this.scene.executeWithSeedOffset(() => message = Utils.randSeedItem(victoryMessages), this.scene.currentBattle.waveIndex); const messagePages = message.split(/\$/g).map(m => m.trim()); for (let p = messagePages.length - 1; p >= 0; p--) { diff --git a/src/battle-scene.ts b/src/battle-scene.ts index c16aaf9d5..276b74f10 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -4,7 +4,7 @@ import { EncounterPhase, SummonPhase, NextEncounterPhase, NewBiomeEncounterPhase import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon'; import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies, speciesStarters } from './data/pokemon-species'; import * as Utils from './utils'; -import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier } from './modifier/modifier'; +import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier } from './modifier/modifier'; import { PokeballType } from './data/pokeball'; import { initAutoPlay } from './system/auto-play'; import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims'; @@ -49,6 +49,8 @@ import { Nature } from './data/nature'; import { SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger, pokemonFormChanges } from './data/pokemon-forms'; import { FormChangePhase, QuietFormChangePhase } from './form-change-phase'; import { BattleSpec } from './enums/battle-spec'; +import { getTypeRgb } from './data/type'; +import PokemonSpriteSparkleHandler from './sprite/pokemon-sprite-sparkle-handler'; const enableAuto = true; const quickStart = false; @@ -141,6 +143,8 @@ export default class BattleScene extends Phaser.Scene { public seed: string; public waveSeed: string; + private spriteSparkleHandler: PokemonSpriteSparkleHandler; + public fieldSpritePipeline: FieldSpritePipeline; public spritePipeline: SpritePipeline; @@ -235,6 +239,8 @@ export default class BattleScene extends Phaser.Scene { this.loadImage('achv_bar_4', 'ui'); this.loadImage('shiny_star', 'ui', 'shiny.png'); this.loadImage('icon_spliced', 'ui'); + this.loadImage('icon_tera', 'ui'); + this.loadImage('type_tera', 'ui'); this.loadImage('pb_tray_overlay_player', 'ui'); this.loadImage('pb_tray_overlay_enemy', 'ui'); @@ -318,8 +324,10 @@ export default class BattleScene extends Phaser.Scene { this.loadImage(`pkmn__sub`, 'pokemon', 'sub.png'); this.loadAtlas('battle_stats', 'effects'); this.loadAtlas('shiny', 'effects'); + this.loadImage('tera', 'effects'); this.loadAtlas('pb_particles', 'effects'); this.loadImage('evo_sparkle', 'effects'); + this.loadAtlas('tera_sparkle', 'effects'); this.load.video('evo_bg', 'images/effects/evo_bg.mp4', true); this.loadAtlas('pb', ''); @@ -501,6 +509,9 @@ export default class BattleScene extends Phaser.Scene { this.updateUIPositions(); + this.spriteSparkleHandler = new PokemonSpriteSparkleHandler(); + this.spriteSparkleHandler.setup(this); + this.party = []; let loadPokemonAssets = []; @@ -537,6 +548,15 @@ export default class BattleScene extends Phaser.Scene { showOnStart: true }); + this.anims.create({ + key: 'tera_sparkle', + frames: this.anims.generateFrameNumbers('tera_sparkle', { start: 0, end: 12 }), + frameRate: 18, + repeat: 0, + showOnStart: true, + hideOnComplete: true + }); + this.reset(); if (this.quickStart) { @@ -1036,6 +1056,18 @@ export default class BattleScene extends Phaser.Scene { return ret; } + addPokemonSprite(pokemon: Pokemon, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number, hasShadow: boolean = false, ignoreOverride: boolean = false): Phaser.GameObjects.Sprite { + const ret = this.addFieldSprite(x, y, texture, frame); + this.initPokemonSprite(ret, pokemon); + return ret; + } + + initPokemonSprite(sprite: Phaser.GameObjects.Sprite, pokemon?: Pokemon, hasShadow: boolean = false, ignoreOverride: boolean = false): Phaser.GameObjects.Sprite { + sprite.setPipeline(this.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: hasShadow, ignoreOverride: ignoreOverride, teraColor: pokemon ? getTypeRgb(pokemon.getTeraType()) : undefined }); + this.spriteSparkleHandler.add(sprite); + return sprite; + } + showFieldOverlay(duration: integer): Promise { return new Promise(resolve => { this.tweens.add({ @@ -1460,10 +1492,13 @@ export default class BattleScene extends Phaser.Scene { return new Promise(resolve => { const soundName = modifier.type.soundName; this.validateAchvs(ModifierAchv, modifier); + const modifiersToRemove: PersistentModifier[] = []; if (modifier instanceof PersistentModifier) { + if (modifier instanceof TerastallizeModifier) + modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId))); if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) { - if (modifier instanceof PokemonFormChangeItemModifier) - modifier.apply([ this.getPokemonById(modifier.pokemonId) ]); + if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) + modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]); if (playSound && !this.sound.get(soundName)) this.playSound(soundName); } else if (!virtual) { @@ -1471,6 +1506,9 @@ export default class BattleScene extends Phaser.Scene { this.queueMessage(`The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true); return this.addModifier(defaultModifierType.newModifier(), ignoreUpdate, playSound, false, instant).then(() => resolve()); } + + for (let rm of modifiersToRemove) + this.removeModifier(rm); if (!ignoreUpdate && !virtual) return this.updateModifiers(true, instant).then(() => resolve()); @@ -1509,9 +1547,17 @@ export default class BattleScene extends Phaser.Scene { }); } - addEnemyModifier(itemModifier: PersistentModifier, ignoreUpdate?: boolean, instant?: boolean): Promise { + addEnemyModifier(modifier: PersistentModifier, ignoreUpdate?: boolean, instant?: boolean): Promise { return new Promise(resolve => { - itemModifier.add(this.enemyModifiers, false, this); + const modifiersToRemove: PersistentModifier[] = []; + if (modifier instanceof TerastallizeModifier) + modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId, false))); + if ((modifier as PersistentModifier).add(this.enemyModifiers, false, this)) { + if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) + modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]); + for (let rm of modifiersToRemove) + this.removeModifier(rm, true); + } if (!ignoreUpdate) this.updateModifiers(false, instant).then(() => resolve()); else @@ -1586,7 +1632,15 @@ export default class BattleScene extends Phaser.Scene { else modifierChance = !isBoss ? 12 : 4; - this.getEnemyParty().forEach((enemyPokemon: EnemyPokemon, i: integer) => { + const party = this.getEnemyParty(); + + if (this.currentBattle.trainer) { + const modifiers = this.currentBattle.trainer.genModifiers(party); + for (let modifier of modifiers) + this.addEnemyModifier(modifier, true, true); + } + + party.forEach((enemyPokemon: EnemyPokemon, i: integer) => { let pokemonModifierChance = modifierChance; if (this.currentBattle.battleType === BattleType.TRAINER) pokemonModifierChance = Math.ceil(pokemonModifierChance * this.currentBattle.trainer.getPartyMemberModifierChanceMultiplier(i)); @@ -1657,33 +1711,27 @@ export default class BattleScene extends Phaser.Scene { const modifierIndex = modifiers.indexOf(modifier); if (modifierIndex > -1) { modifiers.splice(modifierIndex, 1); + if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) + modifier.apply([ this.getPokemonById(modifier.pokemonId), false ]); return true; } return false; } - getModifiers(modifierType: { new(...args: any[]): Modifier }, player?: boolean): PersistentModifier[] { - if (player === undefined) - player = true; + getModifiers(modifierType: { new(...args: any[]): Modifier }, player: boolean = true): PersistentModifier[] { return (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType); } - findModifiers(modifierFilter: ModifierPredicate, player?: boolean): PersistentModifier[] { - if (player === undefined) - player = true; + findModifiers(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier[] { return (player ? this.modifiers : this.enemyModifiers).filter(m => (modifierFilter as ModifierPredicate)(m)); } - findModifier(modifierFilter: ModifierPredicate, player?: boolean): PersistentModifier { - if (player === undefined) - player = true; + findModifier(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier { return (player ? this.modifiers : this.enemyModifiers).find(m => (modifierFilter as ModifierPredicate)(m)); } - applyModifiers(modifierType: { new(...args: any[]): Modifier }, player?: boolean, ...args: any[]): void { - if (player === undefined) - player = true; + applyModifiers(modifierType: { new(...args: any[]): Modifier }, player: boolean = true, ...args: any[]): void { const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args)); for (let modifier of modifiers) { if (modifier.apply(args)) @@ -1691,9 +1739,7 @@ export default class BattleScene extends Phaser.Scene { } } - applyModifier(modifierType: { new(...args: any[]): Modifier }, player?: boolean, ...args: any[]): PersistentModifier { - if (player === undefined) - player = true; + applyModifier(modifierType: { new(...args: any[]): Modifier }, player: boolean = true, ...args: any[]): PersistentModifier { const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args)); for (let modifier of modifiers) { if (modifier.apply(args)) { diff --git a/src/battle.ts b/src/battle.ts index 4834bbda3..48f6db50a 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -216,7 +216,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): Get const trainerTypes: TrainerType[] = []; for (let trainerPoolEntry of trainerPool) { const trainerType = Array.isArray(trainerPoolEntry) - ? Phaser.Math.RND.pick(trainerPoolEntry) + ? Utils.randSeedItem(trainerPoolEntry) : trainerPoolEntry; trainerTypes.push(trainerType); } diff --git a/src/data/ability.ts b/src/data/ability.ts index 1253b92ed..13b0357fe 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -322,7 +322,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr { applyPostDefend(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { if (hitResult < HitResult.NO_EFFECT) { const type = move.getMove().type; - const pokemonTypes = pokemon.getTypes(); + const pokemonTypes = pokemon.getTypes(true); if (pokemonTypes.length !== 1 || pokemonTypes[0] !== type) { pokemon.summonData.types = [ type ]; return true; @@ -333,7 +333,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr { } getTriggerMessage(pokemon: Pokemon, ...args: any[]): string { - return getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nmade it the ${Utils.toReadableString(Type[pokemon.getTypes()[0]])} type!`); + return getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nmade it the ${Utils.toReadableString(Type[pokemon.getTypes(true)[0]])} type!`); } } @@ -656,7 +656,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { const targets = pokemon.getOpponents(); let target: Pokemon; if (targets.length > 1) - pokemon.scene.executeWithSeedOffset(() => target = Phaser.Math.RND.pick(targets), pokemon.scene.currentBattle.waveIndex); + pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); else target = targets[0]; diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index 1c24e10f8..9e419c369 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -6,6 +6,7 @@ import * as Utils from "../utils"; import { BattlerIndex } from "../battle"; import stringify, { Element } from "json-stable-stringify"; import { Moves } from "./enums/moves"; +import { getTypeRgb } from "./type"; //import fs from 'vite-plugin-fs/browser'; export enum AnimFrameTarget { @@ -764,8 +765,7 @@ export abstract class BattleAnim { const spriteSource = isUser ? userSprite : targetSprite; if ((isUser ? u : t) === sprites.length) { let sprite: Phaser.GameObjects.Sprite; - sprite = scene.addFieldSprite(0, 0, spriteSource.texture, spriteSource.frame.name); - sprite.setPipeline(scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: true }); + sprite = scene.addPokemonSprite(isUser ? user : target, 0, 0, spriteSource.texture, spriteSource.frame.name, true); [ 'spriteColors', 'fusionSpriteColors' ].map(k => sprite.pipelineData[k] = (isUser ? user : target).getSprite().pipelineData[k]); spriteSource.on('animationupdate', (_anim, frame) => sprite.setFrame(frame.textureFrame)); scene.field.add(sprite); diff --git a/src/data/egg.ts b/src/data/egg.ts index 3ee5ed752..6aed81310 100644 --- a/src/data/egg.ts +++ b/src/data/egg.ts @@ -98,7 +98,7 @@ export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timesta let ret: Species; scene.executeWithSeedOffset(() => { - ret = Phaser.Math.RND.pick(legendarySpecies); + ret = Utils.randSeedItem(legendarySpecies); }, Utils.getSunday(new Date(timestamp)).getTime(), EGG_SEED.toString()); return ret; @@ -109,7 +109,7 @@ export function getTypeGachaTypeForTimestamp(scene: BattleScene, timestamp: inte let ret: Type; scene.executeWithSeedOffset(() => { - ret = Phaser.Math.RND.pick(types); + ret = Utils.randSeedItem(types); }, Utils.getSunday(new Date(timestamp)).getTime(), EGG_SEED.toString()); return ret; diff --git a/src/data/move.ts b/src/data/move.ts index e33002001..cf24bd125 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1813,7 +1813,7 @@ export class CopyTypeAttr extends MoveEffectAttr { if (!super.apply(user, target, move, args)) return false; - user.summonData.types = target.getTypes(); + user.summonData.types = target.getTypes(true); user.scene.queueMessage(getPokemonMessage(user, `'s type\nchanged to match ${target.name}'s!`)); diff --git a/src/data/pokemon-evolutions.ts b/src/data/pokemon-evolutions.ts index 303968b1b..bee2bc185 100644 --- a/src/data/pokemon-evolutions.ts +++ b/src/data/pokemon-evolutions.ts @@ -841,7 +841,7 @@ export const pokemonEvolutions: PokemonEvolutions = { new SpeciesEvolution(Species.GOGOAT, 32, null, null) ], [Species.PANCHAM]: [ - new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.getTypes(true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM) + new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.getTypes(false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM) ], [Species.ESPURR]: [ new SpeciesFormEvolution(Species.MEOWSTIC, '', '', 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)), diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 6caec2643..3ba9f5d0a 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -2372,6 +2372,7 @@ export const speciesStarters = { [Species.TOGEPI]: 3, [Species.NATU]: 2, [Species.MAREEP]: 3, + [Species.MARILL]: 4, [Species.HOPPIP]: 1, [Species.AIPOM]: 3, [Species.SUNKERN]: 1, diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 70a77b2a2..9523e8628 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -11,6 +11,7 @@ import { Species } from "./enums/species"; import { tmSpecies } from "./tms"; import { Type } from "./type"; import { initTrainerTypeDialogue } from "./dialogue"; +import { PersistentModifier, TerastallizeModifier } from "../modifier/modifier"; export enum TrainerPoolTier { COMMON, @@ -163,6 +164,7 @@ export const trainerPartyTemplates = { type PartyTemplateFunc = (scene: BattleScene) => TrainerPartyTemplate; type PartyMemberFunc = (scene: BattleScene, level: integer) => EnemyPokemon; +type GenModifiersFunc = (party: EnemyPokemon[]) => PersistentModifier[]; export interface PartyMemberFuncs { [key: integer]: PartyMemberFunc @@ -183,6 +185,7 @@ export class TrainerConfig { public encounterBgm: string; public femaleEncounterBgm: string; public victoryBgm: string; + public genModifiersFunc: GenModifiersFunc; public modifierRewardFuncs: ModifierTypeFunc[] = []; public partyTemplates: TrainerPartyTemplate[]; public partyTemplateFunc: PartyTemplateFunc; @@ -325,11 +328,16 @@ export class TrainerConfig { return this; } + setGenModifiersFunc(genModifiersFunc: GenModifiersFunc): TrainerConfig { + this.genModifiersFunc = genModifiersFunc; + return this; + } + setModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig { this.modifierRewardFuncs = modifierTypeFuncs.map(func => () => { const modifierTypeFunc = func(); const modifierType = modifierTypeFunc(); - modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc); + modifierType.withIdFromFunc(modifierTypeFunc); return modifierType; }); return this; @@ -352,6 +360,10 @@ export class TrainerConfig { this.setStaticParty(); this.setBattleBgm('battle_gym'); this.setVictoryBgm('victory_gym'); + this.setGenModifiersFunc(party => { + const waveIndex = party[0].scene.currentBattle.waveIndex; + return getRandomTeraModifiers(party, waveIndex >= 100 ? 1 : 0, specialtyTypes.length ? specialtyTypes : null); + }); return this; } @@ -373,6 +385,7 @@ export class TrainerConfig { this.setStaticParty(); this.setBattleBgm('battle_elite'); this.setVictoryBgm('victory_gym'); + this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 2, specialtyTypes.length ? specialtyTypes : null)); return this; } @@ -390,6 +403,7 @@ export class TrainerConfig { this.setStaticParty(); this.setBattleBgm('battle_champion'); this.setVictoryBgm('victory_champion'); + this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 3)); return this; } @@ -447,7 +461,7 @@ function getGymLeaderPartyTemplate(scene: BattleScene) { function getRandomPartyMemberFunc(speciesPool: Species[], postProcess?: (enemyPokemon: EnemyPokemon) => void): PartyMemberFunc { return (scene: BattleScene, level: integer) => { - const species = getPokemonSpecies(Phaser.Math.RND.pick(speciesPool)).getSpeciesForLevel(level, true, true, scene.currentBattle.trainer.config.isBoss); + const species = getPokemonSpecies(Utils.randSeedItem(speciesPool)).getSpeciesForLevel(level, true, true, scene.currentBattle.trainer.config.isBoss); return scene.addEnemyPokemon(getPokemonSpecies(species), level, true, undefined, undefined, postProcess); }; } @@ -461,6 +475,17 @@ function getSpeciesFilterRandomPartyMemberFunc(speciesFilter: PokemonSpeciesFilt }; } +function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, types?: Type[]): PersistentModifier[] { + const ret: PersistentModifier[] = []; + const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i); + for (let t = 0; t < Math.min(count, party.length); t++) { + const randomIndex = Utils.randSeedItem(partyMemberIndexes); + partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1); + ret.push(modifierTypes.TERA_SHARD().generateType(null, [ Utils.randSeedItem(types ? types : party[randomIndex].getTypes()) ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier); + } + return ret; +} + export const trainerConfigs: TrainerConfigs = { [TrainerType.UNKNOWN]: new TrainerConfig(0).setHasGenders(), [TrainerType.ACE_TRAINER]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER) @@ -753,7 +778,11 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ])) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) - .setSpeciesFilter(species => species.baseTotal >= 540), + .setSpeciesFilter(species => species.baseTotal >= 540) + .setGenModifiersFunc(party => { + const starter = party[0]; + return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; + }), [TrainerType.RIVAL_5]: new TrainerConfig(++t).setName('Finn').setHasGenders('Ivy').setTitle('Rival').setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_5) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ])) @@ -762,7 +791,11 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.RAYQUAZA ], p => { p.setBoss(); p.pokeball = PokeballType.MASTER_BALL; - })), + })) + .setGenModifiersFunc(party => { + const starter = party[0]; + return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; + }), [TrainerType.RIVAL_6]: new TrainerConfig(++t).setName('Finn').setHasGenders('Ivy').setTitle('Rival').setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm('final').setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_6) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT ])) @@ -772,7 +805,11 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(); p.pokeball = PokeballType.MASTER_BALL; p.formIndex = 1; - })), + })) + .setGenModifiersFunc(party => { + const starter = party[0]; + return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ]; + }), }; (function() { diff --git a/src/data/type.ts b/src/data/type.ts index 51aa94c8d..9fb2c9c1b 100644 --- a/src/data/type.ts +++ b/src/data/type.ts @@ -17,7 +17,8 @@ export enum Type { ICE, DRAGON, DARK, - FAIRY + FAIRY, + STELLAR }; export type TypeDamageMultiplier = 0 | 0.25 | 0.5 | 1 | 2 | 4; @@ -491,5 +492,52 @@ export function getTypeDamageMultiplier(attackType: integer, defType: integer): default: return 0; } + case Type.STELLAR: + return 1; } +} + +export function getTypeRgb(type: Type): [ integer, integer, integer ] { + switch (type) { + case Type.NORMAL: + return [ 168, 168, 120 ]; + case Type.FIGHTING: + return [ 192, 48, 40 ]; + case Type.FLYING: + return [ 168, 144, 240 ]; + case Type.POISON: + return [ 160, 64, 160 ]; + case Type.GROUND: + return [ 224, 192, 104 ]; + case Type.ROCK: + return [ 184, 160, 56 ]; + case Type.BUG: + return [ 168, 184, 32 ]; + case Type.GHOST: + return [ 112, 88, 152 ]; + case Type.STEEL: + return [ 184, 184, 208 ]; + case Type.FIRE: + return [ 240, 128, 48 ]; + case Type.WATER: + return [ 104, 144, 240 ]; + case Type.GRASS: + return [ 120, 200, 80 ]; + case Type.ELECTRIC: + return [ 248, 208, 48 ]; + case Type.PSYCHIC: + return [ 248, 88, 136 ]; + case Type.ICE: + return [ 152, 216, 216 ]; + case Type.DRAGON: + return [ 112, 56, 248 ]; + case Type.DARK: + return [ 112, 88, 72 ]; + case Type.FAIRY: + return [ 232, 136, 200 ]; + case Type.STELLAR: + return [ 255, 255, 255 ]; + default: + return [ 0, 0, 0 ]; + } } \ No newline at end of file diff --git a/src/evolution-phase.ts b/src/evolution-phase.ts index 3e5c0bdc0..1bc0b9441 100644 --- a/src/evolution-phase.ts +++ b/src/evolution-phase.ts @@ -8,6 +8,7 @@ import { Mode } from "./ui/ui"; import { LearnMovePhase } from "./battle-phases"; import { cos, sin } from "./anims"; import { PlayerPokemon } from "./pokemon"; +import { getTypeRgb } from "./data/type"; export class EvolutionPhase extends BattlePhase { protected pokemon: PlayerPokemon; @@ -70,7 +71,7 @@ export class EvolutionPhase extends BattlePhase { this.evolutionBgOverlay.setAlpha(0); this.evolutionContainer.add(this.evolutionBgOverlay); - const getPokemonSprite = () => this.scene.addFieldSprite(this.evolutionBaseBg.displayWidth / 2, this.evolutionBaseBg.displayHeight / 2, `pkmn__sub`); + const getPokemonSprite = () => this.scene.addPokemonSprite(this.pokemon, this.evolutionBaseBg.displayWidth / 2, this.evolutionBaseBg.displayHeight / 2, `pkmn__sub`); this.evolutionContainer.add((this.pokemonSprite = getPokemonSprite())); this.evolutionContainer.add((this.pokemonTintSprite = getPokemonSprite())); @@ -90,7 +91,7 @@ export class EvolutionPhase extends BattlePhase { [ this.pokemonSprite, this.pokemonTintSprite, this.pokemonEvoSprite, this.pokemonEvoTintSprite ].map(sprite => { sprite.play(this.pokemon.getSpriteKey(true)); - sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false }); + sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) }); sprite.pipelineData['ignoreTimeTint'] = true; [ 'spriteColors', 'fusionSpriteColors' ].map(k => { if (this.pokemon.summonData?.speciesForm) diff --git a/src/form-change-phase.ts b/src/form-change-phase.ts index 44b3e2b8e..a44cdd6cb 100644 --- a/src/form-change-phase.ts +++ b/src/form-change-phase.ts @@ -10,6 +10,7 @@ import PartyUiHandler from "./ui/party-ui-handler"; import { BattlePhase } from "./battle-phase"; import { BattleSpec } from "./enums/battle-spec"; import { MovePhase, PokemonHealPhase } from "./battle-phases"; +import { getTypeRgb } from "./data/type"; export class FormChangePhase extends EvolutionPhase { private formChange: SpeciesFormChange; @@ -184,10 +185,10 @@ export class QuietFormChangePhase extends BattlePhase { const preName = this.pokemon.name; const getPokemonSprite = () => { - const sprite = this.scene.addFieldSprite(this.pokemon.x + this.pokemon.getSprite().x, this.pokemon.y + this.pokemon.getSprite().y, `pkmn__sub`); + const sprite = this.scene.addPokemonSprite(this.pokemon, this.pokemon.x + this.pokemon.getSprite().x, this.pokemon.y + this.pokemon.getSprite().y, `pkmn__sub`); sprite.setOrigin(0.5, 1); sprite.play(this.pokemon.getSpriteKey()).stop(); - sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false }); + sprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false, teraColor: getTypeRgb(this.pokemon.getTeraType()) }); [ 'spriteColors', 'fusionSpriteColors' ].map(k => { if (this.pokemon.summonData?.speciesForm) k += 'Base'; diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index b132003a4..7a9edb83a 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -59,6 +59,11 @@ export class ModifierType { this.tier = tier; } + withIdFromFunc(func: ModifierTypeFunc): ModifierType { + this.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === func); + return this; + } + newModifier(...args: any[]): Modifier { return this.newModifierFunc(this, args); } @@ -615,6 +620,20 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator { } } +export class TerastallizeModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType { + private teraType: Type; + + constructor(teraType: Type) { + super(`${Utils.toReadableString(Type[teraType])} Tera Shard`, `${Utils.toReadableString(Type[teraType])} Terastallizes the holder for up to 10 battles`, (type, args) => new Modifiers.TerastallizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType), null, 'tera_shard'); + + this.teraType = teraType; + } + + getPregenArgs(): any[] { + return [ this.teraType ]; + } +} + export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemModifierType { constructor(name: string, chancePercent: integer, iconImage?: string, group?: string, soundName?: string) { super(name, `Upon attacking, there is a ${chancePercent}% chance the foe's held item will be stolen`, (type, args) => new Modifiers.ContactHeldItemTransferChanceModifier(type, (args[0] as Pokemon).id, chancePercent), iconImage, group, soundName); @@ -670,7 +689,8 @@ export const modifierTypes = { FORM_CHANGE_ITEM: () => new FormChangeItemModifierTypeGenerator(), MEGA_BRACELET: () => new ModifierType('Mega Bracelet', 'Mega stones become available', (type, _args) => new Modifiers.MegaEvolutionAccessModifier(type)), - DYNAMAX_BAND: () => new ModifierType('Dynamax Band', 'Gigantamaxing becomes available', (type, _args) => new Modifiers.GigantamaxAccessModifier(type)), + DYNAMAX_BAND: () => new ModifierType('Dynamax Band', 'Max Mushrooms become available', (type, _args) => new Modifiers.GigantamaxAccessModifier(type)), + TERA_ORB: () => new ModifierType('Tera Orb', 'Tera Shards become available', (type, _args) => new Modifiers.TerastallizeAccessModifier(type)), MAP: () => new ModifierType('Map', 'Allows you to choose your destination at a crossroads', (type, _args) => new Modifiers.MapModifier(type)), @@ -721,6 +741,20 @@ export const modifierTypes = { ATTACK_TYPE_BOOSTER: () => new AttackTypeBoosterModifierTypeGenerator(), + TERA_SHARD: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { + if (pregenArgs) + return new TerastallizeModifierType(pregenArgs[0] as Type); + if (!party[0].scene.getModifiers(Modifiers.TerastallizeAccessModifier).length) + return null; + let type: Type; + if (!Utils.randInt(3)) { + const partyMemberTypes = party.map(p => p.getTypes(false, true)).flat(); + type = Utils.randSeedItem(partyMemberTypes); + } else + type = Utils.randSeedInt(64) ? Utils.randSeedInt(18) as Type : Type.STELLAR; + return new TerastallizeModifierType(type); + }), + BERRY: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => { if (pregenArgs) return new BerryModifierType(pregenArgs[0] as BerryType); @@ -902,6 +936,7 @@ const modifierPool = { return Math.min(Math.ceil(highestPartyLevel / 20), 4); }), new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3), + new WeightedModifierType(modifierTypes.TERA_SHARD, 1), new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode === GameMode.SPLICED_ENDLESS && party.filter(p => !p.fusionSpecies).length > 1 ? 4 : 0), new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode === GameMode.SPLICED_ENDLESS && party.filter(p => p.fusionSpecies).length ? 6 : 0), ].map(m => { m.setTier(ModifierTier.GREAT); return m; }), @@ -934,6 +969,7 @@ const modifierPool = { new WeightedModifierType(modifierTypes.OVAL_CHARM, 2), new WeightedModifierType(modifierTypes.ABILITY_CHARM, 2), new WeightedModifierType(modifierTypes.IV_SCANNER, 2), + new WeightedModifierType(modifierTypes.TERA_ORB, 3), new WeightedModifierType(modifierTypes.EXP_BALANCE, 1), new WeightedModifierType(modifierTypes.FORM_CHANGE_ITEM, 1), new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode !== GameMode.SPLICED_ENDLESS && party.filter(p => p.fusionSpecies).length ? 3 : 0), @@ -1054,7 +1090,10 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod pool[t].reduce((total: integer, modifierType: WeightedModifierType) => { const weightedModifierType = modifierType as WeightedModifierType; const existingModifiers = party[0].scene.findModifiers(m => (m.type.generatorId || m.type.id) === weightedModifierType.modifierType.id, player); - const weight = !existingModifiers.length || existingModifiers.filter(m => m.stackCount < m.getMaxStackCount(party[0].scene, true)).length + const weight = !existingModifiers.length + || weightedModifierType.modifierType instanceof PokemonHeldItemModifierType + || (weightedModifierType.modifierType instanceof ModifierTypeGenerator && weightedModifierType.modifierType.generateType(party) instanceof PokemonHeldItemModifierType) + || existingModifiers.find(m => m.stackCount < m.getMaxStackCount(party[0].scene, true)) ? weightedModifierType.weight instanceof Function ? (weightedModifierType.weight as Function)(party) : weightedModifierType.weight as integer diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index b1772f9de..0d8b81b43 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -265,7 +265,7 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { this.battlesLeft = battlesLeft; } - lapse(): boolean { + lapse(args: any[]): boolean { return !!--this.battlesLeft; } @@ -281,6 +281,10 @@ export abstract class LapsingPersistentModifier extends PersistentModifier { return container; } + getBattlesLeft(): integer { + return this.battlesLeft; + } + getMaxStackCount(scene: BattleScene, forThreshold?: boolean): number { return 99; } @@ -404,6 +408,24 @@ export class GigantamaxAccessModifier extends PersistentModifier { } } +export class TerastallizeAccessModifier extends PersistentModifier { + constructor(type: ModifierType, stackCount?: integer) { + super(type, stackCount); + } + + clone(): TerastallizeAccessModifier { + return new TerastallizeAccessModifier(this.type, this.stackCount); + } + + apply(args: any[]): boolean { + return true; + } + + getMaxStackCount(scene: BattleScene): integer { + return 1; + } +} + export abstract class PokemonHeldItemModifier extends PersistentModifier { public pokemonId: integer; @@ -481,6 +503,85 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { abstract getMaxHeldItemCount(pokemon: Pokemon): integer } +export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModifier { + protected battlesLeft: integer; + + constructor(type: ModifierTypes.ModifierType, pokemonId: integer, battlesLeft?: integer, stackCount?: integer) { + super(type, pokemonId, stackCount); + + this.battlesLeft = battlesLeft; + } + + lapse(args: any[]): boolean { + return !!--this.battlesLeft; + } + + getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container { + const container = super.getIcon(scene, forSummary); + + if (this.getPokemon(scene).isPlayer()) { + const battleCountText = addTextObject(scene, 27, 0, this.battlesLeft.toString(), TextStyle.PARTY, { fontSize: '66px', color: '#f89890' }); + battleCountText.setShadow(0, 0, null); + battleCountText.setStroke('#984038', 16) + battleCountText.setOrigin(1, 0); + container.add(battleCountText); + } + + return container; + } + + getBattlesLeft(): integer { + return this.battlesLeft; + } + + getMaxStackCount(scene: BattleScene, forThreshold?: boolean): number { + return 1; + } +} + +export class TerastallizeModifier extends LapsingPokemonHeldItemModifier { + public teraType: Type; + + constructor(type: ModifierTypes.TerastallizeModifierType, pokemonId: integer, teraType: Type, battlesLeft?: integer, stackCount?: integer) { + super(type, pokemonId, battlesLeft || 10, stackCount); + + this.teraType = teraType; + } + + matchType(modifier: Modifier): boolean { + if (modifier instanceof TerastallizeModifier && modifier.teraType === this.teraType) + return true; + return false; + } + + clone(): TerastallizeModifier { + return new TerastallizeModifier(this.type as ModifierTypes.TerastallizeModifierType, this.pokemonId, this.teraType, this.battlesLeft, this.stackCount); + } + + getArgs(): any[] { + return [ this.pokemonId, this.teraType, this.battlesLeft ]; + } + + apply(args: any[]): boolean { + const pokemon = args[0] as Pokemon; + pokemon.updateSpritePipelineData(); + return true; + } + + lapse(args: any[]): boolean { + const ret = super.lapse(args); + if (!ret) { + const pokemon = args[0] as Pokemon; + pokemon.updateSpritePipelineData(); + } + return ret; + } + + getMaxHeldItemCount(pokemon: Pokemon): integer { + return 1; + } +} + export class PokemonBaseStatModifier extends PokemonHeldItemModifier { protected stat: Stat; @@ -1323,8 +1424,19 @@ export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier { apply(args: any[]): boolean { const pokemon = args[0] as Pokemon; + const active = args[1] as boolean; - return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger); + let switchActive = this.active && !active; + + if (switchActive) + this.active = false; + + const ret = pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger); + + if (switchActive) + this.active = true; + + return ret; } getMaxHeldItemCount(pokemon: Pokemon): integer { diff --git a/src/pipelines/field-sprite.ts b/src/pipelines/field-sprite.ts index a0885307d..5fdf8f438 100644 --- a/src/pipelines/field-sprite.ts +++ b/src/pipelines/field-sprite.ts @@ -34,8 +34,7 @@ vec3 blendHardLight(vec3 base, vec3 blend) { return blendOverlay(blend, base); } -void main() -{ +void main() { vec4 texture; %forloop% @@ -83,13 +82,11 @@ void main() `; const spriteVertShader = ` -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else precision mediump float; -#endif uniform mat4 uProjectionMatrix; +uniform int uRoundPixels; +uniform vec2 uResolution; attribute vec2 inPosition; attribute vec2 inTexCoord; @@ -99,15 +96,19 @@ attribute vec4 inTint; varying vec2 outTexCoord; varying float outTexId; +varying vec2 outPosition; varying float outTintEffect; varying vec4 outTint; -void main() -{ +void main() { gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0); - + if (uRoundPixels == 1) + { + gl_Position.xy = floor(((gl_Position.xy + 1.0) * 0.5 * uResolution) + 0.5) / uResolution * 2.0 - 1.0; + } outTexCoord = inTexCoord; outTexId = inTexId; + outPosition = inPosition; outTint = inTint; outTintEffect = inTintEffect; } diff --git a/src/pipelines/sprite.ts b/src/pipelines/sprite.ts index 2a3bf79e6..e9f2a51e7 100644 --- a/src/pipelines/sprite.ts +++ b/src/pipelines/sprite.ts @@ -23,12 +23,16 @@ uniform int isOutside; uniform vec3 dayTint; uniform vec3 duskTint; uniform vec3 nightTint; +uniform float teraTime; +uniform vec3 teraColor; uniform int hasShadow; uniform int yCenter; uniform float fieldScale; uniform float vCutoff; uniform vec2 relPosition; +uniform vec2 texFrameUv; uniform vec2 size; +uniform vec2 texSize; uniform float yOffset; uniform vec4 tone; uniform ivec4 spriteColors[32]; @@ -48,11 +52,107 @@ vec3 blendHardLight(vec3 base, vec3 blend) { return blendOverlay(blend, base); } -void main() -{ - vec4 texture; +float hue2rgb(float f1, float f2, float hue) { + if (hue < 0.0) + hue += 1.0; + else if (hue > 1.0) + hue -= 1.0; + float res; + if ((6.0 * hue) < 1.0) + res = f1 + (f2 - f1) * 6.0 * hue; + else if ((2.0 * hue) < 1.0) + res = f2; + else if ((3.0 * hue) < 2.0) + res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0; + else + res = f1; + return res; +} - %forloop% +vec3 rgb2hsl(vec3 color) { + vec3 hsl; + + float fmin = min(min(color.r, color.g), color.b); + float fmax = max(max(color.r, color.g), color.b); + float delta = fmax - fmin; + + hsl.z = (fmax + fmin) / 2.0; + + if (delta == 0.0) { + hsl.x = 0.0; + hsl.y = 0.0; + } else { + if (hsl.z < 0.5) + hsl.y = delta / (fmax + fmin); + else + hsl.y = delta / (2.0 - fmax - fmin); + + float deltaR = (((fmax - color.r) / 6.0) + (delta / 2.0)) / delta; + float deltaG = (((fmax - color.g) / 6.0) + (delta / 2.0)) / delta; + float deltaB = (((fmax - color.b) / 6.0) + (delta / 2.0)) / delta; + + if (color.r == fmax ) + hsl.x = deltaB - deltaG; + else if (color.g == fmax) + hsl.x = (1.0 / 3.0) + deltaR - deltaB; + else if (color.b == fmax) + hsl.x = (2.0 / 3.0) + deltaG - deltaR; + + if (hsl.x < 0.0) + hsl.x += 1.0; + else if (hsl.x > 1.0) + hsl.x -= 1.0; + } + + return hsl; +} + +vec3 hsl2rgb(vec3 hsl) { + vec3 rgb; + + if (hsl.y == 0.0) + rgb = vec3(hsl.z); + else { + float f2; + + if (hsl.z < 0.5) + f2 = hsl.z * (1.0 + hsl.y); + else + f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z); + + float f1 = 2.0 * hsl.z - f2; + + rgb.r = hue2rgb(f1, f2, hsl.x + (1.0/3.0)); + rgb.g = hue2rgb(f1, f2, hsl.x); + rgb.b= hue2rgb(f1, f2, hsl.x - (1.0/3.0)); + } + + return rgb; +} + +vec3 blendHue(vec3 base, vec3 blend) { + vec3 baseHSL = rgb2hsl(base); + return hsl2rgb(vec3(rgb2hsl(blend).r, baseHSL.g, baseHSL.b)); +} + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +void main() { + vec4 texture = texture2D(uMainSampler[0], outTexCoord); for (int i = 0; i < 32; i++) { if (spriteColors[i][3] == 0) @@ -73,6 +173,24 @@ void main() // Multiply texture tint vec4 color = texture * texel; + if (color.a > 0.0 && teraColor.r > 0.0 && teraColor.g > 0.0 && teraColor.b > 0.0) { + vec2 relUv = vec2((outTexCoord.x - texFrameUv.x) / (size.x / texSize.x), (outTexCoord.y - texFrameUv.y) / (size.y / texSize.y)); + vec2 teraTexCoord = vec2(relUv.x * (size.x / 200.0), relUv.y * (size.y / 120.0)); + vec4 teraCol = texture2D(uMainSampler[1], teraTexCoord); + float floorValue = 86.0 / 255.0; + vec3 teraPatternHsv = rgb2hsv(teraCol.rgb); + teraCol.rgb = hsv2rgb(vec3((teraPatternHsv.b - floorValue) * 4.0 + teraTexCoord.x * fieldScale / 2.0 + teraTexCoord.y * fieldScale / 2.0 + teraTime * 255.0, teraPatternHsv.b, teraPatternHsv.b)); + + color.rgb = mix(color.rgb, blendHue(color.rgb, teraColor), 0.625); + teraCol.rgb = mix(teraCol.rgb, teraColor, 0.5); + color.rgb = blendOverlay(color.rgb, teraCol.rgb); + + if (teraColor.r < 1.0 || teraColor.g < 1.0 || teraColor.b < 1.0) { + vec3 teraColHsv = rgb2hsv(teraColor); + color.rgb = mix(color.rgb, teraColor, (1.0 - teraColHsv.g) / 2.0); + } + } + if (outTintEffect == 1.0) { // Solid color + texture alpha color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a); @@ -110,7 +228,7 @@ void main() dayNightTint = mix(duskTint, dayTint, (time - 0.875) / 0.125); } - color = vec4(blendHardLight(color.rgb, dayNightTint), color.a); + color.rgb = blendHardLight(color.rgb, dayNightTint); } if (hasShadow == 1) { @@ -144,13 +262,11 @@ void main() `; const spriteVertShader = ` -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else precision mediump float; -#endif uniform mat4 uProjectionMatrix; +uniform int uRoundPixels; +uniform vec2 uResolution; attribute vec2 inPosition; attribute vec2 inTexCoord; @@ -159,6 +275,7 @@ attribute float inTintEffect; attribute vec4 inTint; varying vec2 outTexCoord; +varying vec2 outtexFrameUv; varying float outTexId; varying vec2 outPosition; varying float outTintEffect; @@ -167,7 +284,10 @@ varying vec4 outTint; void main() { gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0); - + if (uRoundPixels == 1) + { + gl_Position.xy = floor(((gl_Position.xy + 1.0) * 0.5 * uResolution) + 0.5) / uResolution * 2.0 - 1.0; + } outTexCoord = inTexCoord; outTexId = inTexId; outPosition = inPosition; @@ -193,10 +313,14 @@ export default class SpritePipeline extends FieldSpritePipeline { onPreRender(): void { super.onPreRender(); + this.set1f('teraTime', 0); + this.set3fv('teraColor', [ 0, 0, 0 ]); this.set1i('hasShadow', 0); this.set1i('yCenter', 0); this.set2f('relPosition', 0, 0); + this.set2f('texFrameUv', 0, 0); this.set2f('size', 0, 0); + this.set2f('texSize', 0, 0); this.set1f('yOffset', 0); this.set4fv('tone', this._tone); } @@ -208,6 +332,7 @@ export default class SpritePipeline extends FieldSpritePipeline { const data = sprite.pipelineData; const tone = data['tone'] as number[]; + const teraColor = data['teraColor'] as integer[] ?? [ 0, 0, 0 ]; const hasShadow = data['hasShadow'] as boolean; const ignoreOverride = data['ignoreOverride'] as boolean; const spriteColors = (ignoreOverride && data['spriteColorsBase']) || data['spriteColors'] || [] as number[][]; @@ -215,7 +340,6 @@ export default class SpritePipeline extends FieldSpritePipeline { const isEntityObj = sprite.parentContainer instanceof Pokemon || sprite.parentContainer instanceof Trainer; const field = isEntityObj ? sprite.parentContainer.parentContainer : sprite.parentContainer; - const fieldScaleRatio = field.scale / 6; const position = isEntityObj ? [ sprite.parentContainer.x, sprite.parentContainer.y ] : [ sprite.x, sprite.y ]; @@ -224,13 +348,18 @@ export default class SpritePipeline extends FieldSpritePipeline { position[0] += -(sprite.width - (sprite.frame.width)) / 2 + sprite.frame.x; if (sprite.originY === 0.5) position[1] += (sprite.height / 2) * ((isEntityObj ? sprite.parentContainer : sprite).scale - 1); + this.set1f('teraTime', (this.game.getTime() % 500000) / 500000); + this.set3fv('teraColor', teraColor.map(c => c / 255)); this.set1i('hasShadow', hasShadow ? 1 : 0); this.set1i('yCenter', sprite.originY === 0.5 ? 1 : 0); this.set1f('fieldScale', field.scale); this.set2f('relPosition', position[0], position[1]); + this.set2f('texFrameUv', sprite.frame.u0, sprite.frame.v0); this.set2f('size', sprite.frame.width, sprite.height); + this.set2f('texSize', sprite.texture.source[0].width, sprite.texture.source[0].height); this.set1f('yOffset', sprite.height - sprite.frame.height * (isEntityObj ? sprite.parentContainer.scale : sprite.scale)); this.set4fv('tone', tone); + this.bindTexture(this.game.textures.get('tera').source[0].glTexture, 1); const emptyColors = [ 0, 0, 0, 0 ]; const flatSpriteColors: integer[] = []; const flatFusionSpriteColors: integer[] = []; diff --git a/src/pokemon.ts b/src/pokemon.ts index 9edc208de..6465a683e 100644 --- a/src/pokemon.ts +++ b/src/pokemon.ts @@ -2,13 +2,13 @@ import Phaser from 'phaser'; import BattleScene, { AnySound } from './battle-scene'; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from './ui/battle-info'; import { Moves } from "./data/enums/moves"; -import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, AttackMove, AddBattlerTagAttr, OneHitKOAttr } from "./data/move"; +import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr } from "./data/move"; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies } from './data/pokemon-species'; import * as Utils from './utils'; -import { Type, TypeDamageMultiplier, getTypeDamageMultiplier } from './data/type'; +import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from './data/type'; import { getLevelTotalExp } from './data/exp'; import { Stat } from './data/pokemon-stat'; -import { AttackTypeBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempBattleStatBoosterModifier } from './modifier/modifier'; +import { AttackTypeBoosterModifier, DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempBattleStatBoosterModifier, TerastallizeModifier } from './modifier/modifier'; import { PokeballType } from './data/pokeball'; import { Gender } from './data/gender'; import { initMoveAnim, loadMoveAnimAssets } from './data/battle-anims'; @@ -203,9 +203,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.fieldUI.addAt(this.battleInfo, 0); const getSprite = (hasShadow?: boolean) => { - const ret = this.scene.addFieldSprite(0, 0, `pkmn__${this.isPlayer() ? 'back__' : ''}sub`); + const ret = this.scene.addPokemonSprite(this, 0, 0, `pkmn__${this.isPlayer() ? 'back__' : ''}sub`, undefined, true); ret.setOrigin(0.5, 1); - ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow }); + ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, teraColor: getTypeRgb(this.getTeraType()) }); return ret; }; @@ -406,6 +406,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return 1; } + updateSpritePipelineData(): void { + [ this.getSprite(), this.getTintSprite() ].map(s => s.pipelineData['teraColor'] = getTypeRgb(this.getTeraType())); + this.updateInfo(true); + } + initShinySparkle(): void { const shinySparkle = this.scene.addFieldSprite(0, 0, 'shiny'); shinySparkle.setVisible(false); @@ -614,26 +619,32 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return this.getLevelMoves(1, true).filter(lm => !this.moveset.filter(m => m.moveId === lm).length).filter((move: Moves, i: integer, array: Moves[]) => array.indexOf(move) === i); } - getTypes(ignoreOverride?: boolean): Type[] { + getTypes(includeTeraType = false, ignoreOverride?: boolean): Type[] { const types = []; - if (!ignoreOverride && this.summonData?.types) - this.summonData.types.forEach(t => types.push(t)); - else { - const speciesForm = this.getSpeciesForm(); - - types.push(speciesForm.type1); + if (includeTeraType) { + const teraType = this.getTeraType(); + if (teraType != Type.UNKNOWN) + types.push(teraType); + } else { + if (!ignoreOverride && this.summonData?.types) + this.summonData.types.forEach(t => types.push(t)); + else { + const speciesForm = this.getSpeciesForm(); + + types.push(speciesForm.type1); - const fusionSpeciesForm = this.getFusionSpeciesForm(); - if (fusionSpeciesForm) { - if (fusionSpeciesForm.type2 !== null && fusionSpeciesForm.type2 !== speciesForm.type1) - types.push(fusionSpeciesForm.type2); - else if (fusionSpeciesForm.type1 !== speciesForm.type1) - types.push(fusionSpeciesForm.type1); + const fusionSpeciesForm = this.getFusionSpeciesForm(); + if (fusionSpeciesForm) { + if (fusionSpeciesForm.type2 !== null && fusionSpeciesForm.type2 !== speciesForm.type1) + types.push(fusionSpeciesForm.type2); + else if (fusionSpeciesForm.type1 !== speciesForm.type1) + types.push(fusionSpeciesForm.type1); + } + + if (types.length === 1 && speciesForm.type2 !== null) + types.push(speciesForm.type2); } - - if (types.length === 1 && speciesForm.type2 !== null) - types.push(speciesForm.type2); } if (this.getTag(BattlerTagType.IGNORE_FLYING) || this.scene.arena.getTag(ArenaTagType.GRAVITY)) { @@ -649,7 +660,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } isOfType(type: Type) { - return this.getTypes().indexOf(type) > -1; + return this.getTypes(true).indexOf(type) > -1; } getAbility(): Ability { @@ -677,14 +688,29 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return weight.value; } + getTeraType(): Type { + const teraModifier = this.scene.findModifier(m => m instanceof TerastallizeModifier + && m.pokemonId === this.id && !!m.getBattlesLeft(), this.isPlayer()) as TerastallizeModifier; + if (teraModifier) + return teraModifier.teraType; + + return Type.UNKNOWN; + } + + isTerastallized(): boolean { + return this.getTeraType() !== Type.UNKNOWN; + } + getAttackMoveEffectiveness(moveType: Type): TypeDamageMultiplier { - const types = this.getTypes(); + if (moveType === Type.STELLAR) + return this.isTerastallized() ? 2 : 1; + const types = this.getTypes(true); return getTypeDamageMultiplier(moveType, types[0]) * (types.length > 1 ? getTypeDamageMultiplier(moveType, types[1]) : 1) as TypeDamageMultiplier; } getMatchupScore(pokemon: Pokemon): number { - const types = this.getTypes(); - const enemyTypes = pokemon.getTypes(); + const types = this.getTypes(true); + const enemyTypes = pokemon.getTypes(true); let atkScore = pokemon.getAttackMoveEffectiveness(types[0]); let defScore = 1 / this.getAttackMoveEffectiveness(enemyTypes[0]); if (types.length > 1) @@ -965,7 +991,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const cancelled = new Utils.BooleanHolder(false); const typeless = !!move.getAttrs(TypelessAttr).length; - const types = this.getTypes(); + const types = this.getTypes(true); const typeMultiplier = new Utils.NumberHolder(!typeless && moveCategory !== MoveCategory.STATUS ? getTypeDamageMultiplier(move.type, types[0]) * (types.length > 1 ? getTypeDamageMultiplier(move.type, types[1]) : 1) : 1); @@ -977,6 +1003,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { case MoveCategory.SPECIAL: const isPhysical = moveCategory === MoveCategory.PHYSICAL; const power = new Utils.NumberHolder(move.power); + const sourceTeraType = source.getTeraType(); + if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === move.type && power.value < 60 && move.priority <= 0 && !move.getAttrs(MultiHitAttr).length) + power.value = 60; applyPreAttackAbAttrs(VariableMovePowerAbAttr, source, this, battlerMove, power); if (!typeless) @@ -1011,13 +1040,21 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } const sourceAtk = source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this); const targetDef = this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source); - const sourceTypes = source.getTypes(); - const stabMultiplier = new Utils.NumberHolder(sourceTypes[0] === move.type || (sourceTypes.length > 1 && sourceTypes[1] === move.type) ? 1.5 : 1); const criticalMultiplier = isCritical ? 2 : 1; const isTypeImmune = (typeMultiplier.value * weatherTypeMultiplier) === 0; + const sourceTypes = source.getTypes(); + const matchesSourceType = sourceTypes[0] === move.type || (sourceTypes.length > 1 && sourceTypes[1] === move.type); + let stabMultiplier = new Utils.NumberHolder(1); + if (sourceTeraType === Type.UNKNOWN && matchesSourceType) + stabMultiplier.value += 0.5; + else if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === move.type) + stabMultiplier.value += 0.5; applyAbAttrs(StabBoostAbAttr, source, null, stabMultiplier); + if (sourceTeraType !== Type.UNKNOWN && matchesSourceType) + stabMultiplier.value = Math.min(stabMultiplier.value + 0.5, 2.25); + if (!isTypeImmune) { damage.value = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk / targetDef) / 50) + 2) * stabMultiplier.value * typeMultiplier.value * weatherTypeMultiplier * ((this.scene.currentBattle.randSeedInt(15) + 85) / 100)) * criticalMultiplier; if (isPhysical && source.status && source.status.effect === StatusEffect.BURN) diff --git a/src/ui/pokemon-icon-anim-handler.ts b/src/sprite/pokemon-icon-anim-handler.ts similarity index 100% rename from src/ui/pokemon-icon-anim-handler.ts rename to src/sprite/pokemon-icon-anim-handler.ts diff --git a/src/sprite/pokemon-sprite-sparkle-handler.ts b/src/sprite/pokemon-sprite-sparkle-handler.ts new file mode 100644 index 000000000..2e6f7b223 --- /dev/null +++ b/src/sprite/pokemon-sprite-sparkle-handler.ts @@ -0,0 +1,70 @@ +import BattleScene from "../battle-scene"; +import Pokemon from "../pokemon"; +import * as Utils from "../utils"; + +export default class PokemonSpriteSparkleHandler { + private sprites: Set; + + setup(scene: BattleScene): void { + this.sprites = new Set(); + + scene.tweens.addCounter({ + duration: Utils.fixedInt(200), + from: 0, + to: 1, + yoyo: true, + repeat: -1, + onRepeat: () => this.onLapse() + }); + } + + onLapse(): void { + Array.from(this.sprites.values()).filter(s => !s.scene).map(s => this.sprites.delete(s)); + for (let s of this.sprites.values()) { + if (!s.pipelineData['teraColor'] || !(s.pipelineData['teraColor'] as number[]).find(c => c)) + continue; + if (!s.visible || (s.parentContainer instanceof Pokemon && !s.parentContainer.parentContainer)) + continue; + const pokemon = s.parentContainer instanceof Pokemon ? s.parentContainer as Pokemon : null; + const parent = (pokemon || s).parentContainer; + const texture = s.texture; + const [ width, height ] = [ texture.source[0].width, texture.source[0].height ]; + const [ pixelX, pixelY ] = [ Utils.randInt(width), Utils.randInt(height) ]; + const ratioX = s.width / width; + const ratioY = s.height / height; + const pixel = texture.manager.getPixel(pixelX, pixelY, texture.key, '__BASE'); + if (pixel.alpha) { + const [ xOffset, yOffset ] = [ -s.originX * s.width, -s.originY * s.height]; + const sparkle = (s.scene as BattleScene).addFieldSprite(((pokemon?.x || 0) + s.x + pixelX * ratioX + xOffset), ((pokemon?.y || 0) + s.y + pixelY * ratioY + yOffset), 'tera_sparkle'); + sparkle.pipelineData['ignoreTimeTint'] = s.pipelineData['ignoreTimeTint']; + sparkle.play('tera_sparkle'); + const teraColor = s.pipelineData['teraColor'] as number[]; + parent.add(sparkle); + s.scene.time.delayedCall(Utils.fixedInt(Math.floor((1000 / 12) * 13)), () => sparkle.destroy()); + } + } + } + + add(sprites: Phaser.GameObjects.Sprite | Phaser.GameObjects.Sprite[]): void { + if (!Array.isArray(sprites)) + sprites = [ sprites ]; + for (let s of sprites) { + if (this.sprites.has(s)) + continue; + this.sprites.add(s); + } + } + + remove(sprites: Phaser.GameObjects.Sprite | Phaser.GameObjects.Sprite[]): void { + if (!Array.isArray(sprites)) + sprites = [ sprites ]; + for (let s of sprites) { + this.sprites.delete(s); + } + } + + removeAll(): void { + for (let s of this.sprites.values()) + this.sprites.delete(s); + } +} \ No newline at end of file diff --git a/src/system/achv.ts b/src/system/achv.ts index d9f3912bc..c17d8b669 100644 --- a/src/system/achv.ts +++ b/src/system/achv.ts @@ -125,6 +125,9 @@ export const achvs = { TRANSFER_MAX_BATTLE_STAT: new Achv('Teamwork', 'Baton pass to another party member with at least one stat maxed out', 'stick', 20), MAX_FRIENDSHIP: new Achv('Friendmaxxing', 'Reach max friendship on a Pokémon', 'soothe_bell', 25), MEGA_EVOLVE: new Achv('Megamorph', 'Mega evolve a Pokémon', 'mega_bracelet', 50), + GIGANTAMAX: new Achv('Absolute Unit', 'Gigantamax a Pokémon', 'dynamax_band', 50), + TERASTALLIZE: new Achv('STAB Enthusiast', 'Terastallize a Pokémon', 'tera_orb', 25), + STELLAR_TERASTALLIZE: new Achv('The Hidden Type', 'Stellar Terastallize a Pokémon', 'stellar_tera_shard', 25).setSecret(true), SPLICE: new Achv('Infinite Fusion', 'Splice two Pokémon together with DNA Splicers', 'dna_splicers', 10), MINI_BLACK_HOLE: new ModifierAchv('A Hole Lot of Items', 'Acquire a Mini Black Hole', 'mini_black_hole', 25, modifier => modifier instanceof TurnHeldItemTransferModifier).setSecret(), CATCH_MYTHICAL: new Achv('Mythical', 'Catch a mythical Pokémon', 'strange_ball', 50).setSecret(), diff --git a/src/system/game-data.ts b/src/system/game-data.ts index cd319be1c..339e24eac 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -763,7 +763,7 @@ export class GameData { this.scene.executeWithSeedOffset(() => { const neutralNatures = [ Nature.HARDY, Nature.DOCILE, Nature.SERIOUS, Nature.BASHFUL, Nature.QUIRKY ]; for (let s = 0; s < defaultStarters.length; s++) - defaultStarterNatures.push(Phaser.Math.RND.pick(neutralNatures)); + defaultStarterNatures.push(Utils.randSeedItem(neutralNatures)); }, 0, 'default'); for (let ds = 0; ds < defaultStarters.length; ds++) { diff --git a/src/trainer.ts b/src/trainer.ts index 65bacf89c..5a2374ca6 100644 --- a/src/trainer.ts +++ b/src/trainer.ts @@ -5,6 +5,7 @@ import { TrainerConfig, TrainerPartyCompoundTemplate, TrainerPartyMemberStrength import { TrainerType } from "./data/enums/trainer-type"; import { EnemyPokemon } from "./pokemon"; import * as Utils from "./utils"; +import { PersistentModifier } from "./modifier/modifier"; export default class Trainer extends Phaser.GameObjects.Container { public config: TrainerConfig; @@ -17,7 +18,7 @@ export default class Trainer extends Phaser.GameObjects.Container { ? trainerConfigs[trainerType] : trainerConfigs[TrainerType.ACE_TRAINER]; this.female = female; - this.partyTemplateIndex = Math.min(partyTemplateIndex !== undefined ? partyTemplateIndex : Phaser.Math.RND.weightedPick(this.config.partyTemplates.map((_, i) => i)), + this.partyTemplateIndex = Math.min(partyTemplateIndex !== undefined ? partyTemplateIndex : Utils.randSeedWeightedItem(this.config.partyTemplates.map((_, i) => i)), this.config.partyTemplates.length - 1); // TODO: Remove when Phaser weightedPick bug is fixed @@ -174,7 +175,7 @@ export default class Trainer extends Phaser.GameObjects.Container { tier--; } const tierPool = this.config.speciesPools[tier]; - species = getPokemonSpecies(Phaser.Math.RND.pick(tierPool)); + species = getPokemonSpecies(Utils.randSeedItem(tierPool)); } else species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter); @@ -186,7 +187,7 @@ export default class Trainer extends Phaser.GameObjects.Container { if (pokemonPrevolutions.hasOwnProperty(species.speciesId) && ret.speciesId !== species.speciesId) retry = true; else if (template.isBalanced(battle.enemyParty.length)) { - const partyMemberTypes = battle.enemyParty.map(p => p.getTypes()).flat(); + const partyMemberTypes = battle.enemyParty.map(p => p.getTypes(true)).flat(); if (partyMemberTypes.indexOf(ret.type1) > -1 || (ret.type2 !== null && partyMemberTypes.indexOf(ret.type2) > -1)) retry = true; } @@ -271,6 +272,12 @@ export default class Trainer extends Phaser.GameObjects.Container { } } + genModifiers(party: EnemyPokemon[]): PersistentModifier[] { + if (this.config.genModifiersFunc) + return this.config.genModifiersFunc(party); + return []; + } + loadAssets(): Promise { return this.config.loadAssets(this.scene, this.female); } diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index 04c8705ee..89ef9630b 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -5,6 +5,7 @@ import { addTextObject, TextStyle } from './text'; import { getGenderSymbol, getGenderColor, Gender } from '../data/gender'; import { StatusEffect } from '../data/status-effect'; import BattleScene from '../battle-scene'; +import { Type, getTypeRgb } from '../data/type'; export default class BattleInfo extends Phaser.GameObjects.Container { private player: boolean; @@ -13,6 +14,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { private bossSegments: integer; private offset: boolean; private lastName: string; + private lastTeraType: Type; private lastStatus: StatusEffect; private lastHp: integer; private lastMaxHp: integer; @@ -26,6 +28,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { private nameText: Phaser.GameObjects.Text; private genderText: Phaser.GameObjects.Text; private ownedIcon: Phaser.GameObjects.Sprite; + private teraIcon: Phaser.GameObjects.Sprite; private splicedIcon: Phaser.GameObjects.Sprite; private shinyIcon: Phaser.GameObjects.Sprite; private statusIndicator: Phaser.GameObjects.Sprite; @@ -43,6 +46,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.boss = false; this.offset = false; this.lastName = null; + this.lastTeraType = Type.UNKNOWN; this.lastStatus = StatusEffect.NONE; this.lastHp = -1; this.lastMaxHp = -1; @@ -75,11 +79,19 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.add(this.ownedIcon); } + this.teraIcon = this.scene.add.sprite(0, 0, 'icon_tera'); + this.teraIcon.setVisible(false); + this.teraIcon.setOrigin(0, 0); + this.teraIcon.setScale(0.5); + this.teraIcon.setPositionRelative(this.nameText, 0, 2); + this.teraIcon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 14, 15), Phaser.Geom.Rectangle.Contains); + this.add(this.teraIcon); + this.splicedIcon = this.scene.add.sprite(0, 0, 'icon_spliced'); this.splicedIcon.setVisible(false); this.splicedIcon.setOrigin(0, 0); this.splicedIcon.setPositionRelative(this.nameText, 0, 2); - this.splicedIcon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 5, 7), Phaser.Geom.Rectangle.Contains); + this.splicedIcon.setInteractive(new Phaser.Geom.Rectangle(0, 0, 5, 8), Phaser.Geom.Rectangle.Contains); this.add(this.splicedIcon); this.statusIndicator = this.scene.add.sprite(0, 0, 'statuses'); @@ -130,7 +142,17 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.genderText.setColor(getGenderColor(pokemon.gender)); this.genderText.setPositionRelative(this.nameText, nameTextWidth, 0); - this.splicedIcon.setPositionRelative(this.nameText, nameTextWidth + this.genderText.displayWidth + 1, 1); + this.lastTeraType = pokemon.getTeraType(); + + this.teraIcon.setPositionRelative(this.nameText, nameTextWidth + this.genderText.displayWidth + 1, 2); + this.teraIcon.setVisible(this.lastTeraType !== Type.UNKNOWN); + this.teraIcon.on('pointerover', () => { + if (this.lastTeraType !== Type.UNKNOWN) + (this.scene as BattleScene).ui.showTooltip(null, `${Utils.toReadableString(Type[this.lastTeraType])} Terastallized`); + }); + this.teraIcon.on('pointerout', () => (this.scene as BattleScene).ui.hideTooltip()); + + this.splicedIcon.setPositionRelative(this.nameText, nameTextWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0), 1); this.splicedIcon.setVisible(!!pokemon.fusionSpecies); if (this.splicedIcon.visible) { this.splicedIcon.on('pointerover', () => (this.scene as BattleScene).ui.showTooltip(null, `${pokemon.species.getName(pokemon.formIndex)}/${pokemon.fusionSpecies.getName(pokemon.fusionFormIndex)}`)); @@ -197,7 +219,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { if (boss !== this.boss) { this.boss = boss; - [ this.nameText, this.genderText, this.splicedIcon, this.ownedIcon, this.statusIndicator, this.levelContainer ].map(e => e.x += 48 * (boss ? -1 : 1)); + [ this.nameText, this.genderText, this.teraIcon, this.splicedIcon, this.ownedIcon, this.statusIndicator, this.levelContainer ].map(e => e.x += 48 * (boss ? -1 : 1)); this.hpBar.x += 38 * (boss ? -1 : 1); this.hpBar.y += 2 * (this.boss ? -1 : 1); this.hpBar.setTexture(`overlay_hp${boss ? '_boss' : ''}`); @@ -240,12 +262,25 @@ export default class BattleInfo extends Phaser.GameObjects.Container { if (!this.scene) return resolve(); - if (this.lastName !== pokemon.name) { + const nameUpdated = this.lastName !== pokemon.name; + + if (nameUpdated) { this.updateNameText(pokemon); - const nameTextWidth = this.nameText.displayWidth; - this.genderText.setPositionRelative(this.nameText, nameTextWidth, 0); - this.splicedIcon.setPositionRelative(this.nameText, nameTextWidth + this.genderText.displayWidth + 1, 1); + this.genderText.setPositionRelative(this.nameText, this.nameText.displayWidth, 0); } + + const teraType = pokemon.getTeraType(); + const teraTypeUpdated = this.lastTeraType !== teraType; + + if (teraTypeUpdated) { + this.teraIcon.setVisible(teraType !== Type.UNKNOWN); + this.teraIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1, 2); + this.teraIcon.setTintFill(Phaser.Display.Color.GetColor(...getTypeRgb(teraType))); + this.lastTeraType = teraType; + } + + if (nameUpdated || teraTypeUpdated) + this.splicedIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0), 1); if (this.lastStatus !== (pokemon.status?.effect || StatusEffect.NONE)) { this.lastStatus = pokemon.status?.effect || StatusEffect.NONE; diff --git a/src/ui/battle-message-ui-handler.ts b/src/ui/battle-message-ui-handler.ts index d50f66a0f..5ad7f798d 100644 --- a/src/ui/battle-message-ui-handler.ts +++ b/src/ui/battle-message-ui-handler.ts @@ -192,7 +192,7 @@ export default class BattleMessageUiHandler extends MessageUiHandler { if (shownIvsCount < 6) { let statsPool = stats.slice(0); for (let i = 0; i < shownIvsCount; i++) { - const shownStat = Phaser.Math.RND.pick(statsPool); + const shownStat = Utils.randSeedItem(statsPool); shownStats.push(shownStat); statsPool.splice(statsPool.indexOf(shownStat), 1); } diff --git a/src/ui/egg-list-ui-handler.ts b/src/ui/egg-list-ui-handler.ts index 489566651..eebabf2f0 100644 --- a/src/ui/egg-list-ui-handler.ts +++ b/src/ui/egg-list-ui-handler.ts @@ -1,6 +1,6 @@ import BattleScene, { Button } from "../battle-scene"; import { Mode } from "./ui"; -import PokemonIconAnimHandler, { PokemonIconAnimMode } from "./pokemon-icon-anim-handler"; +import PokemonIconAnimHandler, { PokemonIconAnimMode } from "../sprite/pokemon-icon-anim-handler"; import { TextStyle, addTextObject } from "./text"; import MessageUiHandler from "./message-ui-handler"; import { EGG_SEED, Egg, GachaType, getEggGachaTypeDescriptor, getEggHatchWavesMessage, getEggDescriptor } from "../data/egg"; diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index f6a22c4cc..b1d2789a0 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -11,7 +11,7 @@ import { allMoves } from "../data/move"; import { Moves } from "../data/enums/moves"; import { getGenderColor, getGenderSymbol } from "../data/gender"; import { StatusEffect } from "../data/status-effect"; -import PokemonIconAnimHandler, { PokemonIconAnimMode } from "./pokemon-icon-anim-handler"; +import PokemonIconAnimHandler, { PokemonIconAnimMode } from "../sprite/pokemon-icon-anim-handler"; import { pokemonEvolutions } from "../data/pokemon-evolutions"; import { addWindow } from "./window"; import { SpeciesFormChangeItemTrigger } from "../data/pokemon-forms"; @@ -102,7 +102,7 @@ export default class PartyUiHandler extends MessageUiHandler { private static FilterAllMoves = (_pokemonMove: PokemonMove) => null; public static FilterItemMaxStacks = (pokemon: PlayerPokemon, modifier: PokemonHeldItemModifier) => { - const matchingModifier = pokemon.scene.findModifier(m => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).matchType(modifier)) as PokemonHeldItemModifier; + const matchingModifier = pokemon.scene.findModifier(m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(modifier)) as PokemonHeldItemModifier; if (matchingModifier && matchingModifier.stackCount === matchingModifier.getMaxStackCount(pokemon.scene)) return `${pokemon.name} has too many\nof this item!`; return null; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 9be22375b..f5f5fb79e 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -11,13 +11,14 @@ import { Unlockables } from "../system/unlockables"; import { GrowthRate, getGrowthRateColor } from "../data/exp"; import { DexAttr, DexEntry } from "../system/game-data"; import * as Utils from "../utils"; -import PokemonIconAnimHandler, { PokemonIconAnimMode } from "./pokemon-icon-anim-handler"; +import PokemonIconAnimHandler, { PokemonIconAnimMode } from "../sprite/pokemon-icon-anim-handler"; import { StatsContainer } from "./stats-container"; import { addWindow } from "./window"; import { Nature, getNatureName } from "../data/nature"; import BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; import { pokemonFormChanges } from "../data/pokemon-forms"; import { Tutorial, handleTutorial } from "../tutorial"; +import PokemonSpriteSparkleHandler from "../sprite/pokemon-sprite-sparkle-handler"; export type StarterSelectCallback = (starters: Starter[]) => void; @@ -310,7 +311,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { let pokerusCursor: integer; const generateSpecies = () => { - randomSpeciesId = Phaser.Math.RND.pick(starterSpecies); + randomSpeciesId = Utils.randSeedItem(starterSpecies); species = getPokemonSpecies(randomSpeciesId); pokerusCursor = this.genSpecies[species.generation - 1].indexOf(species); }; diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 1ed34dbb5..664ea3816 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -3,7 +3,7 @@ import { Mode } from "./ui"; import UiHandler from "./ui-handler"; import * as Utils from "../utils"; import { PlayerPokemon } from "../pokemon"; -import { Type } from "../data/type"; +import { Type, getTypeRgb } from "../data/type"; import { TextStyle, addBBCodeTextObject, addTextObject, getBBCodeFrag, getTextColor } from "./text"; import Move, { MoveCategory } from "../data/move"; import { getPokeballAtlasKey } from "../data/pokeball"; @@ -98,8 +98,7 @@ export default class SummaryUiHandler extends UiHandler { this.numberText.setOrigin(0, 1); this.summaryContainer.add(this.numberText); - this.pokemonSprite = this.scene.add.sprite(56, -106, `pkmn__sub`); - this.pokemonSprite.setPipeline(this.scene.spritePipeline, { ignoreOverride: true, tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: false }); + this.pokemonSprite = this.scene.initPokemonSprite(this.scene.add.sprite(56, -106, `pkmn__sub`), null, false, true); this.summaryContainer.add(this.pokemonSprite); this.nameText = addTextObject(this.scene, 6, -54, '', TextStyle.SUMMARY); @@ -201,6 +200,7 @@ export default class SummaryUiHandler extends UiHandler { this.numberText.setShadowColor(getTextColor(!this.pokemon.isShiny() ? TextStyle.SUMMARY : TextStyle.SUMMARY_GOLD, true)); this.pokemonSprite.play(this.pokemon.getSpriteKey(true)); + this.pokemonSprite.pipelineData['teraColor'] = getTypeRgb(this.pokemon.getTeraType()); this.pokemonSprite.pipelineData['ignoreTimeTint'] = true; [ 'spriteColors', 'fusionSpriteColors' ].map(k => { delete this.pokemonSprite.pipelineData[`${k}Base`]; @@ -489,16 +489,26 @@ export default class SummaryUiHandler extends UiHandler { typeLabel.setOrigin(0, 0); profileContainer.add(typeLabel); - const getTypeIcon = (index: integer, type: Type) => { - const typeIcon = this.scene.add.sprite(39 + 34 * index, 42, 'types', Type[type].toLowerCase()); + const getTypeIcon = (index: integer, type: Type, tera: boolean = false) => { + const xCoord = 39 + 34 * index; + const typeIcon = !tera + ? this.scene.add.sprite(xCoord, 42, 'types', Type[type].toLowerCase()) + : this.scene.add.sprite(xCoord, 42, 'type_tera'); + if (tera) { + typeIcon.setScale(0.5); + const typeRgb = getTypeRgb(type); + typeIcon.setTint(Phaser.Display.Color.GetColor(typeRgb[0], typeRgb[1], typeRgb[2])); + } typeIcon.setOrigin(0, 1); return typeIcon; }; - const types = this.pokemon.getTypes(true); + const types = this.pokemon.getTypes(false, true); profileContainer.add(getTypeIcon(0, types[0])); if (types.length > 1) profileContainer.add(getTypeIcon(1, types[1])); + if (this.pokemon.isTerastallized()) + profileContainer.add(getTypeIcon(types.length, this.pokemon.getTeraType(), true)); const ability = this.pokemon.getAbility(); @@ -534,7 +544,7 @@ export default class SummaryUiHandler extends UiHandler { }); } - let memoString = `${getBBCodeFrag(Utils.toReadableString(Nature[this.pokemon.nature]), TextStyle.SUMMARY_RED)} nature,\n${getBBCodeFrag(`${this.pokemon.metBiome === -1 ? 'apparently ' : ''}met at Lv`, TextStyle.WINDOW)}${getBBCodeFrag(this.pokemon.metLevel.toString(), TextStyle.SUMMARY_RED)}${getBBCodeFrag(',', TextStyle.WINDOW)}\n${getBBCodeFrag(getBiomeName(this.pokemon.metBiome), TextStyle.SUMMARY_RED)}${getBBCodeFrag('.', TextStyle.WINDOW)}`; + let memoString = `${getBBCodeFrag(Utils.toReadableString(Nature[this.pokemon.nature]), TextStyle.SUMMARY_RED)}${getBBCodeFrag(' nature,', TextStyle.WINDOW)}\n${getBBCodeFrag(`${this.pokemon.metBiome === -1 ? 'apparently ' : ''}met at Lv`, TextStyle.WINDOW)}${getBBCodeFrag(this.pokemon.metLevel.toString(), TextStyle.SUMMARY_RED)}${getBBCodeFrag(',', TextStyle.WINDOW)}\n${getBBCodeFrag(getBiomeName(this.pokemon.metBiome), TextStyle.SUMMARY_RED)}${getBBCodeFrag('.', TextStyle.WINDOW)}`; const memoText = addBBCodeTextObject(this.scene, 7, 113, memoString, TextStyle.WINDOW); memoText.setOrigin(0, 0); diff --git a/src/utils.ts b/src/utils.ts index 495d5d207..3a310493a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -72,6 +72,18 @@ export function randIntRange(min: integer, max: integer): integer { return randInt(max - min, min); } +export function randSeedItem(items: T[]): T { + return items.length === 1 + ? items[0] + : Phaser.Math.RND.pick(items); +} + +export function randSeedWeightedItem(items: T[]): T { + return items.length === 1 + ? items[0] + : Phaser.Math.RND.weightedPick(items); +} + export function getSunday(date: Date): Date { const day = date.getDay(), diff = date.getDate() - day;