mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 15:32:18 +02:00
Merge branch 'beta' into trick
This commit is contained in:
commit
b0ee897d5b
Binary file not shown.
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 4.0 KiB |
@ -9940,12 +9940,12 @@
|
||||
],
|
||||
"672": [
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"673": [
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"677": [
|
||||
@ -10806,7 +10806,7 @@
|
||||
"962": [
|
||||
1,
|
||||
1,
|
||||
2
|
||||
1
|
||||
],
|
||||
"967": [
|
||||
0,
|
||||
@ -11095,4 +11095,4 @@
|
||||
1
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,20 @@
|
||||
{
|
||||
"1": {
|
||||
"3d3128": "69112a",
|
||||
"000000": "000000",
|
||||
"67615b": "9e2c3d",
|
||||
"615140": "89431b",
|
||||
"7e6d5a": "b3743e",
|
||||
"554538": "642509",
|
||||
"efeded": "f8e2b7",
|
||||
"beb8b6": "e3a378",
|
||||
"0e5d58": "8c6859",
|
||||
"09a77c": "f8f0e2",
|
||||
"0d8374": "d2af94",
|
||||
"c16a3f": "321512",
|
||||
"c6b379": "552d30",
|
||||
"a8905c": "4b2525"
|
||||
},
|
||||
"2": {
|
||||
"3d3128": "161526",
|
||||
"000000": "000000",
|
||||
@ -15,4 +31,4 @@
|
||||
"c6b379": "9f5f9b",
|
||||
"a8905c": "854d87"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,965 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "672_2.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 282,
|
||||
"h": 282
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0021.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0022.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0023.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0024.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0045.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 42,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 42,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 84,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 126,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 168,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0018.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 210,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0019.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 41,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0020.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 82,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0025.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 123,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0026.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 164,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0027.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 205,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0042.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 41,
|
||||
"y": 42,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0043.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 41,
|
||||
"y": 84,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0044.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 41,
|
||||
"y": 126,
|
||||
"w": 41,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0008.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 41,
|
||||
"y": 168,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0009.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 41,
|
||||
"y": 209,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0010.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 82,
|
||||
"y": 42,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0015.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 123,
|
||||
"y": 42,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0016.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 164,
|
||||
"y": 42,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0017.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 205,
|
||||
"y": 42,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0028.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 82,
|
||||
"y": 83,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0029.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 82,
|
||||
"y": 124,
|
||||
"w": 41,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0040.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 40,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 82,
|
||||
"y": 165,
|
||||
"w": 40,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0041.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 40,
|
||||
"h": 42
|
||||
},
|
||||
"frame": {
|
||||
"x": 82,
|
||||
"y": 207,
|
||||
"w": 40,
|
||||
"h": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0011.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 122,
|
||||
"y": 165,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0012.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 122,
|
||||
"y": 206,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0013.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 123,
|
||||
"y": 83,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0014.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 123,
|
||||
"y": 124,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0037.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 165,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0038.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 206,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0039.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 163,
|
||||
"y": 83,
|
||||
"w": 40,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0030.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"w": 41,
|
||||
"h": 40
|
||||
},
|
||||
"frame": {
|
||||
"x": 163,
|
||||
"y": 124,
|
||||
"w": 41,
|
||||
"h": 40
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0031.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"w": 41,
|
||||
"h": 40
|
||||
},
|
||||
"frame": {
|
||||
"x": 203,
|
||||
"y": 83,
|
||||
"w": 41,
|
||||
"h": 40
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0032.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
},
|
||||
"frame": {
|
||||
"x": 202,
|
||||
"y": 164,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0033.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
},
|
||||
"frame": {
|
||||
"x": 204,
|
||||
"y": 123,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0034.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
},
|
||||
"frame": {
|
||||
"x": 242,
|
||||
"y": 163,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0035.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
},
|
||||
"frame": {
|
||||
"x": 242,
|
||||
"y": 203,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0036.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 41,
|
||||
"h": 42
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
},
|
||||
"frame": {
|
||||
"x": 202,
|
||||
"y": 204,
|
||||
"w": 40,
|
||||
"h": 40
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:b36f1de558a8fa8ac8b56a9ba43a0dfd:5fe84a3f522e543bfbbfe0837355266b:2e4767b7cd134fc0ab1bb6e9eee82bc7$"
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 28 KiB |
@ -1,4 +1,20 @@
|
||||
{
|
||||
"1": {
|
||||
"3d3128": "5a0e24",
|
||||
"000000": "000000",
|
||||
"554538": "471405",
|
||||
"67615b": "8f2837",
|
||||
"0d835a": "d2af94",
|
||||
"0e5d58": "8c6352",
|
||||
"74593a": "61240a",
|
||||
"09a766": "f8f0e2",
|
||||
"cabfbb": "e3a378",
|
||||
"efeded": "f8e2b7",
|
||||
"a8905c": "9e4e21",
|
||||
"c6b379": "ce8648",
|
||||
"ae492a": "321512",
|
||||
"c16a3f": "552d30"
|
||||
},
|
||||
"2": {
|
||||
"3d3128": "121123",
|
||||
"000000": "000000",
|
||||
@ -15,4 +31,4 @@
|
||||
"ae492a": "612c6b",
|
||||
"c16a3f": "9f5f9b"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,965 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "673_2.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 384,
|
||||
"h": 384
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0029.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0039.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0030.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 62,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0038.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 62,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0031.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 124,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0032.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 186,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0033.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 248,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0035.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 248,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0034.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 310,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0036.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 65,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0037.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 62,
|
||||
"y": 65,
|
||||
"w": 62,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0028.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 61,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 124,
|
||||
"y": 65,
|
||||
"w": 61,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0040.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 61,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 124,
|
||||
"y": 65,
|
||||
"w": 61,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0026.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 60,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 185,
|
||||
"y": 65,
|
||||
"w": 60,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0027.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 60,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 245,
|
||||
"y": 65,
|
||||
"w": 60,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0041.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 60,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 305,
|
||||
"y": 65,
|
||||
"w": 60,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0042.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 60,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 130,
|
||||
"w": 60,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0013.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"w": 60,
|
||||
"h": 62
|
||||
},
|
||||
"frame": {
|
||||
"x": 60,
|
||||
"y": 130,
|
||||
"w": 60,
|
||||
"h": 62
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 120,
|
||||
"y": 130,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0023.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 120,
|
||||
"y": 130,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0024.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 120,
|
||||
"y": 130,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0045.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 120,
|
||||
"y": 130,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 60,
|
||||
"y": 192,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0022.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 60,
|
||||
"y": 192,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0025.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 60,
|
||||
"y": 192,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0043.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 60,
|
||||
"y": 192,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0021.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 195,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0044.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
},
|
||||
"frame": {
|
||||
"x": 179,
|
||||
"y": 130,
|
||||
"w": 59,
|
||||
"h": 65
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
},
|
||||
"frame": {
|
||||
"x": 238,
|
||||
"y": 130,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
},
|
||||
"frame": {
|
||||
"x": 238,
|
||||
"y": 130,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
},
|
||||
"frame": {
|
||||
"x": 238,
|
||||
"y": 194,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
},
|
||||
"frame": {
|
||||
"x": 59,
|
||||
"y": 257,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0019.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 260,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0020.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
},
|
||||
"frame": {
|
||||
"x": 117,
|
||||
"y": 257,
|
||||
"w": 58,
|
||||
"h": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0012.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 58,
|
||||
"h": 62
|
||||
},
|
||||
"frame": {
|
||||
"x": 119,
|
||||
"y": 195,
|
||||
"w": 58,
|
||||
"h": 62
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0018.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 57,
|
||||
"h": 64
|
||||
},
|
||||
"frame": {
|
||||
"x": 175,
|
||||
"y": 257,
|
||||
"w": 57,
|
||||
"h": 64
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0014.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 58,
|
||||
"h": 62
|
||||
},
|
||||
"frame": {
|
||||
"x": 177,
|
||||
"y": 195,
|
||||
"w": 58,
|
||||
"h": 62
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"w": 57,
|
||||
"h": 63
|
||||
},
|
||||
"frame": {
|
||||
"x": 232,
|
||||
"y": 258,
|
||||
"w": 57,
|
||||
"h": 63
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0008.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"w": 57,
|
||||
"h": 63
|
||||
},
|
||||
"frame": {
|
||||
"x": 289,
|
||||
"y": 258,
|
||||
"w": 57,
|
||||
"h": 63
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0009.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"w": 57,
|
||||
"h": 63
|
||||
},
|
||||
"frame": {
|
||||
"x": 296,
|
||||
"y": 130,
|
||||
"w": 57,
|
||||
"h": 63
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0017.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"w": 57,
|
||||
"h": 63
|
||||
},
|
||||
"frame": {
|
||||
"x": 296,
|
||||
"y": 193,
|
||||
"w": 57,
|
||||
"h": 63
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0015.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 2,
|
||||
"w": 56,
|
||||
"h": 63
|
||||
},
|
||||
"frame": {
|
||||
"x": 58,
|
||||
"y": 321,
|
||||
"w": 56,
|
||||
"h": 63
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0016.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 2,
|
||||
"w": 56,
|
||||
"h": 63
|
||||
},
|
||||
"frame": {
|
||||
"x": 114,
|
||||
"y": 321,
|
||||
"w": 56,
|
||||
"h": 63
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0010.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 3,
|
||||
"w": 56,
|
||||
"h": 62
|
||||
},
|
||||
"frame": {
|
||||
"x": 170,
|
||||
"y": 321,
|
||||
"w": 56,
|
||||
"h": 62
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0011.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 62,
|
||||
"h": 65
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 3,
|
||||
"w": 56,
|
||||
"h": 62
|
||||
},
|
||||
"frame": {
|
||||
"x": 226,
|
||||
"y": 321,
|
||||
"w": 56,
|
||||
"h": 62
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:05149e465b79b92adcb764d8f903ce8d:523fbed3890bc743f1863e6db3150ddb:5d92dd5d09b0875a1d8f3606df775958$"
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 18 KiB |
@ -28,5 +28,20 @@
|
||||
"fffbff": "edf8e6",
|
||||
"7b827b": "6a856a",
|
||||
"a7aba7": "98a798"
|
||||
},
|
||||
"2": {
|
||||
"342930": "754156",
|
||||
"0f0f0f": "0f0f0f",
|
||||
"4a3942": "a5777f",
|
||||
"937d85": "2f2655",
|
||||
"b9aaaf": "453863",
|
||||
"665b60": "211f45",
|
||||
"efe3e1": "67548a",
|
||||
"a7aba7": "ddac84",
|
||||
"fffbff": "f7e5d0",
|
||||
"e64c62": "aba7a8",
|
||||
"993e49": "797877",
|
||||
"501d25": "545151",
|
||||
"7b827b": "a96c4b"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,167 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "962_3.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 224,
|
||||
"h": 224
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 101,
|
||||
"h": 97
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 86
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 86
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 101,
|
||||
"h": 97
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 4,
|
||||
"w": 87,
|
||||
"h": 79
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 86,
|
||||
"w": 87,
|
||||
"h": 79
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 101,
|
||||
"h": 97
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 6,
|
||||
"w": 92,
|
||||
"h": 74
|
||||
},
|
||||
"frame": {
|
||||
"x": 82,
|
||||
"y": 0,
|
||||
"w": 92,
|
||||
"h": 74
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 101,
|
||||
"h": 97
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 38,
|
||||
"w": 91,
|
||||
"h": 59
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 165,
|
||||
"w": 91,
|
||||
"h": 59
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 101,
|
||||
"h": 97
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 36,
|
||||
"w": 91,
|
||||
"h": 60
|
||||
},
|
||||
"frame": {
|
||||
"x": 87,
|
||||
"y": 74,
|
||||
"w": 91,
|
||||
"h": 60
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 101,
|
||||
"h": 97
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 41,
|
||||
"w": 101,
|
||||
"h": 41
|
||||
},
|
||||
"frame": {
|
||||
"x": 91,
|
||||
"y": 134,
|
||||
"w": 101,
|
||||
"h": 41
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 101,
|
||||
"h": 97
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 40,
|
||||
"w": 100,
|
||||
"h": 38
|
||||
},
|
||||
"frame": {
|
||||
"x": 91,
|
||||
"y": 175,
|
||||
"w": 100,
|
||||
"h": 38
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:ee54d59ae73a6775b5d1d9b10f273445:828dff0b1dc45966e927a7a1419412f2:1e70eb3d02dd5c47565da4b5d26e2400$"
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
@ -126,6 +126,7 @@ export default class BattleScene extends SceneBase {
|
||||
public bgmVolume: number = 1;
|
||||
public fieldVolume: number = 1;
|
||||
public seVolume: number = 1;
|
||||
public uiVolume: number = 1;
|
||||
public gameSpeed: integer = 1;
|
||||
public damageNumbersMode: integer = 0;
|
||||
public reroll: boolean = false;
|
||||
@ -1755,6 +1756,7 @@ export default class BattleScene extends SceneBase {
|
||||
} else {
|
||||
const soundDetails = sound.key.split("/");
|
||||
switch (soundDetails[0]) {
|
||||
|
||||
case "battle_anims":
|
||||
case "cry":
|
||||
if (soundDetails[1].startsWith("PRSFX- ")) {
|
||||
@ -1791,6 +1793,16 @@ export default class BattleScene extends SceneBase {
|
||||
try {
|
||||
const keyDetails = key.split("/");
|
||||
switch (keyDetails[0]) {
|
||||
case "level_up_fanfare":
|
||||
case "item_fanfare":
|
||||
case "minor_fanfare":
|
||||
case "heal":
|
||||
case "evolution":
|
||||
case "evolution_fanfare":
|
||||
// These sounds are loaded in as BGM, but played as sound effects
|
||||
// When these sounds are updated in updateVolume(), they are treated as BGM however because they are placed in the BGM Cache through being called by playSoundWithoutBGM()
|
||||
config["volume"] = this.masterVolume * this.bgmVolume;
|
||||
break;
|
||||
case "battle_anims":
|
||||
case "cry":
|
||||
config["volume"] = this.masterVolume * this.fieldVolume;
|
||||
@ -1799,9 +1811,11 @@ export default class BattleScene extends SceneBase {
|
||||
config["volume"] *= 0.5;
|
||||
}
|
||||
break;
|
||||
case "se":
|
||||
case "ui":
|
||||
default:
|
||||
//As of, right now this applies to the "select", "menu_open", "error" sound effects
|
||||
config["volume"] = this.masterVolume * this.uiVolume;
|
||||
break;
|
||||
case "se":
|
||||
config["volume"] = this.masterVolume * this.seVolume;
|
||||
break;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import { Weather, WeatherType } from "./weather";
|
||||
import { BattlerTag, GroundedTag, GulpMissileTag, SemiInvulnerableTag } from "./battler-tags";
|
||||
import { StatusEffect, getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
|
||||
import { Gender } from "./gender";
|
||||
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, ChargeAttr, SacrificialAttr, SacrificialAttrOnHit } from "./move";
|
||||
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, FlinchAttr, OneHitKOAttr, HitHealAttr, allMoves, StatusMove, SelfStatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr, VariableMoveTypeAttr, RandomMovesetMoveAttr, RandomMoveAttr, NaturePowerAttr, CopyMoveAttr, MoveAttr, MultiHitAttr, ChargeAttr, SacrificialAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr } from "./move";
|
||||
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
|
||||
import { Stat, getStatName } from "./pokemon-stat";
|
||||
import { BerryModifier, PokemonHeldItemModifier } from "../modifier/modifier";
|
||||
@ -349,7 +349,7 @@ export class TypeImmunityAbAttr extends PreDefendAbAttr {
|
||||
if ([ MoveTarget.BOTH_SIDES, MoveTarget.ENEMY_SIDE, MoveTarget.USER_SIDE ].includes(move.moveTarget)) {
|
||||
return false;
|
||||
}
|
||||
if (attacker !== pokemon && move.type === this.immuneType) {
|
||||
if (attacker !== pokemon && attacker.getMoveType(move) === this.immuneType) {
|
||||
(args[0] as Utils.NumberHolder).value = 0;
|
||||
return true;
|
||||
}
|
||||
@ -372,7 +372,8 @@ export class AttackTypeImmunityAbAttr extends TypeImmunityAbAttr {
|
||||
* Example: Levitate
|
||||
*/
|
||||
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
if (move.category !== MoveCategory.STATUS) {
|
||||
// this is a hacky way to fix the Levitate/Thousand Arrows interaction, but it works for now...
|
||||
if (move.category !== MoveCategory.STATUS && !move.hasAttr(NeutralDamageAgainstFlyingTypeMultiplierAttr)) {
|
||||
return super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
|
||||
}
|
||||
return false;
|
||||
@ -392,6 +393,7 @@ export class TypeImmunityHealAbAttr extends TypeImmunityAbAttr {
|
||||
const abilityName = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name;
|
||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(),
|
||||
Utils.toDmgValue(pokemon.getMaxHp() / 4), i18next.t("abilityTriggers:typeImmunityHeal", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), true));
|
||||
cancelled.value = true; // Suppresses "No Effect" message
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -415,7 +417,7 @@ class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
|
||||
const ret = super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
|
||||
|
||||
if (ret) {
|
||||
cancelled.value = true;
|
||||
cancelled.value = true; // Suppresses "No Effect" message
|
||||
if (!simulated) {
|
||||
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
|
||||
}
|
||||
@ -440,7 +442,7 @@ class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
|
||||
const ret = super.applyPreDefend(pokemon, passive, simulated, attacker, move, cancelled, args);
|
||||
|
||||
if (ret) {
|
||||
cancelled.value = true;
|
||||
cancelled.value = true; // Suppresses "No Effect" message
|
||||
if (!simulated) {
|
||||
pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id);
|
||||
}
|
||||
@ -456,8 +458,8 @@ export class NonSuperEffectiveImmunityAbAttr extends TypeImmunityAbAttr {
|
||||
}
|
||||
|
||||
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
if (move instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.type, attacker) < 2) {
|
||||
cancelled.value = true;
|
||||
if (move instanceof AttackMove && pokemon.getAttackTypeEffectiveness(pokemon.getMoveType(move), attacker) < 2) {
|
||||
cancelled.value = true; // Suppresses "No Effect" message
|
||||
(args[0] as Utils.NumberHolder).value = 0;
|
||||
return true;
|
||||
}
|
||||
@ -764,7 +766,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
|
||||
if (simulated) {
|
||||
return true;
|
||||
}
|
||||
const type = move.type;
|
||||
const type = attacker.getMoveType(move);
|
||||
const pokemonTypes = pokemon.getTypes(true);
|
||||
if (pokemonTypes.length !== 1 || pokemonTypes[0] !== type) {
|
||||
pokemon.summonData.types = [ type ];
|
||||
@ -1212,7 +1214,7 @@ export class FieldMultiplyBattleStatAbAttr extends AbAttr {
|
||||
|
||||
}
|
||||
|
||||
export class MoveTypeChangeAttr extends PreAttackAbAttr {
|
||||
export class MoveTypeChangeAbAttr extends PreAttackAbAttr {
|
||||
constructor(
|
||||
private newType: Type,
|
||||
private powerMultiplier: number,
|
||||
@ -1221,11 +1223,14 @@ export class MoveTypeChangeAttr extends PreAttackAbAttr {
|
||||
super(true);
|
||||
}
|
||||
|
||||
// TODO: Decouple this into two attributes (type change / power boost)
|
||||
applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (this.condition && this.condition(pokemon, defender, move)) {
|
||||
move.type = this.newType;
|
||||
if (args[0] && args[0] instanceof Utils.NumberHolder) {
|
||||
args[0].value *= this.powerMultiplier;
|
||||
args[0].value = this.newType;
|
||||
}
|
||||
if (args[1] && args[1] instanceof Utils.NumberHolder) {
|
||||
args[1].value *= this.powerMultiplier;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1257,22 +1262,12 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr {
|
||||
attr instanceof CopyMoveAttr
|
||||
)
|
||||
) {
|
||||
// TODO remove this copy when phase order is changed so that damage, type, category, etc.
|
||||
// TODO are all calculated prior to playing the move animation.
|
||||
const moveCopy = new Move(move.id, move.type, move.category, move.moveTarget, move.power, move.accuracy, move.pp, move.chance, move.priority, move.generation);
|
||||
moveCopy.attrs = move.attrs;
|
||||
const moveType = pokemon.getMoveType(move);
|
||||
|
||||
// Moves like Weather Ball ignore effects of abilities like Normalize and Refrigerate
|
||||
if (move.findAttr(attr => attr instanceof VariableMoveTypeAttr)) {
|
||||
applyMoveAttrs(VariableMoveTypeAttr, pokemon, null, moveCopy);
|
||||
} else {
|
||||
applyPreAttackAbAttrs(MoveTypeChangeAttr, pokemon, null, moveCopy);
|
||||
}
|
||||
|
||||
if (pokemon.getTypes().some((t) => t !== moveCopy.type)) {
|
||||
if (pokemon.getTypes().some((t) => t !== moveType)) {
|
||||
if (!simulated) {
|
||||
this.moveType = moveCopy.type;
|
||||
pokemon.summonData.types = [moveCopy.type];
|
||||
this.moveType = moveType;
|
||||
pokemon.summonData.types = [moveType];
|
||||
pokemon.updateInfo();
|
||||
}
|
||||
|
||||
@ -2978,16 +2973,20 @@ function getAnticipationCondition(): AbAttrCondition {
|
||||
return (pokemon: Pokemon) => {
|
||||
for (const opponent of pokemon.getOpponents()) {
|
||||
for (const move of opponent.moveset) {
|
||||
// move is super effective
|
||||
if (move!.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move!.getMove().type, opponent, true) >= 2) { // TODO: is this bang correct?
|
||||
// ignore null/undefined moves
|
||||
if (!move) {
|
||||
continue;
|
||||
}
|
||||
// the move's base type (not accounting for variable type changes) is super effective
|
||||
if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent, true) >= 2) {
|
||||
return true;
|
||||
}
|
||||
// move is a OHKO
|
||||
if (move?.getMove().hasAttr(OneHitKOAttr)) {
|
||||
if (move.getMove().hasAttr(OneHitKOAttr)) {
|
||||
return true;
|
||||
}
|
||||
// edge case for hidden power, type is computed
|
||||
if (move?.getMove().id === Moves.HIDDEN_POWER) {
|
||||
if (move.getMove().id === Moves.HIDDEN_POWER) {
|
||||
const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1)
|
||||
+(opponent.ivs[Stat.ATK] & 1) * 2
|
||||
+(opponent.ivs[Stat.DEF] & 1) * 4
|
||||
@ -5019,7 +5018,7 @@ export function initAbilities() {
|
||||
.conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, BattleStatMultiplierAbAttr, BattleStat.SPD, 2)
|
||||
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5),
|
||||
new Ability(Abilities.NORMALIZE, 4)
|
||||
.attr(MoveTypeChangeAttr, Type.NORMAL, 1.2, (user, target, move) => {
|
||||
.attr(MoveTypeChangeAbAttr, Type.NORMAL, 1.2, (user, target, move) => {
|
||||
return ![Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST].includes(move.id);
|
||||
}),
|
||||
new Ability(Abilities.SNIPER, 4)
|
||||
@ -5260,7 +5259,7 @@ export function initAbilities() {
|
||||
new Ability(Abilities.STRONG_JAW, 6)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.BITING_MOVE), 1.5),
|
||||
new Ability(Abilities.REFRIGERATE, 6)
|
||||
.attr(MoveTypeChangeAttr, Type.ICE, 1.2, (user, target, move) => move.type === Type.NORMAL),
|
||||
.attr(MoveTypeChangeAbAttr, Type.ICE, 1.2, (user, target, move) => move.type === Type.NORMAL && !move.hasAttr(VariableMoveTypeAttr)),
|
||||
new Ability(Abilities.SWEET_VEIL, 6)
|
||||
.attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.SLEEP)
|
||||
.attr(UserFieldBattlerTagImmunityAbAttr, BattlerTagType.DROWSY)
|
||||
@ -5283,11 +5282,11 @@ export function initAbilities() {
|
||||
new Ability(Abilities.TOUGH_CLAWS, 6)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 1.3),
|
||||
new Ability(Abilities.PIXILATE, 6)
|
||||
.attr(MoveTypeChangeAttr, Type.FAIRY, 1.2, (user, target, move) => move.type === Type.NORMAL),
|
||||
.attr(MoveTypeChangeAbAttr, Type.FAIRY, 1.2, (user, target, move) => move.type === Type.NORMAL && !move.hasAttr(VariableMoveTypeAttr)),
|
||||
new Ability(Abilities.GOOEY, 6)
|
||||
.attr(PostDefendStatChangeAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), BattleStat.SPD, -1, false),
|
||||
new Ability(Abilities.AERILATE, 6)
|
||||
.attr(MoveTypeChangeAttr, Type.FLYING, 1.2, (user, target, move) => move.type === Type.NORMAL),
|
||||
.attr(MoveTypeChangeAbAttr, Type.FLYING, 1.2, (user, target, move) => move.type === Type.NORMAL && !move.hasAttr(VariableMoveTypeAttr)),
|
||||
new Ability(Abilities.PARENTAL_BOND, 6)
|
||||
.attr(AddSecondStrikeAbAttr, 0.25),
|
||||
new Ability(Abilities.DARK_AURA, 6)
|
||||
@ -5359,11 +5358,11 @@ export function initAbilities() {
|
||||
new Ability(Abilities.LONG_REACH, 7)
|
||||
.attr(IgnoreContactAbAttr),
|
||||
new Ability(Abilities.LIQUID_VOICE, 7)
|
||||
.attr(MoveTypeChangeAttr, Type.WATER, 1, (user, target, move) => move.hasFlag(MoveFlags.SOUND_BASED)),
|
||||
.attr(MoveTypeChangeAbAttr, Type.WATER, 1, (user, target, move) => move.hasFlag(MoveFlags.SOUND_BASED)),
|
||||
new Ability(Abilities.TRIAGE, 7)
|
||||
.attr(ChangeMovePriorityAbAttr, (pokemon, move) => move.hasFlag(MoveFlags.TRIAGE_MOVE), 3),
|
||||
new Ability(Abilities.GALVANIZE, 7)
|
||||
.attr(MoveTypeChangeAttr, Type.ELECTRIC, 1.2, (user, target, move) => move.type === Type.NORMAL),
|
||||
.attr(MoveTypeChangeAbAttr, Type.ELECTRIC, 1.2, (user, target, move) => move.type === Type.NORMAL && !move.hasAttr(VariableMoveTypeAttr)),
|
||||
new Ability(Abilities.SURGE_SURFER, 7)
|
||||
.conditionalAttr(getTerrainCondition(TerrainType.ELECTRIC), BattleStatMultiplierAbAttr, BattleStat.SPD, 2),
|
||||
new Ability(Abilities.SCHOOLING, 7)
|
||||
|
@ -49,7 +49,8 @@ export function getDailyRunStarters(scene: BattleScene, seed: string): Starter[]
|
||||
const costSpecies = Object.keys(speciesStarters)
|
||||
.map(s => parseInt(s) as Species)
|
||||
.filter(s => speciesStarters[s] === cost);
|
||||
const starterSpecies = getPokemonSpecies(getPokemonSpecies(Utils.randSeedItem(costSpecies)).getTrainerSpeciesForLevel(startingLevel, true, PartyMemberStrength.STRONGER));
|
||||
const randPkmSpecies = getPokemonSpecies(Utils.randSeedItem(costSpecies));
|
||||
const starterSpecies = getPokemonSpecies(randPkmSpecies.getTrainerSpeciesForLevel(startingLevel, true, PartyMemberStrength.STRONGER));
|
||||
starters.push(getDailyRunStarter(scene, starterSpecies, startingLevel));
|
||||
}
|
||||
}, 0, seed);
|
||||
|
202
src/data/move.ts
202
src/data/move.ts
@ -9,7 +9,7 @@ import { Constructor } from "#app/utils";
|
||||
import * as Utils from "../utils";
|
||||
import { WeatherType } from "./weather";
|
||||
import { ArenaTagSide, ArenaTrapTag, WeakenMoveTypeTag } from "./arena-tag";
|
||||
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, BlockItemTheftAbAttr, applyPostAttackAbAttrs, ConfusionOnStatusEffectAbAttr, HealFromBerryUseAbAttr, IgnoreProtectOnContactAbAttr, IgnoreMoveEffectsAbAttr, applyPreDefendAbAttrs, MoveEffectChanceMultiplierAbAttr, WonderSkinAbAttr, applyPreAttackAbAttrs, MoveTypeChangeAttr, UserFieldMoveTypePowerBoostAbAttr, FieldMoveTypePowerBoostAbAttr, AllyMoveCategoryPowerBoostAbAttr, VariableMovePowerAbAttr } from "./ability";
|
||||
import { UnswappableAbilityAbAttr, UncopiableAbilityAbAttr, UnsuppressableAbilityAbAttr, BlockRecoilDamageAttr, BlockOneHitKOAbAttr, IgnoreContactAbAttr, MaxMultiHitAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, MoveAbilityBypassAbAttr, ReverseDrainAbAttr, FieldPreventExplosiveMovesAbAttr, ForceSwitchOutImmunityAbAttr, BlockItemTheftAbAttr, applyPostAttackAbAttrs, ConfusionOnStatusEffectAbAttr, HealFromBerryUseAbAttr, IgnoreProtectOnContactAbAttr, IgnoreMoveEffectsAbAttr, applyPreDefendAbAttrs, MoveEffectChanceMultiplierAbAttr, WonderSkinAbAttr, applyPreAttackAbAttrs, MoveTypeChangeAbAttr, UserFieldMoveTypePowerBoostAbAttr, FieldMoveTypePowerBoostAbAttr, AllyMoveCategoryPowerBoostAbAttr, VariableMovePowerAbAttr } from "./ability";
|
||||
import { allAbilities } from "./ability";
|
||||
import { PokemonHeldItemModifier, BerryModifier, PreserveBerryModifier, PokemonMoveAccuracyBoosterModifier, AttackTypeBoosterModifier, PokemonMultiHitModifier } from "../modifier/modifier";
|
||||
import { BattlerIndex, BattleType } from "../battle";
|
||||
@ -114,9 +114,8 @@ type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean;
|
||||
export default class Move implements Localizable {
|
||||
public id: Moves;
|
||||
public name: string;
|
||||
public type: Type;
|
||||
public defaultType: Type;
|
||||
public category: MoveCategory;
|
||||
private _type: Type;
|
||||
private _category: MoveCategory;
|
||||
public moveTarget: MoveTarget;
|
||||
public power: integer;
|
||||
public accuracy: integer;
|
||||
@ -134,9 +133,8 @@ export default class Move implements Localizable {
|
||||
this.id = id;
|
||||
|
||||
this.nameAppend = "";
|
||||
this.type = type;
|
||||
this.defaultType = type;
|
||||
this.category = category;
|
||||
this._type = type;
|
||||
this._category = category;
|
||||
this.moveTarget = defaultMoveTarget;
|
||||
this.power = power;
|
||||
this.accuracy = accuracy;
|
||||
@ -159,6 +157,13 @@ export default class Move implements Localizable {
|
||||
this.localize();
|
||||
}
|
||||
|
||||
get type() {
|
||||
return this._type;
|
||||
}
|
||||
get category() {
|
||||
return this._category;
|
||||
}
|
||||
|
||||
localize(): void {
|
||||
const i18nKey = Moves[this.id].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as unknown as string;
|
||||
|
||||
@ -734,7 +739,7 @@ export default class Move implements Localizable {
|
||||
const power = new Utils.NumberHolder(this.power);
|
||||
const typeChangeMovePowerMultiplier = new Utils.NumberHolder(1);
|
||||
|
||||
applyPreAttackAbAttrs(MoveTypeChangeAttr, source, target, this, simulated, typeChangeMovePowerMultiplier);
|
||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, null, typeChangeMovePowerMultiplier);
|
||||
|
||||
const sourceTeraType = source.getTeraType();
|
||||
if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !source.scene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) {
|
||||
@ -1084,15 +1089,12 @@ export class PreMoveMessageAttr extends MoveAttr {
|
||||
}
|
||||
}
|
||||
|
||||
export class StatusMoveTypeImmunityAttr extends MoveAttr {
|
||||
public immuneType: Type;
|
||||
|
||||
constructor(immuneType: Type) {
|
||||
super(false);
|
||||
|
||||
this.immuneType = immuneType;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Attribute for Status moves that take attack type effectiveness
|
||||
* into consideration (i.e. {@linkcode https://bulbapedia.bulbagarden.net/wiki/Thunder_Wave_(move) | Thunder Wave})
|
||||
* @extends MoveAttr
|
||||
*/
|
||||
export class RespectAttackTypeImmunityAttr extends MoveAttr { }
|
||||
|
||||
export class IgnoreOpponentStatChangesAttr extends MoveAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
@ -1852,19 +1854,11 @@ export class MultiHitAttr extends MoveAttr {
|
||||
* @returns True
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
let hitTimes: integer;
|
||||
const hitType = new Utils.NumberHolder(this.multiHitType);
|
||||
applyMoveAttrs(ChangeMultiHitTypeAttr, user, target, move, hitType);
|
||||
this.multiHitType = hitType.value;
|
||||
|
||||
if (target.getAttackMoveEffectiveness(user, new PokemonMove(move.id)) === 0) {
|
||||
// If there is a type immunity, the attack will stop no matter what
|
||||
hitTimes = 1;
|
||||
} else {
|
||||
const hitType = new Utils.IntegerHolder(this.multiHitType);
|
||||
applyMoveAttrs(ChangeMultiHitTypeAttr, user, target, move, hitType);
|
||||
this.multiHitType = hitType.value;
|
||||
hitTimes = this.getHitCount(user, target);
|
||||
}
|
||||
|
||||
(args[0] as Utils.IntegerHolder).value = hitTimes;
|
||||
(args[0] as Utils.NumberHolder).value = this.getHitCount(user, target);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3763,7 +3757,7 @@ export class VariableMoveCategoryAttr extends MoveAttr {
|
||||
|
||||
export class PhotonGeyserCategoryAttr extends VariableMoveCategoryAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const category = (args[0] as Utils.IntegerHolder);
|
||||
const category = (args[0] as Utils.NumberHolder);
|
||||
|
||||
if (user.getBattleStat(Stat.ATK, target, move) > user.getBattleStat(Stat.SPATK, target, move)) {
|
||||
category.value = MoveCategory.PHYSICAL;
|
||||
@ -3776,7 +3770,7 @@ export class PhotonGeyserCategoryAttr extends VariableMoveCategoryAttr {
|
||||
|
||||
export class TeraBlastCategoryAttr extends VariableMoveCategoryAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const category = (args[0] as Utils.IntegerHolder);
|
||||
const category = (args[0] as Utils.NumberHolder);
|
||||
|
||||
if (user.isTerastallized() && user.getBattleStat(Stat.ATK, target, move) > user.getBattleStat(Stat.SPATK, target, move)) {
|
||||
category.value = MoveCategory.PHYSICAL;
|
||||
@ -3792,18 +3786,21 @@ export class TeraBlastCategoryAttr extends VariableMoveCategoryAttr {
|
||||
* @extends VariablePowerAttr
|
||||
*/
|
||||
export class TeraBlastPowerAttr extends VariablePowerAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
/**
|
||||
* @param user {@linkcode Pokemon} Pokemon using the move
|
||||
* @param target {@linkcode Pokemon} N/A
|
||||
* @param move {@linkcode Move} {@linkcode Move.TERA_BLAST}
|
||||
* @param {any[]} args N/A
|
||||
* @returns true or false
|
||||
* Sets Tera Blast's power to 100 if the user is terastallized with
|
||||
* the Stellar tera type.
|
||||
* @param user {@linkcode Pokemon} the Pokemon using this move
|
||||
* @param target n/a
|
||||
* @param move {@linkcode Move} the Move with this attribute (i.e. Tera Blast)
|
||||
* @param args
|
||||
* - [0] {@linkcode Utils.NumberHolder} the applied move's power, factoring in
|
||||
* previously applied power modifiers.
|
||||
* @returns
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const power = args[0] as Utils.NumberHolder;
|
||||
if (user.isTerastallized() && move.type === Type.STELLAR) {
|
||||
//200 instead of 100 to reflect lack of stellar being 2x dmg on any type
|
||||
power.value = 200;
|
||||
if (user.isTerastallized() && user.getTeraType() === Type.STELLAR) {
|
||||
power.value = 100;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3863,10 +3860,15 @@ export class VariableMoveTypeAttr extends MoveAttr {
|
||||
|
||||
export class FormChangeItemTypeAttr extends VariableMoveTypeAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.ARCEUS) || [user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.SILVALLY)) {
|
||||
const form = user.species.speciesId === Species.ARCEUS || user.species.speciesId === Species.SILVALLY ? user.formIndex : user.fusionSpecies?.formIndex!; // TODO: is this bang correct?
|
||||
|
||||
move.type = Type[Type[form]];
|
||||
moveType.value = Type[Type[form]];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3876,24 +3878,29 @@ export class FormChangeItemTypeAttr extends VariableMoveTypeAttr {
|
||||
|
||||
export class TechnoBlastTypeAttr extends VariableMoveTypeAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.GENESECT)) {
|
||||
const form = user.species.speciesId === Species.GENESECT ? user.formIndex : user.fusionSpecies?.formIndex;
|
||||
|
||||
switch (form) {
|
||||
case 1: // Shock Drive
|
||||
move.type = Type.ELECTRIC;
|
||||
moveType.value = Type.ELECTRIC;
|
||||
break;
|
||||
case 2: // Burn Drive
|
||||
move.type = Type.FIRE;
|
||||
moveType.value = Type.FIRE;
|
||||
break;
|
||||
case 3: // Chill Drive
|
||||
move.type = Type.ICE;
|
||||
moveType.value = Type.ICE;
|
||||
break;
|
||||
case 4: // Douse Drive
|
||||
move.type = Type.WATER;
|
||||
moveType.value = Type.WATER;
|
||||
break;
|
||||
default:
|
||||
move.type = Type.NORMAL;
|
||||
moveType.value = Type.NORMAL;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
@ -3905,15 +3912,20 @@ export class TechnoBlastTypeAttr extends VariableMoveTypeAttr {
|
||||
|
||||
export class AuraWheelTypeAttr extends VariableMoveTypeAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.MORPEKO)) {
|
||||
const form = user.species.speciesId === Species.MORPEKO ? user.formIndex : user.fusionSpecies?.formIndex;
|
||||
|
||||
switch (form) {
|
||||
case 1: // Hangry Mode
|
||||
move.type = Type.DARK;
|
||||
moveType.value = Type.DARK;
|
||||
break;
|
||||
default: // Full Belly Mode
|
||||
move.type = Type.ELECTRIC;
|
||||
moveType.value = Type.ELECTRIC;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
@ -3925,18 +3937,23 @@ export class AuraWheelTypeAttr extends VariableMoveTypeAttr {
|
||||
|
||||
export class RagingBullTypeAttr extends VariableMoveTypeAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.PALDEA_TAUROS)) {
|
||||
const form = user.species.speciesId === Species.PALDEA_TAUROS ? user.formIndex : user.fusionSpecies?.formIndex;
|
||||
|
||||
switch (form) {
|
||||
case 1: // Blaze breed
|
||||
move.type = Type.FIRE;
|
||||
moveType.value = Type.FIRE;
|
||||
break;
|
||||
case 2: // Aqua breed
|
||||
move.type = Type.WATER;
|
||||
moveType.value = Type.WATER;
|
||||
break;
|
||||
default:
|
||||
move.type = Type.FIGHTING;
|
||||
moveType.value = Type.FIGHTING;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
@ -3948,25 +3965,30 @@ export class RagingBullTypeAttr extends VariableMoveTypeAttr {
|
||||
|
||||
export class IvyCudgelTypeAttr extends VariableMoveTypeAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ([user.species.speciesId, user.fusionSpecies?.speciesId].includes(Species.OGERPON)) {
|
||||
const form = user.species.speciesId === Species.OGERPON ? user.formIndex : user.fusionSpecies?.formIndex;
|
||||
|
||||
switch (form) {
|
||||
case 1: // Wellspring Mask
|
||||
case 5: // Wellspring Mask Tera
|
||||
move.type = Type.WATER;
|
||||
moveType.value = Type.WATER;
|
||||
break;
|
||||
case 2: // Hearthflame Mask
|
||||
case 6: // Hearthflame Mask Tera
|
||||
move.type = Type.FIRE;
|
||||
moveType.value = Type.FIRE;
|
||||
break;
|
||||
case 3: // Cornerstone Mask
|
||||
case 7: // Cornerstone Mask Tera
|
||||
move.type = Type.ROCK;
|
||||
moveType.value = Type.ROCK;
|
||||
break;
|
||||
case 4: // Teal Mask Tera
|
||||
default:
|
||||
move.type = Type.GRASS;
|
||||
moveType.value = Type.GRASS;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
@ -3978,22 +4000,27 @@ export class IvyCudgelTypeAttr extends VariableMoveTypeAttr {
|
||||
|
||||
export class WeatherBallTypeAttr extends VariableMoveTypeAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!user.scene.arena.weather?.isEffectSuppressed(user.scene)) {
|
||||
switch (user.scene.arena.weather?.weatherType) {
|
||||
case WeatherType.SUNNY:
|
||||
case WeatherType.HARSH_SUN:
|
||||
move.type = Type.FIRE;
|
||||
moveType.value = Type.FIRE;
|
||||
break;
|
||||
case WeatherType.RAIN:
|
||||
case WeatherType.HEAVY_RAIN:
|
||||
move.type = Type.WATER;
|
||||
moveType.value = Type.WATER;
|
||||
break;
|
||||
case WeatherType.SANDSTORM:
|
||||
move.type = Type.ROCK;
|
||||
moveType.value = Type.ROCK;
|
||||
break;
|
||||
case WeatherType.HAIL:
|
||||
case WeatherType.SNOW:
|
||||
move.type = Type.ICE;
|
||||
moveType.value = Type.ICE;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
@ -4016,10 +4043,15 @@ export class TerrainPulseTypeAttr extends VariableMoveTypeAttr {
|
||||
* @param user {@linkcode Pokemon} using this move
|
||||
* @param target N/A
|
||||
* @param move N/A
|
||||
* @param args [0] {@linkcode Utils.IntegerHolder} The move's type to be modified
|
||||
* @param args [0] {@linkcode Utils.NumberHolder} The move's type to be modified
|
||||
* @returns true if the function succeeds
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!user.isGrounded()) {
|
||||
return false;
|
||||
}
|
||||
@ -4027,16 +4059,16 @@ export class TerrainPulseTypeAttr extends VariableMoveTypeAttr {
|
||||
const currentTerrain = user.scene.arena.getTerrainType();
|
||||
switch (currentTerrain) {
|
||||
case TerrainType.MISTY:
|
||||
move.type = Type.FAIRY;
|
||||
moveType.value = Type.FAIRY;
|
||||
break;
|
||||
case TerrainType.ELECTRIC:
|
||||
move.type = Type.ELECTRIC;
|
||||
moveType.value = Type.ELECTRIC;
|
||||
break;
|
||||
case TerrainType.GRASSY:
|
||||
move.type = Type.GRASS;
|
||||
moveType.value = Type.GRASS;
|
||||
break;
|
||||
case TerrainType.PSYCHIC:
|
||||
move.type = Type.PSYCHIC;
|
||||
moveType.value = Type.PSYCHIC;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
@ -4045,8 +4077,17 @@ export class TerrainPulseTypeAttr extends VariableMoveTypeAttr {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes type based on the user's IVs
|
||||
* @extends VariableMoveTypeAttr
|
||||
*/
|
||||
export class HiddenPowerTypeAttr extends VariableMoveTypeAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const iv_val = Math.floor(((user.ivs[Stat.HP] & 1)
|
||||
+(user.ivs[Stat.ATK] & 1) * 2
|
||||
+(user.ivs[Stat.DEF] & 1) * 4
|
||||
@ -4054,7 +4095,7 @@ export class HiddenPowerTypeAttr extends VariableMoveTypeAttr {
|
||||
+(user.ivs[Stat.SPATK] & 1) * 16
|
||||
+(user.ivs[Stat.SPDEF] & 1) * 32) * 15/63);
|
||||
|
||||
move.type = [
|
||||
moveType.value = [
|
||||
Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND,
|
||||
Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL,
|
||||
Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC,
|
||||
@ -4069,16 +4110,21 @@ export class HiddenPowerTypeAttr extends VariableMoveTypeAttr {
|
||||
* @extends VariableMoveTypeAttr
|
||||
*/
|
||||
export class TeraBlastTypeAttr extends VariableMoveTypeAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
/**
|
||||
* @param user {@linkcode Pokemon} the user's type is checked
|
||||
* @param user {@linkcode Pokemon} the user of the move
|
||||
* @param target {@linkcode Pokemon} N/A
|
||||
* @param move {@linkcode Move} {@linkcode Move.TeraBlastTypeAttr}
|
||||
* @param {any[]} args N/A
|
||||
* @returns true or false
|
||||
* @param move {@linkcode Move} the move with this attribute
|
||||
* @param args `[0]` the move's type to be modified
|
||||
* @returns `true` if the move's type was modified; `false` otherwise
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (user.isTerastallized()) {
|
||||
move.type = user.getTeraType(); //changes move type to tera type
|
||||
moveType.value = user.getTeraType(); // changes move type to tera type
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4088,14 +4134,18 @@ export class TeraBlastTypeAttr extends VariableMoveTypeAttr {
|
||||
|
||||
export class MatchUserTypeAttr extends VariableMoveTypeAttr {
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const moveType = args[0];
|
||||
if (!(moveType instanceof Utils.NumberHolder)) {
|
||||
return false;
|
||||
}
|
||||
const userTypes = user.getTypes(true);
|
||||
|
||||
if (userTypes.includes(Type.STELLAR)) { // will not change to stellar type
|
||||
const nonTeraTypes = user.getTypes();
|
||||
move.type = nonTeraTypes[0];
|
||||
moveType.value = nonTeraTypes[0];
|
||||
return true;
|
||||
} else if (userTypes.length > 0) {
|
||||
move.type = userTypes[0];
|
||||
moveType.value = userTypes[0];
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -4114,8 +4164,8 @@ export class NeutralDamageAgainstFlyingTypeMultiplierAttr extends VariableMoveTy
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
if (!target.getTag(BattlerTagType.IGNORE_FLYING)) {
|
||||
const multiplier = args[0] as Utils.NumberHolder;
|
||||
//When a flying type is hit, the first hit is always 1x multiplier. Levitating pokemon are instantly affected by typing
|
||||
if (target.isOfType(Type.FLYING) || target.hasAbility(Abilities.LEVITATE)) {
|
||||
//When a flying type is hit, the first hit is always 1x multiplier.
|
||||
if (target.isOfType(Type.FLYING)) {
|
||||
multiplier.value = 1;
|
||||
}
|
||||
return true;
|
||||
@ -6590,7 +6640,7 @@ export function initMoves() {
|
||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS),
|
||||
new StatusMove(Moves.THUNDER_WAVE, Type.ELECTRIC, 90, 20, -1, 0, 1)
|
||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS)
|
||||
.attr(StatusMoveTypeImmunityAttr, Type.GROUND),
|
||||
.attr(RespectAttackTypeImmunityAttr),
|
||||
new AttackMove(Moves.THUNDER, Type.ELECTRIC, MoveCategory.SPECIAL, 110, 70, 10, 30, 0, 1)
|
||||
.attr(StatusEffectAttr, StatusEffect.PARALYSIS)
|
||||
.attr(ThunderAccuracyAttr)
|
||||
|
@ -1582,7 +1582,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
||||
new SpeciesEvolution(Species.BLISSEY, 1, null, new SpeciesFriendshipEvolutionCondition(200), SpeciesWildEvolutionDelay.LONG)
|
||||
],
|
||||
[Species.PICHU]: [
|
||||
new SpeciesEvolution(Species.PIKACHU, 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT)
|
||||
new SpeciesFormEvolution(Species.PIKACHU, "spiky", "partner", 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT),
|
||||
new SpeciesFormEvolution(Species.PIKACHU, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT),
|
||||
],
|
||||
[Species.CLEFFA]: [
|
||||
new SpeciesEvolution(Species.CLEFAIRY, 1, null, new SpeciesFriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT)
|
||||
|
@ -1,24 +1,21 @@
|
||||
|
||||
import { Localizable } from "#app/interfaces/locales";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import { Species } from "#enums/species";
|
||||
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
|
||||
import i18next from "i18next";
|
||||
import BattleScene, { AnySound } from "../battle-scene";
|
||||
import { Variant, variantColorCache } from "./variant";
|
||||
import { variantData } from "./variant";
|
||||
import { GameMode } from "../game-mode";
|
||||
import { StarterMoveset } from "../system/game-data";
|
||||
import * as Utils from "../utils";
|
||||
import { uncatchableSpecies } from "./biomes";
|
||||
import { speciesEggMoves } from "./egg-moves";
|
||||
import { GrowthRate } from "./exp";
|
||||
import { EvolutionLevel, SpeciesWildEvolutionDelay, pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions";
|
||||
import { Type } from "./type";
|
||||
import { LevelMoves, pokemonFormLevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from "./pokemon-level-moves";
|
||||
import { uncatchableSpecies } from "./biomes";
|
||||
import * as Utils from "../utils";
|
||||
import { StarterMoveset } from "../system/game-data";
|
||||
import { speciesEggMoves } from "./egg-moves";
|
||||
import { GameMode } from "../game-mode";
|
||||
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
|
||||
import { VariantSet } from "./variant";
|
||||
import i18next from "i18next";
|
||||
import { Localizable } from "#app/interfaces/locales";
|
||||
import { Stat } from "./pokemon-stat";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import { Species } from "#enums/species";
|
||||
import { Variant, VariantSet, variantColorCache, variantData } from "./variant";
|
||||
|
||||
export enum Region {
|
||||
NORMAL,
|
||||
@ -28,7 +25,15 @@ export enum Region {
|
||||
PALDEA
|
||||
}
|
||||
|
||||
export function getPokemonSpecies(species: Species | Species[]): PokemonSpecies {
|
||||
/**
|
||||
* Gets the {@linkcode PokemonSpecies} object associated with the {@linkcode Species} enum given
|
||||
* @param species The species to fetch
|
||||
* @returns The associated {@linkcode PokemonSpecies} object
|
||||
*/
|
||||
export function getPokemonSpecies(species: Species | Species[] | undefined): PokemonSpecies {
|
||||
if (!species) {
|
||||
throw new Error("`species` must not be undefined in `getPokemonSpecies()`");
|
||||
}
|
||||
// If a special pool (named trainers) is used here it CAN happen that they have a array as species (which means choose one of those two). So we catch that with this code block
|
||||
if (Array.isArray(species)) {
|
||||
// Pick a random species from the list
|
||||
@ -648,8 +653,8 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
|
||||
return this.getSpeciesForLevel(level, allowEvolving, false, (isBoss ? PartyMemberStrength.WEAKER : PartyMemberStrength.AVERAGE) + (gameMode?.isEndless ? 1 : 0));
|
||||
}
|
||||
|
||||
getTrainerSpeciesForLevel(level: integer, allowEvolving: boolean = false, strength: PartyMemberStrength): Species {
|
||||
return this.getSpeciesForLevel(level, allowEvolving, true, strength);
|
||||
getTrainerSpeciesForLevel(level: integer, allowEvolving: boolean = false, strength: PartyMemberStrength, currentWave: number = 0): Species {
|
||||
return this.getSpeciesForLevel(level, allowEvolving, true, strength, currentWave);
|
||||
}
|
||||
|
||||
private getStrengthLevelDiff(strength: PartyMemberStrength): integer {
|
||||
@ -669,7 +674,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
|
||||
}
|
||||
}
|
||||
|
||||
getSpeciesForLevel(level: integer, allowEvolving: boolean = false, forTrainer: boolean = false, strength: PartyMemberStrength = PartyMemberStrength.WEAKER): Species {
|
||||
getSpeciesForLevel(level: integer, allowEvolving: boolean = false, forTrainer: boolean = false, strength: PartyMemberStrength = PartyMemberStrength.WEAKER, currentWave: number = 0): Species {
|
||||
const prevolutionLevels = this.getPrevolutionLevels();
|
||||
|
||||
if (prevolutionLevels.length) {
|
||||
@ -730,6 +735,11 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
|
||||
evolutionChance = Math.min(0.65 * easeInFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel) / preferredMinLevel) + 0.35 * easeOutFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel * 2.5) / (preferredMinLevel * 2.5)), 1);
|
||||
}
|
||||
}
|
||||
/* (Most) Trainers shouldn't be using unevolved Pokemon by the third gym leader / wave 80. Exceptions to this include Breeders, whose large teams are balanced by the use of weaker pokemon */
|
||||
if (currentWave >= 80 && forTrainer && strength > PartyMemberStrength.WEAKER) {
|
||||
evolutionChance = 1;
|
||||
noEvolutionChance = 0;
|
||||
}
|
||||
|
||||
if (evolutionChance > 0) {
|
||||
if (isRegionalEvolution) {
|
||||
@ -754,7 +764,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
|
||||
|
||||
for (const weight of evolutionPool.keys()) {
|
||||
if (randValue < weight) {
|
||||
return getPokemonSpecies(evolutionPool.get(weight)!).getSpeciesForLevel(level, true, forTrainer, strength); // TODO: is the bang correct?
|
||||
return getPokemonSpecies(evolutionPool.get(weight)).getSpeciesForLevel(level, true, forTrainer, strength, currentWave);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ export const trainerPartyTemplates = {
|
||||
FIVE_WEAK_BALANCED: new TrainerPartyTemplate(5, PartyMemberStrength.WEAK, false, true),
|
||||
SIX_WEAKER: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER),
|
||||
SIX_WEAKER_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER, true),
|
||||
SIX_WEAK_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAKER, true),
|
||||
SIX_WEAK_SAME: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, true),
|
||||
SIX_WEAK_BALANCED: new TrainerPartyTemplate(6, PartyMemberStrength.WEAK, false, true),
|
||||
|
||||
GYM_LEADER_1: new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(1, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(1, PartyMemberStrength.STRONG)),
|
||||
@ -965,7 +965,7 @@ function getRandomPartyMemberFunc(speciesPool: Species[], trainerSlot: TrainerSl
|
||||
return (scene: BattleScene, level: integer, strength: PartyMemberStrength) => {
|
||||
let species = Utils.randSeedItem(speciesPool);
|
||||
if (!ignoreEvolution) {
|
||||
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength);
|
||||
species = getPokemonSpecies(species).getTrainerSpeciesForLevel(level, true, strength, scene.currentBattle.waveIndex);
|
||||
}
|
||||
return scene.addEnemyPokemon(getPokemonSpecies(species), level, trainerSlot, undefined, undefined, postProcess);
|
||||
};
|
||||
@ -975,7 +975,7 @@ function getSpeciesFilterRandomPartyMemberFunc(speciesFilter: PokemonSpeciesFilt
|
||||
const originalSpeciesFilter = speciesFilter;
|
||||
speciesFilter = (species: PokemonSpecies) => (allowLegendaries || (!species.legendary && !species.subLegendary && !species.mythical)) && !species.isTrainerForbidden() && originalSpeciesFilter(species);
|
||||
return (scene: BattleScene, level: integer, strength: PartyMemberStrength) => {
|
||||
const ret = scene.addEnemyPokemon(getPokemonSpecies(scene.randomSpecies(scene.currentBattle.waveIndex, level, false, speciesFilter).getTrainerSpeciesForLevel(level, true, strength)), level, trainerSlot, undefined, undefined, postProcess);
|
||||
const ret = scene.addEnemyPokemon(getPokemonSpecies(scene.randomSpecies(scene.currentBattle.waveIndex, level, false, speciesFilter).getTrainerSpeciesForLevel(level, true, strength, scene.currentBattle.waveIndex)), level, trainerSlot, undefined, undefined, postProcess);
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import BattleScene, { AnySound } from "../battle-scene";
|
||||
import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
|
||||
import { variantData } from "#app/data/variant";
|
||||
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
|
||||
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, StatusMoveTypeImmunityAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, NeutralDamageAgainstFlyingTypeMultiplierAttr, OneHitKOAccuracyAttr } from "../data/move";
|
||||
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr } from "../data/move";
|
||||
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
|
||||
import { Constructor } from "#app/utils";
|
||||
import * as Utils from "../utils";
|
||||
@ -22,7 +22,7 @@ import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoo
|
||||
import { WeatherType } from "../data/weather";
|
||||
import { TempBattleStat } from "../data/temp-battle-stat";
|
||||
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag";
|
||||
import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldBattleStatMultiplierAbAttrs, FieldMultiplyBattleStatAbAttr, AddSecondStrikeAbAttr, IgnoreOpponentEvasionAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr } from "../data/ability";
|
||||
import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldBattleStatMultiplierAbAttrs, FieldMultiplyBattleStatAbAttr, AddSecondStrikeAbAttr, IgnoreOpponentEvasionAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr } from "../data/ability";
|
||||
import PokemonData from "../system/pokemon-data";
|
||||
import { BattlerIndex } from "../battle";
|
||||
import { Mode } from "../ui/ui";
|
||||
@ -1208,60 +1208,83 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the effectiveness of a move against the Pokémon.
|
||||
*
|
||||
* @param source - The Pokémon using the move.
|
||||
* @param move - The move being used.
|
||||
* @returns The type damage multiplier or 1 if it's a status move
|
||||
* Calculates the type of a move when used by this Pokemon after
|
||||
* type-changing move and ability attributes have applied.
|
||||
* @param move {@linkcode Move} The move being used.
|
||||
* @param simulated If `true`, prevents showing abilities applied in this calculation.
|
||||
* @returns the {@linkcode Type} of the move after attributes are applied
|
||||
*/
|
||||
getMoveEffectiveness(source: Pokemon, move: PokemonMove): TypeDamageMultiplier {
|
||||
if (move.getMove().category === MoveCategory.STATUS) {
|
||||
return 1;
|
||||
}
|
||||
getMoveType(move: Move, simulated: boolean = true): Type {
|
||||
const moveTypeHolder = new Utils.NumberHolder(move.type);
|
||||
|
||||
return this.getAttackMoveEffectiveness(source, move, !this.battleData?.abilityRevealed);
|
||||
applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
|
||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder);
|
||||
|
||||
return moveTypeHolder.value as Type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the effectiveness of an attack move against the Pokémon.
|
||||
* Calculates the effectiveness of a move against the Pokémon.
|
||||
*
|
||||
* @param source - The attacking Pokémon.
|
||||
* @param pokemonMove - The move being used by the attacking Pokémon.
|
||||
* @param ignoreAbility - Whether to check for abilities that might affect type effectiveness or immunity.
|
||||
* @param source {@linkcode Pokemon} The attacking Pokémon.
|
||||
* @param move {@linkcode Move} The move being used by the attacking Pokémon.
|
||||
* @param ignoreAbility Whether to ignore abilities that might affect type effectiveness or immunity (defaults to `false`).
|
||||
* @param simulated Whether to apply abilities via simulated calls (defaults to `true`)
|
||||
* @param cancelled {@linkcode Utils.BooleanHolder} Stores whether the move was cancelled by a non-type-based immunity.
|
||||
* Currently only used by {@linkcode Pokemon.apply} to determine whether a "No effect" message should be shown.
|
||||
* @returns The type damage multiplier, indicating the effectiveness of the move
|
||||
*/
|
||||
getAttackMoveEffectiveness(source: Pokemon, pokemonMove: PokemonMove, ignoreAbility: boolean = false): TypeDamageMultiplier {
|
||||
const move = pokemonMove.getMove();
|
||||
const typeless = move.hasAttr(TypelessAttr);
|
||||
const typeMultiplier = new Utils.NumberHolder(this.getAttackTypeEffectiveness(move, source));
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier);
|
||||
if (!typeless && !ignoreAbility) {
|
||||
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelled, true, typeMultiplier);
|
||||
getMoveEffectiveness(source: Pokemon, move: Move, ignoreAbility: boolean = false, simulated: boolean = true, cancelled?: Utils.BooleanHolder): TypeDamageMultiplier {
|
||||
if (move.hasAttr(TypelessAttr)) {
|
||||
return 1;
|
||||
}
|
||||
if (!cancelled.value && !ignoreAbility) {
|
||||
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelled, true, typeMultiplier);
|
||||
const moveType = source.getMoveType(move);
|
||||
|
||||
const typeMultiplier = new Utils.NumberHolder((move.category !== MoveCategory.STATUS || move.hasAttr(RespectAttackTypeImmunityAttr))
|
||||
? this.getAttackTypeEffectiveness(moveType, source, false, simulated)
|
||||
: 1);
|
||||
|
||||
applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier);
|
||||
if (this.getTypes().find(t => move.isTypeImmune(source, this, t))) {
|
||||
typeMultiplier.value = 0;
|
||||
}
|
||||
|
||||
return (!cancelled.value ? Number(typeMultiplier.value) : 0) as TypeDamageMultiplier;
|
||||
const cancelledHolder = cancelled ?? new Utils.BooleanHolder(false);
|
||||
if (!ignoreAbility) {
|
||||
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelledHolder, simulated, typeMultiplier);
|
||||
|
||||
if (!cancelledHolder.value) {
|
||||
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelledHolder, simulated, typeMultiplier);
|
||||
}
|
||||
|
||||
if (!cancelledHolder.value) {
|
||||
const defendingSidePlayField = this.isPlayer() ? this.scene.getPlayerField() : this.scene.getEnemyField();
|
||||
defendingSidePlayField.forEach((p) => applyPreDefendAbAttrs(FieldPriorityMoveImmunityAbAttr, p, source, move, cancelledHolder));
|
||||
}
|
||||
}
|
||||
|
||||
const immuneTags = this.findTags(tag => tag instanceof TypeImmuneTag && tag.immuneType === moveType);
|
||||
for (const tag of immuneTags) {
|
||||
if (move && !move.getAttrs(HitsTagAttr).some(attr => attr.tagType === tag.tagType)) {
|
||||
typeMultiplier.value = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (!cancelledHolder.value ? typeMultiplier.value : 0) as TypeDamageMultiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the type effectiveness multiplier for an attack type
|
||||
* @param moveOrType The move being used, or a type if the move is unknown
|
||||
* @param source the Pokemon using the move
|
||||
* @param moveType {@linkcode Type} the type of the move being used
|
||||
* @param source {@linkcode Pokemon} the Pokemon using the move
|
||||
* @param ignoreStrongWinds whether or not this ignores strong winds (anticipation, forewarn, stealth rocks)
|
||||
* @param simulated tag to only apply the strong winds effect message when the move is used
|
||||
* @returns a multiplier for the type effectiveness
|
||||
*/
|
||||
getAttackTypeEffectiveness(moveOrType: Move | Type, source?: Pokemon, ignoreStrongWinds: boolean = false, simulated: boolean = true): TypeDamageMultiplier {
|
||||
const move = (moveOrType instanceof Move)
|
||||
? moveOrType
|
||||
: undefined;
|
||||
const moveType = (moveOrType instanceof Move)
|
||||
? move!.type // TODO: is this bang correct?
|
||||
: moveOrType;
|
||||
|
||||
getAttackTypeEffectiveness(moveType: Type, source?: Pokemon, ignoreStrongWinds: boolean = false, simulated: boolean = true): TypeDamageMultiplier {
|
||||
if (moveType === Type.STELLAR) {
|
||||
return this.isTerastallized() ? 2 : 1;
|
||||
}
|
||||
@ -1281,7 +1304,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (source) {
|
||||
const ignoreImmunity = new Utils.BooleanHolder(false);
|
||||
if (source.isActive(true) && source.hasAbilityWithAttr(IgnoreTypeImmunityAbAttr)) {
|
||||
applyAbAttrs(IgnoreTypeImmunityAbAttr, source, ignoreImmunity, false, moveType, defType);
|
||||
applyAbAttrs(IgnoreTypeImmunityAbAttr, source, ignoreImmunity, simulated, moveType, defType);
|
||||
}
|
||||
if (ignoreImmunity.value) {
|
||||
return 1;
|
||||
@ -1303,15 +1326,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
this.scene.queueMessage(i18next.t("weather:strongWindsEffectMessage"));
|
||||
}
|
||||
}
|
||||
|
||||
const immuneTags = this.findTags(tag => tag instanceof TypeImmuneTag && tag.immuneType === moveType);
|
||||
for (const tag of immuneTags) {
|
||||
if (move && !move.getAttrs(HitsTagAttr).some(attr => attr.tagType === tag.tagType)) {
|
||||
multiplier = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return multiplier as TypeDamageMultiplier;
|
||||
}
|
||||
|
||||
@ -1959,29 +1973,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
let result: HitResult;
|
||||
const damage = new Utils.NumberHolder(0);
|
||||
const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||
const defendingSidePlayField = this.isPlayer() ? this.scene.getPlayerField() : this.scene.getEnemyField();
|
||||
|
||||
const variableCategory = new Utils.IntegerHolder(move.category);
|
||||
const variableCategory = new Utils.NumberHolder(move.category);
|
||||
applyMoveAttrs(VariableMoveCategoryAttr, source, this, move, variableCategory);
|
||||
const moveCategory = variableCategory.value as MoveCategory;
|
||||
|
||||
applyMoveAttrs(VariableMoveTypeAttr, source, this, move);
|
||||
const types = this.getTypes(true, true);
|
||||
/** The move's type after type-changing effects are applied */
|
||||
const moveType = source.getMoveType(move);
|
||||
|
||||
/** If `value` is `true`, cancels the move and suppresses "No Effect" messages */
|
||||
const cancelled = new Utils.BooleanHolder(false);
|
||||
const power = move.calculateBattlePower(source, this);
|
||||
const typeless = move.hasAttr(TypelessAttr);
|
||||
|
||||
const typeMultiplier = new Utils.NumberHolder(!typeless && (moveCategory !== MoveCategory.STATUS || move.getAttrs(StatusMoveTypeImmunityAttr).find(attr => types.includes(attr.immuneType)))
|
||||
? this.getAttackTypeEffectiveness(move, source, false, false)
|
||||
: 1);
|
||||
applyMoveAttrs(VariableMoveTypeMultiplierAttr, source, this, move, typeMultiplier);
|
||||
if (typeless) {
|
||||
typeMultiplier.value = 1;
|
||||
}
|
||||
if (types.find(t => move.isTypeImmune(source, this, t))) {
|
||||
typeMultiplier.value = 0;
|
||||
}
|
||||
/**
|
||||
* The effectiveness of the move being used. Along with type matchups, this
|
||||
* accounts for changes in effectiveness from the move's attributes and the
|
||||
* abilities of both the source and this Pokemon.
|
||||
*/
|
||||
const typeMultiplier = this.getMoveEffectiveness(source, move, false, false, cancelled);
|
||||
|
||||
switch (moveCategory) {
|
||||
case MoveCategory.PHYSICAL:
|
||||
@ -1989,27 +1997,44 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
const isPhysical = moveCategory === MoveCategory.PHYSICAL;
|
||||
const sourceTeraType = source.getTeraType();
|
||||
|
||||
if (!typeless) {
|
||||
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelled, false, typeMultiplier);
|
||||
applyMoveAttrs(NeutralDamageAgainstFlyingTypeMultiplierAttr, source, this, move, typeMultiplier);
|
||||
}
|
||||
if (!cancelled.value) {
|
||||
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelled, false, typeMultiplier);
|
||||
defendingSidePlayField.forEach((p) => applyPreDefendAbAttrs(FieldPriorityMoveImmunityAbAttr, p, source, move, cancelled, false, typeMultiplier));
|
||||
}
|
||||
const power = move.calculateBattlePower(source, this);
|
||||
|
||||
if (cancelled.value) {
|
||||
// Cancelled moves fail silently
|
||||
source.stopMultiHit(this);
|
||||
result = HitResult.NO_EFFECT;
|
||||
return HitResult.NO_EFFECT;
|
||||
} else {
|
||||
const typeBoost = source.findTag(t => t instanceof TypeBoostTag && t.boostedType === move.type) as TypeBoostTag;
|
||||
const typeBoost = source.findTag(t => t instanceof TypeBoostTag && t.boostedType === moveType) as TypeBoostTag;
|
||||
if (typeBoost?.oneUse) {
|
||||
source.removeTag(typeBoost.tagType);
|
||||
}
|
||||
|
||||
const arenaAttackTypeMultiplier = new Utils.NumberHolder(this.scene.arena.getAttackTypeMultiplier(move.type, source.isGrounded()));
|
||||
/** Combined damage multiplier from field effects such as weather, terrain, etc. */
|
||||
const arenaAttackTypeMultiplier = new Utils.NumberHolder(this.scene.arena.getAttackTypeMultiplier(moveType, source.isGrounded()));
|
||||
applyMoveAttrs(IgnoreWeatherTypeDebuffAttr, source, this, move, arenaAttackTypeMultiplier);
|
||||
|
||||
/**
|
||||
* Whether or not this Pokemon is immune to the incoming move.
|
||||
* Note that this isn't fully resolved in `getMoveEffectiveness` because
|
||||
* of possible type-suppressing field effects (e.g. Desolate Land's effect on Water-type attacks).
|
||||
*/
|
||||
const isTypeImmune = (typeMultiplier * arenaAttackTypeMultiplier.value) === 0;
|
||||
if (isTypeImmune) {
|
||||
// Moves with no effect that were not cancelled queue a "no effect" message before failing
|
||||
source.stopMultiHit(this);
|
||||
result = (move.id === Moves.SHEER_COLD)
|
||||
? HitResult.IMMUNE
|
||||
: HitResult.NO_EFFECT;
|
||||
|
||||
if (result === HitResult.IMMUNE) {
|
||||
this.scene.queueMessage(i18next.t("battle:hitResultImmune", { pokemonName: this.name }));
|
||||
} else {
|
||||
this.scene.queueMessage(i18next.t("battle:hitResultNoEffect", { pokemonName: getPokemonNameWithAffix(this) }));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const glaiveRushModifier = new Utils.IntegerHolder(1);
|
||||
if (this.getTag(BattlerTagType.RECEIVE_DOUBLE_DAMAGE)) {
|
||||
glaiveRushModifier.value = 2;
|
||||
@ -2059,13 +2084,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (!isCritical) {
|
||||
this.scene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, move.category, this.scene.currentBattle.double, screenMultiplier);
|
||||
}
|
||||
const isTypeImmune = (typeMultiplier.value * arenaAttackTypeMultiplier.value) === 0;
|
||||
const sourceTypes = source.getTypes();
|
||||
const matchesSourceType = sourceTypes[0] === move.type || (sourceTypes.length > 1 && sourceTypes[1] === move.type);
|
||||
const matchesSourceType = sourceTypes[0] === moveType || (sourceTypes.length > 1 && sourceTypes[1] === moveType);
|
||||
const stabMultiplier = new Utils.NumberHolder(1);
|
||||
if (sourceTeraType === Type.UNKNOWN && matchesSourceType) {
|
||||
stabMultiplier.value += 0.5;
|
||||
} else if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === move.type) {
|
||||
} else if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === moveType) {
|
||||
stabMultiplier.value += 0.5;
|
||||
}
|
||||
|
||||
@ -2075,8 +2099,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
stabMultiplier.value = Math.min(stabMultiplier.value + 0.5, 2.25);
|
||||
}
|
||||
|
||||
const targetCount = getMoveTargets(source, move.id).targets.length;
|
||||
const targetMultiplier = targetCount > 1 ? 0.75 : 1; // 25% damage debuff on multi-target hits (even if it's immune)
|
||||
// 25% damage debuff on moves hitting more than one non-fainted target (regardless of immunities)
|
||||
const { targets, multiple } = getMoveTargets(source, move.id);
|
||||
const targetMultiplier = (multiple && targets.length > 1) ? 0.75 : 1;
|
||||
|
||||
applyMoveAttrs(VariableAtkAttr, source, this, move, sourceAtk);
|
||||
applyMoveAttrs(VariableDefAttr, source, this, move, targetDef);
|
||||
@ -2094,7 +2119,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
const randomMultiplier = ((this.scene.randBattleSeedInt(16) + 85) / 100);
|
||||
damage.value = Utils.toDmgValue((((levelMultiplier * power * sourceAtk.value / targetDef.value) / 50) + 2)
|
||||
* stabMultiplier.value
|
||||
* typeMultiplier.value
|
||||
* typeMultiplier
|
||||
* arenaAttackTypeMultiplier.value
|
||||
* screenMultiplier.value
|
||||
* twoStrikeMultiplier.value
|
||||
@ -2128,7 +2153,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
});
|
||||
}
|
||||
|
||||
if (this.scene.arena.terrain?.terrainType === TerrainType.MISTY && this.isGrounded() && move.type === Type.DRAGON) {
|
||||
if (this.scene.arena.terrain?.terrainType === TerrainType.MISTY && this.isGrounded() && moveType === Type.DRAGON) {
|
||||
damage.value = Utils.toDmgValue(damage.value / 2);
|
||||
}
|
||||
|
||||
@ -2142,22 +2167,18 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
result = result!; // telling TS compiler that result is defined!
|
||||
|
||||
if (!result) {
|
||||
if (!typeMultiplier.value) {
|
||||
result = move.id === Moves.SHEER_COLD ? HitResult.IMMUNE : HitResult.NO_EFFECT;
|
||||
const isOneHitKo = new Utils.BooleanHolder(false);
|
||||
applyMoveAttrs(OneHitKOAttr, source, this, move, isOneHitKo);
|
||||
if (isOneHitKo.value) {
|
||||
result = HitResult.ONE_HIT_KO;
|
||||
isCritical = false;
|
||||
damage.value = this.hp;
|
||||
} else if (typeMultiplier >= 2) {
|
||||
result = HitResult.SUPER_EFFECTIVE;
|
||||
} else if (typeMultiplier >= 1) {
|
||||
result = HitResult.EFFECTIVE;
|
||||
} else {
|
||||
const isOneHitKo = new Utils.BooleanHolder(false);
|
||||
applyMoveAttrs(OneHitKOAttr, source, this, move, isOneHitKo);
|
||||
if (isOneHitKo.value) {
|
||||
result = HitResult.ONE_HIT_KO;
|
||||
isCritical = false;
|
||||
damage.value = this.hp;
|
||||
} else if (typeMultiplier.value >= 2) {
|
||||
result = HitResult.SUPER_EFFECTIVE;
|
||||
} else if (typeMultiplier.value >= 1) {
|
||||
result = HitResult.EFFECTIVE;
|
||||
} else {
|
||||
result = HitResult.NOT_VERY_EFFECTIVE;
|
||||
}
|
||||
result = HitResult.NOT_VERY_EFFECTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2224,15 +2245,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
case HitResult.NOT_VERY_EFFECTIVE:
|
||||
this.scene.queueMessage(i18next.t("battle:hitResultNotVeryEffective"));
|
||||
break;
|
||||
case HitResult.NO_EFFECT:
|
||||
this.scene.queueMessage(i18next.t("battle:hitResultNoEffect", { pokemonName: getPokemonNameWithAffix(this) }));
|
||||
break;
|
||||
case HitResult.IMMUNE:
|
||||
this.scene.queueMessage(i18next.t("battle:hitResultImmune", { pokemonName: this.name }));
|
||||
break;
|
||||
case HitResult.ONE_HIT_KO:
|
||||
this.scene.queueMessage(i18next.t("battle:hitResultOneHitKO"));
|
||||
break;
|
||||
case HitResult.IMMUNE:
|
||||
case HitResult.NO_EFFECT:
|
||||
console.error("Unhandled move immunity!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2244,23 +2263,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
if (damage) {
|
||||
const attacker = this.scene.getPokemonById(source.id)!; // TODO: is this bang correct?
|
||||
destinyTag?.lapse(attacker, BattlerTagLapseType.CUSTOM);
|
||||
destinyTag?.lapse(source, BattlerTagLapseType.CUSTOM);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MoveCategory.STATUS:
|
||||
if (!typeless) {
|
||||
applyPreDefendAbAttrs(TypeImmunityAbAttr, this, source, move, cancelled, false, typeMultiplier);
|
||||
}
|
||||
if (!cancelled.value) {
|
||||
applyPreDefendAbAttrs(MoveImmunityAbAttr, this, source, move, cancelled, false, typeMultiplier);
|
||||
defendingSidePlayField.forEach((p) => applyPreDefendAbAttrs(FieldPriorityMoveImmunityAbAttr, p, source, move, cancelled, false, typeMultiplier));
|
||||
}
|
||||
if (!typeMultiplier.value) {
|
||||
if (!cancelled.value && typeMultiplier === 0) {
|
||||
this.scene.queueMessage(i18next.t("battle:hitResultNoEffect", { pokemonName: getPokemonNameWithAffix(this) }));
|
||||
}
|
||||
result = cancelled.value || !typeMultiplier.value ? HitResult.NO_EFFECT : HitResult.STATUS;
|
||||
result = (typeMultiplier === 0) ? HitResult.NO_EFFECT : HitResult.STATUS;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2630,7 +2641,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
private fusionFaintCry(callback: Function): void {
|
||||
const key = this.getSpeciesForm().getCryKey(this.formIndex);
|
||||
const key = `cry/${this.getSpeciesForm().getCryKey(this.formIndex)}`;
|
||||
let i = 0;
|
||||
let rate = 0.85;
|
||||
const cry = this.scene.playSound(key, { rate: rate }) as AnySound;
|
||||
@ -2638,7 +2649,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
const tintSprite = this.getTintSprite();
|
||||
let duration = cry.totalDuration * 1000;
|
||||
|
||||
let fusionCry = this.scene.playSound(this.getFusionSpeciesForm().getCryKey(this.fusionFormIndex), { rate: rate }) as AnySound;
|
||||
const fusionCryKey = `cry/${this.getFusionSpeciesForm().getCryKey(this.fusionFormIndex)}`;
|
||||
let fusionCry = this.scene.playSound(fusionCryKey, { rate: rate }) as AnySound;
|
||||
fusionCry.stop();
|
||||
duration = Math.min(duration, fusionCry.totalDuration * 1000);
|
||||
fusionCry.destroy();
|
||||
@ -2682,7 +2694,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
if (i === transitionIndex) {
|
||||
SoundFade.fadeOut(this.scene, cry, Utils.fixedInt(Math.ceil((duration / rate) * 0.2)));
|
||||
fusionCry = this.scene.playSound(this.getFusionSpeciesForm().getCryKey(this.fusionFormIndex), Object.assign({ seek: Math.max(fusionCry.totalDuration * 0.4, 0), rate: rate }));
|
||||
fusionCry = this.scene.playSound(fusionCryKey, Object.assign({ seek: Math.max(fusionCry.totalDuration * 0.4, 0), rate: rate }));
|
||||
SoundFade.fadeIn(this.scene, fusionCry, Utils.fixedInt(Math.ceil((duration / rate) * 0.2)), this.scene.masterVolume * this.scene.seVolume, 0);
|
||||
}
|
||||
rate *= 0.99;
|
||||
@ -3917,7 +3929,7 @@ export class EnemyPokemon extends Pokemon {
|
||||
* Attack moves are given extra multipliers to their base benefit score based on
|
||||
* the move's type effectiveness against the target and whether the move is a STAB move.
|
||||
*/
|
||||
const effectiveness = target.getAttackMoveEffectiveness(this, pokemonMove);
|
||||
const effectiveness = target.getMoveEffectiveness(this, move, !target.battleData?.abilityRevealed);
|
||||
if (target.isPlayer() !== this.isPlayer()) {
|
||||
targetScore *= effectiveness;
|
||||
if (this.isOfType(move.type)) {
|
||||
|
@ -359,12 +359,12 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
||||
let species = useNewSpeciesPool
|
||||
? getPokemonSpecies(newSpeciesPool[Math.floor(Math.random() * newSpeciesPool.length)])
|
||||
: template.isSameSpecies(index) && index > offset
|
||||
? getPokemonSpecies(battle.enemyParty[offset].species.getTrainerSpeciesForLevel(level, false, template.getStrength(offset)))
|
||||
? getPokemonSpecies(battle.enemyParty[offset].species.getTrainerSpeciesForLevel(level, false, template.getStrength(offset), this.scene.currentBattle.waveIndex))
|
||||
: this.genNewPartyMemberSpecies(level, strength);
|
||||
|
||||
// If the species is from newSpeciesPool, we need to adjust it based on the level and strength
|
||||
if (newSpeciesPool) {
|
||||
species = getPokemonSpecies(species.getSpeciesForLevel(level, true, true, strength));
|
||||
species = getPokemonSpecies(species.getSpeciesForLevel(level, true, true, strength, this.scene.currentBattle.waveIndex));
|
||||
}
|
||||
|
||||
ret = this.scene.addEnemyPokemon(species, level, !this.isDouble() || !(index % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER);
|
||||
@ -393,7 +393,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
||||
species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
|
||||
}
|
||||
|
||||
let ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength));
|
||||
let ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex));
|
||||
let retry = false;
|
||||
|
||||
console.log(ret.getName());
|
||||
@ -412,7 +412,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
||||
console.log("Attempting reroll of species evolution to fit specialty type...");
|
||||
let evoAttempt = 0;
|
||||
while (retry && evoAttempt++ < 10) {
|
||||
ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength));
|
||||
ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex));
|
||||
console.log(ret.name);
|
||||
if (this.config.specialtyTypes.find(t => ret.isOfType(t))) {
|
||||
retry = false;
|
||||
|
@ -45,6 +45,7 @@
|
||||
"battle_legendary_lake_trio": "ORAS Vs. Seen-Trio",
|
||||
"battle_legendary_sinnoh": "ORAS Vs. Legendäres Sinnoh Pokémon",
|
||||
"battle_legendary_dia_pal": "ORAS Vs. Dialga & Palkia",
|
||||
"battle_legendary_origin_forme": "PLA Vs. Urform Dialga & Palkia",
|
||||
"battle_legendary_giratina": "ORAS Vs. Giratina",
|
||||
"battle_legendary_arceus": "HGSS Vs. Arceus",
|
||||
"battle_legendary_unova": "SW Vs. Legendäres Einall Pokémon",
|
||||
@ -59,6 +60,7 @@
|
||||
"battle_legendary_zac_zam": "SWSH Vs. Zacian & Zamazenta",
|
||||
"battle_legendary_glas_spec": "SWSH Vs. Polaross & Phantoross",
|
||||
"battle_legendary_calyrex": "SWSH Vs. Coronospa",
|
||||
"battle_legendary_riders": "SWSH Vs. Schimmelreiter & Rappenreiter Coronospa",
|
||||
"battle_legendary_birds_galar": "SWSH Vs. Legendäre Galar-Vögel",
|
||||
"battle_legendary_ruinous": "KAPU Vs. Schätze des Unheils",
|
||||
"battle_legendary_kor_mir": "KAPU Die Tiefen von Zone Null",
|
||||
@ -135,4 +137,4 @@
|
||||
"heal": "SW Pokémon-Heilung",
|
||||
"menu": "PMD Erkundungsteam Himmel Willkommen in der Welt der Pokémon!",
|
||||
"title": "PMD Erkundungsteam Himmel Top-Menü-Thema"
|
||||
}
|
||||
}
|
||||
|
@ -355,6 +355,30 @@
|
||||
"1": "Ich werde für das nächste Rennen tunen."
|
||||
}
|
||||
},
|
||||
"firebreather": {
|
||||
"encounter": {
|
||||
"1": "Meine Flammen werden dich verschlingen!",
|
||||
"2": "Meine Seele hat Feuer gefangen. Ich werde dir zeigen, wie heiß sie brennt!",
|
||||
"3": "Komm näher und sieh dir meine Flammen an!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Verbrannt bis zur Asche...",
|
||||
"2": "Yow! Das ist heiß!",
|
||||
"3": "Auuu! Ich habe mir die Nasenspitze verbrannt!"
|
||||
}
|
||||
},
|
||||
"sailor": {
|
||||
"encounter": {
|
||||
"1": "Matrose, du gehst über Bord, wenn du verlierst!",
|
||||
"2": "Komm schon! Mein Stolz als Seemann steht auf dem Spiel!",
|
||||
"3": "Ahoj! Bist du seekrank?"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Argh! Von einem Kind besiegt!",
|
||||
"2": "Dein Geist hat mich versenkt!",
|
||||
"3": "Ich glaube, ich bin der der seekrank ist..."
|
||||
}
|
||||
},
|
||||
"archer": {
|
||||
"encounter": {
|
||||
"1": "Bevor du weitergehst, lass uns sehen, wie du dich gegen uns, Team Rocket, schlägst!",
|
||||
@ -535,30 +559,6 @@
|
||||
"3": "Wunderbar! Bemerkenswert! Deine Fähigkeiten und dein Mut sind lobenswert."
|
||||
}
|
||||
},
|
||||
"firebreather": {
|
||||
"encounter": {
|
||||
"1": "Meine Flammen werden dich verschlingen!",
|
||||
"2": "Meine Seele hat Feuer gefangen. Ich werde dir zeigen, wie heiß sie brennt!",
|
||||
"3": "Komm näher und sieh dir meine Flammen an!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Verbrannt bis zur Asche...",
|
||||
"2": "Yow! Das ist heiß!",
|
||||
"3": "Auuu! Ich habe mir die Nasenspitze verbrannt!"
|
||||
}
|
||||
},
|
||||
"sailor": {
|
||||
"encounter": {
|
||||
"1": "Matrose, du gehst über Bord, wenn du verlierst!",
|
||||
"2": "Komm schon! Mein Stolz als Seemann steht auf dem Spiel!",
|
||||
"3": "Ahoj! Bist du seekrank?"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Argh! Von einem Kind besiegt!",
|
||||
"2": "Dein Geist hat mich versenkt!",
|
||||
"3": "Ich glaube, ich bin der der seekrank ist..."
|
||||
}
|
||||
},
|
||||
"rocket_grunt": {
|
||||
"encounter": {
|
||||
"1": "Jetzt gibt es Ärger!…\n$und es kommt noch härter!\n$Wir wollen über die Erde regieren…\n$und naja du kennst den Rest…!",
|
||||
@ -2455,7 +2455,7 @@
|
||||
"1": "@c{smile}Hey, du auch hier?\n@c{smile_eclosed}Immernoch ungeschlagen, hmm…?\n$@c{serious_mopen_fists}Ich weiß es sieht so aus, als wäre ich dir hierher gefolgt, aber das ist so nicht ganz richtig.\n$@c{serious_smile_fists}Ehrlicherweise kann ich es, seit du mich damals besiegt hast, garnicht erwarten erneut gegen dich zu kämpfen.\n$Ich habe selbst hart traniert. Ich werde dir diesesmal also ein würdigerer Gegner sein!.\n$@c{serious_mopen_fists}Halt dich nicht zurück, genauso wie beim letzten Mal!\nLos gehts!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "@c{neutral_eclosed}Oh. Ich war also zu sehr von mir überzeugt.\n$@c{smile}Das ist Ok. Ich hatte mir schon gedacht, dass sowas passiert.\n\n$@c{serious_mopen_fists}Es bedeutet einfach, dass ich mich beim nächsten Mal mehr anstrengen muss!\n\n$@c{smile}Nicht, dass du wirklich Hilfe benötigen würdest, aber ich habe hier noch eins von diesen Dingern herumliegen.\n$Du kannst es haben.\n\n$@c{serious_smile_fists}Erwarte aber nicht, dass ich dir noch mehr gebe!\nIch kann meinen Rivalen doch keine Vorteile verschaffen.\n$@c{smile}Egal, pass auf dich auf und genieße das Event!"
|
||||
"1": "@c{neutral_eclosed}Oh. Ich war also zu sehr von mir überzeugt.\n$@c{smile}Das ist Ok. Ich hatte mir schon gedacht, dass sowas passiert.\n\n$@c{serious_mopen_fists}Es bedeutet einfach, dass ich mich beim nächsten Mal mehr anstrengen muss!\n\n$@c{smile}Nicht, dass du wirklich Hilfe benötigen würdest, aber ich habe hier noch eins von diesen Dingern herumliegen.\n$Du kannst es haben.\n\n$@c{serious_smile_fists}Erwarte aber nicht, dass ich dir noch mehr gebe!\nIch kann meinen Rivalen doch keine Vorteile verschaffen.\n$@c{smile}Egal, pass auf dich auf!"
|
||||
}
|
||||
},
|
||||
"rival_2_female": {
|
||||
@ -2463,7 +2463,7 @@
|
||||
"1": "@c{smile_wave}Oh, wie schön dich hier zu trefen. Sieht so aus als wärst du noch ungeschlagen. @c{angry_mopen}Hmm… Nicht schlecht!\n$@c{angry_mopen}Ich weiß was du denkst, und nein, ich habe dich nicht verfolgt. @c{smile_eclosed}Ich bin einfach in der Gegend gewesen.\n$@c{smile_ehalf}Ich freu mich für dich, aber ich muss dich wissen lassen, dass es auch Ok ist ab und zu mal zu verlieren.\n$@c{smile}Wir lernen oft mehr aus unseren Fehlern, als aus unseren Erfolgen.\n$@c{angry_mopen}Auf jeden Fall habe ich für unseren Rückkampf hart traniert. Also zeig mir was du drauf hast!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "@c{neutral}Ich… sollte dieses Mal doch nicht verlieren…\n$@c{smile}Na gut. Das bedeutet ich muss noch härter tranieren!\n$@c{smile_wave}Ich habe noch eins von diesen Dingern!\n@c{smile_wave_wink}Kein Grund mir zu danken~.\n$@c{angry_mopen}Das ist aber das Letzte! Du bekommst ab jett keine Geschenke mehr von mir!\n$@c{smile_wave}Bleib stark und genieße das Event!"
|
||||
"1": "@c{neutral}Ich… sollte dieses Mal doch nicht verlieren…\n$@c{smile}Na gut. Das bedeutet ich muss noch härter tranieren!\n$@c{smile_wave}Ich habe noch eins von diesen Dingern!\n@c{smile_wave_wink}Kein Grund mir zu danken~.\n$@c{angry_mopen}Das ist aber das Letzte! Du bekommst ab jett keine Geschenke mehr von mir!\n$@c{smile_wave}Bleib stark!"
|
||||
},
|
||||
"defeat": {
|
||||
"1": "Es ist Ok manchmal zu verlieren…"
|
||||
@ -2542,4 +2542,4 @@
|
||||
"1": "@c{smile_ehalf}Ich… Ich denke ich habe meine Aufgabe erfüllt.\n$@c{smile_eclosed}Versprich mir… Nachdem du die Welt geheilt hast… Komm bitte sicher nach Hause. \n$@c{smile_ehalf}…Danke."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -355,6 +355,30 @@
|
||||
"1": "Ich werde für das nächste Rennen tunen."
|
||||
}
|
||||
},
|
||||
"firebreather": {
|
||||
"encounter": {
|
||||
"1": "Meine Flammen werden dich verschlingen!",
|
||||
"2": "Meine Seele hat Feuer gefangen. Ich werde dir zeigen, wie heiß sie brennt!",
|
||||
"3": "Komm näher und sieh dir meine Flammen an!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Verbrannt bis zur Asche...",
|
||||
"2": "Yow! Das ist heiß!",
|
||||
"3": "Auuu! Ich habe mir die Nasenspitze verbrannt!"
|
||||
}
|
||||
},
|
||||
"sailor": {
|
||||
"encounter": {
|
||||
"1": "Matrose, du gehst über Bord, wenn du verlierst!",
|
||||
"2": "Komm schon! Mein Stolz als Seemann steht auf dem Spiel!",
|
||||
"3": "Ahoj! Bist du seekrank?"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Argh! Von einem Kind besiegt!",
|
||||
"2": "Dein Geist hat mich versenkt!",
|
||||
"3": "Ich glaube, ich bin der der seekrank ist..."
|
||||
}
|
||||
},
|
||||
"archer": {
|
||||
"encounter": {
|
||||
"1": "Bevor du weitergehst, lass uns sehen, wie du dich gegen uns, Team Rocket, schlägst!",
|
||||
@ -535,30 +559,6 @@
|
||||
"3": "Wunderbar! Bemerkenswert! Deine Fähigkeiten und dein Mut sind lobenswert."
|
||||
}
|
||||
},
|
||||
"firebreather": {
|
||||
"encounter": {
|
||||
"1": "Meine Flammen werden dich verschlingen!",
|
||||
"2": "Meine Seele hat Feuer gefangen. Ich werde dir zeigen, wie heiß sie brennt!",
|
||||
"3": "Komm näher und sieh dir meine Flammen an!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Verbrannt bis zur Asche...",
|
||||
"2": "Yow! Das ist heiß!",
|
||||
"3": "Auuu! Ich habe mir die Nasenspitze verbrannt!"
|
||||
}
|
||||
},
|
||||
"sailor": {
|
||||
"encounter": {
|
||||
"1": "Matrose, du gehst über Bord, wenn du verlierst!",
|
||||
"2": "Komm schon! Mein Stolz als Seemann steht auf dem Spiel!",
|
||||
"3": "Ahoj! Bist du seekrank?"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Argh! Von einem Kind besiegt!",
|
||||
"2": "Dein Geist hat mich versenkt!",
|
||||
"3": "Ich glaube, ich bin der der seekrank ist..."
|
||||
}
|
||||
},
|
||||
"rocket_grunt": {
|
||||
"encounter": {
|
||||
"1": "Jetzt gibt es Ärger!…\n$und es kommt noch härter!\n$Wir wollen über die Erde regieren…\n$und naja du kennst den Rest…!",
|
||||
@ -2439,7 +2439,7 @@
|
||||
"1": "@c{smile}Hey, ich habe dich gesucht! Ich weiß, dass du es nicht erwarten konntest loszugehen,\n$aber hättest ja wenigstens Tschüss sagen können...\n$@c{smile_eclosed}Du verfolgst also wirklich deinen Traum?\nIch kann es kaum glauben.\n$@c{serious_smile_fists}Da wir schon einmal hier sind, wie wäre es mit einem Kampf?\nImmerhin muss ich doch sicherstellen, dass du bereit bist.\n$@c{serious_mopen_fists}Halte dich nicht zurück, zeig mir alles was du hast!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "@c{shock}Wow…Du hast mich komplett überrumpelt.\nBist du wirklich ein Anfänger?\n$@c{smile}Vielleicht war es einfach etwas Glück, aber…\nWer weiß, vielleicht schaffst du es irgendwann\n$ja wirklich ganz groß raus zu kommen.\n$Übrigens, der Professor hat mich gebeten dir diese Items zu geben. Die sehen wirklich cool aus.\n$@c{serious_smile_fists}Viel Glück da draußen!\n$@c{smile}Oh-und genieße das Event!"
|
||||
"1": "@c{shock}Wow…Du hast mich komplett überrumpelt.\nBist du wirklich ein Anfänger?\n$@c{smile}Vielleicht war es einfach etwas Glück, aber…\nWer weiß, vielleicht schaffst du es irgendwann\n$ja wirklich ganz groß raus zu kommen.\n$Übrigens, der Professor hat mich gebeten dir diese Items zu geben. Die sehen wirklich cool aus.\n$@c{serious_smile_fists}Viel Glück da draußen!"
|
||||
}
|
||||
},
|
||||
"rival_female": {
|
||||
@ -2447,7 +2447,7 @@
|
||||
"1": "@c{smile_wave}Da bist du! Ich habe schon überall nach dir gesucht!\n@c{angry_mopen}Hast du etwas vergessen\n$deiner besten Freundin Tschüss zu sagen?\n$@c{smile_ehalf}Du folgst deinem Traum, oder?\nDas ist wirklich heute…\n$@c{smile}Naja, ich vergeben dir, dass du mich vergessen hast, aber nur unter einer Bedingung. @c{smile_wave_wink}Du musst gegen mich kämpfen!\n$@c{angry_mopen}Gib alles! Wir wollen doch nicht, dass dein Abenteuer endet bevor es begonnen hat, richtig?"
|
||||
},
|
||||
"victory": {
|
||||
"1": "@c{shock}Du hast gerade erst angefangen und bist schon so stark?!@d{96} @c{angry}Du hast sowas von betrogen, oder?\n$@c{smile_wave_wink}Ich mach nur Spaß!@d{64} @c{smile_eclosed}Ich habe ehrlich verloren… Ich habe das Gefühl, dass du es dort draußen weit bringen wirst.\n$@c{smile}Übrigens, der Professor hat mich gebeten dir diese Items zu geben. Ich hoffe sie sind hilfreich!\n$@c{smile_wave}Gib wie immer dein Bestes! Ich glaube an dich!\n$@c{smile}Oh-und genieße das Event!"
|
||||
"1": "@c{shock}Du hast gerade erst angefangen und bist schon so stark?!@d{96} @c{angry}Du hast sowas von betrogen, oder?\n$@c{smile_wave_wink}Ich mach nur Spaß!@d{64} @c{smile_eclosed}Ich habe ehrlich verloren… Ich habe das Gefühl, dass du es dort draußen weit bringen wirst.\n$@c{smile}Übrigens, der Professor hat mich gebeten dir diese Items zu geben. Ich hoffe sie sind hilfreich!\n$@c{smile_wave}Gib wie immer dein Bestes! Ich glaube an dich!"
|
||||
}
|
||||
},
|
||||
"rival_2": {
|
||||
@ -2455,7 +2455,7 @@
|
||||
"1": "@c{smile}Hey, du auch hier?\n@c{smile_eclosed}Immernoch ungeschlagen, hmm…?\n$@c{serious_mopen_fists}Ich weiß es sieht so aus, als wäre ich dir hierher gefolgt, aber das ist so nicht ganz richtig.\n$@c{serious_smile_fists}Ehrlicherweise kann ich es, seit du mich damals besiegt hast, garnicht erwarten erneut gegen dich zu kämpfen.\n$Ich habe selbst hart traniert. Ich werde dir diesesmal also ein würdigerer Gegner sein!.\n$@c{serious_mopen_fists}Halt dich nicht zurück, genauso wie beim letzten Mal!\nLos gehts!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "@c{neutral_eclosed}Oh. Ich war also zu sehr von mir überzeugt.\n$@c{smile}Das ist Ok. Ich hatte mir schon gedacht, dass sowas passiert.\n\n$@c{serious_mopen_fists}Es bedeutet einfach, dass ich mich beim nächsten Mal mehr anstrengen muss!\n\n$@c{smile}Nicht, dass du wirklich Hilfe benötigen würdest, aber ich habe hier noch eins von diesen Dingern herumliegen.\n$Du kannst es haben.\n\n$@c{serious_smile_fists}Erwarte aber nicht, dass ich dir noch mehr gebe!\nIch kann meinen Rivalen doch keine Vorteile verschaffen.\n$@c{smile}Egal, pass auf dich auf und genieße das Event!"
|
||||
"1": "@c{neutral_eclosed}Oh. Ich war also zu sehr von mir überzeugt.\n$@c{smile}Das ist Ok. Ich hatte mir schon gedacht, dass sowas passiert.\n\n$@c{serious_mopen_fists}Es bedeutet einfach, dass ich mich beim nächsten Mal mehr anstrengen muss!\n\n$@c{smile}Nicht, dass du wirklich Hilfe benötigen würdest, aber ich habe hier noch eins von diesen Dingern herumliegen.\n$Du kannst es haben.\n\n$@c{serious_smile_fists}Erwarte aber nicht, dass ich dir noch mehr gebe!\nIch kann meinen Rivalen doch keine Vorteile verschaffen.\n$@c{smile}Egal, pass auf dich auf!"
|
||||
}
|
||||
},
|
||||
"rival_2_female": {
|
||||
@ -2463,7 +2463,7 @@
|
||||
"1": "@c{smile_wave}Oh, wie schön dich hier zu trefen. Sieht so aus als wärst du noch ungeschlagen. @c{angry_mopen}Hmm… Nicht schlecht!\n$@c{angry_mopen}Ich weiß was du denkst, und nein, ich habe dich nicht verfolgt. @c{smile_eclosed}Ich bin einfach in der Gegend gewesen.\n$@c{smile_ehalf}Ich freu mich für dich, aber ich muss dich wissen lassen, dass es auch Ok ist ab und zu mal zu verlieren.\n$@c{smile}Wir lernen oft mehr aus unseren Fehlern, als aus unseren Erfolgen.\n$@c{angry_mopen}Auf jeden Fall habe ich für unseren Rückkampf hart traniert. Also zeig mir was du drauf hast!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "@c{neutral}Ich… sollte dieses Mal doch nicht verlieren…\n$@c{smile}Na gut. Das bedeutet ich muss noch härter tranieren!\n$@c{smile_wave}Ich habe noch eins von diesen Dingern!\n@c{smile_wave_wink}Kein Grund mir zu danken~.\n$@c{angry_mopen}Das ist aber das Letzte! Du bekommst ab jett keine Geschenke mehr von mir!\n$@c{smile_wave}Bleib stark und genieße das Event!"
|
||||
"1": "@c{neutral}Ich… sollte dieses Mal doch nicht verlieren…\n$@c{smile}Na gut. Das bedeutet ich muss noch härter tranieren!\n$@c{smile_wave}Ich habe noch eins von diesen Dingern!\n@c{smile_wave_wink}Kein Grund mir zu danken~.\n$@c{angry_mopen}Das ist aber das Letzte! Du bekommst ab jett keine Geschenke mehr von mir!\n$@c{smile_wave}Bleib stark"
|
||||
},
|
||||
"defeat": {
|
||||
"1": "Es ist Ok manchmal zu verlieren…"
|
||||
@ -2542,4 +2542,4 @@
|
||||
"1": "@c{smile_ehalf}Ich… Ich denke ich habe meine Aufgabe erfüllt.\n$@c{smile_eclosed}Versprich mir… Nachdem du die Welt geheilt hast… Komm bitte sicher nach Hause. \n$@c{smile_ehalf}…Danke."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
{
|
||||
"ending": "@c{smile}Oh? Du hast gewonnen?@d{96} @c{smile_eclosed}Ich schätze, das hätte ich wissen sollen.\n$Aber, du bist jetzt zurück.\n$@c{smile}Es ist vorbei.@d{64} Du hast die Schleife beendet.\n$@c{serious_smile_fists}Du hast auch deinen Traum erfüllt, nicht wahr?\nDu hast nicht einmal verloren.\n$@c{neutral}Ich bin der Einzige, der sich daran erinnern wird, was du getan hast.@d{96}\n$Ich schätze, das ist in Ordnung, oder?\n$@c{serious_smile_fists}Deine Legende wird immer in unseren Herzen weiterleben.\n$@c{smile_eclosed}Wie auch immer, ich habe genug von diesem Ort, oder nicht? Lass uns nach Hause gehen.\n$@c{serious_smile_fists}Vielleicht können wir, wenn wir zurück sind, noch einen Kampf haben?\n$Wenn du dazu bereit bist.",
|
||||
"ending_female": "@c{shock}Du bist zurück?@d{32} Bedeutet das…@d{96} du hast gewonnen?!\n$@c{smile_ehalf}Ich hätte wissen sollen, dass du es in dir hast.\n$@c{smile_eclosed}Natürlich… ich hatte immer dieses Gefühl.\n$@c{smile}Es ist jetzt vorbei, richtig? Du hast die Schleife beendet.\n$@c{smile_ehalf}Du hast auch deinen Traum erfüllt, nicht wahr?\n$Du hast nicht einmal verloren.\n$Ich werde die Einzige sein, die sich daran erinnert, was du getan hast.\n$@c{angry_mopen}Ich werde versuchen, es nicht zu vergessen!\n$@c{smile_wave_wink}Nur ein Scherz!@d{64} @c{smile}Ich würde es nie vergessen.@d{32}\n$Deine Legende wird in unseren Herzen weiterleben.\n$@c{smile_wave}Wie auch immer,@d{64} es wird spät…@d{96} denke ich?\nEs ist schwer zu sagen an diesem Ort.\n$Lass uns nach Hause gehen. \n$@c{smile_wave_wink}Vielleicht können wir morgen noch einen Kampf haben, der alten Zeiten willen?"
|
||||
}
|
||||
"ending_female": "@c{shock}Du bist zurück?@d{32} Bedeutet das…@d{96} du hast gewonnen?!\n$@c{smile_ehalf}Ich hätte wissen sollen, dass du es in dir hast.\n$@c{smile_eclosed}Natürlich… ich hatte immer dieses Gefühl.\n$@c{smile}Es ist jetzt vorbei, richtig? Du hast die Schleife beendet.\n$@c{smile_ehalf}Du hast auch deinen Traum erfüllt, nicht wahr?\n$Du hast nicht einmal verloren.\n$Ich werde die Einzige sein, die sich daran erinnert, was du getan hast.\n$@c{angry_mopen}Ich werde versuchen, es nicht zu vergessen!\n$@c{smile_wave_wink}Nur ein Scherz!@d{64} @c{smile}Ich würde es nie vergessen.@d{32}\n$Deine Legende wird in unseren Herzen weiterleben.\n$@c{smile_wave}Wie auch immer,@d{64} es wird spät…@d{96} denke ich?\nEs ist schwer zu sagen an diesem Ort.\n$Lass uns nach Hause gehen. \n$@c{smile_wave_wink}Vielleicht können wir morgen noch einen Kampf haben, der alten Zeiten willen?",
|
||||
"ending_endless": "Glückwunsch! Du hast das aktuelle Ende erreicht!\nWir arbeiten an mehr Spielinhalten.",
|
||||
"ending_name": "Entwickler"
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
{
|
||||
"ending": "@c{smile}Oh? Du hast gewonnen?@d{96} @c{smile_eclosed}Ich schätze, das hätte ich wissen sollen.\n$Aber, du bist jetzt zurück.\n$@c{smile}Es ist vorbei.@d{64} Du hast die Schleife beendet.\n$@c{serious_smile_fists}Du hast auch deinen Traum erfüllt, nicht wahr?\nDu hast nicht einmal verloren.\n$@c{neutral}Ich bin der Einzige, der sich daran erinnern wird, was du getan hast.@d{96}\n$Ich schätze, das ist in Ordnung, oder?\n$@c{serious_smile_fists}Deine Legende wird immer in unseren Herzen weiterleben.\n$@c{smile_eclosed}Wie auch immer, ich habe genug von diesem Ort, oder nicht? Lass uns nach Hause gehen.\n$@c{serious_smile_fists}Vielleicht können wir, wenn wir zurück sind, noch einen Kampf haben?\n$Wenn du dazu bereit bist.",
|
||||
"ending_female": "@c{shock}Du bist zurück?@d{32} Bedeutet das…@d{96} du hast gewonnen?!\n$@c{smile_ehalf}Ich hätte wissen sollen, dass du es in dir hast.\n$@c{smile_eclosed}Natürlich… ich hatte immer dieses Gefühl.\n$@c{smile}Es ist jetzt vorbei, richtig? Du hast die Schleife beendet.\n$@c{smile_ehalf}Du hast auch deinen Traum erfüllt, nicht wahr?\n$Du hast nicht einmal verloren.\n$Ich werde die Einzige sein, die sich daran erinnert, was du getan hast.\n$@c{angry_mopen}Ich werde versuchen, es nicht zu vergessen!\n$@c{smile_wave_wink}Nur ein Scherz!@d{64} @c{smile}Ich würde es nie vergessen.@d{32}\n$Deine Legende wird in unseren Herzen weiterleben.\n$@c{smile_wave}Wie auch immer,@d{64} es wird spät…@d{96} denke ich?\nEs ist schwer zu sagen an diesem Ort.\n$Lass uns nach Hause gehen. \n$@c{smile_wave_wink}Vielleicht können wir morgen noch einen Kampf haben, der alten Zeiten willen?"
|
||||
}
|
||||
"ending_female": "@c{shock}Du bist zurück?@d{32} Bedeutet das…@d{96} du hast gewonnen?!\n$@c{smile_ehalf}Ich hätte wissen sollen, dass du es in dir hast.\n$@c{smile_eclosed}Natürlich… ich hatte immer dieses Gefühl.\n$@c{smile}Es ist jetzt vorbei, richtig? Du hast die Schleife beendet.\n$@c{smile_ehalf}Du hast auch deinen Traum erfüllt, nicht wahr?\n$Du hast nicht einmal verloren.\n$Ich werde die Einzige sein, die sich daran erinnert, was du getan hast.\n$@c{angry_mopen}Ich werde versuchen, es nicht zu vergessen!\n$@c{smile_wave_wink}Nur ein Scherz!@d{64} @c{smile}Ich würde es nie vergessen.@d{32}\n$Deine Legende wird in unseren Herzen weiterleben.\n$@c{smile_wave}Wie auch immer,@d{64} es wird spät…@d{96} denke ich?\nEs ist schwer zu sagen an diesem Ort.\n$Lass uns nach Hause gehen. \n$@c{smile_wave_wink}Vielleicht können wir morgen noch einen Kampf haben, der alten Zeiten willen?",
|
||||
"ending_endless": "Glückwunsch! Du hast das aktuelle Ende erreicht!\nWir arbeiten an mehr Spielinhalten.",
|
||||
"ending_name": "Entwickler"
|
||||
}
|
||||
|
@ -2913,7 +2913,7 @@
|
||||
},
|
||||
"zippyZap": {
|
||||
"name": "Britzelturbo",
|
||||
"effect": "Ein stürmischer Blitz-Angriff mit hoher Erstschlag- und Volltrefferquote."
|
||||
"effect": "Ein stürmischer Blitz-Angriff mit garantierter Erstschlag- und Volltrefferquote.\n"
|
||||
},
|
||||
"splishySplash": {
|
||||
"name": "Plätschersurfer",
|
||||
@ -3807,4 +3807,4 @@
|
||||
"name": "Giftkettung",
|
||||
"effect": "Der Anwender umwickelt das Ziel mit einer Kette aus Toxinen, die in dessen Körper eindringen und ihm schaden. Das Ziel wird eventuell schwer vergiftet."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@
|
||||
"landorusIncarnate": "Inkarnationsform",
|
||||
"keldeoOrdinary": "Standardform",
|
||||
"meloettaAria": "Gesangsform",
|
||||
"meloettaPirouette": "Tanzform",
|
||||
"froakieBattleBond": "Ash-Form",
|
||||
"scatterbugMeadow": "Blumenmeermuster",
|
||||
"scatterbugIcySnow": "Frostmuster",
|
||||
|
@ -25,13 +25,14 @@
|
||||
"challengeMonoGen9": "Gen IX",
|
||||
"playerItems": "Spielergegenstände",
|
||||
"personalBest": "Persönlicher Bestwert!",
|
||||
"SPDshortened": "Geschw.",
|
||||
"SPDshortened": "Init.",
|
||||
"runInfo": "Durchlauf Informationen",
|
||||
"money": "Geld",
|
||||
"runLength": "Durchlauf Dauer",
|
||||
"viewHeldItems": "Getragene Items",
|
||||
"hallofFameTextM": "Willkommen in der Ruhmeshalle",
|
||||
"hallofFameTextM": "Willkommen in der Ruhmeshalle!",
|
||||
"hallofFameTextF": "Willkommen in der Ruhmeshalle",
|
||||
"viewHallOfFame": "Ruhmeshalle ansehen!",
|
||||
"viewEndingSplash": "Endgrafik anzeigen!"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@
|
||||
"bgmVolume": "Hintergrundmusik",
|
||||
"fieldVolume": "Rufe & Attacken",
|
||||
"seVolume": "Spezialeffekte",
|
||||
"uiVolume": "Benutzeroberfläche",
|
||||
"musicPreference": "Musik Präferenz",
|
||||
"mixed": "Gemischt",
|
||||
"gamepadPleasePlug": "Bitte einen Controller anschließen oder eine Taste drücken.",
|
||||
@ -97,5 +98,10 @@
|
||||
"gamepadSupport": "Controllerunterstützung",
|
||||
"showBgmBar": "Musiknamen anzeigen",
|
||||
"moveTouchControls": "Bewegung Touch Steuerung",
|
||||
"shopOverlayOpacity": "Shop Overlay Deckkraft"
|
||||
"shopOverlayOpacity": "Shop Overlay Deckkraft",
|
||||
"shopCursorTarget": "Shop-Cursor Ziel",
|
||||
"items": "Items",
|
||||
"reroll": "Neu rollen",
|
||||
"shop": "Shop",
|
||||
"checkTeam": "Team überprüfen"
|
||||
}
|
||||
|
@ -64,6 +64,7 @@
|
||||
"landorusIncarnate": "Incarnate",
|
||||
"keldeoOrdinary": "Ordinary",
|
||||
"meloettaAria": "Aria",
|
||||
"meloettaPirouette": "Pirouette",
|
||||
"froakieBattleBond": "Battle Bond",
|
||||
"scatterbugMeadow": "Meadow",
|
||||
"scatterbugIcySnow": "Icy Snow",
|
||||
|
@ -63,6 +63,7 @@
|
||||
"bgmVolume": "BGM Volume",
|
||||
"fieldVolume": "Field Volume",
|
||||
"seVolume": "SE Volume",
|
||||
"uiVolume": "UI Volume",
|
||||
"musicPreference": "Music Preference",
|
||||
"mixed": "Mixed",
|
||||
"gamepadPleasePlug": "Please Plug in a Gamepad or Press a Button",
|
||||
|
@ -1,11 +1,62 @@
|
||||
{
|
||||
"blockRecoilDamage": "¡{{abilityName}} de {{pokemonName}}\nlo protegió del daño de retroceso!",
|
||||
"badDreams": "¡{{pokemonName}} está atormentado!",
|
||||
"costar": "¡{{pokemonName}} copió los cambios de características de {{allyName}}!",
|
||||
"iceFaceAvoidedDamage": "¡{{pokemonNameWithAffix}} evitó\ndaño con {{abilityName}}!",
|
||||
"perishBody": "¡{{abilityName}} de {{pokemonName}} debilitará a ambos Pokémon en 3 turnos!",
|
||||
"poisonHeal": "¡{{pokemonNameWithAffix}} restauró algunos de sus PS gracias a {{abilityName}}!",
|
||||
"trace": "¡{{pokemonName}} ha copiado la habilidad {{abilityName}} \nde {{targetName}}!",
|
||||
"windPowerCharged": "¡{{pokemonName}} se ha cargado de electricidad gracias a {{moveName}}!",
|
||||
"quickDraw": "¡{{pokemonName}} ataca primero gracias a la habilidad Mano Rápida!",
|
||||
"disguiseAvoidedDamage": "¡El disfraz de {{pokemonNameWithAffix}} se ha roto!",
|
||||
"preventBerryUse": "{{pokemonNameWithAffix}} está muy nervioso y no puede comer bayas!",
|
||||
"weatherEffectDisappeared": "El tiempo atmosférico ya no ejerce ninguna influencia."
|
||||
}
|
||||
"blockItemTheft": "¡{{pokemonNameWithAffix}} evitó el robo gracias a {{abilityName}}!",
|
||||
"typeImmunityHeal": "¡{{pokemonNameWithAffix}} restauró algunos de sus PS gracias a {{abilityName}}!",
|
||||
"nonSuperEffectiveImmunity": "¡{{pokemonNameWithAffix}} evitó el daño gracias a {{abilityName}}!",
|
||||
"moveImmunity": "¡No afecta a {{pokemonNameWithAffix}}!",
|
||||
"reverseDrain": "¡{{pokemonNameWithAffix}} absorbió lodo líquido!",
|
||||
"postDefendTypeChange": "¡{{abilityName}} de {{pokemonNameWithAffix}} cambió a tipo {{typeName}}!",
|
||||
"postDefendContactDamage": "¡{{abilityName}} de {{pokemonNameWithAffix}} ha herido a su atacante!",
|
||||
"postDefendAbilitySwap": "¡{{pokemonNameWithAffix}} intercambió su habilidad con su objetivo!",
|
||||
"postDefendAbilityGive": "¡{{pokemonNameWithAffix}} cambió la habilidad del objetivo por {{abilityName}}!",
|
||||
"postDefendMoveDisable": "¡{{moveName}} de {{pokemonNameWithAffix}} ha sido anulado!",
|
||||
"pokemonTypeChange": "¡{{pokemonNameWithAffix}} ha cambiado a tipo {{moveType}}!",
|
||||
"postAttackStealHeldItem": "¡{{pokemonNameWithAffix}} robó {{stolenItemType}} de {{defenderName}}!",
|
||||
"postDefendStealHeldItem": "¡{{pokemonNameWithAffix}} robó {{stolenItemType}} de {{attackerName}}!",
|
||||
"copyFaintedAllyAbility": "¡{{abilityName}} de {{pokemonNameWithAffix}} fue copiada!",
|
||||
"intimidateImmunity": "¡{{abilityName}} de {{pokemonNameWithAffix}} evita que sea intimidado!",
|
||||
"postSummonAllyHeal": "¡{{pokemonNameWithAffix}} se ha bebido el té que ha preparado {{pokemonName}}!",
|
||||
"postSummonClearAllyStats": "¡Los cambios de características de {{pokemonNameWithAffix}} fueron eliminados!",
|
||||
"postSummonTransform": "¡{{pokemonNameWithAffix}} se transformó en {{targetName}}!",
|
||||
"protectStat": "¡{{abilityName}} de {{pokemonNameWithAffix}} evita que baje su {{statName}}!",
|
||||
"statusEffectImmunityWithName": "¡{{abilityName}} de {{pokemonNameWithAffix}} evita {{statusEffectName}}!",
|
||||
"statusEffectImmunity": "¡{{abilityName}} de {{pokemonNameWithAffix}} evita los problemas de estado!",
|
||||
"battlerTagImmunity": "¡{{abilityName}} de {{pokemonNameWithAffix}} previene {{battlerTagName}}!",
|
||||
"forewarn": "¡{{pokemonNameWithAffix}} ha detectado el movimiento {{moveName}}!",
|
||||
"frisk": "¡{{pokemonNameWithAffix}} ha cacheado {{opponentAbilityName}} de {{opponentName}}!",
|
||||
"postWeatherLapseHeal": "¡{{pokemonNameWithAffix}} restauró algunos de sus PS gracias a {{abilityName}}!",
|
||||
"postWeatherLapseDamage": "¡{{pokemonNameWithAffix}} se hizo daño por su {{abilityName}}!",
|
||||
"postTurnLootCreateEatenBerry": "¡{{pokemonNameWithAffix}} recogió una {{berryName}}!",
|
||||
"postTurnHeal": "¡{{pokemonNameWithAffix}} restauró algunos de sus PS gracias a {{abilityName}}!",
|
||||
"fetchBall": "¡{{pokemonNameWithAffix}} encontró {{pokeballName}}!",
|
||||
"healFromBerryUse": "¡{{pokemonNameWithAffix}} se curó gracias a {{abilityName}}!",
|
||||
"arenaTrap": "¡{{pokemonNameWithAffix}} impide el cambio con {{abilityName}}!",
|
||||
"postBattleLoot": "¡{{pokemonNameWithAffix}} recogió {{itemName}}!",
|
||||
"postFaintContactDamage": "¡{{abilityName}} de {{pokemonNameWithAffix}} hizo daño a su atacante!",
|
||||
"postFaintHpDamage": "¡{{abilityName}} de {{pokemonNameWithAffix}} hizo daño a su atacante!",
|
||||
"postSummonPressure": "¡{{pokemonNameWithAffix}} ejerce Presión!",
|
||||
"weatherEffectDisappeared": "El tiempo atmosférico ya no ejerce ninguna influencia.",
|
||||
"postSummonMoldBreaker": "¡{{pokemonNameWithAffix}} rompió el molde!",
|
||||
"postSummonAnticipation": "¡{{pokemonNameWithAffix}} se anticipó!",
|
||||
"postSummonTurboblaze": "¡{{pokemonNameWithAffix}} irradia un aura llameante!",
|
||||
"postSummonTeravolt": "¡{{pokemonNameWithAffix}} irradia un aura chisporroteante!",
|
||||
"postSummonDarkAura": "¡{{pokemonNameWithAffix}} irradia un aura oscura!",
|
||||
"postSummonFairyAura": "¡{{pokemonNameWithAffix}} irradia un aura feérica!",
|
||||
"postSummonNeutralizingGas": "¡El Gas Reactivo de {{pokemonNameWithAffix}} se propaga por toda la zona!",
|
||||
"postSummonAsOneGlastrier": "¡{{pokemonNameWithAffix}} tiene dos Habilidades!",
|
||||
"postSummonAsOneSpectrier": "¡{{pokemonNameWithAffix}} tiene dos Habilidades!",
|
||||
"postSummonVesselOfRuin": "¡{{pokemonNameWithAffix}} ha mermado {{statName}} de los demás Pokémon con Caldero Debacle!",
|
||||
"postSummonSwordOfRuin": "¡{{pokemonNameWithAffix}} ha mermado {{statName}} de los demás Pokémon con Espada Debacle!",
|
||||
"postSummonTabletsOfRuin": "¡{{pokemonNameWithAffix}} ha mermado {{statName}} de los demás Pokémon con Tablilla Debacle!",
|
||||
"postSummonBeadsOfRuin": "¡{{pokemonNameWithAffix}} ha mermado {{statName}} de los demás Pokémon con Abalorio Debacle!",
|
||||
"preventBerryUse": "{{pokemonNameWithAffix}} está muy nervioso y no puede comer bayas!"
|
||||
}
|
||||
|
@ -56,7 +56,8 @@
|
||||
"deerlingSummer": "Verano",
|
||||
"deerlingAutumn": "Otoño",
|
||||
"deerlingWinter": "Invierno",
|
||||
"meloettaAria": "Aria",
|
||||
"meloettaAria": "Lírica",
|
||||
"meloettaPirouette": "Danza",
|
||||
"froakieBattleBond": "Fuerte Afecto",
|
||||
"scatterbugMeadow": "Floral",
|
||||
"scatterbugIcySnow": "Polar",
|
||||
|
@ -45,6 +45,7 @@
|
||||
"battle_legendary_lake_trio": "ROSA - Vs. Gardiens des Lacs",
|
||||
"battle_legendary_sinnoh": "ROSA - Vs. Légendaire de Sinnoh",
|
||||
"battle_legendary_dia_pal": "ROSA - Vs. Dialga/Palkia",
|
||||
"battle_legendary_origin_forme": "LPA - Vs. Dialga/Palkia Originel",
|
||||
"battle_legendary_giratina": "ROSA - Vs. Giratina",
|
||||
"battle_legendary_arceus": "HGSS - Vs. Arceus",
|
||||
"battle_legendary_unova": "NB - Vs. Légendaire d’Unys",
|
||||
@ -59,6 +60,7 @@
|
||||
"battle_legendary_zac_zam": "ÉB - Vs. Zacian/Zamazenta",
|
||||
"battle_legendary_glas_spec": "ÉB - Vs. Blizzeval/Spectreval",
|
||||
"battle_legendary_calyrex": "ÉB - Vs. Sylveroy",
|
||||
"battle_legendary_riders": "ÉB - Vs. Sylveroy Cavalier du Froid/d’Effroi",
|
||||
"battle_legendary_birds_galar": "ÉB - Vs. Oiseaux Légendaires de Galar",
|
||||
"battle_legendary_ruinous": "ÉV - Vs. Trésors du fléau",
|
||||
"battle_legendary_kor_mir": "ÉV - Profondeurs de la Zone Zéro (Combat)",
|
||||
|
@ -64,6 +64,7 @@
|
||||
"landorusIncarnate": "Avatar",
|
||||
"keldeoOrdinary": "Normal",
|
||||
"meloettaAria": "Chant",
|
||||
"meloettaPirouette": "Danse",
|
||||
"froakieBattleBond": "Synergie",
|
||||
"scatterbugMeadow": "Floraison",
|
||||
"scatterbugIcySnow": "Blizzard",
|
||||
|
@ -63,6 +63,7 @@
|
||||
"bgmVolume": "Vol. musique",
|
||||
"fieldVolume": "Vol. combats",
|
||||
"seVolume": "Vol. effets",
|
||||
"uiVolume": "Vol. menus",
|
||||
"musicPreference": "Préf. musicale",
|
||||
"mixed": "Mixte",
|
||||
"gamepadPleasePlug": "Veuillez brancher une manette ou appuyer sur un bouton.",
|
||||
|
@ -64,6 +64,7 @@
|
||||
"landorusIncarnate": "Incarnazione",
|
||||
"keldeoOrdinary": "Normale",
|
||||
"meloettaAria": "Canto",
|
||||
"meloettaPirouette": "Danza",
|
||||
"froakieBattleBond": "Morfosintonia",
|
||||
"scatterbugMeadow": "Giardinfiore",
|
||||
"scatterbugIcySnow": "Nevi perenni",
|
||||
|
@ -13,7 +13,8 @@
|
||||
"SPD": "Velocità",
|
||||
"SPDshortened": "Vel",
|
||||
"ACC": "Precisione",
|
||||
"EVA": "Elusione"
|
||||
"EVA": "Elusione",
|
||||
"HPStat": "PS"
|
||||
},
|
||||
"Type": {
|
||||
"UNKNOWN": "Sconosciuto",
|
||||
@ -37,4 +38,4 @@
|
||||
"FAIRY": "Folletto",
|
||||
"STELLAR": "Astrale"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,9 @@
|
||||
"boy": "Ragazzo",
|
||||
"girl": "Ragazza",
|
||||
"general": "Generale",
|
||||
"uiVolume": "Volume UI ",
|
||||
"gamepadSupport": "Supporto Gamepad",
|
||||
"showBgmBar": "Mostra Nomi Musica",
|
||||
"fieldVolume": "Volume Campo",
|
||||
"moveTouchControls": "Move Touch Controls",
|
||||
"shopOverlayOpacity": "Opacità Finestra Negozio",
|
||||
"shopCursorTarget": "Target Cursore Negozio",
|
||||
|
@ -1 +1,3 @@
|
||||
{}
|
||||
{
|
||||
"generation": "{{generation}}世代"
|
||||
}
|
||||
|
@ -1 +1,42 @@
|
||||
{}
|
||||
{
|
||||
"stats": "統計",
|
||||
"playTime": "プレー時間",
|
||||
"totalBattles": "合計バトル数",
|
||||
"starters": "スターター数",
|
||||
"shinyStarters": "色違いスターター数",
|
||||
"speciesSeen": "合計発見数",
|
||||
"speciesCaught": "合計捕獲数",
|
||||
"ribbonsOwned": "リボン数",
|
||||
"classicRuns": "クラシックラン",
|
||||
"classicWins": "クラシック勝利",
|
||||
"dailyRunAttempts": "デイリーラン",
|
||||
"dailyRunWins": "デイリーラン勝利",
|
||||
"endlessRuns": "エンドレスラン",
|
||||
"highestWaveEndless": "エンドレス最高ウェーブ",
|
||||
"highestMoney": "最大貯金",
|
||||
"highestDamage": "最大ダメージ",
|
||||
"highestHPHealed": "最大HP回復",
|
||||
"pokemonEncountered": "遭遇したポケモン",
|
||||
"pokemonDefeated": "倒したポケモン",
|
||||
"pokemonCaught": "捕まえたポケモン",
|
||||
"eggsHatched": "ふかしたタマゴ",
|
||||
"subLegendsSeen": "見つけた順伝説",
|
||||
"subLegendsCaught": "捕まえた順伝説",
|
||||
"subLegendsHatched": "ふかした順伝説",
|
||||
"legendsSeen": "見つけた伝説",
|
||||
"legendsCaught": "捕まえた伝説",
|
||||
"legendsHatched": "ふかした伝説",
|
||||
"mythicalsSeen": "見つけた幻ポケモン",
|
||||
"mythicalsCaught": "捕まえた幻ポケモン",
|
||||
"mythicalsHatched": "ふかした幻ポケモン",
|
||||
"shiniesSeen": "見つけた色違い",
|
||||
"shiniesCaught": "捕まえた色違い",
|
||||
"shiniesHatched": "ふかした色違い",
|
||||
"pokemonFused": "合体したポケモン",
|
||||
"trainersDefeated": "倒したトレーナー",
|
||||
"eggsPulled": "引いたタマゴ",
|
||||
"rareEggsPulled": "引いたレアタマゴ",
|
||||
"epicEggsPulled": "引いた超レアタマゴ",
|
||||
"legendaryEggsPulled": "引いた伝説タマゴ",
|
||||
"manaphyEggsPulled": "引いたマナフィタマゴ"
|
||||
}
|
@ -1,19 +1,26 @@
|
||||
{
|
||||
"GAME_SETTINGS": "せってい",
|
||||
"ACHIEVEMENTS": "じっせき",
|
||||
"STATS": "とうけい",
|
||||
"RUN_HISTORY":"ラン履歴",
|
||||
"GAME_SETTINGS": "設定",
|
||||
"ACHIEVEMENTS": "実績",
|
||||
"STATS": "統計",
|
||||
"EGG_LIST": "タマゴリスト",
|
||||
"EGG_GACHA": "タマゴガチャ",
|
||||
"MANAGE_DATA": "データかんり",
|
||||
"MANAGE_DATA": "データ管理",
|
||||
"COMMUNITY": "コミュニティ",
|
||||
"SAVE_AND_QUIT": "保存して終了",
|
||||
"LOG_OUT": "ログアウト",
|
||||
"slot": "スロット {{slotNumber}}",
|
||||
"importSession": "セッションのインポート",
|
||||
"importSlotSelect": "インポート先の スロットを 選んでください",
|
||||
"exportSession": "セッションのエクスポート",
|
||||
"importRunHistory":"ラン履歴インポート",
|
||||
"exportRunHistory":"ラン履歴エクスポート",
|
||||
"exportSlotSelect": "エクスポート元の スロットを 選んでください",
|
||||
"importData": "データのインポート",
|
||||
"exportData": "データのエクスポート",
|
||||
"cancel": "キャンセル"
|
||||
"consentPreferences": "同意設定",
|
||||
"linkDiscord": "Discord連携",
|
||||
"unlinkDiscord": "Discord連携解除",
|
||||
"linkGoogle": "Google連携",
|
||||
"unlinkGoogle": "Google連携解除",
|
||||
"cancel": "キャンセル",
|
||||
"losingProgressionWarning": "戦闘開始からの データが 保存されません。\nよろしいですか?",
|
||||
"noEggs": "現在 タマゴを ふかしていません!"
|
||||
}
|
@ -1 +1,12 @@
|
||||
{}
|
||||
{
|
||||
"transfer": "アイテム移行",
|
||||
"reroll": "選択肢変更",
|
||||
"lockRarities": "レア度の固定",
|
||||
"checkTeam": "チームを確認",
|
||||
"transferDesc": "ポケモンの 手持ちアイテムを 移行する",
|
||||
"rerollDesc": "お金を 使って アイテムの 選択肢を 変更する",
|
||||
"lockRaritiesDesc": "選択肢を 変更するときの レア度を 固定する\n(選択肢変更金額を影響する)",
|
||||
"checkTeamDesc": "チームの 状態を 確認する\nフォルムチェンジアイテムを 有効・無効にする",
|
||||
"rerollCost": "{{formattedMoney}}円",
|
||||
"itemCost": "{{formattedMoney}}円"
|
||||
}
|
||||
|
@ -1 +1,14 @@
|
||||
{}
|
||||
{
|
||||
"mega": "メガ{{pokemonName}}",
|
||||
"mega-x": "メガ{{pokemonName}}X",
|
||||
"mega-y": "メガ{{pokemonName}}Y",
|
||||
"primal": "ゲンシ{{pokemonName}}",
|
||||
"gigantamax": "キョダイ{{pokemonName}}",
|
||||
"eternamax": "E・{{pokemonName}}",
|
||||
"megaChange": "{{preName}}は\nメガ{{pokemonName}}に メガシンカした!",
|
||||
"gigantamaxChange": "{{preName}}は\nキョダイマックスした!",
|
||||
"eternamaxChange": "{{preName}}は\nムゲンダイマックスした!",
|
||||
"revertChange": "{{pokemonName}}は\n元の姿に 戻った!",
|
||||
"formChange": "{{preName}}は\n姿を 変えた!",
|
||||
"disguiseChange": "ばけのかわが みがわりに なった!"
|
||||
}
|
||||
|
@ -1 +1,170 @@
|
||||
{}
|
||||
{
|
||||
"pikachuCosplay": "コスプレ",
|
||||
"pikachuCoolCosplay": "クールなコスプレ",
|
||||
"pikachuBeautyCosplay": "きれいなコスプレ",
|
||||
"pikachuCuteCosplay": "かわいいコスプレ",
|
||||
"pikachuSmartCosplay": "かしこいコスプレ",
|
||||
"pikachuToughCosplay": "パワフルなコスプレ",
|
||||
"pikachuPartner": "パートナー",
|
||||
"eeveePartner": "パートナー",
|
||||
"pichuSpiky": "ギザみみ",
|
||||
"unownA": "A",
|
||||
"unownB": "B",
|
||||
"unownC": "C",
|
||||
"unownD": "D",
|
||||
"unownE": "E",
|
||||
"unownF": "F",
|
||||
"unownG": "G",
|
||||
"unownH": "H",
|
||||
"unownI": "I",
|
||||
"unownJ": "J",
|
||||
"unownK": "K",
|
||||
"unownL": "L",
|
||||
"unownM": "M",
|
||||
"unownN": "N",
|
||||
"unownO": "O",
|
||||
"unownP": "P",
|
||||
"unownQ": "Q",
|
||||
"unownR": "R",
|
||||
"unownS": "S",
|
||||
"unownT": "T",
|
||||
"unownU": "U",
|
||||
"unownV": "V",
|
||||
"unownW": "W",
|
||||
"unownX": "X",
|
||||
"unownY": "Y",
|
||||
"unownZ": "Z",
|
||||
"unownExclamation": "!",
|
||||
"unownQuestion": "?",
|
||||
"castformSunny": "たいよう",
|
||||
"castformRainy": "あまみず",
|
||||
"castformSnowy": "ゆきぐも",
|
||||
"deoxysNormal": "ノーマル",
|
||||
"burmyPlant": "くさき",
|
||||
"burmySandy": "すなち",
|
||||
"burmyTrash": "ゴミ",
|
||||
"shellosEast": "ひがし",
|
||||
"shellosWest": "にし",
|
||||
"rotomHeat": "ヒート",
|
||||
"rotomWash": "ウォッシュ",
|
||||
"rotomFrost": "フロスト",
|
||||
"rotomFan": "スピン",
|
||||
"rotomMow": "カット",
|
||||
"giratinaAltered": "アナザー",
|
||||
"shayminLand": "ランド",
|
||||
"basculinRedStriped": "赤筋",
|
||||
"basculinBlueStriped": "青筋",
|
||||
"basculinWhiteStriped": "白筋",
|
||||
"deerlingSpring": "春",
|
||||
"deerlingSummer": "夏",
|
||||
"deerlingAutumn": "秋",
|
||||
"deerlingWinter": "冬",
|
||||
"tornadusIncarnate": "けしん",
|
||||
"thundurusIncarnate": "けしん",
|
||||
"landorusIncarnate": "けしん",
|
||||
"keldeoOrdinary": "いつも",
|
||||
"meloettaAria": "ボイス",
|
||||
"meloettaPirouette": "ステップ",
|
||||
"froakieBattleBond": "きずなへんげ",
|
||||
"scatterbugMeadow": "はなぞの",
|
||||
"scatterbugIcySnow": "ひょうせつ",
|
||||
"scatterbugPolar": "ゆきぐに",
|
||||
"scatterbugTundra": "せつげん",
|
||||
"scatterbugContinental": "たいりく",
|
||||
"scatterbugGarden": "ていえん",
|
||||
"scatterbugElegant": "みやび",
|
||||
"scatterbugModern": "モダン",
|
||||
"scatterbugMarine": "マリン",
|
||||
"scatterbugArchipelago": "ぐんとう",
|
||||
"scatterbugHighPlains": "こうや",
|
||||
"scatterbugSandstorm": "さじん",
|
||||
"scatterbugRiver": "たいが",
|
||||
"scatterbugMonsoon": "スコール",
|
||||
"scatterbugSavanna": "サバンナ",
|
||||
"scatterbugSun": "たいよう",
|
||||
"scatterbugOcean": "オーシャン",
|
||||
"scatterbugJungle": "ジャングル",
|
||||
"scatterbugFancy": "ファンシー",
|
||||
"scatterbugPokeBall": "ボール",
|
||||
"flabebeRed": "赤",
|
||||
"flabebeYellow": "黄",
|
||||
"flabebeOrange": "オレンジ",
|
||||
"flabebeBlue": "青",
|
||||
"flabebeWhite": "白",
|
||||
"furfrouHeart": "ハート",
|
||||
"furfrouStar": "スター",
|
||||
"furfrouDiamond": "ダイア",
|
||||
"furfrouDebutante": "レディ",
|
||||
"furfrouMatron": "マダム",
|
||||
"furfrouDandy": "ジェントル",
|
||||
"furfrouLaReine": "クイーン",
|
||||
"furfrouKabuki": "カブキ",
|
||||
"furfrouPharaoh": "キングダム",
|
||||
"pumpkabooSmall": "ちいさい",
|
||||
"pumpkabooLarge": "おおきい",
|
||||
"pumpkabooSuper": "とくだい",
|
||||
"xerneasNeutral": "リラックス",
|
||||
"xerneasActive": "アクティブ",
|
||||
"zygarde50": "50%フォルム",
|
||||
"zygarde10": "10%フォルム",
|
||||
"zygarde50Pc": "50%フォルム スワームチェンジ",
|
||||
"zygarde10Pc": "10%フォルム スワームチェンジ",
|
||||
"zygardeComplete": "パーフェクトフォルム",
|
||||
"oricorioBaile": "めらめら",
|
||||
"oricorioPompom": "ぱちぱち",
|
||||
"oricorioPau": "ふらふら",
|
||||
"oricorioSensu": "まいまい",
|
||||
"rockruffOwnTempo": "マイペース",
|
||||
"miniorRedMeteor": "赤 りゅうせい",
|
||||
"miniorOrangeMeteor": "オレンジ りゅうせい",
|
||||
"miniorYellowMeteor": "黄 りゅうせい",
|
||||
"miniorGreenMeteor": "緑 りゅうせい",
|
||||
"miniorBlueMeteor": "水色 りゅうせい",
|
||||
"miniorIndigoMeteor": "青 りゅうせい",
|
||||
"miniorVioletMeteor": "紫 りゅうせい",
|
||||
"miniorRed": "赤",
|
||||
"miniorOrange": "オレンジ",
|
||||
"miniorYellow": "黄",
|
||||
"miniorGreen": "緑",
|
||||
"miniorBlue": "水色",
|
||||
"miniorIndigo": "青",
|
||||
"miniorViolet": "紫",
|
||||
"mimikyuDisguised": "ばけたすがた",
|
||||
"mimikyuBusted": "ばれたすがた",
|
||||
"magearnaOriginal": "500ねんまえ",
|
||||
"marshadowZenith": "Zパワー",
|
||||
"sinisteaPhony": "がんさく",
|
||||
"sinisteaAntique": "しんさく",
|
||||
"eiscueNoIce": "ナイスなし",
|
||||
"indeedeeMale": "オス",
|
||||
"indeedeeFemale": "メス",
|
||||
"morpekoFullBelly": "まんぷく",
|
||||
"zacianHeroOfManyBattles": "れきせんのゆうしゃ",
|
||||
"zamazentaHeroOfManyBattles": "れきせんのゆうしゃ",
|
||||
"zarudeDada": "とうちゃん",
|
||||
"enamorusIncarnate": "けしん",
|
||||
"squawkabillyGreenPlumage": "グリーンフェザー",
|
||||
"squawkabillyBluePlumage": "ブルーフェザー",
|
||||
"squawkabillyYellowPlumage": "イエローフェザー",
|
||||
"squawkabillyWhitePlumage": "ホワイトフェザー",
|
||||
"tatsugiriCurly": "そったすがた",
|
||||
"tatsugiriDroopy": "たれたすがた",
|
||||
"tatsugiriStretchy": "のびたすがた",
|
||||
"gimmighoulChest": "はこ",
|
||||
"gimmighoulRoaming": "とほ",
|
||||
"koraidonApexBuild": "かんぜんけいたい",
|
||||
"koraidonLimitedBuild":"せいげんけいたい",
|
||||
"koraidonSprintingBuild":"しっそうけいたい",
|
||||
"koraidonSwimmingBuild":"ゆうえいけいたい",
|
||||
"koraidonGlidingBuild":"かっくうけいたい",
|
||||
"miraidonUltimateMode":"コンプリートモード",
|
||||
"miraidonLowPowerMode":"リミテッドモード",
|
||||
"miraidonDriveMode":"ドライブモード",
|
||||
"miraidonAquaticMode":"フロートモード",
|
||||
"miraidonGlideMode":"グライドモード",
|
||||
"poltchageistCounterfeit": "マガイモノ",
|
||||
"poltchageistArtisan": "タカイモノ",
|
||||
"paldeaTaurosCombat": "コンバット",
|
||||
"paldeaTaurosBlaze": "ブレイズ",
|
||||
"paldeaTaurosAqua": "ウォーター"
|
||||
}
|
@ -45,6 +45,7 @@
|
||||
"battle_legendary_lake_trio": "ORAS 호수의 수호신 배틀",
|
||||
"battle_legendary_sinnoh": "ORAS 신오 전설 조우 배틀",
|
||||
"battle_legendary_dia_pal": "ORAS 디아루가 & 펄기아 배틀",
|
||||
"battle_legendary_origin_forme": "LA 오리진 디아루가 & 펄기아 배틀",
|
||||
"battle_legendary_giratina": "ORAS 기라티나 배틀",
|
||||
"battle_legendary_arceus": "HGSS 아르세우스 배틀",
|
||||
"battle_legendary_unova": "BW 하나 전설 조우 배틀",
|
||||
@ -59,6 +60,7 @@
|
||||
"battle_legendary_zac_zam": "SWSH 자시안 & 자마젠타 배틀",
|
||||
"battle_legendary_glas_spec": "SWSH 블리자포스 & 레이스포스 배틀",
|
||||
"battle_legendary_calyrex": "SWSH 버드렉스 배틀",
|
||||
"battle_legendary_riders": "SWSH 백마 & 흑마 버드렉스 배틀",
|
||||
"battle_legendary_birds_galar": "SWSH 가라르 전설의 새 배틀",
|
||||
"battle_legendary_ruinous": "SV 재앙의 보물 배틀",
|
||||
"battle_legendary_kor_mir": "SV 에리어 제로 배틀",
|
||||
@ -135,4 +137,4 @@
|
||||
"heal": "BW 포켓몬 센터",
|
||||
"menu": "불가사의 던전 하늘의 탐험대 포켓몬 세계에 온 것을 환영한다!",
|
||||
"title": "불가사의 던전 하늘의 탐험대 메뉴 테마"
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
"score": "점수",
|
||||
"wave": "웨이브",
|
||||
"loading": "로딩 중…",
|
||||
"loadingAsset": "리소스 로드 중: {{assetName}}",
|
||||
"playersOnline": "플레이어 온라인",
|
||||
"yes": "예",
|
||||
"no": "아니오",
|
||||
@ -51,4 +52,4 @@
|
||||
"rename": "닉네임 바꾸기",
|
||||
"nickname": "닉네임",
|
||||
"errorServerDown": "서버 연결 중 문제가 발생했습니다.\n\n이 창을 종료하지 않고 두면,\n게임은 자동으로 재접속됩니다."
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@
|
||||
"landorusIncarnate": "화신폼",
|
||||
"keldeoOrdinary": "평상시 모습",
|
||||
"meloettaAria": "보이스폼",
|
||||
"meloettaPirouette": "스텝폼",
|
||||
"froakieBattleBond": "유대변화",
|
||||
"scatterbugMeadow": "화원의 모양",
|
||||
"scatterbugIcySnow": "빙설의 모양",
|
||||
|
@ -13,7 +13,8 @@
|
||||
"SPD": "스피드",
|
||||
"SPDshortened": "스피드",
|
||||
"ACC": "명중률",
|
||||
"EVA": "회피율"
|
||||
"EVA": "회피율",
|
||||
"HPStat": "HP"
|
||||
},
|
||||
"Type": {
|
||||
"UNKNOWN": "Unknown",
|
||||
@ -37,4 +38,4 @@
|
||||
"FAIRY": "페어리",
|
||||
"STELLAR": "스텔라"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,34 +11,7 @@
|
||||
"cancel": "그만둔다",
|
||||
"memoString": "{{natureFragment}}.\n{{metFragment}}",
|
||||
"metFragment": {
|
||||
"normal": "{{biome}}에서\nLv{{level}}일 때 만났다.",
|
||||
"apparently": "{{biome}}에서\nLv{{level}}일 때 만난 것 같다."
|
||||
},
|
||||
"natureFragment": {
|
||||
"Hardy": "{{nature}}하는 성격",
|
||||
"Lonely": "{{nature}}을 타는 성격",
|
||||
"Brave": "{{nature}}한 성격",
|
||||
"Adamant": "{{nature}}스러운 성격",
|
||||
"Naughty": "{{nature}}같은 성격",
|
||||
"Bold": "{{nature}}한 성격",
|
||||
"Docile": "{{nature}}한 성격",
|
||||
"Relaxed": "{{nature}}한 성격",
|
||||
"Impish": "{{nature}}같은 성격",
|
||||
"Lax": "{{nature}}거리는 성격",
|
||||
"Timid": "{{nature}}같은 성격",
|
||||
"Hasty": "{{nature}}한 성격",
|
||||
"Serious": "{{nature}}한 성격",
|
||||
"Jolly": "{{nature}}한 성격",
|
||||
"Naive": "{{nature}}한 성격",
|
||||
"Modest": "{{nature}}스러운 성격",
|
||||
"Mild": "{{nature}}한 성격",
|
||||
"Quiet": "{{nature}}한 성격",
|
||||
"Bashful": "{{nature}}을 타는 성격",
|
||||
"Rash": "{{nature}}거리는 성격",
|
||||
"Calm": "{{nature}}한 성격",
|
||||
"Gentle": "{{nature}}한 성격",
|
||||
"Sassy": "{{nature}}진 성격",
|
||||
"Careful": "{{nature}}한 성격",
|
||||
"Quirky": "{{nature}}스러운 성격"
|
||||
"normal": "{{biome}}에서\n레벨 {{level}}일 때 만났다.",
|
||||
"apparently": "{{biome}}에서\n레벨 {{level}}일 때 만난 것 같다."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"victory": "승리!",
|
||||
"defeatedWild": "야생에서 패배: ",
|
||||
"defeatedTrainer": "트레이너에게 패배: ",
|
||||
"defeatedTrainerDouble": "더블 배틀에서 패배",
|
||||
"defeatedRival": "라이벌에게 패배",
|
||||
"defeatedWildM": "야생에서 패배: ",
|
||||
"defeatedTrainerM": "트레이너에게 패배: ",
|
||||
"defeatedTrainerDoubleM": "더블 배틀에서 패배",
|
||||
"defeatedRivalM": "라이벌에게 패배",
|
||||
"defeatedM": "패배",
|
||||
"defeatedWildF": "야생에서 패배: ",
|
||||
"defeatedTrainerF": "트레이너에게 패배: ",
|
||||
@ -34,4 +34,4 @@
|
||||
"hallofFameTextF": "전당 등록을 축하합니다!",
|
||||
"viewHallOfFame": "전당 보기",
|
||||
"viewEndingSplash": "엔딩 화면 보기"
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +257,7 @@
|
||||
},
|
||||
"overgrow": {
|
||||
"name": "Overgrow",
|
||||
"description": "Fortalece os movimentos do tipo Planta quando o Pokémon está com poucos PS."
|
||||
"description": "Fortalece os movimentos do tipo Grama quando o Pokémon está com poucos PS."
|
||||
},
|
||||
"blaze": {
|
||||
"name": "Blaze",
|
||||
@ -625,7 +625,7 @@
|
||||
},
|
||||
"sapSipper": {
|
||||
"name": "Sap Sipper",
|
||||
"description": "Se for atingido por um movimento do tipo Planta, ao invés de receber dano, aumenta seu Ataque."
|
||||
"description": "Se for atingido por um movimento do tipo Grama, ao invés de receber dano, aumenta seu Ataque."
|
||||
},
|
||||
"prankster": {
|
||||
"name": "Prankster",
|
||||
@ -661,7 +661,7 @@
|
||||
},
|
||||
"flowerVeil": {
|
||||
"name": "Flower Veil",
|
||||
"description": "Pokémon aliados do tipo Planta são protegidos de mudanças de estado e diminuição de seus atributos."
|
||||
"description": "Pokémon aliados do tipo Grama são protegidos de mudanças de estado e diminuição de seus atributos."
|
||||
},
|
||||
"cheekPouch": {
|
||||
"name": "Cheek Pouch",
|
||||
@ -927,6 +927,10 @@
|
||||
"name": "Prism Armor",
|
||||
"description": "Reduz o dano recebido por movimentos supereficazes."
|
||||
},
|
||||
"neuroforce": {
|
||||
"name": "Neuroforce",
|
||||
"description": "Fortalece movimentos supereficazes."
|
||||
},
|
||||
"intrepidSword": {
|
||||
"name": "Intrepid Sword",
|
||||
"description": "Aumenta o atributo de Ataque ao entrar em batalha."
|
||||
@ -1055,9 +1059,9 @@
|
||||
"name": "Grim Neigh",
|
||||
"description": "Quando o Pokémon derrota um alvo, emite um relincho assustador que aumenta seu Ataque Esp."
|
||||
},
|
||||
"asOneGlacier": {
|
||||
"asOneGlastrier": {
|
||||
"name": "As One",
|
||||
"description": "Essa Habilidade combina os efeitos das Habilidades Enervar de Calyrex e Relincho Branco de Glastrier."
|
||||
"description": "Esta habilidade combina os efeitos da habilidade Unnerve de Calyrex e da habilidade Chilling Neigh de Glastrier."
|
||||
},
|
||||
"asOneSpectrier": {
|
||||
"name": "As One",
|
||||
@ -1235,4 +1239,4 @@
|
||||
"name": "Poison Puppeteer",
|
||||
"description": "Pokémon envenenados pelos movimentos de Pecharunt também ficarão confusos."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,5 +15,26 @@
|
||||
"misty": "Terreno Enevoado",
|
||||
"electric": "Terreno Elétrico",
|
||||
"grassy": "Terreno de Planta",
|
||||
"psychic": "Terreno Psíquico"
|
||||
}
|
||||
"psychic": "Terreno Psíquico",
|
||||
"mudSport": "Mud Sport",
|
||||
"waterSport": "Water Sport",
|
||||
"spikes": "Spikes",
|
||||
"toxicSpikes": "Toxic Spikes",
|
||||
"mist": "Mist",
|
||||
"futureSight": "Future Sight",
|
||||
"doomDesire": "Doom Desire",
|
||||
"wish": "Wish",
|
||||
"stealthRock": "Stealth Rock",
|
||||
"stickyWeb": "Sticky Web",
|
||||
"trickRoom": "Trick Room",
|
||||
"gravity": "Gravity",
|
||||
"reflect": "Reflect",
|
||||
"lightScreen": "Light Screen",
|
||||
"auroraVeil": "Aurora Veil",
|
||||
"quickGuard": "Quick Guard",
|
||||
"wideGuard": "Wide Guard",
|
||||
"matBlock": "Mat Block",
|
||||
"craftyShield": "Crafty Shield",
|
||||
"tailwind": "Tailwind",
|
||||
"happyHour": "Happy Hour"
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
"battle_legendary_lake_trio": "ORAS Batalha do Trio dos Lagos",
|
||||
"battle_legendary_sinnoh": "ORAS Batalha dos Lendários de Sinnoh",
|
||||
"battle_legendary_dia_pal": "ORAS Batalha do Dialga & Palkia",
|
||||
"battle_legendary_origin_forme": "LA Origin Batalha com Dialga & Palkia",
|
||||
"battle_legendary_giratina": "ORAS Batalha do Giratina",
|
||||
"battle_legendary_arceus": "HGSS Batalha do Arceus",
|
||||
"battle_legendary_unova": "BW Batalha dos Lendários de Unova",
|
||||
@ -59,6 +60,7 @@
|
||||
"battle_legendary_zac_zam": "SWSH Batalha do Zacian & Zamazenta",
|
||||
"battle_legendary_glas_spec": "SWSH Batalha do Glastrier & Spectrier",
|
||||
"battle_legendary_calyrex": "SWSH Batalha do Calyrex",
|
||||
"battle_legendary_riders": "SWSH Batalha com Ice & Shadow Rider Calyrex",
|
||||
"battle_legendary_birds_galar": "SWSH Batalha dos Pássaros Lendários de Galar",
|
||||
"battle_legendary_ruinous": "SV Batalha dos Lendários Ruinosos",
|
||||
"battle_legendary_kor_mir": "SV Batalha das Cavernas da Área Zero",
|
||||
@ -135,4 +137,4 @@
|
||||
"heal": "BW Centro Pokémon",
|
||||
"menu": "PMD EoS Bem-vindo ao Mundo dos Pokémon!",
|
||||
"title": "PMD EoS Menu Principal"
|
||||
}
|
||||
}
|
||||
|
@ -1218,6 +1218,40 @@
|
||||
"3": "Cheguei onde estou porque os Pokémon estavam ao meu lado.\nTalvez precisemos pensar por que os Pokémon nos ajudam, não em termos de Pokémon e Treinadores, mas como uma relação entre seres vivos."
|
||||
}
|
||||
},
|
||||
"chili": {
|
||||
"encounter": {
|
||||
"1": "Yeeeeeooow! Hora de brincar com FOGO!! Eu sou o mais forte de nós irmãos!",
|
||||
"2": "Tcharan! O escaldante Chili tipo Fogo (sou eu) será seu oponente!",
|
||||
"3": "Vou te mostrar o que eu e meus ardentes tipo Fogo podemos fazer!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Você me pegou. Eu estou… queimado… esgotado…",
|
||||
"2": "Uau! Você tá pegando fogo!",
|
||||
"3": "Ai! Você me pegou!"
|
||||
},
|
||||
"defeat": {
|
||||
"1": "Estou pegando fogo! Brinque comigo e você vai se queimar!",
|
||||
"2": "Quando você brinca com fogo, você se queima!",
|
||||
"3": "Quero dizer, fala sério, seu oponente era eu! Você não teve chance!"
|
||||
}
|
||||
},
|
||||
"cilan": {
|
||||
"encounter": {
|
||||
"1": "Nada pessoal... Sem ressentimentos... Eu e meus Pokémon do tipo Grama vamos...\n$Hum... Nós iremos batalhar, aconteça o que acontecer.",
|
||||
"2": "Então, hum, se você estiver bem comigo, eu vou, hum, dar tudo o que tenho para ser, hum, você sabe, seu oponente.",
|
||||
"3": "OK... Então, eu sou Cilan, eu gosto de Pokémon do tipo Grama."
|
||||
},
|
||||
"victory": {
|
||||
"1": "Er… Já acabou?",
|
||||
"2": "…Que surpresa. Você é muito forte, não é? \n$Eu acho que meus irmãos também não conseguiriam derrotar você…",
|
||||
"3": "…Huh. Parece que meu timing estava, hum, errado?"
|
||||
},
|
||||
"defeat": {
|
||||
"1": "Hein? Eu ganhei?",
|
||||
"2": "Eu acho... \n$Eu acho que ganhei, porque eu estava competindo com meus irmãos Chili e Cress, e todos nós conseguimos ficar mais fortes.",
|
||||
"3": "Foi… foi uma experiência bastante emocionante…"
|
||||
}
|
||||
},
|
||||
"roark": {
|
||||
"encounter": {
|
||||
"1": "Preciso ver seu potencial como Treinadora. E, vou precisar ver a dureza dos Pokémon que batalham com você!",
|
||||
@ -2508,4 +2542,4 @@
|
||||
"1": "@c{smile_ehalf}Eu… acho que cumpri meu propósito…\n$@c{smile_eclosed}Prometa-me… Depois que curar o mundo… Por favor… volte para casa.\n$@c{smile_ehalf}…Obrigada."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -505,8 +505,8 @@
|
||||
"BLASTOISINITE": "Blastoisinita",
|
||||
"BLAZIKENITE": "Blazikenita",
|
||||
"CAMERUPTITE": "Cameruptita",
|
||||
"CHARIZARDITE X": "Charizardita X",
|
||||
"CHARIZARDITE Y": "Charizardita Y",
|
||||
"CHARIZARDITE_X": "Charizardita X",
|
||||
"CHARIZARDITE_Y": "Charizardita Y",
|
||||
"DIANCITE": "Diancita",
|
||||
"GALLADITE": "Galladita",
|
||||
"GARCHOMPITE": "Garchompita",
|
||||
@ -525,12 +525,12 @@
|
||||
"MAWILITE": "Mawilita",
|
||||
"MEDICHAMITE": "Medichamita",
|
||||
"METAGROSSITE": "Metagrossita",
|
||||
"MEWTWONITE X": "Mewtwonita X",
|
||||
"MEWTWONITE Y": "Mewtwonita Y",
|
||||
"MEWTWONITE_X": "Mewtwonita X",
|
||||
"MEWTWONITE_Y": "Mewtwonita Y",
|
||||
"PIDGEOTITE": "Pidgeotita",
|
||||
"PINSIRITE": "Pinsirita",
|
||||
"SABLENITE": "Sablenita",
|
||||
"RAYQUAZITE": "Rayquazita",
|
||||
"SABLENITE": "Sablenita",
|
||||
"SALAMENCITE": "Salamencita",
|
||||
"SCEPTILITE": "Sceptilita",
|
||||
"SCIZORITE": "Scizorita",
|
||||
@ -606,4 +606,4 @@
|
||||
"FAIRY_MEMORY": "Memória de Fada",
|
||||
"BLANK_MEMORY": "Memória Vazia"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,9 +39,9 @@
|
||||
"name": "Scratch",
|
||||
"effect": "Garras duras, pontiagudas e afiadas rasgam o alvo para causar dano."
|
||||
},
|
||||
"viceGrip": {
|
||||
"name": "Vice Grip",
|
||||
"effect": "O alvo é agarrado pelos lados e espremido."
|
||||
"viseGrip": {
|
||||
"name": "Vise Grip",
|
||||
"effect": "O alvo é agarrado e espremido de ambos os lados para causar dano."
|
||||
},
|
||||
"guillotine": {
|
||||
"name": "Guillotine",
|
||||
|
@ -64,6 +64,7 @@
|
||||
"landorusIncarnate": "Materializado",
|
||||
"keldeoOrdinary": "Comum",
|
||||
"meloettaAria": "Ária",
|
||||
"meloettaPirouette": "Pirueta",
|
||||
"froakieBattleBond": "Vínculo de Batalha",
|
||||
"scatterbugMeadow": "Prado",
|
||||
"scatterbugIcySnow": "Neve Congelada",
|
||||
@ -151,10 +152,19 @@
|
||||
"tatsugiriStretchy": "Reto",
|
||||
"gimmighoulChest": "Baú",
|
||||
"gimmighoulRoaming": "Perambulante",
|
||||
"koraidonGlidingBuild": "Gliding Build",
|
||||
"koraidonApexBuild": "Forma Plena",
|
||||
"koraidonLimitedBuild": "Forma Limitada",
|
||||
"koraidonSprintingBuild": "Forma de Corrida",
|
||||
"koraidonSwimmingBuild": "Forma de Nado",
|
||||
"koraidonGlidingBuild": "Forma de Voo",
|
||||
"miraidonUltimateMode": "Modo Pleno",
|
||||
"miraidonLowPowerMode": "Modo Limitado",
|
||||
"miraidonDriveMode": "Modo Terrestre",
|
||||
"miraidonAquaticMode": "Modo Aquático",
|
||||
"miraidonGlideMode": "Modo Aéreo",
|
||||
"poltchageistCounterfeit": "Imitação",
|
||||
"poltchageistArtisan": "Artesão",
|
||||
"paldeaTaurosCombat": "Combate",
|
||||
"paldeaTaurosBlaze": "Chamas",
|
||||
"paldeaTaurosAqua": "Aquático"
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,8 @@
|
||||
"SPD": "Veloc.",
|
||||
"SPDshortened": "Veloc.",
|
||||
"ACC": "Precisão",
|
||||
"EVA": "Evasão"
|
||||
"EVA": "Evasão",
|
||||
"HPStat": "PS"
|
||||
},
|
||||
"Type": {
|
||||
"UNKNOWN": "Desconhecido",
|
||||
@ -37,4 +38,4 @@
|
||||
"FAIRY": "Fada",
|
||||
"STELLAR": "Estelar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -59,11 +59,12 @@
|
||||
"fusionPaletteSwaps": "Cores da Paleta de Fusão",
|
||||
"playerGender": "Gênero do Jogador",
|
||||
"typeHints": "Dicas de Tipo",
|
||||
"masterVolume": "Volume Geral",
|
||||
"masterVolume": "Volume Mestre",
|
||||
"bgmVolume": "Músicas",
|
||||
"fieldVolume": "Ambiente",
|
||||
"seVolume": "Ef. Sonoros",
|
||||
"musicPreference": "Estilo da Música",
|
||||
"uiVolume": "Interface",
|
||||
"musicPreference": "Preferência de Música",
|
||||
"mixed": "Misto",
|
||||
"gamepadPleasePlug": "Conecte um controle ou pressione um botão",
|
||||
"delete": "Deletar",
|
||||
@ -96,11 +97,11 @@
|
||||
"controller": "Controle",
|
||||
"gamepadSupport": "Suporte para Controle",
|
||||
"showBgmBar": "Exibir Nomes das Músicas",
|
||||
"moveTouchControls": "Move Touch Controls",
|
||||
"moveTouchControls": "Mover Controles de Toque",
|
||||
"shopOverlayOpacity": "Opacidade da Loja",
|
||||
"shopCursorTarget": "Alvo do Cursor da Loja",
|
||||
"items": "Itens",
|
||||
"reroll": "Atualizar",
|
||||
"shop": "Loja",
|
||||
"checkTeam": "Checar Time"
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,10 @@
|
||||
"ace_duo": "Dupla Ás",
|
||||
"artist": "Artista",
|
||||
"artist_female": "Artista",
|
||||
"backpackers": "Mochileiros",
|
||||
"backers": "Torcedores",
|
||||
"backpacker": "Mochileiro",
|
||||
"backpacker_female": "Mochileira",
|
||||
"backpackers": "Mochileiros",
|
||||
"baker": "Padeira",
|
||||
"battle_girl": "Lutadora",
|
||||
"beauty": "Modelo",
|
||||
@ -30,8 +30,8 @@
|
||||
"doctor": "Doutor",
|
||||
"doctor_female": "Doutora",
|
||||
"firebreather": "Cospe-Fogo",
|
||||
"fishermen": "Pescador",
|
||||
"fishermen_female": "Pescadora",
|
||||
"fisherman": "Pescador",
|
||||
"fisherman_female": "Pescadora",
|
||||
"gentleman": "Cavalheiro",
|
||||
"guitarist": "Guitarrista",
|
||||
"guitarist_female": "Guitarrista",
|
||||
@ -101,8 +101,8 @@
|
||||
"workers": "Operários",
|
||||
"youngster": "Jovem",
|
||||
"rocket_grunt": "Capanga da Equipe Rocket",
|
||||
"rocket_grunt_female": "Capanga da Equipe Rocket",
|
||||
"rocket_grunts": "Capangas da Equipe Rocket",
|
||||
"rocket_grunt_female": "Capanga da Equipe Rocket",
|
||||
"magma_grunt": "Capanga da Equipe Magma",
|
||||
"magma_grunt_female": "Capanga da Equipe Magma",
|
||||
"magma_grunts": "Capangas da Equipe Magma",
|
||||
@ -118,4 +118,4 @@
|
||||
"flare_grunt": "Capanga da Equipe Flare",
|
||||
"flare_grunt_female": "Capanga da Equipe Flare",
|
||||
"flare_grunts": "Capangas da Equipe Flare"
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,6 @@
|
||||
"starterSelect": "Aqui você pode escolher seus iniciais apertando a tecla Z ou\na Barra de Espaço.\n$Esses serão os primeiro Pokémon da sua equipe.\n$Cada inicial tem seu custo. Sua equipe pode ter até 6\nmembros, desde que a soma dos custos não ultrapasse 10. \n$Você pode escolher o gênero, a habilidade\ne até a forma do seu inicial.\n$Essas opções dependem das variantes dessa\nespécie que você já capturou ou chocou. \n$Os IVs de cada inicial são os melhores de todos os Pokémon\ndaquela espécie que você já capturou ou chocou.\n$Sempre capture vários Pokémon de várias espécies!",
|
||||
"pokerus": "Todo dia, 3 Pokémon iniciais ficam com uma borda roxa.\n$Caso veja um inicial que você possui com uma dessa, tente\nadicioná-lo a sua equipe. Lembre-se de olhar seu sumário!",
|
||||
"statChange": "As mudanças de atributos se mantém após a batalha desde que o Pokémon não seja trocado.\n$Seus Pokémon voltam a suas Poké Bolas antes de batalhas contra treinadores e de entrar em um novo bioma.\n$Para ver as mudanças de atributos dos Pokémon em campo, mantena C ou Shift pressionado durante a batalha.",
|
||||
"selectItem": "Após cada batalha, você pode escolher entre 3 itens aleatórios.\n$Você pode escolher apenas um deles.\n$Esses itens variam entre consumíveis, itens de segurar e itens passivos permanentes.\n$A maioria dos efeitos de itens não consumíveis podem ser acumulados.\n$Alguns itens só aparecerão se puderem ser usados, como os itens de evolução.\n$Você também pode transferir itens de segurar entre os Pokémon utilizando a opção \"Transfer\".\n$A opção de transferir irá aparecer no canto inferior direito assim que você obter um item de segurar.\n$Você pode comprar itens consumíveis com dinheiro, e sua variedade aumentará conforme você for mais longe.\n$Certifique-se de comprá-los antes de escolher seu item aleatório. Ao escolhê-lo, a próxima batalha começará.",
|
||||
"selectItem": "Após cada batalha, você pode escolher entre 3 itens aleatórios.\n$Você pode escolher apenas um deles.\n$Esses itens variam entre consumíveis, itens de segurar e itens passivos permanentes.\n$A maioria dos efeitos de itens não consumíveis podem ser acumulados.\n$Alguns itens só aparecerão se puderem ser usados, como os itens de evolução.\n$Você também pode transferir itens de segurar entre os Pokémon utilizando a opção \"Alterar\".\n$A opção de transferir irá aparecer no canto inferior direito assim que você obter um item de segurar.\n$Você pode comprar itens consumíveis com dinheiro, e sua variedade aumentará conforme você for mais longe.\n$Certifique-se de comprá-los antes de escolher seu item aleatório. Ao escolhê-lo, a próxima batalha começará.",
|
||||
"eggGacha": "Aqui você pode trocar seus vouchers\npor ovos de Pokémon.\n$Ovos ficam mais próximos de chocar após cada batalha.\nOvos mais raros demoram mais para chocar.\n$Pokémon chocados não serão adicionados a sua equipe,\nmas sim aos seus iniciais.\n$Pokémon chocados geralmente possuem IVs melhores\nque Pokémon selvagens.\n$Alguns Pokémon só podem ser obtidos através de seus ovos.\n$Temos 3 máquinas, cada uma com seu bônus específico,\nentão escolha a que mais lhe convém!"
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@
|
||||
"landorusIncarnate": "化身",
|
||||
"keldeoOrdinary": "通常",
|
||||
"meloettaAria": "歌声",
|
||||
"meloettaPirouette": "舞步形态",
|
||||
"froakieBattleBond": "牵绊变身",
|
||||
"scatterbugMeadow": "花园花纹",
|
||||
"scatterbugIcySnow": "冰雪花纹",
|
||||
|
@ -1 +1,3 @@
|
||||
{}
|
||||
{
|
||||
"meloettaPirouette": "舞步形態"
|
||||
}
|
@ -311,8 +311,6 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
}
|
||||
|
||||
end() {
|
||||
const move = this.move.getMove();
|
||||
move.type = move.defaultType;
|
||||
const user = this.getUserPokemon();
|
||||
/**
|
||||
* If this phase isn't for the invoked move's last strike,
|
||||
|
@ -119,6 +119,7 @@ export const SettingKeys = {
|
||||
BGM_Volume: "BGM_VOLUME",
|
||||
Field_Volume: "FIELD_VOLUME",
|
||||
SE_Volume: "SE_VOLUME",
|
||||
UI_Volume: "UI_SOUND_EFFECTS",
|
||||
Music_Preference: "MUSIC_PREFERENCE",
|
||||
Show_BGM_Bar: "SHOW_BGM_BAR",
|
||||
Move_Touch_Controls: "MOVE_TOUCH_CONTROLS",
|
||||
@ -556,6 +557,13 @@ export const Setting: Array<Setting> = [
|
||||
default: 10,
|
||||
type: SettingType.AUDIO
|
||||
},
|
||||
{
|
||||
key: SettingKeys.UI_Volume,
|
||||
label: i18next.t("settings:uiVolume"),
|
||||
options: VOLUME_OPTIONS,
|
||||
default: 10,
|
||||
type: SettingType.AUDIO
|
||||
},
|
||||
{
|
||||
key: SettingKeys.Music_Preference,
|
||||
label: i18next.t("settings:musicPreference"),
|
||||
@ -670,6 +678,9 @@ export function setSetting(scene: BattleScene, setting: string, value: integer):
|
||||
scene.seVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0;
|
||||
scene.updateSoundVolume();
|
||||
break;
|
||||
case SettingKeys.UI_Volume:
|
||||
scene.uiVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0;
|
||||
break;
|
||||
case SettingKeys.Music_Preference:
|
||||
scene.musicPreference = value;
|
||||
break;
|
||||
|
133
src/test/abilities/galvanize.test.ts
Normal file
133
src/test/abilities/galvanize.test.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { Type } from "#app/data/type";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
import { Moves } from "#app/enums/moves";
|
||||
import { Species } from "#app/enums/species";
|
||||
import { HitResult } from "#app/field/pokemon";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import { SPLASH_ONLY } from "#test/utils/testUtils";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
describe("Abilities - Galvanize", () => {
|
||||
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
|
||||
.battleType("single")
|
||||
.startingLevel(100)
|
||||
.ability(Abilities.GALVANIZE)
|
||||
.moveset([Moves.TACKLE, Moves.REVELATION_DANCE, Moves.FURY_SWIPES])
|
||||
.enemySpecies(Species.DUSCLOPS)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset(SPLASH_ONLY)
|
||||
.enemyLevel(100);
|
||||
});
|
||||
|
||||
it("should change Normal-type attacks to Electric type and boost their power", async () => {
|
||||
await game.startBattle();
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
vi.spyOn(playerPokemon, "getMoveType");
|
||||
|
||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
vi.spyOn(enemyPokemon, "apply");
|
||||
|
||||
const move = allMoves[Moves.TACKLE];
|
||||
vi.spyOn(move, "calculateBattlePower");
|
||||
|
||||
game.move.select(Moves.TACKLE);
|
||||
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(playerPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC);
|
||||
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.EFFECTIVE);
|
||||
expect(move.calculateBattlePower).toHaveReturnedWith(48);
|
||||
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
|
||||
}, TIMEOUT);
|
||||
|
||||
it("should cause Normal-type attacks to activate Volt Absorb", async () => {
|
||||
game.override.enemyAbility(Abilities.VOLT_ABSORB);
|
||||
|
||||
await game.startBattle();
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
vi.spyOn(playerPokemon, "getMoveType");
|
||||
|
||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
vi.spyOn(enemyPokemon, "apply");
|
||||
|
||||
enemyPokemon.hp = Math.floor(enemyPokemon.getMaxHp() * 0.8);
|
||||
|
||||
game.move.select(Moves.TACKLE);
|
||||
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(playerPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC);
|
||||
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.NO_EFFECT);
|
||||
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
|
||||
}, TIMEOUT);
|
||||
|
||||
it("should not change the type of variable-type moves", async () => {
|
||||
game.override.enemySpecies(Species.MIGHTYENA);
|
||||
|
||||
await game.startBattle([Species.ESPEON]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
vi.spyOn(playerPokemon, "getMoveType");
|
||||
|
||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
vi.spyOn(enemyPokemon, "apply");
|
||||
|
||||
game.move.select(Moves.REVELATION_DANCE);
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(playerPokemon.getMoveType).not.toHaveLastReturnedWith(Type.ELECTRIC);
|
||||
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.NO_EFFECT);
|
||||
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
|
||||
}, TIMEOUT);
|
||||
|
||||
it("should affect all hits of a Normal-type multi-hit move", async () => {
|
||||
await game.startBattle();
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
vi.spyOn(playerPokemon, "getMoveType");
|
||||
|
||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
vi.spyOn(enemyPokemon, "apply");
|
||||
|
||||
game.move.select(Moves.FURY_SWIPES);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.move.forceHit();
|
||||
|
||||
await game.phaseInterceptor.to("MoveEffectPhase");
|
||||
expect(playerPokemon.turnData.hitCount).toBeGreaterThan(1);
|
||||
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
|
||||
|
||||
while (playerPokemon.turnData.hitsLeft > 0) {
|
||||
const enemyStartingHp = enemyPokemon.hp;
|
||||
await game.phaseInterceptor.to("MoveEffectPhase");
|
||||
|
||||
expect(playerPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC);
|
||||
expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp);
|
||||
}
|
||||
|
||||
expect(enemyPokemon.apply).not.toHaveReturnedWith(HitResult.NO_EFFECT);
|
||||
}, TIMEOUT);
|
||||
});
|
@ -76,7 +76,7 @@ describe("Abilities - Libero", () => {
|
||||
|
||||
expect(leadPokemon.summonData.abilitiesApplied.filter((a) => a === Abilities.LIBERO)).toHaveLength(1);
|
||||
const leadPokemonType = Type[leadPokemon.getTypes()[0]];
|
||||
const moveType = Type[allMoves[Moves.AGILITY].defaultType];
|
||||
const moveType = Type[allMoves[Moves.AGILITY].type];
|
||||
expect(leadPokemonType).not.toBe(moveType);
|
||||
|
||||
await game.toNextTurn();
|
||||
@ -249,7 +249,7 @@ describe("Abilities - Libero", () => {
|
||||
const leadPokemon = game.scene.getPlayerPokemon()!;
|
||||
expect(leadPokemon).not.toBe(undefined);
|
||||
|
||||
leadPokemon.summonData.types = [allMoves[Moves.SPLASH].defaultType];
|
||||
leadPokemon.summonData.types = [allMoves[Moves.SPLASH].type];
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
@ -357,6 +357,6 @@ function testPokemonTypeMatchesDefaultMoveType(pokemon: PlayerPokemon, move: Mov
|
||||
expect(pokemon.summonData.abilitiesApplied).toContain(Abilities.LIBERO);
|
||||
expect(pokemon.getTypes()).toHaveLength(1);
|
||||
const pokemonType = Type[pokemon.getTypes()[0]],
|
||||
moveType = Type[allMoves[move].defaultType];
|
||||
moveType = Type[allMoves[move].type];
|
||||
expect(pokemonType).toBe(moveType);
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ describe("Abilities - Protean", () => {
|
||||
|
||||
expect(leadPokemon.summonData.abilitiesApplied.filter((a) => a === Abilities.PROTEAN)).toHaveLength(1);
|
||||
const leadPokemonType = Type[leadPokemon.getTypes()[0]];
|
||||
const moveType = Type[allMoves[Moves.AGILITY].defaultType];
|
||||
const moveType = Type[allMoves[Moves.AGILITY].type];
|
||||
expect(leadPokemonType).not.toBe(moveType);
|
||||
|
||||
await game.toNextTurn();
|
||||
@ -249,7 +249,7 @@ describe("Abilities - Protean", () => {
|
||||
const leadPokemon = game.scene.getPlayerPokemon()!;
|
||||
expect(leadPokemon).not.toBe(undefined);
|
||||
|
||||
leadPokemon.summonData.types = [allMoves[Moves.SPLASH].defaultType];
|
||||
leadPokemon.summonData.types = [allMoves[Moves.SPLASH].type];
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
@ -357,6 +357,6 @@ function testPokemonTypeMatchesDefaultMoveType(pokemon: PlayerPokemon, move: Mov
|
||||
expect(pokemon.summonData.abilitiesApplied).toContain(Abilities.PROTEAN);
|
||||
expect(pokemon.getTypes()).toHaveLength(1);
|
||||
const pokemonType = Type[pokemon.getTypes()[0]],
|
||||
moveType = Type[allMoves[move].defaultType];
|
||||
moveType = Type[allMoves[move].type];
|
||||
expect(pokemonType).toBe(moveType);
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
|
||||
import { SPLASH_ONLY } from "../utils/testUtils";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
// RATIO : HP Cost of Move
|
||||
@ -29,12 +31,14 @@ describe("Moves - BELLY DRUM", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override.starterSpecies(Species.MAGIKARP);
|
||||
game.override.enemySpecies(Species.SNORLAX);
|
||||
game.override.startingLevel(100);
|
||||
game.override.enemyLevel(100);
|
||||
game.override.moveset([Moves.BELLY_DRUM]);
|
||||
game.override.enemyMoveset([Moves.SPLASH]);
|
||||
game.override
|
||||
.starterSpecies(Species.MAGIKARP)
|
||||
.enemySpecies(Species.SNORLAX)
|
||||
.startingLevel(100)
|
||||
.enemyLevel(100)
|
||||
.moveset([Moves.BELLY_DRUM])
|
||||
.enemyMoveset(SPLASH_ONLY)
|
||||
.enemyAbility(Abilities.BALL_FETCH);
|
||||
});
|
||||
|
||||
// Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/Belly_Drum_(move)
|
||||
|
70
src/test/moves/effectiveness.test.ts
Normal file
70
src/test/moves/effectiveness.test.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import { TrainerSlot } from "#app/data/trainer-config";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
import { Moves } from "#app/enums/moves";
|
||||
import { Species } from "#app/enums/species";
|
||||
import * as Messages from "#app/messages";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
|
||||
function testMoveEffectiveness(game: GameManager, move: Moves, targetSpecies: Species,
|
||||
expected: number, targetAbility: Abilities = Abilities.BALL_FETCH): void {
|
||||
// Suppress getPokemonNameWithAffix because it calls on a null battle spec
|
||||
vi.spyOn(Messages, "getPokemonNameWithAffix").mockReturnValue("");
|
||||
game.override.enemyAbility(targetAbility);
|
||||
const user = game.scene.addPlayerPokemon(getPokemonSpecies(Species.SNORLAX), 5);
|
||||
const target = game.scene.addEnemyPokemon(getPokemonSpecies(targetSpecies), 5, TrainerSlot.NONE);
|
||||
|
||||
expect(target.getMoveEffectiveness(user, allMoves[move])).toBe(expected);
|
||||
}
|
||||
|
||||
describe("Moves - Type Effectiveness", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
game = new GameManager(phaserGame);
|
||||
game.override.ability(Abilities.BALL_FETCH);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
it("Normal-type attacks are neutrally effective against Normal-type Pokemon",
|
||||
() => testMoveEffectiveness(game, Moves.TACKLE, Species.SNORLAX, 1)
|
||||
);
|
||||
|
||||
it("Normal-type attacks are not very effective against Steel-type Pokemon",
|
||||
() => testMoveEffectiveness(game, Moves.TACKLE, Species.REGISTEEL, 0.5)
|
||||
);
|
||||
|
||||
it("Normal-type attacks are doubly resisted by Steel/Rock-type Pokemon",
|
||||
() => testMoveEffectiveness(game, Moves.TACKLE, Species.AGGRON, 0.25)
|
||||
);
|
||||
|
||||
it("Normal-type attacks have no effect on Ghost-type Pokemon",
|
||||
() => testMoveEffectiveness(game, Moves.TACKLE, Species.DUSCLOPS, 0)
|
||||
);
|
||||
|
||||
it("Normal-type status moves are not affected by type matchups",
|
||||
() => testMoveEffectiveness(game, Moves.GROWL, Species.DUSCLOPS, 1)
|
||||
);
|
||||
|
||||
it("Electric-type attacks are super-effective against Water-type Pokemon",
|
||||
() => testMoveEffectiveness(game, Moves.THUNDERBOLT, Species.BLASTOISE, 2)
|
||||
);
|
||||
|
||||
it("Electric-type attacks are doubly super-effective against Water/Flying-type Pokemon",
|
||||
() => testMoveEffectiveness(game, Moves.THUNDERBOLT, Species.GYARADOS, 4)
|
||||
);
|
||||
|
||||
it("Electric-type attacks are negated by Volt Absorb",
|
||||
() => testMoveEffectiveness(game, Moves.THUNDERBOLT, Species.GYARADOS, 0, Abilities.VOLT_ABSORB)
|
||||
);
|
||||
});
|
@ -1,7 +1,7 @@
|
||||
import { getMoveTargets } from "#app/data/move";
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
import { Species } from "#app/enums/species";
|
||||
import { TurnEndPhase } from "#app/phases/turn-end-phase";
|
||||
import * as Utils from "#app/utils";
|
||||
import { Moves } from "#enums/moves";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import { SPLASH_ONLY } from "#test/utils/testUtils";
|
||||
@ -10,7 +10,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
describe("Moves - Multi target", () => {
|
||||
describe("Multi-target damage reduction", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
@ -21,160 +21,111 @@ describe("Moves - Multi target", () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
afterTrial(game);
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = beforeTrial(phaserGame);
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.disableCrits()
|
||||
.battleType("double")
|
||||
.enemyLevel(100)
|
||||
.startingLevel(100)
|
||||
.enemySpecies(Species.POLIWAG)
|
||||
.enemyMoveset(SPLASH_ONLY)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.moveset([Moves.TACKLE, Moves.DAZZLING_GLEAM, Moves.EARTHQUAKE, Moves.SPLASH])
|
||||
.ability(Abilities.BALL_FETCH);
|
||||
});
|
||||
|
||||
it("2v2 - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, false, false, true), TIMEOUT);
|
||||
it("should reduce d.gleam damage when multiple enemies but not tackle", async () => {
|
||||
await game.startBattle([Species.MAGIKARP, Species.FEEBAS]);
|
||||
|
||||
it("2v2 - target all near others - damage decrase", () => checkDamageDecrease(game, Moves.EARTHQUAKE, false, false, true), TIMEOUT);
|
||||
const [enemy1, enemy2] = game.scene.getEnemyField();
|
||||
|
||||
it("2v1 - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, false, true, true), TIMEOUT);
|
||||
game.move.select(Moves.DAZZLING_GLEAM);
|
||||
game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
it("2v1 - target all near others - damage decrase", () => checkDamageDecrease(game, Moves.EARTHQUAKE, false, true, true), TIMEOUT);
|
||||
const gleam1 = enemy1.getMaxHp() - enemy1.hp;
|
||||
enemy1.hp = enemy1.getMaxHp();
|
||||
|
||||
it("1v2 - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, true, false, true), TIMEOUT);
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
it("1v2 - target all near others - damage decrase", () => checkDamageDecrease(game, Moves.EARTHQUAKE, true, false, true), TIMEOUT);
|
||||
const tackle1 = enemy1.getMaxHp() - enemy1.hp;
|
||||
enemy1.hp = enemy1.getMaxHp();
|
||||
|
||||
it("1v1 - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, true, true, false), TIMEOUT);
|
||||
await game.killPokemon(enemy2);
|
||||
await game.toNextTurn();
|
||||
|
||||
it("2v2 (immune) - target all near others - check modifier", () => checkTargetMultiplier(game, Moves.EARTHQUAKE, false, false, true, Abilities.LEVITATE), TIMEOUT);
|
||||
game.move.select(Moves.DAZZLING_GLEAM);
|
||||
game.move.select(Moves.TACKLE, 1, BattlerIndex.ENEMY);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]);
|
||||
|
||||
it("2v2 (immune) - target all near others - damage decrase", () => checkDamageDecrease(game, Moves.EARTHQUAKE, false, false, true, Abilities.LEVITATE), TIMEOUT);
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
it("2v2 - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, false, false, true), TIMEOUT);
|
||||
const gleam2 = enemy1.getMaxHp() - enemy1.hp;
|
||||
enemy1.hp = enemy1.getMaxHp();
|
||||
|
||||
it("2v2 - target all near enemies - damage decrase", () => checkDamageDecrease(game, Moves.HYPER_VOICE, false, false, true), TIMEOUT);
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
const tackle2 = enemy1.getMaxHp() - enemy1.hp;
|
||||
|
||||
it("2v1 - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, false, true, false), TIMEOUT);
|
||||
// Single target moves don't get reduced
|
||||
expect(tackle1).toBe(tackle2);
|
||||
// Moves that target all enemies get reduced if there's more than one enemy
|
||||
expect(gleam1).toBeLessThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) + 1);
|
||||
expect(gleam1).toBeGreaterThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) - 1);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("2v1 - target all near enemies - no damage decrase", () => checkDamageDecrease(game, Moves.HYPER_VOICE, false, true, false), TIMEOUT);
|
||||
it("should reduce earthquake when more than one pokemon other than user is not fainted", async () => {
|
||||
await game.startBattle([Species.MAGIKARP, Species.FEEBAS]);
|
||||
|
||||
it("1v2 - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, true, false, true), TIMEOUT);
|
||||
const player2 = game.scene.getParty()[1];
|
||||
const [enemy1, enemy2] = game.scene.getEnemyField();
|
||||
|
||||
it("1v2 - target all near enemies - damage decrase", () => checkDamageDecrease(game, Moves.HYPER_VOICE, true, false, true), TIMEOUT);
|
||||
|
||||
it("1v1 - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, true, true, false), TIMEOUT);
|
||||
|
||||
it("2v2 (immune) - target all near enemies - check modifier", () => checkTargetMultiplier(game, Moves.HYPER_VOICE, false, false, true, Abilities.SOUNDPROOF), TIMEOUT);
|
||||
|
||||
it("2v2 (immune) - target all near enemies - damage decrase", () => checkDamageDecrease(game, Moves.HYPER_VOICE, false, false, true, Abilities.SOUNDPROOF), TIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
async function checkTargetMultiplier(game: GameManager, attackMove: Moves, killAlly: boolean, killSecondEnemy: boolean, shouldMultiplied: boolean, oppAbility?: Abilities) {
|
||||
// play an attack and check target count
|
||||
game.override.enemyAbility(oppAbility ? oppAbility : Abilities.BALL_FETCH);
|
||||
await game.startBattle();
|
||||
|
||||
const playerPokemonRepr = game.scene.getPlayerField();
|
||||
|
||||
killAllyAndEnemy(game, killAlly, killSecondEnemy);
|
||||
|
||||
const targetCount = getMoveTargets(playerPokemonRepr[0], attackMove).targets.length;
|
||||
const targetMultiplier = targetCount > 1 ? 0.75 : 1;
|
||||
|
||||
if (shouldMultiplied) {
|
||||
expect(targetMultiplier).toBe(0.75);
|
||||
} else {
|
||||
expect(targetMultiplier).toBe(1);
|
||||
}
|
||||
}
|
||||
|
||||
async function checkDamageDecrease(game: GameManager, attackMove: Moves, killAlly: boolean, killSecondEnemy: boolean, shouldDecreased: boolean, ability?: Abilities) {
|
||||
// Tested combination on first turn, 1v1 on second turn
|
||||
await game.classicMode.runToSummon([Species.EEVEE, Species.EEVEE]);
|
||||
|
||||
if (ability !== undefined) {
|
||||
game.scene.getPlayerField()[1].abilityIndex = ability;
|
||||
game.scene.getEnemyField()[1].abilityIndex = ability;
|
||||
}
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
game.move.select(Moves.SPLASH, 1);
|
||||
|
||||
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
killAllyAndEnemy(game, killAlly, killSecondEnemy);
|
||||
await game.toNextTurn();
|
||||
|
||||
const initialHp = game.scene.getEnemyField()[0].hp;
|
||||
game.move.select(attackMove);
|
||||
if (!killAlly) {
|
||||
game.move.select(Moves.EARTHQUAKE);
|
||||
game.move.select(Moves.SPLASH, 1);
|
||||
}
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
|
||||
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
const afterHp = game.scene.getEnemyField()[0].hp;
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
killAllyAndEnemy(game, true, true);
|
||||
await game.toNextTurn();
|
||||
const damagePlayer2Turn1 = player2.getMaxHp() - player2.hp;
|
||||
const damageEnemy1Turn1 = enemy1.getMaxHp() - enemy1.hp;
|
||||
|
||||
game.scene.getEnemyField()[0].hp = initialHp;
|
||||
player2.hp = player2.getMaxHp();
|
||||
enemy1.hp = enemy1.getMaxHp();
|
||||
|
||||
const initialHp1v1 = game.scene.getEnemyField()[0].hp;
|
||||
game.move.select(attackMove);
|
||||
await game.killPokemon(enemy2);
|
||||
await game.toNextTurn();
|
||||
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
const afterHp1v1 = game.scene.getEnemyField()[0].hp;
|
||||
game.move.select(Moves.EARTHQUAKE);
|
||||
game.move.select(Moves.SPLASH, 1);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY]);
|
||||
|
||||
if (shouldDecreased) {
|
||||
expect(initialHp - afterHp).toBeLessThan(0.75 * (initialHp1v1 - afterHp1v1) + 2);
|
||||
expect(initialHp - afterHp).toBeGreaterThan(0.75 * (initialHp1v1 - afterHp1v1) - 2);
|
||||
} else {
|
||||
expect(initialHp - afterHp).toBeLessThan(initialHp1v1 - afterHp1v1 + 2);
|
||||
expect(initialHp - afterHp).toBeGreaterThan(initialHp1v1 - afterHp1v1 - 2);
|
||||
}
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
}
|
||||
const damagePlayer2Turn2 = player2.getMaxHp() - player2.hp;
|
||||
const damageEnemy1Turn2 = enemy1.getMaxHp() - enemy1.hp;
|
||||
|
||||
// To simulate the situation where all of the enemies or the player's Pokemons dies except for one.
|
||||
function killAllyAndEnemy(game: GameManager, killAlly: boolean, killSecondEnemy: boolean) {
|
||||
if (killAlly) {
|
||||
leaveOnePlayerPokemon(game);
|
||||
expect(game.scene.getPlayerField().filter(p => p.isActive()).length).toBe(1);
|
||||
}
|
||||
if (killSecondEnemy) {
|
||||
leaveOneEnemyPokemon(game);
|
||||
expect(game.scene.getEnemyField().filter(p => p.isActive()).length).toBe(1);
|
||||
}
|
||||
}
|
||||
enemy1.hp = enemy1.getMaxHp();
|
||||
|
||||
function leaveOnePlayerPokemon(game: GameManager) {
|
||||
const playerPokemons = game.scene.getParty();
|
||||
for (let i = 1; i < playerPokemons.length; i++) {
|
||||
playerPokemons[i].hp = 0;
|
||||
}
|
||||
expect(playerPokemons.filter(pokemon => pokemon.hp > 0).length).toBe(1);
|
||||
}
|
||||
// Turn 1: 3 targets, turn 2: 2 targets
|
||||
// Both should have damage reduction
|
||||
expect(damageEnemy1Turn1).toBe(damageEnemy1Turn2);
|
||||
expect(damagePlayer2Turn1).toBe(damagePlayer2Turn2);
|
||||
|
||||
function leaveOneEnemyPokemon(game: GameManager) {
|
||||
const enemyPokemons = game.scene.getEnemyParty();
|
||||
for (let i = 1; i < enemyPokemons.length; i++) {
|
||||
enemyPokemons[i].hp = 0;
|
||||
}
|
||||
}
|
||||
await game.killPokemon(player2);
|
||||
await game.toNextTurn();
|
||||
|
||||
function beforeTrial(phaserGame: Phaser.Game, single: boolean = false) {
|
||||
const game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.battleType("double")
|
||||
.moveset([Moves.EARTHQUAKE, Moves.HYPER_VOICE, Moves.SURF, Moves.SPLASH])
|
||||
.ability(Abilities.BALL_FETCH)
|
||||
.passiveAbility(Abilities.UNNERVE)
|
||||
.enemyMoveset(SPLASH_ONLY)
|
||||
.disableCrits()
|
||||
.startingLevel(50)
|
||||
.enemyLevel(40)
|
||||
.enemySpecies(Species.EEVEE);
|
||||
return game;
|
||||
}
|
||||
game.move.select(Moves.EARTHQUAKE);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
|
||||
function afterTrial(game: GameManager) {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
}
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
const damageEnemy1Turn3 = enemy1.getMaxHp() - enemy1.hp;
|
||||
// Turn 3: 1 target, should be no damage reduction
|
||||
expect(damageEnemy1Turn1).toBeLessThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) + 1);
|
||||
expect(damageEnemy1Turn1).toBeGreaterThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) - 1);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
|
@ -62,9 +62,6 @@ describe("Moves - Tera Blast", () => {
|
||||
|
||||
it("increases power if user is Stellar tera type", async () => {
|
||||
game.override.startingHeldItems([{ name: "TERA_SHARD", type: Type.STELLAR }]);
|
||||
const stellarTypeMultiplier = 2;
|
||||
const stellarTypeDmgBonus = 20;
|
||||
const basePower = moveToCheck.power;
|
||||
|
||||
await game.startBattle();
|
||||
|
||||
@ -72,9 +69,25 @@ describe("Moves - Tera Blast", () => {
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.phaseInterceptor.to("MoveEffectPhase");
|
||||
|
||||
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith((basePower + stellarTypeDmgBonus) * stellarTypeMultiplier);
|
||||
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(100);
|
||||
}, 20000);
|
||||
|
||||
it("is super effective against terastallized targets if user is Stellar tera type", async () => {
|
||||
game.override.startingHeldItems([{ name: "TERA_SHARD", type: Type.STELLAR }]);
|
||||
|
||||
await game.startBattle();
|
||||
|
||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
vi.spyOn(enemyPokemon, "apply");
|
||||
vi.spyOn(enemyPokemon, "isTerastallized").mockReturnValue(true);
|
||||
|
||||
game.move.select(Moves.TERA_BLAST);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.phaseInterceptor.to("MoveEffectPhase");
|
||||
|
||||
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.SUPER_EFFECTIVE);
|
||||
});
|
||||
|
||||
// Currently abilities are bugged and can't see when a move's category is changed
|
||||
it.skip("uses the higher stat of the user's Atk and SpAtk for damage calculation", async () => {
|
||||
game.override.enemyAbility(Abilities.TOXIC_DEBRIS);
|
||||
|
102
src/test/moves/thunder_wave.test.ts
Normal file
102
src/test/moves/thunder_wave.test.ts
Normal file
@ -0,0 +1,102 @@
|
||||
import { StatusEffect } from "#app/data/status-effect";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
import { EnemyPokemon } from "#app/field/pokemon";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import { SPLASH_ONLY } from "../utils/testUtils";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
describe("Moves - Thunder Wave", () => {
|
||||
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
|
||||
.battleType("single")
|
||||
.starterSpecies(Species.PIKACHU)
|
||||
.moveset([Moves.THUNDER_WAVE])
|
||||
.enemyMoveset(SPLASH_ONLY);
|
||||
});
|
||||
|
||||
// References: https://bulbapedia.bulbagarden.net/wiki/Thunder_Wave_(move)
|
||||
|
||||
it("paralyzes non-statused Pokemon that are not Ground types", async () => {
|
||||
game.override.enemySpecies(Species.MAGIKARP);
|
||||
await game.startBattle();
|
||||
|
||||
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.THUNDER_WAVE);
|
||||
await game.move.forceHit();
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(enemyPokemon.status?.effect).toBe(StatusEffect.PARALYSIS);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("does not paralyze if the Pokemon is a Ground-type", async () => {
|
||||
game.override.enemySpecies(Species.DIGLETT);
|
||||
await game.startBattle();
|
||||
|
||||
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.THUNDER_WAVE);
|
||||
await game.move.forceHit();
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(enemyPokemon.status).toBeUndefined();
|
||||
}, TIMEOUT);
|
||||
|
||||
it("does not paralyze if the Pokemon already has a status effect", async () => {
|
||||
game.override.enemySpecies(Species.MAGIKARP).enemyStatusEffect(StatusEffect.BURN);
|
||||
await game.startBattle();
|
||||
|
||||
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.THUNDER_WAVE);
|
||||
await game.move.forceHit();
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(enemyPokemon.status?.effect).not.toBe(StatusEffect.PARALYSIS);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("affects Ground types if the user has Normalize", async () => {
|
||||
game.override.ability(Abilities.NORMALIZE).enemySpecies(Species.DIGLETT);
|
||||
await game.startBattle();
|
||||
|
||||
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.THUNDER_WAVE);
|
||||
await game.move.forceHit();
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(enemyPokemon.status?.effect).toBe(StatusEffect.PARALYSIS);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("does not affect Ghost types if the user has Normalize", async () => {
|
||||
game.override.ability(Abilities.NORMALIZE).enemySpecies(Species.HAUNTER);
|
||||
await game.startBattle();
|
||||
|
||||
const enemyPokemon: EnemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.THUNDER_WAVE);
|
||||
await game.move.forceHit();
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
expect(enemyPokemon.status).toBeUndefined();
|
||||
}, TIMEOUT);
|
||||
});
|
@ -28,7 +28,7 @@ export class DailyModeHelper extends GameManagerHelper {
|
||||
uihandler.processInput(Button.ACTION); // select first slot. that's fine
|
||||
});
|
||||
|
||||
await this.game.phaseInterceptor.run(EncounterPhase);
|
||||
await this.game.phaseInterceptor.to(EncounterPhase);
|
||||
|
||||
if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0) {
|
||||
this.game.removeEnemyHeldItems();
|
||||
|
@ -143,7 +143,7 @@ export default class GameChallengesUiHandler extends UiHandler {
|
||||
};
|
||||
}
|
||||
|
||||
this.monoTypeValue = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`);
|
||||
this.monoTypeValue = this.scene.add.sprite(8, 98, Utils.getLocalizedSpriteKey("types"));
|
||||
this.monoTypeValue.setName("challenge-value-monotype-sprite");
|
||||
this.monoTypeValue.setScale(0.86);
|
||||
this.monoTypeValue.setVisible(false);
|
||||
|
@ -359,7 +359,7 @@ export default class EggGachaUiHandler extends MessageUiHandler {
|
||||
this.scene.time.delayedCall(this.getDelayValue(count ? 500 : 1250), () => {
|
||||
this.scene.playSound("se/gacha_dispense");
|
||||
this.scene.time.delayedCall(this.getDelayValue(750), () => {
|
||||
this.scene.sound.stopByKey("gacha_running");
|
||||
this.scene.sound.stopByKey("se/gacha_running");
|
||||
this.scene.tweens.add({
|
||||
targets: egg,
|
||||
duration: this.getDelayValue(350),
|
||||
|
@ -44,7 +44,7 @@ export default class FightUiHandler extends UiHandler {
|
||||
this.moveInfoContainer.setName("move-info");
|
||||
ui.add(this.moveInfoContainer);
|
||||
|
||||
this.typeIcon = this.scene.add.sprite(this.scene.scaledCanvas.width - 57, -36, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, "unknown");
|
||||
this.typeIcon = this.scene.add.sprite(this.scene.scaledCanvas.width - 57, -36, Utils.getLocalizedSpriteKey("types"), "unknown");
|
||||
this.typeIcon.setVisible(false);
|
||||
this.moveInfoContainer.add(this.typeIcon);
|
||||
|
||||
@ -179,15 +179,20 @@ export default class FightUiHandler extends UiHandler {
|
||||
|
||||
if (hasMove) {
|
||||
const pokemonMove = moveset[cursor]!; // TODO: is the bang correct?
|
||||
this.typeIcon.setTexture(`types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[pokemonMove.getMove().type].toLowerCase()).setScale(0.8);
|
||||
this.moveCategoryIcon.setTexture("categories", MoveCategory[pokemonMove.getMove().category].toLowerCase()).setScale(1.0);
|
||||
const moveType = pokemon.getMoveType(pokemonMove.getMove());
|
||||
const textureKey = Utils.getLocalizedSpriteKey("types");
|
||||
this.typeIcon.setTexture(textureKey, Type[moveType].toLowerCase()).setScale(0.8);
|
||||
|
||||
const moveCategory = pokemonMove.getMove().category;
|
||||
this.moveCategoryIcon.setTexture("categories", MoveCategory[moveCategory].toLowerCase()).setScale(1.0);
|
||||
const power = pokemonMove.getMove().power;
|
||||
const accuracy = pokemonMove.getMove().accuracy;
|
||||
const maxPP = pokemonMove.getMovePp();
|
||||
const pp = maxPP - pokemonMove.ppUsed;
|
||||
|
||||
this.ppText.setText(`${Utils.padInt(pp, 2, " ")}/${Utils.padInt(maxPP, 2, " ")}`);
|
||||
const ppLeftStr = Utils.padInt(pp, 2, " ");
|
||||
const ppMaxStr = Utils.padInt(maxPP, 2, " ");
|
||||
this.ppText.setText(`${ppLeftStr}/${ppMaxStr}`);
|
||||
this.powerText.setText(`${power >= 0 ? power : "---"}`);
|
||||
this.accuracyText.setText(`${accuracy >= 0 ? accuracy : "---"}`);
|
||||
|
||||
@ -231,7 +236,7 @@ export default class FightUiHandler extends UiHandler {
|
||||
* Returns undefined if it's a status move
|
||||
*/
|
||||
private getEffectivenessText(pokemon: Pokemon, opponent: Pokemon, pokemonMove: PokemonMove): string | undefined {
|
||||
const effectiveness = opponent.getMoveEffectiveness(pokemon, pokemonMove);
|
||||
const effectiveness = opponent.getMoveEffectiveness(pokemon, pokemonMove.getMove(), !opponent.battleData?.abilityRevealed);
|
||||
if (effectiveness === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@ -274,7 +279,7 @@ export default class FightUiHandler extends UiHandler {
|
||||
}
|
||||
|
||||
const moveColors = opponents
|
||||
.map((opponent) => opponent.getMoveEffectiveness(pokemon, pokemonMove))
|
||||
.map((opponent) => opponent.getMoveEffectiveness(pokemon, pokemonMove.getMove(), !opponent.battleData.abilityRevealed))
|
||||
.sort((a, b) => b - a)
|
||||
.map((effectiveness) => getTypeDamageMultiplierColor(effectiveness ?? 0, "offense"));
|
||||
|
||||
|
@ -15,6 +15,6 @@ export default class SettingsAudioUiHandler extends AbstractSettingsUiHandler {
|
||||
super(scene, SettingType.AUDIO, mode);
|
||||
this.title = "Audio";
|
||||
this.localStorageKey = "settings";
|
||||
this.rowsToDisplay = 5;
|
||||
this.rowsToDisplay = 6;
|
||||
}
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
if (index === 0 || index === 19) {
|
||||
return;
|
||||
}
|
||||
const typeSprite = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`);
|
||||
const typeSprite = this.scene.add.sprite(0, 0, Utils.getLocalizedSpriteKey("types"));
|
||||
typeSprite.setScale(0.5);
|
||||
typeSprite.setFrame(type.toLowerCase());
|
||||
typeOptions.push(new DropDownOption(this.scene, index, new DropDownLabel("", typeSprite)));
|
||||
@ -668,12 +668,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
this.pokemonSprite.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], ignoreTimeTint: true });
|
||||
this.starterSelectContainer.add(this.pokemonSprite);
|
||||
|
||||
this.type1Icon = this.scene.add.sprite(8, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`);
|
||||
this.type1Icon = this.scene.add.sprite(8, 98, Utils.getLocalizedSpriteKey("types"));
|
||||
this.type1Icon.setScale(0.5);
|
||||
this.type1Icon.setOrigin(0, 0);
|
||||
this.starterSelectContainer.add(this.type1Icon);
|
||||
|
||||
this.type2Icon = this.scene.add.sprite(26, 98, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`);
|
||||
this.type2Icon = this.scene.add.sprite(26, 98, Utils.getLocalizedSpriteKey("types"));
|
||||
this.type2Icon.setScale(0.5);
|
||||
this.type2Icon.setOrigin(0, 0);
|
||||
this.starterSelectContainer.add(this.type2Icon);
|
||||
@ -1701,7 +1701,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
}
|
||||
});
|
||||
ui.setMode(Mode.STARTER_SELECT);
|
||||
this.scene.playSound("buy");
|
||||
this.scene.playSound("se/buy");
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1753,7 +1753,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
starterAttributes.shiny = starterAttributes.shiny ? !starterAttributes.shiny : true;
|
||||
this.setSpeciesDetails(this.lastSpecies, !props.shiny, undefined, undefined, props.shiny ? 0 : undefined, undefined, undefined);
|
||||
if (starterAttributes.shiny) {
|
||||
this.scene.playSound("sparkle");
|
||||
this.scene.playSound("se/sparkle");
|
||||
// Set the variant label to the shiny tint
|
||||
const tint = getVariantTint(newVariant);
|
||||
this.pokemonShinyIcon.setFrame(getVariantIcon(newVariant));
|
||||
|
@ -716,7 +716,8 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
const getTypeIcon = (index: integer, type: Type, tera: boolean = false) => {
|
||||
const xCoord = typeLabel.width * typeLabel.scale + 9 + 34 * index;
|
||||
const typeIcon = !tera
|
||||
? this.scene.add.sprite(xCoord, 42, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[type].toLowerCase()) : this.scene.add.sprite(xCoord, 42, "type_tera");
|
||||
? this.scene.add.sprite(xCoord, 42, Utils.getLocalizedSpriteKey("types"), Type[type].toLowerCase())
|
||||
: this.scene.add.sprite(xCoord, 42, "type_tera");
|
||||
if (tera) {
|
||||
typeIcon.setScale(0.5);
|
||||
const typeRgb = getTypeRgb(type);
|
||||
@ -934,10 +935,14 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
|
||||
this.extraMoveRowContainer.setVisible(true);
|
||||
const newMoveTypeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[this.newMove?.type!].toLowerCase()); // TODO: is this bang correct?
|
||||
newMoveTypeIcon.setOrigin(0, 1);
|
||||
this.extraMoveRowContainer.add(newMoveTypeIcon);
|
||||
|
||||
if (this.newMove && this.pokemon) {
|
||||
const spriteKey = Utils.getLocalizedSpriteKey("types");
|
||||
const moveType = this.pokemon.getMoveType(this.newMove);
|
||||
const newMoveTypeIcon = this.scene.add.sprite(0, 0, spriteKey, Type[moveType].toLowerCase());
|
||||
newMoveTypeIcon.setOrigin(0, 1);
|
||||
this.extraMoveRowContainer.add(newMoveTypeIcon);
|
||||
}
|
||||
const ppOverlay = this.scene.add.image(163, -1, "summary_moves_overlay_pp");
|
||||
ppOverlay.setOrigin(0, 1);
|
||||
this.extraMoveRowContainer.add(ppOverlay);
|
||||
@ -956,8 +961,11 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
const moveRowContainer = this.scene.add.container(0, 16 * m);
|
||||
this.moveRowsContainer.add(moveRowContainer);
|
||||
|
||||
if (move) {
|
||||
const typeIcon = this.scene.add.sprite(0, 0, `types${Utils.verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`, Type[move.getMove().type].toLowerCase()); typeIcon.setOrigin(0, 1);
|
||||
if (move && this.pokemon) {
|
||||
const spriteKey = Utils.getLocalizedSpriteKey("types");
|
||||
const moveType = this.pokemon.getMoveType(move.getMove());
|
||||
const typeIcon = this.scene.add.sprite(0, 0, spriteKey, Type[moveType].toLowerCase());
|
||||
typeIcon.setOrigin(0, 1);
|
||||
moveRowContainer.add(typeIcon);
|
||||
}
|
||||
|
||||
|
@ -574,3 +574,12 @@ export function isNullOrUndefined(object: any): boolean {
|
||||
export function toDmgValue(value: number, minValue: number = 1) {
|
||||
return Math.max(Math.floor(value), minValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to localize a sprite key (e.g. for types)
|
||||
* @param baseKey the base key of the sprite (e.g. `type`)
|
||||
* @returns the localized sprite key
|
||||
*/
|
||||
export function getLocalizedSpriteKey(baseKey: string) {
|
||||
return `${baseKey}${verifyLang(i18next.resolvedLanguage) ? `_${i18next.resolvedLanguage}` : ""}`;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user