mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-02-16 17:27:41 +00:00
adds 2 new encounters and colorable text options
This commit is contained in:
parent
872242c44f
commit
7b35efe95e
734
public/images/mystery-encounters/b2w2_lady.json
Normal file
734
public/images/mystery-encounters/b2w2_lady.json
Normal file
@ -0,0 +1,734 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "b2w2_lady.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 399,
|
||||
"h": 360
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0000.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 8,
|
||||
"y": 8,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 8,
|
||||
"y": 8,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 57,
|
||||
"y": 0,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 8,
|
||||
"y": 8,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 114,
|
||||
"y": 0,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 9,
|
||||
"y": 8,
|
||||
"w": 55,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 171,
|
||||
"y": 0,
|
||||
"w": 55,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 11,
|
||||
"y": 8,
|
||||
"w": 54,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 228,
|
||||
"y": 0,
|
||||
"w": 54,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 11,
|
||||
"y": 8,
|
||||
"w": 54,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 285,
|
||||
"y": 0,
|
||||
"w": 54,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 14,
|
||||
"y": 8,
|
||||
"w": 52,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 342,
|
||||
"y": 0,
|
||||
"w": 52,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 20,
|
||||
"y": 8,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 72,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0008.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 47,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 57,
|
||||
"y": 72,
|
||||
"w": 47,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0009.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 47,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 114,
|
||||
"y": 72,
|
||||
"w": 47,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0010.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 171,
|
||||
"y": 72,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0011.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 228,
|
||||
"y": 72,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0012.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 285,
|
||||
"y": 72,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0013.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 342,
|
||||
"y": 72,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0014.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 49,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 144,
|
||||
"w": 49,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0015.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 49,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 57,
|
||||
"y": 144,
|
||||
"w": 49,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0016.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 49,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 114,
|
||||
"y": 144,
|
||||
"w": 49,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0017.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 49,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 171,
|
||||
"y": 144,
|
||||
"w": 49,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0018.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 228,
|
||||
"y": 144,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0019.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 285,
|
||||
"y": 144,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0020.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 342,
|
||||
"y": 144,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0021.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 22,
|
||||
"y": 8,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 216,
|
||||
"w": 48,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0022.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 20,
|
||||
"y": 8,
|
||||
"w": 50,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 57,
|
||||
"y": 216,
|
||||
"w": 50,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0023.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 18,
|
||||
"y": 8,
|
||||
"w": 51,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 114,
|
||||
"y": 216,
|
||||
"w": 51,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0024.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 18,
|
||||
"y": 8,
|
||||
"w": 51,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 171,
|
||||
"y": 216,
|
||||
"w": 51,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0025.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 15,
|
||||
"y": 8,
|
||||
"w": 53,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 228,
|
||||
"y": 216,
|
||||
"w": 53,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0026.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 10,
|
||||
"y": 8,
|
||||
"w": 57,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 285,
|
||||
"y": 216,
|
||||
"w": 57,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0027.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 10,
|
||||
"y": 8,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 342,
|
||||
"y": 216,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0028.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 10,
|
||||
"y": 8,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 288,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0029.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 9,
|
||||
"y": 8,
|
||||
"w": 55,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 57,
|
||||
"y": 288,
|
||||
"w": 55,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0030.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 8,
|
||||
"y": 8,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 114,
|
||||
"y": 288,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0031.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 8,
|
||||
"y": 8,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 171,
|
||||
"y": 288,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0032.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 8,
|
||||
"y": 8,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 228,
|
||||
"y": 288,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0033.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 8,
|
||||
"y": 8,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 285,
|
||||
"y": 288,
|
||||
"w": 56,
|
||||
"h": 72
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:e7f062304401dbd7b3ec79512f0ff4cb:0136dac01331f88892a3df26aeab78f5:1ed1e22abb9b55d76337a5a599835c06$"
|
||||
}
|
||||
}
|
BIN
public/images/mystery-encounters/b2w2_lady.png
Normal file
BIN
public/images/mystery-encounters/b2w2_lady.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
797
public/images/mystery-encounters/b2w2_veteran_m.json
Normal file
797
public/images/mystery-encounters/b2w2_veteran_m.json
Normal file
@ -0,0 +1,797 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "b2w2_veteran_m.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 424,
|
||||
"h": 390
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0000.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 53,
|
||||
"y": 0,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 106,
|
||||
"y": 0,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 159,
|
||||
"y": 0,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 212,
|
||||
"y": 0,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 265,
|
||||
"y": 0,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 318,
|
||||
"y": 0,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 371,
|
||||
"y": 0,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0008.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 78,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0009.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 53,
|
||||
"y": 78,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0010.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 48,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 106,
|
||||
"y": 78,
|
||||
"w": 48,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0011.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 50,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 159,
|
||||
"y": 78,
|
||||
"w": 50,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0012.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 212,
|
||||
"y": 78,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0013.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 265,
|
||||
"y": 78,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0014.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 52,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 318,
|
||||
"y": 78,
|
||||
"w": 52,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0015.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 51,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 371,
|
||||
"y": 78,
|
||||
"w": 51,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0016.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 52,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 156,
|
||||
"w": 52,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0017.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 52,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 53,
|
||||
"y": 156,
|
||||
"w": 52,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0018.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 106,
|
||||
"y": 156,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0019.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 159,
|
||||
"y": 156,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0020.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 212,
|
||||
"y": 156,
|
||||
"w": 53,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0021.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 52,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 265,
|
||||
"y": 156,
|
||||
"w": 52,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0022.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 51,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 318,
|
||||
"y": 156,
|
||||
"w": 51,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0023.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 51,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 371,
|
||||
"y": 156,
|
||||
"w": 51,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0024.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 51,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 234,
|
||||
"w": 51,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0025.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 50,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 53,
|
||||
"y": 234,
|
||||
"w": 50,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0026.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 48,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 106,
|
||||
"y": 234,
|
||||
"w": 48,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0027.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 46,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 159,
|
||||
"y": 234,
|
||||
"w": 46,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0028.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 46,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 212,
|
||||
"y": 234,
|
||||
"w": 46,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0029.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 265,
|
||||
"y": 234,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0030.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 318,
|
||||
"y": 234,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0031.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 371,
|
||||
"y": 234,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0032.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 312,
|
||||
"w": 44,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0033.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 53,
|
||||
"y": 312,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0034.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 106,
|
||||
"y": 312,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0035.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 159,
|
||||
"y": 312,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0036.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 80,
|
||||
"h": 80
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 13,
|
||||
"y": 2,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
},
|
||||
"frame": {
|
||||
"x": 212,
|
||||
"y": 312,
|
||||
"w": 43,
|
||||
"h": 78
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:4deb068879a8ac195cb4f00c8b17b7f5:b32f0f90436649264b6f3c49b09ac06a:05e903aa75b8e50c28334d9b5e14c85a$"
|
||||
}
|
||||
}
|
BIN
public/images/mystery-encounters/b2w2_veteran_m.png
Normal file
BIN
public/images/mystery-encounters/b2w2_veteran_m.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
@ -1,18 +1,18 @@
|
||||
import { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { ModifierType, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||
import {PlayerPokemon} from "#app/field/pokemon";
|
||||
import {ModifierType, PokemonHeldItemModifierType} from "#app/modifier/modifier-type";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { isNullOrUndefined } from "../utils";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import { TimeOfDay } from "#enums/time-of-day";
|
||||
import { Nature } from "./nature";
|
||||
import { EvolutionItem, pokemonEvolutions } from "./pokemon-evolutions";
|
||||
import { FormChangeItem, SpeciesFormChangeItemTrigger, pokemonFormChanges } from "./pokemon-forms";
|
||||
import { SpeciesFormKey } from "./pokemon-species";
|
||||
import { StatusEffect } from "./status-effect";
|
||||
import { Type } from "./type";
|
||||
import { WeatherType } from "./weather";
|
||||
import {isNullOrUndefined} from "../utils";
|
||||
import {Abilities} from "#enums/abilities";
|
||||
import {Moves} from "#enums/moves";
|
||||
import {Species} from "#enums/species";
|
||||
import {TimeOfDay} from "#enums/time-of-day";
|
||||
import {Nature} from "./nature";
|
||||
import {EvolutionItem, pokemonEvolutions} from "./pokemon-evolutions";
|
||||
import {FormChangeItem, pokemonFormChanges, SpeciesFormChangeItemTrigger} from "./pokemon-forms";
|
||||
import {SpeciesFormKey} from "./pokemon-species";
|
||||
import {StatusEffect} from "./status-effect";
|
||||
import {Type} from "./type";
|
||||
import {WeatherType} from "./weather";
|
||||
import {MysteryEncounterType} from "#enums/mystery-encounter-type";
|
||||
|
||||
export interface EncounterRequirement {
|
||||
@ -39,7 +39,7 @@ export abstract class EncounterPokemonRequirement implements EncounterRequiremen
|
||||
}
|
||||
|
||||
// Returns all party members that are compatible with this requirement. For non pokemon related requirements, the entire party is returned..
|
||||
queryParty(partyPokemon: PlayerPokemon[]) {
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -215,23 +215,31 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
|
||||
}
|
||||
|
||||
export class MoneyRequirement extends EncounterSceneRequirement {
|
||||
requiredMoney: number;
|
||||
requiredMoney: number; // Static value
|
||||
scalingMultiplier: number; // Calculates required money based off wave index
|
||||
|
||||
constructor(requiredMoney: number) {
|
||||
constructor(requiredMoney: number, scalingMultiplier?: number) {
|
||||
super();
|
||||
this.requiredMoney = requiredMoney;
|
||||
this.scalingMultiplier = scalingMultiplier ? scalingMultiplier : 0;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
const money = scene.money;
|
||||
if (!isNullOrUndefined(money) && this?.requiredMoney > 0 && this.requiredMoney > money) {
|
||||
if (isNullOrUndefined(money)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
if (this?.scalingMultiplier > 0) {
|
||||
this.requiredMoney = scene.getWaveMoneyAmount(this.scalingMultiplier);
|
||||
}
|
||||
return !(this?.requiredMoney > 0 && this.requiredMoney > money);
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["money", "₽" + scene.money.toString()];
|
||||
const value = this?.scalingMultiplier > 0 ? scene.getWaveMoneyAmount(this.scalingMultiplier).toString() : this.requiredMoney.toString();
|
||||
// Colors money text
|
||||
return ["money", "@ecCol[MONEY]{₽" + value + "}"];
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,9 +407,9 @@ export class MoveRequirement extends EncounterPokemonRequirement {
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const includedMoves = this.requiredMoves.filter((reqMove) => pokemon.moveset.filter((move) => move.moveId === reqMove).length > 0);
|
||||
const includedMoves = pokemon.moveset.filter((move) => this.requiredMoves.includes(move.moveId));
|
||||
if (includedMoves.length > 0) {
|
||||
return ["move", Moves[includedMoves[0]].replace("_", " ")];
|
||||
return ["move", includedMoves[0].getName()];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -552,15 +560,15 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
||||
minNumberOfPokemon:number;
|
||||
invertQuery:boolean;
|
||||
|
||||
constructor(StatusEffect: StatusEffect | StatusEffect[], minNumberOfPokemon: number = 1, invertQuery: boolean = false) {
|
||||
constructor(statusEffect: StatusEffect | StatusEffect[], minNumberOfPokemon: number = 1, invertQuery: boolean = false) {
|
||||
super();
|
||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||
this.invertQuery = invertQuery;
|
||||
if (StatusEffect instanceof Array) {
|
||||
this.requiredStatusEffect = StatusEffect;
|
||||
if (statusEffect instanceof Array) {
|
||||
this.requiredStatusEffect = statusEffect;
|
||||
} else {
|
||||
this.requiredStatusEffect = [];
|
||||
this.requiredStatusEffect.push(StatusEffect);
|
||||
this.requiredStatusEffect.push(statusEffect);
|
||||
}
|
||||
}
|
||||
|
||||
@ -576,16 +584,38 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredStatusEffect.filter((StatusEffect) => pokemon.status?.effect === StatusEffect).length > 0);
|
||||
return partyPokemon.filter((pokemon) => {
|
||||
return this.requiredStatusEffect.some((statusEffect) => {
|
||||
if (statusEffect === StatusEffect.NONE) {
|
||||
// StatusEffect.NONE also checks for null or undefined status
|
||||
return isNullOrUndefined(pokemon.status) || isNullOrUndefined(pokemon.status.effect) || pokemon.status?.effect === statusEffect;
|
||||
} else {
|
||||
return pokemon.status?.effect === statusEffect;
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// for an inverted query, we only want to get the pokemon that don't have ANY of the listed StatusEffects
|
||||
return partyPokemon.filter((pokemon) => this.requiredStatusEffect.filter((StatusEffect) => pokemon.status?.effect === StatusEffect).length === 0);
|
||||
// return partyPokemon.filter((pokemon) => this.requiredStatusEffect.filter((statusEffect) => pokemon.status?.effect === statusEffect).length === 0);
|
||||
return partyPokemon.filter((pokemon) => {
|
||||
return !this.requiredStatusEffect.some((statusEffect) => {
|
||||
if (statusEffect === StatusEffect.NONE) {
|
||||
// StatusEffect.NONE also checks for null or undefined status
|
||||
return isNullOrUndefined(pokemon.status) || isNullOrUndefined(pokemon.status.effect) || pokemon.status?.effect === statusEffect;
|
||||
} else {
|
||||
return pokemon.status?.effect === statusEffect;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const reqStatus = this.requiredStatusEffect.filter((a) => {
|
||||
pokemon.status?.effect ===(a);
|
||||
if (a === StatusEffect.NONE) {
|
||||
return isNullOrUndefined(pokemon.status) || isNullOrUndefined(pokemon.status.effect) || pokemon.status?.effect === a;
|
||||
}
|
||||
return pokemon.status?.effect === a;
|
||||
});
|
||||
if (reqStatus.length > 0) {
|
||||
return ["status", StatusEffect[reqStatus[0]]];
|
||||
@ -863,7 +893,9 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => pokemon.getHpRatio() >= this.requiredHealthRange[0] && pokemon.getHpRatio() <= this.requiredHealthRange[1]);
|
||||
return partyPokemon.filter((pokemon) => {
|
||||
return pokemon.getHpRatio() >= this.requiredHealthRange[0] && pokemon.getHpRatio() <= this.requiredHealthRange[1];
|
||||
});
|
||||
} else {
|
||||
// for an inverted query, we only want to get the pokemon that don't have ANY of the listed requiredHealthRanges
|
||||
return partyPokemon.filter((pokemon) => pokemon.getHpRatio() < this.requiredHealthRange[0] || pokemon.getHpRatio() > this.requiredHealthRange[1]);
|
||||
|
@ -5,10 +5,13 @@ import MysteryEncounterDialogue, {
|
||||
allMysteryEncounterDialogue
|
||||
} from "./mystery-encounters/dialogue/mystery-encounter-dialogue";
|
||||
import MysteryEncounterOption from "./mystery-encounter-option";
|
||||
import { EncounterPokemonRequirement, EncounterSceneRequirement } from "./mystery-encounter-requirements";
|
||||
import {
|
||||
EncounterPokemonRequirement,
|
||||
EncounterSceneRequirement
|
||||
} from "./mystery-encounter-requirements";
|
||||
import * as Utils from "../utils";
|
||||
import {EnemyPartyConfig} from "#app/data/mystery-encounters/mystery-encounter-utils";
|
||||
import { PlayerPokemon } from "#app/field/pokemon";
|
||||
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
||||
import {isNullOrUndefined} from "../utils";
|
||||
|
||||
export enum MysteryEncounterVariant {
|
||||
@ -167,6 +170,10 @@ export default class MysteryEncounter implements MysteryEncounter {
|
||||
return sceneReq && secReqs && priReqs;
|
||||
}
|
||||
|
||||
pokemonMeetsPrimaryRequirements?(scene: BattleScene, pokemon: Pokemon) {
|
||||
return !this.primaryPokemonRequirements.some(req => !req.queryParty(scene.getParty()).map(p => p.id).includes(pokemon.id));
|
||||
}
|
||||
|
||||
private meetsPrimaryRequirementAndPrimaryPokemonSelected?(scene: BattleScene) {
|
||||
if (this.primaryPokemonRequirements.length === 0) {
|
||||
const activeMon = scene.getParty().filter(p => p.isActive(true));
|
||||
@ -263,6 +270,12 @@ export default class MysteryEncounter implements MysteryEncounter {
|
||||
* For multiple support pokemon in the dialogue token, it will have to be overridden.
|
||||
*/
|
||||
populateDialogueTokensFromRequirements?(scene: BattleScene) {
|
||||
if (this.requirements?.length > 0) {
|
||||
for (const req of this.requirements) {
|
||||
const dialogueToken = req.getDialogueToken(scene);
|
||||
this.setDialogueToken(...dialogueToken);
|
||||
}
|
||||
}
|
||||
if (this.primaryPokemon?.length > 0) {
|
||||
this.setDialogueToken("primaryName", this.primaryPokemon.name);
|
||||
for (const req of this.primaryPokemonRequirements) {
|
||||
@ -281,9 +294,17 @@ export default class MysteryEncounter implements MysteryEncounter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dialogue tokens for options
|
||||
for (let i = 0; i < this.options.length; i++) {
|
||||
const opt = this.options[i];
|
||||
const j = i + 1;
|
||||
if (opt.requirements?.length > 0) {
|
||||
for (const req of opt.requirements) {
|
||||
const dialogueToken = req.getDialogueToken(scene);
|
||||
this.setDialogueToken("option" + j + this.capitalizeFirstLetter(dialogueToken[0]), dialogueToken[1]);
|
||||
}
|
||||
}
|
||||
if (opt.primaryPokemonRequirements?.length > 0 && opt.primaryPokemon?.length > 0) {
|
||||
this.setDialogueToken("option" + j + "PrimaryName", opt.primaryPokemon.name);
|
||||
for (const req of opt.primaryPokemonRequirements) {
|
||||
|
120
src/data/mystery-encounters/department-store-sale.ts
Normal file
120
src/data/mystery-encounters/department-store-sale.ts
Normal file
@ -0,0 +1,120 @@
|
||||
import BattleScene from "../../battle-scene";
|
||||
import {
|
||||
leaveEncounterWithoutBattle,
|
||||
setCustomEncounterRewards,
|
||||
} from "#app/data/mystery-encounters/mystery-encounter-utils";
|
||||
import MysteryEncounter, {MysteryEncounterBuilder, MysteryEncounterTier} from "../mystery-encounter";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import {WaveCountRequirement} from "../mystery-encounter-requirements";
|
||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||
import {modifierTypes} from "#app/modifier/modifier-type";
|
||||
import {Species} from "#enums/species";
|
||||
import {randSeedInt} from "#app/utils";
|
||||
|
||||
export const DepartmentStoreSaleEncounter: MysteryEncounter = new MysteryEncounterBuilder()
|
||||
.withEncounterType(MysteryEncounterType.DEPARTMENT_STORE_SALE)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "b2w2_lady",
|
||||
fileRoot: "mystery-encounters",
|
||||
hasShadow: true,
|
||||
x: -20
|
||||
},
|
||||
{
|
||||
spriteKey: Species.FURFROU.toString(),
|
||||
fileRoot: "pokemon",
|
||||
hasShadow: true,
|
||||
repeat: true,
|
||||
x: 30
|
||||
}
|
||||
])
|
||||
// .withHideIntroVisuals(false)
|
||||
.withSceneRequirement(new WaveCountRequirement([10, 100]))
|
||||
.withOption(new MysteryEncounterOptionBuilder()
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
// Choose TMs
|
||||
const modifiers = [];
|
||||
let i = 0;
|
||||
while (i < 4) {
|
||||
// 2/2/1 weight on TM rarity
|
||||
const roll = randSeedInt(5);
|
||||
if (roll < 2) {
|
||||
modifiers.push(modifierTypes.TM_COMMON);
|
||||
} else if (roll < 4) {
|
||||
modifiers.push(modifierTypes.TM_GREAT);
|
||||
} else {
|
||||
modifiers.push(modifierTypes.TM_ULTRA);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
setCustomEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false});
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
})
|
||||
.build())
|
||||
.withOption(new MysteryEncounterOptionBuilder()
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
// Choose Vitamins
|
||||
const modifiers = [];
|
||||
let i = 0;
|
||||
while (i < 3) {
|
||||
// 2/1 weight on base stat booster vs PP Up
|
||||
const roll = randSeedInt(3);
|
||||
if (roll === 0) {
|
||||
modifiers.push(modifierTypes.PP_UP);
|
||||
} else {
|
||||
modifiers.push(modifierTypes.BASE_STAT_BOOSTER);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
setCustomEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false});
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
})
|
||||
.build())
|
||||
.withOption(new MysteryEncounterOptionBuilder()
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
// Choose X Items
|
||||
const modifiers = [];
|
||||
let i = 0;
|
||||
while (i < 5) {
|
||||
// 4/1 weight on base stat booster vs Dire Hit
|
||||
const roll = randSeedInt(5);
|
||||
if (roll === 0) {
|
||||
modifiers.push(modifierTypes.DIRE_HIT);
|
||||
} else {
|
||||
modifiers.push(modifierTypes.TEMP_STAT_BOOSTER);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
setCustomEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false});
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
})
|
||||
.build())
|
||||
.withOption(new MysteryEncounterOptionBuilder()
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
// Choose Pokeballs
|
||||
const modifiers = [];
|
||||
let i = 0;
|
||||
while (i < 4) {
|
||||
// 10/30/20/5 weight on pokeballs
|
||||
const roll = randSeedInt(65);
|
||||
if (roll < 10) {
|
||||
modifiers.push(modifierTypes.POKEBALL);
|
||||
} else if (roll < 40) {
|
||||
modifiers.push(modifierTypes.GREAT_BALL);
|
||||
} else if (roll < 60) {
|
||||
modifiers.push(modifierTypes.ULTRA_BALL);
|
||||
} else {
|
||||
modifiers.push(modifierTypes.ROGUE_BALL);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
setCustomEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false});
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
})
|
||||
.build())
|
||||
.build();
|
@ -0,0 +1,36 @@
|
||||
import MysteryEncounterDialogue from "#app/data/mystery-encounters/dialogue/mystery-encounter-dialogue";
|
||||
|
||||
export const DepartmentStoreSaleDialogue: MysteryEncounterDialogue = {
|
||||
intro: [
|
||||
{
|
||||
text: "mysteryEncounter:department_store_sale_intro_message"
|
||||
},
|
||||
{
|
||||
text: "mysteryEncounter:department_store_sale_intro_dialogue",
|
||||
speaker: "mysteryEncounter:department_store_sale_speaker"
|
||||
}
|
||||
],
|
||||
encounterOptionsDialogue: {
|
||||
title: "mysteryEncounter:department_store_sale_title",
|
||||
description: "mysteryEncounter:department_store_sale_description",
|
||||
query: "mysteryEncounter:department_store_sale_query",
|
||||
options: [
|
||||
{
|
||||
buttonLabel: "mysteryEncounter:department_store_sale_option_1_label",
|
||||
buttonTooltip: "mysteryEncounter:department_store_sale_option_1_tooltip"
|
||||
},
|
||||
{
|
||||
buttonLabel: "mysteryEncounter:department_store_sale_option_2_label",
|
||||
buttonTooltip: "mysteryEncounter:department_store_sale_option_2_tooltip"
|
||||
},
|
||||
{
|
||||
buttonLabel: "mysteryEncounter:department_store_sale_option_3_label",
|
||||
buttonTooltip: "mysteryEncounter:department_store_sale_option_3_tooltip"
|
||||
},
|
||||
{
|
||||
buttonLabel: "mysteryEncounter:department_store_sale_option_4_label",
|
||||
buttonTooltip: "mysteryEncounter:department_store_sale_option_4_tooltip"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
@ -5,10 +5,14 @@ import {DarkDealDialogue} from "#app/data/mystery-encounters/dialogue/dark-deal-
|
||||
import {FightOrFlightDialogue} from "#app/data/mystery-encounters/dialogue/fight-or-flight-dialogue";
|
||||
import {TrainingSessionDialogue} from "#app/data/mystery-encounters/dialogue/training-session-dialogue";
|
||||
import { SleepingSnorlaxDialogue } from "./sleeping-snorlax-dialogue";
|
||||
import {DepartmentStoreSaleDialogue} from "#app/data/mystery-encounters/dialogue/department-store-sale-dialogue";
|
||||
import {ShadyVitaminDealerDialogue} from "#app/data/mystery-encounters/dialogue/shady-vitamin-dealer";
|
||||
import {TextStyle} from "#app/ui/text";
|
||||
|
||||
export class TextDisplay {
|
||||
speaker?: TemplateStringsArray | `mysteryEncounter:${string}`;
|
||||
text: TemplateStringsArray | `mysteryEncounter:${string}`;
|
||||
style?: TextStyle;
|
||||
}
|
||||
|
||||
export class OptionTextDisplay {
|
||||
@ -17,6 +21,7 @@ export class OptionTextDisplay {
|
||||
disabledTooltip?: TemplateStringsArray | `mysteryEncounter:${string}`;
|
||||
secondOptionPrompt?: TemplateStringsArray | `mysteryEncounter:${string}`;
|
||||
selected?: TextDisplay[];
|
||||
style?: TextStyle;
|
||||
}
|
||||
|
||||
export class EncounterOptionsDialogue {
|
||||
@ -91,4 +96,6 @@ export function initMysteryEncounterDialogue() {
|
||||
allMysteryEncounterDialogue[MysteryEncounterType.FIGHT_OR_FLIGHT] = FightOrFlightDialogue;
|
||||
allMysteryEncounterDialogue[MysteryEncounterType.TRAINING_SESSION] = TrainingSessionDialogue;
|
||||
allMysteryEncounterDialogue[MysteryEncounterType.SLEEPING_SNORLAX] = SleepingSnorlaxDialogue;
|
||||
allMysteryEncounterDialogue[MysteryEncounterType.DEPARTMENT_STORE_SALE] = DepartmentStoreSaleDialogue;
|
||||
allMysteryEncounterDialogue[MysteryEncounterType.SHADY_VITAMIN_DEALER] = ShadyVitaminDealerDialogue;
|
||||
}
|
||||
|
42
src/data/mystery-encounters/dialogue/shady-vitamin-dealer.ts
Normal file
42
src/data/mystery-encounters/dialogue/shady-vitamin-dealer.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import MysteryEncounterDialogue from "#app/data/mystery-encounters/dialogue/mystery-encounter-dialogue";
|
||||
|
||||
export const ShadyVitaminDealerDialogue: MysteryEncounterDialogue = {
|
||||
intro: [
|
||||
{
|
||||
text: "mysteryEncounter:shady_vitamin_dealer_intro_message"
|
||||
},
|
||||
{
|
||||
text: "mysteryEncounter:shady_vitamin_dealer_intro_dialogue",
|
||||
speaker: "mysteryEncounter:shady_vitamin_dealer_speaker"
|
||||
}
|
||||
],
|
||||
encounterOptionsDialogue: {
|
||||
title: "mysteryEncounter:shady_vitamin_dealer_title",
|
||||
description: "mysteryEncounter:shady_vitamin_dealer_description",
|
||||
query: "mysteryEncounter:shady_vitamin_dealer_query",
|
||||
options: [
|
||||
{
|
||||
buttonLabel: "mysteryEncounter:shady_vitamin_dealer_option_1_label",
|
||||
buttonTooltip: "mysteryEncounter:shady_vitamin_dealer_option_1_tooltip",
|
||||
selected: [
|
||||
{
|
||||
text: "mysteryEncounter:shady_vitamin_dealer_option_selected"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
buttonLabel: "mysteryEncounter:shady_vitamin_dealer_option_2_label",
|
||||
buttonTooltip: "mysteryEncounter:shady_vitamin_dealer_option_2_tooltip",
|
||||
selected: [
|
||||
{
|
||||
text: "mysteryEncounter:shady_vitamin_dealer_option_selected"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
buttonLabel: "mysteryEncounter:shady_vitamin_dealer_option_3_label",
|
||||
buttonTooltip: "mysteryEncounter:shady_vitamin_dealer_option_3_tooltip"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
@ -9,7 +9,7 @@ import {
|
||||
} from "#app/data/mystery-encounters/mystery-encounter-utils";
|
||||
import MysteryEncounter, {MysteryEncounterBuilder, MysteryEncounterTier} from "../mystery-encounter";
|
||||
import {MysteryEncounterType} from "#enums/mystery-encounter-type";
|
||||
import {WaveCountRequirement} from "../mystery-encounter-requirements";
|
||||
import {MoveRequirement, WaveCountRequirement} from "../mystery-encounter-requirements";
|
||||
import {MysteryEncounterOptionBuilder} from "../mystery-encounter-option";
|
||||
import {
|
||||
getPartyLuckValue,
|
||||
@ -23,6 +23,18 @@ import {StatChangePhase} from "#app/phases";
|
||||
import {BattleStat} from "#app/data/battle-stat";
|
||||
import Pokemon from "#app/field/pokemon";
|
||||
import {randSeedInt} from "#app/utils";
|
||||
import {Moves} from "#enums/moves";
|
||||
import {TextStyle} from "#app/ui/text";
|
||||
|
||||
const validMovesForSteal = [
|
||||
Moves.PLUCK,
|
||||
Moves.COVET,
|
||||
Moves.FAKE_OUT,
|
||||
Moves.THIEF,
|
||||
Moves.TRICK,
|
||||
Moves.SWITCHEROO,
|
||||
Moves.GIGA_DRAIN
|
||||
];
|
||||
|
||||
export const FightOrFlightEncounter: MysteryEncounter = new MysteryEncounterBuilder()
|
||||
.withEncounterType(MysteryEncounterType.FIGHT_OR_FLIGHT)
|
||||
@ -70,6 +82,21 @@ export const FightOrFlightEncounter: MysteryEncounter = new MysteryEncounterBuil
|
||||
}
|
||||
];
|
||||
|
||||
// If player has a stealing move, they succeed automatically
|
||||
const moveRequirement = new MoveRequirement(validMovesForSteal);
|
||||
const validPokemon = moveRequirement.queryParty(scene.getParty());
|
||||
if (validPokemon?.length > 0) {
|
||||
// Use first valid pokemon to execute the theivery
|
||||
const pokemon = validPokemon[0];
|
||||
encounter.setDialogueToken("thiefPokemon", pokemon.name);
|
||||
encounter.setDialogueToken(...moveRequirement.getDialogueToken(scene, pokemon));
|
||||
encounter.dialogue.encounterOptionsDialogue.options[1].buttonTooltip = "mysteryEncounter:fight_or_flight_option_2_steal_tooltip";
|
||||
encounter.dialogue.encounterOptionsDialogue.options[1].style = TextStyle.SUMMARY_GREEN;
|
||||
} else {
|
||||
encounter.dialogue.encounterOptionsDialogue.options[1].buttonTooltip = "mysteryEncounter:fight_or_flight_option_2_tooltip";
|
||||
encounter.dialogue.encounterOptionsDialogue.options[1].style = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
.withOption(new MysteryEncounterOptionBuilder()
|
||||
@ -83,9 +110,23 @@ export const FightOrFlightEncounter: MysteryEncounter = new MysteryEncounterBuil
|
||||
.withOption(new MysteryEncounterOptionBuilder()
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
// Pick steal
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
const item = scene.currentBattle.mysteryEncounter.misc as ModifierTypeOption;
|
||||
setCustomEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false});
|
||||
|
||||
// If player has a stealing move, they succeed automatically
|
||||
const moveRequirement = new MoveRequirement(validMovesForSteal);
|
||||
const validPokemon = moveRequirement.queryParty(scene.getParty());
|
||||
if (validPokemon?.length > 0) {
|
||||
// Use first valid pokemon to execute the theivery
|
||||
const pokemon = validPokemon[0];
|
||||
encounter.setDialogueToken("thiefPokemon", pokemon.name);
|
||||
encounter.setDialogueToken(...moveRequirement.getDialogueToken(scene, pokemon));
|
||||
await showEncounterText(scene, "mysteryEncounter:fight_or_flight_option_2_steal_result");
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
const roll = randSeedInt(16);
|
||||
if (roll > 6) {
|
||||
// Noticed and attacked by boss, gets +1 to all stats at start of fight (62.5%)
|
||||
@ -101,8 +142,8 @@ export const FightOrFlightEncounter: MysteryEncounter = new MysteryEncounterBuil
|
||||
} else {
|
||||
// Steal item (37.5%)
|
||||
// Display result message then proceed to rewards
|
||||
await showEncounterText(scene, "mysteryEncounter:fight_or_flight_option_2_good_result")
|
||||
.then(() => leaveEncounterWithoutBattle(scene));
|
||||
await showEncounterText(scene, "mysteryEncounter:fight_or_flight_option_2_good_result");
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
}
|
||||
})
|
||||
.build())
|
||||
|
@ -10,8 +10,12 @@ import Trainer, {TrainerVariant} from "../../field/trainer";
|
||||
import {PokemonExpBoosterModifier} from "#app/modifier/modifier";
|
||||
import {
|
||||
CustomModifierSettings,
|
||||
getModifierPoolForType,
|
||||
ModifierPoolType,
|
||||
ModifierType,
|
||||
ModifierTypeFunc,
|
||||
ModifierTypeGenerator,
|
||||
modifierTypes,
|
||||
PokemonHeldItemModifierType,
|
||||
regenerateModifierPoolThresholds
|
||||
} from "#app/modifier/modifier-type";
|
||||
@ -31,6 +35,7 @@ import {Mode} from "#app/ui/ui";
|
||||
import {PartyOption, PartyUiMode} from "#app/ui/party-ui-handler";
|
||||
import {OptionSelectConfig, OptionSelectItem} from "#app/ui/abstact-option-select-ui-handler";
|
||||
import {WIGHT_INCREMENT_ON_SPAWN_MISS} from "#app/data/mystery-encounters/mystery-encounters";
|
||||
import {getBBCodeFrag, TextStyle} from "#app/ui/text";
|
||||
|
||||
/**
|
||||
*
|
||||
@ -162,21 +167,35 @@ export function koPlayerPokemon(pokemon: PlayerPokemon) {
|
||||
pokemon.updateInfo();
|
||||
}
|
||||
|
||||
export function getTextWithEncounterDialogueTokens(scene: BattleScene, textKey: TemplateStringsArray | `mysteryEncounter:${string}`): string {
|
||||
export function getTextWithEncounterDialogueTokensAndColor(scene: BattleScene, textKey: TemplateStringsArray | `mysteryEncounter:${string}`, primaryStyle: TextStyle = TextStyle.MESSAGE): string {
|
||||
if (isNullOrUndefined(textKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let textString: string = i18next.t(textKey);
|
||||
|
||||
const dialogueTokens = scene.currentBattle?.mysteryEncounter?.dialogueTokens;
|
||||
// Apply primary styling before anything else, if it exists
|
||||
textString = getBBCodeFrag(textString, primaryStyle) + "[/color][/shadow]";
|
||||
const primaryStyleString = [...textString.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))][0];
|
||||
|
||||
// Apply dialogue tokens
|
||||
const dialogueTokens = scene.currentBattle?.mysteryEncounter?.dialogueTokens;
|
||||
if (dialogueTokens) {
|
||||
dialogueTokens.forEach((value) => {
|
||||
textString = textString.replace(value[0], value[1]);
|
||||
});
|
||||
}
|
||||
|
||||
// Set custom colors
|
||||
// Looks for any pattern like this: @ecCol[SUMMARY_BLUE]{my text to color}
|
||||
// Resulting in: "my text to color" string with TextStyle.SUMMARY_BLUE
|
||||
textString = textString.replace(/@ecCol\[([^{]*)\]{([^}]*)}/gi, (substring, textStyle: string, textToColor: string) => {
|
||||
return "[/color][/shadow]" + getBBCodeFrag(textToColor, TextStyle[textStyle]) + "[/color][/shadow]" + primaryStyleString;
|
||||
});
|
||||
|
||||
// Remove extra style block at the end
|
||||
textString = textString.replace(/\[color=[^\[]*\]\[shadow=[^\[]*\]\[\/color\]\[\/shadow\]/gi, "");
|
||||
|
||||
return textString;
|
||||
}
|
||||
|
||||
@ -186,7 +205,7 @@ export function getTextWithEncounterDialogueTokens(scene: BattleScene, textKey:
|
||||
* @param contentKey
|
||||
*/
|
||||
export function queueEncounterMessage(scene: BattleScene, contentKey: TemplateStringsArray | `mysteryEncounter:${string}`): void {
|
||||
const text: string = getTextWithEncounterDialogueTokens(scene, contentKey);
|
||||
const text: string = getTextWithEncounterDialogueTokensAndColor(scene, contentKey, TextStyle.MESSAGE);
|
||||
scene.queueMessage(text, null, true);
|
||||
}
|
||||
|
||||
@ -197,7 +216,7 @@ export function queueEncounterMessage(scene: BattleScene, contentKey: TemplateSt
|
||||
*/
|
||||
export function showEncounterText(scene: BattleScene, contentKey: TemplateStringsArray | `mysteryEncounter:${string}`): Promise<void> {
|
||||
return new Promise<void>(resolve => {
|
||||
const text: string = getTextWithEncounterDialogueTokens(scene, contentKey);
|
||||
const text: string = getTextWithEncounterDialogueTokensAndColor(scene, contentKey, TextStyle.MESSAGE);
|
||||
scene.ui.showText(text, null, () => resolve(), 0, true);
|
||||
});
|
||||
}
|
||||
@ -210,8 +229,8 @@ export function showEncounterText(scene: BattleScene, contentKey: TemplateString
|
||||
* @param callback
|
||||
*/
|
||||
export function showEncounterDialogue(scene: BattleScene, textContentKey: TemplateStringsArray | `mysteryEncounter:${string}`, speakerContentKey: TemplateStringsArray | `mysteryEncounter:${string}`, callback?: Function) {
|
||||
const text: string = getTextWithEncounterDialogueTokens(scene, textContentKey);
|
||||
const speaker: string = getTextWithEncounterDialogueTokens(scene, speakerContentKey);
|
||||
const text: string = getTextWithEncounterDialogueTokensAndColor(scene, textContentKey, TextStyle.MESSAGE);
|
||||
const speaker: string = getTextWithEncounterDialogueTokensAndColor(scene, speakerContentKey);
|
||||
scene.ui.showDialogue(text, speaker, null, callback, 0, 0);
|
||||
}
|
||||
|
||||
@ -399,6 +418,50 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will update player money, and animate change (sound optional)
|
||||
* @param scene - Battle Scene
|
||||
* @param changeValue
|
||||
* @param playSound
|
||||
*/
|
||||
export function updatePlayerMoney(scene: BattleScene, changeValue: number, playSound: boolean = true) {
|
||||
scene.money += changeValue;
|
||||
scene.updateMoneyText();
|
||||
scene.animateMoneyChanged(false);
|
||||
if (playSound) {
|
||||
scene.playSound("buy");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts modifier bullshit to an actual item
|
||||
* @param scene - Battle Scene
|
||||
* @param modifier
|
||||
* @param pregenArgs - can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
|
||||
*/
|
||||
export function generateModifierType(scene: BattleScene, modifier: () => ModifierType, pregenArgs?: any[]): ModifierType {
|
||||
const modifierId = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifier);
|
||||
let result: ModifierType = modifierTypes[modifierId]?.();
|
||||
|
||||
// Gets tier of item by checking player item pool
|
||||
const modifierPool = getModifierPoolForType(ModifierPoolType.PLAYER);
|
||||
Object.keys(modifierPool).every(modifierTier => {
|
||||
const modType = modifierPool[modifierTier].find(m => {
|
||||
if (m.modifierType.id === modifierId) {
|
||||
return m;
|
||||
}
|
||||
});
|
||||
if (modType) {
|
||||
result = modType.modifierType;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
result = result instanceof ModifierTypeGenerator ? result.generateType(scene.getParty(), pregenArgs) : result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will initialize reward phases to follow the mystery encounter
|
||||
* Can have shop displayed or skipped
|
||||
@ -439,8 +502,9 @@ export function setCustomEncounterRewards(scene: BattleScene, customShopRewards?
|
||||
* @param onPokemonSelected - Any logic that needs to be performed when Pokemon is chosen
|
||||
* If a second option needs to be selected, onPokemonSelected should return a OptionSelectItem[] object
|
||||
* @param onPokemonNotSelected - Any logic that needs to be performed if no Pokemon is chosen
|
||||
* @param selectablePokemonFilter
|
||||
*/
|
||||
export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (pokemon: PlayerPokemon) => void | OptionSelectItem[], onPokemonNotSelected?: () => void): Promise<boolean> {
|
||||
export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (pokemon: PlayerPokemon) => void | OptionSelectItem[], onPokemonNotSelected?: () => void, selectablePokemonFilter?: (pokemon: PlayerPokemon) => string): Promise<boolean> {
|
||||
return new Promise(resolve => {
|
||||
// Open party screen to choose pokemon to train
|
||||
scene.ui.setMode(Mode.PARTY, PartyUiMode.SELECT, -1, (slotIndex: integer, option: PartyOption) => {
|
||||
@ -493,7 +557,7 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p
|
||||
if (!textPromptKey) {
|
||||
displayOptions();
|
||||
} else {
|
||||
const secondOptionSelectPrompt = getTextWithEncounterDialogueTokens(scene, textPromptKey);
|
||||
const secondOptionSelectPrompt = getTextWithEncounterDialogueTokensAndColor(scene, textPromptKey, TextStyle.MESSAGE);
|
||||
scene.ui.showText(secondOptionSelectPrompt, null, displayOptions, null, true);
|
||||
}
|
||||
});
|
||||
@ -506,7 +570,7 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p
|
||||
resolve(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
}, selectablePokemonFilter);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@ import {TrainingSessionEncounter} from "#app/data/mystery-encounters/training-se
|
||||
import { Biome } from "#app/enums/biome";
|
||||
import { SleepingSnorlaxEncounter } from "./sleeping-snorlax";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import {DepartmentStoreSaleEncounter} from "#app/data/mystery-encounters/department-store-sale";
|
||||
import {ShadyVitaminDealerEncounter} from "#app/data/mystery-encounters/shady-vitamin-dealer";
|
||||
|
||||
// Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * <number of missed spawns>) / 256
|
||||
export const BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT = 1;
|
||||
@ -19,18 +21,20 @@ export const allMysteryEncounters : {[encounterType:string]: MysteryEncounter} =
|
||||
// To enable an encounter in all biomes, do not add to this map
|
||||
export const mysteryEncountersByBiome = new Map<Biome, MysteryEncounterType[]>([
|
||||
[Biome.TOWN, [
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.PLAINS,[
|
||||
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.GRASS, [
|
||||
MysteryEncounterType.SLEEPING_SNORLAX
|
||||
MysteryEncounterType.SLEEPING_SNORLAX,
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.TALL_GRASS, [
|
||||
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.METROPOLIS, [
|
||||
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.FOREST, [
|
||||
MysteryEncounterType.SLEEPING_SNORLAX
|
||||
@ -43,7 +47,7 @@ export const mysteryEncountersByBiome = new Map<Biome, MysteryEncounterType[]>([
|
||||
|
||||
]],
|
||||
[Biome.BEACH, [
|
||||
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.LAKE, [
|
||||
|
||||
@ -67,10 +71,10 @@ export const mysteryEncountersByBiome = new Map<Biome, MysteryEncounterType[]>([
|
||||
|
||||
]],
|
||||
[Biome.MEADOW, [
|
||||
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.POWER_PLANT, [
|
||||
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.VOLCANO, [
|
||||
|
||||
@ -82,7 +86,7 @@ export const mysteryEncountersByBiome = new Map<Biome, MysteryEncounterType[]>([
|
||||
|
||||
]],
|
||||
[Biome.FACTORY, [
|
||||
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.RUINS, [
|
||||
|
||||
@ -97,7 +101,7 @@ export const mysteryEncountersByBiome = new Map<Biome, MysteryEncounterType[]>([
|
||||
|
||||
]],
|
||||
[Biome.CONSTRUCTION_SITE, [
|
||||
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.JUNGLE, [
|
||||
|
||||
@ -109,7 +113,7 @@ export const mysteryEncountersByBiome = new Map<Biome, MysteryEncounterType[]>([
|
||||
|
||||
]],
|
||||
[Biome.SLUM, [
|
||||
|
||||
MysteryEncounterType.DEPARTMENT_STORE_SALE
|
||||
]],
|
||||
[Biome.SNOWY_FOREST, [
|
||||
|
||||
@ -131,6 +135,8 @@ export function initMysteryEncounters() {
|
||||
allMysteryEncounters[MysteryEncounterType.FIGHT_OR_FLIGHT] = FightOrFlightEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.TRAINING_SESSION] = TrainingSessionEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.SLEEPING_SNORLAX] = SleepingSnorlaxEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.DEPARTMENT_STORE_SALE] = DepartmentStoreSaleEncounter;
|
||||
allMysteryEncounters[MysteryEncounterType.SHADY_VITAMIN_DEALER] = ShadyVitaminDealerEncounter;
|
||||
|
||||
// Append encounters that can occur in any biome to biome map
|
||||
const anyBiomeEncounters: MysteryEncounterType[] = Object.keys(MysteryEncounterType).filter(e => !isNaN(Number(e))).map(k => Number(k) as MysteryEncounterType);
|
||||
|
148
src/data/mystery-encounters/shady-vitamin-dealer.ts
Normal file
148
src/data/mystery-encounters/shady-vitamin-dealer.ts
Normal file
@ -0,0 +1,148 @@
|
||||
import BattleScene from "../../battle-scene";
|
||||
import {
|
||||
generateModifierType,
|
||||
leaveEncounterWithoutBattle,
|
||||
queueEncounterMessage,
|
||||
selectPokemonForOption,
|
||||
setCustomEncounterRewards,
|
||||
updatePlayerMoney,
|
||||
} from "#app/data/mystery-encounters/mystery-encounter-utils";
|
||||
import MysteryEncounter, {MysteryEncounterBuilder, MysteryEncounterTier} from "../mystery-encounter";
|
||||
import {MysteryEncounterType} from "#enums/mystery-encounter-type";
|
||||
import {
|
||||
HealthRatioRequirement,
|
||||
MoneyRequirement,
|
||||
StatusEffectRequirement,
|
||||
WaveCountRequirement
|
||||
} from "../mystery-encounter-requirements";
|
||||
import {MysteryEncounterOptionBuilder} from "../mystery-encounter-option";
|
||||
import {modifierTypes} from "#app/modifier/modifier-type";
|
||||
import {Species} from "#enums/species";
|
||||
import {randSeedInt} from "#app/utils";
|
||||
import Pokemon, {PlayerPokemon} from "#app/field/pokemon";
|
||||
import {StatusEffect} from "#app/data/status-effect";
|
||||
|
||||
export const ShadyVitaminDealerEncounter: MysteryEncounter = new MysteryEncounterBuilder()
|
||||
.withEncounterType(MysteryEncounterType.SHADY_VITAMIN_DEALER)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: Species.KROOKODILE.toString(),
|
||||
fileRoot: "pokemon",
|
||||
hasShadow: true,
|
||||
repeat: true,
|
||||
x: 10,
|
||||
y: -1
|
||||
},
|
||||
{
|
||||
spriteKey: "b2w2_veteran_m",
|
||||
fileRoot: "mystery-encounters",
|
||||
hasShadow: true,
|
||||
x: -10,
|
||||
y: 2
|
||||
}
|
||||
])
|
||||
.withSceneRequirement(new WaveCountRequirement([10, 180]))
|
||||
.withPrimaryPokemonRequirement(new StatusEffectRequirement([StatusEffect.NONE])) // Pokemon must not have status
|
||||
.withPrimaryPokemonRequirement(new HealthRatioRequirement([0.34, 1])) // Pokemon must have above 1/3rd HP
|
||||
.withOption(new MysteryEncounterOptionBuilder()
|
||||
.withSceneRequirement(new MoneyRequirement(0, 2)) // Wave scaling multiplier of 2 for cost
|
||||
.withPreOptionPhase(async (scene: BattleScene): Promise<boolean> => {
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||
// Update money
|
||||
updatePlayerMoney(scene, -(encounter.options[0].requirements[0] as MoneyRequirement).requiredMoney);
|
||||
// Calculate modifiers and dialogue tokens
|
||||
const modifiers = [
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER),
|
||||
generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER)
|
||||
];
|
||||
encounter.setDialogueToken("boost1", modifiers[0].name);
|
||||
encounter.setDialogueToken("boost2", modifiers[1].name);
|
||||
encounter.misc = {
|
||||
chosenPokemon: pokemon,
|
||||
modifiers: modifiers
|
||||
};
|
||||
};
|
||||
|
||||
// Only Pokemon that can gain benefits are unfainted with no status
|
||||
const selectableFilter = (pokemon: Pokemon) => {
|
||||
// If pokemon meets primary pokemon reqs, it can be selected
|
||||
const meetsReqs = encounter.pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||
if (!meetsReqs) {
|
||||
return "Pokémon must be healthy enough.";
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
||||
})
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
// Choose Cheap Option
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
const chosenPokemon = encounter.misc.chosenPokemon;
|
||||
const modifiers = encounter.misc.modifiers;
|
||||
|
||||
for (const modType of modifiers) {
|
||||
const modifier = modType.newModifier(chosenPokemon);
|
||||
await scene.addModifier(modifier, true, false, false, true);
|
||||
}
|
||||
scene.updateModifiers(true);
|
||||
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
})
|
||||
.withPostOptionPhase(async (scene: BattleScene) => {
|
||||
// Damage and status applied after dealer leaves (to make thematic sense)
|
||||
const encounter = scene.currentBattle.mysteryEncounter;
|
||||
const chosenPokemon = encounter.misc.chosenPokemon;
|
||||
|
||||
// Pokemon takes 1/3 max HP damage
|
||||
const damage = Math.round(chosenPokemon.getMaxHp() / 3);
|
||||
chosenPokemon.hp = Math.max(chosenPokemon.hp - damage, 0);
|
||||
|
||||
// Roll for poison (80%)
|
||||
if (randSeedInt(10) < 10) {
|
||||
if (chosenPokemon.trySetStatus(StatusEffect.TOXIC)) {
|
||||
// Toxic applied
|
||||
queueEncounterMessage(scene, "mysteryEncounter:shady_vitamin_dealer_bad_poison");
|
||||
} else {
|
||||
// Pokemon immune or something else prevents status
|
||||
queueEncounterMessage(scene, "mysteryEncounter:shady_vitamin_dealer_damage_only");
|
||||
}
|
||||
} else {
|
||||
queueEncounterMessage(scene, "mysteryEncounter:shady_vitamin_dealer_damage_only");
|
||||
}
|
||||
|
||||
chosenPokemon.updateInfo();
|
||||
})
|
||||
.build())
|
||||
.withOption(new MysteryEncounterOptionBuilder()
|
||||
.withSceneRequirement(new MoneyRequirement(0, 5)) // Wave scaling multiplier of 2 for cost
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
// Choose Expensive Option
|
||||
const modifiers = [];
|
||||
let i = 0;
|
||||
while (i < 3) {
|
||||
// 2/1 weight on base stat booster vs PP Up
|
||||
const roll = randSeedInt(3);
|
||||
if (roll === 0) {
|
||||
modifiers.push(modifierTypes.PP_UP);
|
||||
} else {
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
setCustomEncounterRewards(scene, { guaranteedModifierTypeFuncs: modifiers, fillRemaining: false});
|
||||
leaveEncounterWithoutBattle(scene);
|
||||
})
|
||||
.build())
|
||||
.withOption(new MysteryEncounterOptionBuilder()
|
||||
.withOptionPhase(async (scene: BattleScene) => {
|
||||
// Leave encounter with no rewards or exp
|
||||
leaveEncounterWithoutBattle(scene, true);
|
||||
return true;
|
||||
})
|
||||
.build())
|
||||
.build();
|
@ -1,7 +1,7 @@
|
||||
import BattleScene from "../../battle-scene";
|
||||
import {
|
||||
EnemyPartyConfig,
|
||||
EnemyPokemonConfig,
|
||||
EnemyPokemonConfig, generateModifierType,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle, queueEncounterMessage,
|
||||
setCustomEncounterRewards
|
||||
@ -12,7 +12,6 @@ import {MysteryEncounterType} from "#enums/mystery-encounter-type";
|
||||
import {MoveRequirement, WaveCountRequirement} from "../mystery-encounter-requirements";
|
||||
import {MysteryEncounterOptionBuilder} from "../mystery-encounter-option";
|
||||
import {
|
||||
ModifierTypeGenerator,
|
||||
ModifierTypeOption,
|
||||
modifierTypes
|
||||
} from "#app/modifier/modifier-type";
|
||||
@ -76,7 +75,8 @@ export const SleepingSnorlaxEncounter: MysteryEncounter = new MysteryEncounterBu
|
||||
const p = instance.primaryPokemon;
|
||||
p.status = new Status(StatusEffect.SLEEP, 0, 3);
|
||||
p.updateInfo(true);
|
||||
const sitrus = (modifierTypes.BERRY?.() as ModifierTypeGenerator).generateType(scene.getParty(), [BerryType.SITRUS]);
|
||||
// const sitrus = (modifierTypes.BERRY?.() as ModifierTypeGenerator).generateType(scene.getParty(), [BerryType.SITRUS]);
|
||||
const sitrus = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]);
|
||||
|
||||
setCustomEncounterRewards(scene, { guaranteedModifierTypeOptions: [new ModifierTypeOption(sitrus, 0)], fillRemaining: false});
|
||||
queueEncounterMessage(scene, "mysteryEncounter:sleeping_snorlax_option_2_bad_result");
|
||||
|
@ -1,7 +1,7 @@
|
||||
import BattleScene from "../../battle-scene";
|
||||
import {
|
||||
EnemyPartyConfig,
|
||||
getTextWithEncounterDialogueTokens,
|
||||
getTextWithEncounterDialogueTokensAndColor,
|
||||
initBattleWithEnemyConfig,
|
||||
selectPokemonForOption,
|
||||
setCustomEncounterRewards
|
||||
@ -128,7 +128,7 @@ export const TrainingSessionEncounter: MysteryEncounter = new MysteryEncounterBu
|
||||
scene.addModifier(mod, true, false, false, true);
|
||||
}
|
||||
scene.updateModifiers(true);
|
||||
scene.queueMessage(getTextWithEncounterDialogueTokens(scene, "mysteryEncounter:training_session_battle_finished_1"), null, true);
|
||||
scene.queueMessage(getTextWithEncounterDialogueTokensAndColor(scene, "mysteryEncounter:training_session_battle_finished_1"), null, true);
|
||||
};
|
||||
|
||||
setCustomEncounterRewards(scene, { fillRemaining: true }, null, onBeforeRewardsPhase);
|
||||
@ -174,7 +174,7 @@ export const TrainingSessionEncounter: MysteryEncounter = new MysteryEncounterBu
|
||||
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
||||
|
||||
const onBeforeRewardsPhase = () => {
|
||||
scene.queueMessage(getTextWithEncounterDialogueTokens(scene, "mysteryEncounter:training_session_battle_finished_2"), null, true);
|
||||
scene.queueMessage(getTextWithEncounterDialogueTokensAndColor(scene, "mysteryEncounter:training_session_battle_finished_2"), null, true);
|
||||
// Add the pokemon back to party with Nature change
|
||||
playerPokemon.setNature(encounter.misc.chosenNature);
|
||||
scene.gameData.setPokemonCaught(playerPokemon, false);
|
||||
@ -237,7 +237,7 @@ export const TrainingSessionEncounter: MysteryEncounter = new MysteryEncounterBu
|
||||
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
||||
|
||||
const onBeforeRewardsPhase = () => {
|
||||
scene.queueMessage(getTextWithEncounterDialogueTokens(scene, "mysteryEncounter:training_session_battle_finished_3"), null, true);
|
||||
scene.queueMessage(getTextWithEncounterDialogueTokensAndColor(scene, "mysteryEncounter:training_session_battle_finished_3"), null, true);
|
||||
// Add the pokemon back to party with ability change
|
||||
const abilityIndex = encounter.misc.abilityIndex;
|
||||
if (!!playerPokemon.getFusionSpeciesForm()) {
|
||||
|
@ -4,5 +4,7 @@ export enum MysteryEncounterType {
|
||||
DARK_DEAL,
|
||||
FIGHT_OR_FLIGHT,
|
||||
SLEEPING_SNORLAX,
|
||||
TRAINING_SESSION
|
||||
TRAINING_SESSION,
|
||||
DEPARTMENT_STORE_SALE,
|
||||
SHADY_VITAMIN_DEALER
|
||||
}
|
||||
|
@ -79,12 +79,12 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
||||
// Sprite offset from origin
|
||||
if (config.x || config.y) {
|
||||
if (config.x) {
|
||||
sprite.x = origin + config.x;
|
||||
tintSprite.x = origin + config.x;
|
||||
sprite.setPosition(origin + config.x, sprite.y);
|
||||
tintSprite.setPosition(origin + config.x, tintSprite.y);
|
||||
}
|
||||
if (config.y) {
|
||||
sprite.y = origin + config.y;
|
||||
tintSprite.y = origin + config.y;
|
||||
sprite.setPosition(sprite.x, config.y);
|
||||
tintSprite.setPosition(tintSprite.x, config.y);
|
||||
}
|
||||
} else {
|
||||
// Single sprite
|
||||
|
@ -1,17 +1,28 @@
|
||||
import {SimpleTranslationEntries} from "#app/interfaces/locales";
|
||||
|
||||
/**
|
||||
* Patterns that can be used:
|
||||
* '$' will be treated as a new line for Message and Dialogue strings
|
||||
* '@d{<number>}' will add a time delay to text animation for Message and Dialogue strings
|
||||
*
|
||||
* '@ec{<token>}' will auto-inject the matching token value for the specified Encounter
|
||||
*
|
||||
* '@ecCol[<TextStyle>]{<text>}' will auto-color the given text to a specified TextStyle (e.g. TextStyle.SUMMARY_GREEN)
|
||||
*
|
||||
* Any '(+)' or '(-)' type of tooltip will auto-color to green/blue respectively. THIS ONLY OCCURS FOR OPTION TOOLTIPS, NOWHERE ELSE
|
||||
* Other types of '(...)' tooltips will have to specify the text color manually by using '@ecCol[SUMMARY_GREEN]{<text>}' pattern
|
||||
*/
|
||||
export const mysteryEncounter: SimpleTranslationEntries = {
|
||||
// DO NOT REMOVE
|
||||
"unit_test_dialogue": "@ec{test}@ec{test} @ec{test@ec{test}} @ec{test1} @ec{test\} @ec{test\\} @ec{test\\\} {test}",
|
||||
|
||||
// Mysterious Encounters -- Common Tier
|
||||
|
||||
// Mystery Encounters -- Common Tier
|
||||
"mysterious_chest_intro_message": "You found...@d{32} a chest?",
|
||||
"mysterious_chest_title": "The Mysterious Chest",
|
||||
"mysterious_chest_description": "A beautifully ornamented chest stands on the ground. There must be something good inside... right?",
|
||||
"mysterious_chest_query": "Will you open it?",
|
||||
"mysterious_chest_option_1_label": "Open it",
|
||||
"mysterious_chest_option_1_tooltip": "(35%) Something terrible\n(40%) Okay Rewards\n(20%) Good Rewards\n(4%) Great Rewards\n(1%) Amazing Rewards",
|
||||
"mysterious_chest_option_1_tooltip": "@ecCol[SUMMARY_BLUE]{(35%) Something terrible}\n@ecCol[SUMMARY_GREEN]{(40%) Okay Rewards}\n@ecCol[SUMMARY_GREEN]{(20%) Good Rewards}\n@ecCol[SUMMARY_GREEN]{(4%) Great Rewards}\n@ecCol[SUMMARY_GREEN]{(1%) Amazing Rewards}",
|
||||
"mysterious_chest_option_2_label": "It's too risky, leave",
|
||||
"mysterious_chest_option_2_tooltip": "(-) No Rewards",
|
||||
"mysterious_chest_option_1_selected_message": "You open the chest to find...",
|
||||
@ -27,36 +38,82 @@ export const mysteryEncounter: SimpleTranslationEntries = {
|
||||
"fight_or_flight_title": "Fight or Flight",
|
||||
"fight_or_flight_description": "It looks like there's a strong Pokémon guarding an item. Battling is the straightforward approach, but this Pokémon looks strong. You could also try to sneak around, though the Pokémon might catch you.",
|
||||
"fight_or_flight_query": "What will you do?",
|
||||
"fight_or_flight_option_1_label": "Battle it",
|
||||
"fight_or_flight_option_1_tooltip": "(+) Hard Battle\n(+) New Item",
|
||||
"fight_or_flight_option_2_label": "Sneak around",
|
||||
"fight_or_flight_option_2_tooltip": "(35%) Steal Item\n(65%) Harder Battle",
|
||||
"fight_or_flight_option_1_label": "Battle the Pokémon",
|
||||
"fight_or_flight_option_1_tooltip": "(-) Hard Battle\n(+) New Item",
|
||||
"fight_or_flight_option_2_label": "Steal the item",
|
||||
"fight_or_flight_option_2_tooltip": "@ecCol[SUMMARY_GREEN]{(35%) Steal Item}\n@ecCol[SUMMARY_BLUE]{(65%) Harder Battle}",
|
||||
"fight_or_flight_option_2_steal_tooltip": "@ecCol[SUMMARY_GREEN]{(?) Use a Pokémon Move}",
|
||||
"fight_or_flight_option_3_label": "Leave",
|
||||
"fight_or_flight_option_3_tooltip": "(-) No Rewards",
|
||||
"fight_or_flight_option_1_selected_message": "You approach the\nPokémon without fear.",
|
||||
"fight_or_flight_option_2_good_result": `.@d{32}.@d{32}.@d{32}
|
||||
$You manage to sneak your way\npast and grab the item!`,
|
||||
"fight_or_flight_option_2_steal_result": `.@d{32}.@d{32}.@d{32}
|
||||
$Your @ec{thiefPokemon} helps you out and uses @ec{move}!
|
||||
$ You nabbed the item!`,
|
||||
"fight_or_flight_option_2_bad_result": `.@d{32}.@d{32}.@d{32}
|
||||
$The Pokémon catches you\nas you try to sneak around!`,
|
||||
"fight_or_flight_boss_enraged": "The opposing @ec{enemyPokemon} has become enraged!",
|
||||
"fight_or_flight_option_3_selected": "You leave the strong Pokémon\nwith its prize and continue on.",
|
||||
|
||||
// Mysterious Encounters -- Uncommon Tier
|
||||
"department_store_sale_intro_message": "It's a lady with a ton of shopping bags.",
|
||||
"department_store_sale_speaker": "Shopper",
|
||||
"department_store_sale_intro_dialogue": `Hello! Are you here for\nthe amazing sales too?
|
||||
$There's a special coupon that you can\nredeem for a free item during the sale!
|
||||
$I have an extra one. Here you go!`,
|
||||
"department_store_sale_title": "Department Store Sale",
|
||||
"department_store_sale_description": "There is merchandise in every direction! It looks like there are 4 counters where you can redeem the coupon for various items. The possibilities are endless!",
|
||||
"department_store_sale_query": "Which counter will you go to?",
|
||||
"department_store_sale_option_1_label": "TM Counter",
|
||||
"department_store_sale_option_1_tooltip": "(+) TM Shop",
|
||||
"department_store_sale_option_2_label": "Vitamin Counter",
|
||||
"department_store_sale_option_2_tooltip": "(+) Vitamin Shop",
|
||||
"department_store_sale_option_3_label": "Battle Item Counter",
|
||||
"department_store_sale_option_3_tooltip": "(+) X Item Shop",
|
||||
"department_store_sale_option_4_label": "Pokéball Counter",
|
||||
"department_store_sale_option_4_tooltip": "(+) Pokéball Shop",
|
||||
"department_store_sale_outro": "What a deal! You should shop there more often.",
|
||||
|
||||
"shady_vitamin_dealer_intro_message": "A man in a dark coat approaches you.",
|
||||
"shady_vitamin_dealer_speaker": "Shady Salesman",
|
||||
"shady_vitamin_dealer_intro_dialogue": `.@d{16}.@d{16}.@d{16}
|
||||
$I've got the goods if you've got the money.
|
||||
$Make sure your Pokémon can handle it though.`,
|
||||
"shady_vitamin_dealer_title": "The Vitamin Dealer",
|
||||
"shady_vitamin_dealer_description": "The man opens his jacket to reveal some Pokémon vitamins. The numbers he quotes seem like a really good deal. Almost too good...\nHe offers two package deals to choose from.",
|
||||
"shady_vitamin_dealer_query": "Which deal will choose?",
|
||||
"shady_vitamin_dealer_option_1_label": "The Cheap Deal",
|
||||
"shady_vitamin_dealer_option_1_tooltip": "(-) Pay @ec{option1Money}\n(-) Side Effects?\n(+) Chosen Pokémon Gains 2 Random Vitamins",
|
||||
"shady_vitamin_dealer_option_2_label": "The Pricey Deal",
|
||||
"shady_vitamin_dealer_option_2_tooltip": "(-) Pay @ec{option2Money}\n(-) Side Effects?\n(+) Chosen Pokémon Gains 2 Random Vitamins",
|
||||
"shady_vitamin_dealer_option_selected": `The man hands you two bottles and quickly disappears.
|
||||
$@ec{selectedPokemon} gained @ec{boost1} and @ec{boost2} boosts!`,
|
||||
"shady_vitamin_dealer_damage_only": `But the medicine had some side effects!
|
||||
$Your @ec{selectedPokemon} takes some damage...`,
|
||||
"shady_vitamin_dealer_bad_poison": `But the medicine had some side effects!
|
||||
$Your @ec{selectedPokemon} takes some damage\nand becomes badly poisoned...`,
|
||||
"shady_vitamin_dealer_poison": `But the medicine had some side effects!
|
||||
$Your @ec{selectedPokemon} becomes poisoned...`,
|
||||
"shady_vitamin_dealer_option_3_label": "Leave",
|
||||
"shady_vitamin_dealer_option_3_tooltip": "(-) No Rewards",
|
||||
"shady_vitamin_dealer_outro_good": "Looks like there were no side-effects this time.",
|
||||
|
||||
// Mystery Encounters -- Uncommon Tier
|
||||
|
||||
"mysterious_challengers_intro_message": "Mysterious challengers have appeared!",
|
||||
"mysterious_challengers_title": "Mysterious Challengers",
|
||||
"mysterious_challengers_description": "If you defeat a challenger, you might impress them enough to receive a boon. But some look tough, are you up to the challenge?",
|
||||
"mysterious_challengers_query": "Who will you battle?",
|
||||
"mysterious_challengers_option_1_label": "A clever, mindful foe",
|
||||
"mysterious_challengers_option_1_tooltip": "(+) Standard Battle\n(+) Move Item Rewards",
|
||||
"mysterious_challengers_option_1_tooltip": "(-) Standard Battle\n(+) Move Item Rewards",
|
||||
"mysterious_challengers_option_2_label": "A strong foe",
|
||||
"mysterious_challengers_option_2_tooltip": "(+) Hard Battle\n(+) Good Rewards",
|
||||
"mysterious_challengers_option_2_tooltip": "(-) Hard Battle\n(+) Good Rewards",
|
||||
"mysterious_challengers_option_3_label": "The mightiest foe",
|
||||
"mysterious_challengers_option_3_tooltip": "(+) Brutal Battle\n(+) Great Rewards",
|
||||
"mysterious_challengers_option_3_tooltip": "(-) Brutal Battle\n(+) Great Rewards",
|
||||
"mysterious_challengers_option_selected_message": "The trainer steps forward...",
|
||||
"mysterious_challengers_outro_win": "The mysterious challenger was defeated!",
|
||||
|
||||
// Mysterious Encounters -- Rare Tier
|
||||
// Mystery Encounters -- Rare Tier
|
||||
"training_session_intro_message": "You've come across some\ntraining tools and supplies.",
|
||||
"training_session_title": "Training Session",
|
||||
"training_session_description": "These supplies look like they could be used to train a member of your party! There are a few ways you could train your Pokémon, by battling against it with the rest of your team.",
|
||||
@ -78,7 +135,7 @@ export const mysteryEncounter: SimpleTranslationEntries = {
|
||||
$Its ability was changed to @ec{ability}!`,
|
||||
"training_session_outro_win": "That was a successful training session!",
|
||||
|
||||
// Mysterious Encounters -- Super Rare Tier
|
||||
// Mystery Encounters -- Super Rare Tier
|
||||
|
||||
"dark_deal_intro_message": "A strange man in a tattered coat\nstands in your way...",
|
||||
"dark_deal_speaker": "Shady Guy",
|
||||
@ -108,9 +165,9 @@ export const mysteryEncounter: SimpleTranslationEntries = {
|
||||
"sleeping_snorlax_description": "You could attack it to try and get it to move, or simply wait for it to wake up.",
|
||||
"sleeping_snorlax_query": "What will you do?",
|
||||
"sleeping_snorlax_option_1_label": "Fight it",
|
||||
"sleeping_snorlax_option_1_tooltip": "(+) Fight Sleeping Snorlax",
|
||||
"sleeping_snorlax_option_1_tooltip": "(-) Fight Sleeping Snorlax",
|
||||
"sleeping_snorlax_option_2_label": "Wait for it to move",
|
||||
"sleeping_snorlax_option_2_tooltip": "(75%) Wait a short time\n(25%) Wait a long time",
|
||||
"sleeping_snorlax_option_2_tooltip": "@ecCol[SUMMARY_BLUE]{(75%) Wait a short time}\n@ecCol[SUMMARY_BLUE]{(25%) Wait a long time}",
|
||||
"sleeping_snorlax_option_3_label": "Steal",
|
||||
"sleeping_snorlax_option_3_tooltip": "(+) Leftovers",
|
||||
"sleeping_snorlax_option_3_disabled_tooltip": "Your Pokémon need to know certain moves to choose this",
|
||||
|
@ -118,9 +118,9 @@ export const EGG_GACHA_PULL_COUNT_OVERRIDE: number = 0;
|
||||
*/
|
||||
|
||||
// 1 to 256, set to null to ignore
|
||||
export const MYSTERY_ENCOUNTER_RATE_OVERRIDE: number = null;
|
||||
export const MYSTERY_ENCOUNTER_RATE_OVERRIDE: number = 256;
|
||||
export const MYSTERY_ENCOUNTER_TIER_OVERRIDE: MysteryEncounterTier = null;
|
||||
export const MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType = null;
|
||||
export const MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType = MysteryEncounterType.SHADY_VITAMIN_DEALER;
|
||||
|
||||
/**
|
||||
* MODIFIER / ITEM OVERRIDES
|
||||
|
@ -3,7 +3,7 @@ import BattleScene from "../battle-scene";
|
||||
import { Phase } from "../phase";
|
||||
import { Mode } from "../ui/ui";
|
||||
import {
|
||||
getTextWithEncounterDialogueTokens
|
||||
getTextWithEncounterDialogueTokensAndColor
|
||||
} from "../data/mystery-encounters/mystery-encounter-utils";
|
||||
import { CheckSwitchPhase, NewBattlePhase, PostSummonPhase, ReturnPhase, ScanIvsPhase, SummonPhase, ToggleDoublePositionPhase } from "../phases";
|
||||
import MysteryEncounterOption from "../data/mystery-encounter-option";
|
||||
@ -89,9 +89,9 @@ export class MysteryEncounterPhase extends Phase {
|
||||
const nextAction = i === selectedDialogue.length - 1 ? endDialogueAndContinueEncounter : showNextDialogue;
|
||||
const dialogue = selectedDialogue[i];
|
||||
let title: string = null;
|
||||
const text: string = getTextWithEncounterDialogueTokens(this.scene, dialogue.text);
|
||||
const text: string = getTextWithEncounterDialogueTokensAndColor(this.scene, dialogue.text);
|
||||
if (dialogue.speaker) {
|
||||
title = getTextWithEncounterDialogueTokens(this.scene, dialogue.speaker);
|
||||
title = getTextWithEncounterDialogueTokensAndColor(this.scene, dialogue.speaker);
|
||||
}
|
||||
|
||||
if (title) {
|
||||
@ -451,9 +451,9 @@ export class PostMysteryEncounterPhase extends Phase {
|
||||
const nextAction = i === outroDialogue.length - 1 ? endPhase : showNextDialogue;
|
||||
const dialogue = outroDialogue[i];
|
||||
let title: string = null;
|
||||
const text: string = getTextWithEncounterDialogueTokens(this.scene, dialogue.text);
|
||||
const text: string = getTextWithEncounterDialogueTokensAndColor(this.scene, dialogue.text);
|
||||
if (dialogue.speaker) {
|
||||
title = getTextWithEncounterDialogueTokens(this.scene, dialogue.speaker);
|
||||
title = getTextWithEncounterDialogueTokensAndColor(this.scene, dialogue.speaker);
|
||||
}
|
||||
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
|
@ -3,7 +3,7 @@ import GameManager from "#app/test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import {
|
||||
getHighestLevelPlayerPokemon, getLowestLevelPlayerPokemon,
|
||||
getRandomPlayerPokemon, getRandomSpeciesByStarterTier, getTextWithEncounterDialogueTokens,
|
||||
getRandomPlayerPokemon, getRandomSpeciesByStarterTier, getTextWithEncounterDialogueTokensAndColor,
|
||||
koPlayerPokemon, queueEncounterMessage, showEncounterDialogue, showEncounterText,
|
||||
} from "#app/data/mystery-encounters/mystery-encounter-utils";
|
||||
import {initSceneWithoutEncounterPhase} from "#test/utils/gameManagerUtils";
|
||||
@ -272,12 +272,12 @@ describe("Mystery Encounter Utils", () => {
|
||||
});
|
||||
|
||||
describe("getTextWithEncounterDialogueTokens", () => {
|
||||
it("injects dialogue tokens", () => {
|
||||
it("injects dialogue tokens and color styling", () => {
|
||||
scene.currentBattle.mysteryEncounter = new MysteryEncounter(null);
|
||||
scene.currentBattle.mysteryEncounter.setDialogueToken("test", "value");
|
||||
|
||||
const result = getTextWithEncounterDialogueTokens(scene, "mysteryEncounter:unit_test_dialogue");
|
||||
expect(result).toEqual("valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}");
|
||||
const result = getTextWithEncounterDialogueTokensAndColor(scene, "mysteryEncounter:unit_test_dialogue");
|
||||
expect(result).toEqual("[color=#f8f8f8][shadow=#6b5a73]valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}[/color][/shadow]");
|
||||
});
|
||||
|
||||
it("can perform nested dialogue token injection", () => {
|
||||
@ -285,8 +285,8 @@ describe("Mystery Encounter Utils", () => {
|
||||
scene.currentBattle.mysteryEncounter.setDialogueToken("test", "value");
|
||||
scene.currentBattle.mysteryEncounter.setDialogueToken("testvalue", "new");
|
||||
|
||||
const result = getTextWithEncounterDialogueTokens(scene, "mysteryEncounter:unit_test_dialogue");
|
||||
expect(result).toEqual("valuevalue new @ec{test1} value @ec{test\\} @ec{test\\} {test}");
|
||||
const result = getTextWithEncounterDialogueTokensAndColor(scene, "mysteryEncounter:unit_test_dialogue");
|
||||
expect(result).toEqual("[color=#f8f8f8][shadow=#6b5a73]valuevalue new @ec{test1} value @ec{test\\} @ec{test\\} {test}[/color][/shadow]");
|
||||
});
|
||||
});
|
||||
|
||||
@ -298,7 +298,7 @@ describe("Mystery Encounter Utils", () => {
|
||||
const phaseSpy = vi.spyOn(game.scene, "unshiftPhase");
|
||||
|
||||
queueEncounterMessage(scene, "mysteryEncounter:unit_test_dialogue");
|
||||
expect(spy).toHaveBeenCalledWith("valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}", null, true);
|
||||
expect(spy).toHaveBeenCalledWith("[color=#f8f8f8][shadow=#6b5a73]valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}[/color][/shadow]", null, true);
|
||||
expect(phaseSpy).toHaveBeenCalledWith(expect.any(MessagePhase));
|
||||
});
|
||||
});
|
||||
@ -310,7 +310,7 @@ describe("Mystery Encounter Utils", () => {
|
||||
const spy = vi.spyOn(game.scene.ui, "showText");
|
||||
|
||||
showEncounterText(scene, "mysteryEncounter:unit_test_dialogue");
|
||||
expect(spy).toHaveBeenCalledWith("valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}", null, expect.any(Function), 0, true);
|
||||
expect(spy).toHaveBeenCalledWith("[color=#f8f8f8][shadow=#6b5a73]valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}[/color][/shadow]", null, expect.any(Function), 0, true);
|
||||
});
|
||||
});
|
||||
|
||||
@ -321,7 +321,7 @@ describe("Mystery Encounter Utils", () => {
|
||||
const spy = vi.spyOn(game.scene.ui, "showDialogue");
|
||||
|
||||
showEncounterDialogue(scene, "mysteryEncounter:unit_test_dialogue", "mysteryEncounter:unit_test_dialogue");
|
||||
expect(spy).toHaveBeenCalledWith("valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}", "valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}", null, undefined, 0, 0);
|
||||
expect(spy).toHaveBeenCalledWith("[color=#f8f8f8][shadow=#6b5a73]valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}[/color][/shadow]", "[color=#f8f8f8][shadow=#6b5a73]valuevalue @ec{testvalue} @ec{test1} value @ec{test\\} @ec{test\\} {test}[/color][/shadow]", null, undefined, 0, 0);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -84,7 +84,7 @@ describe("Mystery Encounter Phases", () => {
|
||||
expect(messageSpy).toHaveBeenCalledTimes(2);
|
||||
expect(dialogueSpy).toHaveBeenCalledWith("What's this?", "???", null, expect.any(Function));
|
||||
expect(messageSpy).toHaveBeenCalledWith("Mysterious challengers have appeared!", null, expect.any(Function), 750, true);
|
||||
expect(messageSpy).toHaveBeenCalledWith("The trainer steps forward...", null, expect.any(Function), 750, true);
|
||||
expect(messageSpy).toHaveBeenCalledWith("[color=#f8f8f8][shadow=#6b5a73]The trainer steps forward...[/color][/shadow]", null, expect.any(Function), 750, true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import { addTextObject, TextStyle } from "./text";
|
||||
import { Mode } from "./ui";
|
||||
import {addBBCodeTextObject, getBBCodeFrag, TextStyle} from "./text";
|
||||
import {Mode} from "./ui";
|
||||
import UiHandler from "./ui-handler";
|
||||
import { Button } from "#enums/buttons";
|
||||
import { addWindow, WindowVariant } from "./ui-theme";
|
||||
import i18next from "i18next";
|
||||
import { MysteryEncounterPhase } from "../phases/mystery-encounter-phase";
|
||||
import { PartyUiMode } from "./party-ui-handler";
|
||||
import {Button} from "#enums/buttons";
|
||||
import {addWindow, WindowVariant} from "./ui-theme";
|
||||
import {MysteryEncounterPhase} from "../phases/mystery-encounter-phase";
|
||||
import {PartyUiMode} from "./party-ui-handler";
|
||||
import MysteryEncounterOption from "../data/mystery-encounter-option";
|
||||
import * as Utils from "../utils";
|
||||
import { getPokeballAtlasKey } from "../data/pokeball";
|
||||
import {isNullOrUndefined} from "../utils";
|
||||
import {getPokeballAtlasKey} from "../data/pokeball";
|
||||
import {getTextWithEncounterDialogueTokensAndColor} from "#app/data/mystery-encounters/mystery-encounter-utils";
|
||||
|
||||
export default class MysteryEncounterUiHandler extends UiHandler {
|
||||
private cursorContainer: Phaser.GameObjects.Container;
|
||||
@ -298,9 +298,9 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
||||
this.filteredEncounterOptions = mysteryEncounter.options;
|
||||
this.optionsMeetsReqs = [];
|
||||
|
||||
const titleText: string = i18next.t(mysteryEncounter.dialogue.encounterOptionsDialogue.title);
|
||||
const descriptionText: string = i18next.t(mysteryEncounter.dialogue.encounterOptionsDialogue.description);
|
||||
const queryText: string = i18next.t(mysteryEncounter.dialogue.encounterOptionsDialogue.query);
|
||||
const titleText: string = getTextWithEncounterDialogueTokensAndColor(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue.title, TextStyle.TOOLTIP_TITLE);
|
||||
const descriptionText: string = getTextWithEncounterDialogueTokensAndColor(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue.description, TextStyle.TOOLTIP_CONTENT);
|
||||
const queryText: string = getTextWithEncounterDialogueTokensAndColor(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue.query, TextStyle.TOOLTIP_CONTENT);
|
||||
|
||||
// Clear options container (except cursor)
|
||||
this.optionsContainer.removeAll();
|
||||
@ -310,16 +310,17 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
||||
let optionText;
|
||||
switch (this.filteredEncounterOptions.length) {
|
||||
case 2:
|
||||
optionText = addTextObject(this.scene, i % 2 === 0 ? 0 : 100, 8, "-", TextStyle.WINDOW, { wordWrap: { width: 558 }, fontSize: "80px", lineSpacing: -8 });
|
||||
optionText = addBBCodeTextObject(this.scene, i % 2 === 0 ? 0 : 100, 8, "-", TextStyle.WINDOW, { wordWrap: { width: 558 }, fontSize: "80px", lineSpacing: -8 });
|
||||
break;
|
||||
case 3:
|
||||
optionText = addTextObject(this.scene, i % 2 === 0 ? 0 : 100, i < 2 ? 0 : 16, "-", TextStyle.WINDOW, { wordWrap: { width: 558 }, fontSize: "80px", lineSpacing: -8 });
|
||||
optionText = addBBCodeTextObject(this.scene, i % 2 === 0 ? 0 : 100, i < 2 ? 0 : 16, "-", TextStyle.WINDOW, { wordWrap: { width: 558 }, fontSize: "80px", lineSpacing: -8 });
|
||||
break;
|
||||
case 4:
|
||||
optionText = addTextObject(this.scene, i % 2 === 0 ? 0 : 100, i < 2 ? 0 : 16, "-", TextStyle.WINDOW, { wordWrap: { width: 558 }, fontSize: "80px", lineSpacing: -8 });
|
||||
optionText = addBBCodeTextObject(this.scene, i % 2 === 0 ? 0 : 100, i < 2 ? 0 : 16, "-", TextStyle.WINDOW, { wordWrap: { width: 558 }, fontSize: "80px", lineSpacing: -8 });
|
||||
break;
|
||||
}
|
||||
const text = i18next.t(mysteryEncounter.dialogue.encounterOptionsDialogue.options[i].buttonLabel);
|
||||
const option = mysteryEncounter.dialogue.encounterOptionsDialogue.options[i];
|
||||
const text = getTextWithEncounterDialogueTokensAndColor(this.scene, option.buttonLabel, option.style ? option.style : TextStyle.WINDOW);
|
||||
if (text) {
|
||||
optionText.setText(text);
|
||||
}
|
||||
@ -336,11 +337,11 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
||||
}
|
||||
|
||||
// View Party Button
|
||||
const viewPartyText = addTextObject(this.scene, 256, -24, "View Party", TextStyle.PARTY);
|
||||
const viewPartyText = addBBCodeTextObject(this.scene, 256, -24, getBBCodeFrag("View Party", TextStyle.PARTY), TextStyle.PARTY);
|
||||
this.optionsContainer.add(viewPartyText);
|
||||
|
||||
// Description Window
|
||||
const titleTextObject = addTextObject(this.scene, 0, 0, titleText, TextStyle.TOOLTIP_TITLE, { wordWrap: { width: 750 }, align: "center", lineSpacing: -8 });
|
||||
const titleTextObject = addBBCodeTextObject(this.scene, 0, 0, titleText, TextStyle.TOOLTIP_TITLE, { wordWrap: { width: 750 }, align: "center", lineSpacing: -8 });
|
||||
this.descriptionContainer.add(titleTextObject);
|
||||
titleTextObject.setPosition(72 - titleTextObject.displayWidth / 2, 5.5);
|
||||
|
||||
@ -348,7 +349,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
||||
const ballType = getPokeballAtlasKey(mysteryEncounter.encounterTier as number);
|
||||
this.rarityBall.setTexture("pb", ballType);
|
||||
|
||||
const descriptionTextObject = addTextObject(this.scene, 6, 25, descriptionText, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } });
|
||||
const descriptionTextObject = addBBCodeTextObject(this.scene, 6, 25, descriptionText, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } });
|
||||
|
||||
// Sets up the mask that hides the description text to give an illusion of scrolling
|
||||
const descriptionTextMaskRect = this.scene.make.graphics({});
|
||||
@ -382,8 +383,9 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
||||
|
||||
this.descriptionContainer.add(descriptionTextObject);
|
||||
|
||||
const queryTextObject = addTextObject(this.scene, 65 - (queryText.length), 90, queryText, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } });
|
||||
const queryTextObject = addBBCodeTextObject(this.scene, 0, 0, queryText, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } });
|
||||
this.descriptionContainer.add(queryTextObject);
|
||||
queryTextObject.setPosition(75 - queryTextObject.displayWidth / 2, 90);
|
||||
|
||||
// Slide in description container
|
||||
if (slideInDescription) {
|
||||
@ -412,15 +414,20 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
||||
|
||||
const mysteryEncounter = this.scene.currentBattle.mysteryEncounter;
|
||||
let text;
|
||||
if (!this.optionsMeetsReqs[cursor] && mysteryEncounter.dialogue.encounterOptionsDialogue.options[cursor].disabledTooltip) {
|
||||
text = i18next.t(mysteryEncounter.dialogue.encounterOptionsDialogue.options[cursor].disabledTooltip);
|
||||
const option = mysteryEncounter.dialogue.encounterOptionsDialogue.options[cursor];
|
||||
if (!this.optionsMeetsReqs[cursor] && option.disabledTooltip) {
|
||||
text = getTextWithEncounterDialogueTokensAndColor(this.scene, option.disabledTooltip, TextStyle.TOOLTIP_CONTENT);
|
||||
} else {
|
||||
text = i18next.t(mysteryEncounter.dialogue.encounterOptionsDialogue.options[cursor].buttonTooltip);
|
||||
text = getTextWithEncounterDialogueTokensAndColor(this.scene, option.buttonTooltip, TextStyle.TOOLTIP_CONTENT);
|
||||
}
|
||||
|
||||
// Auto-color options green/blue for good/bad by looking for (+)/(-)
|
||||
const primaryStyleString = [...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))][0];
|
||||
text = text.replace(/(\([^\(]*\+\)[^\(\[]*)/gi, substring => "[/color][/shadow]" + getBBCodeFrag(substring, TextStyle.SUMMARY_GREEN) + "[/color][/shadow]" + primaryStyleString);
|
||||
text = text.replace(/(\([^\(]*\-\)[^\(\[]*)/gi, substring => "[/color][/shadow]" + getBBCodeFrag(substring, TextStyle.SUMMARY_BLUE) + "[/color][/shadow]" + primaryStyleString);
|
||||
|
||||
if (text) {
|
||||
const tooltipTextObject = addTextObject(this.scene, 6, 7, text, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 600 }, fontSize: "72px" });
|
||||
const tooltipTextObject = addBBCodeTextObject(this.scene, 6, 7, text, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 600 }, fontSize: "72px" });
|
||||
this.tooltipContainer.add(tooltipTextObject);
|
||||
|
||||
// Sets up the mask that hides the description text to give an illusion of scrolling
|
||||
|
Loading…
x
Reference in New Issue
Block a user