Merge branch 'beta' into bulkgacha

This commit is contained in:
David Yang 2025-04-05 04:21:00 +08:00 committed by GitHub
commit ecf627a1d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 3732 additions and 1481 deletions

1595
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
{
"name": "pokemon-rogue-battle",
"private": true,
"version": "1.8.1",
"version": "1.8.4",
"type": "module",
"scripts": {
"start": "vite",

View File

@ -1,20 +1,755 @@
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 0, "y": 0, "w": 96, "h": 98 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 96, "h": 98 },
"sourceSize": { "w": 96, "h": 98 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.13-x64",
"image": "890-eternamax.png",
"format": "RGBA8888",
"size": { "w": 96, "h": 98 },
"scale": "1"
}
{
"textures": [
{
"image": "890-eternamax.png",
"format": "RGBA8888",
"size": {
"w": 579,
"h": 579
},
"scale": 1,
"frames": [
{
"filename": "0035.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 100,
"h": 98
},
"frame": {
"x": 0,
"y": 0,
"w": 100,
"h": 98
}
},
{
"filename": "0031.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 95,
"h": 100
},
"frame": {
"x": 100,
"y": 0,
"w": 95,
"h": 100
}
},
{
"filename": "0029.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 8,
"w": 91,
"h": 100
},
"frame": {
"x": 0,
"y": 98,
"w": 91,
"h": 100
}
},
{
"filename": "0001.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 96,
"h": 98
},
"frame": {
"x": 91,
"y": 100,
"w": 96,
"h": 98
}
},
{
"filename": "0032.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 95,
"h": 99
},
"frame": {
"x": 187,
"y": 100,
"w": 95,
"h": 99
}
},
{
"filename": "0030.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 9,
"y": 10,
"w": 91,
"h": 98
},
"frame": {
"x": 0,
"y": 198,
"w": 91,
"h": 98
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 10,
"w": 88,
"h": 98
},
"frame": {
"x": 91,
"y": 198,
"w": 88,
"h": 98
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 10,
"w": 95,
"h": 97
},
"frame": {
"x": 195,
"y": 0,
"w": 95,
"h": 97
}
},
{
"filename": "0003.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 179,
"y": 199,
"w": 95,
"h": 97
}
},
{
"filename": "0004.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 274,
"y": 199,
"w": 95,
"h": 97
}
},
{
"filename": "0033.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 290,
"y": 0,
"w": 95,
"h": 97
}
},
{
"filename": "0034.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 94,
"h": 96
},
"frame": {
"x": 282,
"y": 97,
"w": 94,
"h": 96
}
},
{
"filename": "0028.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 11,
"w": 90,
"h": 97
},
"frame": {
"x": 369,
"y": 193,
"w": 90,
"h": 97
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 13,
"w": 93,
"h": 95
},
"frame": {
"x": 385,
"y": 0,
"w": 93,
"h": 95
}
},
{
"filename": "0017.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 9,
"w": 91,
"h": 96
},
"frame": {
"x": 385,
"y": 95,
"w": 91,
"h": 96
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 97
},
"frame": {
"x": 369,
"y": 290,
"w": 87,
"h": 97
}
},
{
"filename": "0009.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 90,
"h": 96
},
"frame": {
"x": 456,
"y": 290,
"w": 90,
"h": 96
}
},
{
"filename": "0015.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 8,
"w": 90,
"h": 96
},
"frame": {
"x": 459,
"y": 191,
"w": 90,
"h": 96
}
},
{
"filename": "0016.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 8,
"w": 90,
"h": 95
},
"frame": {
"x": 476,
"y": 95,
"w": 90,
"h": 95
}
},
{
"filename": "0014.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 89,
"h": 95
},
"frame": {
"x": 478,
"y": 0,
"w": 89,
"h": 95
}
},
{
"filename": "0027.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 89,
"h": 96
},
"frame": {
"x": 456,
"y": 386,
"w": 89,
"h": 96
}
},
{
"filename": "0025.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 11,
"w": 89,
"h": 95
},
"frame": {
"x": 0,
"y": 296,
"w": 89,
"h": 95
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 9,
"y": 14,
"w": 89,
"h": 94
},
"frame": {
"x": 89,
"y": 296,
"w": 89,
"h": 94
}
},
{
"filename": "0011.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 88,
"h": 95
},
"frame": {
"x": 178,
"y": 296,
"w": 88,
"h": 95
}
},
{
"filename": "0023.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 95
},
"frame": {
"x": 89,
"y": 390,
"w": 87,
"h": 95
}
},
{
"filename": "0013.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 89,
"h": 94
},
"frame": {
"x": 0,
"y": 391,
"w": 89,
"h": 94
}
},
{
"filename": "0012.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 14,
"w": 89,
"h": 93
},
"frame": {
"x": 266,
"y": 387,
"w": 89,
"h": 93
}
},
{
"filename": "0019.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 16,
"y": 13,
"w": 85,
"h": 91
},
"frame": {
"x": 266,
"y": 296,
"w": 85,
"h": 91
}
},
{
"filename": "0024.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 13,
"w": 88,
"h": 94
},
"frame": {
"x": 176,
"y": 391,
"w": 88,
"h": 94
}
},
{
"filename": "0010.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 13,
"w": 87,
"h": 94
},
"frame": {
"x": 355,
"y": 387,
"w": 87,
"h": 94
}
},
{
"filename": "0018.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 16,
"y": 11,
"w": 87,
"h": 94
},
"frame": {
"x": 264,
"y": 480,
"w": 87,
"h": 94
}
},
{
"filename": "0026.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 14,
"w": 89,
"h": 93
},
"frame": {
"x": 351,
"y": 481,
"w": 89,
"h": 93
}
},
{
"filename": "0022.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 93
},
"frame": {
"x": 440,
"y": 482,
"w": 87,
"h": 93
}
},
{
"filename": "0021.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 10,
"w": 86,
"h": 94
},
"frame": {
"x": 0,
"y": 485,
"w": 86,
"h": 94
}
},
{
"filename": "0020.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 14,
"w": 85,
"h": 91
},
"frame": {
"x": 86,
"y": 485,
"w": 85,
"h": 91
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:8fd9e1830200ec8e4aac8571cc2d27a6:c966e3efce03c7bae43d7bca6d6dfa62:cedd2711a12bbacba5623505fe88bd92$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -1,20 +1,755 @@
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 1, "y": 1, "w": 92, "h": 94 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 1, "w": 92, "h": 94 },
"sourceSize": { "w": 96, "h": 98 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.13-x64",
"image": "890-eternamax.png",
"format": "RGBA8888",
"size": { "w": 94, "h": 96 },
"scale": "1"
}
{
"textures": [
{
"image": "890-eternamax.png",
"format": "RGBA8888",
"size": {
"w": 579,
"h": 579
},
"scale": 1,
"frames": [
{
"filename": "0035.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 100,
"h": 98
},
"frame": {
"x": 0,
"y": 0,
"w": 100,
"h": 98
}
},
{
"filename": "0031.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 95,
"h": 100
},
"frame": {
"x": 100,
"y": 0,
"w": 95,
"h": 100
}
},
{
"filename": "0029.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 8,
"w": 91,
"h": 100
},
"frame": {
"x": 0,
"y": 98,
"w": 91,
"h": 100
}
},
{
"filename": "0001.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 96,
"h": 98
},
"frame": {
"x": 91,
"y": 100,
"w": 96,
"h": 98
}
},
{
"filename": "0032.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 95,
"h": 99
},
"frame": {
"x": 187,
"y": 100,
"w": 95,
"h": 99
}
},
{
"filename": "0030.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 9,
"y": 10,
"w": 91,
"h": 98
},
"frame": {
"x": 0,
"y": 198,
"w": 91,
"h": 98
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 10,
"w": 88,
"h": 98
},
"frame": {
"x": 91,
"y": 198,
"w": 88,
"h": 98
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 10,
"w": 95,
"h": 97
},
"frame": {
"x": 195,
"y": 0,
"w": 95,
"h": 97
}
},
{
"filename": "0003.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 179,
"y": 199,
"w": 95,
"h": 97
}
},
{
"filename": "0004.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 274,
"y": 199,
"w": 95,
"h": 97
}
},
{
"filename": "0033.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 290,
"y": 0,
"w": 95,
"h": 97
}
},
{
"filename": "0034.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 94,
"h": 96
},
"frame": {
"x": 282,
"y": 97,
"w": 94,
"h": 96
}
},
{
"filename": "0028.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 11,
"w": 90,
"h": 97
},
"frame": {
"x": 369,
"y": 193,
"w": 90,
"h": 97
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 13,
"w": 93,
"h": 95
},
"frame": {
"x": 385,
"y": 0,
"w": 93,
"h": 95
}
},
{
"filename": "0017.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 9,
"w": 91,
"h": 96
},
"frame": {
"x": 385,
"y": 95,
"w": 91,
"h": 96
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 97
},
"frame": {
"x": 369,
"y": 290,
"w": 87,
"h": 97
}
},
{
"filename": "0009.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 90,
"h": 96
},
"frame": {
"x": 456,
"y": 290,
"w": 90,
"h": 96
}
},
{
"filename": "0015.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 8,
"w": 90,
"h": 96
},
"frame": {
"x": 459,
"y": 191,
"w": 90,
"h": 96
}
},
{
"filename": "0016.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 8,
"w": 90,
"h": 95
},
"frame": {
"x": 476,
"y": 95,
"w": 90,
"h": 95
}
},
{
"filename": "0014.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 89,
"h": 95
},
"frame": {
"x": 478,
"y": 0,
"w": 89,
"h": 95
}
},
{
"filename": "0027.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 89,
"h": 96
},
"frame": {
"x": 456,
"y": 386,
"w": 89,
"h": 96
}
},
{
"filename": "0025.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 11,
"w": 89,
"h": 95
},
"frame": {
"x": 0,
"y": 296,
"w": 89,
"h": 95
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 9,
"y": 14,
"w": 89,
"h": 94
},
"frame": {
"x": 89,
"y": 296,
"w": 89,
"h": 94
}
},
{
"filename": "0011.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 88,
"h": 95
},
"frame": {
"x": 178,
"y": 296,
"w": 88,
"h": 95
}
},
{
"filename": "0023.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 95
},
"frame": {
"x": 89,
"y": 390,
"w": 87,
"h": 95
}
},
{
"filename": "0013.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 89,
"h": 94
},
"frame": {
"x": 0,
"y": 391,
"w": 89,
"h": 94
}
},
{
"filename": "0012.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 14,
"w": 89,
"h": 93
},
"frame": {
"x": 266,
"y": 387,
"w": 89,
"h": 93
}
},
{
"filename": "0019.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 16,
"y": 13,
"w": 85,
"h": 91
},
"frame": {
"x": 266,
"y": 296,
"w": 85,
"h": 91
}
},
{
"filename": "0024.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 13,
"w": 88,
"h": 94
},
"frame": {
"x": 176,
"y": 391,
"w": 88,
"h": 94
}
},
{
"filename": "0010.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 13,
"w": 87,
"h": 94
},
"frame": {
"x": 355,
"y": 387,
"w": 87,
"h": 94
}
},
{
"filename": "0018.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 16,
"y": 11,
"w": 87,
"h": 94
},
"frame": {
"x": 264,
"y": 480,
"w": 87,
"h": 94
}
},
{
"filename": "0026.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 14,
"w": 89,
"h": 93
},
"frame": {
"x": 351,
"y": 481,
"w": 89,
"h": 93
}
},
{
"filename": "0022.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 93
},
"frame": {
"x": 440,
"y": 482,
"w": 87,
"h": 93
}
},
{
"filename": "0021.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 10,
"w": 86,
"h": 94
},
"frame": {
"x": 0,
"y": 485,
"w": 86,
"h": 94
}
},
{
"filename": "0020.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 14,
"w": 85,
"h": 91
},
"frame": {
"x": 86,
"y": 485,
"w": 85,
"h": 91
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:1eb3f67ba4e434995b4589c97560f1be:539129d777c30d08fa799dcebaeb523e:cf277fd83435e8c90cd46073c543568b$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -1,20 +1,755 @@
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 1, "y": 1, "w": 92, "h": 94 },
"rotated": false,
"trimmed": true,
"spriteSourceSize": { "x": 3, "y": 1, "w": 92, "h": 94 },
"sourceSize": { "w": 96, "h": 98 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.13-x64",
"image": "890-eternamax_2.png",
"format": "RGBA8888",
"size": { "w": 94, "h": 96 },
"scale": "1"
}
}
{
"textures": [
{
"image": "890-eternamax_2.png",
"format": "RGBA8888",
"size": {
"w": 579,
"h": 579
},
"scale": 1,
"frames": [
{
"filename": "0035.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 100,
"h": 98
},
"frame": {
"x": 0,
"y": 0,
"w": 100,
"h": 98
}
},
{
"filename": "0031.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 95,
"h": 100
},
"frame": {
"x": 100,
"y": 0,
"w": 95,
"h": 100
}
},
{
"filename": "0029.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 8,
"w": 91,
"h": 100
},
"frame": {
"x": 0,
"y": 98,
"w": 91,
"h": 100
}
},
{
"filename": "0001.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 96,
"h": 98
},
"frame": {
"x": 91,
"y": 100,
"w": 96,
"h": 98
}
},
{
"filename": "0032.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 95,
"h": 99
},
"frame": {
"x": 187,
"y": 100,
"w": 95,
"h": 99
}
},
{
"filename": "0030.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 9,
"y": 10,
"w": 91,
"h": 98
},
"frame": {
"x": 0,
"y": 198,
"w": 91,
"h": 98
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 10,
"w": 88,
"h": 98
},
"frame": {
"x": 91,
"y": 198,
"w": 88,
"h": 98
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 10,
"w": 95,
"h": 97
},
"frame": {
"x": 195,
"y": 0,
"w": 95,
"h": 97
}
},
{
"filename": "0003.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 179,
"y": 199,
"w": 95,
"h": 97
}
},
{
"filename": "0004.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 274,
"y": 199,
"w": 95,
"h": 97
}
},
{
"filename": "0033.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 290,
"y": 0,
"w": 95,
"h": 97
}
},
{
"filename": "0034.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 94,
"h": 96
},
"frame": {
"x": 282,
"y": 97,
"w": 94,
"h": 96
}
},
{
"filename": "0028.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 11,
"w": 90,
"h": 97
},
"frame": {
"x": 369,
"y": 193,
"w": 90,
"h": 97
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 13,
"w": 93,
"h": 95
},
"frame": {
"x": 385,
"y": 0,
"w": 93,
"h": 95
}
},
{
"filename": "0017.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 9,
"w": 91,
"h": 96
},
"frame": {
"x": 385,
"y": 95,
"w": 91,
"h": 96
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 97
},
"frame": {
"x": 369,
"y": 290,
"w": 87,
"h": 97
}
},
{
"filename": "0009.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 90,
"h": 96
},
"frame": {
"x": 456,
"y": 290,
"w": 90,
"h": 96
}
},
{
"filename": "0015.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 8,
"w": 90,
"h": 96
},
"frame": {
"x": 459,
"y": 191,
"w": 90,
"h": 96
}
},
{
"filename": "0016.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 8,
"w": 90,
"h": 95
},
"frame": {
"x": 476,
"y": 95,
"w": 90,
"h": 95
}
},
{
"filename": "0014.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 89,
"h": 95
},
"frame": {
"x": 478,
"y": 0,
"w": 89,
"h": 95
}
},
{
"filename": "0027.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 89,
"h": 96
},
"frame": {
"x": 456,
"y": 386,
"w": 89,
"h": 96
}
},
{
"filename": "0025.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 11,
"w": 89,
"h": 95
},
"frame": {
"x": 0,
"y": 296,
"w": 89,
"h": 95
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 9,
"y": 14,
"w": 89,
"h": 94
},
"frame": {
"x": 89,
"y": 296,
"w": 89,
"h": 94
}
},
{
"filename": "0011.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 88,
"h": 95
},
"frame": {
"x": 178,
"y": 296,
"w": 88,
"h": 95
}
},
{
"filename": "0023.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 95
},
"frame": {
"x": 89,
"y": 390,
"w": 87,
"h": 95
}
},
{
"filename": "0013.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 89,
"h": 94
},
"frame": {
"x": 0,
"y": 391,
"w": 89,
"h": 94
}
},
{
"filename": "0012.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 14,
"w": 89,
"h": 93
},
"frame": {
"x": 266,
"y": 387,
"w": 89,
"h": 93
}
},
{
"filename": "0019.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 16,
"y": 13,
"w": 85,
"h": 91
},
"frame": {
"x": 266,
"y": 296,
"w": 85,
"h": 91
}
},
{
"filename": "0024.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 13,
"w": 88,
"h": 94
},
"frame": {
"x": 176,
"y": 391,
"w": 88,
"h": 94
}
},
{
"filename": "0010.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 13,
"w": 87,
"h": 94
},
"frame": {
"x": 355,
"y": 387,
"w": 87,
"h": 94
}
},
{
"filename": "0018.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 16,
"y": 11,
"w": 87,
"h": 94
},
"frame": {
"x": 264,
"y": 480,
"w": 87,
"h": 94
}
},
{
"filename": "0026.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 14,
"w": 89,
"h": 93
},
"frame": {
"x": 351,
"y": 481,
"w": 89,
"h": 93
}
},
{
"filename": "0022.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 93
},
"frame": {
"x": 440,
"y": 482,
"w": 87,
"h": 93
}
},
{
"filename": "0021.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 10,
"w": 86,
"h": 94
},
"frame": {
"x": 0,
"y": 485,
"w": 86,
"h": 94
}
},
{
"filename": "0020.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 14,
"w": 85,
"h": 91
},
"frame": {
"x": 86,
"y": 485,
"w": 85,
"h": 91
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:8fd9e1830200ec8e4aac8571cc2d27a6:c966e3efce03c7bae43d7bca6d6dfa62:cedd2711a12bbacba5623505fe88bd92$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -1,20 +1,755 @@
{ "frames": [
{
"filename": "0001.png",
"frame": { "x": 1, "y": 1, "w": 96, "h": 98 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 96, "h": 98 },
"sourceSize": { "w": 96, "h": 98 },
"duration": 100
}
],
"meta": {
"app": "https://www.aseprite.org/",
"version": "1.3.13-x64",
"image": "890-eternamax_3.png",
"format": "RGBA8888",
"size": { "w": 98, "h": 100 },
"scale": "1"
}
}
{
"textures": [
{
"image": "890-eternamax_3.png",
"format": "RGBA8888",
"size": {
"w": 579,
"h": 579
},
"scale": 1,
"frames": [
{
"filename": "0035.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 100,
"h": 98
},
"frame": {
"x": 0,
"y": 0,
"w": 100,
"h": 98
}
},
{
"filename": "0031.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 8,
"w": 95,
"h": 100
},
"frame": {
"x": 100,
"y": 0,
"w": 95,
"h": 100
}
},
{
"filename": "0029.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 8,
"w": 91,
"h": 100
},
"frame": {
"x": 0,
"y": 98,
"w": 91,
"h": 100
}
},
{
"filename": "0001.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 96,
"h": 98
},
"frame": {
"x": 91,
"y": 100,
"w": 96,
"h": 98
}
},
{
"filename": "0032.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 9,
"w": 95,
"h": 99
},
"frame": {
"x": 187,
"y": 100,
"w": 95,
"h": 99
}
},
{
"filename": "0030.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 9,
"y": 10,
"w": 91,
"h": 98
},
"frame": {
"x": 0,
"y": 198,
"w": 91,
"h": 98
}
},
{
"filename": "0007.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 10,
"w": 88,
"h": 98
},
"frame": {
"x": 91,
"y": 198,
"w": 88,
"h": 98
}
},
{
"filename": "0002.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 10,
"w": 95,
"h": 97
},
"frame": {
"x": 195,
"y": 0,
"w": 95,
"h": 97
}
},
{
"filename": "0003.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 179,
"y": 199,
"w": 95,
"h": 97
}
},
{
"filename": "0004.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 274,
"y": 199,
"w": 95,
"h": 97
}
},
{
"filename": "0033.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 95,
"h": 97
},
"frame": {
"x": 290,
"y": 0,
"w": 95,
"h": 97
}
},
{
"filename": "0034.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 11,
"w": 94,
"h": 96
},
"frame": {
"x": 282,
"y": 97,
"w": 94,
"h": 96
}
},
{
"filename": "0028.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 11,
"w": 90,
"h": 97
},
"frame": {
"x": 369,
"y": 193,
"w": 90,
"h": 97
}
},
{
"filename": "0005.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 8,
"y": 13,
"w": 93,
"h": 95
},
"frame": {
"x": 385,
"y": 0,
"w": 93,
"h": 95
}
},
{
"filename": "0017.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 9,
"w": 91,
"h": 96
},
"frame": {
"x": 385,
"y": 95,
"w": 91,
"h": 96
}
},
{
"filename": "0008.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 97
},
"frame": {
"x": 369,
"y": 290,
"w": 87,
"h": 97
}
},
{
"filename": "0009.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 90,
"h": 96
},
"frame": {
"x": 456,
"y": 290,
"w": 90,
"h": 96
}
},
{
"filename": "0015.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 8,
"w": 90,
"h": 96
},
"frame": {
"x": 459,
"y": 191,
"w": 90,
"h": 96
}
},
{
"filename": "0016.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 8,
"w": 90,
"h": 95
},
"frame": {
"x": 476,
"y": 95,
"w": 90,
"h": 95
}
},
{
"filename": "0014.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 89,
"h": 95
},
"frame": {
"x": 478,
"y": 0,
"w": 89,
"h": 95
}
},
{
"filename": "0027.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 89,
"h": 96
},
"frame": {
"x": 456,
"y": 386,
"w": 89,
"h": 96
}
},
{
"filename": "0025.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 11,
"w": 89,
"h": 95
},
"frame": {
"x": 0,
"y": 296,
"w": 89,
"h": 95
}
},
{
"filename": "0006.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 9,
"y": 14,
"w": 89,
"h": 94
},
"frame": {
"x": 89,
"y": 296,
"w": 89,
"h": 94
}
},
{
"filename": "0011.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 88,
"h": 95
},
"frame": {
"x": 178,
"y": 296,
"w": 88,
"h": 95
}
},
{
"filename": "0023.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 95
},
"frame": {
"x": 89,
"y": 390,
"w": 87,
"h": 95
}
},
{
"filename": "0013.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 12,
"w": 89,
"h": 94
},
"frame": {
"x": 0,
"y": 391,
"w": 89,
"h": 94
}
},
{
"filename": "0012.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 14,
"w": 89,
"h": 93
},
"frame": {
"x": 266,
"y": 387,
"w": 89,
"h": 93
}
},
{
"filename": "0019.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 16,
"y": 13,
"w": 85,
"h": 91
},
"frame": {
"x": 266,
"y": 296,
"w": 85,
"h": 91
}
},
{
"filename": "0024.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 13,
"w": 88,
"h": 94
},
"frame": {
"x": 176,
"y": 391,
"w": 88,
"h": 94
}
},
{
"filename": "0010.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 13,
"w": 87,
"h": 94
},
"frame": {
"x": 355,
"y": 387,
"w": 87,
"h": 94
}
},
{
"filename": "0018.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 16,
"y": 11,
"w": 87,
"h": 94
},
"frame": {
"x": 264,
"y": 480,
"w": 87,
"h": 94
}
},
{
"filename": "0026.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 11,
"y": 14,
"w": 89,
"h": 93
},
"frame": {
"x": 351,
"y": 481,
"w": 89,
"h": 93
}
},
{
"filename": "0022.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 12,
"y": 11,
"w": 87,
"h": 93
},
"frame": {
"x": 440,
"y": 482,
"w": 87,
"h": 93
}
},
{
"filename": "0021.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 10,
"w": 86,
"h": 94
},
"frame": {
"x": 0,
"y": 485,
"w": 86,
"h": 94
}
},
{
"filename": "0020.png",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 112,
"h": 112
},
"spriteSourceSize": {
"x": 13,
"y": 14,
"w": 85,
"h": 91
},
"frame": {
"x": 86,
"y": 485,
"w": 85,
"h": 91
}
}
]
}
],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:8fd9e1830200ec8e4aac8571cc2d27a6:c966e3efce03c7bae43d7bca6d6dfa62:cedd2711a12bbacba5623505fe88bd92$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -719,7 +719,7 @@
"888-crowned": [0, 1, 1],
"889": [0, 1, 1],
"889-crowned": [0, 1, 1],
"890-eternamax": [0, 2, 2],
"890-eternamax": [0, 1, 1],
"890": [0, 1, 1],
"891": [1, 1, 1],
"892-gigantamax-rapid": [1, 2, 2],

