diff --git a/public/images/mystery-encounters/safari_zone.json b/public/images/mystery-encounters/safari_zone.json new file mode 100644 index 00000000000..fe81d1b9f53 --- /dev/null +++ b/public/images/mystery-encounters/safari_zone.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "safari_zone.png", + "format": "RGBA8888", + "size": { + "w": 120, + "h": 84 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 118, + "h": 82 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 118, + "h": 82 + }, + "frame": { + "x": 1, + "y": 1, + "w": 118, + "h": 82 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:6fad7a61e47043b974153148b4fd3997:5ec4d0890f2f03446daf22c8ae8ba77b:87aa745cd95eef6cbf38935230f4e10f$" + } +} diff --git a/public/images/mystery-encounters/safari_zone.png b/public/images/mystery-encounters/safari_zone.png new file mode 100644 index 00000000000..375d66ebbe9 Binary files /dev/null and b/public/images/mystery-encounters/safari_zone.png differ diff --git a/public/images/trainer/buck.json b/public/images/trainer/buck.json new file mode 100644 index 00000000000..d2d215f716a --- /dev/null +++ b/public/images/trainer/buck.json @@ -0,0 +1,524 @@ +{ + "textures": [ + { + "image": "buck.png", + "format": "RGBA8888", + "size": { + "w": 120, + "h": 78 + }, + "scale": 1, + "frames": [ + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 33, + "y": 4, + "w": 35, + "h": 76 + }, + "frame": { + "x": 1, + "y": 1, + "w": 35, + "h": 76 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 33, + "y": 4, + "w": 35, + "h": 76 + }, + "frame": { + "x": 1, + "y": 1, + "w": 35, + "h": 76 + } + }, + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 33, + "y": 4, + "w": 35, + "h": 76 + }, + "frame": { + "x": 1, + "y": 1, + "w": 35, + "h": 76 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 33, + "y": 4, + "w": 35, + "h": 76 + }, + "frame": { + "x": 1, + "y": 1, + "w": 35, + "h": 76 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 33, + "y": 4, + "w": 35, + "h": 76 + }, + "frame": { + "x": 1, + "y": 1, + "w": 35, + "h": 76 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 33, + "y": 4, + "w": 35, + "h": 76 + }, + "frame": { + "x": 1, + "y": 1, + "w": 35, + "h": 76 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 33, + "y": 4, + "w": 35, + "h": 76 + }, + "frame": { + "x": 1, + "y": 1, + "w": 35, + "h": 76 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 33, + "y": 4, + "w": 35, + "h": 76 + }, + "frame": { + "x": 1, + "y": 1, + "w": 35, + "h": 76 + } + }, + { + "filename": "0018.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 18, + "y": 8, + "w": 44, + "h": 72 + }, + "frame": { + "x": 38, + "y": 1, + "w": 44, + "h": 72 + } + }, + { + "filename": "0019.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 18, + "y": 8, + "w": 44, + "h": 72 + }, + "frame": { + "x": 38, + "y": 1, + "w": 44, + "h": 72 + } + }, + { + "filename": "0020.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 15, + "y": 8, + "w": 44, + "h": 72 + }, + "frame": { + "x": 38, + "y": 1, + "w": 44, + "h": 72 + } + }, + { + "filename": "0021.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 15, + "y": 8, + "w": 44, + "h": 72 + }, + "frame": { + "x": 38, + "y": 1, + "w": 44, + "h": 72 + } + }, + { + "filename": "0022.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 44, + "h": 72 + }, + "frame": { + "x": 38, + "y": 1, + "w": 44, + "h": 72 + } + }, + { + "filename": "0023.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 13, + "y": 8, + "w": 44, + "h": 72 + }, + "frame": { + "x": 38, + "y": 1, + "w": 44, + "h": 72 + } + }, + { + "filename": "0000.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + }, + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 80 + }, + "spriteSourceSize": { + "x": 34, + "y": 5, + "w": 35, + "h": 75 + }, + "frame": { + "x": 84, + "y": 1, + "w": 35, + "h": 75 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:033f3d363b4192f64c92e02c19622c15:0d06141bef5af87ef82da967253207cb:3347efe478119141b0e3e6eccdecd0f5$" + } +} diff --git a/public/images/trainer/buck.png b/public/images/trainer/buck.png new file mode 100644 index 00000000000..2384fb42a33 Binary files /dev/null and b/public/images/trainer/buck.png differ diff --git a/public/images/trainer/cheryl.json b/public/images/trainer/cheryl.json new file mode 100644 index 00000000000..4cac665a588 --- /dev/null +++ b/public/images/trainer/cheryl.json @@ -0,0 +1,398 @@ +{ + "textures": [ + { + "image": "cheryl.png", + "format": "RGBA8888", + "size": { + "w": 154, + "h": 83 + }, + "scale": 1, + "frames": [ + { + "filename": "0006.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 41, + "h": 81 + }, + "frame": { + "x": 1, + "y": 1, + "w": 41, + "h": 81 + } + }, + { + "filename": "0007.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 25, + "y": 0, + "w": 41, + "h": 81 + }, + "frame": { + "x": 1, + "y": 1, + "w": 41, + "h": 81 + } + }, + { + "filename": "0008.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 26, + "y": 0, + "w": 41, + "h": 81 + }, + "frame": { + "x": 1, + "y": 1, + "w": 41, + "h": 81 + } + }, + { + "filename": "0009.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 26, + "y": 0, + "w": 41, + "h": 81 + }, + "frame": { + "x": 1, + "y": 1, + "w": 41, + "h": 81 + } + }, + { + "filename": "0010.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 27, + "y": 0, + "w": 41, + "h": 81 + }, + "frame": { + "x": 44, + "y": 1, + "w": 41, + "h": 81 + } + }, + { + "filename": "0011.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 27, + "y": 0, + "w": 41, + "h": 81 + }, + "frame": { + "x": 44, + "y": 1, + "w": 41, + "h": 81 + } + }, + { + "filename": "0012.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 24, + "y": 0, + "w": 41, + "h": 81 + }, + "frame": { + "x": 44, + "y": 1, + "w": 41, + "h": 81 + } + }, + { + "filename": "0013.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 24, + "y": 0, + "w": 41, + "h": 81 + }, + "frame": { + "x": 44, + "y": 1, + "w": 41, + "h": 81 + } + }, + { + "filename": "0014.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 27, + "y": 0, + "w": 33, + "h": 81 + }, + "frame": { + "x": 87, + "y": 1, + "w": 33, + "h": 81 + } + }, + { + "filename": "0015.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 27, + "y": 0, + "w": 33, + "h": 81 + }, + "frame": { + "x": 87, + "y": 1, + "w": 33, + "h": 81 + } + }, + { + "filename": "0016.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 26, + "y": 0, + "w": 33, + "h": 81 + }, + "frame": { + "x": 87, + "y": 1, + "w": 33, + "h": 81 + } + }, + { + "filename": "0017.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 26, + "y": 0, + "w": 33, + "h": 81 + }, + "frame": { + "x": 87, + "y": 1, + "w": 33, + "h": 81 + } + }, + { + "filename": "0000.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 20, + "y": 0, + "w": 31, + "h": 81 + }, + "frame": { + "x": 122, + "y": 1, + "w": 31, + "h": 81 + } + }, + { + "filename": "0001.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 20, + "y": 0, + "w": 31, + "h": 81 + }, + "frame": { + "x": 122, + "y": 1, + "w": 31, + "h": 81 + } + }, + { + "filename": "0002.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 20, + "y": 0, + "w": 31, + "h": 81 + }, + "frame": { + "x": 122, + "y": 1, + "w": 31, + "h": 81 + } + }, + { + "filename": "0003.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 20, + "y": 0, + "w": 31, + "h": 81 + }, + "frame": { + "x": 122, + "y": 1, + "w": 31, + "h": 81 + } + }, + { + "filename": "0004.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 31, + "h": 81 + }, + "frame": { + "x": 122, + "y": 1, + "w": 31, + "h": 81 + } + }, + { + "filename": "0005.png", + "rotated": false, + "trimmed": true, + "sourceSize": { + "w": 80, + "h": 81 + }, + "spriteSourceSize": { + "x": 21, + "y": 0, + "w": 31, + "h": 81 + }, + "frame": { + "x": 122, + "y": 1, + "w": 31, + "h": 81 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:dfcf7aedbd588c4e42427a2e17c171bf:206549943a0e3325d20a017ef01eefee:a233cd27590422717866c66e366b68fb$" + } +} diff --git a/public/images/trainer/cheryl.png b/public/images/trainer/cheryl.png new file mode 100644 index 00000000000..c46505f6b25 Binary files /dev/null and b/public/images/trainer/cheryl.png differ diff --git a/public/images/trainer/marley.json b/public/images/trainer/marley.json new file mode 100644 index 00000000000..92d9f1449e5 --- /dev/null +++ b/public/images/trainer/marley.json @@ -0,0 +1,83 @@ +{ "frames": [ + { + "filename": "0000.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 26, "y": 2, "w": 31, "h": 77 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 26, "y": 2, "w": 31, "h": 77 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 26, "y": 2, "w": 31, "h": 77 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 31, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 26, "y": 2, "w": 31, "h": 77 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 32, "y": 0, "w": 28, "h": 78 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 28, "y": 1, "w": 28, "h": 78 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 32, "y": 0, "w": 28, "h": 78 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 28, "y": 1, "w": 28, "h": 78 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 78, "w": 31, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 28, "y": 2, "w": 31, "h": 77 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 78, "w": 31, "h": 77 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 28, "y": 2, "w": 31, "h": 77 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.pngprite.org/", + "version": "1.3.7-x64", + "image": "marley.png", + "format": "I8", + "size": { "w": 60, "h": 155 }, + "scale": "1" + } +} diff --git a/public/images/trainer/marley.png b/public/images/trainer/marley.png new file mode 100644 index 00000000000..8e78e11e8ad Binary files /dev/null and b/public/images/trainer/marley.png differ diff --git a/public/images/trainer/mira.json b/public/images/trainer/mira.json new file mode 100644 index 00000000000..7bd29f53475 --- /dev/null +++ b/public/images/trainer/mira.json @@ -0,0 +1,209 @@ +{ "frames": [ + { + "filename": "0000.png", + "frame": { "x": 53, "y": 0, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 14, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0001.png", + "frame": { "x": 53, "y": 0, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 14, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 53, "y": 0, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 22, "y": 13, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 53, "y": 0, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 0, "y": 0, "w": 53, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 53, "h": 63 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 0, "y": 0, "w": 53, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 12, "w": 53, "h": 63 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 0, "y": 63, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 11, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 0, "y": 63, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 13, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 0, "y": 63, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 14, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 0, "y": 63, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 13, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 0, "y": 63, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 11, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 0, "y": 0, "w": 53, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 53, "h": 63 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 0, "y": 0, "w": 53, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 12, "w": 53, "h": 63 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 53, "y": 0, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 53, "y": 0, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 22, "y": 13, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 53, "y": 0, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 23, "y": 14, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 53, "y": 0, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 22, "y": 13, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0017.png", + "frame": { "x": 53, "y": 0, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0018.png", + "frame": { "x": 0, "y": 0, "w": 53, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 11, "w": 53, "h": 63 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0019.png", + "frame": { "x": 0, "y": 0, "w": 53, "h": 63 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 21, "y": 12, "w": 53, "h": 63 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0020.png", + "frame": { "x": 0, "y": 63, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 13, "y": 11, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0021.png", + "frame": { "x": 0, "y": 63, "w": 44, "h": 65 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 13, "w": 44, "h": 65 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "image": "mira.png", + "format": "I8", + "size": { "w": 97, "h": 128 }, + "scale": "1" + } +} diff --git a/public/images/trainer/mira.png b/public/images/trainer/mira.png new file mode 100644 index 00000000000..5c1afe5d241 Binary files /dev/null and b/public/images/trainer/mira.png differ diff --git a/public/images/trainer/riley.json b/public/images/trainer/riley.json new file mode 100644 index 00000000000..f0f84a909db --- /dev/null +++ b/public/images/trainer/riley.json @@ -0,0 +1,209 @@ +{ "frames": [ + { + "filename": "0000.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0001.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0002.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0003.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0004.png", + "frame": { "x": 55, "y": 80, "w": 37, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 31, "y": 0, "w": 37, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0005.png", + "frame": { "x": 55, "y": 80, "w": 37, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 31, "y": 0, "w": 37, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0006.png", + "frame": { "x": 55, "y": 80, "w": 37, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 30, "y": 0, "w": 37, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0007.png", + "frame": { "x": 55, "y": 80, "w": 37, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 30, "y": 0, "w": 37, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0008.png", + "frame": { "x": 55, "y": 80, "w": 37, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 28, "y": 0, "w": 37, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0009.png", + "frame": { "x": 55, "y": 80, "w": 37, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 28, "y": 0, "w": 37, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0010.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0011.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 10, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0012.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0013.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 11, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0014.png", + "frame": { "x": 55, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0015.png", + "frame": { "x": 55, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0016.png", + "frame": { "x": 0, "y": 80, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0017.png", + "frame": { "x": 0, "y": 80, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0018.png", + "frame": { "x": 55, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0019.png", + "frame": { "x": 55, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0020.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + }, + { + "filename": "0021.png", + "frame": { "x": 0, "y": 0, "w": 55, "h": 80 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 12, "y": 0, "w": 55, "h": 80 }, + "sourceSize": { "w": 80, "h": 80 }, + "duration": 100 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.7-x64", + "image": "riley.png", + "format": "I8", + "size": { "w": 110, "h": 160 }, + "scale": "1" + } +} diff --git a/public/images/trainer/riley.png b/public/images/trainer/riley.png new file mode 100644 index 00000000000..a9f0e3b53a9 Binary files /dev/null and b/public/images/trainer/riley.png differ diff --git a/src/data/dialogue.ts b/src/data/dialogue.ts index ec3358b1a77..5d4bea542de 100644 --- a/src/data/dialogue.ts +++ b/src/data/dialogue.ts @@ -665,6 +665,76 @@ export const trainerTypeDialogue: TrainerTypeDialogue = { ] } ], + [TrainerType.BUCK]: [ + { + encounter: [ + "dialogue:stat_trainer_buck.encounter.1", + "dialogue:stat_trainer_buck.encounter.2" + ], + victory: [ + "dialogue:stat_trainer_buck.victory.1" + ], + defeat: [ + "dialogue:stat_trainer_buck.defeat.1" + ] + } + ], + [TrainerType.CHERYL]: [ + { + encounter: [ + "dialogue:stat_trainer_cheryl.encounter.1", + "dialogue:stat_trainer_cheryl.encounter.2" + ], + victory: [ + "dialogue:stat_trainer_cheryl.victory.1" + ], + defeat: [ + "dialogue:stat_trainer_cheryl.defeat.1" + ] + } + ], + [TrainerType.MARLEY]: [ + { + encounter: [ + "dialogue:stat_trainer_marley.encounter.1", + "dialogue:stat_trainer_marley.encounter.2" + ], + victory: [ + "dialogue:stat_trainer_marley.victory.1" + ], + defeat: [ + "dialogue:stat_trainer_marley.defeat.1" + ] + } + ], + [TrainerType.MIRA]: [ + { + encounter: [ + "dialogue:stat_trainer_mira.encounter.1", + "dialogue:stat_trainer_mira.encounter.2" + ], + victory: [ + "dialogue:stat_trainer_mira.victory.1" + ], + defeat: [ + "dialogue:stat_trainer_mira.defeat.1" + ] + } + ], + [TrainerType.RILEY]: [ + { + encounter: [ + "dialogue:stat_trainer_riley.encounter.1", + "dialogue:stat_trainer_riley.encounter.2" + ], + victory: [ + "dialogue:stat_trainer_riley.victory.1" + ], + defeat: [ + "dialogue:stat_trainer_riley.defeat.1" + ] + } + ], [TrainerType.BROCK]: { encounter: [ "dialogue:brock.encounter.1", diff --git a/src/data/egg.ts b/src/data/egg.ts index bf4d6577dd7..a924298c014 100644 --- a/src/data/egg.ts +++ b/src/data/egg.ts @@ -60,13 +60,16 @@ export interface IEggOptions { /** Defines if the egg will hatch with the hidden ability of this species. * If no hidden ability exist, a random one will get choosen. */ - overrideHiddenAbility?: boolean + overrideHiddenAbility?: boolean, + + /** If Egg is of {@link EggSourceType.EVENT}, can customize the message displayed for where the egg was obtained */ + eventEggTypeDescriptor?: string; } export class Egg { //// - // #region Privat properties + // #region Private properties //// private _id: number; @@ -82,6 +85,8 @@ export class Egg { private _overrideHiddenAbility: boolean; + private _eventEggTypeDescriptor: string; + //// // #endregion //// @@ -179,6 +184,8 @@ export class Egg { this.increasePullStatistic(eggOptions.scene); this.addEggToGameData(eggOptions.scene); } + + this._eventEggTypeDescriptor = eggOptions.eventEggTypeDescriptor ?? null; } //// @@ -273,6 +280,8 @@ export class Egg { return i18next.t("egg:gachaTypeShiny"); case EggSourceType.GACHA_MOVE: return i18next.t("egg:gachaTypeMove"); + case EggSourceType.EVENT: + return this._eventEggTypeDescriptor ?? i18next.t("egg:eventType"); } } diff --git a/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts b/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts new file mode 100644 index 00000000000..9a69a85d722 --- /dev/null +++ b/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts @@ -0,0 +1,191 @@ +import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { trainerConfigs, } from "#app/data/trainer-config"; +import { MysteryEncounterType } from "#enums/mystery-encounter-type"; +import BattleScene from "#app/battle-scene"; +import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter"; +import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; +import { TrainerType } from "#enums/trainer-type"; +import { Species } from "#enums/species"; +import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { randSeedInt } from "#app/utils"; +import i18next from "i18next"; +import { PartyHealPhase } from "#app/phases"; +import { IEggOptions } from "#app/data/egg"; +import { EggSourceType } from "#enums/egg-source-types"; +import { EggTier } from "#enums/egg-type"; + +/** the i18n namespace for the encounter */ +const namespace = "mysteryEncounter:aTrainersTest"; + +/** + * A Trainer's Test encounter. + * @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/115 | GitHub Issue #115} + * @see For biome requirements check {@linkcode mysteryEncountersByBiome} + */ +export const ATrainersTestEncounter: IMysteryEncounter = + MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.A_TRAINERS_TEST) + .withEncounterTier(MysteryEncounterTier.ROGUE) + .withSceneWaveRangeRequirement(10, 180) // waves 10 to 180 + .withIntroSpriteConfigs([]) // These are set in onInit() + .withIntroDialogue([ + { + text: `${namespace}.intro`, + }, + ]) + .withAutoHideIntroVisuals(false) + .withOnInit((scene: BattleScene) => { + const encounter = scene.currentBattle.mysteryEncounter; + + // Randomly pick from 1 of the 5 stat trainers to spawn + let trainerType: TrainerType; + let spriteKeys; + let trainerNameKey: string; + switch (randSeedInt(5)) { + default: + case 0: + trainerType = TrainerType.BUCK; + spriteKeys = getSpriteKeysFromSpecies(Species.CLAYDOL); + trainerNameKey = "buck"; + break; + case 1: + trainerType = TrainerType.CHERYL; + spriteKeys = getSpriteKeysFromSpecies(Species.BLISSEY); + trainerNameKey = "cheryl"; + break; + case 2: + trainerType = TrainerType.MARLEY; + spriteKeys = getSpriteKeysFromSpecies(Species.ARCANINE); + trainerNameKey = "marley"; + break; + case 3: + trainerType = TrainerType.MIRA; + spriteKeys = getSpriteKeysFromSpecies(Species.ALAKAZAM, false, 1); + trainerNameKey = "mira"; + break; + case 4: + trainerType = TrainerType.RILEY; + spriteKeys = getSpriteKeysFromSpecies(Species.LUCARIO, false, 1); + trainerNameKey = "riley"; + break; + } + + // Dialogue and tokens for trainer + encounter.dialogue.intro = [ + { + speaker: `trainerNames:${trainerNameKey}`, + text: `${namespace}.${trainerNameKey}.intro_dialogue` + } + ]; + encounter.options[0].dialogue.selected = [ + { + speaker: `trainerNames:${trainerNameKey}`, + text: `${namespace}.${trainerNameKey}.accept` + } + ]; + encounter.options[1].dialogue.selected = [ + { + speaker: `trainerNames:${trainerNameKey}`, + text: `${namespace}.${trainerNameKey}.decline` + } + ]; + + encounter.setDialogueToken("statTrainerName", i18next.t(`trainerNames:${trainerNameKey}`)); + const eggDescription = i18next.t(`${namespace}.title`) + ":\n" + i18next.t(`trainerNames:${trainerNameKey}`); + encounter.misc = { trainerType, trainerNameKey, trainerEggDescription: eggDescription }; + + // Trainer config + const trainerConfig = trainerConfigs[trainerType].copy(); + const trainerSpriteKey = trainerConfig.getSpriteKey(); + encounter.enemyPartyConfigs.push({ + levelAdditiveMultiplier: 1, + trainerConfig: trainerConfig + }); + + encounter.spriteConfigs = [ + { + spriteKey: spriteKeys.spriteKey, + fileRoot: spriteKeys.fileRoot, + hasShadow: true, + repeat: true, + isPokemon: true, + x: 22, + y: -2, + yShadow: -2 + }, + { + spriteKey: trainerSpriteKey, + fileRoot: "trainer", + hasShadow: true, + disableAnimation: true, + x: -24, + y: 4, + yShadow: 4 + } + ]; + + return true; + }) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) + .withIntroDialogue() + .withSimpleOption( + { + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip` + }, + async (scene: BattleScene) => { + const encounter = scene.currentBattle.mysteryEncounter; + // Spawn standard trainer battle with memory mushroom reward + const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0]; + + let eggTier; + if (randSeedInt(64) >= 54) { + eggTier = EggTier.MASTER; + } else { + eggTier = EggTier.ULTRA; + } + + await transitionMysteryEncounterIntroVisuals(scene); + + const eggOptions: IEggOptions = { + scene, + pulled: false, + sourceType: EggSourceType.EVENT, + eventEggTypeDescriptor: encounter.misc.trainerEggDescription, + tier: eggTier + }; + encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.${eggTier === EggTier.ULTRA ? "epic" : "legendary"}`)); + setEncounterRewards(scene, { fillRemaining: true }, [eggOptions]); + + return initBattleWithEnemyConfig(scene, config); + } + ) + .withSimpleOption( + { + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip` + }, + async (scene: BattleScene) => { + const encounter = scene.currentBattle.mysteryEncounter; + // Full heal party + scene.unshiftPhase(new PartyHealPhase(scene, true)); + + const eggOptions: IEggOptions = { + scene, + pulled: false, + sourceType: EggSourceType.EVENT, + eventEggTypeDescriptor: encounter.misc.trainerEggDescription, + tier: EggTier.GREAT + }; + encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.rare`)); + setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: 0 }, [eggOptions]); + leaveEncounterWithoutBattle(scene); + } + ) + .withOutroDialogue([ + { + text: `${namespace}:outro`, + }, + ]) + .build(); diff --git a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts index 2b379bdba86..3f7f86ef744 100644 --- a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts +++ b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts @@ -1,5 +1,5 @@ import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; -import Pokemon, { PokemonMove } from "#app/field/pokemon"; +import Pokemon, { EnemyPokemon, PokemonMove } from "#app/field/pokemon"; import { BerryModifierType, modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { Species } from "#enums/species"; @@ -37,18 +37,20 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter = .withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Must have at least 4 berries to spawn .withIntroSpriteConfigs([ { - spriteKey: Species.GREEDENT.toString(), - fileRoot: "pokemon", - hasShadow: false, + // This sprite has the shadow + spriteKey: null, + fileRoot: null, + species: Species.GREEDENT, + hasShadow: true, + alpha: 0.001, repeat: true, x: -5 }, { - // This sprite has the shadow - spriteKey: Species.GREEDENT.toString(), - fileRoot: "pokemon", - hasShadow: true, - alpha: 0.001, + spriteKey: null, + fileRoot: null, + species: Species.GREEDENT, + hasShadow: false, repeat: true, x: -5 }, @@ -162,12 +164,12 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter = }) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, } ]) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOnInit((scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; @@ -213,7 +215,7 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter = modifierTypes: bossModifierTypes, tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], mysteryEncounterBattleEffects: (pokemon: Pokemon) => { - queueEncounterMessage(pokemon.scene, `${namespace}:option:1:boss_enraged`); + queueEncounterMessage(pokemon.scene, `${namespace}.option.1.boss_enraged`); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD], 1)); } } @@ -228,11 +230,11 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter = new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }) @@ -248,7 +250,7 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter = const seedModifier = revSeed.newModifier(p); scene.addModifier(seedModifier, false, false, false, true); }); - queueEncounterMessage(scene, `${namespace}:option:1:food_stash`); + queueEncounterMessage(scene, `${namespace}.option.1.food_stash`); }; setEncounterRewards(scene, { fillRemaining: true }, null, givePartyPokemonReviverSeeds); @@ -269,11 +271,11 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter = new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }) @@ -310,11 +312,11 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter = new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, selected: [ { - text: `${namespace}:option:3:selected`, + text: `${namespace}.option.3.selected`, }, ], }) @@ -328,7 +330,7 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter = // Let it have the food // Greedent joins the team, level equal to 2 below highest party member const level = getHighestLevelPlayerPokemon(scene).level - 2; - const greedent = scene.addEnemyPokemon(getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false); + const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false, null); greedent.moveset = [new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF)]; greedent.passive = true; @@ -344,7 +346,7 @@ function doGreedentSpriteSteal(scene: BattleScene) { const shakeDelay = 50; const slideDelay = 500; - const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(0); + const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(1); scene.playSound("Follow Me"); scene.tweens.chain({ @@ -418,7 +420,7 @@ function doGreedentSpriteSteal(scene: BattleScene) { } function doGreedentEatBerries(scene: BattleScene) { - const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(0); + const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(1); let index = 1; scene.tweens.add({ targets: greedentSprites, @@ -452,7 +454,7 @@ function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) { } const encounter = scene.currentBattle.mysteryEncounter; animationOrder.forEach((berry, i) => { - const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey.includes(berry)); + const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey?.includes(berry)); const [ sprite, tintSprite ] = encounter.introVisuals.getSpriteAtIndex(introVisualsIndex); scene.time.delayedCall(berryAddDelay * i + 400, () => { if (sprite) { diff --git a/src/data/mystery-encounters/encounters/offer-you-cant-refuse-encounter.ts b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts similarity index 83% rename from src/data/mystery-encounters/encounters/offer-you-cant-refuse-encounter.ts rename to src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts index 80510430be3..0bf3145ea7e 100644 --- a/src/data/mystery-encounters/encounters/offer-you-cant-refuse-encounter.ts +++ b/src/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter.ts @@ -21,8 +21,8 @@ const namespace = "mysteryEncounter:offerYouCantRefuse"; * @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/72 | GitHub Issue #72} * @see For biome requirements check {@linkcode mysteryEncountersByBiome} */ -export const OfferYouCantRefuseEncounter: IMysteryEncounter = - MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.OFFER_YOU_CANT_REFUSE) +export const AnOfferYouCantRefuseEncounter: IMysteryEncounter = + MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE) .withEncounterTier(MysteryEncounterTier.GREAT) .withSceneWaveRangeRequirement(10, 180) .withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party @@ -47,16 +47,16 @@ export const OfferYouCantRefuseEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, { - text: `${namespace}:intro_dialogue`, - speaker: `${namespace}:speaker`, + text: `${namespace}.intro_dialogue`, + speaker: `${namespace}.speaker`, }, ]) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOnInit((scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; const pokemon = getHighestStatTotalPlayerPokemon(scene, false); @@ -89,12 +89,12 @@ export const OfferYouCantRefuseEncounter: IMysteryEncounter = new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, - speaker: `${namespace}:speaker`, + text: `${namespace}.option.1.selected`, + speaker: `${namespace}.speaker`, }, ], }) @@ -120,13 +120,13 @@ export const OfferYouCantRefuseEncounter: IMysteryEncounter = new AbilityRequirement(EXTORTION_ABILITIES)) ) .withDialogue({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, - disabledButtonTooltip: `${namespace}:option:2:tooltip_disabled`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + disabledButtonTooltip: `${namespace}.option.2.tooltip_disabled`, selected: [ { - speaker: `${namespace}:speaker`, - text: `${namespace}:option:2:selected`, + speaker: `${namespace}.speaker`, + text: `${namespace}.option.2.selected`, }, ], }) @@ -144,12 +144,12 @@ export const OfferYouCantRefuseEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, selected: [ { - speaker: `${namespace}:speaker`, - text: `${namespace}:option:3:selected`, + speaker: `${namespace}.speaker`, + text: `${namespace}.option.3.selected`, }, ], }, diff --git a/src/data/mystery-encounters/encounters/dark-deal-encounter.ts b/src/data/mystery-encounters/encounters/dark-deal-encounter.ts index 1e73ffd11c0..e8a8272df0e 100644 --- a/src/data/mystery-encounters/encounters/dark-deal-encounter.ts +++ b/src/data/mystery-encounters/encounters/dark-deal-encounter.ts @@ -92,32 +92,32 @@ export const DarkDealEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, { - speaker: `${namespace}:speaker`, - text: `${namespace}:intro_dialogue`, + speaker: `${namespace}.speaker`, + text: `${namespace}.intro_dialogue`, }, ]) .withSceneWaveRangeRequirement(30, 180) // waves 30 to 180 .withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party .withCatchAllowed(true) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOption( new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - speaker: `${namespace}:speaker`, - text: `${namespace}:option:1:selected_dialogue`, + speaker: `${namespace}.speaker`, + text: `${namespace}.option.1.selected_dialogue`, }, { - text: `${namespace}:option:1:selected_message`, + text: `${namespace}.option.1.selected_message`, }, ], }) @@ -164,12 +164,12 @@ export const DarkDealEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - speaker: `${namespace}:speaker`, - text: `${namespace}:option:2:selected`, + speaker: `${namespace}.speaker`, + text: `${namespace}.option.2.selected`, }, ], }, @@ -181,7 +181,7 @@ export const DarkDealEncounter: IMysteryEncounter = ) .withOutroDialogue([ { - text: `${namespace}:outro` + text: `${namespace}.outro` } ]) .build(); diff --git a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts index c1c3fb8c3c8..bcab1b4bd02 100644 --- a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts +++ b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts @@ -47,23 +47,26 @@ export const DelibirdyEncounter: IMysteryEncounter = )) .withIntroSpriteConfigs([ { - spriteKey: Species.DELIBIRD.toString(), - fileRoot: "pokemon", + spriteKey: null, + fileRoot: null, + species: Species.DELIBIRD, hasShadow: true, repeat: true, startFrame: 38, scale: 0.94 }, { - spriteKey: Species.DELIBIRD.toString(), - fileRoot: "pokemon", + spriteKey: null, + fileRoot: null, + species: Species.DELIBIRD, hasShadow: true, repeat: true, scale: 1.06 }, { - spriteKey: Species.DELIBIRD.toString(), - fileRoot: "pokemon", + spriteKey: null, + fileRoot: null, + species: Species.DELIBIRD, hasShadow: true, repeat: true, startFrame: 65, @@ -74,15 +77,15 @@ export const DelibirdyEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, } ]) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOutroDialogue([ { - text: `${namespace}:outro`, + text: `${namespace}.outro`, } ]) .withOption( @@ -90,11 +93,11 @@ export const DelibirdyEncounter: IMysteryEncounter = .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .withSceneMoneyRequirement(0, 2.75) // Must have money to spawn .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }) @@ -127,12 +130,12 @@ export const DelibirdyEncounter: IMysteryEncounter = .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .withPrimaryPokemonRequirement(new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS)) .withDialogue({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, - secondOptionPrompt: `${namespace}:option:2:select_prompt`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + secondOptionPrompt: `${namespace}.option.2.select_prompt`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }) @@ -222,12 +225,12 @@ export const DelibirdyEncounter: IMysteryEncounter = .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .withPrimaryPokemonRequirement(new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true)) .withDialogue({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, - secondOptionPrompt: `${namespace}:option:3:select_prompt`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, + secondOptionPrompt: `${namespace}.option.3.select_prompt`, selected: [ { - text: `${namespace}:option:3:selected`, + text: `${namespace}.option.3.selected`, }, ], }) @@ -261,7 +264,7 @@ export const DelibirdyEncounter: IMysteryEncounter = // If pokemon meets primary pokemon reqs, it can be selected const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon); if (!meetsReqs) { - return getEncounterText(scene, `${namespace}:invalid_selection`); + return getEncounterText(scene, `${namespace}.invalid_selection`); } return null; diff --git a/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts b/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts index 610b836ef9e..fa27c31c273 100644 --- a/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts +++ b/src/data/mystery-encounters/encounters/department-store-sale-encounter.ts @@ -32,8 +32,9 @@ export const DepartmentStoreSaleEncounter: IMysteryEncounter = x: -20, }, { - spriteKey: Species.FURFROU.toString(), - fileRoot: "pokemon", + spriteKey: null, + fileRoot: null, + species: Species.FURFROU, hasShadow: true, repeat: true, x: 30, @@ -41,21 +42,21 @@ export const DepartmentStoreSaleEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, { - text: `${namespace}:intro_dialogue`, - speaker: `${namespace}:speaker`, + text: `${namespace}.intro_dialogue`, + speaker: `${namespace}.speaker`, }, ]) .withAutoHideIntroVisuals(false) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withSimpleOption( { - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, }, async (scene: BattleScene) => { // Choose TMs @@ -80,8 +81,8 @@ export const DepartmentStoreSaleEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, }, async (scene: BattleScene) => { // Choose Vitamins @@ -104,8 +105,8 @@ export const DepartmentStoreSaleEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, }, async (scene: BattleScene) => { // Choose X Items @@ -128,8 +129,8 @@ export const DepartmentStoreSaleEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:4:label`, - buttonTooltip: `${namespace}:option:4:tooltip`, + buttonLabel: `${namespace}.option.4.label`, + buttonTooltip: `${namespace}.option.4.tooltip`, }, async (scene: BattleScene) => { // Choose Pokeballs @@ -156,7 +157,7 @@ export const DepartmentStoreSaleEncounter: IMysteryEncounter = ) .withOutroDialogue([ { - text: `${namespace}:outro`, + text: `${namespace}.outro`, } ]) .build(); diff --git a/src/data/mystery-encounters/encounters/field-trip-encounter.ts b/src/data/mystery-encounters/encounters/field-trip-encounter.ts index 9f912be1a35..e67aaa1ffad 100644 --- a/src/data/mystery-encounters/encounters/field-trip-encounter.ts +++ b/src/data/mystery-encounters/encounters/field-trip-encounter.ts @@ -42,27 +42,27 @@ export const FieldTripEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, { - text: `${namespace}:intro_dialogue`, - speaker: `${namespace}:speaker`, + text: `${namespace}.intro_dialogue`, + speaker: `${namespace}.speaker`, }, ]) .withAutoHideIntroVisuals(false) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOption( new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, - secondOptionPrompt: `${namespace}:second_option_prompt`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, + secondOptionPrompt: `${namespace}.second_option_prompt`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }) @@ -80,17 +80,17 @@ export const FieldTripEncounter: IMysteryEncounter = if (!correctMove) { encounter.options[0].dialogue.selected = [ { - text: `${namespace}:option:incorrect`, - speaker: `${namespace}:speaker`, + text: `${namespace}.option.incorrect`, + speaker: `${namespace}.speaker`, }, { - text: `${namespace}:option:lesson_learned`, + text: `${namespace}.option.lesson_learned`, }, ]; encounter.dialogue.outro = [ { - text: `${namespace}:outro_bad`, - speaker: `${namespace}:speaker`, + text: `${namespace}.outro_bad`, + speaker: `${namespace}.speaker`, }, ]; setEncounterExp(scene, scene.getParty().map((p) => p.id), 50); @@ -99,13 +99,13 @@ export const FieldTripEncounter: IMysteryEncounter = encounter.setDialogueToken("move", move.getName()); encounter.options[0].dialogue.selected = [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ]; encounter.dialogue.outro = [ { - text: `${namespace}:outro_good`, - speaker: `${namespace}:speaker`, + text: `${namespace}.outro_good`, + speaker: `${namespace}.speaker`, }, ]; setEncounterExp(scene, [pokemon.id], 100); @@ -143,12 +143,12 @@ export const FieldTripEncounter: IMysteryEncounter = new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, - secondOptionPrompt: `${namespace}:second_option_prompt`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + secondOptionPrompt: `${namespace}.second_option_prompt`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }) @@ -166,23 +166,23 @@ export const FieldTripEncounter: IMysteryEncounter = if (!correctMove) { encounter.options[1].dialogue.selected = [ { - text: `${namespace}:option:incorrect`, - speaker: `${namespace}:speaker`, + text: `${namespace}.option.incorrect`, + speaker: `${namespace}.speaker`, }, { - text: `${namespace}:option:lesson_learned`, + text: `${namespace}.option.lesson_learned`, }, ]; encounter.dialogue.outro = [ { - text: `${namespace}:outro_bad`, - speaker: `${namespace}:speaker`, + text: `${namespace}.outro_bad`, + speaker: `${namespace}.speaker`, }, ]; encounter.dialogue.outro = [ { - text: `${namespace}:outro_bad`, - speaker: `${namespace}:speaker`, + text: `${namespace}.outro_bad`, + speaker: `${namespace}.speaker`, }, ]; setEncounterExp(scene, scene.getParty().map((p) => p.id), 50); @@ -191,13 +191,13 @@ export const FieldTripEncounter: IMysteryEncounter = encounter.setDialogueToken("move", move.getName()); encounter.options[1].dialogue.selected = [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ]; encounter.dialogue.outro = [ { - text: `${namespace}:outro_good`, - speaker: `${namespace}:speaker`, + text: `${namespace}.outro_good`, + speaker: `${namespace}.speaker`, }, ]; setEncounterExp(scene, [pokemon.id], 100); @@ -235,12 +235,12 @@ export const FieldTripEncounter: IMysteryEncounter = new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, - secondOptionPrompt: `${namespace}:second_option_prompt`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, + secondOptionPrompt: `${namespace}.second_option_prompt`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }) @@ -258,17 +258,17 @@ export const FieldTripEncounter: IMysteryEncounter = if (!correctMove) { encounter.options[2].dialogue.selected = [ { - text: `${namespace}:option:incorrect`, - speaker: `${namespace}:speaker`, + text: `${namespace}.option.incorrect`, + speaker: `${namespace}.speaker`, }, { - text: `${namespace}:option:lesson_learned`, + text: `${namespace}.option.lesson_learned`, }, ]; encounter.dialogue.outro = [ { - text: `${namespace}:outro_bad`, - speaker: `${namespace}:speaker`, + text: `${namespace}.outro_bad`, + speaker: `${namespace}.speaker`, }, ]; setEncounterExp(scene, scene.getParty().map((p) => p.id), 50); @@ -277,13 +277,13 @@ export const FieldTripEncounter: IMysteryEncounter = encounter.setDialogueToken("move", move.getName()); encounter.options[2].dialogue.selected = [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ]; encounter.dialogue.outro = [ { - text: `${namespace}:outro_good`, - speaker: `${namespace}:speaker`, + text: `${namespace}.outro_good`, + speaker: `${namespace}.speaker`, }, ]; setEncounterExp(scene, [pokemon.id], 100); diff --git a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts index c7933129ff9..71311481ed1 100644 --- a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts +++ b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts @@ -1,5 +1,5 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; -import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, initCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { AttackTypeBoosterModifierType, modifierTypes, } from "#app/modifier/modifier-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "#app/battle-scene"; @@ -46,7 +46,7 @@ export const FieryFalloutEncounter: IMysteryEncounter = .withAutoHideIntroVisuals(false) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, ]) .withOnInit((scene: BattleScene) => { @@ -75,8 +75,9 @@ export const FieryFalloutEncounter: IMysteryEncounter = // Load hidden Volcarona sprites encounter.spriteConfigs = [ { - spriteKey: volcaronaSpecies.getSpriteId(false), - fileRoot: "pokemon", + spriteKey: null, + fileRoot: null, + species: Species.VOLCARONA, repeat: true, hidden: true, hasShadow: true, @@ -84,8 +85,9 @@ export const FieryFalloutEncounter: IMysteryEncounter = startFrame: 20 }, { - spriteKey: volcaronaSpecies.getSpriteId(true ), - fileRoot: "pokemon", + spriteKey: null, + fileRoot: null, + species: Species.VOLCARONA, repeat: true, hidden: true, hasShadow: true, @@ -94,7 +96,7 @@ export const FieryFalloutEncounter: IMysteryEncounter = ]; // Load animations/sfx for Volcarona moves - initCustomMovesForEncounter(scene, [Moves.FIRE_SPIN, Moves.QUIVER_DANCE]); + loadCustomMovesForEncounter(scene, [Moves.FIRE_SPIN, Moves.QUIVER_DANCE]); scene.arena.trySetWeather(WeatherType.SUNNY, true); @@ -115,28 +117,23 @@ export const FieryFalloutEncounter: IMysteryEncounter = return true; }) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withSimpleOption( { - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }, async (scene: BattleScene) => { // Pick battle const encounter = scene.currentBattle.mysteryEncounter; - setEncounterRewards(scene, - { fillRemaining: true }, - null, - () => { - giveLeadPokemonCharcoal(scene); - }); + setEncounterRewards(scene, { fillRemaining: true }, null, () => giveLeadPokemonCharcoal(scene)); encounter.startOfBattleEffects.push( { @@ -168,11 +165,11 @@ export const FieryFalloutEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }, @@ -195,7 +192,7 @@ export const FieryFalloutEncounter: IMysteryEncounter = if (chosenPokemon.trySetStatus(StatusEffect.BURN)) { // Burn applied encounter.setDialogueToken("burnedPokemon", chosenPokemon.name); - queueEncounterMessage(scene, `${namespace}:option:2:target_burned`); + queueEncounterMessage(scene, `${namespace}.option.2.target_burned`); } } @@ -209,12 +206,12 @@ export const FieryFalloutEncounter: IMysteryEncounter = .withPrimaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3PrimaryName dialogue token automatically .withSecondaryPokemonRequirement(new TypeRequirement(Type.FIRE, true, 1)) // Will set option3SecondaryName dialogue token automatically .withDialogue({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, - disabledButtonTooltip: `${namespace}:option:3:disabled_tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, + disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`, selected: [ { - text: `${namespace}:option:3:selected`, + text: `${namespace}.option.3.selected`, }, ], }) @@ -249,6 +246,6 @@ function giveLeadPokemonCharcoal(scene: BattleScene) { const charcoal = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FIRE]).type as AttackTypeBoosterModifierType; applyModifierTypeToPlayerPokemon(scene, leadPokemon, charcoal); scene.currentBattle.mysteryEncounter.setDialogueToken("leadPokemon", leadPokemon.name); - queueEncounterMessage(scene, `${namespace}:found_charcoal`); + queueEncounterMessage(scene, `${namespace}.found_charcoal`); } } diff --git a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts index 77ef97ace84..a60c4ff4c05 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts @@ -7,7 +7,7 @@ import { setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups"; -import Pokemon from "#app/field/pokemon"; +import Pokemon, { EnemyPokemon } from "#app/field/pokemon"; import { ModifierTier } from "#app/modifier/modifier-tier"; import { getPartyLuckValue, @@ -27,6 +27,9 @@ import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-enco import { getPokemonNameWithAffix } from "#app/messages"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; +import { TrainerSlot } from "#app/data/trainer-config"; +import { getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import PokemonData from "#app/system/pokemon-data"; /** the i18n namespace for the encounter */ const namespace = "mysteryEncounter:fightOrFlight"; @@ -45,7 +48,7 @@ export const FightOrFlightEncounter: IMysteryEncounter = .withIntroSpriteConfigs([]) // Set in onInit() .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, ]) .withOnInit((scene: BattleScene) => { @@ -53,9 +56,14 @@ export const FightOrFlightEncounter: IMysteryEncounter = // Calculate boss mon const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, scene.currentBattle.waveIndex, 0, getPartyLuckValue(scene.getParty()), true); + const bossPokemon = new EnemyPokemon(scene, bossSpecies, scene.currentBattle.waveIndex, TrainerSlot.NONE, true, null); const config: EnemyPartyConfig = { levelAdditiveMultiplier: 1, - pokemonConfigs: [{ species: bossSpecies, isBoss: true }], + pokemonConfigs: [{ + species: bossSpecies, + dataSource: new PokemonData(bossPokemon), + isBoss: true + }], }; encounter.enemyPartyConfigs = [config]; @@ -74,7 +82,7 @@ export const FightOrFlightEncounter: IMysteryEncounter = encounter.setDialogueToken("itemName", item.type.name); encounter.misc = item; - const bossSpriteKey = bossSpecies.getSpriteId(false, bossSpecies.forms ? 0 : null, false, bossSpecies.hasVariants() ? 0 : null); + const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(bossPokemon); encounter.spriteConfigs = [ { spriteKey: item.type.iconImage, @@ -87,12 +95,13 @@ export const FightOrFlightEncounter: IMysteryEncounter = disableAnimation: true }, { - spriteKey: bossSpriteKey, - fileRoot: "pokemon", + spriteKey: spriteKey, + fileRoot: fileRoot, hasShadow: true, tint: 0.25, x: -5, repeat: true, + isPokemon: true }, ]; @@ -101,23 +110,23 @@ export const FightOrFlightEncounter: IMysteryEncounter = const primaryPokemon = encounter.options[1].primaryPokemon; if (primaryPokemon) { // Use primaryPokemon to execute the thievery - encounter.options[1].dialogue.buttonTooltip = `${namespace}:option:2:tooltip_special`; + encounter.options[1].dialogue.buttonTooltip = `${namespace}.option.2.tooltip_special`; } else { - encounter.options[1].dialogue.buttonTooltip = `${namespace}:option:2:tooltip`; + encounter.options[1].dialogue.buttonTooltip = `${namespace}.option.2.tooltip`; } return true; }) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withSimpleOption( { - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }, @@ -134,8 +143,8 @@ export const FightOrFlightEncounter: IMysteryEncounter = .withOptionMode(MysteryEncounterOptionMode.DEFAULT_OR_SPECIAL) .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically .withDialogue({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, }) .withOptionPhase(async (scene: BattleScene) => { // Pick steal @@ -147,7 +156,7 @@ export const FightOrFlightEncounter: IMysteryEncounter = const primaryPokemon = encounter.options[1].primaryPokemon; if (primaryPokemon) { // Use primaryPokemon to execute the thievery - await showEncounterText(scene, `${namespace}:option:2:special_result`); + await showEncounterText(scene, `${namespace}.option.2.special_result`); setEncounterExp(scene, primaryPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs[0].species.baseExp, true); leaveEncounterWithoutBattle(scene); return; @@ -160,15 +169,15 @@ export const FightOrFlightEncounter: IMysteryEncounter = config.pokemonConfigs[0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON]; config.pokemonConfigs[0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => { pokemon.scene.currentBattle.mysteryEncounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(pokemon)); - queueEncounterMessage(pokemon.scene, `${namespace}option:2:boss_enraged`); + queueEncounterMessage(pokemon.scene, `${namespace}option.2.boss_enraged`); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD], 1)); }; - await showEncounterText(scene, `${namespace}:option:2:bad_result`); + await showEncounterText(scene, `${namespace}.option.2.bad_result`); await initBattleWithEnemyConfig(scene, config); } else { // Steal item (37.5%) // Display result message then proceed to rewards - await showEncounterText(scene, `${namespace}:option:2:good_result`); + await showEncounterText(scene, `${namespace}.option.2.good_result`); leaveEncounterWithoutBattle(scene); } }) @@ -176,11 +185,11 @@ export const FightOrFlightEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, selected: [ { - text: `${namespace}:option:3:selected`, + text: `${namespace}.option.3.selected`, }, ], }, diff --git a/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts b/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts index a4e47311f43..02f2393811a 100644 --- a/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts +++ b/src/data/mystery-encounters/encounters/lost-at-sea-encounter.ts @@ -31,14 +31,14 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with .withSceneWaveRangeRequirement(11, 179) .withIntroSpriteConfigs([ { - fileRoot: "mystery-encounters", spriteKey: "buoy", + fileRoot: "mystery-encounters", hasShadow: false, x: 20, y: 3, }, ]) - .withIntroDialogue([{ text: `${namespace}:intro` }]) + .withIntroDialogue([{ text: `${namespace}.intro` }]) .withOnInit((scene: BattleScene) => { const { mysteryEncounter } = scene.currentBattle; @@ -48,22 +48,22 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with return true; }) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOption( // Option 1: Use a (non fainted) pokemon that can learn Surf to guide you back/ new MysteryEncounterOptionBuilder() .withPokemonCanLearnMoveRequirement(OPTION_1_REQUIRED_MOVE) .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - disabledButtonLabel: `${namespace}:option:1:label_disabled`, - buttonTooltip: `${namespace}:option:1:tooltip`, - disabledButtonTooltip: `${namespace}:option:1:tooltip_disabled`, + buttonLabel: `${namespace}.option.1.label`, + disabledButtonLabel: `${namespace}.option.1.label_disabled`, + buttonTooltip: `${namespace}.option.1.tooltip`, + disabledButtonTooltip: `${namespace}.option.1.tooltip_disabled`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }) @@ -76,13 +76,13 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with .withPokemonCanLearnMoveRequirement(OPTION_2_REQUIRED_MOVE) .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:2:label`, - disabledButtonLabel: `${namespace}:option:2:label_disabled`, - buttonTooltip: `${namespace}:option:2:tooltip`, - disabledButtonTooltip: `${namespace}:option:2:tooltip_disabled`, + buttonLabel: `${namespace}.option.2.label`, + disabledButtonLabel: `${namespace}.option.2.label_disabled`, + buttonTooltip: `${namespace}.option.2.tooltip`, + disabledButtonTooltip: `${namespace}.option.2.tooltip_disabled`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }) @@ -92,11 +92,11 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with .withSimpleOption( // Option 3: Wander aimlessly { - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, selected: [ { - text: `${namespace}:option:3:selected`, + text: `${namespace}.option.3.selected`, }, ], }, @@ -116,7 +116,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with ) .withOutroDialogue([ { - text: `${namespace}:outro`, + text: `${namespace}.outro`, }, ]) .build(); diff --git a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts index ab77f0c4646..368b18b11c0 100644 --- a/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-challengers-encounter.ts @@ -33,7 +33,7 @@ export const MysteriousChallengersEncounter: IMysteryEncounter = .withIntroSpriteConfigs([]) // These are set in onInit() .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, ]) .withOnInit((scene: BattleScene) => { @@ -122,16 +122,16 @@ export const MysteriousChallengersEncounter: IMysteryEncounter = return true; }) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withSimpleOption( { - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }, @@ -152,11 +152,11 @@ export const MysteriousChallengersEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }, @@ -177,11 +177,11 @@ export const MysteriousChallengersEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }, @@ -205,7 +205,7 @@ export const MysteriousChallengersEncounter: IMysteryEncounter = ) .withOutroDialogue([ { - text: `${namespace}:outro`, + text: `${namespace}.outro`, }, ]) .build(); diff --git a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts index e418655bbf5..5f6f235efc2 100644 --- a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts @@ -36,21 +36,21 @@ export const MysteriousChestEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, } ]) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOption( new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }) @@ -75,7 +75,7 @@ export const MysteriousChestEncounter: IMysteryEncounter = ], }); // Display result message then proceed to rewards - queueEncounterMessage(scene, `${namespace}:option:1:normal`); + queueEncounterMessage(scene, `${namespace}.option.1.normal`); leaveEncounterWithoutBattle(scene); } else if (roll > 40) { // Choose between 3 ULTRA tier items (20%) @@ -87,7 +87,7 @@ export const MysteriousChestEncounter: IMysteryEncounter = ], }); // Display result message then proceed to rewards - queueEncounterMessage(scene, `${namespace}:option:1:good`); + queueEncounterMessage(scene, `${namespace}.option.1.good`); leaveEncounterWithoutBattle(scene); } else if (roll > 36) { // Choose between 2 ROGUE tier items (4%) @@ -95,7 +95,7 @@ export const MysteriousChestEncounter: IMysteryEncounter = guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE], }); // Display result message then proceed to rewards - queueEncounterMessage(scene, `${namespace}:option:1:great`); + queueEncounterMessage(scene, `${namespace}.option.1.great`); leaveEncounterWithoutBattle(scene); } else if (roll > 35) { // Choose 1 MASTER tier item (1%) @@ -103,7 +103,7 @@ export const MysteriousChestEncounter: IMysteryEncounter = guaranteedModifierTiers: [ModifierTier.MASTER], }); // Display result message then proceed to rewards - queueEncounterMessage(scene, `${namespace}:option:1:amazing`); + queueEncounterMessage(scene, `${namespace}.option.1.amazing`); leaveEncounterWithoutBattle(scene); } else { // Your highest level unfainted Pok�mon gets OHKO. Progress with no rewards (35%) @@ -116,7 +116,7 @@ export const MysteriousChestEncounter: IMysteryEncounter = scene.currentBattle.mysteryEncounter.setDialogueToken("pokeName", highestLevelPokemon.name); // Show which Pokemon was KOed, then leave encounter with no rewards // Does this synchronously so that game over doesn't happen over result message - await showEncounterText(scene, `${namespace}:option:1:bad`).then(() => { + await showEncounterText(scene, `${namespace}.option.1.bad`).then(() => { leaveEncounterWithoutBattle(scene); }); } @@ -125,11 +125,11 @@ export const MysteriousChestEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }, diff --git a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts index 7ca2e991305..e110d43fc50 100644 --- a/src/data/mystery-encounters/encounters/safari-zone-encounter.ts +++ b/src/data/mystery-encounters/encounters/safari-zone-encounter.ts @@ -36,31 +36,30 @@ export const SafariZoneEncounter: IMysteryEncounter = .withSceneRequirement(new MoneyRequirement(0, 2.75)) // Cost equal to 1 Max Revive .withIntroSpriteConfigs([ { - spriteKey: "chest_blue", + spriteKey: "safari_zone", fileRoot: "mystery-encounters", - hasShadow: true, + hasShadow: false, x: 4, - y: 10, - yShadow: 3 + y: 6 }, ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, ]) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOption(new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .withSceneRequirement(new MoneyRequirement(0, 2.75)) // Cost equal to 1 Max Revive .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }) @@ -86,11 +85,11 @@ export const SafariZoneEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }, @@ -121,11 +120,11 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [ new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:safari:1:label`, - buttonTooltip: `${namespace}:safari:1:tooltip`, + buttonLabel: `${namespace}.safari.1.label`, + buttonTooltip: `${namespace}.safari.1.tooltip`, selected: [ { - text: `${namespace}:safari:1:selected`, + text: `${namespace}.safari.1.selected`, } ], }) @@ -154,11 +153,11 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [ new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:safari:2:label`, - buttonTooltip: `${namespace}:safari:2:tooltip`, + buttonLabel: `${namespace}.safari.2.label`, + buttonTooltip: `${namespace}.safari.2.tooltip`, selected: [ { - text: `${namespace}:safari:2:selected`, + text: `${namespace}.safari.2.selected`, }, ], }) @@ -172,9 +171,9 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [ // 80% chance to increase flee stage +1 const fleeChangeResult = tryChangeFleeStage(scene, 1, 8); if (!fleeChangeResult) { - await showEncounterText(scene, getEncounterText(scene, `${namespace}:safari:busy_eating`), 1000, false ); + await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.busy_eating`), 1000, false ); } else { - await showEncounterText(scene, getEncounterText(scene, `${namespace}:safari:eating`), 1000, false); + await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.eating`), 1000, false); } await doEndTurn(scene, 1); @@ -184,11 +183,11 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [ new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:safari:3:label`, - buttonTooltip: `${namespace}:safari:3:tooltip`, + buttonLabel: `${namespace}.safari.3.label`, + buttonTooltip: `${namespace}.safari.3.tooltip`, selected: [ { - text: `${namespace}:safari:3:selected`, + text: `${namespace}.safari.3.selected`, }, ], }) @@ -201,9 +200,9 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [ // 80% chance to decrease catch stage -1 const catchChangeResult = tryChangeCatchStage(scene, -1, 8); if (!catchChangeResult) { - await showEncounterText(scene, getEncounterText(scene, `${namespace}:safari:beside_itself_angry`), 1000, false ); + await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.beside_itself_angry`), 1000, false ); } else { - await showEncounterText(scene, getEncounterText(scene, `${namespace}:safari:angry`), 1000, false ); + await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.angry`), 1000, false ); } await doEndTurn(scene, 2); @@ -213,8 +212,8 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [ new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withDialogue({ - buttonLabel: `${namespace}:safari:4:label`, - buttonTooltip: `${namespace}:safari:4:tooltip`, + buttonLabel: `${namespace}.safari.4.label`, + buttonTooltip: `${namespace}.safari.4.tooltip`, }) .withOptionPhase(async (scene: BattleScene) => { // Flee option @@ -237,7 +236,7 @@ async function summonSafariPokemon(scene: BattleScene) { const encounter = scene.currentBattle.mysteryEncounter; // Message pokemon remaining encounter.setDialogueToken("remainingCount", encounter.misc.safariPokemonRemaining); - scene.queueMessage(getEncounterText(scene, `${namespace}:safari:remaining_count`), null, true); + scene.queueMessage(getEncounterText(scene, `${namespace}.safari.remaining_count`), null, true); // Generate pokemon using safariPokemonRemaining so they are always the same pokemon no matter how many turns are taken // Safari pokemon roll twice on shiny and HA chances, but are otherwise normal @@ -491,7 +490,7 @@ async function doEndTurn(scene: BattleScene, cursorIndex: number) { leaveEncounterWithoutBattle(scene, true); } } else { - scene.queueMessage(getEncounterText(scene, `${namespace}:safari:watching`), 0, null, 1000); + scene.queueMessage(getEncounterText(scene, `${namespace}.safari.watching`), 0, null, 1000); initSubsequentOptionSelect(scene, { overrideOptions: safariZoneGameOptions, startingCursorIndex: cursorIndex, hideDescription: true }); } } diff --git a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts index bd7afdaa832..86a8a614ba6 100644 --- a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts +++ b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts @@ -49,26 +49,26 @@ export const ShadyVitaminDealerEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, { - text: `${namespace}:intro_dialogue`, - speaker: `${namespace}:speaker`, + text: `${namespace}.intro_dialogue`, + speaker: `${namespace}.speaker`, }, ]) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOption( new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .withSceneMoneyRequirement(0, 2) // Wave scaling money multiplier of 2 .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }) @@ -127,13 +127,13 @@ export const ShadyVitaminDealerEncounter: IMysteryEncounter = if (randSeedInt(10) < 8) { if (chosenPokemon.trySetStatus(StatusEffect.TOXIC)) { // Toxic applied - queueEncounterMessage(scene, `${namespace}:bad_poison`); + queueEncounterMessage(scene, `${namespace}.bad_poison`); } else { // Pokemon immune or something else prevents status - queueEncounterMessage(scene, `${namespace}:damage_only`); + queueEncounterMessage(scene, `${namespace}.damage_only`); } } else { - queueEncounterMessage(scene, `${namespace}:damage_only`); + queueEncounterMessage(scene, `${namespace}.damage_only`); } setEncounterExp(scene, [chosenPokemon.id], 100); @@ -147,11 +147,11 @@ export const ShadyVitaminDealerEncounter: IMysteryEncounter = .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) .withSceneMoneyRequirement(0, 5) // Wave scaling money multiplier of 5 .withDialogue({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }) @@ -178,7 +178,7 @@ export const ShadyVitaminDealerEncounter: IMysteryEncounter = // If pokemon meets primary pokemon reqs, it can be selected const meetsReqs = encounter.pokemonMeetsPrimaryRequirements(scene, pokemon); if (!meetsReqs) { - return getEncounterText(scene, `${namespace}:invalid_selection`); + return getEncounterText(scene, `${namespace}.invalid_selection`); } return null; @@ -207,13 +207,13 @@ export const ShadyVitaminDealerEncounter: IMysteryEncounter = if (randSeedInt(10) < 2) { if (chosenPokemon.trySetStatus(StatusEffect.POISON)) { // Poison applied - queueEncounterMessage(scene, `${namespace}:poison`); + queueEncounterMessage(scene, `${namespace}.poison`); } else { // Pokemon immune or something else prevents status - queueEncounterMessage(scene, `${namespace}:no_bad_effects`); + queueEncounterMessage(scene, `${namespace}.no_bad_effects`); } } else { - queueEncounterMessage(scene, `${namespace}:no_bad_effects`); + queueEncounterMessage(scene, `${namespace}.no_bad_effects`); } setEncounterExp(scene, [chosenPokemon.id], 100); @@ -224,12 +224,12 @@ export const ShadyVitaminDealerEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, selected: [ { - text: `${namespace}:option:3:selected`, - speaker: `${namespace}:speaker` + text: `${namespace}.option.3.selected`, + speaker: `${namespace}.speaker` } ] }, diff --git a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts index 316416e3809..6d56f2cde46 100644 --- a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts +++ b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts @@ -7,7 +7,7 @@ import { StatusEffect } from "#app/data/status-effect"; import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter"; import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option"; import { MoveRequirement } from "../mystery-encounter-requirements"; -import { EnemyPartyConfig, EnemyPokemonConfig, initBattleWithEnemyConfig, initCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, } from "../utils/encounter-phase-utils"; +import { EnemyPartyConfig, EnemyPokemonConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, } from "../utils/encounter-phase-utils"; import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { Moves } from "#enums/moves"; import { BattlerIndex } from "#app/battle"; @@ -44,7 +44,7 @@ export const SlumberingSnorlaxEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, ]) .withOnInit((scene: BattleScene) => { @@ -66,20 +66,20 @@ export const SlumberingSnorlaxEncounter: IMysteryEncounter = encounter.enemyPartyConfigs = [config]; // Load animations/sfx for Snorlax fight start moves - initCustomMovesForEncounter(scene, [Moves.SNORE]); + loadCustomMovesForEncounter(scene, [Moves.SNORE]); return true; }) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withSimpleOption( { - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }, @@ -105,11 +105,11 @@ export const SlumberingSnorlaxEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }, @@ -117,7 +117,7 @@ export const SlumberingSnorlaxEncounter: IMysteryEncounter = // Fall asleep waiting for Snorlax // Full heal party scene.unshiftPhase(new PartyHealPhase(scene, true)); - queueEncounterMessage(scene, `${namespace}:option:2:rest_result`); + queueEncounterMessage(scene, `${namespace}.option.2.rest_result`); leaveEncounterWithoutBattle(scene); } ) @@ -126,12 +126,12 @@ export const SlumberingSnorlaxEncounter: IMysteryEncounter = .withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) .withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) .withDialogue({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, - disabledButtonTooltip: `${namespace}:option:3:disabled_tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, + disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`, selected: [ { - text: `${namespace}:option:3:selected` + text: `${namespace}.option.3.selected` } ] }) diff --git a/src/data/mystery-encounters/encounters/pokemon-salesman-encounter.ts b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts similarity index 79% rename from src/data/mystery-encounters/encounters/pokemon-salesman-encounter.ts rename to src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts index d1750119add..26ddf86719d 100644 --- a/src/data/mystery-encounters/encounters/pokemon-salesman-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts @@ -4,7 +4,7 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "#app/battle-scene"; import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter"; import { MoneyRequirement } from "../mystery-encounter-requirements"; -import { catchPokemon, getRandomSpeciesByStarterTier } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { catchPokemon, getRandomSpeciesByStarterTier, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species"; import { Species } from "#enums/species"; import { PokeballType } from "#app/data/pokeball"; @@ -25,8 +25,8 @@ const MAX_POKEMON_PRICE_MULTIPLIER = 6; * @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/36 | GitHub Issue #36} * @see For biome requirements check {@linkcode mysteryEncountersByBiome} */ -export const PokemonSalesmanEncounter: IMysteryEncounter = - MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.POKEMON_SALESMAN) +export const ThePokemonSalesmanEncounter: IMysteryEncounter = + MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_POKEMON_SALESMAN) .withEncounterTier(MysteryEncounterTier.ULTRA) .withSceneWaveRangeRequirement(10, 180) .withSceneRequirement(new MoneyRequirement(null, MAX_POKEMON_PRICE_MULTIPLIER)) // Some costs may not be as significant, this is the max you'd pay @@ -40,16 +40,16 @@ export const PokemonSalesmanEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, { - text: `${namespace}:intro_dialogue`, - speaker: `${namespace}:speaker`, + text: `${namespace}.intro_dialogue`, + speaker: `${namespace}.speaker`, }, ]) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOnInit((scene: BattleScene) => { const encounter = scene.currentBattle.mysteryEncounter; @@ -66,17 +66,16 @@ export const PokemonSalesmanEncounter: IMysteryEncounter = // If no HA mon found or you roll 1%, give shiny Magikarp species = getPokemonSpecies(Species.MAGIKARP); const hiddenIndex = species.ability2 ? 2 : 1; - pokemon = scene.addPlayerPokemon(species, 5, hiddenIndex, species.formIndex, null, true); + pokemon = new PlayerPokemon(scene, species, 5, hiddenIndex, species.formIndex, null, true, null, null, null, null); } else { const hiddenIndex = species.ability2 ? 2 : 1; - pokemon = scene.addPlayerPokemon(species, 5, hiddenIndex, species.formIndex); + pokemon = new PlayerPokemon(scene, species, 5, hiddenIndex, species.formIndex, null, null, null, null, null, null); } - const spriteKey = pokemon.getSpriteId(); - const spriteRoot = pokemon.getSpriteAtlasPath(); + const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(pokemon); encounter.spriteConfigs.push({ spriteKey: spriteKey, - fileRoot: spriteRoot, + fileRoot: fileRoot, hasShadow: true, repeat: true, isPokemon: true @@ -89,8 +88,8 @@ export const PokemonSalesmanEncounter: IMysteryEncounter = // Always max price for shiny (flip HA back to normal), and add special messaging priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER; pokemon.abilityIndex = 0; - encounter.dialogue.encounterOptionsDialogue.description = `${namespace}:description_shiny`; - encounter.options[0].dialogue.buttonTooltip = `${namespace}:option:1:tooltip_shiny`; + encounter.dialogue.encounterOptionsDialogue.description = `${namespace}.description_shiny`; + encounter.options[0].dialogue.buttonTooltip = `${namespace}.option.1.tooltip_shiny`; } const price = scene.getWaveMoneyAmount(priceMultiplier); encounter.setDialogueToken("purchasePokemon", pokemon.name); @@ -110,11 +109,11 @@ export const PokemonSalesmanEncounter: IMysteryEncounter = .withHasDexProgress(true) .withSceneMoneyRequirement(null, MAX_POKEMON_PRICE_MULTIPLIER) // Wave scaling money multiplier of 2 .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected_message`, + text: `${namespace}.option.1.selected_message`, } ], }) @@ -127,7 +126,7 @@ export const PokemonSalesmanEncounter: IMysteryEncounter = updatePlayerMoney(scene, -price, true, false); // Show dialogue - await showEncounterDialogue(scene, `${namespace}:option:1:selected_dialogue`, `${namespace}:speaker`); + await showEncounterDialogue(scene, `${namespace}.option.1.selected_dialogue`, `${namespace}.speaker`); await transitionMysteryEncounterIntroVisuals(scene); // "Catch" purchased pokemon @@ -141,11 +140,11 @@ export const PokemonSalesmanEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }, diff --git a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts index 34967112a72..e3e410b5b93 100644 --- a/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-strong-stuff-encounter.ts @@ -1,4 +1,4 @@ -import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, initCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { modifierTypes, PokemonHeldItemModifierType, } from "#app/modifier/modifier-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "#app/battle-scene"; @@ -55,7 +55,7 @@ export const TheStrongStuffEncounter: IMysteryEncounter = ]) // Set in onInit() .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, }, ]) .withOnInit((scene: BattleScene) => { @@ -82,7 +82,7 @@ export const TheStrongStuffEncounter: IMysteryEncounter = ], tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], mysteryEncounterBattleEffects: (pokemon: Pokemon) => { - queueEncounterMessage(pokemon.scene, `${namespace}:option:2:stat_boost`); + queueEncounterMessage(pokemon.scene, `${namespace}.option.2.stat_boost`); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.DEF, BattleStat.SPDEF], 2)); } } @@ -91,20 +91,20 @@ export const TheStrongStuffEncounter: IMysteryEncounter = encounter.enemyPartyConfigs = [config]; - initCustomMovesForEncounter(scene, [Moves.GASTRO_ACID, Moves.STEALTH_ROCK]); + loadCustomMovesForEncounter(scene, [Moves.GASTRO_ACID, Moves.STEALTH_ROCK]); return true; }) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withSimpleOption( { - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected` + text: `${namespace}.option.1.selected` } ] }, @@ -148,7 +148,7 @@ export const TheStrongStuffEncounter: IMysteryEncounter = } encounter.setDialogueToken("highBstPokemon", highestBst.name); - await showEncounterText(scene, `${namespace}:option:1:selected_2`, null, true); + await showEncounterText(scene, `${namespace}.option.1.selected_2`, null, true); setEncounterRewards(scene, { fillRemaining: true }); leaveEncounterWithoutBattle(scene, true); @@ -157,11 +157,11 @@ export const TheStrongStuffEncounter: IMysteryEncounter = ) .withSimpleOption( { - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }, diff --git a/src/data/mystery-encounters/encounters/training-session-encounter.ts b/src/data/mystery-encounters/encounters/training-session-encounter.ts index 02bee131a02..c6cd93068b9 100644 --- a/src/data/mystery-encounters/encounters/training-session-encounter.ts +++ b/src/data/mystery-encounters/encounters/training-session-encounter.ts @@ -46,22 +46,22 @@ export const TrainingSessionEncounter: IMysteryEncounter = ]) .withIntroDialogue([ { - text: `${namespace}:intro`, + text: `${namespace}.intro`, } ]) - .withTitle(`${namespace}:title`) - .withDescription(`${namespace}:description`) - .withQuery(`${namespace}:query`) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) .withOption( new MysteryEncounterOptionBuilder() .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withHasDexProgress(true) .withDialogue({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }) @@ -77,7 +77,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = const selectableFilter = (pokemon: Pokemon) => { const meetsReqs = pokemon.isAllowedInBattle(); if (!meetsReqs) { - return getEncounterText(scene, `${namespace}:invalid_selection`); + return getEncounterText(scene, `${namespace}.invalid_selection`); } return null; @@ -182,7 +182,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = scene.addModifier(mod, true, false, false, true); } scene.updateModifiers(true); - queueEncounterMessage(scene, `${namespace}:option:1:finished`); + queueEncounterMessage(scene, `${namespace}.option.1.finished`); }; setEncounterRewards( @@ -201,12 +201,12 @@ export const TrainingSessionEncounter: IMysteryEncounter = .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withHasDexProgress(true) .withDialogue({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, - secondOptionPrompt: `${namespace}:option:2:select_prompt`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + secondOptionPrompt: `${namespace}.option.2.select_prompt`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }) @@ -237,7 +237,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = const selectableFilter = (pokemon: Pokemon) => { const meetsReqs = pokemon.isAllowedInBattle(); if (!meetsReqs) { - return getEncounterText(scene, `${namespace}:invalid_selection`); + return getEncounterText(scene, `${namespace}.invalid_selection`); } return null; @@ -265,7 +265,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = scene.removePokemonFromPlayerParty(playerPokemon, false); const onBeforeRewardsPhase = () => { - queueEncounterMessage(scene, `${namespace}:option:2:finished`); + queueEncounterMessage(scene, `${namespace}.option.2.finished`); // Add the pokemon back to party with Nature change playerPokemon.setNature(encounter.misc.chosenNature); scene.gameData.setPokemonCaught(playerPokemon, false); @@ -294,12 +294,12 @@ export const TrainingSessionEncounter: IMysteryEncounter = .withOptionMode(MysteryEncounterOptionMode.DEFAULT) .withHasDexProgress(true) .withDialogue({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, - secondOptionPrompt: `${namespace}:option:3:select_prompt`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, + secondOptionPrompt: `${namespace}.option.3.select_prompt`, selected: [ { - text: `${namespace}:option:selected`, + text: `${namespace}.option.selected`, }, ], }) @@ -339,7 +339,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = const selectableFilter = (pokemon: Pokemon) => { const meetsReqs = pokemon.isAllowedInBattle(); if (!meetsReqs) { - return getEncounterText(scene, `${namespace}:invalid_selection`); + return getEncounterText(scene, `${namespace}.invalid_selection`); } return null; @@ -371,7 +371,7 @@ export const TrainingSessionEncounter: IMysteryEncounter = scene.removePokemonFromPlayerParty(playerPokemon, false); const onBeforeRewardsPhase = () => { - queueEncounterMessage(scene, `${namespace}:option:3:finished`); + queueEncounterMessage(scene, `${namespace}.option.3.finished`); // Add the pokemon back to party with ability change const abilityIndex = encounter.misc.abilityIndex; if (!!playerPokemon.getFusionSpeciesForm()) { diff --git a/src/data/mystery-encounters/mystery-encounter.ts b/src/data/mystery-encounters/mystery-encounter.ts index 502d84d9124..8eababcfdeb 100644 --- a/src/data/mystery-encounters/mystery-encounter.ts +++ b/src/data/mystery-encounters/mystery-encounter.ts @@ -47,6 +47,7 @@ export default interface IMysteryEncounter { encounterAnimations?: EncounterAnim[]; hideBattleIntroMessage?: boolean; autoHideIntroVisuals?: boolean; + enterIntroVisualsFromRight?: boolean; catchAllowed?: boolean; maxAllowedEncounters?: number; @@ -159,14 +160,15 @@ export default class IMysteryEncounter implements IMysteryEncounter { if (!isNullOrUndefined(encounter)) { Object.assign(this, encounter); } - this.encounterTier = !isNullOrUndefined(this.encounterTier) ? this.encounterTier : MysteryEncounterTier.COMMON; + this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON; this.dialogue = this.dialogue ?? {}; // Default max is 1 for ROGUE encounters, 3 for others this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? 1 : 3; this.encounterMode = MysteryEncounterMode.DEFAULT; this.requirements = this.requirements ? this.requirements : []; - this.hideBattleIntroMessage = !isNullOrUndefined(this.hideBattleIntroMessage) ? this.hideBattleIntroMessage : false; - this.autoHideIntroVisuals = !isNullOrUndefined(this.autoHideIntroVisuals) ? this.autoHideIntroVisuals : true; + this.hideBattleIntroMessage = this.hideBattleIntroMessage ?? false; + this.autoHideIntroVisuals = this.autoHideIntroVisuals ?? true; + this.enterIntroVisualsFromRight = this.enterIntroVisualsFromRight ?? false; // Reset any dirty flags or encounter data this.startOfBattleEffectsComplete = false; @@ -414,6 +416,7 @@ export class MysteryEncounterBuilder implements Partial { hideBattleIntroMessage?: boolean; hideIntroVisuals?: boolean; + enterIntroVisualsFromRight?: boolean; enemyPartyConfigs?: EnemyPartyConfig[] = []; /** @@ -717,6 +720,15 @@ export class MysteryEncounterBuilder implements Partial { return Object.assign(this, { autoHideIntroVisuals: autoHideIntroVisuals }); } + /** + * @param enterIntroVisualsFromRight - If true, will slide in intro visuals from the right side of the screen. If false, slides in from left, as normal + * Default false + * @returns + */ + withEnterIntroVisualsFromRight(enterIntroVisualsFromRight: boolean): this & Required> { + return Object.assign(this, { enterIntroVisualsFromRight: enterIntroVisualsFromRight }); + } + /** * Add a title for the encounter * diff --git a/src/data/mystery-encounters/mystery-encounters.ts b/src/data/mystery-encounters/mystery-encounters.ts index c41fd8dfe53..c4a3251e6af 100644 --- a/src/data/mystery-encounters/mystery-encounters.ts +++ b/src/data/mystery-encounters/mystery-encounters.ts @@ -14,10 +14,11 @@ import IMysteryEncounter from "./mystery-encounter"; import { SafariZoneEncounter } from "#app/data/mystery-encounters/encounters/safari-zone-encounter"; import { FieryFalloutEncounter } from "#app/data/mystery-encounters/encounters/fiery-fallout-encounter"; import { TheStrongStuffEncounter } from "#app/data/mystery-encounters/encounters/the-strong-stuff-encounter"; -import { PokemonSalesmanEncounter } from "#app/data/mystery-encounters/encounters/pokemon-salesman-encounter"; -import { OfferYouCantRefuseEncounter } from "#app/data/mystery-encounters/encounters/offer-you-cant-refuse-encounter"; +import { ThePokemonSalesmanEncounter } from "#app/data/mystery-encounters/encounters/the-pokemon-salesman-encounter"; +import { AnOfferYouCantRefuseEncounter } from "#app/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter"; import { DelibirdyEncounter } from "#app/data/mystery-encounters/encounters/delibirdy-encounter"; import { AbsoluteAvariceEncounter } from "#app/data/mystery-encounters/encounters/absolute-avarice-encounter"; +import { ATrainersTestEncounter } from "#app/data/mystery-encounters/encounters/a-trainers-test-encounter"; // Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * ) / 256 export const BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT = 1; @@ -137,8 +138,8 @@ const nonExtremeBiomeEncounters: MysteryEncounterType[] = [ const humanTransitableBiomeEncounters: MysteryEncounterType[] = [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS, MysteryEncounterType.SHADY_VITAMIN_DEALER, - MysteryEncounterType.POKEMON_SALESMAN, - MysteryEncounterType.OFFER_YOU_CANT_REFUSE + MysteryEncounterType.THE_POKEMON_SALESMAN, + MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE ]; const civilizationBiomeEncounters: MysteryEncounterType[] = [ @@ -154,6 +155,7 @@ const anyBiomeEncounters: MysteryEncounterType[] = [ MysteryEncounterType.MYSTERIOUS_CHEST, MysteryEncounterType.TRAINING_SESSION, MysteryEncounterType.DELIBIRDY, + MysteryEncounterType.A_TRAINERS_TEST ]; /** @@ -236,10 +238,11 @@ export function initMysteryEncounters() { allMysteryEncounters[MysteryEncounterType.LOST_AT_SEA] = LostAtSeaEncounter; allMysteryEncounters[MysteryEncounterType.FIERY_FALLOUT] = FieryFalloutEncounter; allMysteryEncounters[MysteryEncounterType.THE_STRONG_STUFF] = TheStrongStuffEncounter; - allMysteryEncounters[MysteryEncounterType.POKEMON_SALESMAN] = PokemonSalesmanEncounter; - allMysteryEncounters[MysteryEncounterType.OFFER_YOU_CANT_REFUSE] = OfferYouCantRefuseEncounter; + allMysteryEncounters[MysteryEncounterType.THE_POKEMON_SALESMAN] = ThePokemonSalesmanEncounter; + allMysteryEncounters[MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE] = AnOfferYouCantRefuseEncounter; allMysteryEncounters[MysteryEncounterType.DELIBIRDY] = DelibirdyEncounter; allMysteryEncounters[MysteryEncounterType.ABSOLUTE_AVARICE] = AbsoluteAvariceEncounter; + allMysteryEncounters[MysteryEncounterType.A_TRAINERS_TEST] = ATrainersTestEncounter; // Add extreme encounters to biome map extremeBiomeEncounters.forEach(encounter => { diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index 9fa24106417..deb65ff5774 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -5,8 +5,8 @@ import { WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mys import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import Pokemon, { FieldPosition, PlayerPokemon, PokemonMove } from "#app/field/pokemon"; import { ExpBalanceModifier, ExpShareModifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier } from "#app/modifier/modifier"; -import { CustomModifierSettings, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeGenerator, ModifierTypeOption, modifierTypes, PokemonHeldItemModifierType, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type"; -import { BattleEndPhase, EggLapsePhase, ExpPhase, GameOverPhase, ModifierRewardPhase, MovePhase, SelectModifierPhase, ShowPartyExpBarPhase, TrainerVictoryPhase } from "#app/phases"; +import { CustomModifierSettings, ModifierPoolType, ModifierType, ModifierTypeGenerator, ModifierTypeOption, modifierTypes, PokemonHeldItemModifierType, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type"; +import { BattleEndPhase, EggLapsePhase, ExpPhase, GameOverPhase, MovePhase, SelectModifierPhase, ShowPartyExpBarPhase, TrainerVictoryPhase } from "#app/phases"; import { MysteryEncounterBattlePhase, MysteryEncounterBattleStartCleanupPhase, MysteryEncounterPhase, MysteryEncounterRewardsPhase } from "#app/phases/mystery-encounter-phases"; import PokemonData from "#app/system/pokemon-data"; import { OptionSelectConfig, OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; @@ -29,6 +29,7 @@ import { Status, StatusEffect } from "#app/data/status-effect"; import { TrainerConfig, trainerConfigs, TrainerSlot } from "#app/data/trainer-config"; import PokemonSpecies from "#app/data/pokemon-species"; import Overrides from "#app/overrides"; +import { Egg, IEggOptions } from "#app/data/egg"; /** * Animates exclamation sprite over trainer's head at start of encounter @@ -305,7 +306,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig: * @param scene * @param moves */ -export function initCustomMovesForEncounter(scene: BattleScene, moves: Moves | Moves[]) { +export function loadCustomMovesForEncounter(scene: BattleScene, moves: Moves | Moves[]) { moves = Array.isArray(moves) ? moves : [moves]; return Promise.all(moves.map(move => initMoveAnim(scene, move))) .then(() => loadMoveAnimAssets(scene, moves)); @@ -436,10 +437,10 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p * Can have shop displayed or skipped * @param scene - Battle Scene * @param customShopRewards - adds a shop phase with the specified rewards / reward tiers - * @param nonShopPlayerItemRewards - will add a non-shop reward phase for each specified item/modifier (can happen in addition to a shop) + * @param eggRewards * @param preRewardsCallback - can execute an arbitrary callback before the new phases if necessary (useful for updating items/party/injecting new phases before MysteryEncounterRewardsPhase) */ -export function setEncounterRewards(scene: BattleScene, customShopRewards?: CustomModifierSettings, nonShopPlayerItemRewards?: ModifierTypeFunc[], preRewardsCallback?: Function) { +export function setEncounterRewards(scene: BattleScene, customShopRewards?: CustomModifierSettings, eggRewards?: IEggOptions[], preRewardsCallback?: Function) { scene.currentBattle.mysteryEncounter.doEncounterRewards = (scene: BattleScene) => { if (preRewardsCallback) { preRewardsCallback(); @@ -451,14 +452,12 @@ export function setEncounterRewards(scene: BattleScene, customShopRewards?: Cust scene.tryRemovePhase(p => p instanceof SelectModifierPhase); } - if (nonShopPlayerItemRewards?.length > 0) { - nonShopPlayerItemRewards.forEach((reward) => { - scene.unshiftPhase(new ModifierRewardPhase(scene, reward)); + if (eggRewards) { + eggRewards.forEach(eggOptions => { + const egg = new Egg(eggOptions); + egg.addEggToGameData(scene); + // queueEncounterMessage(scene, `You gained a ${egg.getEggTypeDescriptor(scene)} Egg!`); }); - } else { - while (!isNullOrUndefined(scene.findPhase(p => p instanceof ModifierRewardPhase))) { - scene.tryRemovePhase(p => p instanceof ModifierRewardPhase); - } } return true; diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index edfb72e6611..e3dd3106aeb 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -3,7 +3,7 @@ import i18next from "i18next"; import { isNullOrUndefined, randSeedInt } from "#app/utils"; import { PokemonHeldItemModifier } from "#app/modifier/modifier"; import { VictoryPhase } from "#app/phases"; -import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon"; +import Pokemon, { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon"; import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "#app/data/pokeball"; import { PlayerGender } from "#enums/player-gender"; import { addPokeballCaptureStars, addPokeballOpenParticles } from "#app/field/anims"; @@ -18,11 +18,25 @@ import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "#app/data/po import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { getPokemonNameWithAffix } from "#app/messages"; import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; +import { Gender } from "#app/data/gender"; export interface MysteryEncounterPokemonData { spriteScale?: number } +export function getSpriteKeysFromSpecies(species: Species, female?: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): { spriteKey: string, fileRoot: string } { + const spriteKey = getPokemonSpecies(species).getSpriteKey(female ?? false, formIndex ?? 0, shiny ?? false, variant ?? 0); + const fileRoot = getPokemonSpecies(species).getSpriteAtlasPath(female ?? false, formIndex ?? 0, shiny ?? false, variant ?? 0); + return { spriteKey, fileRoot }; +} + +export function getSpriteKeysFromPokemon(pokemon: Pokemon): { spriteKey: string, fileRoot: string } { + const spriteKey = pokemon.getSpeciesForm().getSpriteKey(pokemon.getGender() === Gender.FEMALE, pokemon.formIndex, pokemon.shiny, pokemon.variant); + const fileRoot = pokemon.getSpeciesForm().getSpriteAtlasPath(pokemon.getGender() === Gender.FEMALE, pokemon.formIndex, pokemon.shiny, pokemon.variant); + + return { spriteKey, fileRoot }; +} + /** * * Will never remove the player's last non-fainted Pokemon (if they only have 1) diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index 8b251d59de9..f3e6009e02e 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -1,16 +1,16 @@ -import BattleScene, {startingWave} from "../battle-scene"; -import {ModifierTypeFunc, modifierTypes} from "../modifier/modifier-type"; -import {EnemyPokemon} from "../field/pokemon"; +import BattleScene, { startingWave } from "../battle-scene"; +import { ModifierTypeFunc, modifierTypes } from "../modifier/modifier-type"; +import { EnemyPokemon } from "../field/pokemon"; import * as Utils from "../utils"; -import {PokeballType} from "./pokeball"; -import {pokemonEvolutions, pokemonPrevolutions} from "./pokemon-evolutions"; -import PokemonSpecies, {getPokemonSpecies, PokemonSpeciesFilter} from "./pokemon-species"; -import {tmSpecies} from "./tms"; -import {Type} from "./type"; -import {doubleBattleDialogue} from "./dialogue"; -import {PersistentModifier} from "../modifier/modifier"; -import {TrainerVariant} from "../field/trainer"; -import {getIsInitialized, initI18n} from "#app/plugins/i18n"; +import { PokeballType } from "./pokeball"; +import { pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions"; +import PokemonSpecies, { getPokemonSpecies, PokemonSpeciesFilter } from "./pokemon-species"; +import { tmSpecies } from "./tms"; +import { Type } from "./type"; +import { doubleBattleDialogue } from "./dialogue"; +import { PersistentModifier } from "../modifier/modifier"; +import { TrainerVariant } from "../field/trainer"; +import { getIsInitialized, initI18n } from "#app/plugins/i18n"; import i18next from "i18next"; import { Moves } from "#enums/moves"; import { PartyMemberStrength } from "#enums/party-member-strength"; @@ -527,6 +527,44 @@ export class TrainerConfig { return this; } + /** + * Initializes the trainer configuration for a Stat Trainer, as part of the Trainer's Test Mystery Encounter. + * @param {Species | Species[]} signatureSpecies - The signature species for the Elite Four member. + * @param {Type[]} specialtyTypes - The specialty types for the Stat Trainer. + * @param isMale - Whether the Elite Four Member is Male or Female (for localization of the title). + * @returns {TrainerConfig} - The updated TrainerConfig instance. + **/ + initForStatTrainer(signatureSpecies: (Species | Species[])[], isMale: boolean, ...specialtyTypes: Type[]): TrainerConfig { + if (!getIsInitialized()) { + initI18n(); + } + + this.setPartyTemplates(trainerPartyTemplates.ELITE_FOUR); + + signatureSpecies.forEach((speciesPool, s) => { + if (!Array.isArray(speciesPool)) { + speciesPool = [speciesPool]; + } + this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool)); + }); + if (specialtyTypes.length) { + this.setSpeciesFilter(p => specialtyTypes.find(t => p.isOfType(t)) !== undefined); + this.setSpecialtyTypes(...specialtyTypes); + } + const nameForCall = this.name.toLowerCase().replace(/\s/g, "_"); + this.name = i18next.t(`trainerNames:${nameForCall}`); + // this.setTitle(title); + this.setMoneyMultiplier(2); + this.setBoss(); + this.setStaticParty(); + + // TODO: replace with more suitable music? + this.setBattleBgm("battle_trainer"); + this.setVictoryBgm("victory_trainer"); + + return this; + } + /** * Initializes the trainer configuration for an evil team leader. Temporarily hardcoding evil leader teams though. * @param {Species | Species[]} signatureSpecies - The signature species for the evil team leader. @@ -1787,4 +1825,137 @@ export const trainerConfigs: TrainerConfigs = { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; })), + // TODO: use signature species? + [TrainerType.BUCK]: new TrainerConfig(++t).setName("Buck").initForStatTrainer([], true) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLAYDOL ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 3); + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.ULTRA_BALL; + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.COALOSSAL ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.GREAT_BALL; + if (p.species.speciesId === Species.VENUSAUR) { + p.formIndex = 2; // Gmax + p.abilityIndex = 2; // Venusaur gets Chlorophyll + } else { + p.formIndex = 1; // Gmax + } + p.generateName(); + })) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.AGGRON ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.formIndex = 1; // Mega + p.generateName(); + })) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.TORKOAL ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.abilityIndex = 1; // Drought + })) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.GREAT_TUSK ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.HEATRAN ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 2); + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.MASTER_BALL; + })), + [TrainerType.CHERYL]: new TrainerConfig(++t).setName("Cheryl").initForStatTrainer([], false) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BLISSEY ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 3); + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.ULTRA_BALL; + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.SNORLAX, Species.LAPRAS ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.GREAT_BALL; + p.formIndex = 1; // Gmax + p.generateName(); + })) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.AUDINO ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.formIndex = 1; // Mega + p.generateName(); + })) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.GOODRA ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.IRON_HANDS ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.CRESSELIA, Species.ENAMORUS ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 2); + p.generateAndPopulateMoveset(); + if (p.species.speciesId === Species.ENAMORUS) { + p.formIndex = 1; // Therian + p.generateName(); + } + p.pokeball = PokeballType.MASTER_BALL; + })), + [TrainerType.MARLEY]: new TrainerConfig(++t).setName("Marley").initForStatTrainer([], false) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.ARCANINE ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 3); + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.ULTRA_BALL; + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.CINDERACE, Species.INTELEON ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.GREAT_BALL; + p.formIndex = 1; // Gmax + p.generateName(); + })) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.AERODACTYL ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.formIndex = 1; // Mega + p.generateName(); + })) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.DRAGAPULT ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.IRON_BUNDLE ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.REGIELEKI ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 2); + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.MASTER_BALL; + })), + [TrainerType.MIRA]: new TrainerConfig(++t).setName("Mira").initForStatTrainer([], false) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.ALAKAZAM ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 2); + p.generateAndPopulateMoveset(); + p.formIndex = 1; + p.pokeball = PokeballType.ULTRA_BALL; + p.generateName(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.GENGAR, Species.HATTERENE ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.GREAT_BALL; + p.formIndex = p.species.speciesId === Species.GENGAR ? 2 : 1; // Gmax + p.generateName(); + })) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.FLUTTER_MANE ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.HYDREIGON ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.MAGNEZONE ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.LATIOS, Species.LATIAS ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 2); + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.MASTER_BALL; + })), + [TrainerType.RILEY]: new TrainerConfig(++t).setName("Riley").initForStatTrainer([], true) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.LUCARIO ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 2); + p.generateAndPopulateMoveset(); + p.formIndex = 1; + p.pokeball = PokeballType.ULTRA_BALL; + p.generateName(); + })) + .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.RILLABOOM, Species.CENTISKORCH ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.pokeball = PokeballType.GREAT_BALL; + p.formIndex = 1; // Gmax + p.generateName(); + })) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.TYRANITAR ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.ROARING_MOON ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.URSALUNA ], TrainerSlot.TRAINER, true)) + .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.REGIGIGAS, Species.LANDORUS ], TrainerSlot.TRAINER, true, p => { + p.setBoss(true, 2); + p.generateAndPopulateMoveset(); + if (p.species.speciesId === Species.LANDORUS) { + p.formIndex = 1; // Therian + p.generateName(); + } + p.pokeball = PokeballType.MASTER_BALL; + })), }; diff --git a/src/enums/mystery-encounter-type.ts b/src/enums/mystery-encounter-type.ts index 95283e63b36..e054b03c33b 100644 --- a/src/enums/mystery-encounter-type.ts +++ b/src/enums/mystery-encounter-type.ts @@ -12,8 +12,9 @@ export enum MysteryEncounterType { LOST_AT_SEA, //might be generalized later on FIERY_FALLOUT, THE_STRONG_STUFF, - POKEMON_SALESMAN, - OFFER_YOU_CANT_REFUSE, + THE_POKEMON_SALESMAN, + AN_OFFER_YOU_CANT_REFUSE, DELIBIRDY, - ABSOLUTE_AVARICE + ABSOLUTE_AVARICE, + A_TRAINERS_TEST } diff --git a/src/enums/trainer-type.ts b/src/enums/trainer-type.ts index 6bd8f567acb..0d3a0771604 100644 --- a/src/enums/trainer-type.ts +++ b/src/enums/trainer-type.ts @@ -70,6 +70,11 @@ export enum TrainerType { GHETSIS_2, LYSANDRE, LYSANDRE_2, + BUCK, + CHERYL, + MARLEY, + MIRA, + RILEY, BROCK = 200, MISTY, diff --git a/src/field/mystery-encounter-intro.ts b/src/field/mystery-encounter-intro.ts index 467d44c23cd..7055d29d45c 100644 --- a/src/field/mystery-encounter-intro.ts +++ b/src/field/mystery-encounter-intro.ts @@ -1,10 +1,11 @@ import { GameObjects } from "phaser"; import BattleScene from "../battle-scene"; import IMysteryEncounter from "../data/mystery-encounters/mystery-encounter"; +import { Species } from "#enums/species"; +import { isNullOrUndefined } from "#app/utils"; +import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; type KnownFileRoot = - | "trainer" - | "pokemon" | "arenas" | "battle_anims" | "cg" @@ -33,6 +34,8 @@ export class MysteryEncounterSpriteConfig { spriteKey: string; /** Refer to [/public/images](../../public/images) directorty for all folder names */ fileRoot: KnownFileRoot & string | string; + /** Optional replacement for `spriteKey`/`fileRoot`. Just know this defaults to male/genderless, form 0, no shiny */ + species?: Species; /** Enable shadow. Defaults to `false` */ hasShadow?: boolean = false; /** Disable animation. Defaults to `false` */ @@ -69,15 +72,26 @@ export class MysteryEncounterSpriteConfig { export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container { public encounter: IMysteryEncounter; public spriteConfigs: MysteryEncounterSpriteConfig[]; + public enterFromRight: boolean; constructor(scene: BattleScene, encounter: IMysteryEncounter) { super(scene, -72, 76); this.encounter = encounter; + this.enterFromRight = encounter.enterIntroVisualsFromRight ?? false; // Shallow copy configs to allow visual config updates at runtime without dirtying master copy of Encounter this.spriteConfigs = encounter.spriteConfigs.map(config => { - return { + const result = { ...config }; + + if (!isNullOrUndefined(result.species)) { + const keys = getSpriteKeysFromSpecies(result.species); + result.spriteKey = keys.spriteKey; + result.fileRoot = keys.fileRoot; + result.isPokemon = true; + } + + return result; }); if (!this.spriteConfigs) { return; @@ -90,9 +104,10 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con return ret; }; - const getItemSprite = (spriteKey: string) => { + const getItemSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => { const icon = this.scene.add.sprite(-19, 2, "items", spriteKey); icon.setOrigin(0.5, 1); + icon.setPipeline(this.scene.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 }); return icon; }; @@ -114,7 +129,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con sprite = getSprite(spriteKey, hasShadow, yShadow); tintSprite = getSprite(spriteKey); } else { - sprite = getItemSprite(spriteKey); + sprite = getItemSprite(spriteKey, hasShadow, yShadow); tintSprite = getItemSprite(spriteKey); } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 49561db4b54..f396367e491 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1728,7 +1728,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { hideInfo(): Promise { return new Promise(resolve => { - if (this.battleInfo.visible) { + if (this.battleInfo && this.battleInfo.visible) { this.scene.tweens.add({ targets: [ this.battleInfo, this.battleInfo.expMaskRect ], x: this.isPlayer() ? "+=150" : `-=${!this.isBoss() ? 150 : 246}`, diff --git a/src/locales/en/dialogue.ts b/src/locales/en/dialogue.ts index dda8891b788..50dee033782 100644 --- a/src/locales/en/dialogue.ts +++ b/src/locales/en/dialogue.ts @@ -566,6 +566,67 @@ export const PGMdialogue: DialogueTranslationEntries = { 1: "Fools with no vision will continue to befoul this beautiful world." } }, + "stat_trainer_buck": { + "encounter": { + 1: "...I'm telling you right now. I'm seriously tough. Act surprised!", + 2: "I can feel my Pokémon shivering inside their Pokéballs!" + }, + "victory": { + 1: "Heeheehee!\nSo hot, you!" + }, + "defeat": { + 1: "Whoa! You're all out of gas, I guess." + } + }, + "stat_trainer_cheryl": { + "encounter": { + 1: "My Pokémon have been itching for a battle.", + 2: "I should warn you, my Pokémon can be quite rambunctious." + }, + "victory": { + 1: "Striking the right balance of offense and defense... It's not easy to do." + }, + "defeat": { + 1: "Do your Pokémon need any healing?" + } + }, + "stat_trainer_marley": { + "encounter": { + 1: "... OK.\nI'll do my best.", + 2: "... OK.\nI... won't lose...!" + }, + "victory": { + 1: "... Awww." + }, + "defeat": { + 1: "... Goodbye." + } + }, + "stat_trainer_mira": { + "encounter": { + 1: "You will be shocked by Mira!", + 2: "Mira will show you that Mira doesn't get lost anymore!" + }, + "victory": { + 1: "Mira wonders if she can get very far in this land." + }, + "defeat": { + 1: "Mira knew she would win!" + } + }, + "stat_trainer_riley": { + "encounter": { + 1: "Battling is our way of greeting!", + 2: "We're pulling out all the stops to put your Pokémon down.", + }, + "victory": { + 1: `At times we battle, and sometimes we team up... + $It's great how Trainers can interact.` + }, + "defeat": { + 1: "You put up quite the display.\nBetter luck next time." + } + }, "brock": { "encounter": { 1: "My expertise on Rock-type Pokémon will take you down! Come on!", diff --git a/src/locales/en/egg.ts b/src/locales/en/egg.ts index 9f699ce0fdc..cfa6375fe2e 100644 --- a/src/locales/en/egg.ts +++ b/src/locales/en/egg.ts @@ -13,6 +13,7 @@ export const egg: SimpleTranslationEntries = { "gachaTypeLegendary": "Legendary Rate Up", "gachaTypeMove": "Rare Egg Move Rate Up", "gachaTypeShiny": "Shiny Rate Up", + "eventType": "Mystery Event", "selectMachine": "Select a machine.", "notEnoughVouchers": "You don't have enough vouchers!", "tooManyEggs": "You have too many eggs!", diff --git a/src/locales/en/mystery-encounter.ts b/src/locales/en/mystery-encounter.ts index 7cb6cb98178..6d03e5b3eb6 100644 --- a/src/locales/en/mystery-encounter.ts +++ b/src/locales/en/mystery-encounter.ts @@ -11,10 +11,11 @@ import { shadyVitaminDealerDialogue } from "#app/locales/en/mystery-encounters/s import { slumberingSnorlaxDialogue } from "#app/locales/en/mystery-encounters/slumbering-snorlax-dialogue"; import { trainingSessionDialogue } from "#app/locales/en/mystery-encounters/training-session-dialogue"; import { theStrongStuffDialogue } from "#app/locales/en/mystery-encounters/the-strong-stuff-dialogue"; -import { pokemonSalesmanDialogue } from "#app/locales/en/mystery-encounters/pokemon-salesman-dialogue"; -import { offerYouCantRefuseDialogue } from "#app/locales/en/mystery-encounters/offer-you-cant-refuse-dialogue"; +import { thePokemonSalesmanDialogue } from "#app/locales/en/mystery-encounters/the-pokemon-salesman-dialogue"; +import { anOfferYouCantRefuseDialogue } from "#app/locales/en/mystery-encounters/an-offer-you-cant-refuse-dialogue"; import { delibirdyDialogue } from "#app/locales/en/mystery-encounters/delibirdy-dialogue"; import { absoluteAvariceDialogue } from "#app/locales/en/mystery-encounters/absolute-avarice-dialogue"; +import { aTrainersTestDialogue } from "#app/locales/en/mystery-encounters/a-trainers-test-dialogue"; /** * Patterns that can be used: @@ -51,8 +52,9 @@ export const mysteryEncounter = { lostAtSea: lostAtSeaDialogue, fieryFallout: fieryFalloutDialogue, theStrongStuff: theStrongStuffDialogue, - pokemonSalesman: pokemonSalesmanDialogue, - offerYouCantRefuse: offerYouCantRefuseDialogue, + pokemonSalesman: thePokemonSalesmanDialogue, + offerYouCantRefuse: anOfferYouCantRefuseDialogue, delibirdy: delibirdyDialogue, absoluteAvarice: absoluteAvariceDialogue, + aTrainersTest: aTrainersTestDialogue, } as const; diff --git a/src/locales/en/mystery-encounters/a-trainers-test-dialogue.ts b/src/locales/en/mystery-encounters/a-trainers-test-dialogue.ts new file mode 100644 index 00000000000..13fe8209c19 --- /dev/null +++ b/src/locales/en/mystery-encounters/a-trainers-test-dialogue.ts @@ -0,0 +1,67 @@ +export const aTrainersTestDialogue = { + intro: "An extremely strong trainer approaches you...", + buck: { + intro_dialogue: `Yo, trainer! My name's Buck. + $I have a super awesome proposal\nfor a strong trainer such as yourself! + $I'm carrying two rare Pokémon Eggs with me,\nbut I'd like someone else to care for one. + $If you can prove your strength as a trainer to me,\nI'll give you the rarer egg!`, + accept: "Whoooo, I'm getting fired up!", + decline: `Darn, it looks like your\nteam isn't in peak condition. + $Here, let me help with that.` + }, + cheryl: { + intro_dialogue: `Hello, my name's Cheryl. + $I have a particularly interesting request,\nfor a strong trainer such as yourself. + $I'm carrying two rare Pokémon Eggs with me,\nbut I'd like someone else to care for one. + $If you can prove your strength as a trainer to me,\nI'll give you the rarer Egg!`, + accept: "I hope you're ready!", + decline: `I understand, it looks like your team\nisn't in the best condition at the moment. + $Here, let me help with that.` + }, + marley: { + intro_dialogue: `...@d{64} I'm Marley. + $I have an offer for you... + $I'm carrying two Pokémon Eggs with me,\nbut I'd like someone else to care for one. + $If you're stronger than me,\nI'll give you the rarer Egg.`, + accept: "... I see.", + decline: `... I see. + $Your Pokémon look hurt...\nLet me help.` + }, + mira: { + intro_dialogue: `Hi! I'm Mira! + $Mira has a request\nfor a strong trainer like you! + $Mira has two rare Pokémon Eggs,\nbut Mira wants someone else to take one! + $If you show Mira that you're strong,\nMira will give you the rarer Egg!`, + accept: "You'll battle Mira?\nYay!", + decline: `Aww, no battle?\nThat's okay! + $Here, Mira will heal your team!` + }, + riley: { + intro_dialogue: `I'm Riley. + $I have an odd proposal\nfor a strong trainer such as yourself. + $I'm carrying two rare Pokémon Eggs with me,\nbut I'd like to give one to another trainer. + $If you can prove your strength to me,\nI'll give you the rarer Egg!`, + accept: "That look you have...\nLet's do this.", + decline: `I understand, your team looks beat up. + $Here, let me help with that.` + }, + title: "A Trainer's Test", + description: "It seems this trainer is willing to give you an Egg regardless of your decision. However, if you can manage to defeat this strong trainer, you'll receive a much rarer Egg.", + query: "What will you do?", + option: { + 1: { + label: "Accept the Challenge", + tooltip: "(-) Tough Battle\n(+) Gain a @[TOOLTIP_TITLE]{Very Rare Egg}" + }, + 2: { + label: "Refuse the Challenge", + tooltip: "(+) Full Heal Party\n(+) Gain an @[TOOLTIP_TITLE]{Egg}", + }, + }, + eggTypes: { + rare: "a Rare Egg", + epic: "an Epic Egg", + legendary: "a Legendary Egg" + }, + outro: "{{statTrainerName}} gave you {{eggType}}!" +}; diff --git a/src/locales/en/mystery-encounters/offer-you-cant-refuse-dialogue.ts b/src/locales/en/mystery-encounters/an-offer-you-cant-refuse-dialogue.ts similarity index 96% rename from src/locales/en/mystery-encounters/offer-you-cant-refuse-dialogue.ts rename to src/locales/en/mystery-encounters/an-offer-you-cant-refuse-dialogue.ts index 7cee39b3ae8..00ca2f5f309 100644 --- a/src/locales/en/mystery-encounters/offer-you-cant-refuse-dialogue.ts +++ b/src/locales/en/mystery-encounters/an-offer-you-cant-refuse-dialogue.ts @@ -1,4 +1,4 @@ -export const offerYouCantRefuseDialogue = { +export const anOfferYouCantRefuseDialogue = { intro: "You're stopped by a rich looking boy.", speaker: "Rich Boy", intro_dialogue: `Good day to you. diff --git a/src/locales/en/mystery-encounters/pokemon-salesman-dialogue.ts b/src/locales/en/mystery-encounters/the-pokemon-salesman-dialogue.ts similarity index 96% rename from src/locales/en/mystery-encounters/pokemon-salesman-dialogue.ts rename to src/locales/en/mystery-encounters/the-pokemon-salesman-dialogue.ts index d35e3947a42..00b1f4beb6a 100644 --- a/src/locales/en/mystery-encounters/pokemon-salesman-dialogue.ts +++ b/src/locales/en/mystery-encounters/the-pokemon-salesman-dialogue.ts @@ -1,4 +1,4 @@ -export const pokemonSalesmanDialogue = { +export const thePokemonSalesmanDialogue = { intro: "A chipper elderly man approaches you.", speaker: "Gentleman", intro_dialogue: "Hello there! Have I got a deal just for YOU!", diff --git a/src/locales/en/trainers.ts b/src/locales/en/trainers.ts index b59cfdc4fda..0581a6698de 100644 --- a/src/locales/en/trainers.ts +++ b/src/locales/en/trainers.ts @@ -270,6 +270,11 @@ export const trainerNames: SimpleTranslationEntries = { "cyrus": "Cyrus", "ghetsis": "Ghetsis", "lysandre": "Lysandre", + "buck": "Buck", + "cheryl": "Cheryl", + "marley": "Marley", + "mira": "Mira", + "riley": "Riley", // Double Names "blue_red_double": "Blue & Red", diff --git a/src/phases.ts b/src/phases.ts index 7f2933a738a..b0bfc739ae8 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -1002,8 +1002,8 @@ export class EncounterPhase extends BattlePhase { const enemyField = this.scene.getEnemyField(); this.scene.tweens.add({ - targets: [this.scene.arenaEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.currentBattle?.mysteryEncounter?.introVisuals, this.scene.arenaPlayer, this.scene.trainer].flat(), - x: (_target, _key, value, fieldIndex: integer) => fieldIndex < 3 + (enemyField.length) ? value + 300 : value - 300, + targets: [this.scene.arenaEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.arenaPlayer, this.scene.trainer].flat(), + x: (_target, _key, value, fieldIndex: integer) => fieldIndex < 2 + (enemyField.length) ? value + 300 : value - 300, duration: 2000, onComplete: () => { if (!this.tryOverrideForBattleSpec()) { @@ -1011,6 +1011,19 @@ export class EncounterPhase extends BattlePhase { } } }); + + const encounterIntroVisuals = this.scene.currentBattle?.mysteryEncounter?.introVisuals; + if (encounterIntroVisuals) { + const enterFromRight = encounterIntroVisuals.enterFromRight; + if (enterFromRight) { + encounterIntroVisuals.x += 500; + } + this.scene.tweens.add({ + targets: encounterIntroVisuals, + x: enterFromRight ? "-=200" : "+=300", + duration: 2000 + }); + } } getEncounterMessage(): string { @@ -1106,8 +1119,6 @@ export class EncounterPhase extends BattlePhase { } const doEncounter = () => { - this.scene.playBgm(undefined); - const doShowEncounterOptions = () => { this.scene.ui.clearText(); this.scene.ui.getMessageHandler().hideNameText(); @@ -1264,7 +1275,17 @@ export class NextEncounterPhase extends EncounterPhase { } const nextEncounterVisuals = this.scene.currentBattle?.mysteryEncounter?.introVisuals; if (nextEncounterVisuals) { - moveTargets.push(nextEncounterVisuals); + const enterFromRight = nextEncounterVisuals.enterFromRight; + if (enterFromRight) { + nextEncounterVisuals.x += 500; + this.scene.tweens.add({ + targets: nextEncounterVisuals, + x: "-=200", + duration: 2000 + }); + } else { + moveTargets.push(nextEncounterVisuals); + } } this.scene.tweens.add({ targets: moveTargets.flat(), diff --git a/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts b/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts new file mode 100644 index 00000000000..083d6c6985f --- /dev/null +++ b/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts @@ -0,0 +1,203 @@ +import * as MysteryEncounters from "#app/data/mystery-encounters/mystery-encounters"; +import { HUMAN_TRANSITABLE_BIOMES } from "#app/data/mystery-encounters/mystery-encounters"; +import { Biome } from "#app/enums/biome"; +import { MysteryEncounterType } from "#app/enums/mystery-encounter-type"; +import { Species } from "#app/enums/species"; +import GameManager from "#app/test/utils/gameManager"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } from "#test/mystery-encounter/encounterTestUtils"; +import BattleScene from "#app/battle-scene"; +import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; +import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; +import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; +import { ATrainersTestEncounter } from "#app/data/mystery-encounters/encounters/a-trainers-test-encounter"; +import { CommandPhase, PartyHealPhase, SelectModifierPhase } from "#app/phases"; +import { EggTier } from "#enums/egg-type"; + +const namespace = "mysteryEncounter:aTrainersTest"; +const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; +const defaultBiome = Biome.CAVE; +const defaultWave = 45; + +describe("A Trainer's Test - Mystery Encounter", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + let scene: BattleScene; + + beforeAll(() => { + phaserGame = new Phaser.Game({ type: Phaser.HEADLESS }); + }); + + beforeEach(async () => { + game = new GameManager(phaserGame); + scene = game.scene; + game.override.mysteryEncounterChance(100); + game.override.mysteryEncounterTier(MysteryEncounterTier.COMMON); + game.override.startingWave(defaultWave); + game.override.startingBiome(defaultBiome); + + const biomeMap = new Map([ + [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], + ]); + HUMAN_TRANSITABLE_BIOMES.forEach(biome => { + biomeMap.set(biome, [MysteryEncounterType.A_TRAINERS_TEST]); + }); + vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + vi.clearAllMocks(); + vi.resetAllMocks(); + }); + + it("should have the correct properties", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.A_TRAINERS_TEST, defaultParty); + + expect(ATrainersTestEncounter.encounterType).toBe(MysteryEncounterType.A_TRAINERS_TEST); + expect(ATrainersTestEncounter.encounterTier).toBe(MysteryEncounterTier.ROGUE); + expect(ATrainersTestEncounter.dialogue).toBeDefined(); + expect(ATrainersTestEncounter.dialogue.intro).toBeDefined(); + expect(ATrainersTestEncounter.dialogue.intro[0].speaker).toBeDefined(); + expect(ATrainersTestEncounter.dialogue.intro[0].text).toBeDefined(); + expect(ATrainersTestEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(ATrainersTestEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(ATrainersTestEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); + expect(ATrainersTestEncounter.options.length).toBe(2); + }); + + it("should not run below wave 10", async () => { + game.override.startingWave(9); + + await game.runToMysteryEncounter(); + + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.A_TRAINERS_TEST); + }); + + it("should not run above wave 179", async () => { + game.override.startingWave(181); + + await game.runToMysteryEncounter(); + + expect(scene.currentBattle.mysteryEncounter).toBeUndefined(); + }); + + it("should initialize fully ", async () => { + initSceneWithoutEncounterPhase(scene, defaultParty); + scene.currentBattle.mysteryEncounter = ATrainersTestEncounter; + + const { onInit } = ATrainersTestEncounter; + + expect(ATrainersTestEncounter.onInit).toBeDefined(); + + ATrainersTestEncounter.populateDialogueTokensFromRequirements(scene); + const onInitResult = onInit(scene); + + expect(ATrainersTestEncounter.dialogueTokens?.statTrainerName).toBeDefined(); + expect(ATrainersTestEncounter.misc.trainerType).toBeDefined(); + expect(ATrainersTestEncounter.misc.trainerNameKey).toBeDefined(); + expect(ATrainersTestEncounter.misc.trainerEggDescription).toBeDefined(); + expect(ATrainersTestEncounter.dialogue.intro).toBeDefined(); + expect(ATrainersTestEncounter.options[1].dialogue.selected).toBeDefined(); + expect(onInitResult).toBe(true); + }); + + describe("Option 1 - Accept the Challenge", () => { + it("should have the correct properties", () => { + const option = ATrainersTestEncounter.options[0]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue.buttonLabel).toStrictEqual(`${namespace}.option.1.label`); + expect(option.dialogue.buttonTooltip).toStrictEqual(`${namespace}.option.1.tooltip`); + }); + + it("Should start battle against the trainer", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.A_TRAINERS_TEST, defaultParty); + await runMysteryEncounterToEnd(game, 1, null, true); + + const enemyField = scene.getEnemyField(); + expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name); + expect(enemyField.length).toBe(1); + expect(scene.currentBattle.trainer).toBeDefined(); + expect(["buck", "cheryl", "marley", "mira", "riley"].includes(scene.currentBattle.trainer.config.name.toLowerCase())).toBeTruthy(); + expect(enemyField[0]).toBeDefined(); + }); + + it("Should reward the player with an Epic or Legendary egg", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.A_TRAINERS_TEST, defaultParty); + + const eggsBefore = scene.gameData.eggs; + expect(eggsBefore).toBeDefined(); + const eggsBeforeLength = eggsBefore.length; + + await runMysteryEncounterToEnd(game, 1, null, true); + await skipBattleRunMysteryEncounterRewardsPhase(game); + await game.phaseInterceptor.to(SelectModifierPhase, false); + expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name); + + const eggsAfter = scene.gameData.eggs; + expect(eggsAfter).toBeDefined(); + expect(eggsBeforeLength + 1).toBe(eggsAfter.length); + const eggTier = eggsAfter[eggsAfter.length - 1].tier; + expect(eggTier === EggTier.ULTRA || eggTier === EggTier.MASTER).toBeTruthy(); + }); + }); + + describe("Option 2 - Decline the Challenge", () => { + beforeEach(() => { + // Mock sound object + vi.spyOn(scene, "playSoundWithoutBgm").mockImplementation(() => { + return { + totalDuration: 1, + destroy: () => null + } as Phaser.Sound.NoAudioSound; + }); + }); + + it("should have the correct properties", () => { + const option = ATrainersTestEncounter.options[1]; + expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); + expect(option.dialogue).toBeDefined(); + expect(option.dialogue.buttonLabel).toStrictEqual(`${namespace}.option.2.label`); + expect(option.dialogue.buttonTooltip).toStrictEqual(`${namespace}.option.2.tooltip`); + }); + + it("Should fully heal the party", async () => { + const phaseSpy = vi.spyOn(scene, "unshiftPhase"); + + await game.runToMysteryEncounter(MysteryEncounterType.A_TRAINERS_TEST, defaultParty); + await runMysteryEncounterToEnd(game, 2); + + const partyHealPhases = phaseSpy.mock.calls.filter(p => p[0] instanceof PartyHealPhase).map(p => p[0]); + expect(partyHealPhases.length).toBe(1); + }); + + it("Should reward the player with a Rare egg", async () => { + await game.runToMysteryEncounter(MysteryEncounterType.A_TRAINERS_TEST, defaultParty); + + const eggsBefore = scene.gameData.eggs; + expect(eggsBefore).toBeDefined(); + const eggsBeforeLength = eggsBefore.length; + + await runMysteryEncounterToEnd(game, 2); + await game.phaseInterceptor.to(SelectModifierPhase, false); + expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name); + + const eggsAfter = scene.gameData.eggs; + expect(eggsAfter).toBeDefined(); + expect(eggsBeforeLength + 1).toBe(eggsAfter.length); + const eggTier = eggsAfter[eggsAfter.length - 1].tier; + expect(eggTier).toBe(EggTier.GREAT); + }); + + it("should leave encounter without battle", async () => { + const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); + + await game.runToMysteryEncounter(MysteryEncounterType.A_TRAINERS_TEST, defaultParty); + await runMysteryEncounterToEnd(game, 2); + + expect(leaveEncounterWithoutBattleSpy).toBeCalled(); + }); + }); +}); diff --git a/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts b/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts index 4aaf5f3d518..7b0c7a2dd7e 100644 --- a/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts @@ -57,10 +57,10 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(AbsoluteAvariceEncounter.encounterType).toBe(MysteryEncounterType.ABSOLUTE_AVARICE); expect(AbsoluteAvariceEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT); expect(AbsoluteAvariceEncounter.dialogue).toBeDefined(); - expect(AbsoluteAvariceEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}:intro` }]); - expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`); - expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}:description`); - expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}:query`); + expect(AbsoluteAvariceEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]); + expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); expect(AbsoluteAvariceEncounter.options.length).toBe(3); }); @@ -118,11 +118,11 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option1.dialogue).toBeDefined(); expect(option1.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }); @@ -171,11 +171,11 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }); @@ -229,11 +229,11 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, selected: [ { - text: `${namespace}:option:3:selected`, + text: `${namespace}.option.3.selected`, }, ], }); diff --git a/src/test/mystery-encounter/encounters/offer-you-cant-refuse-encounter.test.ts b/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts similarity index 67% rename from src/test/mystery-encounter/encounters/offer-you-cant-refuse-encounter.test.ts rename to src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts index 0290d32f242..fe7e5b676a3 100644 --- a/src/test/mystery-encounter/encounters/offer-you-cant-refuse-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts @@ -9,7 +9,7 @@ import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encount import { runMysteryEncounterToEnd } from "#test/mystery-encounter/encounterTestUtils"; import BattleScene from "#app/battle-scene"; import { PlayerPokemon, PokemonMove } from "#app/field/pokemon"; -import { OfferYouCantRefuseEncounter } from "#app/data/mystery-encounters/encounters/offer-you-cant-refuse-encounter"; +import { AnOfferYouCantRefuseEncounter } from "#app/data/mystery-encounters/encounters/an-offer-you-cant-refuse-encounter"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; @@ -44,7 +44,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], ]); HUMAN_TRANSITABLE_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.OFFER_YOU_CANT_REFUSE]); + biomeMap.set(biome, [MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -56,26 +56,26 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { }); it("should have the correct properties", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); - expect(OfferYouCantRefuseEncounter.encounterType).toBe(MysteryEncounterType.OFFER_YOU_CANT_REFUSE); - expect(OfferYouCantRefuseEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT); - expect(OfferYouCantRefuseEncounter.dialogue).toBeDefined(); - expect(OfferYouCantRefuseEncounter.dialogue.intro).toStrictEqual([ - { text: `${namespace}:intro` }, - { speaker: `${namespace}:speaker`, text: `${namespace}:intro_dialogue` } + expect(AnOfferYouCantRefuseEncounter.encounterType).toBe(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE); + expect(AnOfferYouCantRefuseEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT); + expect(AnOfferYouCantRefuseEncounter.dialogue).toBeDefined(); + expect(AnOfferYouCantRefuseEncounter.dialogue.intro).toStrictEqual([ + { text: `${namespace}.intro` }, + { speaker: `${namespace}.speaker`, text: `${namespace}.intro_dialogue` } ]); - expect(OfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`); - expect(OfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}:description`); - expect(OfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}:query`); - expect(OfferYouCantRefuseEncounter.options.length).toBe(3); + expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); + expect(AnOfferYouCantRefuseEncounter.options.length).toBe(3); }); it("should not spawn outside of HUMAN_TRANSITABLE_BIOMES", async () => { game.override.startingBiome(Biome.VOLCANO); await game.runToMysteryEncounter(); - expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.OFFER_YOU_CANT_REFUSE); + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE); }); it("should not run below wave 10", async () => { @@ -83,7 +83,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { await game.runToMysteryEncounter(); - expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.OFFER_YOU_CANT_REFUSE); + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE); }); it("should not run above wave 179", async () => { @@ -96,36 +96,36 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { it("should initialize fully ", async () => { initSceneWithoutEncounterPhase(scene, defaultParty); - scene.currentBattle.mysteryEncounter = OfferYouCantRefuseEncounter; + scene.currentBattle.mysteryEncounter = AnOfferYouCantRefuseEncounter; - const { onInit } = OfferYouCantRefuseEncounter; + const { onInit } = AnOfferYouCantRefuseEncounter; - expect(OfferYouCantRefuseEncounter.onInit).toBeDefined(); + expect(AnOfferYouCantRefuseEncounter.onInit).toBeDefined(); - OfferYouCantRefuseEncounter.populateDialogueTokensFromRequirements(scene); + AnOfferYouCantRefuseEncounter.populateDialogueTokensFromRequirements(scene); const onInitResult = onInit(scene); - expect(OfferYouCantRefuseEncounter.dialogueTokens?.strongestPokemon).toBeDefined(); - expect(OfferYouCantRefuseEncounter.dialogueTokens?.price).toBeDefined(); - expect(OfferYouCantRefuseEncounter.dialogueTokens?.option2PrimaryAbility).toBe("Intimidate"); - expect(OfferYouCantRefuseEncounter.dialogueTokens?.moveOrAbility).toBe("Intimidate"); - expect(OfferYouCantRefuseEncounter.misc.pokemon instanceof PlayerPokemon).toBeTruthy(); - expect(OfferYouCantRefuseEncounter.misc?.price?.toString()).toBe(OfferYouCantRefuseEncounter.dialogueTokens?.price); + expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.strongestPokemon).toBeDefined(); + expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.price).toBeDefined(); + expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.option2PrimaryAbility).toBe("Intimidate"); + expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.moveOrAbility).toBe("Intimidate"); + expect(AnOfferYouCantRefuseEncounter.misc.pokemon instanceof PlayerPokemon).toBeTruthy(); + expect(AnOfferYouCantRefuseEncounter.misc?.price?.toString()).toBe(AnOfferYouCantRefuseEncounter.dialogueTokens?.price); expect(onInitResult).toBe(true); }); describe("Option 1 - Sell your Pokemon for money and a Shiny Charm", () => { it("should have the correct properties", () => { - const option = OfferYouCantRefuseEncounter.options[0]; + const option = AnOfferYouCantRefuseEncounter.options[0]; expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - speaker: `${namespace}:speaker`, - text: `${namespace}:option:1:selected`, + speaker: `${namespace}.speaker`, + text: `${namespace}.option.1.selected`, }, ], }); @@ -136,7 +136,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { scene.money = initialMoney; const updateMoneySpy = vi.spyOn(EncounterPhaseUtils, "updatePlayerMoney"); - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); await runMysteryEncounterToEnd(game, 1); const price = scene.currentBattle.mysteryEncounter.misc.price; @@ -146,7 +146,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { }); it("Should give the player a Shiny Charm", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); await runMysteryEncounterToEnd(game, 1); const itemModifier = scene.findModifier(m => m instanceof ShinyRateBoosterModifier) as ShinyRateBoosterModifier; @@ -156,7 +156,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { }); it("Should remove the Pokemon from the party", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); const initialPartySize = scene.getParty().length; const pokemonName = scene.currentBattle.mysteryEncounter.misc.pokemon.name; @@ -170,7 +170,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { it("should leave encounter without battle", async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); await runMysteryEncounterToEnd(game, 1); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); @@ -179,24 +179,24 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { describe("Option 2 - Extort the Kid", () => { it("should have the correct properties", () => { - const option = OfferYouCantRefuseEncounter.options[1]; + const option = AnOfferYouCantRefuseEncounter.options[1]; expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, - disabledButtonTooltip: `${namespace}:option:2:tooltip_disabled`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + disabledButtonTooltip: `${namespace}.option.2.tooltip_disabled`, selected: [ { - speaker: `${namespace}:speaker`, - text: `${namespace}:option:2:selected`, + speaker: `${namespace}.speaker`, + text: `${namespace}.option.2.selected`, }, ], }); }); it("should award EXP to a pokemon with an ability in EXTORTION_ABILITIES", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); const party = scene.getParty(); const gyarados = party.find((pkm) => pkm.species.speciesId === Species.GYARADOS); const expBefore = gyarados.exp; @@ -207,7 +207,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { }); it("should award EXP to a pokemon with a move in EXTORTION_MOVES", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, [Species.ABRA]); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, [Species.ABRA]); const party = scene.getParty(); const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA); abra.moveset = [new PokemonMove(Moves.BEAT_UP)]; @@ -223,7 +223,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { scene.money = initialMoney; const updateMoneySpy = vi.spyOn(EncounterPhaseUtils, "updatePlayerMoney"); - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); await runMysteryEncounterToEnd(game, 2); const price = scene.currentBattle.mysteryEncounter.misc.price; @@ -235,7 +235,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { it("should leave encounter without battle", async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); await runMysteryEncounterToEnd(game, 2); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); @@ -246,7 +246,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { it("should leave encounter without battle", async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); - await game.runToMysteryEncounter(MysteryEncounterType.OFFER_YOU_CANT_REFUSE, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); await runMysteryEncounterToEnd(game, 3); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); diff --git a/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts b/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts index 9cee29b130d..0da778d793c 100644 --- a/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/delibirdy-encounter.test.ts @@ -58,11 +58,11 @@ describe("Delibird-y - Mystery Encounter", () => { expect(DelibirdyEncounter.encounterType).toBe(MysteryEncounterType.DELIBIRDY); expect(DelibirdyEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT); expect(DelibirdyEncounter.dialogue).toBeDefined(); - expect(DelibirdyEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}:intro` }]); - expect(DelibirdyEncounter.dialogue.outro).toStrictEqual([{ text: `${namespace}:outro` }]); - expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`); - expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}:description`); - expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}:query`); + expect(DelibirdyEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]); + expect(DelibirdyEncounter.dialogue.outro).toStrictEqual([{ text: `${namespace}.outro` }]); + expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); expect(DelibirdyEncounter.options.length).toBe(3); }); @@ -96,11 +96,11 @@ describe("Delibird-y - Mystery Encounter", () => { expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); expect(option1.dialogue).toBeDefined(); expect(option1.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }); @@ -190,12 +190,12 @@ describe("Delibird-y - Mystery Encounter", () => { expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, - secondOptionPrompt: `${namespace}:option:2:select_prompt`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + secondOptionPrompt: `${namespace}.option.2.select_prompt`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }); @@ -352,12 +352,12 @@ describe("Delibird-y - Mystery Encounter", () => { expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, - secondOptionPrompt: `${namespace}:option:3:select_prompt`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, + secondOptionPrompt: `${namespace}.option.3.select_prompt`, selected: [ { - text: `${namespace}:option:3:selected`, + text: `${namespace}.option.3.selected`, }, ], }); diff --git a/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts b/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts index 095d8a109d7..2eb1b6176bc 100644 --- a/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/department-store-sale-encounter.test.ts @@ -60,15 +60,15 @@ describe("Department Store Sale - Mystery Encounter", () => { expect(DepartmentStoreSaleEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON); expect(DepartmentStoreSaleEncounter.dialogue).toBeDefined(); expect(DepartmentStoreSaleEncounter.dialogue.intro).toStrictEqual([ - { text: `${namespace}:intro` }, + { text: `${namespace}.intro` }, { - speaker: `${namespace}:speaker`, - text: `${namespace}:intro_dialogue`, + speaker: `${namespace}.speaker`, + text: `${namespace}.intro_dialogue`, } ]); - expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`); - expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}:description`); - expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}:query`); + expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); expect(DepartmentStoreSaleEncounter.options.length).toBe(4); }); @@ -101,8 +101,8 @@ describe("Department Store Sale - Mystery Encounter", () => { expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, }); }); @@ -136,8 +136,8 @@ describe("Department Store Sale - Mystery Encounter", () => { expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, }); }); @@ -172,8 +172,8 @@ describe("Department Store Sale - Mystery Encounter", () => { expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, }); }); @@ -208,8 +208,8 @@ describe("Department Store Sale - Mystery Encounter", () => { expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:4:label`, - buttonTooltip: `${namespace}:option:4:tooltip`, + buttonLabel: `${namespace}.option.4.label`, + buttonTooltip: `${namespace}.option.4.tooltip`, }); }); diff --git a/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts b/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts index 43f23b261e6..00ae3a37139 100644 --- a/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/fiery-fallout-encounter.test.ts @@ -64,10 +64,10 @@ describe("Fiery Fallout - Mystery Encounter", () => { expect(FieryFalloutEncounter.encounterType).toBe(MysteryEncounterType.FIERY_FALLOUT); expect(FieryFalloutEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON); expect(FieryFalloutEncounter.dialogue).toBeDefined(); - expect(FieryFalloutEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}:intro` }]); - expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`); - expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}:description`); - expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}:query`); + expect(FieryFalloutEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]); + expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); expect(FieryFalloutEncounter.options.length).toBe(3); }); @@ -138,11 +138,11 @@ describe("Fiery Fallout - Mystery Encounter", () => { expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option1.dialogue).toBeDefined(); expect(option1.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }); @@ -188,11 +188,11 @@ describe("Fiery Fallout - Mystery Encounter", () => { expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option1.dialogue).toBeDefined(); expect(option1.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }); @@ -235,12 +235,12 @@ describe("Fiery Fallout - Mystery Encounter", () => { expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL); expect(option1.dialogue).toBeDefined(); expect(option1.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, - disabledButtonTooltip: `${namespace}:option:3:disabled_tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, + disabledButtonTooltip: `${namespace}.option.3.disabled_tooltip`, selected: [ { - text: `${namespace}:option:3:selected`, + text: `${namespace}.option.3.selected`, }, ], }); diff --git a/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts b/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts index e1318c79c8a..dd892ee8a9d 100644 --- a/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/lost-at-sea-encounter.test.ts @@ -57,10 +57,10 @@ describe("Lost at Sea - Mystery Encounter", () => { expect(LostAtSeaEncounter.encounterType).toBe(MysteryEncounterType.LOST_AT_SEA); expect(LostAtSeaEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON); expect(LostAtSeaEncounter.dialogue).toBeDefined(); - expect(LostAtSeaEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}:intro` }]); - expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`); - expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}:description`); - expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}:query`); + expect(LostAtSeaEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]); + expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); expect(LostAtSeaEncounter.options.length).toBe(3); }); @@ -110,13 +110,13 @@ describe("Lost at Sea - Mystery Encounter", () => { expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); expect(option1.dialogue).toBeDefined(); expect(option1.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:1:label`, - disabledButtonLabel: `${namespace}:option:1:label_disabled`, - buttonTooltip: `${namespace}:option:1:tooltip`, - disabledButtonTooltip: `${namespace}:option:1:tooltip_disabled`, + buttonLabel: `${namespace}.option.1.label`, + disabledButtonLabel: `${namespace}.option.1.label_disabled`, + buttonTooltip: `${namespace}.option.1.tooltip`, + disabledButtonTooltip: `${namespace}.option.1.tooltip_disabled`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }); @@ -172,13 +172,13 @@ describe("Lost at Sea - Mystery Encounter", () => { expect(option2.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); expect(option2.dialogue).toBeDefined(); expect(option2.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:2:label`, - disabledButtonLabel: `${namespace}:option:2:label_disabled`, - buttonTooltip: `${namespace}:option:2:tooltip`, - disabledButtonTooltip: `${namespace}:option:2:tooltip_disabled`, + buttonLabel: `${namespace}.option.2.label`, + disabledButtonLabel: `${namespace}.option.2.label_disabled`, + buttonTooltip: `${namespace}.option.2.tooltip`, + disabledButtonTooltip: `${namespace}.option.2.tooltip_disabled`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], }); @@ -236,11 +236,11 @@ describe("Lost at Sea - Mystery Encounter", () => { expect(option3.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option3.dialogue).toBeDefined(); expect(option3.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:3:label`, - buttonTooltip: `${namespace}:option:3:tooltip`, + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, selected: [ { - text: `${namespace}:option:3:selected`, + text: `${namespace}.option.3.selected`, }, ], }); diff --git a/src/test/mystery-encounter/encounters/pokemon-salesman-encounter.test.ts b/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts similarity index 70% rename from src/test/mystery-encounter/encounters/pokemon-salesman-encounter.test.ts rename to src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts index bbd2d92e26c..93686ecc64b 100644 --- a/src/test/mystery-encounter/encounters/pokemon-salesman-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts @@ -9,7 +9,7 @@ import { runMysteryEncounterToEnd, runSelectMysteryEncounterOption } from "#test import BattleScene from "#app/battle-scene"; import { PlayerPokemon } from "#app/field/pokemon"; import { HUMAN_TRANSITABLE_BIOMES } from "#app/data/mystery-encounters/mystery-encounters"; -import { PokemonSalesmanEncounter } from "#app/data/mystery-encounters/encounters/pokemon-salesman-encounter"; +import { ThePokemonSalesmanEncounter } from "#app/data/mystery-encounters/encounters/the-pokemon-salesman-encounter"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils"; @@ -41,7 +41,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], ]); HUMAN_TRANSITABLE_BIOMES.forEach(biome => { - biomeMap.set(biome, [MysteryEncounterType.POKEMON_SALESMAN]); + biomeMap.set(biome, [MysteryEncounterType.THE_POKEMON_SALESMAN]); }); vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(biomeMap); }); @@ -53,26 +53,26 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { }); it("should have the correct properties", async () => { - await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.THE_POKEMON_SALESMAN, defaultParty); - expect(PokemonSalesmanEncounter.encounterType).toBe(MysteryEncounterType.POKEMON_SALESMAN); - expect(PokemonSalesmanEncounter.encounterTier).toBe(MysteryEncounterTier.ULTRA); - expect(PokemonSalesmanEncounter.dialogue).toBeDefined(); - expect(PokemonSalesmanEncounter.dialogue.intro).toStrictEqual([ - { text: `${namespace}:intro` }, - { speaker: `${namespace}:speaker`, text: `${namespace}:intro_dialogue` } + expect(ThePokemonSalesmanEncounter.encounterType).toBe(MysteryEncounterType.THE_POKEMON_SALESMAN); + expect(ThePokemonSalesmanEncounter.encounterTier).toBe(MysteryEncounterTier.ULTRA); + expect(ThePokemonSalesmanEncounter.dialogue).toBeDefined(); + expect(ThePokemonSalesmanEncounter.dialogue.intro).toStrictEqual([ + { text: `${namespace}.intro` }, + { speaker: `${namespace}.speaker`, text: `${namespace}.intro_dialogue` } ]); - expect(PokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`); - expect(PokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}:description`); - expect(PokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}:query`); - expect(PokemonSalesmanEncounter.options.length).toBe(2); + expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); + expect(ThePokemonSalesmanEncounter.options.length).toBe(2); }); it("should not spawn outside of HUMAN_TRANSITABLE_BIOMES", async () => { game.override.startingBiome(Biome.VOLCANO); await game.runToMysteryEncounter(); - expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.POKEMON_SALESMAN); + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.THE_POKEMON_SALESMAN); }); it("should not run below wave 10", async () => { @@ -80,7 +80,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { await game.runToMysteryEncounter(); - expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.POKEMON_SALESMAN); + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.THE_POKEMON_SALESMAN); }); it("should not run above wave 179", async () => { @@ -93,19 +93,19 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { it("should initialize fully ", async () => { initSceneWithoutEncounterPhase(scene, defaultParty); - scene.currentBattle.mysteryEncounter = PokemonSalesmanEncounter; + scene.currentBattle.mysteryEncounter = ThePokemonSalesmanEncounter; - const { onInit } = PokemonSalesmanEncounter; + const { onInit } = ThePokemonSalesmanEncounter; - expect(PokemonSalesmanEncounter.onInit).toBeDefined(); + expect(ThePokemonSalesmanEncounter.onInit).toBeDefined(); - PokemonSalesmanEncounter.populateDialogueTokensFromRequirements(scene); + ThePokemonSalesmanEncounter.populateDialogueTokensFromRequirements(scene); const onInitResult = onInit(scene); - expect(PokemonSalesmanEncounter.dialogueTokens?.purchasePokemon).toBeDefined(); - expect(PokemonSalesmanEncounter.dialogueTokens?.price).toBeDefined(); - expect(PokemonSalesmanEncounter.misc.pokemon instanceof PlayerPokemon).toBeTruthy(); - expect(PokemonSalesmanEncounter.misc?.price?.toString()).toBe(PokemonSalesmanEncounter.dialogueTokens?.price); + expect(ThePokemonSalesmanEncounter.dialogueTokens?.purchasePokemon).toBeDefined(); + expect(ThePokemonSalesmanEncounter.dialogueTokens?.price).toBeDefined(); + expect(ThePokemonSalesmanEncounter.misc.pokemon instanceof PlayerPokemon).toBeTruthy(); + expect(ThePokemonSalesmanEncounter.misc?.price?.toString()).toBe(ThePokemonSalesmanEncounter.dialogueTokens?.price); expect(onInitResult).toBe(true); }); @@ -114,20 +114,20 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { await game.runToMysteryEncounter(); - expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.POKEMON_SALESMAN); + expect(scene.currentBattle?.mysteryEncounter?.encounterType).not.toBe(MysteryEncounterType.THE_POKEMON_SALESMAN); }); describe("Option 1 - Purchase the pokemon", () => { it("should have the correct properties", () => { - const option = PokemonSalesmanEncounter.options[0]; + const option = ThePokemonSalesmanEncounter.options[0]; expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT); expect(option.dialogue).toBeDefined(); expect(option.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected_message`, + text: `${namespace}.option.1.selected_message`, }, ], }); @@ -138,7 +138,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { scene.money = initialMoney; const updateMoneySpy = vi.spyOn(EncounterPhaseUtils, "updatePlayerMoney"); - await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.THE_POKEMON_SALESMAN, defaultParty); await runMysteryEncounterToEnd(game, 1); const price = scene.currentBattle.mysteryEncounter.misc.price; @@ -149,7 +149,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { it("Should add the Pokemon to the party", async () => { scene.money = 20000; - await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.THE_POKEMON_SALESMAN, defaultParty); const initialPartySize = scene.getParty().length; const pokemonName = scene.currentBattle.mysteryEncounter.misc.pokemon.name; @@ -162,7 +162,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { it("should be disabled if player does not have enough money", async () => { scene.money = 0; - await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.THE_POKEMON_SALESMAN, defaultParty); await game.phaseInterceptor.to(MysteryEncounterPhase, false); const encounterPhase = scene.getCurrentPhase(); @@ -184,7 +184,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { scene.money = 20000; const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); - await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.THE_POKEMON_SALESMAN, defaultParty); await runMysteryEncounterToEnd(game, 1); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); @@ -195,7 +195,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { it("should leave encounter without battle", async () => { const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); - await game.runToMysteryEncounter(MysteryEncounterType.POKEMON_SALESMAN, defaultParty); + await game.runToMysteryEncounter(MysteryEncounterType.THE_POKEMON_SALESMAN, defaultParty); await runMysteryEncounterToEnd(game, 2); expect(leaveEncounterWithoutBattleSpy).toBeCalled(); diff --git a/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts b/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts index 91b9d509cbf..78610b76863 100644 --- a/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-strong-stuff-encounter.test.ts @@ -66,10 +66,10 @@ describe("The Strong Stuff - Mystery Encounter", () => { expect(TheStrongStuffEncounter.encounterType).toBe(MysteryEncounterType.THE_STRONG_STUFF); expect(TheStrongStuffEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON); expect(TheStrongStuffEncounter.dialogue).toBeDefined(); - expect(TheStrongStuffEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}:intro` }]); - expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}:title`); - expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}:description`); - expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}:query`); + expect(TheStrongStuffEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]); + expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`); + expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`); + expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`); expect(TheStrongStuffEncounter.options.length).toBe(2); }); @@ -139,11 +139,11 @@ describe("The Strong Stuff - Mystery Encounter", () => { expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option1.dialogue).toBeDefined(); expect(option1.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:1:label`, - buttonTooltip: `${namespace}:option:1:tooltip`, + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, selected: [ { - text: `${namespace}:option:1:selected`, + text: `${namespace}.option.1.selected`, }, ], }); @@ -182,11 +182,11 @@ describe("The Strong Stuff - Mystery Encounter", () => { expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT); expect(option1.dialogue).toBeDefined(); expect(option1.dialogue).toStrictEqual({ - buttonLabel: `${namespace}:option:2:label`, - buttonTooltip: `${namespace}:option:2:tooltip`, + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, selected: [ { - text: `${namespace}:option:2:selected`, + text: `${namespace}.option.2.selected`, }, ], });