update visuals loading for safari and stat trainer visuals
This commit is contained in:
parent
3cb64cfa1f
commit
c9aab45b94
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "safarizone.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 105,
|
||||||
|
"h": 83
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "safarizone.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": false,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 103,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"w": 103,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 103,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:f07e2d44900011048b658765e193a86c:3d91036b9c3943256dd1e4712042ec59:d467a15bea042bd0d310f1cce7d9791f$"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,272 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "buck.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 120,
|
||||||
|
"h": 78
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 4,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 76
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 18,
|
||||||
|
"y": 8,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00010.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 15,
|
||||||
|
"y": 8,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00011.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 13,
|
||||||
|
"y": 8,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 1,
|
||||||
|
"w": 44,
|
||||||
|
"h": 72
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 34,
|
||||||
|
"y": 5,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 84,
|
||||||
|
"y": 1,
|
||||||
|
"w": 35,
|
||||||
|
"h": 75
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:bedd2f8769ba9b1430dc6479e53194f2:49cc02f839fd834c23053d7c92ce9e20:3347efe478119141b0e3e6eccdecd0f5$"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,398 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "cheryll.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 154,
|
||||||
|
"h": 83
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 25,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 25,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 26,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 26,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00010.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 44,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00011.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 44,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00012.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 24,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 44,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00013.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 24,
|
||||||
|
"y": 0,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 44,
|
||||||
|
"y": 1,
|
||||||
|
"w": 41,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00014.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 0,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 87,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00015.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 0,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 87,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00016.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 26,
|
||||||
|
"y": 0,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 87,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00017.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 26,
|
||||||
|
"y": 0,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 87,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 21,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 21,
|
||||||
|
"y": 0,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 122,
|
||||||
|
"y": 1,
|
||||||
|
"w": 31,
|
||||||
|
"h": 81
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:dfcf7aedbd588c4e42427a2e17c171bf:206549943a0e3325d20a017ef01eefee:a233cd27590422717866c66e366b68fb$"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,104 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "marley.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 102,
|
||||||
|
"h": 82
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 0,
|
||||||
|
"w": 30,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 30,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 79
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 79
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 27,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 79
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 33,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 79
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 25,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 79
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 68,
|
||||||
|
"y": 1,
|
||||||
|
"w": 33,
|
||||||
|
"h": 79
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:4b2edf4443e93acdceffb1d86ae96a96:1019efd49d236cd477b7e9d786d99ffe:d7dbd866d03c506dac6716ab23e62168$"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,482 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "mira.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 57,
|
||||||
|
"h": 205
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 10,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 11,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00011.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 10,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00012.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 11,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00018.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 10,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00019.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 11,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 55,
|
||||||
|
"h": 65
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 13,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 68,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 13,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 68,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 21,
|
||||||
|
"y": 12,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 68,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 10,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 68,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00013.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 10,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 68,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00014.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 21,
|
||||||
|
"y": 12,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 68,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00015.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 22,
|
||||||
|
"y": 13,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 68,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00016.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 21,
|
||||||
|
"y": 12,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 68,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00017.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 20,
|
||||||
|
"y": 10,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 68,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 12,
|
||||||
|
"y": 10,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 137,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 12,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 137,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 13,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 137,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 12,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 137,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00010.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 12,
|
||||||
|
"y": 10,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 137,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00020.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 12,
|
||||||
|
"y": 10,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 137,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00021.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 12,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 137,
|
||||||
|
"w": 46,
|
||||||
|
"h": 67
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:fa0a6e132823f8a832e4a5a4f7f22e71:0662a4931405bc13b67679afcad37bac:f9bd0c7364e7f214bd64723bef0b3fe9$"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,461 @@
|
||||||
|
{
|
||||||
|
"textures": [
|
||||||
|
{
|
||||||
|
"image": "riley.png",
|
||||||
|
"format": "RGBA8888",
|
||||||
|
"size": {
|
||||||
|
"w": 59,
|
||||||
|
"h": 246
|
||||||
|
},
|
||||||
|
"scale": 1,
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"filename": "0000.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0003.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 9,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0004.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0006.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0008.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00010.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00012.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00014.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00016.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00018.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00020.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 10,
|
||||||
|
"y": 0,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"w": 57,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0005.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 83,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0007.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 83,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0009.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 83,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00011.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 83,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00013.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 83,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00015.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 83,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00017.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 83,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "00019.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 11,
|
||||||
|
"y": 0,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 83,
|
||||||
|
"w": 56,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0001.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 30,
|
||||||
|
"y": 0,
|
||||||
|
"w": 39,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 165,
|
||||||
|
"w": 39,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "0002.png",
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"sourceSize": {
|
||||||
|
"w": 80,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"spriteSourceSize": {
|
||||||
|
"x": 29,
|
||||||
|
"y": 0,
|
||||||
|
"w": 39,
|
||||||
|
"h": 80
|
||||||
|
},
|
||||||
|
"frame": {
|
||||||
|
"x": 1,
|
||||||
|
"y": 165,
|
||||||
|
"w": 39,
|
||||||
|
"h": 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"app": "https://www.codeandweb.com/texturepacker",
|
||||||
|
"version": "3.0",
|
||||||
|
"smartupdate": "$TexturePacker:SmartUpdate:d0f27c1a776dc776dbc730ec409fafad:7a665e1bfee26403e5d49912c4dad042:cb98d9ba5e960a1d670368dad1073434$"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -665,6 +665,76 @@ export const trainerTypeDialogue: TrainerTypeDialogue = {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[TrainerType.BUCK]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_buck.encounter.1",
|
||||||
|
"dialogue:stat_trainer_buck.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_buck.victory.1"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_buck.defeat.1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.CHERYL]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_cheryl.encounter.1",
|
||||||
|
"dialogue:stat_trainer_cheryl.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_cheryl.victory.1"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_cheryl.defeat.1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.MARLEY]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_marley.encounter.1",
|
||||||
|
"dialogue:stat_trainer_marley.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_marley.victory.1"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_marley.defeat.1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.MIRA]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_mira.encounter.1",
|
||||||
|
"dialogue:stat_trainer_mira.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_mira.victory.1"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_mira.defeat.1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[TrainerType.RILEY]: [
|
||||||
|
{
|
||||||
|
encounter: [
|
||||||
|
"dialogue:stat_trainer_riley.encounter.1",
|
||||||
|
"dialogue:stat_trainer_riley.encounter.2"
|
||||||
|
],
|
||||||
|
victory: [
|
||||||
|
"dialogue:stat_trainer_riley.victory.1"
|
||||||
|
],
|
||||||
|
defeat: [
|
||||||
|
"dialogue:stat_trainer_riley.defeat.1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
[TrainerType.BROCK]: {
|
[TrainerType.BROCK]: {
|
||||||
encounter: [
|
encounter: [
|
||||||
"dialogue:brock.encounter.1",
|
"dialogue:brock.encounter.1",
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
import { EnemyPartyConfig, initBattleWithEnemyConfig, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
|
import { trainerConfigs, } from "#app/data/trainer-config";
|
||||||
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { randSeedInt } from "#app/utils";
|
||||||
|
|
||||||
|
/** the i18n namespace for the encounter */
|
||||||
|
const namespace = "mysteryEncounter:aTrainersTest";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Trainer's Test encounter.
|
||||||
|
* @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/115 | GitHub Issue #115}
|
||||||
|
* @see For biome requirements check {@linkcode mysteryEncountersByBiome}
|
||||||
|
*/
|
||||||
|
export const ATrainersTestEncounter: IMysteryEncounter =
|
||||||
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.A_TRAINERS_TEST)
|
||||||
|
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||||
|
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||||
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
|
.withIntroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}:intro`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.withOnInit((scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
|
|
||||||
|
// Randomly pick from 1 of the 5 stat trainers to spawn
|
||||||
|
let trainerType: TrainerType;
|
||||||
|
let spriteKeys;
|
||||||
|
switch (randSeedInt(5)) {
|
||||||
|
default:
|
||||||
|
case 0:
|
||||||
|
trainerType = TrainerType.BUCK;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.CLAYDOL);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
trainerType = TrainerType.CHERYL;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.BLISSEY);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
trainerType = TrainerType.MARLEY;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.ARCANINE);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
trainerType = TrainerType.MIRA;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.ALAKAZAM, false, 1);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
trainerType = TrainerType.RILEY;
|
||||||
|
spriteKeys = getSpriteKeysFromSpecies(Species.LUCARIO, false, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
encounter.misc = { trainerType };
|
||||||
|
const trainerConfig = trainerConfigs[trainerType].copy();
|
||||||
|
const trainerSpriteKey = trainerConfig.getSpriteKey();
|
||||||
|
encounter.enemyPartyConfigs.push({
|
||||||
|
levelAdditiveMultiplier: 1,
|
||||||
|
trainerConfig: trainerConfig
|
||||||
|
});
|
||||||
|
|
||||||
|
encounter.spriteConfigs = [
|
||||||
|
{
|
||||||
|
spriteKey: spriteKeys.spriteKey,
|
||||||
|
fileRoot: spriteKeys.fileRoot,
|
||||||
|
hasShadow: true,
|
||||||
|
repeat: true,
|
||||||
|
isPokemon: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spriteKey: trainerSpriteKey,
|
||||||
|
fileRoot: "trainer",
|
||||||
|
hasShadow: true,
|
||||||
|
disableAnimation: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.withTitle(`${namespace}:title`)
|
||||||
|
.withDescription(`${namespace}:description`)
|
||||||
|
.withQuery(`${namespace}:query`)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}:option:1:label`,
|
||||||
|
buttonTooltip: `${namespace}:option:1:tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}:option:selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
|
// Spawn standard trainer battle with memory mushroom reward
|
||||||
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.TM_COMMON, modifierTypes.TM_GREAT, modifierTypes.MEMORY_MUSHROOM], fillRemaining: true });
|
||||||
|
return initBattleWithEnemyConfig(scene, config);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}:option:2:label`,
|
||||||
|
buttonTooltip: `${namespace}:option:2:tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}:option:selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
|
// Spawn hard fight with ULTRA/GREAT reward (can improve with luck)
|
||||||
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], fillRemaining: true });
|
||||||
|
|
||||||
|
// Seed offsets to remove possibility of different trainers having exact same teams
|
||||||
|
let ret;
|
||||||
|
scene.executeWithSeedOffset(() => {
|
||||||
|
ret = initBattleWithEnemyConfig(scene, config);
|
||||||
|
}, scene.currentBattle.waveIndex * 100);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withSimpleOption(
|
||||||
|
{
|
||||||
|
buttonLabel: `${namespace}:option:3:label`,
|
||||||
|
buttonTooltip: `${namespace}:option:3:tooltip`,
|
||||||
|
selected: [
|
||||||
|
{
|
||||||
|
text: `${namespace}:option:selected`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async (scene: BattleScene) => {
|
||||||
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
|
// Spawn brutal fight with ROGUE/ULTRA/GREAT reward (can improve with luck)
|
||||||
|
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[2];
|
||||||
|
|
||||||
|
// To avoid player level snowballing from picking this option
|
||||||
|
encounter.expMultiplier = 0.9;
|
||||||
|
|
||||||
|
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true });
|
||||||
|
|
||||||
|
// Seed offsets to remove possibility of different trainers having exact same teams
|
||||||
|
let ret;
|
||||||
|
scene.executeWithSeedOffset(() => {
|
||||||
|
ret = initBattleWithEnemyConfig(scene, config);
|
||||||
|
}, scene.currentBattle.waveIndex * 1000);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.withOutroDialogue([
|
||||||
|
{
|
||||||
|
text: `${namespace}:outro`,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.build();
|
|
@ -1,5 +1,5 @@
|
||||||
import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import Pokemon, { PokemonMove } from "#app/field/pokemon";
|
import Pokemon, { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
import { BerryModifierType, modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
import { BerryModifierType, modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
|
@ -37,18 +37,20 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter =
|
||||||
.withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Must have at least 4 berries to spawn
|
.withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Must have at least 4 berries to spawn
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: Species.GREEDENT.toString(),
|
// This sprite has the shadow
|
||||||
fileRoot: "pokemon",
|
spriteKey: null,
|
||||||
hasShadow: false,
|
fileRoot: null,
|
||||||
|
species: Species.GREEDENT,
|
||||||
|
hasShadow: true,
|
||||||
|
alpha: 0.001,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
x: -5
|
x: -5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// This sprite has the shadow
|
spriteKey: null,
|
||||||
spriteKey: Species.GREEDENT.toString(),
|
fileRoot: null,
|
||||||
fileRoot: "pokemon",
|
species: Species.GREEDENT,
|
||||||
hasShadow: true,
|
hasShadow: false,
|
||||||
alpha: 0.001,
|
|
||||||
repeat: true,
|
repeat: true,
|
||||||
x: -5
|
x: -5
|
||||||
},
|
},
|
||||||
|
@ -328,7 +330,7 @@ export const AbsoluteAvariceEncounter: IMysteryEncounter =
|
||||||
// Let it have the food
|
// Let it have the food
|
||||||
// Greedent joins the team, level equal to 2 below highest party member
|
// Greedent joins the team, level equal to 2 below highest party member
|
||||||
const level = getHighestLevelPlayerPokemon(scene).level - 2;
|
const level = getHighestLevelPlayerPokemon(scene).level - 2;
|
||||||
const greedent = scene.addEnemyPokemon(getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false);
|
const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false, null);
|
||||||
greedent.moveset = [new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF)];
|
greedent.moveset = [new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF)];
|
||||||
greedent.passive = true;
|
greedent.passive = true;
|
||||||
|
|
||||||
|
@ -344,7 +346,7 @@ function doGreedentSpriteSteal(scene: BattleScene) {
|
||||||
const shakeDelay = 50;
|
const shakeDelay = 50;
|
||||||
const slideDelay = 500;
|
const slideDelay = 500;
|
||||||
|
|
||||||
const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(0);
|
const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(1);
|
||||||
|
|
||||||
scene.playSound("Follow Me");
|
scene.playSound("Follow Me");
|
||||||
scene.tweens.chain({
|
scene.tweens.chain({
|
||||||
|
@ -418,7 +420,7 @@ function doGreedentSpriteSteal(scene: BattleScene) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function doGreedentEatBerries(scene: BattleScene) {
|
function doGreedentEatBerries(scene: BattleScene) {
|
||||||
const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(0);
|
const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(1);
|
||||||
let index = 1;
|
let index = 1;
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: greedentSprites,
|
targets: greedentSprites,
|
||||||
|
@ -452,7 +454,7 @@ function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) {
|
||||||
}
|
}
|
||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
animationOrder.forEach((berry, i) => {
|
animationOrder.forEach((berry, i) => {
|
||||||
const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey.includes(berry));
|
const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey?.includes(berry));
|
||||||
const [ sprite, tintSprite ] = encounter.introVisuals.getSpriteAtIndex(introVisualsIndex);
|
const [ sprite, tintSprite ] = encounter.introVisuals.getSpriteAtIndex(introVisualsIndex);
|
||||||
scene.time.delayedCall(berryAddDelay * i + 400, () => {
|
scene.time.delayedCall(berryAddDelay * i + 400, () => {
|
||||||
if (sprite) {
|
if (sprite) {
|
||||||
|
|
|
@ -47,23 +47,26 @@ export const DelibirdyEncounter: IMysteryEncounter =
|
||||||
))
|
))
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: Species.DELIBIRD.toString(),
|
spriteKey: null,
|
||||||
fileRoot: "pokemon",
|
fileRoot: null,
|
||||||
|
species: Species.DELIBIRD,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
startFrame: 38,
|
startFrame: 38,
|
||||||
scale: 0.94
|
scale: 0.94
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: Species.DELIBIRD.toString(),
|
spriteKey: null,
|
||||||
fileRoot: "pokemon",
|
fileRoot: null,
|
||||||
|
species: Species.DELIBIRD,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
scale: 1.06
|
scale: 1.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: Species.DELIBIRD.toString(),
|
spriteKey: null,
|
||||||
fileRoot: "pokemon",
|
fileRoot: null,
|
||||||
|
species: Species.DELIBIRD,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
startFrame: 65,
|
startFrame: 65,
|
||||||
|
|
|
@ -32,8 +32,9 @@ export const DepartmentStoreSaleEncounter: IMysteryEncounter =
|
||||||
x: -20,
|
x: -20,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: Species.FURFROU.toString(),
|
spriteKey: null,
|
||||||
fileRoot: "pokemon",
|
fileRoot: null,
|
||||||
|
species: Species.FURFROU,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
x: 30,
|
x: 30,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, initCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { AttackTypeBoosterModifierType, modifierTypes, } from "#app/modifier/modifier-type";
|
import { AttackTypeBoosterModifierType, modifierTypes, } from "#app/modifier/modifier-type";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
|
@ -75,8 +75,9 @@ export const FieryFalloutEncounter: IMysteryEncounter =
|
||||||
// Load hidden Volcarona sprites
|
// Load hidden Volcarona sprites
|
||||||
encounter.spriteConfigs = [
|
encounter.spriteConfigs = [
|
||||||
{
|
{
|
||||||
spriteKey: volcaronaSpecies.getSpriteId(false),
|
spriteKey: null,
|
||||||
fileRoot: "pokemon",
|
fileRoot: null,
|
||||||
|
species: Species.VOLCARONA,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
|
@ -84,8 +85,9 @@ export const FieryFalloutEncounter: IMysteryEncounter =
|
||||||
startFrame: 20
|
startFrame: 20
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: volcaronaSpecies.getSpriteId(true ),
|
spriteKey: null,
|
||||||
fileRoot: "pokemon",
|
fileRoot: null,
|
||||||
|
species: Species.VOLCARONA,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
|
@ -94,7 +96,7 @@ export const FieryFalloutEncounter: IMysteryEncounter =
|
||||||
];
|
];
|
||||||
|
|
||||||
// Load animations/sfx for Volcarona moves
|
// Load animations/sfx for Volcarona moves
|
||||||
initCustomMovesForEncounter(scene, [Moves.FIRE_SPIN, Moves.QUIVER_DANCE]);
|
loadCustomMovesForEncounter(scene, [Moves.FIRE_SPIN, Moves.QUIVER_DANCE]);
|
||||||
|
|
||||||
scene.arena.trySetWeather(WeatherType.SUNNY, true);
|
scene.arena.trySetWeather(WeatherType.SUNNY, true);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
setEncounterRewards
|
setEncounterRewards
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||||
import Pokemon from "#app/field/pokemon";
|
import Pokemon, { EnemyPokemon } from "#app/field/pokemon";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import {
|
import {
|
||||||
getPartyLuckValue,
|
getPartyLuckValue,
|
||||||
|
@ -27,6 +27,9 @@ import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-enco
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { TrainerSlot } from "#app/data/trainer-config";
|
||||||
|
import { getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:fightOrFlight";
|
const namespace = "mysteryEncounter:fightOrFlight";
|
||||||
|
@ -53,9 +56,14 @@ export const FightOrFlightEncounter: IMysteryEncounter =
|
||||||
|
|
||||||
// Calculate boss mon
|
// Calculate boss mon
|
||||||
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, scene.currentBattle.waveIndex, 0, getPartyLuckValue(scene.getParty()), true);
|
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, scene.currentBattle.waveIndex, 0, getPartyLuckValue(scene.getParty()), true);
|
||||||
|
const bossPokemon = new EnemyPokemon(scene, bossSpecies, scene.currentBattle.waveIndex, TrainerSlot.NONE, true, null);
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
levelAdditiveMultiplier: 1,
|
levelAdditiveMultiplier: 1,
|
||||||
pokemonConfigs: [{ species: bossSpecies, isBoss: true }],
|
pokemonConfigs: [{
|
||||||
|
species: bossSpecies,
|
||||||
|
dataSource: new PokemonData(bossPokemon),
|
||||||
|
isBoss: true
|
||||||
|
}],
|
||||||
};
|
};
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [config];
|
||||||
|
|
||||||
|
@ -74,7 +82,7 @@ export const FightOrFlightEncounter: IMysteryEncounter =
|
||||||
encounter.setDialogueToken("itemName", item.type.name);
|
encounter.setDialogueToken("itemName", item.type.name);
|
||||||
encounter.misc = item;
|
encounter.misc = item;
|
||||||
|
|
||||||
const bossSpriteKey = bossSpecies.getSpriteId(false, bossSpecies.forms ? 0 : null, false, bossSpecies.hasVariants() ? 0 : null);
|
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(bossPokemon);
|
||||||
encounter.spriteConfigs = [
|
encounter.spriteConfigs = [
|
||||||
{
|
{
|
||||||
spriteKey: item.type.iconImage,
|
spriteKey: item.type.iconImage,
|
||||||
|
@ -87,12 +95,13 @@ export const FightOrFlightEncounter: IMysteryEncounter =
|
||||||
disableAnimation: true
|
disableAnimation: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: bossSpriteKey,
|
spriteKey: spriteKey,
|
||||||
fileRoot: "pokemon",
|
fileRoot: fileRoot,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
tint: 0.25,
|
tint: 0.25,
|
||||||
x: -5,
|
x: -5,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
|
isPokemon: true
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,8 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
||||||
.withSceneWaveRangeRequirement(11, 179)
|
.withSceneWaveRangeRequirement(11, 179)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
fileRoot: "mystery-encounters",
|
|
||||||
spriteKey: "buoy",
|
spriteKey: "buoy",
|
||||||
|
fileRoot: "mystery-encounters",
|
||||||
hasShadow: false,
|
hasShadow: false,
|
||||||
x: 20,
|
x: 20,
|
||||||
y: 3,
|
y: 3,
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
import { MoneyRequirement } from "../mystery-encounter-requirements";
|
import { MoneyRequirement } from "../mystery-encounter-requirements";
|
||||||
import { catchPokemon, getRandomSpeciesByStarterTier } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { catchPokemon, getRandomSpeciesByStarterTier, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
|
import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { PokeballType } from "#app/data/pokeball";
|
import { PokeballType } from "#app/data/pokeball";
|
||||||
|
@ -66,17 +66,16 @@ export const PokemonSalesmanEncounter: IMysteryEncounter =
|
||||||
// If no HA mon found or you roll 1%, give shiny Magikarp
|
// If no HA mon found or you roll 1%, give shiny Magikarp
|
||||||
species = getPokemonSpecies(Species.MAGIKARP);
|
species = getPokemonSpecies(Species.MAGIKARP);
|
||||||
const hiddenIndex = species.ability2 ? 2 : 1;
|
const hiddenIndex = species.ability2 ? 2 : 1;
|
||||||
pokemon = scene.addPlayerPokemon(species, 5, hiddenIndex, species.formIndex, null, true);
|
pokemon = new PlayerPokemon(scene, species, 5, hiddenIndex, species.formIndex, null, true, null, null, null, null);
|
||||||
} else {
|
} else {
|
||||||
const hiddenIndex = species.ability2 ? 2 : 1;
|
const hiddenIndex = species.ability2 ? 2 : 1;
|
||||||
pokemon = scene.addPlayerPokemon(species, 5, hiddenIndex, species.formIndex);
|
pokemon = new PlayerPokemon(scene, species, 5, hiddenIndex, species.formIndex, null, null, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const spriteKey = pokemon.getSpriteId();
|
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(pokemon);
|
||||||
const spriteRoot = pokemon.getSpriteAtlasPath();
|
|
||||||
encounter.spriteConfigs.push({
|
encounter.spriteConfigs.push({
|
||||||
spriteKey: spriteKey,
|
spriteKey: spriteKey,
|
||||||
fileRoot: spriteRoot,
|
fileRoot: fileRoot,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
isPokemon: true
|
isPokemon: true
|
||||||
|
|
|
@ -36,12 +36,11 @@ export const SafariZoneEncounter: IMysteryEncounter =
|
||||||
.withSceneRequirement(new MoneyRequirement(0, 2.75)) // Cost equal to 1 Max Revive
|
.withSceneRequirement(new MoneyRequirement(0, 2.75)) // Cost equal to 1 Max Revive
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: "chest_blue",
|
spriteKey: "safari_zone",
|
||||||
fileRoot: "mystery-encounters",
|
fileRoot: "mystery-encounters",
|
||||||
hasShadow: true,
|
hasShadow: false,
|
||||||
x: 4,
|
x: 4,
|
||||||
y: 10,
|
y: 6
|
||||||
yShadow: 3
|
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
|
@ -52,6 +51,11 @@ export const SafariZoneEncounter: IMysteryEncounter =
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
// .withEnterIntroVisualsFromRight(true)
|
||||||
|
// .withOnVisualsStart((scene: BattleScene) => {
|
||||||
|
// scene.setFieldScale(0.9);
|
||||||
|
// return true;
|
||||||
|
// })
|
||||||
.withOption(new MysteryEncounterOptionBuilder()
|
.withOption(new MysteryEncounterOptionBuilder()
|
||||||
.withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.withOptionMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withSceneRequirement(new MoneyRequirement(0, 2.75)) // Cost equal to 1 Max Revive
|
.withSceneRequirement(new MoneyRequirement(0, 2.75)) // Cost equal to 1 Max Revive
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { StatusEffect } from "#app/data/status-effect";
|
||||||
import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
import IMysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||||
import { MoveRequirement } from "../mystery-encounter-requirements";
|
import { MoveRequirement } from "../mystery-encounter-requirements";
|
||||||
import { EnemyPartyConfig, EnemyPokemonConfig, initBattleWithEnemyConfig, initCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, } from "../utils/encounter-phase-utils";
|
import { EnemyPartyConfig, EnemyPokemonConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, } from "../utils/encounter-phase-utils";
|
||||||
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
@ -66,7 +66,7 @@ export const SlumberingSnorlaxEncounter: IMysteryEncounter =
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [config];
|
||||||
|
|
||||||
// Load animations/sfx for Snorlax fight start moves
|
// Load animations/sfx for Snorlax fight start moves
|
||||||
initCustomMovesForEncounter(scene, [Moves.SNORE]);
|
loadCustomMovesForEncounter(scene, [Moves.SNORE]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, initCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { modifierTypes, PokemonHeldItemModifierType, } from "#app/modifier/modifier-type";
|
import { modifierTypes, PokemonHeldItemModifierType, } from "#app/modifier/modifier-type";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
|
@ -91,7 +91,7 @@ export const TheStrongStuffEncounter: IMysteryEncounter =
|
||||||
|
|
||||||
encounter.enemyPartyConfigs = [config];
|
encounter.enemyPartyConfigs = [config];
|
||||||
|
|
||||||
initCustomMovesForEncounter(scene, [Moves.GASTRO_ACID, Moves.STEALTH_ROCK]);
|
loadCustomMovesForEncounter(scene, [Moves.GASTRO_ACID, Moves.STEALTH_ROCK]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
|
|
@ -47,6 +47,7 @@ export default interface IMysteryEncounter {
|
||||||
encounterAnimations?: EncounterAnim[];
|
encounterAnimations?: EncounterAnim[];
|
||||||
hideBattleIntroMessage?: boolean;
|
hideBattleIntroMessage?: boolean;
|
||||||
autoHideIntroVisuals?: boolean;
|
autoHideIntroVisuals?: boolean;
|
||||||
|
enterIntroVisualsFromRight?: boolean;
|
||||||
catchAllowed?: boolean;
|
catchAllowed?: boolean;
|
||||||
maxAllowedEncounters?: number;
|
maxAllowedEncounters?: number;
|
||||||
|
|
||||||
|
@ -159,14 +160,15 @@ export default class IMysteryEncounter implements IMysteryEncounter {
|
||||||
if (!isNullOrUndefined(encounter)) {
|
if (!isNullOrUndefined(encounter)) {
|
||||||
Object.assign(this, encounter);
|
Object.assign(this, encounter);
|
||||||
}
|
}
|
||||||
this.encounterTier = !isNullOrUndefined(this.encounterTier) ? this.encounterTier : MysteryEncounterTier.COMMON;
|
this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON;
|
||||||
this.dialogue = this.dialogue ?? {};
|
this.dialogue = this.dialogue ?? {};
|
||||||
// Default max is 1 for ROGUE encounters, 3 for others
|
// Default max is 1 for ROGUE encounters, 3 for others
|
||||||
this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? 1 : 3;
|
this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? 1 : 3;
|
||||||
this.encounterMode = MysteryEncounterMode.DEFAULT;
|
this.encounterMode = MysteryEncounterMode.DEFAULT;
|
||||||
this.requirements = this.requirements ? this.requirements : [];
|
this.requirements = this.requirements ? this.requirements : [];
|
||||||
this.hideBattleIntroMessage = !isNullOrUndefined(this.hideBattleIntroMessage) ? this.hideBattleIntroMessage : false;
|
this.hideBattleIntroMessage = this.hideBattleIntroMessage ?? false;
|
||||||
this.autoHideIntroVisuals = !isNullOrUndefined(this.autoHideIntroVisuals) ? this.autoHideIntroVisuals : true;
|
this.autoHideIntroVisuals = this.autoHideIntroVisuals ?? true;
|
||||||
|
this.enterIntroVisualsFromRight = this.enterIntroVisualsFromRight ?? false;
|
||||||
|
|
||||||
// Reset any dirty flags or encounter data
|
// Reset any dirty flags or encounter data
|
||||||
this.startOfBattleEffectsComplete = false;
|
this.startOfBattleEffectsComplete = false;
|
||||||
|
@ -414,6 +416,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
||||||
|
|
||||||
hideBattleIntroMessage?: boolean;
|
hideBattleIntroMessage?: boolean;
|
||||||
hideIntroVisuals?: boolean;
|
hideIntroVisuals?: boolean;
|
||||||
|
enterIntroVisualsFromRight?: boolean;
|
||||||
enemyPartyConfigs?: EnemyPartyConfig[] = [];
|
enemyPartyConfigs?: EnemyPartyConfig[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -717,6 +720,15 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
||||||
return Object.assign(this, { autoHideIntroVisuals: autoHideIntroVisuals });
|
return Object.assign(this, { autoHideIntroVisuals: autoHideIntroVisuals });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param enterIntroVisualsFromRight - If true, will slide in intro visuals from the right side of the screen. If false, slides in from left, as normal
|
||||||
|
* Default false
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
withEnterIntroVisualsFromRight(enterIntroVisualsFromRight: boolean): this & Required<Pick<IMysteryEncounter, "enterIntroVisualsFromRight">> {
|
||||||
|
return Object.assign(this, { enterIntroVisualsFromRight: enterIntroVisualsFromRight });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a title for the encounter
|
* Add a title for the encounter
|
||||||
*
|
*
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { PokemonSalesmanEncounter } from "#app/data/mystery-encounters/encounter
|
||||||
import { OfferYouCantRefuseEncounter } from "#app/data/mystery-encounters/encounters/offer-you-cant-refuse-encounter";
|
import { OfferYouCantRefuseEncounter } from "#app/data/mystery-encounters/encounters/offer-you-cant-refuse-encounter";
|
||||||
import { DelibirdyEncounter } from "#app/data/mystery-encounters/encounters/delibirdy-encounter";
|
import { DelibirdyEncounter } from "#app/data/mystery-encounters/encounters/delibirdy-encounter";
|
||||||
import { AbsoluteAvariceEncounter } from "#app/data/mystery-encounters/encounters/absolute-avarice-encounter";
|
import { AbsoluteAvariceEncounter } from "#app/data/mystery-encounters/encounters/absolute-avarice-encounter";
|
||||||
|
import { ATrainersTestEncounter } from "#app/data/mystery-encounters/encounters/a-trainers-test-encounter";
|
||||||
|
|
||||||
// Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * <number of missed spawns>) / 256
|
// 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;
|
export const BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT = 1;
|
||||||
|
@ -154,6 +155,7 @@ const anyBiomeEncounters: MysteryEncounterType[] = [
|
||||||
MysteryEncounterType.MYSTERIOUS_CHEST,
|
MysteryEncounterType.MYSTERIOUS_CHEST,
|
||||||
MysteryEncounterType.TRAINING_SESSION,
|
MysteryEncounterType.TRAINING_SESSION,
|
||||||
MysteryEncounterType.DELIBIRDY,
|
MysteryEncounterType.DELIBIRDY,
|
||||||
|
MysteryEncounterType.A_TRAINERS_TEST
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,6 +242,7 @@ export function initMysteryEncounters() {
|
||||||
allMysteryEncounters[MysteryEncounterType.OFFER_YOU_CANT_REFUSE] = OfferYouCantRefuseEncounter;
|
allMysteryEncounters[MysteryEncounterType.OFFER_YOU_CANT_REFUSE] = OfferYouCantRefuseEncounter;
|
||||||
allMysteryEncounters[MysteryEncounterType.DELIBIRDY] = DelibirdyEncounter;
|
allMysteryEncounters[MysteryEncounterType.DELIBIRDY] = DelibirdyEncounter;
|
||||||
allMysteryEncounters[MysteryEncounterType.ABSOLUTE_AVARICE] = AbsoluteAvariceEncounter;
|
allMysteryEncounters[MysteryEncounterType.ABSOLUTE_AVARICE] = AbsoluteAvariceEncounter;
|
||||||
|
allMysteryEncounters[MysteryEncounterType.A_TRAINERS_TEST] = ATrainersTestEncounter;
|
||||||
|
|
||||||
// Add extreme encounters to biome map
|
// Add extreme encounters to biome map
|
||||||
extremeBiomeEncounters.forEach(encounter => {
|
extremeBiomeEncounters.forEach(encounter => {
|
||||||
|
|
|
@ -305,7 +305,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
||||||
* @param scene
|
* @param scene
|
||||||
* @param moves
|
* @param moves
|
||||||
*/
|
*/
|
||||||
export function initCustomMovesForEncounter(scene: BattleScene, moves: Moves | Moves[]) {
|
export function loadCustomMovesForEncounter(scene: BattleScene, moves: Moves | Moves[]) {
|
||||||
moves = Array.isArray(moves) ? moves : [moves];
|
moves = Array.isArray(moves) ? moves : [moves];
|
||||||
return Promise.all(moves.map(move => initMoveAnim(scene, move)))
|
return Promise.all(moves.map(move => initMoveAnim(scene, move)))
|
||||||
.then(() => loadMoveAnimAssets(scene, moves));
|
.then(() => loadMoveAnimAssets(scene, moves));
|
||||||
|
|
|
@ -3,7 +3,7 @@ import i18next from "i18next";
|
||||||
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||||
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||||
import { VictoryPhase } from "#app/phases";
|
import { VictoryPhase } from "#app/phases";
|
||||||
import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
|
import Pokemon, { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
|
||||||
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "#app/data/pokeball";
|
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "#app/data/pokeball";
|
||||||
import { PlayerGender } from "#enums/player-gender";
|
import { PlayerGender } from "#enums/player-gender";
|
||||||
import { addPokeballCaptureStars, addPokeballOpenParticles } from "#app/field/anims";
|
import { addPokeballCaptureStars, addPokeballOpenParticles } from "#app/field/anims";
|
||||||
|
@ -18,11 +18,25 @@ import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "#app/data/po
|
||||||
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||||
|
import { Gender } from "#app/data/gender";
|
||||||
|
|
||||||
export interface MysteryEncounterPokemonData {
|
export interface MysteryEncounterPokemonData {
|
||||||
spriteScale?: number
|
spriteScale?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSpriteKeysFromSpecies(species: Species, female?: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): { spriteKey: string, fileRoot: string } {
|
||||||
|
const spriteKey = getPokemonSpecies(species).getSpriteKey(female ?? false, formIndex ?? 0, shiny ?? false, variant ?? 0);
|
||||||
|
const fileRoot = getPokemonSpecies(species).getSpriteAtlasPath(female ?? false, formIndex ?? 0, shiny ?? false, variant ?? 0);
|
||||||
|
return { spriteKey, fileRoot };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSpriteKeysFromPokemon(pokemon: Pokemon): { spriteKey: string, fileRoot: string } {
|
||||||
|
const spriteKey = pokemon.getSpeciesForm().getSpriteKey(pokemon.getGender() === Gender.FEMALE, pokemon.formIndex, pokemon.shiny, pokemon.variant);
|
||||||
|
const fileRoot = pokemon.getSpeciesForm().getSpriteAtlasPath(pokemon.getGender() === Gender.FEMALE, pokemon.formIndex, pokemon.shiny, pokemon.variant);
|
||||||
|
|
||||||
|
return { spriteKey, fileRoot };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Will never remove the player's last non-fainted Pokemon (if they only have 1)
|
* Will never remove the player's last non-fainted Pokemon (if they only have 1)
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import BattleScene, {startingWave} from "../battle-scene";
|
import BattleScene, { startingWave } from "../battle-scene";
|
||||||
import {ModifierTypeFunc, modifierTypes} from "../modifier/modifier-type";
|
import { ModifierTypeFunc, modifierTypes } from "../modifier/modifier-type";
|
||||||
import {EnemyPokemon} from "../field/pokemon";
|
import { EnemyPokemon } from "../field/pokemon";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import {PokeballType} from "./pokeball";
|
import { PokeballType } from "./pokeball";
|
||||||
import {pokemonEvolutions, pokemonPrevolutions} from "./pokemon-evolutions";
|
import { pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions";
|
||||||
import PokemonSpecies, {getPokemonSpecies, PokemonSpeciesFilter} from "./pokemon-species";
|
import PokemonSpecies, { getPokemonSpecies, PokemonSpeciesFilter } from "./pokemon-species";
|
||||||
import {tmSpecies} from "./tms";
|
import { tmSpecies } from "./tms";
|
||||||
import {Type} from "./type";
|
import { Type } from "./type";
|
||||||
import {doubleBattleDialogue} from "./dialogue";
|
import { doubleBattleDialogue } from "./dialogue";
|
||||||
import {PersistentModifier} from "../modifier/modifier";
|
import { PersistentModifier } from "../modifier/modifier";
|
||||||
import {TrainerVariant} from "../field/trainer";
|
import { TrainerVariant } from "../field/trainer";
|
||||||
import {getIsInitialized, initI18n} from "#app/plugins/i18n";
|
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||||
|
@ -527,6 +527,44 @@ export class TrainerConfig {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the trainer configuration for a Stat Trainer, as part of the Trainer's Test Mystery Encounter.
|
||||||
|
* @param {Species | Species[]} signatureSpecies - The signature species for the Elite Four member.
|
||||||
|
* @param {Type[]} specialtyTypes - The specialty types for the Stat Trainer.
|
||||||
|
* @param isMale - Whether the Elite Four Member is Male or Female (for localization of the title).
|
||||||
|
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
||||||
|
**/
|
||||||
|
initForStatTrainer(signatureSpecies: (Species | Species[])[], isMale: boolean, ...specialtyTypes: Type[]): TrainerConfig {
|
||||||
|
if (!getIsInitialized()) {
|
||||||
|
initI18n();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setPartyTemplates(trainerPartyTemplates.ELITE_FOUR);
|
||||||
|
|
||||||
|
signatureSpecies.forEach((speciesPool, s) => {
|
||||||
|
if (!Array.isArray(speciesPool)) {
|
||||||
|
speciesPool = [speciesPool];
|
||||||
|
}
|
||||||
|
this.setPartyMemberFunc(-(s + 1), getRandomPartyMemberFunc(speciesPool));
|
||||||
|
});
|
||||||
|
if (specialtyTypes.length) {
|
||||||
|
this.setSpeciesFilter(p => specialtyTypes.find(t => p.isOfType(t)) !== undefined);
|
||||||
|
this.setSpecialtyTypes(...specialtyTypes);
|
||||||
|
}
|
||||||
|
const nameForCall = this.name.toLowerCase().replace(/\s/g, "_");
|
||||||
|
this.name = i18next.t(`trainerNames:${nameForCall}`);
|
||||||
|
// this.setTitle(title);
|
||||||
|
this.setMoneyMultiplier(2);
|
||||||
|
this.setBoss();
|
||||||
|
this.setStaticParty();
|
||||||
|
|
||||||
|
// TODO: replace with more suitable music?
|
||||||
|
this.setBattleBgm("battle_trainer");
|
||||||
|
this.setVictoryBgm("victory_trainer");
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the trainer configuration for an evil team leader. Temporarily hardcoding evil leader teams though.
|
* Initializes the trainer configuration for an evil team leader. Temporarily hardcoding evil leader teams though.
|
||||||
* @param {Species | Species[]} signatureSpecies - The signature species for the evil team leader.
|
* @param {Species | Species[]} signatureSpecies - The signature species for the evil team leader.
|
||||||
|
@ -1787,4 +1825,137 @@ export const trainerConfigs: TrainerConfigs = {
|
||||||
p.generateAndPopulateMoveset();
|
p.generateAndPopulateMoveset();
|
||||||
p.pokeball = PokeballType.MASTER_BALL;
|
p.pokeball = PokeballType.MASTER_BALL;
|
||||||
})),
|
})),
|
||||||
|
// TODO: use signature species?
|
||||||
|
[TrainerType.BUCK]: new TrainerConfig(++t).setName("Buck").initForStatTrainer([], true)
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLAYDOL ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 3);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.ULTRA_BALL;
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.COALOSSAL ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.GREAT_BALL;
|
||||||
|
if (p.species.speciesId === Species.VENUSAUR) {
|
||||||
|
p.formIndex = 2; // Gmax
|
||||||
|
p.abilityIndex = 2; // Venusaur gets Chlorophyll
|
||||||
|
} else {
|
||||||
|
p.formIndex = 1; // Gmax
|
||||||
|
}
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.AGGRON ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.formIndex = 1; // Mega
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.TORKOAL ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.abilityIndex = 1; // Drought
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.GREAT_TUSK ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.HEATRAN ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 2);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.MASTER_BALL;
|
||||||
|
})),
|
||||||
|
[TrainerType.CHERYL]: new TrainerConfig(++t).setName("Cheryl").initForStatTrainer([], false)
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BLISSEY ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 3);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.ULTRA_BALL;
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.SNORLAX, Species.LAPRAS ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.GREAT_BALL;
|
||||||
|
p.formIndex = 1; // Gmax
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.AUDINO ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.formIndex = 1; // Mega
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.GOODRA ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.IRON_HANDS ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.CRESSELIA, Species.ENAMORUS ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 2);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
if (p.species.speciesId === Species.ENAMORUS) {
|
||||||
|
p.formIndex = 1; // Therian
|
||||||
|
p.generateName();
|
||||||
|
}
|
||||||
|
p.pokeball = PokeballType.MASTER_BALL;
|
||||||
|
})),
|
||||||
|
[TrainerType.MARLEY]: new TrainerConfig(++t).setName("Marley").initForStatTrainer([], false)
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.ARCANINE ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 3);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.ULTRA_BALL;
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.CINDERACE, Species.INTELEON ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.GREAT_BALL;
|
||||||
|
p.formIndex = 1; // Gmax
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.AERODACTYL ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.formIndex = 1; // Mega
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.DRAGAPULT ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.IRON_BUNDLE ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.REGIELEKI ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 2);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.MASTER_BALL;
|
||||||
|
})),
|
||||||
|
[TrainerType.MIRA]: new TrainerConfig(++t).setName("Mira").initForStatTrainer([], false)
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.ALAKAZAM ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 2);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.pokeball = PokeballType.ULTRA_BALL;
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.GENGAR, Species.HATTERENE ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.GREAT_BALL;
|
||||||
|
p.formIndex = p.species.speciesId === Species.GENGAR ? 2 : 1; // Gmax
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.FLUTTER_MANE ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.HYDREIGON ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.MAGNEZONE ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.LATIOS, Species.LATIAS ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 2);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.MASTER_BALL;
|
||||||
|
})),
|
||||||
|
[TrainerType.RILEY]: new TrainerConfig(++t).setName("Riley").initForStatTrainer([], true)
|
||||||
|
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.LUCARIO ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 2);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.formIndex = 1;
|
||||||
|
p.pokeball = PokeballType.ULTRA_BALL;
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.RILLABOOM, Species.CENTISKORCH ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
p.pokeball = PokeballType.GREAT_BALL;
|
||||||
|
p.formIndex = 1; // Gmax
|
||||||
|
p.generateName();
|
||||||
|
}))
|
||||||
|
.setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.TYRANITAR ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.ROARING_MOON ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.URSALUNA ], TrainerSlot.TRAINER, true))
|
||||||
|
.setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.REGIGIGAS, Species.LANDORUS ], TrainerSlot.TRAINER, true, p => {
|
||||||
|
p.setBoss(true, 2);
|
||||||
|
p.generateAndPopulateMoveset();
|
||||||
|
if (p.species.speciesId === Species.LANDORUS) {
|
||||||
|
p.formIndex = 1; // Therian
|
||||||
|
p.generateName();
|
||||||
|
}
|
||||||
|
p.pokeball = PokeballType.MASTER_BALL;
|
||||||
|
})),
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,5 +15,6 @@ export enum MysteryEncounterType {
|
||||||
POKEMON_SALESMAN,
|
POKEMON_SALESMAN,
|
||||||
OFFER_YOU_CANT_REFUSE,
|
OFFER_YOU_CANT_REFUSE,
|
||||||
DELIBIRDY,
|
DELIBIRDY,
|
||||||
ABSOLUTE_AVARICE
|
ABSOLUTE_AVARICE,
|
||||||
|
A_TRAINERS_TEST
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,11 @@ export enum TrainerType {
|
||||||
GHETSIS_2,
|
GHETSIS_2,
|
||||||
LYSANDRE,
|
LYSANDRE,
|
||||||
LYSANDRE_2,
|
LYSANDRE_2,
|
||||||
|
BUCK,
|
||||||
|
CHERYL,
|
||||||
|
MARLEY,
|
||||||
|
MIRA,
|
||||||
|
RILEY,
|
||||||
|
|
||||||
BROCK = 200,
|
BROCK = 200,
|
||||||
MISTY,
|
MISTY,
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { GameObjects } from "phaser";
|
import { GameObjects } from "phaser";
|
||||||
import BattleScene from "../battle-scene";
|
import BattleScene from "../battle-scene";
|
||||||
import IMysteryEncounter from "../data/mystery-encounters/mystery-encounter";
|
import IMysteryEncounter from "../data/mystery-encounters/mystery-encounter";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import { isNullOrUndefined } from "#app/utils";
|
||||||
|
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
|
||||||
type KnownFileRoot =
|
type KnownFileRoot =
|
||||||
| "trainer"
|
|
||||||
| "pokemon"
|
|
||||||
| "arenas"
|
| "arenas"
|
||||||
| "battle_anims"
|
| "battle_anims"
|
||||||
| "cg"
|
| "cg"
|
||||||
|
@ -33,6 +34,8 @@ export class MysteryEncounterSpriteConfig {
|
||||||
spriteKey: string;
|
spriteKey: string;
|
||||||
/** Refer to [/public/images](../../public/images) directorty for all folder names */
|
/** Refer to [/public/images](../../public/images) directorty for all folder names */
|
||||||
fileRoot: KnownFileRoot & string | string;
|
fileRoot: KnownFileRoot & string | string;
|
||||||
|
/** Optional replacement for `spriteKey`/`fileRoot`. Just know this defaults to male/genderless, form 0, no shiny */
|
||||||
|
species?: Species;
|
||||||
/** Enable shadow. Defaults to `false` */
|
/** Enable shadow. Defaults to `false` */
|
||||||
hasShadow?: boolean = false;
|
hasShadow?: boolean = false;
|
||||||
/** Disable animation. Defaults to `false` */
|
/** Disable animation. Defaults to `false` */
|
||||||
|
@ -69,15 +72,26 @@ export class MysteryEncounterSpriteConfig {
|
||||||
export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container {
|
export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Container {
|
||||||
public encounter: IMysteryEncounter;
|
public encounter: IMysteryEncounter;
|
||||||
public spriteConfigs: MysteryEncounterSpriteConfig[];
|
public spriteConfigs: MysteryEncounterSpriteConfig[];
|
||||||
|
public enterFromRight: boolean;
|
||||||
|
|
||||||
constructor(scene: BattleScene, encounter: IMysteryEncounter) {
|
constructor(scene: BattleScene, encounter: IMysteryEncounter) {
|
||||||
super(scene, -72, 76);
|
super(scene, -72, 76);
|
||||||
this.encounter = encounter;
|
this.encounter = encounter;
|
||||||
|
this.enterFromRight = encounter.enterIntroVisualsFromRight ?? false;
|
||||||
// Shallow copy configs to allow visual config updates at runtime without dirtying master copy of Encounter
|
// Shallow copy configs to allow visual config updates at runtime without dirtying master copy of Encounter
|
||||||
this.spriteConfigs = encounter.spriteConfigs.map(config => {
|
this.spriteConfigs = encounter.spriteConfigs.map(config => {
|
||||||
return {
|
const result = {
|
||||||
...config
|
...config
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!isNullOrUndefined(result.species)) {
|
||||||
|
const keys = getSpriteKeysFromSpecies(result.species);
|
||||||
|
result.spriteKey = keys.spriteKey;
|
||||||
|
result.fileRoot = keys.fileRoot;
|
||||||
|
result.isPokemon = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
});
|
});
|
||||||
if (!this.spriteConfigs) {
|
if (!this.spriteConfigs) {
|
||||||
return;
|
return;
|
||||||
|
@ -90,9 +104,10 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getItemSprite = (spriteKey: string) => {
|
const getItemSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => {
|
||||||
const icon = this.scene.add.sprite(-19, 2, "items", spriteKey);
|
const icon = this.scene.add.sprite(-19, 2, "items", spriteKey);
|
||||||
icon.setOrigin(0.5, 1);
|
icon.setOrigin(0.5, 1);
|
||||||
|
icon.setPipeline(this.scene.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
|
||||||
return icon;
|
return icon;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,7 +129,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
||||||
sprite = getSprite(spriteKey, hasShadow, yShadow);
|
sprite = getSprite(spriteKey, hasShadow, yShadow);
|
||||||
tintSprite = getSprite(spriteKey);
|
tintSprite = getSprite(spriteKey);
|
||||||
} else {
|
} else {
|
||||||
sprite = getItemSprite(spriteKey);
|
sprite = getItemSprite(spriteKey, hasShadow, yShadow);
|
||||||
tintSprite = getItemSprite(spriteKey);
|
tintSprite = getItemSprite(spriteKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -566,6 +566,67 @@ export const PGMdialogue: DialogueTranslationEntries = {
|
||||||
1: "Fools with no vision will continue to befoul this beautiful world."
|
1: "Fools with no vision will continue to befoul this beautiful world."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"stat_trainer_buck": {
|
||||||
|
"encounter": {
|
||||||
|
1: "...I'm telling you right now. I'm seriously tough. Act surprised!",
|
||||||
|
2: "I can feel my Pokémon shivering inside their Pokéballs!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "Heeheehee!\nSo hot, you!"
|
||||||
|
},
|
||||||
|
"defeat": {
|
||||||
|
1: "Whoa! You're all out of gas, I guess."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stat_trainer_cheryl": {
|
||||||
|
"encounter": {
|
||||||
|
1: "My Pokémon have been itching for a battle.",
|
||||||
|
2: "I should warn you, my Pokémon can be quite rambunctious."
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "Striking the right balance of offense and defense... It's not easy to do."
|
||||||
|
},
|
||||||
|
"defeat": {
|
||||||
|
1: "Do your Pokémon need any healing?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stat_trainer_marley": {
|
||||||
|
"encounter": {
|
||||||
|
1: "... OK.\nI'll do my best.",
|
||||||
|
2: "... OK.\nI... won't lose...!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "... Awww."
|
||||||
|
},
|
||||||
|
"defeat": {
|
||||||
|
1: "... Goodbye."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stat_trainer_mira": {
|
||||||
|
"encounter": {
|
||||||
|
1: "You will be shocked by Mira!",
|
||||||
|
2: "Mira will show you that Mira doesn't get lost anymore!"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: "Mira wonders if she can get very far in this land."
|
||||||
|
},
|
||||||
|
"defeat": {
|
||||||
|
1: "Mira knew she would win!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stat_trainer_riley": {
|
||||||
|
"encounter": {
|
||||||
|
1: "Battling is our way of greeting!",
|
||||||
|
2: "We're pulling out all the stops to put your Pokémon down.",
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
1: `At times we battle, and sometimes we team up...
|
||||||
|
$It's great how Trainers can interact.`
|
||||||
|
},
|
||||||
|
"defeat": {
|
||||||
|
1: "You put up quite the display.\nBetter luck next time."
|
||||||
|
}
|
||||||
|
},
|
||||||
"brock": {
|
"brock": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
1: "My expertise on Rock-type Pokémon will take you down! Come on!",
|
||||||
|
|
|
@ -270,6 +270,11 @@ export const trainerNames: SimpleTranslationEntries = {
|
||||||
"cyrus": "Cyrus",
|
"cyrus": "Cyrus",
|
||||||
"ghetsis": "Ghetsis",
|
"ghetsis": "Ghetsis",
|
||||||
"lysandre": "Lysandre",
|
"lysandre": "Lysandre",
|
||||||
|
"buck": "Buck",
|
||||||
|
"cheryl": "Cheryl",
|
||||||
|
"marley": "Marley",
|
||||||
|
"mira": "Mira",
|
||||||
|
"riley": "Riley",
|
||||||
|
|
||||||
// Double Names
|
// Double Names
|
||||||
"blue_red_double": "Blue & Red",
|
"blue_red_double": "Blue & Red",
|
||||||
|
|
|
@ -127,9 +127,9 @@ class DefaultOverrides {
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
// 1 to 256, set to null to ignore
|
// 1 to 256, set to null to ignore
|
||||||
readonly MYSTERY_ENCOUNTER_RATE_OVERRIDE: number = null;
|
readonly MYSTERY_ENCOUNTER_RATE_OVERRIDE: number = 256;
|
||||||
readonly MYSTERY_ENCOUNTER_TIER_OVERRIDE: MysteryEncounterTier = null;
|
readonly MYSTERY_ENCOUNTER_TIER_OVERRIDE: MysteryEncounterTier = null;
|
||||||
readonly MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType = null;
|
readonly MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType = MysteryEncounterType.A_TRAINERS_TEST;
|
||||||
|
|
||||||
// -------------------------
|
// -------------------------
|
||||||
// MODIFIER / ITEM OVERRIDES
|
// MODIFIER / ITEM OVERRIDES
|
||||||
|
|
|
@ -1002,8 +1002,8 @@ export class EncounterPhase extends BattlePhase {
|
||||||
|
|
||||||
const enemyField = this.scene.getEnemyField();
|
const enemyField = this.scene.getEnemyField();
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: [this.scene.arenaEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.currentBattle?.mysteryEncounter?.introVisuals, this.scene.arenaPlayer, this.scene.trainer].flat(),
|
targets: [this.scene.arenaEnemy, this.scene.currentBattle.trainer, enemyField, this.scene.arenaPlayer, this.scene.trainer].flat(),
|
||||||
x: (_target, _key, value, fieldIndex: integer) => fieldIndex < 3 + (enemyField.length) ? value + 300 : value - 300,
|
x: (_target, _key, value, fieldIndex: integer) => fieldIndex < 2 + (enemyField.length) ? value + 300 : value - 300,
|
||||||
duration: 2000,
|
duration: 2000,
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
if (!this.tryOverrideForBattleSpec()) {
|
if (!this.tryOverrideForBattleSpec()) {
|
||||||
|
@ -1011,6 +1011,19 @@ export class EncounterPhase extends BattlePhase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const encounterIntroVisuals = this.scene.currentBattle?.mysteryEncounter?.introVisuals;
|
||||||
|
if (encounterIntroVisuals) {
|
||||||
|
const enterFromRight = encounterIntroVisuals.enterFromRight;
|
||||||
|
if (enterFromRight) {
|
||||||
|
encounterIntroVisuals.x += 500;
|
||||||
|
}
|
||||||
|
this.scene.tweens.add({
|
||||||
|
targets: encounterIntroVisuals,
|
||||||
|
x: enterFromRight ? "-=200" : "+=300",
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getEncounterMessage(): string {
|
getEncounterMessage(): string {
|
||||||
|
@ -1106,8 +1119,6 @@ export class EncounterPhase extends BattlePhase {
|
||||||
}
|
}
|
||||||
|
|
||||||
const doEncounter = () => {
|
const doEncounter = () => {
|
||||||
this.scene.playBgm(undefined);
|
|
||||||
|
|
||||||
const doShowEncounterOptions = () => {
|
const doShowEncounterOptions = () => {
|
||||||
this.scene.ui.clearText();
|
this.scene.ui.clearText();
|
||||||
this.scene.ui.getMessageHandler().hideNameText();
|
this.scene.ui.getMessageHandler().hideNameText();
|
||||||
|
@ -1264,7 +1275,17 @@ export class NextEncounterPhase extends EncounterPhase {
|
||||||
}
|
}
|
||||||
const nextEncounterVisuals = this.scene.currentBattle?.mysteryEncounter?.introVisuals;
|
const nextEncounterVisuals = this.scene.currentBattle?.mysteryEncounter?.introVisuals;
|
||||||
if (nextEncounterVisuals) {
|
if (nextEncounterVisuals) {
|
||||||
moveTargets.push(nextEncounterVisuals);
|
const enterFromRight = nextEncounterVisuals.enterFromRight;
|
||||||
|
if (enterFromRight) {
|
||||||
|
nextEncounterVisuals.x += 500;
|
||||||
|
this.scene.tweens.add({
|
||||||
|
targets: nextEncounterVisuals,
|
||||||
|
x: "-=200",
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
moveTargets.push(nextEncounterVisuals);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: moveTargets.flat(),
|
targets: moveTargets.flat(),
|
||||||
|
|
Loading…
Reference in New Issue