@ -1 +1 @@
Subproject commit 8538aa3e0f6f38c9c9c74fd0cf6df1e2f8a0bd6d
Subproject commit e98f0eb9c2022bc78b53f0444424c636498e725a

View File

@ -167,7 +167,7 @@ import { ExpGainsSpeed } from "#enums/exp-gains-speed";
import { BattlerTagType } from "#enums/battler-tag-type";
import { FRIENDSHIP_GAIN_FROM_BATTLE } from "#app/data/balance/starters";
import { StatusEffect } from "#enums/status-effect";
import { globalScene, initGlobalScene } from "#app/global-scene";
import { initGlobalScene } from "#app/global-scene";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { HideAbilityPhase } from "#app/phases/hide-ability-phase";
import { timedEventManager } from "./global-event-manager";
@ -2665,7 +2665,7 @@ export default class BattleScene extends SceneBase {
case "mystery_encounter_delibirdy": // Firel Delibirdy
return 82.28;
case "title_afd": // Andr06 - PokéRogue Title Remix (AFD)
return 47.660;
return 47.66;
case "battle_rival_3_afd": // Andr06 - Final N Battle Remix (AFD)
return 49.147;
}
@ -2937,14 +2937,19 @@ export default class BattleScene extends SceneBase {
* @param show Whether to show or hide the bar
*/
public queueAbilityDisplay(pokemon: Pokemon, passive: boolean, show: boolean): void {
this.unshiftPhase(
show
? new ShowAbilityPhase(pokemon.getBattlerIndex(), passive)
: new HideAbilityPhase(pokemon.getBattlerIndex(), passive),
);
this.unshiftPhase(show ? new ShowAbilityPhase(pokemon.getBattlerIndex(), passive) : new HideAbilityPhase());
this.clearPhaseQueueSplice();
}
/**
* Hides the ability bar if it is currently visible
*/
public hideAbilityBar(): void {
if (this.abilityBar.isVisible()) {
this.unshiftPhase(new HideAbilityPhase());
}
}
/**
* Moves everything from nextCommandPhaseQueue to phaseQueue (keeping order)
*/

View File

@ -854,7 +854,8 @@ export class PostDefendStatStageChangeAbAttr extends PostDefendAbAttr {
}
if (this.allOthers) {
const otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents();
const ally = pokemon.getAlly();
const otherPokemon = !Utils.isNullOrUndefined(ally) ? pokemon.getOpponents().concat([ ally ]) : pokemon.getOpponents();
for (const other of otherPokemon) {
globalScene.unshiftPhase(new StatStageChangePhase((other).getBattlerIndex(), false, [ this.stat ], this.stages));
}
@ -2460,12 +2461,12 @@ export class PostSummonAllyHealAbAttr extends PostSummonAbAttr {
}
override canApplyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
return pokemon.getAlly()?.isActive(true);
return pokemon.getAlly()?.isActive(true) ?? false;
}
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
const target = pokemon.getAlly();
if (!simulated) {
if (!simulated && !Utils.isNullOrUndefined(target)) {
globalScene.unshiftPhase(new PokemonHealPhase(target.getBattlerIndex(),
Utils.toDmgValue(pokemon.getMaxHp() / this.healRatio), i18next.t("abilityTriggers:postSummonAllyHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(target), pokemonName: pokemon.name }), true, !this.showAnim));
}
@ -2486,12 +2487,12 @@ export class PostSummonClearAllyStatStagesAbAttr extends PostSummonAbAttr {
}
override canApplyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
return pokemon.getAlly()?.isActive(true);
return pokemon.getAlly()?.isActive(true) ?? false;
}
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
const target = pokemon.getAlly();
if (!simulated) {
if (!simulated && !Utils.isNullOrUndefined(target)) {
for (const s of BATTLE_STATS) {
target.setStatStage(s, 0);
}
@ -2712,7 +2713,7 @@ export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr {
}
const ally = pokemon.getAlly();
if (!ally || ally.getStatStages().every(s => s === 0)) {
if (Utils.isNullOrUndefined(ally) || ally.getStatStages().every(s => s === 0)) {
return false;
}
@ -2721,7 +2722,7 @@ export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr {
override applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
const ally = pokemon.getAlly();
if (!simulated) {
if (!simulated && !Utils.isNullOrUndefined(ally)) {
for (const s of BATTLE_STATS) {
pokemon.setStatStage(s, ally.getStatStage(s));
}
@ -2866,8 +2867,9 @@ export class CommanderAbAttr extends AbAttr {
// another Pokemon, this effect cannot apply.
// TODO: Should this work with X + Dondozo fusions?
return globalScene.currentBattle?.double && pokemon.getAlly()?.species.speciesId === Species.DONDOZO
&& !(pokemon.getAlly().isFainted() || pokemon.getAlly().getTag(BattlerTagType.COMMANDED));
const ally = pokemon.getAlly();
return globalScene.currentBattle?.double && !Utils.isNullOrUndefined(ally) && ally.species.speciesId === Species.DONDOZO
&& !(ally.isFainted() || ally.getTag(BattlerTagType.COMMANDED));
}
override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: null, args: any[]): void {
@ -2877,7 +2879,7 @@ export class CommanderAbAttr extends AbAttr {
// Play an animation of the source jumping into the ally Dondozo's mouth
globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.COMMANDER_APPLY);
// Apply boosts from this effect to the ally Dondozo
pokemon.getAlly().addTag(BattlerTagType.COMMANDED, 0, Moves.NONE, pokemon.id);
pokemon.getAlly()?.addTag(BattlerTagType.COMMANDED, 0, Moves.NONE, pokemon.id);
// Cancel the source Pokemon's next move (if a move is queued)
globalScene.tryRemovePhase((phase) => phase instanceof MovePhase && phase.pokemon === pokemon);
}
@ -4077,7 +4079,7 @@ export class PostTurnStatusHealAbAttr extends PostTurnAbAttr {
*/
export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
private allyTarget: boolean;
private target: Pokemon;
private target: Pokemon | undefined;
constructor(allyTarget = false) {
super(true);
@ -4090,11 +4092,11 @@ export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
} else {
this.target = pokemon;
}
return !Utils.isNullOrUndefined(this.target.status);
return !Utils.isNullOrUndefined(this.target?.status);
}
override applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void {
if (!simulated && this.target.status) {
if (!simulated && this.target?.status) {
globalScene.queueMessage(getStatusEffectHealText(this.target.status?.effect, getPokemonNameWithAffix(this.target)));
this.target.resetStatus(false);
this.target.updateInfo();
@ -5440,6 +5442,8 @@ class ForceSwitchOutHelper {
* It will not flee if it is a Mystery Encounter with fleeing disabled (checked in `getSwitchOutCondition()`) or if it is a wave 10x wild boss
*/
} else {
const allyPokemon = switchOutTarget.getAlly();
if (!globalScene.currentBattle.waveIndex || globalScene.currentBattle.waveIndex % 10 === 0) {
return false;
}
@ -5447,14 +5451,12 @@ class ForceSwitchOutHelper {
if (switchOutTarget.hp > 0) {
switchOutTarget.leaveField(false);
globalScene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
if (globalScene.currentBattle.double) {
const allyPokemon = switchOutTarget.getAlly();
if (globalScene.currentBattle.double && !Utils.isNullOrUndefined(allyPokemon)) {
globalScene.redirectPokemonMoves(switchOutTarget, allyPokemon);
}
}
if (!switchOutTarget.getAlly()?.isActive(true)) {
if (!allyPokemon?.isActive(true)) {
globalScene.clearEnemyHeldItemModifiers();
if (switchOutTarget.hp) {
@ -6440,9 +6442,9 @@ export function initAbilities() {
new Ability(Abilities.CUTE_CHARM, 3)
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
new Ability(Abilities.PLUS, 3)
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5),
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => (p.getAlly()?.hasAbility(a) ?? false)), StatMultiplierAbAttr, Stat.SPATK, 1.5),
new Ability(Abilities.MINUS, 3)
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5),
.conditionalAttr(p => globalScene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => (p.getAlly()?.hasAbility(a) ?? false)), StatMultiplierAbAttr, Stat.SPATK, 1.5),
new Ability(Abilities.FORECAST, 3)
.uncopiable()
.unreplaceable()
@ -6669,7 +6671,7 @@ export function initAbilities() {
.attr(PostDefendMoveDisableAbAttr, 30)
.bypassFaint(),
new Ability(Abilities.HEALER, 5)
.conditionalAttr(pokemon => pokemon.getAlly() && Utils.randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true),
.conditionalAttr(pokemon => !Utils.isNullOrUndefined(pokemon.getAlly()) && Utils.randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true),
new Ability(Abilities.FRIEND_GUARD, 5)
.attr(AlliedFieldDamageReductionAbAttr, 0.75)
.ignorable(),

View File

@ -28,7 +28,6 @@ import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves";
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
@ -1160,9 +1159,11 @@ class TailwindTag extends ArenaTag {
);
}
// Raise attack by one stage if party member has WIND_RIDER ability
// TODO: Ability displays should be handled by the ability
if (pokemon.hasAbility(Abilities.WIND_RIDER)) {
globalScene.unshiftPhase(new ShowAbilityPhase(pokemon.getBattlerIndex()));
globalScene.queueAbilityDisplay(pokemon, false, true);
globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [Stat.ATK], 1, true));
globalScene.queueAbilityDisplay(pokemon, false, false);
}
}
}

View File

@ -15,7 +15,7 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
[Species.VENUSAUR]: { 0: Abilities.GRASSY_SURGE, 1: Abilities.SEED_SOWER, 2: Abilities.FLOWER_VEIL },
[Species.CHARMANDER]: { 0: Abilities.SHEER_FORCE },
[Species.CHARMELEON]: { 0: Abilities.BEAST_BOOST },
[Species.CHARIZARD]: { 0: Abilities.BEAST_BOOST, 1: Abilities.LEVITATE, 2: Abilities.INTIMIDATE, 3: Abilities.UNNERVE },
[Species.CHARIZARD]: { 0: Abilities.BEAST_BOOST, 1: Abilities.LEVITATE, 2: Abilities.TURBOBLAZE, 3: Abilities.UNNERVE },
[Species.SQUIRTLE]: { 0: Abilities.DAUNTLESS_SHIELD },
[Species.WARTORTLE]: { 0: Abilities.DAUNTLESS_SHIELD },
[Species.BLASTOISE]: { 0: Abilities.DAUNTLESS_SHIELD, 1: Abilities.BULLETPROOF, 2: Abilities.BULLETPROOF },
@ -154,14 +154,14 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
[Species.LEAFEON]: { 0: Abilities.GRASSY_SURGE },
[Species.GLACEON]: { 0: Abilities.SNOW_WARNING },
[Species.SYLVEON]: { 0: Abilities.COMPETITIVE },
[Species.PORYGON]: { 0: Abilities.LEVITATE },
[Species.PORYGON2]: { 0: Abilities.LEVITATE },
[Species.PORYGON]: { 0: Abilities.TRANSISTOR },
[Species.PORYGON2]: { 0: Abilities.TRANSISTOR },
[Species.PORYGON_Z]: { 0: Abilities.PROTEAN },
[Species.OMANYTE]: { 0: Abilities.STURDY },
[Species.OMASTAR]: { 0: Abilities.STURDY },
[Species.KABUTO]: { 0: Abilities.TOUGH_CLAWS },
[Species.KABUTOPS]: { 0: Abilities.TOUGH_CLAWS },
[Species.AERODACTYL]: { 0: Abilities.INTIMIDATE, 1: Abilities.DELTA_STREAM },
[Species.AERODACTYL]: { 0: Abilities.INTIMIDATE, 1: Abilities.INTIMIDATE },
[Species.ARTICUNO]: { 0: Abilities.SNOW_WARNING },
[Species.ZAPDOS]: { 0: Abilities.DRIZZLE },
[Species.MOLTRES]: { 0: Abilities.DROUGHT },
@ -309,7 +309,7 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
[Species.SHIFTRY]: { 0: Abilities.SHARPNESS },
[Species.TAILLOW]: { 0: Abilities.AERILATE },
[Species.SWELLOW]: { 0: Abilities.AERILATE },
[Species.WINGULL]: { 0: Abilities.DRIZZLE },
[Species.WINGULL]: { 0: Abilities.WATER_ABSORB },
[Species.PELIPPER]: { 0: Abilities.SWIFT_SWIM },
[Species.RALTS]: { 0: Abilities.NEUROFORCE },
[Species.KIRLIA]: { 0: Abilities.NEUROFORCE },
@ -612,8 +612,8 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
[Species.REUNICLUS]: { 0: Abilities.PSYCHIC_SURGE },
[Species.DUCKLETT]: { 0: Abilities.DRIZZLE },
[Species.SWANNA]: { 0: Abilities.DRIZZLE },
[Species.VANILLITE]: { 0: Abilities.SNOW_WARNING },
[Species.VANILLISH]: { 0: Abilities.SNOW_WARNING },
[Species.VANILLITE]: { 0: Abilities.REFRIGERATE },
[Species.VANILLISH]: { 0: Abilities.REFRIGERATE },
[Species.VANILLUXE]: { 0: Abilities.SLUSH_RUSH },
[Species.DEERLING]: { 0: Abilities.FLOWER_VEIL, 1: Abilities.CUD_CHEW, 2: Abilities.HARVEST, 3: Abilities.FUR_COAT },
[Species.SAWSBUCK]: { 0: Abilities.FLOWER_VEIL, 1: Abilities.CUD_CHEW, 2: Abilities.HARVEST, 3: Abilities.FUR_COAT },
@ -838,7 +838,7 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
[Species.CELESTEELA]: { 0: Abilities.HEATPROOF },
[Species.KARTANA]: { 0: Abilities.TECHNICIAN },
[Species.GUZZLORD]: { 0: Abilities.POISON_HEAL },
[Species.NECROZMA]: { 0: Abilities.BEAST_BOOST, 1: Abilities.FULL_METAL_BODY, 2: Abilities.SHADOW_SHIELD, 3: Abilities.PRISM_ARMOR },
[Species.NECROZMA]: { 0: Abilities.BEAST_BOOST, 1: Abilities.FULL_METAL_BODY, 2: Abilities.SHADOW_SHIELD, 3: Abilities.UNNERVE },
[Species.MAGEARNA]: { 0: Abilities.STEELY_SPIRIT, 1: Abilities.STEELY_SPIRIT },
[Species.MARSHADOW]: { 0: Abilities.IRON_FIST },
[Species.POIPOLE]: { 0: Abilities.LEVITATE },

View File

@ -30,7 +30,6 @@ import { CommonAnimPhase } from "#app/phases/common-anim-phase";
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { MovePhase } from "#app/phases/move-phase";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import type { StatStageChangeCallback } from "#app/phases/stat-stage-change-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import i18next from "#app/plugins/i18n";
@ -1901,12 +1900,14 @@ export class TruantTag extends AbilityBattlerTag {
if (lastMove && lastMove.move !== Moves.NONE) {
(globalScene.getCurrentPhase() as MovePhase).cancel();
globalScene.unshiftPhase(new ShowAbilityPhase(pokemon.id, passive));
// TODO: Ability displays should be handled by the ability
globalScene.queueAbilityDisplay(pokemon, passive, true);
globalScene.queueMessage(
i18next.t("battlerTags:truantLapse", {
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
}),
);
globalScene.queueAbilityDisplay(pokemon, passive, false);
}
return true;

View File

@ -1272,23 +1272,22 @@ function checkSpeciesValidForChallenge(species: PokemonSpecies, props: DexAttrPr
if (soft && isValidForChallenge.value) {
return true;
}
pokemonFormChanges[species.speciesId].forEach(f1 => {
// Exclude form changes that require the mon to be on the field to begin with,
// such as Castform
if (!("item" in f1)) {
return;
const result = pokemonFormChanges[species.speciesId].some(f1 => {
// Exclude form changes that require the mon to be on the field to begin with
if (!("item" in f1.trigger)) {
return false;
}
species.forms.forEach((f2, formIndex) => {
return species.forms.some((f2, formIndex) => {
if (f1.formKey === f2.formKey) {
const formProps = { ...props };
formProps.formIndex = formIndex;
const formProps = { ...props, formIndex };
const isFormValidForChallenge = new Utils.BooleanHolder(true);
applyChallenges(ChallengeType.STARTER_CHOICE, species, isFormValidForChallenge, formProps);
if (isFormValidForChallenge.value) {
return true;
}
return isFormValidForChallenge.value;
}
return false;
});
});
return false;
return result;
}

View File

@ -106,7 +106,6 @@ import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { SwitchPhase } from "#app/phases/switch-phase";
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { SpeciesFormChangeRevertWeatherFormTrigger } from "../pokemon-forms";
import type { GameMode } from "#app/game-mode";
import { applyChallenges, ChallengeType } from "../challenge";
@ -789,9 +788,9 @@ export default class Move implements Localizable {
}
applyPreAttackAbAttrs(VariableMovePowerAbAttr, source, target, this, simulated, power);
if (source.getAlly()) {
applyPreAttackAbAttrs(AllyMoveCategoryPowerBoostAbAttr, source.getAlly(), target, this, simulated, power);
const ally = source.getAlly();
if (!Utils.isNullOrUndefined(ally)) {
applyPreAttackAbAttrs(AllyMoveCategoryPowerBoostAbAttr, ally, target, this, simulated, power);
}
const fieldAuras = new Set(
@ -912,7 +911,8 @@ export default class Move implements Localizable {
];
// ...and cannot enhance Pollen Puff when targeting an ally.
const exceptPollenPuffAlly: boolean = this.id === Moves.POLLEN_PUFF && targets.includes(user.getAlly().getBattlerIndex())
const ally = user.getAlly();
const exceptPollenPuffAlly: boolean = this.id === Moves.POLLEN_PUFF && !Utils.isNullOrUndefined(ally) && targets.includes(ally.getBattlerIndex())
return (!restrictSpread || !isMultiTarget)
&& !this.isChargingMove()
@ -1924,7 +1924,9 @@ export class PartyStatusCureAttr extends MoveEffectAttr {
pokemon.resetStatus();
pokemon.updateInfo();
} else {
globalScene.unshiftPhase(new ShowAbilityPhase(pokemon.id, pokemon.getPassiveAbility()?.id === this.abilityCondition));
// TODO: Ability displays should be handled by the ability
globalScene.queueAbilityDisplay(pokemon, pokemon.getPassiveAbility()?.id === this.abilityCondition, true);
globalScene.queueAbilityDisplay(pokemon, pokemon.getPassiveAbility()?.id === this.abilityCondition, false);
}
}
}
@ -1945,7 +1947,7 @@ export class FlameBurstAttr extends MoveEffectAttr {
const targetAlly = target.getAlly();
const cancelled = new Utils.BooleanHolder(false);
if (targetAlly) {
if (!Utils.isNullOrUndefined(targetAlly)) {
applyAbAttrs(BlockNonDirectDamageAbAttr, targetAlly, cancelled);
}
@ -1958,7 +1960,7 @@ export class FlameBurstAttr extends MoveEffectAttr {
}
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
return target.getAlly() ? -5 : 0;
return !Utils.isNullOrUndefined(target.getAlly()) ? -5 : 0;
}
}
@ -4356,10 +4358,10 @@ export class LastMoveDoublePowerAttr extends VariablePowerAttr {
const userAlly = user.getAlly();
const enemyAlly = enemy?.getAlly();
if (userAlly && userAlly.turnData.acted) {
if (!Utils.isNullOrUndefined(userAlly) && userAlly.turnData.acted) {
pokemonActed.push(userAlly);
}
if (enemyAlly && enemyAlly.turnData.acted) {
if (!Utils.isNullOrUndefined(enemyAlly) && enemyAlly.turnData.acted) {
pokemonActed.push(enemyAlly);
}
}
@ -6161,9 +6163,8 @@ export class RevivalBlessingAttr extends MoveEffectAttr {
pokemon.resetStatus();
pokemon.heal(Math.min(Utils.toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
globalScene.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: getPokemonNameWithAffix(pokemon) }), 0, true);
if (globalScene.currentBattle.double && globalScene.getEnemyParty().length > 1) {
const allyPokemon = user.getAlly();
const allyPokemon = user.getAlly();
if (globalScene.currentBattle.double && globalScene.getEnemyParty().length > 1 && !Utils.isNullOrUndefined(allyPokemon)) {
// Handle cases where revived pokemon needs to get switched in on same turn
if (allyPokemon.isFainted() || allyPokemon === pokemon) {
// Enemy switch phase should be removed and replaced with the revived pkmn switching in
@ -6342,18 +6343,19 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
return false;
}
const allyPokemon = switchOutTarget.getAlly();
if (switchOutTarget.hp > 0) {
switchOutTarget.leaveField(false);
globalScene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
// in double battles redirect potential moves off fled pokemon
if (globalScene.currentBattle.double) {
const allyPokemon = switchOutTarget.getAlly();
if (globalScene.currentBattle.double && !Utils.isNullOrUndefined(allyPokemon)) {
globalScene.redirectPokemonMoves(switchOutTarget, allyPokemon);
}
}
if (!switchOutTarget.getAlly()?.isActive(true)) {
if (!allyPokemon?.isActive(true)) {
globalScene.clearEnemyHeldItemModifiers();
if (switchOutTarget.hp) {
@ -7029,7 +7031,7 @@ export class RepeatMoveAttr extends MoveEffectAttr {
const firstTarget = globalScene.getField()[moveTargets[0]];
if (globalScene.currentBattle.double && moveTargets.length === 1 && firstTarget.isFainted() && firstTarget !== target.getAlly()) {
const ally = firstTarget.getAlly();
if (ally.isActive()) { // ally exists, is not dead and can sponge the blast
if (!Utils.isNullOrUndefined(ally) && ally.isActive()) { // ally exists, is not dead and can sponge the blast
moveTargets = [ ally.getBattlerIndex() ];
}
}
@ -7403,10 +7405,11 @@ export class AbilityCopyAttr extends MoveEffectAttr {
globalScene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
user.setTempAbility(target.getAbility());
const ally = user.getAlly();
if (this.copyToPartner && globalScene.currentBattle?.double && user.getAlly().hp) {
globalScene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(user.getAlly()), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
user.getAlly().setTempAbility(target.getAbility());
if (this.copyToPartner && globalScene.currentBattle?.double && !Utils.isNullOrUndefined(ally) && ally.hp) { // TODO is this the best way to check that the ally is active?
globalScene.queueMessage(i18next.t("moveTriggers:copiedTargetAbility", { pokemonName: getPokemonNameWithAffix(ally), targetName: getPokemonNameWithAffix(target), abilityName: allAbilities[target.getAbility().id].name }));
ally.setTempAbility(target.getAbility());
}
return true;
@ -7414,9 +7417,10 @@ export class AbilityCopyAttr extends MoveEffectAttr {
getCondition(): MoveConditionFunc {
return (user, target, move) => {
const ally = user.getAlly();
let ret = target.getAbility().isCopiable && user.getAbility().isReplaceable;
if (this.copyToPartner && globalScene.currentBattle?.double) {
ret = ret && (!user.getAlly().hp || user.getAlly().getAbility().isReplaceable);
ret = ret && (!ally?.hp || ally?.getAbility().isReplaceable);
} else {
ret = ret && user.getAbility().id !== target.getAbility().id;
}
@ -8187,6 +8191,7 @@ export function getMoveTargets(user: Pokemon, move: Moves, replaceTarget?: MoveT
let set: Pokemon[] = [];
let multiple = false;
const ally: Pokemon | undefined = user.getAlly();
switch (moveTarget) {
case MoveTarget.USER:
@ -8197,7 +8202,7 @@ export function getMoveTargets(user: Pokemon, move: Moves, replaceTarget?: MoveT
case MoveTarget.OTHER:
case MoveTarget.ALL_NEAR_OTHERS:
case MoveTarget.ALL_OTHERS:
set = (opponents.concat([ user.getAlly() ]));
set = !Utils.isNullOrUndefined(ally) ? (opponents.concat([ ally ])) : opponents;
multiple = moveTarget === MoveTarget.ALL_NEAR_OTHERS || moveTarget === MoveTarget.ALL_OTHERS;
break;
case MoveTarget.NEAR_ENEMY:
@ -8214,21 +8219,22 @@ export function getMoveTargets(user: Pokemon, move: Moves, replaceTarget?: MoveT
return { targets: [ -1 as BattlerIndex ], multiple: false };
case MoveTarget.NEAR_ALLY:
case MoveTarget.ALLY:
set = [ user.getAlly() ];
set = !Utils.isNullOrUndefined(ally) ? [ ally ] : [];
break;
case MoveTarget.USER_OR_NEAR_ALLY:
case MoveTarget.USER_AND_ALLIES:
case MoveTarget.USER_SIDE:
set = [ user, user.getAlly() ];
set = !Utils.isNullOrUndefined(ally) ? [ user, ally ] : [ user ];
multiple = moveTarget !== MoveTarget.USER_OR_NEAR_ALLY;
break;
case MoveTarget.ALL:
case MoveTarget.BOTH_SIDES:
set = [ user, user.getAlly() ].concat(opponents);
set = (!Utils.isNullOrUndefined(ally) ? [ user, ally ] : [ user ]).concat(opponents);
multiple = true;
break;
case MoveTarget.CURSE:
set = user.getTypes(true).includes(PokemonType.GHOST) ? (opponents.concat([ user.getAlly() ])) : [ user ];
const extraTargets = !Utils.isNullOrUndefined(ally) ? [ ally ] : [];
set = user.getTypes(true).includes(PokemonType.GHOST) ? (opponents.concat(extraTargets)) : [ user ];
break;
}
@ -10122,7 +10128,7 @@ export function initMoves() {
.attr(StatStageChangeAttr, [ Stat.DEF, Stat.SPDEF ], 1, false, { condition: (user, target, move) => !![ Abilities.PLUS, Abilities.MINUS ].find(a => target.hasAbility(a, false)) })
.ignoresSubstitute()
.target(MoveTarget.USER_AND_ALLIES)
.condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p.hasAbility(a, false)))),
.condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p?.hasAbility(a, false)))),
new StatusMove(Moves.HAPPY_HOUR, PokemonType.NORMAL, -1, 30, -1, 0, 6) // No animation
.attr(AddArenaTagAttr, ArenaTagType.HAPPY_HOUR, null, true)
.target(MoveTarget.USER_SIDE),
@ -10312,7 +10318,7 @@ export function initMoves() {
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], 1, false, { condition: (user, target, move) => !![ Abilities.PLUS, Abilities.MINUS ].find(a => target.hasAbility(a, false)) })
.ignoresSubstitute()
.target(MoveTarget.USER_AND_ALLIES)
.condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p.hasAbility(a, false)))),
.condition((user, target, move) => !![ user, user.getAlly() ].filter(p => p?.isActive()).find(p => !![ Abilities.PLUS, Abilities.MINUS ].find(a => p?.hasAbility(a, false)))),
new AttackMove(Moves.THROAT_CHOP, PokemonType.DARK, MoveCategory.PHYSICAL, 80, 100, 15, 100, 0, 7)
.attr(AddBattlerTagAttr, BattlerTagType.THROAT_CHOPPED),
new AttackMove(Moves.POLLEN_PUFF, PokemonType.BUG, MoveCategory.SPECIAL, 90, 100, 15, -1, 0, 7)

View File

@ -985,12 +985,11 @@ function doTradeReceivedSequence(
function generateRandomTraderName() {
const length = TrainerType.YOUNGSTER - TrainerType.ACE_TRAINER + 1;
// +1 avoids TrainerType.UNKNOWN
const trainerTypePool = i18next.t("trainersCommon:" + TrainerType[randInt(length) + 1], { returnObjects: true });
const classKey = `trainersCommon:${TrainerType[randInt(length) + 1]}`;
// Some trainers have 2 gendered pools, some do not
const gender = randInt(2) === 0 ? "MALE" : "FEMALE";
const trainerNameString = randSeedItem(
Object.values(trainerTypePool.hasOwnProperty(gender) ? trainerTypePool[gender] : trainerTypePool),
) as string;
const genderKey = i18next.exists(`${classKey}.MALE`) ? (randInt(2) === 0 ? ".MALE" : ".FEMALE") : "";
const trainerNameKey = randSeedItem(Object.keys(i18next.t(`${classKey}${genderKey}`, { returnObjects: true })));
const trainerNameString = i18next.t(`${classKey}${genderKey}.${trainerNameKey}`);
// Some names have an '&' symbol and need to be trimmed to a single name instead of a double name
const trainerNames = trainerNameString.split(" & ");
return trainerNames[randInt(trainerNames.length)];

View File

@ -40,7 +40,6 @@ import { TrainerType } from "#enums/trainer-type";
import { Abilities } from "#enums/abilities";
import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "#app/data/pokemon-forms";
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { WeatherType } from "#enums/weather-type";
import { FieldEffectModifier } from "#app/modifier/modifier";
@ -378,7 +377,6 @@ export class Arena {
const isCherrimWithFlowerGift = p.hasAbility(Abilities.FLOWER_GIFT) && p.species.speciesId === Species.CHERRIM;
if (isCastformWithForecast || isCherrimWithFlowerGift) {
new ShowAbilityPhase(p.getBattlerIndex());
globalScene.triggerPokemonFormChange(p, SpeciesFormChangeWeatherTrigger);
}
});
@ -395,7 +393,6 @@ export class Arena {
p.hasAbility(Abilities.FLOWER_GIFT, false, true) && p.species.speciesId === Species.CHERRIM;
if (isCastformWithForecast || isCherrimWithFlowerGift) {
new ShowAbilityPhase(p.getBattlerIndex());
return globalScene.triggerPokemonFormChange(p, SpeciesFormChangeRevertWeatherFormTrigger);
}
});

View File

@ -1447,7 +1447,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
const ally = this.getAlly();
if (ally) {
if (!Utils.isNullOrUndefined(ally)) {
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, stat, statValue, simulated, this, move?.hasFlag(MoveFlags.IGNORE_ABILITIES) || ignoreAllyAbility);
}
@ -3714,7 +3714,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
: i18next.t("arenaTag:yourTeam");
}
getAlly(): Pokemon {
getAlly(): Pokemon | undefined {
return (
this.isPlayer()
? globalScene.getPlayerField()
@ -3900,7 +3900,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
);
const ally = this.getAlly();
if (ally) {
if (!isNullOrUndefined(ally)) {
const ignore = this.hasAbilityWithAttr(MoveAbilityBypassAbAttr) || sourceMove.hasFlag(MoveFlags.IGNORE_ABILITIES);
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, Stat.ACC, accuracyMultiplier, false, this, ignore);
applyAllyStatMultiplierAbAttrs(AllyStatMultiplierAbAttr, ally, Stat.EVA, evasionMultiplier, false, this, ignore);
@ -4336,11 +4336,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
damage,
);
const ally = this.getAlly();
/** Additionally apply friend guard damage reduction if ally has it. */
if (globalScene.currentBattle.double && this.getAlly()?.isActive(true)) {
if (globalScene.currentBattle.double && !isNullOrUndefined(ally) && ally.isActive(true)) {
applyPreDefendAbAttrs(
AlliedFieldDamageReductionAbAttr,
this.getAlly(),
ally,
source,
move,
cancelled,

View File

@ -33,14 +33,16 @@ export default class Trainer extends Phaser.GameObjects.Container {
public partyTemplateIndex: number;
public name: string;
public partnerName: string;
public nameKey: string;
public partnerNameKey: string | undefined;
public originalIndexes: { [key: number]: number } = {};
constructor(
trainerType: TrainerType,
variant: TrainerVariant,
partyTemplateIndex?: number,
name?: string,
partnerName?: string,
nameKey?: string,
partnerNameKey?: string,
trainerConfigOverride?: TrainerConfig,
) {
super(globalScene, -72, 80);
@ -59,28 +61,41 @@ export default class Trainer extends Phaser.GameObjects.Container {
: Utils.randSeedWeightedItem(this.config.partyTemplates.map((_, i) => i)),
this.config.partyTemplates.length - 1,
);
if (i18next.exists("trainersCommon:" + TrainerType[trainerType], { returnObjects: true })) {
const namePool = i18next.t("trainersCommon:" + TrainerType[trainerType], { returnObjects: true });
this.name =
name ||
Utils.randSeedItem(
Object.values(
namePool.hasOwnProperty("MALE")
? namePool[variant === TrainerVariant.FEMALE ? "FEMALE" : "MALE"]
: namePool,
),
const classKey = `trainersCommon:${TrainerType[trainerType]}`;
if (i18next.exists(classKey, { returnObjects: true })) {
if (nameKey) {
this.nameKey = nameKey;
} else {
const genderKey = i18next.exists(`${classKey}.MALE`)
? variant === TrainerVariant.FEMALE
? ".FEMALE"
: ".MALE"
: "";
const trainerKey = Utils.randSeedItem(
Object.keys(i18next.t(`${classKey}${genderKey}`, { returnObjects: true })),
);
this.nameKey = `${classKey}${genderKey}.${trainerKey}`;
}
this.name = i18next.t(this.nameKey);
if (variant === TrainerVariant.DOUBLE) {
if (this.config.doubleOnly) {
if (partnerName) {
this.partnerName = partnerName;
if (partnerNameKey) {
this.partnerNameKey = partnerNameKey;
this.partnerName = i18next.t(this.partnerNameKey);
} else {
[this.name, this.partnerName] = this.name.split(" & ");
}
} else {
this.partnerName =
partnerName ||
Utils.randSeedItem(Object.values(namePool.hasOwnProperty("FEMALE") ? namePool["FEMALE"] : namePool));
const partnerGenderKey = i18next.exists(`${classKey}.FEMALE`) ? ".FEMALE" : "";
const partnerTrainerKey = Utils.randSeedItem(
Object.keys(
i18next.t(`${classKey}${partnerGenderKey}`, {
returnObjects: true,
}),
),
);
this.partnerNameKey = `${classKey}${partnerGenderKey}.${partnerTrainerKey}`;
this.partnerName = i18next.t(this.partnerNameKey);
}
}
}

View File

@ -2823,37 +2823,48 @@ const modifierPool: ModifierPool = {
modifierTypes.MYSTICAL_ROCK,
(party: Pokemon[]) => {
return party.some(p => {
const moveset = p.getMoveset(true).map(m => m.moveId);
let isHoldingMax = false;
for (const i of p.getHeldItems()) {
if (i.type.id === "MYSTICAL_ROCK") {
isHoldingMax = i.getStackCount() === i.getMaxStackCount();
break;
}
}
const hasAbility = [
Abilities.DRIZZLE,
Abilities.ORICHALCUM_PULSE,
Abilities.DRIZZLE,
Abilities.SAND_STREAM,
Abilities.SAND_SPIT,
Abilities.SNOW_WARNING,
Abilities.ELECTRIC_SURGE,
Abilities.HADRON_ENGINE,
Abilities.PSYCHIC_SURGE,
Abilities.GRASSY_SURGE,
Abilities.SEED_SOWER,
Abilities.MISTY_SURGE,
].some(a => p.hasAbility(a, false, true));
if (!isHoldingMax) {
const moveset = p.getMoveset(true).map(m => m.moveId);
const hasMoves = [
Moves.SUNNY_DAY,
Moves.RAIN_DANCE,
Moves.SANDSTORM,
Moves.SNOWSCAPE,
Moves.HAIL,
Moves.CHILLY_RECEPTION,
Moves.ELECTRIC_TERRAIN,
Moves.PSYCHIC_TERRAIN,
Moves.GRASSY_TERRAIN,
Moves.MISTY_TERRAIN,
].some(m => moveset.includes(m));
const hasAbility = [
Abilities.DROUGHT,
Abilities.ORICHALCUM_PULSE,
Abilities.DRIZZLE,
Abilities.SAND_STREAM,
Abilities.SAND_SPIT,
Abilities.SNOW_WARNING,
Abilities.ELECTRIC_SURGE,
Abilities.HADRON_ENGINE,
Abilities.PSYCHIC_SURGE,
Abilities.GRASSY_SURGE,
Abilities.SEED_SOWER,
Abilities.MISTY_SURGE,
].some(a => p.hasAbility(a, false, true));
return hasAbility || hasMoves;
const hasMoves = [
Moves.SUNNY_DAY,
Moves.RAIN_DANCE,
Moves.SANDSTORM,
Moves.SNOWSCAPE,
Moves.HAIL,
Moves.CHILLY_RECEPTION,
Moves.ELECTRIC_TERRAIN,
Moves.PSYCHIC_TERRAIN,
Moves.GRASSY_TERRAIN,
Moves.MISTY_TERRAIN,
].some(m => moveset.includes(m));
return hasAbility || hasMoves;
}
return false;
})
? 10
: 0;

View File

@ -39,7 +39,7 @@ export class EnemyCommandPhase extends FieldPhase {
if (
battle.double &&
enemyPokemon.hasAbility(Abilities.COMMANDER) &&
enemyPokemon.getAlly().getTag(BattlerTagType.COMMANDED)
enemyPokemon.getAlly()?.getTag(BattlerTagType.COMMANDED)
) {
this.skipTurn = true;
}

View File

@ -209,8 +209,8 @@ export class FaintPhase extends PokemonPhase {
}
// in double battles redirect potential moves off fainted pokemon
if (globalScene.currentBattle.double) {
const allyPokemon = pokemon.getAlly();
const allyPokemon = pokemon.getAlly();
if (globalScene.currentBattle.double && !isNullOrUndefined(allyPokemon)) {
globalScene.redirectPokemonMoves(pokemon, allyPokemon);
}

View File

@ -45,6 +45,8 @@ export class GameOverPhase extends BattlePhase {
start() {
super.start();
globalScene.hideAbilityBar();
// Failsafe if players somehow skip floor 200 in classic mode
if (globalScene.gameMode.isClassic && globalScene.currentBattle.waveIndex > 200) {
this.isVictory = true;

View File

@ -1,27 +1,12 @@
import { globalScene } from "#app/global-scene";
import type { BattlerIndex } from "#app/battle";
import { PokemonPhase } from "./pokemon-phase";
export class HideAbilityPhase extends PokemonPhase {
private passive: boolean;
constructor(battlerIndex: BattlerIndex, passive = false) {
super(battlerIndex);
this.passive = passive;
}
import { Phase } from "#app/phase";
export class HideAbilityPhase extends Phase {
start() {
super.start();
const pokemon = this.getPokemon();
if (pokemon) {
globalScene.abilityBar.hide().then(() => {
this.end();
});
} else {
globalScene.abilityBar.hide().then(() => {
this.end();
}
});
}
}

View File

@ -69,6 +69,7 @@ import type { Phase } from "#app/phase";
import { ShowAbilityPhase } from "./show-ability-phase";
import { MovePhase } from "./move-phase";
import { MoveEndPhase } from "./move-end-phase";
import { HideAbilityPhase } from "#app/phases/hide-ability-phase";
export class MoveEffectPhase extends PokemonPhase {
public move: PokemonMove;
@ -326,12 +327,14 @@ export class MoveEffectPhase extends PokemonPhase {
? getMoveTargets(target, move.id).targets
: [user.getBattlerIndex()];
if (!isReflecting) {
// TODO: Ability displays should be handled by the ability
queuedPhases.push(
new ShowAbilityPhase(
target.getBattlerIndex(),
target.getPassiveAbility().hasAttr(ReflectStatusMoveAbAttr),
),
);
queuedPhases.push(new HideAbilityPhase());
}
queuedPhases.push(

View File

@ -42,7 +42,6 @@ import { CommonAnimPhase } from "#app/phases/common-anim-phase";
import { MoveChargePhase } from "#app/phases/move-charge-phase";
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { MoveEndPhase } from "#app/phases/move-end-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { NumberHolder } from "#app/utils";
import { Abilities } from "#enums/abilities";
import { ArenaTagType } from "#enums/arena-tag-type";
@ -535,11 +534,16 @@ export class MovePhase extends BattlePhase {
if (this.pokemon.hasAbilityWithAttr(BlockRedirectAbAttr)) {
redirectTarget.value = currentTarget;
globalScene.unshiftPhase(
new ShowAbilityPhase(
this.pokemon.getBattlerIndex(),
this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr),
),
// TODO: Ability displays should be handled by the ability
globalScene.queueAbilityDisplay(
this.pokemon,
this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr),
true,
);
globalScene.queueAbilityDisplay(
this.pokemon,
this.pokemon.getPassiveAbility().hasAttr(BlockRedirectAbAttr),
false,
);
}

View File

@ -42,8 +42,12 @@ export class RevivalBlessingPhase extends BattlePhase {
true,
);
if (globalScene.currentBattle.double && globalScene.getPlayerParty().length > 1) {
const allyPokemon = this.user.getAlly();
const allyPokemon = this.user.getAlly();
if (
globalScene.currentBattle.double &&
globalScene.getPlayerParty().length > 1 &&
!Utils.isNullOrUndefined(allyPokemon)
) {
if (slotIndex <= 1) {
// Revived ally pokemon
globalScene.unshiftPhase(

View File

@ -35,7 +35,7 @@ export class ShowAbilityPhase extends PokemonPhase {
// If the bar is already out, hide it before showing the new one
if (globalScene.abilityBar.isVisible()) {
globalScene.unshiftPhase(new HideAbilityPhase(this.battlerIndex, this.passive));
globalScene.unshiftPhase(new HideAbilityPhase());
globalScene.unshiftPhase(new ShowAbilityPhase(this.battlerIndex, this.passive));
return this.end();
}

View File

@ -17,7 +17,7 @@ import type Pokemon from "#app/field/pokemon";
import { getPokemonNameWithAffix } from "#app/messages";
import { ResetNegativeStatStageModifier } from "#app/modifier/modifier";
import { handleTutorial, Tutorial } from "#app/tutorial";
import { NumberHolder, BooleanHolder } from "#app/utils";
import { NumberHolder, BooleanHolder, isNullOrUndefined } from "#app/utils";
import i18next from "i18next";
import { PokemonPhase } from "./pokemon-phase";
import { Stat, type BattleStat, getStatKey, getStatStageChangeDescriptionKey } from "#enums/stat";
@ -161,7 +161,7 @@ export class StatStageChangePhase extends PokemonPhase {
pokemon,
);
const ally = pokemon.getAlly();
if (ally) {
if (!isNullOrUndefined(ally)) {
applyPreStatStageChangeAbAttrs(
ConditionalUserFieldProtectStatAbAttr,
ally,

View File

@ -28,6 +28,8 @@ export class TurnEndPhase extends FieldPhase {
globalScene.currentBattle.incrementTurn();
globalScene.eventTarget.dispatchEvent(new TurnEndEvent(globalScene.currentBattle.turn));
globalScene.hideAbilityBar();
const handlePokemon = (pokemon: Pokemon) => {
if (!pokemon.switchOutStatus) {
pokemon.lapseTags(BattlerTagLapseType.TURN_END);

View File

@ -1793,7 +1793,9 @@ export class GameData {
const dexEntry = this.dexData[species.speciesId];
const caughtAttr = dexEntry.caughtAttr;
const formIndex = pokemon.formIndex;
const dexAttr = pokemon.getDexAttr();
// This makes sure that we do not try to unlock data which cannot be unlocked
const dexAttr = pokemon.getDexAttr() & species.getFullUnlocksData();
// Mark as caught
dexEntry.caughtAttr |= dexAttr;
@ -1803,6 +1805,10 @@ export class GameData {
// always true except for the case of Urshifu.
const formKey = pokemon.getFormKey();
if (formIndex > 0) {
// In case a Pikachu with formIndex > 0 was unlocked, base form Pichu is also unlocked
if (pokemon.species.speciesId === Species.PIKACHU && species.speciesId === Species.PICHU) {
dexEntry.caughtAttr |= globalScene.gameData.getFormAttr(0);
}
if (pokemon.species.speciesId === Species.URSHIFU) {
if (formIndex === 2) {
dexEntry.caughtAttr |= globalScene.gameData.getFormAttr(0);

View File

@ -5,8 +5,8 @@ export default class TrainerData {
public trainerType: TrainerType;
public variant: TrainerVariant;
public partyTemplateIndex: number;
public name: string;
public partnerName: string;
public nameKey: string;
public partnerNameKey: string | undefined;
constructor(source: Trainer | any) {
const sourceTrainer = source instanceof Trainer ? (source as Trainer) : null;
@ -17,11 +17,11 @@ export default class TrainerData {
? TrainerVariant.FEMALE
: TrainerVariant.DEFAULT;
this.partyTemplateIndex = source.partyMemberTemplateIndex;
this.name = source.name;
this.partnerName = source.partnerName;
this.nameKey = source.nameKey;
this.partnerNameKey = source.partnerNameKey;
}
toTrainer(): Trainer {
return new Trainer(this.trainerType, this.variant, this.partyTemplateIndex, this.name, this.partnerName);
return new Trainer(this.trainerType, this.variant, this.partyTemplateIndex, this.nameKey, this.partnerNameKey);
}
}

View File

@ -10,6 +10,9 @@ import * as v1_1_0 from "./versions/v1_1_0";
// --- v1.7.0 PATCHES --- //
import * as v1_7_0 from "./versions/v1_7_0";
// --- v1.8.3 PATCHES --- //
import * as v1_8_3 from "./versions/v1_8_3";
const LATEST_VERSION = version.split(".").map(value => Number.parseInt(value));
/**
@ -174,6 +177,12 @@ class SystemVersionConverter extends VersionConverter {
console.log("Applying v1.7.0 system data migration!");
this.callMigrators(data, v1_7_0.systemMigrators);
}
if (curMinor === 8) {
if (curPatch <= 2) {
console.log("Applying v1.8.3 system data migration!");
this.callMigrators(data, v1_8_3.systemMigrators);
}
}
}
console.log(`System data successfully migrated to v${version}!`);

View File

@ -0,0 +1,30 @@
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { DexAttr, type SystemSaveData } from "#app/system/game-data";
import { Species } from "#enums/species";
export const systemMigrators = [
/**
* If a starter is caught, but the only forms registered as caught are not starterSelectable,
* unlock the default form.
* @param data {@linkcode SystemSaveData}
*/
function migratePichuForms(data: SystemSaveData) {
if (data.starterData && data.dexData) {
// This is Pichu's Pokédex number
const sd = 172;
const caughtAttr = data.dexData[sd]?.caughtAttr;
const species = getPokemonSpecies(sd);
// An extra check because you never know
if (species.speciesId === Species.PICHU && caughtAttr) {
// Ensuring that only existing forms are unlocked
data.dexData[sd].caughtAttr &= species.getFullUnlocksData();
// If no forms are unlocked now, since Pichu is caught, we unlock form 0
data.dexData[sd].caughtAttr |= DexAttr.DEFAULT_FORM;
}
}
},
] as const;
export const settingsMigrators = [] as const;
export const sessionMigrators = [] as const;

View File

@ -9,7 +9,6 @@ import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { BattlerIndex } from "#app/battle";
describe("Abilities - Parental Bond", () => {
let phaserGame: Phaser.Game;
@ -427,21 +426,4 @@ describe("Abilities - Parental Bond", () => {
// TODO: Update hit count to 1 once Future Sight is fixed to not activate abilities if user is off the field
expect(enemyPokemon.damageAndUpdate).toHaveBeenCalledTimes(2);
});
it("should not allow Pollen Puff to heal ally more than once", async () => {
game.override.battleType("double").moveset([Moves.POLLEN_PUFF, Moves.ENDURE]);
await game.classicMode.startBattle([Species.BULBASAUR, Species.OMANYTE]);
const [, rightPokemon] = game.scene.getPlayerField();
rightPokemon.damageAndUpdate(rightPokemon.hp - 1);
game.move.select(Moves.POLLEN_PUFF, 0, BattlerIndex.PLAYER_2);
game.move.select(Moves.ENDURE, 1);
await game.toNextTurn();
// Pollen Puff heals with a ratio of 0.5, as long as Pollen Puff triggers only once the pokemon will always be <= (0.5 * Max HP) + 1
expect(rightPokemon.hp).toBeLessThanOrEqual(0.5 * rightPokemon.getMaxHp() + 1);
});
});

View File

@ -0,0 +1,64 @@
import { BattlerIndex } from "#app/battle";
import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("Moves - Pollen Puff", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([Moves.POLLEN_PUFF])
.ability(Abilities.BALL_FETCH)
.battleType("single")
.disableCrits()
.enemySpecies(Species.MAGIKARP)
.enemyAbility(Abilities.BALL_FETCH)
.enemyMoveset(Moves.SPLASH);
});
it("should not heal more than once when the user has a source of multi-hit", async () => {
game.override.battleType("double").moveset([Moves.POLLEN_PUFF, Moves.ENDURE]).ability(Abilities.PARENTAL_BOND);
await game.classicMode.startBattle([Species.BULBASAUR, Species.OMANYTE]);
const [_, rightPokemon] = game.scene.getPlayerField();
rightPokemon.damageAndUpdate(rightPokemon.hp - 1);
game.move.select(Moves.POLLEN_PUFF, 0, BattlerIndex.PLAYER_2);
game.move.select(Moves.ENDURE, 1);
await game.phaseInterceptor.to("BerryPhase");
// Pollen Puff heals with a ratio of 0.5, as long as Pollen Puff triggers only once the pokemon will always be <= (0.5 * Max HP) + 1
expect(rightPokemon.hp).toBeLessThanOrEqual(0.5 * rightPokemon.getMaxHp() + 1);
});
it("should damage an enemy multiple times when the user has a source of multi-hit", async () => {
game.override.moveset([Moves.POLLEN_PUFF]).ability(Abilities.PARENTAL_BOND).enemyLevel(100);
await game.classicMode.startBattle([Species.MAGIKARP]);
const target = game.scene.getEnemyPokemon()!;
game.move.select(Moves.POLLEN_PUFF);
await game.phaseInterceptor.to("BerryPhase");
expect(target.battleData.hitCount).toBe(2);
});
});