Merge branch 'beta' into danish-workspace
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 879 B After Width: | Height: | Size: 942 B |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
40
public/images/pokemon/variant/6706.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"1": {
|
||||
"566678": "0e6296",
|
||||
"e0e4f4": "513981",
|
||||
"625287": "4e4094",
|
||||
"536273": "1f1233",
|
||||
"988b98": "b24c86",
|
||||
"9170b9": "8b69c3",
|
||||
"c4cce1": "3b235c",
|
||||
"e6d3e9": "f1a4c5",
|
||||
"bfacc1": "da75a5",
|
||||
"515f70": "197497",
|
||||
"c5cee3": "63cee1",
|
||||
"8e96aa": "301848",
|
||||
"8b93a6": "3aa8c4",
|
||||
"80737f": "8a2166",
|
||||
"4b454f": "6f1357",
|
||||
"36404c": "0c5474",
|
||||
"b791f2": "c7a1e5"
|
||||
},
|
||||
"2": {
|
||||
"566678": "8e480b",
|
||||
"e0e4f4": "176463",
|
||||
"625287": "274159",
|
||||
"536273": "02262c",
|
||||
"988b98": "2a6563",
|
||||
"9170b9": "2f667c",
|
||||
"c4cce1": "0d484a",
|
||||
"e6d3e9": "9cead8",
|
||||
"bfacc1": "5db6a9",
|
||||
"515f70": "a34205",
|
||||
"c5cee3": "f7af58",
|
||||
"8e96aa": "073338",
|
||||
"8b93a6": "d27e26",
|
||||
"80737f": "2b736f",
|
||||
"4b454f": "194f51",
|
||||
"36404c": "842401",
|
||||
"b791f2": "4a9699"
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "6706_2.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 82,
|
||||
"h": 82
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:02eb46aa66ac70df612e129b7801a85c:a77cca14b23f4f3aece64d1a82449a0f:d60cc2e5ae2bd18de8ee3ab0649593ee$"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 5.0 KiB |
@ -1,41 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "6706_3.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 82,
|
||||
"h": 82
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:02eb46aa66ac70df612e129b7801a85c:a77cca14b23f4f3aece64d1a82449a0f:d60cc2e5ae2bd18de8ee3ab0649593ee$"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 5.1 KiB |
@ -3721,8 +3721,8 @@
|
||||
],
|
||||
"6706": [
|
||||
0,
|
||||
2,
|
||||
2
|
||||
1,
|
||||
1
|
||||
],
|
||||
"6713": [
|
||||
0,
|
||||
@ -7754,8 +7754,8 @@
|
||||
],
|
||||
"6706": [
|
||||
0,
|
||||
2,
|
||||
2
|
||||
1,
|
||||
1
|
||||
],
|
||||
"6713": [
|
||||
0,
|
||||
@ -8493,8 +8493,8 @@
|
||||
],
|
||||
"705": [
|
||||
0,
|
||||
2,
|
||||
2
|
||||
1,
|
||||
1
|
||||
],
|
||||
"706": [
|
||||
0,
|
||||
@ -9568,8 +9568,8 @@
|
||||
],
|
||||
"6706": [
|
||||
0,
|
||||
2,
|
||||
2
|
||||
1,
|
||||
1
|
||||
],
|
||||
"female": {},
|
||||
"back": {
|
||||
@ -11095,8 +11095,8 @@
|
||||
],
|
||||
"6706": [
|
||||
0,
|
||||
2,
|
||||
2
|
||||
1,
|
||||
1
|
||||
],
|
||||
"6713": [
|
||||
0,
|
||||
|
38
public/images/pokemon/variant/back/6706.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"1": {
|
||||
"566678": "197497",
|
||||
"8e96aa": "3b235c",
|
||||
"929aad": "3aa8c4",
|
||||
"625287": "4e4094",
|
||||
"536273": "301848",
|
||||
"988b98": "b24c86",
|
||||
"36404c": "0c5474",
|
||||
"c4cce1": "513981",
|
||||
"e6d3e9": "f1a4c5",
|
||||
"bfacc1": "d074a0",
|
||||
"546475": "0e6296",
|
||||
"c5cee3": "63cee1",
|
||||
"80737f": "8a2166",
|
||||
"4b454f": "6f1357",
|
||||
"9170b9": "8b69c3",
|
||||
"b791f2": "c7a1e5"
|
||||
},
|
||||
"2": {
|
||||
"566678": "a34205",
|
||||
"8e96aa": "073338",
|
||||
"929aad": "d27e26",
|
||||
"625287": "0e3f47",
|
||||
"536273": "042329",
|
||||
"988b98": "2b736f",
|
||||
"36404c": "842401",
|
||||
"c4cce1": "0d484a",
|
||||
"e6d3e9": "9cead8",
|
||||
"bfacc1": "5db6a9",
|
||||
"546475": "8e480b",
|
||||
"c5cee3": "f7af58",
|
||||
"80737f": "194f51",
|
||||
"4b454f": "274159",
|
||||
"9170b9": "2f667c",
|
||||
"b791f2": "4a9699"
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "6706_2.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 79,
|
||||
"h": 79
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 79,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 79,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 79,
|
||||
"h": 73
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:64f7e6dfa489012922487e45ba53d557:4d24652b372939abe499497c4b6647b0:d60cc2e5ae2bd18de8ee3ab0649593ee$"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 4.7 KiB |
@ -1,41 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "6706_3.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 79,
|
||||
"h": 79
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"sourceSize": {
|
||||
"w": 79,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 79,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 79,
|
||||
"h": 73
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:64f7e6dfa489012922487e45ba53d557:4d24652b372939abe499497c4b6647b0:d60cc2e5ae2bd18de8ee3ab0649593ee$"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 4.7 KiB |
40
public/images/pokemon/variant/exp/6706.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"1": {
|
||||
"566678": "0e6296",
|
||||
"e0e4f4": "513981",
|
||||
"625287": "4e4094",
|
||||
"536273": "1f1233",
|
||||
"988b98": "b24c86",
|
||||
"36404c": "0c5474",
|
||||
"c4cce1": "3b235c",
|
||||
"e6d3e9": "f1a4c5",
|
||||
"bfacc1": "da75a5",
|
||||
"515f70": "197497",
|
||||
"c5cee3": "63cee1",
|
||||
"b791f2": "c7a1e5",
|
||||
"8b93a6": "3aa8c4",
|
||||
"80737f": "8a2166",
|
||||
"4b454f": "6f1357",
|
||||
"9170b9": "8b69c3",
|
||||
"8e96aa": "301848"
|
||||
},
|
||||
"2": {
|
||||
"566678": "8e480b",
|
||||
"e0e4f4": "176463",
|
||||
"625287": "274159",
|
||||
"536273": "02262c",
|
||||
"988b98": "2a6563",
|
||||
"36404c": "842401",
|
||||
"c4cce1": "0d484a",
|
||||
"e6d3e9": "9cead8",
|
||||
"bfacc1": "5db6a9",
|
||||
"515f70": "a34205",
|
||||
"c5cee3": "f7af58",
|
||||
"b791f2": "4a9699",
|
||||
"8b93a6": "d27e26",
|
||||
"80737f": "2b736f",
|
||||
"4b454f": "194f51",
|
||||
"9170b9": "2f667c",
|
||||
"8e96aa": "073338"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 55 KiB |
33
public/images/pokemon/variant/exp/705.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"1": {
|
||||
"101010":"101010",
|
||||
"4d454d":"8a2166",
|
||||
"807380":"b93f84",
|
||||
"bfacbf":"e56ca6",
|
||||
"f2daf2":"fbb3d2",
|
||||
"665980":"4e4094",
|
||||
"8f7db3":"8b69c3",
|
||||
"b8a1e5":"c7a1e5",
|
||||
"4d993d":"aa6a00",
|
||||
"66cc52":"ffd047",
|
||||
"4e9c3e":"0c5474",
|
||||
"67cf53":"3aa8c4",
|
||||
"b6f2aa":"63cee1"
|
||||
},
|
||||
"2": {
|
||||
"101010":"101010",
|
||||
"4d454d":"194f51",
|
||||
"807380":"2b736f",
|
||||
"bfacbf":"5db6a9",
|
||||
"f2daf2":"9cead8",
|
||||
"665980":"274159",
|
||||
"8f7db3":"2f667c",
|
||||
"b8a1e5":"4a9699",
|
||||
"4d993d":"007d61",
|
||||
"66cc52":"49ffbf",
|
||||
"4e9c3e":"842401",
|
||||
"67cf53":"a34205",
|
||||
"b6f2aa":"d27e26"
|
||||
}
|
||||
}
|
||||
|
@ -1,272 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "705_2.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 154,
|
||||
"h": 154
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 46,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 46,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0008.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 46,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 46,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 46,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0009.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 46,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 91,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 42,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 58,
|
||||
"w": 42,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0010.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 42,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 58,
|
||||
"w": 42,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 42,
|
||||
"y": 58,
|
||||
"w": 41,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0011.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 42,
|
||||
"y": 58,
|
||||
"w": 41,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 36,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 83,
|
||||
"y": 58,
|
||||
"w": 36,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0012.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 36,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 83,
|
||||
"y": 58,
|
||||
"w": 36,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 35,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 119,
|
||||
"y": 58,
|
||||
"w": 35,
|
||||
"h": 58
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:4bf155254b23c88780e7eee282256589:82bb727988054c3064e203b6908ff464:6b57e983626c7fc9144ab67f30c66814$"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 4.0 KiB |
@ -1,272 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "705_3.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 154,
|
||||
"h": 154
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 46,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 46,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0008.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 46,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 46,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 46,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0009.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 46,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 91,
|
||||
"y": 0,
|
||||
"w": 45,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 42,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 58,
|
||||
"w": 42,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0010.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 42,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 58,
|
||||
"w": 42,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 42,
|
||||
"y": 58,
|
||||
"w": 41,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0011.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 41,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 42,
|
||||
"y": 58,
|
||||
"w": 41,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 36,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 83,
|
||||
"y": 58,
|
||||
"w": 36,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0012.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 36,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 83,
|
||||
"y": 58,
|
||||
"w": 36,
|
||||
"h": 58
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 49,
|
||||
"h": 58
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 35,
|
||||
"h": 58
|
||||
},
|
||||
"frame": {
|
||||
"x": 119,
|
||||
"y": 58,
|
||||
"w": 35,
|
||||
"h": 58
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:4bf155254b23c88780e7eee282256589:82bb727988054c3064e203b6908ff464:6b57e983626c7fc9144ab67f30c66814$"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 4.0 KiB |
38
public/images/pokemon/variant/exp/back/6706.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"1": {
|
||||
"566678": "197497",
|
||||
"8e96aa": "3b235c",
|
||||
"929aad": "3aa8c4",
|
||||
"625287": "4e4094",
|
||||
"536273": "301848",
|
||||
"988b98": "b24c86",
|
||||
"36404c": "0c5474",
|
||||
"c4cce1": "513981",
|
||||
"e6d3e9": "f1a4c5",
|
||||
"bfacc1": "d074a0",
|
||||
"546475": "0e6296",
|
||||
"c5cee3": "63cee1",
|
||||
"80737f": "8a2166",
|
||||
"4b454f": "6f1357",
|
||||
"9170b9": "8b69c3",
|
||||
"b791f2": "c7a1e5"
|
||||
},
|
||||
"2": {
|
||||
"566678": "a34205",
|
||||
"8e96aa": "073338",
|
||||
"929aad": "d27e26",
|
||||
"625287": "0e3f47",
|
||||
"536273": "042329",
|
||||
"988b98": "2b736f",
|
||||
"36404c": "842401",
|
||||
"c4cce1": "0d484a",
|
||||
"e6d3e9": "9cead8",
|
||||
"bfacc1": "5db6a9",
|
||||
"546475": "8e480b",
|
||||
"c5cee3": "f7af58",
|
||||
"80737f": "194f51",
|
||||
"4b454f": "274159",
|
||||
"9170b9": "2f667c",
|
||||
"b791f2": "4a9699"
|
||||
}
|
||||
}
|
@ -1,776 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "6706_2.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 358,
|
||||
"h": 358
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 4,
|
||||
"w": 84,
|
||||
"h": 69
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 84,
|
||||
"h": 69
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 4,
|
||||
"w": 84,
|
||||
"h": 69
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 84,
|
||||
"h": 69
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 84,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 84,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0034.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 69,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 167,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 167,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0035.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 250,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0036.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 250,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 167,
|
||||
"y": 70,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0008.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 167,
|
||||
"y": 70,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0013.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 83,
|
||||
"y": 72,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0014.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 83,
|
||||
"y": 72,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0025.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 141,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0026.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 141,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0027.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 141,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0032.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 249,
|
||||
"y": 70,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0033.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 249,
|
||||
"y": 70,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0011.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 5,
|
||||
"y": 0,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 214,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0012.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 5,
|
||||
"y": 0,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 214,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0017.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 287,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0018.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 287,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0028.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 5,
|
||||
"y": 0,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 81,
|
||||
"y": 214,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0029.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 5,
|
||||
"y": 0,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 81,
|
||||
"y": 214,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0021.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
},
|
||||
"frame": {
|
||||
"x": 81,
|
||||
"y": 287,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0022.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
},
|
||||
"frame": {
|
||||
"x": 81,
|
||||
"y": 287,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0015.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 165,
|
||||
"y": 143,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0016.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 165,
|
||||
"y": 143,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0023.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 247,
|
||||
"y": 143,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0024.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 247,
|
||||
"y": 143,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0009.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 215,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0010.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 215,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0019.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"w": 81,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 288,
|
||||
"w": 81,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0020.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"w": 81,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 288,
|
||||
"w": 81,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0030.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 242,
|
||||
"y": 215,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0031.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 242,
|
||||
"y": 215,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:5d65e2c5a6a97b7c7014a175ce3592af:3255e87f637a475d82734fc7d93baf71:d60cc2e5ae2bd18de8ee3ab0649593ee$"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 22 KiB |
@ -1,776 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"image": "6706_3.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 358,
|
||||
"h": 358
|
||||
},
|
||||
"scale": 1,
|
||||
"frames": [
|
||||
{
|
||||
"filename": "0001.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 4,
|
||||
"w": 84,
|
||||
"h": 69
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 84,
|
||||
"h": 69
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0002.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 4,
|
||||
"w": 84,
|
||||
"h": 69
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 84,
|
||||
"h": 69
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0005.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 84,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0006.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 84,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0034.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 69,
|
||||
"w": 83,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0003.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 167,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0004.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 167,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0035.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 250,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0036.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 250,
|
||||
"y": 0,
|
||||
"w": 83,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0007.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 167,
|
||||
"y": 70,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0008.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 167,
|
||||
"y": 70,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0013.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 83,
|
||||
"y": 72,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0014.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 83,
|
||||
"y": 72,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0025.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 141,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0026.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 141,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0027.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 141,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0032.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 249,
|
||||
"y": 70,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0033.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 4,
|
||||
"y": 0,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 249,
|
||||
"y": 70,
|
||||
"w": 82,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0011.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 5,
|
||||
"y": 0,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 214,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0012.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 5,
|
||||
"y": 0,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 214,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0017.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 287,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0018.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
},
|
||||
"frame": {
|
||||
"x": 0,
|
||||
"y": 287,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0028.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 5,
|
||||
"y": 0,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 81,
|
||||
"y": 214,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0029.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 5,
|
||||
"y": 0,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 81,
|
||||
"y": 214,
|
||||
"w": 81,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0021.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
},
|
||||
"frame": {
|
||||
"x": 81,
|
||||
"y": 287,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0022.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
},
|
||||
"frame": {
|
||||
"x": 81,
|
||||
"y": 287,
|
||||
"w": 81,
|
||||
"h": 71
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0015.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 165,
|
||||
"y": 143,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0016.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 165,
|
||||
"y": 143,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0023.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 247,
|
||||
"y": 143,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0024.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
},
|
||||
"frame": {
|
||||
"x": 247,
|
||||
"y": 143,
|
||||
"w": 82,
|
||||
"h": 72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0009.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 215,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0010.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 215,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0019.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"w": 81,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 288,
|
||||
"w": 81,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0020.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"w": 81,
|
||||
"h": 70
|
||||
},
|
||||
"frame": {
|
||||
"x": 162,
|
||||
"y": 288,
|
||||
"w": 81,
|
||||
"h": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0030.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 242,
|
||||
"y": 215,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename": "0031.png",
|
||||
"rotated": false,
|
||||
"trimmed": true,
|
||||
"sourceSize": {
|
||||
"w": 86,
|
||||
"h": 73
|
||||
},
|
||||
"spriteSourceSize": {
|
||||
"x": 6,
|
||||
"y": 0,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
},
|
||||
"frame": {
|
||||
"x": 242,
|
||||
"y": 215,
|
||||
"w": 80,
|
||||
"h": 73
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "3.0",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:5d65e2c5a6a97b7c7014a175ce3592af:3255e87f637a475d82734fc7d93baf71:d60cc2e5ae2bd18de8ee3ab0649593ee$"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 22 KiB |
@ -2316,7 +2316,10 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
}
|
||||
|
||||
this.currentPhase?.start();
|
||||
if (this.currentPhase) {
|
||||
console.log(`%cStart Phase ${this.currentPhase.constructor.name}`, "color:green;");
|
||||
this.currentPhase.start();
|
||||
}
|
||||
}
|
||||
|
||||
overridePhase(phase: Phase): boolean {
|
||||
@ -2326,6 +2329,7 @@ export default class BattleScene extends SceneBase {
|
||||
|
||||
this.standbyPhase = this.currentPhase;
|
||||
this.currentPhase = phase;
|
||||
console.log(`%cStart Phase ${phase.constructor.name}`, "color:green;");
|
||||
phase.start();
|
||||
|
||||
return true;
|
||||
|
@ -118,6 +118,14 @@ export class Ability implements Localizable {
|
||||
this.nameAppend += " (N)";
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal flag used for developers to document edge cases. When using this, please be sure to document the edge case.
|
||||
* @returns the ability
|
||||
*/
|
||||
edgeCase(): this {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
type AbAttrApplyFunc<TAttr extends AbAttr> = (attr: TAttr, passive: boolean) => boolean | Promise<boolean>;
|
||||
@ -4906,7 +4914,7 @@ export function initAbilities() {
|
||||
.ignorable(),
|
||||
new Ability(Abilities.SHIELD_DUST, 3)
|
||||
.attr(IgnoreMoveEffectsAbAttr)
|
||||
.partial(),
|
||||
.edgeCase(), // Does not work with secret power (unimplemented)
|
||||
new Ability(Abilities.OWN_TEMPO, 3)
|
||||
.attr(BattlerTagImmunityAbAttr, BattlerTagType.CONFUSED)
|
||||
.attr(IntimidateImmunityAbAttr)
|
||||
@ -4951,7 +4959,7 @@ export function initAbilities() {
|
||||
.ignorable(),
|
||||
new Ability(Abilities.SERENE_GRACE, 3)
|
||||
.attr(MoveEffectChanceMultiplierAbAttr, 2)
|
||||
.partial(),
|
||||
.edgeCase(), // does not work with secret power (unimplemented)
|
||||
new Ability(Abilities.SWIFT_SWIM, 3)
|
||||
.attr(StatMultiplierAbAttr, Stat.SPD, 2)
|
||||
.condition(getWeatherCondition(WeatherType.RAIN, WeatherType.HEAVY_RAIN)),
|
||||
@ -5235,7 +5243,8 @@ export function initAbilities() {
|
||||
new Ability(Abilities.SHEER_FORCE, 5)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 5461 / 4096)
|
||||
.attr(MoveEffectChanceMultiplierAbAttr, 0)
|
||||
.partial(),
|
||||
.edgeCase() // Should disable shell bell and Meloetta's relic song transformation
|
||||
.edgeCase(), // Should disable life orb, eject button, red card, kee/maranga berry if they get implemented
|
||||
new Ability(Abilities.CONTRARY, 5)
|
||||
.attr(StatStageChangeMultiplierAbAttr, -1)
|
||||
.ignorable(),
|
||||
@ -5278,7 +5287,7 @@ export function initAbilities() {
|
||||
/** Rate is doubled when under sun {@link https://dex.pokemonshowdown.com/abilities/harvest} */
|
||||
(pokemon) => 0.5 * (getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)(pokemon) ? 2 : 1)
|
||||
)
|
||||
.partial(),
|
||||
.edgeCase(), // Cannot recover berries used up by fling or natural gift (unimplemented)
|
||||
new Ability(Abilities.TELEPATHY, 5)
|
||||
.attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon.getAlly() === attacker && move instanceof AttackMove)
|
||||
.ignorable(),
|
||||
@ -5357,7 +5366,7 @@ export function initAbilities() {
|
||||
.bypassFaint(),
|
||||
new Ability(Abilities.VICTORY_STAR, 5)
|
||||
.attr(StatMultiplierAbAttr, Stat.ACC, 1.1)
|
||||
.partial(),
|
||||
.partial(), // Does not boost ally's accuracy
|
||||
new Ability(Abilities.TURBOBLAZE, 5)
|
||||
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTurboblaze", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
|
||||
.attr(MoveAbilityBypassAbAttr),
|
||||
@ -5468,7 +5477,7 @@ export function initAbilities() {
|
||||
.attr(UnsuppressableAbilityAbAttr)
|
||||
.attr(NoFusionAbilityAbAttr)
|
||||
.bypassFaint()
|
||||
.partial(),
|
||||
.partial(), // Meteor form should protect against status effects and yawn
|
||||
new Ability(Abilities.STAKEOUT, 7)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => user?.scene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command === Command.POKEMON, 2),
|
||||
new Ability(Abilities.WATER_BUBBLE, 7)
|
||||
@ -5536,9 +5545,9 @@ export function initAbilities() {
|
||||
.attr(NoFusionAbilityAbAttr)
|
||||
.bypassFaint()
|
||||
.partial(),
|
||||
new Ability(Abilities.CORROSION, 7) // TODO: Test Corrosion against Magic Bounce once it is implemented
|
||||
new Ability(Abilities.CORROSION, 7)
|
||||
.attr(IgnoreTypeStatusEffectImmunityAbAttr, [ StatusEffect.POISON, StatusEffect.TOXIC ], [ Type.STEEL, Type.POISON ])
|
||||
.partial(),
|
||||
.edgeCase(), // Should interact correctly with magic coat/bounce (not yet implemented), fling with toxic orb (not implemented yet), and synchronize (not fully implemented yet)
|
||||
new Ability(Abilities.COMATOSE, 7)
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
.attr(UnswappableAbilityAbAttr)
|
||||
@ -5693,7 +5702,7 @@ export function initAbilities() {
|
||||
new Ability(Abilities.WANDERING_SPIRIT, 8)
|
||||
.attr(PostDefendAbilitySwapAbAttr)
|
||||
.bypassFaint()
|
||||
.partial(),
|
||||
.edgeCase(), // interacts incorrectly with rock head. It's meant to switch abilities before recoil would apply so that a pokemon with rock head would lose rock head first and still take the recoil
|
||||
new Ability(Abilities.GORILLA_TACTICS, 8)
|
||||
.attr(GorillaTacticsAbAttr),
|
||||
new Ability(Abilities.NEUTRALIZING_GAS, 8)
|
||||
@ -5702,7 +5711,7 @@ export function initAbilities() {
|
||||
.attr(UnswappableAbilityAbAttr)
|
||||
.attr(NoTransformAbilityAbAttr)
|
||||
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonNeutralizingGas", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
|
||||
.partial(),
|
||||
.partial(), // A bunch of weird interactions with other abilities being suppressed then unsuppressed
|
||||
new Ability(Abilities.PASTEL_VEIL, 8)
|
||||
.attr(PostSummonUserFieldRemoveStatusEffectAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)
|
||||
.attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)
|
||||
@ -5807,7 +5816,7 @@ export function initAbilities() {
|
||||
new Ability(Abilities.GOOD_AS_GOLD, 9)
|
||||
.attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.category === MoveCategory.STATUS)
|
||||
.ignorable()
|
||||
.partial(),
|
||||
.partial(), // Lots of weird interactions with moves and abilities such as negating status moves that target the field
|
||||
new Ability(Abilities.VESSEL_OF_RUIN, 9)
|
||||
.attr(FieldMultiplyStatAbAttr, Stat.SPATK, 0.75)
|
||||
.attr(PostSummonMessageAbAttr, (user) => i18next.t("abilityTriggers:postSummonVesselOfRuin", { pokemonNameWithAffix: getPokemonNameWithAffix(user), statName: i18next.t(getStatKey(Stat.SPATK)) }))
|
||||
@ -5840,7 +5849,7 @@ export function initAbilities() {
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.SLICING_MOVE), 1.5),
|
||||
new Ability(Abilities.SUPREME_OVERLORD, 9)
|
||||
.attr(VariableMovePowerBoostAbAttr, (user, target, move) => 1 + 0.1 * Math.min(user.isPlayer() ? user.scene.currentBattle.playerFaints : user.scene.currentBattle.enemyFaints, 5))
|
||||
.partial(),
|
||||
.partial(), // Counter resets every wave
|
||||
new Ability(Abilities.COSTAR, 9)
|
||||
.attr(PostSummonCopyAllyStatsAbAttr),
|
||||
new Ability(Abilities.TOXIC_DEBRIS, 9)
|
||||
@ -5873,25 +5882,25 @@ export function initAbilities() {
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
.attr(UnswappableAbilityAbAttr)
|
||||
.attr(NoTransformAbilityAbAttr)
|
||||
.partial(),
|
||||
.partial(), // Ogerpon tera interactions
|
||||
new Ability(Abilities.EMBODY_ASPECT_WELLSPRING, 9)
|
||||
.attr(PostBattleInitStatStageChangeAbAttr, [ Stat.SPDEF ], 1, true)
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
.attr(UnswappableAbilityAbAttr)
|
||||
.attr(NoTransformAbilityAbAttr)
|
||||
.partial(),
|
||||
.partial(), // Ogerpon tera interactions
|
||||
new Ability(Abilities.EMBODY_ASPECT_HEARTHFLAME, 9)
|
||||
.attr(PostBattleInitStatStageChangeAbAttr, [ Stat.ATK ], 1, true)
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
.attr(UnswappableAbilityAbAttr)
|
||||
.attr(NoTransformAbilityAbAttr)
|
||||
.partial(),
|
||||
.partial(), // Ogerpon tera interactions
|
||||
new Ability(Abilities.EMBODY_ASPECT_CORNERSTONE, 9)
|
||||
.attr(PostBattleInitStatStageChangeAbAttr, [ Stat.DEF ], 1, true)
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
.attr(UnswappableAbilityAbAttr)
|
||||
.attr(NoTransformAbilityAbAttr)
|
||||
.partial(),
|
||||
.partial(), // Ogerpon tera interactions
|
||||
new Ability(Abilities.TERA_SHIFT, 9)
|
||||
.attr(PostSummonFormChangeAbAttr, p => p.getFormKey() ? 0 : 1)
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
|
@ -4,7 +4,7 @@ import { Type } from "#app/data/type";
|
||||
import * as Utils from "#app/utils";
|
||||
import { MoveCategory, allMoves, MoveTarget, IncrementMovePriorityAttr, applyMoveAttrs } from "#app/data/move";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import Pokemon, { HitResult, PlayerPokemon, PokemonMove, EnemyPokemon } from "#app/field/pokemon";
|
||||
import Pokemon, { HitResult, PokemonMove } from "#app/field/pokemon";
|
||||
import { StatusEffect } from "#app/data/status-effect";
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { BlockNonDirectDamageAbAttr, ChangeMovePriorityAbAttr, ProtectStatAbAttr, applyAbAttrs } from "#app/data/ability";
|
||||
@ -71,6 +71,32 @@ export abstract class ArenaTag {
|
||||
this.sourceId = source.sourceId;
|
||||
this.side = source.side;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that retrieves the source Pokemon
|
||||
* @param scene medium to retrieve the source Pokemon
|
||||
* @returns The source {@linkcode Pokemon} or `null` if none is found
|
||||
*/
|
||||
public getSourcePokemon(scene: BattleScene): Pokemon | null {
|
||||
return this.sourceId ? scene.getPokemonById(this.sourceId) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that retrieves the Pokemon affected
|
||||
* @param scene - medium to retrieve the involved Pokemon
|
||||
* @returns list of PlayerPokemon or EnemyPokemon on the field
|
||||
*/
|
||||
public getAffectedPokemon(scene: BattleScene): Pokemon[] {
|
||||
switch (this.side) {
|
||||
case ArenaTagSide.PLAYER:
|
||||
return scene.getPlayerField() ?? [];
|
||||
case ArenaTagSide.ENEMY:
|
||||
return scene.getEnemyField() ?? [];
|
||||
case ArenaTagSide.BOTH:
|
||||
default:
|
||||
return scene.getField(true) ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -885,7 +911,8 @@ export class GravityTag extends ArenaTag {
|
||||
arena.scene.queueMessage(i18next.t("arenaTag:gravityOnAdd"));
|
||||
arena.scene.getField(true).forEach((pokemon) => {
|
||||
if (pokemon !== null) {
|
||||
pokemon.removeTag(BattlerTagType.MAGNET_RISEN);
|
||||
pokemon.removeTag(BattlerTagType.FLOATING);
|
||||
pokemon.removeTag(BattlerTagType.TELEKINESIS);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -977,36 +1004,24 @@ class NoneTag extends ArenaTag {
|
||||
* Imprison will apply to any opposing Pokemon that switch onto the field as well.
|
||||
*/
|
||||
class ImprisonTag extends ArenaTrapTag {
|
||||
private source: Pokemon;
|
||||
|
||||
constructor(sourceId: number, side: ArenaTagSide) {
|
||||
super(ArenaTagType.IMPRISON, Moves.IMPRISON, sourceId, side, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that retrieves the Pokemon affected
|
||||
* @param {BattleScene} scene medium to retrieve the involved Pokemon
|
||||
* @returns list of PlayerPokemon or EnemyPokemon on the field
|
||||
*/
|
||||
private retrieveField(scene: BattleScene): PlayerPokemon[] | EnemyPokemon[] {
|
||||
if (!this.source.isPlayer()) {
|
||||
return scene.getPlayerField() ?? [];
|
||||
}
|
||||
return scene.getEnemyField() ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* This function applies the effects of Imprison to the opposing Pokemon already present on the field.
|
||||
* @param arena
|
||||
*/
|
||||
override onAdd({ scene }: Arena) {
|
||||
this.source = scene.getPokemonById(this.sourceId!)!;
|
||||
if (this.source) {
|
||||
const party = this.retrieveField(scene);
|
||||
party?.forEach((p: PlayerPokemon | EnemyPokemon ) => {
|
||||
p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId);
|
||||
const source = this.getSourcePokemon(scene);
|
||||
if (source) {
|
||||
const party = this.getAffectedPokemon(scene);
|
||||
party?.forEach((p: Pokemon ) => {
|
||||
if (p.isAllowedInBattle()) {
|
||||
p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId);
|
||||
}
|
||||
});
|
||||
scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(this.source) }));
|
||||
scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1015,8 +1030,9 @@ class ImprisonTag extends ArenaTrapTag {
|
||||
* @param _arena
|
||||
* @returns `true` if the source of the tag is still active on the field | `false` if not
|
||||
*/
|
||||
override lapse(_arena: Arena): boolean {
|
||||
return this.source.isActive(true);
|
||||
override lapse({ scene }: Arena): boolean {
|
||||
const source = this.getSourcePokemon(scene);
|
||||
return source ? source.isActive(true) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1025,7 +1041,8 @@ class ImprisonTag extends ArenaTrapTag {
|
||||
* @returns `true`
|
||||
*/
|
||||
override activateTrap(pokemon: Pokemon): boolean {
|
||||
if (this.source.isActive(true)) {
|
||||
const source = this.getSourcePokemon(pokemon.scene);
|
||||
if (source && source.isActive(true) && pokemon.isAllowedInBattle()) {
|
||||
pokemon.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId);
|
||||
}
|
||||
return true;
|
||||
@ -1036,8 +1053,8 @@ class ImprisonTag extends ArenaTrapTag {
|
||||
* @param arena
|
||||
*/
|
||||
override onRemove({ scene }: Arena): void {
|
||||
const party = this.retrieveField(scene);
|
||||
party?.forEach((p: PlayerPokemon | EnemyPokemon) => {
|
||||
const party = this.getAffectedPokemon(scene);
|
||||
party?.forEach((p: Pokemon) => {
|
||||
p.removeTag(BattlerTagType.IMPRISON);
|
||||
});
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||
import { StatStageChangePhase, StatStageChangeCallback } from "#app/phases/stat-stage-change-phase";
|
||||
import { PokemonAnimType } from "#app/enums/pokemon-anim-type";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
|
||||
export enum BattlerTagLapseType {
|
||||
FAINT,
|
||||
@ -90,6 +91,15 @@ export class BattlerTag {
|
||||
this.sourceMove = source.sourceMove;
|
||||
this.sourceId = source.sourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that retrieves the source Pokemon object
|
||||
* @param scene medium to retrieve the source Pokemon
|
||||
* @returns The source {@linkcode Pokemon} or `null` if none is found
|
||||
*/
|
||||
public getSourcePokemon(scene: BattleScene): Pokemon | null {
|
||||
return this.sourceId ? scene.getPokemonById(this.sourceId) : null;
|
||||
}
|
||||
}
|
||||
|
||||
export interface WeatherBattlerTag {
|
||||
@ -120,7 +130,7 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag {
|
||||
const phase = pokemon.scene.getCurrentPhase() as MovePhase;
|
||||
const move = phase.move;
|
||||
|
||||
if (this.isMoveRestricted(move.moveId)) {
|
||||
if (this.isMoveRestricted(move.moveId, pokemon)) {
|
||||
if (this.interruptedText(pokemon, move.moveId)) {
|
||||
pokemon.scene.queueMessage(this.interruptedText(pokemon, move.moveId));
|
||||
}
|
||||
@ -136,10 +146,11 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag {
|
||||
/**
|
||||
* Gets whether this tag is restricting a move.
|
||||
*
|
||||
* @param {Moves} move {@linkcode Moves} ID to check restriction for.
|
||||
* @returns {boolean} `true` if the move is restricted by this tag, otherwise `false`.
|
||||
* @param move - {@linkcode Moves} ID to check restriction for.
|
||||
* @param user - The {@linkcode Pokemon} involved
|
||||
* @returns `true` if the move is restricted by this tag, otherwise `false`.
|
||||
*/
|
||||
abstract isMoveRestricted(move: Moves): boolean;
|
||||
public abstract isMoveRestricted(move: Moves, user?: Pokemon): boolean;
|
||||
|
||||
/**
|
||||
* Checks if this tag is restricting a move based on a user's decisions during the target selection phase
|
||||
@ -327,6 +338,16 @@ export class GorillaTacticsTag extends MoveRestrictionBattlerTag {
|
||||
pokemon.setStat(Stat.ATK, pokemon.getStat(Stat.ATK, false) * 1.5, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Gorilla Tactics Battler Tag along with its unique class variable moveId
|
||||
* @override
|
||||
* @param source Gorilla Tactics' {@linkcode BattlerTag} information
|
||||
*/
|
||||
public override loadTag(source: BattlerTag | any): void {
|
||||
super.loadTag(source);
|
||||
this.moveId = source.moveId;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @override
|
||||
@ -1713,7 +1734,12 @@ export class TypeImmuneTag extends BattlerTag {
|
||||
}
|
||||
}
|
||||
|
||||
export class MagnetRisenTag extends TypeImmuneTag {
|
||||
/**
|
||||
* Battler Tag that lifts the affected Pokemon into the air and provides immunity to Ground type moves.
|
||||
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Magnet_Rise_(move) | Moves.MAGNET_RISE}
|
||||
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | Moves.TELEKINESIS}
|
||||
*/
|
||||
export class FloatingTag extends TypeImmuneTag {
|
||||
constructor(tagType: BattlerTagType, sourceMove: Moves) {
|
||||
super(tagType, sourceMove, Type.GROUND, 5);
|
||||
}
|
||||
@ -1721,13 +1747,17 @@ export class MagnetRisenTag extends TypeImmuneTag {
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
|
||||
pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||
if (this.sourceMove === Moves.MAGNET_RISE) {
|
||||
pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
|
||||
pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||
if (this.sourceMove === Moves.MAGNET_RISE) {
|
||||
pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2501,8 +2531,6 @@ export class MysteryEncounterPostSummonTag extends BattlerTag {
|
||||
* Torment does not interrupt the move if the move is performed consecutively in the same turn and right after Torment is applied
|
||||
*/
|
||||
export class TormentTag extends MoveRestrictionBattlerTag {
|
||||
private target: Pokemon;
|
||||
|
||||
constructor(sourceId: number) {
|
||||
super(BattlerTagType.TORMENT, BattlerTagLapseType.AFTER_MOVE, 1, Moves.TORMENT, sourceId);
|
||||
}
|
||||
@ -2514,7 +2542,6 @@ export class TormentTag extends MoveRestrictionBattlerTag {
|
||||
*/
|
||||
override onAdd(pokemon: Pokemon) {
|
||||
super.onAdd(pokemon);
|
||||
this.target = pokemon;
|
||||
pokemon.scene.queueMessage(i18next.t("battlerTags:tormentOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500);
|
||||
}
|
||||
|
||||
@ -2533,15 +2560,18 @@ export class TormentTag extends MoveRestrictionBattlerTag {
|
||||
* @param {Moves} move the move under investigation
|
||||
* @returns `true` if there is valid consecutive usage | `false` if the moves are different from each other
|
||||
*/
|
||||
override isMoveRestricted(move: Moves): boolean {
|
||||
const lastMove = this.target.getLastXMoves(1)[0];
|
||||
public override isMoveRestricted(move: Moves, user: Pokemon): boolean {
|
||||
if (!user) {
|
||||
return false;
|
||||
}
|
||||
const lastMove = user.getLastXMoves(1)[0];
|
||||
if ( !lastMove ) {
|
||||
return false;
|
||||
}
|
||||
// This checks for locking / momentum moves like Rollout and Hydro Cannon + if the user is under the influence of BattlerTagType.FRENZY
|
||||
// Because Uproar's unique behavior is not implemented, it does not check for Uproar. Torment has been marked as partial in moves.ts
|
||||
const moveObj = allMoves[lastMove.move];
|
||||
const isUnaffected = moveObj.hasAttr(ConsecutiveUseDoublePowerAttr) || this.target.getTag(BattlerTagType.FRENZY) || moveObj.hasAttr(ChargeAttr);
|
||||
const isUnaffected = moveObj.hasAttr(ConsecutiveUseDoublePowerAttr) || user.getTag(BattlerTagType.FRENZY) || moveObj.hasAttr(ChargeAttr);
|
||||
const validLastMoveResult = (lastMove.result === MoveResult.SUCCESS) || (lastMove.result === MoveResult.MISS);
|
||||
if (lastMove.move === move && validLastMoveResult && lastMove.move !== Moves.STRUGGLE && !isUnaffected) {
|
||||
return true;
|
||||
@ -2593,37 +2623,39 @@ export class TauntTag extends MoveRestrictionBattlerTag {
|
||||
* The tag is only removed when the source-user is removed from the field.
|
||||
*/
|
||||
export class ImprisonTag extends MoveRestrictionBattlerTag {
|
||||
private source: Pokemon | null;
|
||||
|
||||
constructor(sourceId: number) {
|
||||
super(BattlerTagType.IMPRISON, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 1, Moves.IMPRISON, sourceId);
|
||||
}
|
||||
|
||||
override onAdd(pokemon: Pokemon) {
|
||||
if (this.sourceId) {
|
||||
this.source = pokemon.scene.getPokemonById(this.sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the source of Imprison is still active
|
||||
* @param _pokemon
|
||||
* @param _lapseType
|
||||
* @override
|
||||
* @param pokemon The pokemon this tag is attached to
|
||||
* @returns `true` if the source is still active
|
||||
*/
|
||||
override lapse(_pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean {
|
||||
return this.source?.isActive(true) ?? false;
|
||||
public override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
const source = this.getSourcePokemon(pokemon.scene);
|
||||
if (source) {
|
||||
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
|
||||
return super.lapse(pokemon, lapseType) && source.isActive(true);
|
||||
} else {
|
||||
return source.isActive(true);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the source of the tag has the parameter move in its moveset and that the source is still active
|
||||
* @override
|
||||
* @param {Moves} move the move under investigation
|
||||
* @returns `false` if either condition is not met
|
||||
*/
|
||||
override isMoveRestricted(move: Moves): boolean {
|
||||
if (this.source) {
|
||||
const sourceMoveset = this.source.getMoveset().map(m => m!.moveId);
|
||||
return sourceMoveset?.includes(move) && this.source.isActive(true);
|
||||
public override isMoveRestricted(move: Moves, user: Pokemon): boolean {
|
||||
const source = this.getSourcePokemon(user.scene);
|
||||
if (source) {
|
||||
const sourceMoveset = source.getMoveset().map(m => m!.moveId);
|
||||
return sourceMoveset?.includes(move) && source.isActive(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -2676,6 +2708,22 @@ export class SyrupBombTag extends BattlerTag {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Telekinesis raises the target into the air for three turns and causes all moves used against the target (aside from OHKO moves) to hit the target unless the target is in a semi-invulnerable state from Fly/Dig.
|
||||
* The first effect is provided by {@linkcode FloatingTag}, the accuracy-bypass effect is provided by TelekinesisTag
|
||||
* The effects of Telekinesis can be baton passed to a teammate. Unlike the mainline games, Telekinesis can be baton-passed to Mega Gengar.
|
||||
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | Moves.TELEKINESIS}
|
||||
*/
|
||||
export class TelekinesisTag extends BattlerTag {
|
||||
constructor(sourceMove: Moves) {
|
||||
super(BattlerTagType.TELEKINESIS, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 3, sourceMove, undefined, true);
|
||||
}
|
||||
|
||||
override onAdd(pokemon: Pokemon) {
|
||||
pokemon.scene.queueMessage(i18next.t("battlerTags:telekinesisOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID.
|
||||
* @param sourceId - The ID of the pokemon adding the tag
|
||||
@ -2802,8 +2850,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
||||
return new CursedTag(sourceId);
|
||||
case BattlerTagType.CHARGED:
|
||||
return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true);
|
||||
case BattlerTagType.MAGNET_RISEN:
|
||||
return new MagnetRisenTag(tagType, sourceMove);
|
||||
case BattlerTagType.FLOATING:
|
||||
return new FloatingTag(tagType, sourceMove);
|
||||
case BattlerTagType.MINIMIZED:
|
||||
return new MinimizeTag();
|
||||
case BattlerTagType.DESTINY_BOND:
|
||||
@ -2849,6 +2897,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
||||
return new ImprisonTag(sourceId);
|
||||
case BattlerTagType.SYRUP_BOMB:
|
||||
return new SyrupBombTag(sourceId);
|
||||
case BattlerTagType.TELEKINESIS:
|
||||
return new TelekinesisTag(sourceMove);
|
||||
case BattlerTagType.NONE:
|
||||
default:
|
||||
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
||||
|
134
src/data/move.ts
@ -365,6 +365,14 @@ export default class Move implements Localizable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal dev flag for documenting edge cases. When using this, please document the known edge case.
|
||||
* @returns the called object {@linkcode Move}
|
||||
*/
|
||||
edgeCase(): this {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the move as "partial": appends texts to the move name
|
||||
* @returns the called object {@linkcode Move}
|
||||
@ -4556,18 +4564,19 @@ export class WaterSuperEffectTypeMultiplierAttr extends VariableMoveTypeMultipli
|
||||
export class IceNoEffectTypeAttr extends VariableMoveTypeMultiplierAttr {
|
||||
/**
|
||||
* Checks to see if the Target is Ice-Type or not. If so, the move will have no effect.
|
||||
* @param {Pokemon} user N/A
|
||||
* @param {Pokemon} target Pokemon that is being checked whether Ice-Type or not.
|
||||
* @param {Move} move N/A
|
||||
* @param {any[]} args Sets to false if the target is Ice-Type, so it should do no damage/no effect.
|
||||
* @returns {boolean} Returns true if move is successful, false if Ice-Type.
|
||||
* @param user n/a
|
||||
* @param target The {@linkcode Pokemon} targeted by the move
|
||||
* @param move n/a
|
||||
* @param args `[0]` a {@linkcode Utils.NumberHolder | NumberHolder} containing a type effectiveness multiplier
|
||||
* @returns `true` if this Ice-type immunity applies; `false` otherwise
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||
const multiplier = args[0] as Utils.NumberHolder;
|
||||
if (target.isOfType(Type.ICE)) {
|
||||
(args[0] as Utils.BooleanHolder).value = false;
|
||||
return false;
|
||||
multiplier.value = 0;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5475,37 +5484,38 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
||||
*/
|
||||
const switchOutTarget = this.selfSwitch ? user : target;
|
||||
if (switchOutTarget instanceof PlayerPokemon) {
|
||||
// Switch out logic for the player's Pokemon
|
||||
if (switchOutTarget.scene.getParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) {
|
||||
return false;
|
||||
}
|
||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||
|
||||
if (switchOutTarget.hp > 0) {
|
||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||
user.scene.prependToPhase(new SwitchPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(), true, true), MoveEndPhase);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if (user.scene.currentBattle.battleType !== BattleType.WILD) {
|
||||
// Switch out logic for trainer battles
|
||||
if (switchOutTarget.scene.getEnemyParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) {
|
||||
return false;
|
||||
}
|
||||
// Switch out logic for trainer battles
|
||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||
|
||||
if (switchOutTarget.hp > 0) {
|
||||
// for opponent switching out
|
||||
switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH);
|
||||
user.scene.prependToPhase(new SwitchSummonPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(),
|
||||
(user.scene.currentBattle.trainer ? user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot) : 0),
|
||||
false, false), MoveEndPhase);
|
||||
}
|
||||
} else {
|
||||
// Switch out logic for everything else (eg: WILD battles)
|
||||
if (user.scene.currentBattle.waveIndex % 10 === 0) {
|
||||
return false;
|
||||
}
|
||||
// Switch out logic for everything else (eg: WILD battles)
|
||||
switchOutTarget.leaveField(false);
|
||||
|
||||
if (switchOutTarget.hp) {
|
||||
if (switchOutTarget.hp > 0) {
|
||||
switchOutTarget.leaveField(false);
|
||||
user.scene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500);
|
||||
|
||||
// in double battles redirect potential moves off fled pokemon
|
||||
@ -7083,7 +7093,8 @@ export function initMoves() {
|
||||
.attr(ForceSwitchOutAttr)
|
||||
.ignoresSubstitute()
|
||||
.hidesTarget()
|
||||
.windMove(),
|
||||
.windMove()
|
||||
.partial(), // Should force random switches
|
||||
new AttackMove(Moves.FLY, Type.FLYING, MoveCategory.PHYSICAL, 90, 95, 15, -1, 0, 1)
|
||||
.attr(ChargeAttr, ChargeAnim.FLY_CHARGING, i18next.t("moveTriggers:flewUpHigh", { pokemonName: "{USER}" }), BattlerTagType.FLYING)
|
||||
.condition(failOnGravityCondition)
|
||||
@ -7160,7 +7171,8 @@ export function initMoves() {
|
||||
new StatusMove(Moves.ROAR, Type.NORMAL, -1, 20, -1, -6, 1)
|
||||
.attr(ForceSwitchOutAttr)
|
||||
.soundBased()
|
||||
.hidesTarget(),
|
||||
.hidesTarget()
|
||||
.partial(), // Should force random switching
|
||||
new StatusMove(Moves.SING, Type.NORMAL, 55, 15, -1, 0, 1)
|
||||
.attr(StatusEffectAttr, StatusEffect.SLEEP)
|
||||
.soundBased(),
|
||||
@ -7301,7 +7313,7 @@ export function initMoves() {
|
||||
.attr(StatStageChangeAttr, [ Stat.SPD ], 2, true),
|
||||
new AttackMove(Moves.QUICK_ATTACK, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 30, -1, 1, 1),
|
||||
new AttackMove(Moves.RAGE, Type.NORMAL, MoveCategory.PHYSICAL, 20, 100, 20, -1, 0, 1)
|
||||
.partial(),
|
||||
.partial(), // No effect implemented
|
||||
new SelfStatusMove(Moves.TELEPORT, Type.PSYCHIC, -1, 20, -1, -6, 1)
|
||||
.attr(ForceSwitchOutAttr, true)
|
||||
.hidesUser(),
|
||||
@ -7616,7 +7628,7 @@ export function initMoves() {
|
||||
new StatusMove(Moves.CHARM, Type.FAIRY, 100, 20, -1, 0, 2)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK ], -2),
|
||||
new AttackMove(Moves.ROLLOUT, Type.ROCK, MoveCategory.PHYSICAL, 30, 90, 20, -1, 0, 2)
|
||||
.partial()
|
||||
.partial() // Does not lock the user, also does not increase damage properly
|
||||
.attr(ConsecutiveUseDoublePowerAttr, 5, true, true, Moves.DEFENSE_CURL),
|
||||
new AttackMove(Moves.FALSE_SWIPE, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 40, -1, 0, 2)
|
||||
.attr(SurviveDamageAttr),
|
||||
@ -7687,7 +7699,7 @@ export function initMoves() {
|
||||
.ignoresSubstitute()
|
||||
.condition((user, target, move) => new EncoreTag(user.id).canAdd(target)),
|
||||
new AttackMove(Moves.PURSUIT, Type.DARK, MoveCategory.PHYSICAL, 40, 100, 20, -1, 0, 2)
|
||||
.partial(),
|
||||
.partial(), // No effect implemented
|
||||
new AttackMove(Moves.RAPID_SPIN, Type.NORMAL, MoveCategory.PHYSICAL, 50, 100, 40, 100, 0, 2)
|
||||
.attr(StatStageChangeAttr, [ Stat.SPD ], 1, true)
|
||||
.attr(RemoveBattlerTagAttr, [
|
||||
@ -7752,7 +7764,7 @@ export function initMoves() {
|
||||
.attr(StatStageChangeAttr, [ Stat.SPDEF ], -1)
|
||||
.ballBombMove(),
|
||||
new AttackMove(Moves.FUTURE_SIGHT, Type.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 2)
|
||||
.partial()
|
||||
.partial() // Complete buggy mess
|
||||
.attr(DelayedAttackAttr, ArenaTagType.FUTURE_SIGHT, ChargeAnim.FUTURE_SIGHT_CHARGING, i18next.t("moveTriggers:foresawAnAttack", { pokemonName: "{USER}" })),
|
||||
new AttackMove(Moves.ROCK_SMASH, Type.FIGHTING, MoveCategory.PHYSICAL, 40, 100, 15, 50, 0, 2)
|
||||
.attr(StatStageChangeAttr, [ Stat.DEF ], -1),
|
||||
@ -7770,7 +7782,7 @@ export function initMoves() {
|
||||
.ignoresVirtual()
|
||||
.soundBased()
|
||||
.target(MoveTarget.RANDOM_NEAR_ENEMY)
|
||||
.partial(),
|
||||
.partial(), // Does not lock the user, does not stop Pokemon from sleeping
|
||||
new SelfStatusMove(Moves.STOCKPILE, Type.NORMAL, -1, 20, -1, 0, 3)
|
||||
.condition(user => (user.getTag(StockpilingTag)?.stockpiledCount ?? 0) < 3)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.STOCKPILING, true),
|
||||
@ -7793,7 +7805,7 @@ export function initMoves() {
|
||||
.target(MoveTarget.BOTH_SIDES),
|
||||
new StatusMove(Moves.TORMENT, Type.DARK, 100, 15, -1, 0, 3)
|
||||
.ignoresSubstitute()
|
||||
.partial() // Incomplete implementation because of Uproar's partial implementation
|
||||
.edgeCase() // Incomplete implementation because of Uproar's partial implementation
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.TORMENT, false, true, 1),
|
||||
new StatusMove(Moves.FLATTER, Type.DARK, 100, 15, -1, 0, 3)
|
||||
.attr(StatStageChangeAttr, [ Stat.SPATK ], 1)
|
||||
@ -7842,7 +7854,9 @@ export function initMoves() {
|
||||
.attr(RandomMovesetMoveAttr, true)
|
||||
.ignoresVirtual(),
|
||||
new SelfStatusMove(Moves.INGRAIN, Type.GRASS, -1, 20, -1, 0, 3)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.INGRAIN, true, true),
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.INGRAIN, true, true)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, true, true)
|
||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.FLOATING ], true),
|
||||
new AttackMove(Moves.SUPERPOWER, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 3)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF ], -1, true),
|
||||
new SelfStatusMove(Moves.MAGIC_COAT, Type.PSYCHIC, -1, 15, -1, 4, 3)
|
||||
@ -7870,7 +7884,8 @@ export function initMoves() {
|
||||
.attr(SwitchAbilitiesAttr),
|
||||
new StatusMove(Moves.IMPRISON, Type.PSYCHIC, 100, 10, -1, 0, 3)
|
||||
.ignoresSubstitute()
|
||||
.attr(AddArenaTagAttr, ArenaTagType.IMPRISON, 1, true, false),
|
||||
.attr(AddArenaTagAttr, ArenaTagType.IMPRISON, 1, true, false)
|
||||
.target(MoveTarget.ENEMY_SIDE),
|
||||
new SelfStatusMove(Moves.REFRESH, Type.NORMAL, -1, 20, -1, 0, 3)
|
||||
.attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN)
|
||||
.condition((user, target, move) => !!user.status && (user.status.effect === StatusEffect.PARALYSIS || user.status.effect === StatusEffect.POISON || user.status.effect === StatusEffect.TOXIC || user.status.effect === StatusEffect.BURN)),
|
||||
@ -7880,7 +7895,7 @@ export function initMoves() {
|
||||
.unimplemented(),
|
||||
new AttackMove(Moves.SECRET_POWER, Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, 30, 0, 3)
|
||||
.makesContact(false)
|
||||
.partial(),
|
||||
.partial(), // No effect implemented
|
||||
new AttackMove(Moves.DIVE, Type.WATER, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 3)
|
||||
.attr(ChargeAttr, ChargeAnim.DIVE_CHARGING, i18next.t("moveTriggers:hidUnderwater", { pokemonName: "{USER}" }), BattlerTagType.UNDERWATER, true)
|
||||
.attr(GulpMissileTagAttr)
|
||||
@ -7911,7 +7926,7 @@ export function initMoves() {
|
||||
.attr(AddArenaTagAttr, ArenaTagType.MUD_SPORT, 5)
|
||||
.target(MoveTarget.BOTH_SIDES),
|
||||
new AttackMove(Moves.ICE_BALL, Type.ICE, MoveCategory.PHYSICAL, 30, 90, 20, -1, 0, 3)
|
||||
.partial()
|
||||
.partial() // Does not lock the user properly, does not increase damage correctly
|
||||
.attr(ConsecutiveUseDoublePowerAttr, 5, true, true, Moves.DEFENSE_CURL)
|
||||
.ballBombMove(),
|
||||
new AttackMove(Moves.NEEDLE_ARM, Type.GRASS, MoveCategory.PHYSICAL, 60, 100, 15, 30, 0, 3)
|
||||
@ -8054,7 +8069,7 @@ export function initMoves() {
|
||||
.attr(ConfuseAttr)
|
||||
.pulseMove(),
|
||||
new AttackMove(Moves.DOOM_DESIRE, Type.STEEL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 3)
|
||||
.partial()
|
||||
.partial() // Complete buggy mess
|
||||
.attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, i18next.t("moveTriggers:choseDoomDesireAsDestiny", { pokemonName: "{USER}" })),
|
||||
new AttackMove(Moves.PSYCHO_BOOST, Type.PSYCHIC, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 3)
|
||||
.attr(StatStageChangeAttr, [ Stat.SPATK ], -2, true),
|
||||
@ -8176,8 +8191,8 @@ export function initMoves() {
|
||||
new SelfStatusMove(Moves.AQUA_RING, Type.WATER, -1, 20, -1, 0, 4)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true),
|
||||
new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.MAGNET_RISEN, true, true)
|
||||
.condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) && [ BattlerTagType.MAGNET_RISEN, BattlerTagType.IGNORE_FLYING, BattlerTagType.INGRAIN ].every((tag) => !user.getTag(tag))),
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.FLOATING, true, true)
|
||||
.condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) && [ BattlerTagType.FLOATING, BattlerTagType.IGNORE_FLYING, BattlerTagType.INGRAIN ].every((tag) => !user.getTag(tag))),
|
||||
new AttackMove(Moves.FLARE_BLITZ, Type.FIRE, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 4)
|
||||
.attr(RecoilAttr, false, 0.33)
|
||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||
@ -8402,7 +8417,11 @@ export function initMoves() {
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.CENTER_OF_ATTENTION, true),
|
||||
new StatusMove(Moves.TELEKINESIS, Type.PSYCHIC, -1, 15, -1, 0, 5)
|
||||
.condition(failOnGravityCondition)
|
||||
.unimplemented(),
|
||||
.condition((_user, target, _move) => ![ Species.DIGLETT, Species.DUGTRIO, Species.ALOLA_DIGLETT, Species.ALOLA_DUGTRIO, Species.SANDYGAST, Species.PALOSSAND, Species.WIGLETT, Species.WUGTRIO ].includes(target.species.speciesId))
|
||||
.condition((_user, target, _move) => !(target.species.speciesId === Species.GENGAR && target.getFormKey() === "mega"))
|
||||
.condition((_user, target, _move) => Utils.isNullOrUndefined(target.getTag(BattlerTagType.INGRAIN)) && Utils.isNullOrUndefined(target.getTag(BattlerTagType.IGNORE_FLYING)))
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.TELEKINESIS, false, true, 3)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.FLOATING, false, true, 3),
|
||||
new StatusMove(Moves.MAGIC_ROOM, Type.PSYCHIC, -1, 10, -1, 0, 5)
|
||||
.ignoresProtect()
|
||||
.target(MoveTarget.BOTH_SIDES)
|
||||
@ -8410,7 +8429,7 @@ export function initMoves() {
|
||||
new AttackMove(Moves.SMACK_DOWN, Type.ROCK, MoveCategory.PHYSICAL, 50, 100, 15, 100, 0, 5)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
|
||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN ])
|
||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ])
|
||||
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
||||
.makesContact(false),
|
||||
new AttackMove(Moves.STORM_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5)
|
||||
@ -8460,7 +8479,7 @@ export function initMoves() {
|
||||
.attr(AfterYouAttr),
|
||||
new AttackMove(Moves.ROUND, Type.NORMAL, MoveCategory.SPECIAL, 60, 100, 15, -1, 0, 5)
|
||||
.soundBased()
|
||||
.partial(),
|
||||
.partial(), // No effect implemented
|
||||
new AttackMove(Moves.ECHOED_VOICE, Type.NORMAL, MoveCategory.SPECIAL, 40, 100, 15, -1, 0, 5)
|
||||
.attr(ConsecutiveUseMultiBasePowerAttr, 5, false)
|
||||
.soundBased(),
|
||||
@ -8502,7 +8521,8 @@ export function initMoves() {
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK ], 1, true)
|
||||
.attr(StatStageChangeAttr, [ Stat.SPD ], 2, true),
|
||||
new AttackMove(Moves.CIRCLE_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 90, 10, -1, -6, 5)
|
||||
.attr(ForceSwitchOutAttr),
|
||||
.attr(ForceSwitchOutAttr)
|
||||
.partial(), // Should force random switches
|
||||
new AttackMove(Moves.INCINERATE, Type.FIRE, MoveCategory.SPECIAL, 60, 100, 15, -1, 0, 5)
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
||||
.attr(RemoveHeldItemAttr, true),
|
||||
@ -8570,7 +8590,8 @@ export function initMoves() {
|
||||
.attr(CritOnlyAttr),
|
||||
new AttackMove(Moves.DRAGON_TAIL, Type.DRAGON, MoveCategory.PHYSICAL, 60, 90, 10, -1, -6, 5)
|
||||
.attr(ForceSwitchOutAttr)
|
||||
.hidesTarget(),
|
||||
.hidesTarget()
|
||||
.partial(), // Should force random switches
|
||||
new SelfStatusMove(Moves.WORK_UP, Type.NORMAL, -1, 30, -1, 0, 5)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], 1, true),
|
||||
new AttackMove(Moves.ELECTROWEB, Type.ELECTRIC, MoveCategory.SPECIAL, 55, 95, 15, 100, 0, 5)
|
||||
@ -8698,7 +8719,7 @@ export function initMoves() {
|
||||
.ignoresVirtual(),
|
||||
new StatusMove(Moves.TRICK_OR_TREAT, Type.GHOST, 100, 20, -1, 0, 6)
|
||||
.attr(AddTypeAttr, Type.GHOST)
|
||||
.partial(),
|
||||
.edgeCase(), // Weird interaction with Forest's Curse, reflect type, burn up
|
||||
new StatusMove(Moves.NOBLE_ROAR, Type.NORMAL, 100, 30, -1, 0, 6)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1)
|
||||
.soundBased(),
|
||||
@ -8711,7 +8732,7 @@ export function initMoves() {
|
||||
.triageMove(),
|
||||
new StatusMove(Moves.FORESTS_CURSE, Type.GRASS, 100, 20, -1, 0, 6)
|
||||
.attr(AddTypeAttr, Type.GRASS)
|
||||
.partial(),
|
||||
.edgeCase(), // Weird interaction with Trick or Treat, reflect type, burn up
|
||||
new AttackMove(Moves.PETAL_BLIZZARD, Type.GRASS, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 6)
|
||||
.windMove()
|
||||
.makesContact(false)
|
||||
@ -8719,7 +8740,7 @@ export function initMoves() {
|
||||
new AttackMove(Moves.FREEZE_DRY, Type.ICE, MoveCategory.SPECIAL, 70, 100, 20, 10, 0, 6)
|
||||
.attr(StatusEffectAttr, StatusEffect.FREEZE)
|
||||
.attr(WaterSuperEffectTypeMultiplierAttr)
|
||||
.partial(), // This currently just multiplies the move's power instead of changing its effectiveness. It also doesn't account for abilities that modify type effectiveness such as tera shell.
|
||||
.edgeCase(), // This currently just multiplies the move's power instead of changing its effectiveness. It also doesn't account for abilities that modify type effectiveness such as tera shell.
|
||||
new AttackMove(Moves.DISARMING_VOICE, Type.FAIRY, MoveCategory.SPECIAL, 40, -1, 15, -1, 0, 6)
|
||||
.soundBased()
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||
@ -8843,9 +8864,9 @@ export function initMoves() {
|
||||
.attr(NeutralDamageAgainstFlyingTypeMultiplierAttr)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true)
|
||||
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
||||
.attr(HitsTagAttr, BattlerTagType.MAGNET_RISEN)
|
||||
.attr(HitsTagAttr, BattlerTagType.FLOATING)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
|
||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN ])
|
||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ])
|
||||
.makesContact(false)
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||
new AttackMove(Moves.THOUSAND_WAVES, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6)
|
||||
@ -9097,15 +9118,15 @@ export function initMoves() {
|
||||
/* Unused */
|
||||
new AttackMove(Moves.SINISTER_ARROW_RAID, Type.GHOST, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7)
|
||||
.makesContact(false)
|
||||
.partial()
|
||||
.edgeCase() // I assume it's because the user needs spirit shackle and decidueye
|
||||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.MALICIOUS_MOONSAULT, Type.DARK, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7)
|
||||
.attr(AlwaysHitMinimizeAttr)
|
||||
.attr(HitsTagAttr, BattlerTagType.MINIMIZED, true)
|
||||
.partial()
|
||||
.edgeCase() // I assume it's because it needs darkest lariat and incineroar
|
||||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.OCEANIC_OPERETTA, Type.WATER, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
|
||||
.partial()
|
||||
.edgeCase() // I assume it's because it needs sparkling aria and primarina
|
||||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.GUARDIAN_OF_ALOLA, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7)
|
||||
.unimplemented()
|
||||
@ -9114,10 +9135,10 @@ export function initMoves() {
|
||||
.unimplemented()
|
||||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.STOKED_SPARKSURFER, Type.ELECTRIC, MoveCategory.SPECIAL, 175, -1, 1, 100, 0, 7)
|
||||
.partial()
|
||||
.edgeCase() // I assume it's because it needs thunderbolt and Alola Raichu
|
||||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.PULVERIZING_PANCAKE, Type.NORMAL, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7)
|
||||
.partial()
|
||||
.edgeCase() // I assume it's because it needs giga impact and snorlax
|
||||
.ignoresVirtual(),
|
||||
new SelfStatusMove(Moves.EXTREME_EVOBOOST, Type.NORMAL, -1, 1, -1, 0, 7)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 2, true)
|
||||
@ -9148,13 +9169,13 @@ export function initMoves() {
|
||||
.attr(RechargeAttr),
|
||||
new AttackMove(Moves.SPECTRAL_THIEF, Type.GHOST, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 7)
|
||||
.ignoresSubstitute()
|
||||
.partial(),
|
||||
.partial(), // Does not steal stats
|
||||
new AttackMove(Moves.SUNSTEEL_STRIKE, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 7)
|
||||
.ignoresAbilities()
|
||||
.partial(),
|
||||
.edgeCase(), // Should not ignore abilities when called virtually (metronome)
|
||||
new AttackMove(Moves.MOONGEIST_BEAM, Type.GHOST, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7)
|
||||
.ignoresAbilities()
|
||||
.partial(),
|
||||
.edgeCase(), // Should not ignore abilities when called virtually (metronome)
|
||||
new StatusMove(Moves.TEARFUL_LOOK, Type.NORMAL, -1, 20, -1, 0, 7)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1),
|
||||
new AttackMove(Moves.ZING_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 30, 0, 7)
|
||||
@ -9165,7 +9186,7 @@ export function initMoves() {
|
||||
.attr(FormChangeItemTypeAttr),
|
||||
/* Unused */
|
||||
new AttackMove(Moves.TEN_MILLION_VOLT_THUNDERBOLT, Type.ELECTRIC, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7)
|
||||
.partial()
|
||||
.edgeCase() // I assume it's because it needs thunderbolt and pikachu in a cap
|
||||
.ignoresVirtual(),
|
||||
/* End Unused */
|
||||
new AttackMove(Moves.MIND_BLOWN, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 7)
|
||||
@ -9178,7 +9199,7 @@ export function initMoves() {
|
||||
new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7)
|
||||
.attr(PhotonGeyserCategoryAttr)
|
||||
.ignoresAbilities()
|
||||
.partial(),
|
||||
.edgeCase(), // Should not ignore abilities when called virtually (metronome)
|
||||
/* Unused */
|
||||
new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
|
||||
.attr(PhotonGeyserCategoryAttr)
|
||||
@ -9191,7 +9212,7 @@ export function initMoves() {
|
||||
.ignoresAbilities()
|
||||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.LETS_SNUGGLE_FOREVER, Type.FAIRY, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
|
||||
.partial()
|
||||
.edgeCase() // I assume it needs play rough and mimikyu
|
||||
.ignoresVirtual(),
|
||||
new AttackMove(Moves.SPLINTERED_STORMSHARDS, Type.ROCK, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7)
|
||||
.attr(ClearTerrainAttr)
|
||||
@ -9201,7 +9222,7 @@ export function initMoves() {
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true, undefined, undefined, undefined, undefined, true)
|
||||
.soundBased()
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES)
|
||||
.partial()
|
||||
.edgeCase() // I assume it needs clanging scales and Kommo-O
|
||||
.ignoresVirtual(),
|
||||
/* End Unused */
|
||||
new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 50, 100, 15, -1, 2, 7) //LGPE Implementation
|
||||
@ -9264,14 +9285,14 @@ export function initMoves() {
|
||||
new AttackMove(Moves.JAW_LOCK, Type.DARK, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 8)
|
||||
.attr(JawLockAttr)
|
||||
.bitingMove(),
|
||||
new SelfStatusMove(Moves.STUFF_CHEEKS, Type.NORMAL, -1, 10, -1, 0, 8) // TODO: Stuff Cheeks should not be selectable when the user does not have a berry, see wiki
|
||||
new SelfStatusMove(Moves.STUFF_CHEEKS, Type.NORMAL, -1, 10, -1, 0, 8)
|
||||
.attr(EatBerryAttr)
|
||||
.attr(StatStageChangeAttr, [ Stat.DEF ], 2, true)
|
||||
.condition((user) => {
|
||||
const userBerries = user.scene.findModifiers(m => m instanceof BerryModifier, user.isPlayer());
|
||||
return userBerries.length > 0;
|
||||
})
|
||||
.partial(),
|
||||
.edgeCase(), // Stuff Cheeks should not be selectable when the user does not have a berry, see wiki
|
||||
new SelfStatusMove(Moves.NO_RETREAT, Type.FIGHTING, -1, 5, -1, 0, 8)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.NO_RETREAT, true, false)
|
||||
@ -9285,7 +9306,7 @@ export function initMoves() {
|
||||
new AttackMove(Moves.DRAGON_DARTS, Type.DRAGON, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 8)
|
||||
.attr(MultiHitAttr, MultiHitType._2)
|
||||
.makesContact(false)
|
||||
.partial(),
|
||||
.partial(), // smart targetting is unimplemented
|
||||
new StatusMove(Moves.TEATIME, Type.NORMAL, -1, 10, -1, 0, 8)
|
||||
.attr(EatBerryAttr)
|
||||
.target(MoveTarget.ALL),
|
||||
@ -9724,7 +9745,7 @@ export function initMoves() {
|
||||
.attr(StatStageChangeAttr, [ Stat.SPDEF ], -2),
|
||||
new AttackMove(Moves.ORDER_UP, Type.DRAGON, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 9)
|
||||
.makesContact(false)
|
||||
.partial(),
|
||||
.partial(), // No effect implemented (requires Commander)
|
||||
new AttackMove(Moves.JET_PUNCH, Type.WATER, MoveCategory.PHYSICAL, 60, 100, 15, -1, 1, 9)
|
||||
.punchingMove(),
|
||||
new StatusMove(Moves.SPICY_EXTRACT, Type.GRASS, -1, 15, -1, 0, 9)
|
||||
@ -9936,8 +9957,7 @@ export function initMoves() {
|
||||
new AttackMove(Moves.UPPER_HAND, Type.FIGHTING, MoveCategory.PHYSICAL, 65, 100, 15, 100, 3, 9)
|
||||
.attr(FlinchAttr)
|
||||
.condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].category !== MoveCategory.STATUS && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].priority > 0 ) // TODO: is this bang correct?
|
||||
//TODO: Should also apply when target move priority increased by ability ex. gale wings
|
||||
.partial(),
|
||||
.partial(), // Should also apply when target move priority increased by ability ex. gale wings
|
||||
new AttackMove(Moves.MALIGNANT_CHAIN, Type.POISON, MoveCategory.SPECIAL, 100, 100, 5, 50, 0, 9)
|
||||
.attr(StatusEffectAttr, StatusEffect.TOXIC)
|
||||
);
|
||||
|
@ -975,7 +975,7 @@ export function initSpecies() {
|
||||
new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true,
|
||||
new PokemonForm("Normal", "", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, true, null, true),
|
||||
new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GRASS, Type.POISON, 2.4, 155.5, Abilities.THICK_FAT, Abilities.THICK_FAT, Abilities.THICK_FAT, 625, 80, 100, 123, 122, 120, 80, 45, 50, 263, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.NONE, Abilities.EFFECT_SPORE, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true),
|
||||
),
|
||||
new PokemonSpecies(Species.CHARMANDER, 1, false, false, false, "Lizard Pokémon", Type.FIRE, null, 0.6, 8.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 309, 39, 52, 43, 60, 50, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
new PokemonSpecies(Species.CHARMELEON, 1, false, false, false, "Flame Pokémon", Type.FIRE, null, 1.1, 19, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 405, 58, 64, 58, 80, 65, 80, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
@ -983,20 +983,20 @@ export function initSpecies() {
|
||||
new PokemonForm("Normal", "", Type.FIRE, Type.FLYING, 1.7, 90.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 534, 78, 84, 78, 109, 85, 100, 45, 50, 267, false, null, true),
|
||||
new PokemonForm("Mega X", SpeciesFormKey.MEGA_X, Type.FIRE, Type.DRAGON, 1.7, 110.5, Abilities.TOUGH_CLAWS, Abilities.NONE, Abilities.TOUGH_CLAWS, 634, 78, 130, 111, 130, 85, 100, 45, 50, 267),
|
||||
new PokemonForm("Mega Y", SpeciesFormKey.MEGA_Y, Type.FIRE, Type.FLYING, 1.7, 100.5, Abilities.DROUGHT, Abilities.NONE, Abilities.DROUGHT, 634, 78, 104, 78, 159, 115, 100, 45, 50, 267),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.FLYING, 28, 999.9, Abilities.BERSERK, Abilities.BERSERK, Abilities.BERSERK, 634, 118, 84, 93, 139, 110, 100, 45, 50, 267),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.FLYING, 28, 999.9, Abilities.BERSERK, Abilities.NONE, Abilities.BERSERK, 634, 118, 84, 93, 139, 100, 100, 45, 50, 267),
|
||||
),
|
||||
new PokemonSpecies(Species.SQUIRTLE, 1, false, false, false, "Tiny Turtle Pokémon", Type.WATER, null, 0.5, 9, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 314, 44, 48, 65, 50, 64, 43, 45, 50, 63, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
new PokemonSpecies(Species.WARTORTLE, 1, false, false, false, "Turtle Pokémon", Type.WATER, null, 1, 22.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 405, 59, 63, 80, 65, 80, 58, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
new PokemonSpecies(Species.BLASTOISE, 1, false, false, false, "Shellfish Pokémon", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true,
|
||||
new PokemonForm("Normal", "", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, false, null, true),
|
||||
new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.WATER, null, 1.6, 101.1, Abilities.MEGA_LAUNCHER, Abilities.NONE, Abilities.MEGA_LAUNCHER, 630, 79, 103, 120, 135, 115, 78, 45, 50, 265),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 630, 119, 83, 135, 115, 110, 68, 45, 50, 265),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.NONE, Abilities.SHELL_ARMOR, 630, 119, 83, 135, 115, 110, 68, 45, 50, 265),
|
||||
),
|
||||
new PokemonSpecies(Species.CATERPIE, 1, false, false, false, "Worm Pokémon", Type.BUG, null, 0.3, 2.9, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 45, 30, 35, 20, 20, 45, 255, 50, 39, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.METAPOD, 1, false, false, false, "Cocoon Pokémon", Type.BUG, null, 0.7, 9.9, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.BUTTERFREE, 1, false, false, false, "Butterfly Pokémon", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, GrowthRate.MEDIUM_FAST, 50, true, true,
|
||||
new PokemonForm("Normal", "", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, true, null, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 999.9, Abilities.COMPOUND_EYES, Abilities.COMPOUND_EYES, Abilities.COMPOUND_EYES, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 999.9, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.COMPOUND_EYES, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true),
|
||||
),
|
||||
new PokemonSpecies(Species.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", Type.BUG, Type.POISON, 0.3, 3.2, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 40, 35, 30, 20, 20, 50, 255, 70, 39, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.KAKUNA, 1, false, false, false, "Cocoon Pokémon", Type.BUG, Type.POISON, 0.6, 10, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 45, 25, 50, 25, 25, 35, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
@ -1025,7 +1025,7 @@ export function initSpecies() {
|
||||
new PokemonForm("Cute Cosplay", "cute-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom
|
||||
new PokemonForm("Smart Cosplay", "smart-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom
|
||||
new PokemonForm("Tough Cosplay", "tough-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, null, 21, 999.9, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, 530, 125, 95, 60, 90, 70, 90, 190, 50, 112), //+100 BST from Partner Form
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, null, 21, 999.9, Abilities.LIGHTNING_ROD, Abilities.NONE, Abilities.LIGHTNING_ROD, 530, 125, 95, 60, 90, 70, 90, 190, 50, 112), //+100 BST from Partner Form
|
||||
),
|
||||
new PokemonSpecies(Species.RAICHU, 1, false, false, false, "Mouse Pokémon", Type.ELECTRIC, null, 0.8, 30, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 485, 60, 90, 55, 90, 80, 110, 75, 50, 243, GrowthRate.MEDIUM_FAST, 50, true),
|
||||
new PokemonSpecies(Species.SANDSHREW, 1, false, false, false, "Mouse Pokémon", Type.GROUND, null, 0.6, 12, Abilities.SAND_VEIL, Abilities.NONE, Abilities.SAND_RUSH, 300, 50, 75, 85, 20, 30, 40, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
@ -1110,7 +1110,7 @@ export function initSpecies() {
|
||||
new PokemonSpecies(Species.GENGAR, 1, false, false, false, "Shadow Pokémon", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false, true,
|
||||
new PokemonForm("Normal", "", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, false, null, true),
|
||||
new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GHOST, Type.POISON, 1.4, 40.5, Abilities.SHADOW_TAG, Abilities.NONE, Abilities.NONE, 600, 60, 65, 80, 170, 95, 130, 45, 50, 250),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GHOST, Type.POISON, 20, 999.9, Abilities.CURSED_BODY, Abilities.CURSED_BODY, Abilities.CURSED_BODY, 600, 140, 65, 70, 140, 85, 100, 45, 50, 250),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GHOST, Type.POISON, 20, 999.9, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 600, 140, 65, 70, 140, 85, 100, 45, 50, 250),
|
||||
),
|
||||
new PokemonSpecies(Species.ONIX, 1, false, false, false, "Rock Snake Pokémon", Type.ROCK, Type.GROUND, 8.8, 210, Abilities.ROCK_HEAD, Abilities.STURDY, Abilities.WEAK_ARMOR, 385, 35, 45, 160, 30, 45, 70, 45, 50, 77, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.DROWZEE, 1, false, false, false, "Hypnosis Pokémon", Type.PSYCHIC, null, 1, 32.4, Abilities.INSOMNIA, Abilities.FOREWARN, Abilities.INNER_FOCUS, 328, 60, 48, 45, 43, 90, 42, 190, 70, 66, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
@ -1118,7 +1118,7 @@ export function initSpecies() {
|
||||
new PokemonSpecies(Species.KRABBY, 1, false, false, false, "River Crab Pokémon", Type.WATER, null, 0.4, 6.5, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 325, 30, 105, 90, 25, 25, 50, 225, 50, 65, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.KINGLER, 1, false, false, false, "Pincer Pokémon", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true,
|
||||
new PokemonForm("Normal", "", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, false, null, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 19, 999.9, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, 575, 90, 155, 140, 50, 80, 70, 60, 50, 166),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 19, 999.9, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, 575, 90, 155, 140, 50, 70, 70, 60, 50, 166),
|
||||
),
|
||||
new PokemonSpecies(Species.VOLTORB, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 0.5, 10.4, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 330, 40, 30, 50, 55, 55, 100, 190, 70, 66, GrowthRate.MEDIUM_FAST, null, false),
|
||||
new PokemonSpecies(Species.ELECTRODE, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 1.2, 66.6, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 490, 60, 50, 70, 80, 80, 150, 60, 70, 172, GrowthRate.MEDIUM_FAST, null, false),
|
||||
@ -2298,25 +2298,25 @@ export function initSpecies() {
|
||||
new PokemonSpecies(Species.MELTAN, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 0.2, 8, Abilities.MAGNET_PULL, Abilities.NONE, Abilities.NONE, 300, 46, 65, 65, 55, 35, 34, 3, 0, 150, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(Species.MELMETAL, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, GrowthRate.SLOW, null, false, true,
|
||||
new PokemonForm("Normal", "", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, false, null, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, null, 25, 999.9, Abilities.IRON_FIST, Abilities.IRON_FIST, Abilities.IRON_FIST, 700, 175, 165, 155, 85, 75, 45, 3, 0, 300),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, null, 25, 999.9, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 700, 175, 165, 155, 85, 75, 45, 3, 0, 300),
|
||||
),
|
||||
new PokemonSpecies(Species.GROOKEY, 8, false, false, false, "Chimp Pokémon", Type.GRASS, null, 0.3, 5, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 310, 50, 65, 50, 40, 40, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
new PokemonSpecies(Species.THWACKEY, 8, false, false, false, "Beat Pokémon", Type.GRASS, null, 0.7, 14, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 420, 70, 85, 70, 55, 60, 80, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
new PokemonSpecies(Species.RILLABOOM, 8, false, false, false, "Drummer Pokémon", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true,
|
||||
new PokemonForm("Normal", "", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, false, null, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, null, 28, 999.9, Abilities.GRASSY_SURGE, Abilities.GRASSY_SURGE, Abilities.GRASSY_SURGE, 630, 125, 150, 105, 85, 85, 80, 45, 50, 265),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, null, 28, 999.9, Abilities.GRASSY_SURGE, Abilities.NONE, Abilities.GRASSY_SURGE, 630, 125, 150, 105, 85, 85, 80, 45, 50, 265),
|
||||
),
|
||||
new PokemonSpecies(Species.SCORBUNNY, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.3, 4.5, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 310, 50, 71, 40, 40, 40, 69, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
new PokemonSpecies(Species.RABOOT, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.6, 9, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 420, 65, 86, 60, 55, 60, 94, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
new PokemonSpecies(Species.CINDERACE, 8, false, false, false, "Striker Pokémon", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true,
|
||||
new PokemonForm("Normal", "", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, false, null, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, null, 27, 999.9, Abilities.LIBERO, Abilities.LIBERO, Abilities.LIBERO, 630, 100, 146, 80, 90, 80, 134, 45, 50, 265),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, null, 27, 999.9, Abilities.LIBERO, Abilities.NONE, Abilities.LIBERO, 630, 100, 146, 80, 90, 80, 134, 45, 50, 265),
|
||||
),
|
||||
new PokemonSpecies(Species.SOBBLE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.3, 4, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 310, 50, 40, 40, 70, 40, 70, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
new PokemonSpecies(Species.DRIZZILE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.7, 11.5, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 420, 65, 60, 55, 95, 55, 90, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false),
|
||||
new PokemonSpecies(Species.INTELEON, 8, false, false, false, "Secret Agent Pokémon", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true,
|
||||
new PokemonForm("Normal", "", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, false, null, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 40, 999.9, Abilities.SNIPER, Abilities.SNIPER, Abilities.SNIPER, 630, 95, 97, 77, 147, 77, 137, 45, 50, 265),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 40, 999.9, Abilities.SNIPER, Abilities.NONE, Abilities.SNIPER, 630, 95, 97, 77, 147, 77, 137, 45, 50, 265),
|
||||
),
|
||||
new PokemonSpecies(Species.SKWOVET, 8, false, false, false, "Cheeky Pokémon", Type.NORMAL, null, 0.3, 2.5, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 275, 70, 55, 55, 35, 35, 25, 255, 50, 55, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.GREEDENT, 8, false, false, false, "Greedy Pokémon", Type.NORMAL, null, 0.6, 6, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 460, 120, 95, 95, 55, 75, 20, 90, 50, 161, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
@ -2422,7 +2422,7 @@ export function initSpecies() {
|
||||
new PokemonForm("Ruby Swirl", "ruby-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true),
|
||||
new PokemonForm("Caramel Swirl", "caramel-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true),
|
||||
new PokemonForm("Rainbow Swirl", "rainbow-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FAIRY, null, 30, 999.9, Abilities.MISTY_SURGE, Abilities.MISTY_SURGE, Abilities.MISTY_SURGE, 595, 135, 60, 75, 130, 131, 64, 100, 50, 173),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FAIRY, null, 30, 999.9, Abilities.MISTY_SURGE, Abilities.NONE, Abilities.MISTY_SURGE, 595, 135, 60, 75, 130, 131, 64, 100, 50, 173),
|
||||
),
|
||||
new PokemonSpecies(Species.FALINKS, 8, false, false, false, "Formation Pokémon", Type.FIGHTING, null, 3, 62, Abilities.BATTLE_ARMOR, Abilities.NONE, Abilities.DEFIANT, 470, 65, 100, 100, 70, 60, 75, 45, 50, 165, GrowthRate.MEDIUM_FAST, null, false),
|
||||
new PokemonSpecies(Species.PINCURCHIN, 8, false, false, false, "Sea Urchin Pokémon", Type.ELECTRIC, null, 0.3, 1, Abilities.LIGHTNING_ROD, Abilities.NONE, Abilities.ELECTRIC_SURGE, 435, 48, 101, 95, 91, 85, 15, 75, 50, 152, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
@ -2444,7 +2444,7 @@ export function initSpecies() {
|
||||
new PokemonSpecies(Species.CUFANT, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 1.2, 100, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 330, 72, 80, 49, 40, 49, 40, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false),
|
||||
new PokemonSpecies(Species.COPPERAJAH, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, true,
|
||||
new PokemonForm("Normal", "", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, false, null, true),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, Type.GROUND, 23, 999.9, Abilities.MOLD_BREAKER, Abilities.MOLD_BREAKER, Abilities.MOLD_BREAKER, 600, 167, 155, 89, 80, 89, 20, 90, 50, 175),
|
||||
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, Type.GROUND, 23, 999.9, Abilities.MOLD_BREAKER, Abilities.NONE, Abilities.MOLD_BREAKER, 600, 167, 155, 89, 80, 89, 20, 90, 50, 175),
|
||||
),
|
||||
new PokemonSpecies(Species.DRACOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.DRAGON, 1.8, 190, Abilities.VOLT_ABSORB, Abilities.HUSTLE, Abilities.SAND_RUSH, 505, 90, 100, 90, 80, 70, 75, 45, 50, 177, GrowthRate.SLOW, null, false),
|
||||
new PokemonSpecies(Species.ARCTOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.ICE, 2.3, 150, Abilities.VOLT_ABSORB, Abilities.STATIC, Abilities.SLUSH_RUSH, 505, 90, 100, 90, 90, 80, 55, 45, 50, 177, GrowthRate.SLOW, null, false),
|
||||
|
@ -54,7 +54,7 @@ export enum BattlerTagType {
|
||||
CURSED = "CURSED",
|
||||
CHARGED = "CHARGED",
|
||||
ROOSTED = "ROOSTED",
|
||||
MAGNET_RISEN = "MAGNET_RISEN",
|
||||
FLOATING = "FLOATING",
|
||||
MINIMIZED = "MINIMIZED",
|
||||
DESTINY_BOND = "DESTINY_BOND",
|
||||
CENTER_OF_ATTENTION = "CENTER_OF_ATTENTION",
|
||||
@ -86,4 +86,5 @@ export enum BattlerTagType {
|
||||
IMPRISON = "IMPRISON",
|
||||
SYRUP_BOMB = "SYRUP_BOMB",
|
||||
ELECTRIFIED = "ELECTRIFIED",
|
||||
TELEKINESIS = "TELEKINESIS"
|
||||
}
|
||||
|
@ -749,9 +749,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
const relX = newOffset[0] - initialOffset[0];
|
||||
const relY = newOffset[1] - initialOffset[1];
|
||||
|
||||
const subTag = this.getTag(SubstituteTag);
|
||||
|
||||
if (duration) {
|
||||
// TODO: can this use stricter typing?
|
||||
const targets: any[] = [ this ];
|
||||
if (subTag?.sprite) {
|
||||
targets.push(subTag.sprite);
|
||||
}
|
||||
this.scene.tweens.add({
|
||||
targets: this,
|
||||
targets: targets,
|
||||
x: (_target, _key, value: number) => value + relX,
|
||||
y: (_target, _key, value: number) => value + relY,
|
||||
duration: duration,
|
||||
@ -761,6 +768,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
} else {
|
||||
this.x += relX;
|
||||
this.y += relY;
|
||||
if (subTag?.sprite) {
|
||||
subTag.sprite.x += relX;
|
||||
subTag.sprite.y += relY;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1488,7 +1499,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
isGrounded(): boolean {
|
||||
return !!this.getTag(GroundedTag) || (!this.isOfType(Type.FLYING, true, true) && !this.hasAbility(Abilities.LEVITATE) && !this.getTag(BattlerTagType.MAGNET_RISEN) && !this.getTag(SemiInvulnerableTag));
|
||||
return !!this.getTag(GroundedTag) || (!this.isOfType(Type.FLYING, true, true) && !this.hasAbility(Abilities.LEVITATE) && !this.getTag(BattlerTagType.FLOATING) && !this.getTag(SemiInvulnerableTag));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3051,8 +3062,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
*
|
||||
* @see {@linkcode MoveRestrictionBattlerTag}
|
||||
*/
|
||||
isMoveRestricted(moveId: Moves): boolean {
|
||||
return this.getRestrictingTag(moveId) !== null;
|
||||
public isMoveRestricted(moveId: Moves, pokemon?: Pokemon): boolean {
|
||||
return this.getRestrictingTag(moveId, pokemon) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3085,7 +3096,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
*/
|
||||
getRestrictingTag(moveId: Moves, user?: Pokemon, target?: Pokemon): MoveRestrictionBattlerTag | null {
|
||||
for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) {
|
||||
if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId)) {
|
||||
if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId, user)) {
|
||||
return tag as MoveRestrictionBattlerTag;
|
||||
} else if (user && target && (tag as MoveRestrictionBattlerTag).isMoveTargetRestricted(moveId, user, target)) {
|
||||
return tag as MoveRestrictionBattlerTag;
|
||||
@ -5128,7 +5139,7 @@ export class PokemonMove {
|
||||
* @returns `true` if the move can be selected and used by the Pokemon, otherwise `false`.
|
||||
*/
|
||||
isUsable(pokemon: Pokemon, ignorePp: boolean = false, ignoreRestrictionTags: boolean = false): boolean {
|
||||
if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId)) {
|
||||
if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId, pokemon)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
||||
const battle = this.scene.currentBattle;
|
||||
const template = this.getPartyTemplate();
|
||||
|
||||
let species: PokemonSpecies;
|
||||
let baseSpecies: PokemonSpecies;
|
||||
if (this.config.speciesPools) {
|
||||
const tierValue = Utils.randSeedInt(512);
|
||||
let tier = tierValue >= 156 ? TrainerPoolTier.COMMON : tierValue >= 32 ? TrainerPoolTier.UNCOMMON : tierValue >= 6 ? TrainerPoolTier.RARE : tierValue >= 1 ? TrainerPoolTier.SUPER_RARE : TrainerPoolTier.ULTRA_RARE;
|
||||
@ -393,17 +393,17 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
||||
tier--;
|
||||
}
|
||||
const tierPool = this.config.speciesPools[tier];
|
||||
species = getPokemonSpecies(Utils.randSeedItem(tierPool));
|
||||
baseSpecies = getPokemonSpecies(Utils.randSeedItem(tierPool));
|
||||
} else {
|
||||
species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
|
||||
baseSpecies = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter);
|
||||
}
|
||||
|
||||
let ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex));
|
||||
let ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex));
|
||||
let retry = false;
|
||||
|
||||
console.log(ret.getName());
|
||||
|
||||
if (pokemonPrevolutions.hasOwnProperty(species.speciesId) && ret.speciesId !== species.speciesId) {
|
||||
if (pokemonPrevolutions.hasOwnProperty(baseSpecies.speciesId) && ret.speciesId !== baseSpecies.speciesId) {
|
||||
retry = true;
|
||||
} else if (template.isBalanced(battle.enemyParty.length)) {
|
||||
const partyMemberTypes = battle.enemyParty.map(p => p.getTypes(true)).flat();
|
||||
@ -417,7 +417,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, this.scene.currentBattle.waveIndex));
|
||||
ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex));
|
||||
console.log(ret.name);
|
||||
if (this.config.specialtyTypes.find(t => ret.isOfType(t))) {
|
||||
retry = false;
|
||||
@ -426,7 +426,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
// Prompts reroll of party member species if species already present in the enemy party
|
||||
if (this.checkDuplicateSpecies(ret)) {
|
||||
if (this.checkDuplicateSpecies(ret, baseSpecies)) {
|
||||
console.log("Duplicate species detected, prompting reroll...");
|
||||
retry = true;
|
||||
}
|
||||
@ -442,13 +442,16 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
||||
/**
|
||||
* Checks if the enemy trainer already has the Pokemon species in their party
|
||||
* @param {PokemonSpecies} species {@linkcode PokemonSpecies}
|
||||
* @param {PokemonSpecies} baseSpecies {@linkcode PokemonSpecies} - baseSpecies of the Pokemon if species is forced to evolve
|
||||
* @returns `true` if the species is already present in the party
|
||||
*/
|
||||
checkDuplicateSpecies(species: PokemonSpecies): boolean {
|
||||
checkDuplicateSpecies(species: PokemonSpecies, baseSpecies: PokemonSpecies): boolean {
|
||||
const staticPartyPokemon = (signatureSpecies[TrainerType[this.config.trainerType]] ?? []).flat(1);
|
||||
|
||||
const currentPartySpecies = this.scene.getEnemyParty().map(p => {
|
||||
return p.species.speciesId;
|
||||
});
|
||||
return currentPartySpecies.includes(species.speciesId);
|
||||
return currentPartySpecies.includes(species.speciesId) || staticPartyPokemon.includes(baseSpecies.speciesId);
|
||||
}
|
||||
|
||||
getPartyMemberMatchupScores(trainerSlot: TrainerSlot = TrainerSlot.NONE, forSwitch: boolean = false): [integer, integer][] {
|
||||
|
@ -8,7 +8,6 @@ export class Phase {
|
||||
}
|
||||
|
||||
start() {
|
||||
console.log(`%cStart Phase ${this.constructor.name}`, "color:green;");
|
||||
if (this.scene.abilityBar.shown) {
|
||||
this.scene.abilityBar.resetAutoHideTimer();
|
||||
}
|
||||
|
@ -114,8 +114,8 @@ export class CommandPhase extends FieldPhase {
|
||||
|
||||
// Decides between a Disabled, Not Implemented, or No PP translation message
|
||||
const errorMessage =
|
||||
playerPokemon.isMoveRestricted(move.moveId)
|
||||
? playerPokemon.getRestrictingTag(move.moveId)!.selectionDeniedText(playerPokemon, move.moveId)
|
||||
playerPokemon.isMoveRestricted(move.moveId, playerPokemon)
|
||||
? playerPokemon.getRestrictingTag(move.moveId, playerPokemon)!.selectionDeniedText(playerPokemon, move.moveId)
|
||||
: move.getName().endsWith(" (N)") ? "battle:moveNotImplemented" : "battle:moveNoPP";
|
||||
const moveName = move.getName().replace(" (N)", ""); // Trims off the indicator
|
||||
|
||||
|
@ -33,7 +33,7 @@ export class EggLapsePhase extends Phase {
|
||||
if (eggsToHatchCount > 0) {
|
||||
if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 1) {
|
||||
this.scene.ui.showText(i18next.t("battle:eggHatching"), 0, () => {
|
||||
// show prompt for skip
|
||||
// show prompt for skip, blocking inputs for 1 second
|
||||
this.scene.ui.showText(i18next.t("battle:eggSkipPrompt"), 0);
|
||||
this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => {
|
||||
this.hatchEggsSkipped(eggsToHatch);
|
||||
@ -41,7 +41,8 @@ export class EggLapsePhase extends Phase {
|
||||
}, () => {
|
||||
this.hatchEggsRegular(eggsToHatch);
|
||||
this.end();
|
||||
}
|
||||
},
|
||||
null, null, null, 1000, true
|
||||
);
|
||||
}, 100, true);
|
||||
} else if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 2) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { Phase } from "#app/phase";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import EggHatchSceneHandler from "#app/ui/egg-hatch-scene-handler";
|
||||
import { EggHatchData } from "#app/data/egg-hatch-data";
|
||||
|
||||
/**
|
||||
@ -11,7 +10,6 @@ import { EggHatchData } from "#app/data/egg-hatch-data";
|
||||
*/
|
||||
export class EggSummaryPhase extends Phase {
|
||||
private eggHatchData: EggHatchData[];
|
||||
private eggHatchHandler: EggHatchSceneHandler;
|
||||
|
||||
constructor(scene: BattleScene, eggHatchData: EggHatchData[]) {
|
||||
super(scene);
|
||||
@ -26,7 +24,6 @@ export class EggSummaryPhase extends Phase {
|
||||
if (i >= this.eggHatchData.length) {
|
||||
this.scene.ui.setModeForceTransition(Mode.EGG_HATCH_SUMMARY, this.eggHatchData).then(() => {
|
||||
this.scene.fadeOutBgm(undefined, false);
|
||||
this.eggHatchHandler = this.scene.ui.getHandler() as EggHatchSceneHandler;
|
||||
});
|
||||
|
||||
} else {
|
||||
|
@ -4,7 +4,7 @@ import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr,
|
||||
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag";
|
||||
import { MoveAnim } from "#app/data/battle-anims";
|
||||
import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags";
|
||||
import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr, ToxicAccuracyAttr } from "#app/data/move";
|
||||
import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, OneHitKOAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr, ToxicAccuracyAttr } from "#app/data/move";
|
||||
import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms";
|
||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
||||
import { Moves } from "#app/enums/moves";
|
||||
@ -404,6 +404,10 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.getTag(BattlerTagType.TELEKINESIS) && !target.getTag(SemiInvulnerableTag) && !this.move.getMove().hasAttr(OneHitKOAttr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const semiInvulnerableTag = target.getTag(SemiInvulnerableTag);
|
||||
if (semiInvulnerableTag
|
||||
&& !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType)
|
||||
|
@ -36,6 +36,16 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
}
|
||||
|
||||
start() {
|
||||
|
||||
// Check if multiple stats are being changed at the same time, then run SSCPhase for each of them
|
||||
if (this.stats.length > 1) {
|
||||
for (let i = 0; i < this.stats.length; i++) {
|
||||
const stat = [ this.stats[i] ];
|
||||
this.scene.unshiftPhase(new StatStageChangePhase(this.scene, this.battlerIndex, this.selfTarget, stat, this.stages, this.showMessage, this.ignoreAbilities, this.canBeCopied, this.onChange));
|
||||
}
|
||||
return this.end();
|
||||
}
|
||||
|
||||
const pokemon = this.getPokemon();
|
||||
|
||||
if (!pokemon.isActive(true)) {
|
||||
|
72
src/test/abilities/competitive.test.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import { Stat } from "#enums/stat";
|
||||
import { TurnInitPhase } from "#app/phases/turn-init-phase";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
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";
|
||||
|
||||
describe("Abilities - Competitive", () => {
|
||||
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")
|
||||
.enemySpecies(Species.BEEDRILL)
|
||||
.enemyMoveset(Moves.TICKLE)
|
||||
.startingLevel(1)
|
||||
.moveset([ Moves.SPLASH, Moves.CLOSE_COMBAT ])
|
||||
.ability(Abilities.COMPETITIVE);
|
||||
});
|
||||
|
||||
it("lower atk and def by 1 via tickle, then increase spatk by 4 via competitive", async () => {
|
||||
await game.classicMode.startBattle([ Species.FLYGON ]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
|
||||
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1);
|
||||
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1);
|
||||
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(4);
|
||||
});
|
||||
|
||||
it("lowering your own stats should not trigger competitive", async () => {
|
||||
game.override.enemyMoveset(Moves.SPLASH);
|
||||
await game.classicMode.startBattle([ Species.FLYGON ]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
game.move.select(Moves.CLOSE_COMBAT);
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
|
||||
expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1);
|
||||
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1);
|
||||
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0);
|
||||
});
|
||||
|
||||
it("white herb should remove only the negative effects", async () => {
|
||||
game.override.startingHeldItems([{ name: "WHITE_HERB" }]);
|
||||
await game.classicMode.startBattle([ Species.FLYGON ]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
|
||||
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0);
|
||||
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0);
|
||||
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(4);
|
||||
});
|
||||
});
|
70
src/test/abilities/defiant.test.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import { Stat } from "#enums/stat";
|
||||
import { TurnInitPhase } from "#app/phases/turn-init-phase";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
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";
|
||||
|
||||
describe("Abilities - Defiant", () => {
|
||||
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")
|
||||
.enemySpecies(Species.BEEDRILL)
|
||||
.enemyMoveset(Moves.TICKLE)
|
||||
.startingLevel(1)
|
||||
.moveset([ Moves.SPLASH, Moves.CLOSE_COMBAT ])
|
||||
.ability(Abilities.DEFIANT);
|
||||
});
|
||||
|
||||
it("lower atk and def by 1 via tickle, then increase atk by 4 via defiant", async () => {
|
||||
await game.classicMode.startBattle([ Species.FLYGON ]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
|
||||
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(3);
|
||||
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1);
|
||||
});
|
||||
|
||||
it("lowering your own stats should not trigger defiant", async () => {
|
||||
game.override.enemyMoveset(Moves.SPLASH);
|
||||
await game.classicMode.startBattle([ Species.FLYGON ]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
game.move.select(Moves.CLOSE_COMBAT);
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
|
||||
expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1);
|
||||
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1);
|
||||
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0);
|
||||
});
|
||||
|
||||
it("white herb should remove only the negative effects", async () => {
|
||||
game.override.startingHeldItems([{ name: "WHITE_HERB" }]);
|
||||
await game.classicMode.startBattle([ Species.FLYGON ]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
|
||||
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0);
|
||||
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(3);
|
||||
});
|
||||
});
|
@ -139,4 +139,58 @@ describe("Moves - Dragon Tail", () => {
|
||||
|
||||
expect(enemy.isFullHp()).toBe(false);
|
||||
});
|
||||
|
||||
it("should force a switch upon fainting an opponent normally", async () => {
|
||||
game.override.startingWave(5)
|
||||
.startingLevel(1000); // To make sure Dragon Tail KO's the opponent
|
||||
await game.classicMode.startBattle([ Species.DRATINI ]);
|
||||
|
||||
game.move.select(Moves.DRAGON_TAIL);
|
||||
|
||||
await game.toNextTurn();
|
||||
|
||||
// Make sure the enemy switched to a healthy Pokemon
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
expect(enemy).toBeDefined();
|
||||
expect(enemy.isFullHp()).toBe(true);
|
||||
|
||||
// Make sure the enemy has a fainted Pokemon in their party and not on the field
|
||||
const faintedEnemy = game.scene.getEnemyParty().find(p => !p.isAllowedInBattle());
|
||||
expect(faintedEnemy).toBeDefined();
|
||||
expect(game.scene.getEnemyField().length).toBe(1);
|
||||
});
|
||||
|
||||
it("should not cause a softlock when activating an opponent trainer's reviver seed", async () => {
|
||||
game.override.startingWave(5)
|
||||
.enemyHeldItems([{ name: "REVIVER_SEED" }])
|
||||
.startingLevel(1000); // To make sure Dragon Tail KO's the opponent
|
||||
await game.classicMode.startBattle([ Species.DRATINI ]);
|
||||
|
||||
game.move.select(Moves.DRAGON_TAIL);
|
||||
|
||||
await game.toNextTurn();
|
||||
|
||||
// Make sure the enemy field is not empty and has a revived Pokemon
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
expect(enemy).toBeDefined();
|
||||
expect(enemy.hp).toBe(Math.floor(enemy.getMaxHp() / 2));
|
||||
expect(game.scene.getEnemyField().length).toBe(1);
|
||||
});
|
||||
|
||||
it("should not cause a softlock when activating a player's reviver seed", async () => {
|
||||
game.override.startingHeldItems([{ name: "REVIVER_SEED" }])
|
||||
.enemyMoveset(Moves.DRAGON_TAIL)
|
||||
.enemyLevel(1000); // To make sure Dragon Tail KO's the player
|
||||
await game.classicMode.startBattle([ Species.DRATINI, Species.BULBASAUR ]);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
|
||||
await game.toNextTurn();
|
||||
|
||||
// Make sure the player's field is not empty and has a revived Pokemon
|
||||
const dratini = game.scene.getPlayerPokemon()!;
|
||||
expect(dratini).toBeDefined();
|
||||
expect(dratini.hp).toBe(Math.floor(dratini.getMaxHp() / 2));
|
||||
expect(game.scene.getPlayerField().length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
@ -33,7 +33,7 @@ describe("Moves - Safeguard", () => {
|
||||
.enemyLevel(5)
|
||||
.starterSpecies(Species.DRATINI)
|
||||
.moveset([ Moves.NUZZLE, Moves.SPORE, Moves.YAWN, Moves.SPLASH ])
|
||||
.ability(Abilities.BALL_FETCH);
|
||||
.ability(Abilities.UNNERVE); // Stop wild Pokemon from potentially eating Lum Berry
|
||||
});
|
||||
|
||||
it("protects from damaging moves with additional effects", async () => {
|
||||
|
124
src/test/moves/telekinesis.test.ts
Normal file
@ -0,0 +1,124 @@
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import { MoveResult } from "#app/field/pokemon";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest";
|
||||
|
||||
describe("Moves - Telekinesis", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.moveset([ Moves.TELEKINESIS, Moves.TACKLE, Moves.MUD_SHOT, Moves.SMACK_DOWN ])
|
||||
.battleType("single")
|
||||
.enemySpecies(Species.SNORLAX)
|
||||
.enemyLevel(60)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset([ Moves.SPLASH ]);
|
||||
});
|
||||
|
||||
it("Telekinesis makes the affected vulnerable to most attacking moves regardless of accuracy", async () => {
|
||||
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||
|
||||
const enemyOpponent = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.TELEKINESIS);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined();
|
||||
expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined();
|
||||
|
||||
await game.toNextTurn();
|
||||
vi.spyOn(allMoves[Moves.TACKLE], "accuracy", "get").mockReturnValue(0);
|
||||
game.move.select(Moves.TACKLE);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
expect(enemyOpponent.isFullHp()).toBe(false);
|
||||
});
|
||||
|
||||
it("Telekinesis makes the affected airborne and immune to most Ground-moves", async () => {
|
||||
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||
|
||||
const enemyOpponent = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.TELEKINESIS);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined();
|
||||
expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined();
|
||||
|
||||
await game.toNextTurn();
|
||||
vi.spyOn(allMoves[Moves.MUD_SHOT], "accuracy", "get").mockReturnValue(100);
|
||||
game.move.select(Moves.MUD_SHOT);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
expect(enemyOpponent.isFullHp()).toBe(true);
|
||||
});
|
||||
|
||||
it("Telekinesis can still affect Pokemon that have been transformed into invalid Pokemon", async () => {
|
||||
game.override.enemyMoveset(Moves.TRANSFORM);
|
||||
await game.classicMode.startBattle([ Species.DIGLETT ]);
|
||||
|
||||
const enemyOpponent = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.TELEKINESIS);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined();
|
||||
expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined();
|
||||
expect(enemyOpponent.summonData.speciesForm?.speciesId).toBe(Species.DIGLETT);
|
||||
});
|
||||
|
||||
it("Moves like Smack Down and 1000 Arrows remove all effects of Telekinesis from the target Pokemon", async () => {
|
||||
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||
|
||||
const enemyOpponent = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.TELEKINESIS);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined();
|
||||
expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined();
|
||||
|
||||
await game.toNextTurn();
|
||||
game.move.select(Moves.SMACK_DOWN);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeUndefined();
|
||||
expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Ingrain will remove the floating effect of Telekinesis, but not the 100% hit", async () => {
|
||||
game.override.enemyMoveset([ Moves.SPLASH, Moves.INGRAIN ]);
|
||||
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||
|
||||
const playerPokemon = game.scene.getPlayerPokemon()!;
|
||||
const enemyOpponent = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.move.select(Moves.TELEKINESIS);
|
||||
await game.forceEnemyMove(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined();
|
||||
expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined();
|
||||
|
||||
await game.toNextTurn();
|
||||
vi.spyOn(allMoves[Moves.MUD_SHOT], "accuracy", "get").mockReturnValue(0);
|
||||
game.move.select(Moves.MUD_SHOT);
|
||||
await game.forceEnemyMove(Moves.INGRAIN);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined();
|
||||
expect(enemyOpponent.getTag(BattlerTagType.INGRAIN)).toBeDefined();
|
||||
expect(enemyOpponent.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined();
|
||||
expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeUndefined();
|
||||
expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS);
|
||||
});
|
||||
});
|
@ -85,13 +85,13 @@ describe("Moves - Thousand Arrows", () => {
|
||||
|
||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||
|
||||
enemyPokemon.addTag(BattlerTagType.MAGNET_RISEN, undefined, Moves.MAGNET_RISE);
|
||||
enemyPokemon.addTag(BattlerTagType.FLOATING, undefined, Moves.MAGNET_RISE);
|
||||
|
||||
game.move.select(Moves.THOUSAND_ARROWS);
|
||||
|
||||
await game.phaseInterceptor.to(BerryPhase, false);
|
||||
|
||||
expect(enemyPokemon.getTag(BattlerTagType.MAGNET_RISEN)).toBeUndefined();
|
||||
expect(enemyPokemon.getTag(BattlerTagType.FLOATING)).toBeUndefined();
|
||||
expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined();
|
||||
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
|
||||
}
|
||||
|
@ -96,4 +96,23 @@ describe("Moves - U-turn", () => {
|
||||
expect(game.scene.getEnemyPokemon()!.battleData.abilityRevealed).toBe(true); // proxy for asserting ability activated
|
||||
expect(game.phaseInterceptor.log).not.toContain("SwitchSummonPhase");
|
||||
}, 20000);
|
||||
|
||||
it("still forces a switch if u-turn KO's the opponent", async () => {
|
||||
game.override.startingLevel(1000); // Ensure that U-Turn KO's the opponent
|
||||
await game.classicMode.startBattle([
|
||||
Species.RAICHU,
|
||||
Species.SHUCKLE
|
||||
]);
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
|
||||
// KO the opponent with U-Turn
|
||||
game.move.select(Moves.U_TURN);
|
||||
game.doSelectPartyPokemon(1);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
expect(enemy.isFainted()).toBe(true);
|
||||
|
||||
// Check that U-Turn forced a switch
|
||||
expect(game.phaseInterceptor.log).toContain("SwitchSummonPhase");
|
||||
expect(game.scene.getPlayerPokemon()!.species.speciesId).toBe(Species.SHUCKLE);
|
||||
});
|
||||
});
|
||||
|
@ -18,6 +18,7 @@ import { Moves } from "#enums/moves";
|
||||
import { ShinyRateBoosterModifier } from "#app/modifier/modifier";
|
||||
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
|
||||
import i18next from "i18next";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
|
||||
const namespace = "mysteryEncounters/anOfferYouCantRefuse";
|
||||
/** Gyarados for Indimidate */
|
||||
@ -37,10 +38,11 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
||||
beforeEach(async () => {
|
||||
game = new GameManager(phaserGame);
|
||||
scene = game.scene;
|
||||
game.override.mysteryEncounterChance(100);
|
||||
game.override.startingWave(defaultWave);
|
||||
game.override.startingBiome(defaultBiome);
|
||||
game.override.disableTrainerWaves();
|
||||
game.override.mysteryEncounterChance(100)
|
||||
.startingWave(defaultWave)
|
||||
.startingBiome(defaultBiome)
|
||||
.disableTrainerWaves()
|
||||
.ability(Abilities.INTIMIDATE); // Extortion ability
|
||||
|
||||
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
||||
[ Biome.VOLCANO, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]],
|
||||
@ -195,6 +197,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
||||
});
|
||||
|
||||
it("should award EXP to a pokemon with a move in EXTORTION_MOVES", async () => {
|
||||
game.override.ability(Abilities.SYNCHRONIZE); // Not an extortion ability, so we can test extortion move
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, [ Species.ABRA ]);
|
||||
const party = scene.getParty();
|
||||
const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA)!;
|
||||
|
@ -176,10 +176,12 @@ describe("Berries Abound - Mystery Encounter", () => {
|
||||
const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText");
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
||||
|
||||
scene.getParty().forEach(pkm => {
|
||||
vi.spyOn(pkm, "getStat").mockReturnValue(1); // for ease return for every stat
|
||||
});
|
||||
|
||||
const config = game.scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
|
||||
const speciesToSpawn = config.pokemonConfigs?.[0].species.speciesId;
|
||||
// Setting enemy's level arbitrarily high to outspeed
|
||||
config.pokemonConfigs![0].dataSource!.level = 1000;
|
||||
|
||||
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||
|
||||
@ -198,10 +200,12 @@ describe("Berries Abound - Mystery Encounter", () => {
|
||||
const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText");
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
||||
|
||||
scene.getParty().forEach(pkm => {
|
||||
vi.spyOn(pkm, "getStat").mockReturnValue(1); // for ease return for every stat
|
||||
});
|
||||
|
||||
const config = game.scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
|
||||
const speciesToSpawn = config.pokemonConfigs?.[0].species.speciesId;
|
||||
// Setting enemy's level arbitrarily high to outspeed
|
||||
config.pokemonConfigs![0].dataSource!.level = 1000;
|
||||
|
||||
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||
|
||||
|
@ -147,8 +147,8 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
|
||||
|
||||
expect(scene.getParty().length).toBe(initialPartySize + 1);
|
||||
|
||||
const newlyPurchasedPokemon = scene.getParty().find(p => p.name === pokemonName);
|
||||
expect(newlyPurchasedPokemon).toBeDefined();
|
||||
const newlyPurchasedPokemon = scene.getParty()[scene.getParty().length - 1];
|
||||
expect(newlyPurchasedPokemon.name).toBe(pokemonName);
|
||||
expect(newlyPurchasedPokemon!.moveset.length > 0).toBeTruthy();
|
||||
});
|
||||
|
||||
|
@ -165,6 +165,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
if (this.config.delay) {
|
||||
this.blockInput = true;
|
||||
this.optionSelectText.setAlpha(0.5);
|
||||
this.cursorObj?.setAlpha(0.8);
|
||||
this.scene.time.delayedCall(Utils.fixedInt(this.config.delay), () => this.unblockInput());
|
||||
}
|
||||
|
||||
@ -256,6 +257,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
|
||||
|
||||
this.blockInput = false;
|
||||
this.optionSelectText.setAlpha(1);
|
||||
this.cursorObj?.setAlpha(1);
|
||||
}
|
||||
|
||||
getOptionsWithScroll(): OptionSelectItem[] {
|
||||
|
@ -76,7 +76,8 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler {
|
||||
}
|
||||
}
|
||||
],
|
||||
delay: args.length >= 6 && args[5] !== null ? args[5] as integer : 0
|
||||
delay: args.length >= 6 && args[5] !== null ? args[5] as number : 0,
|
||||
noCancel: args.length >= 7 && args[6] !== null ? args[6] as boolean : false,
|
||||
};
|
||||
|
||||
super.show([ config ]);
|
||||
@ -96,7 +97,7 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler {
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
if (button === Button.CANCEL && this.blockInput) {
|
||||
if (button === Button.CANCEL && this.blockInput && !this.config?.noCancel) {
|
||||
this.unblockInput();
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,9 @@ export default class EggSummaryUiHandler extends MessageUiHandler {
|
||||
private scrollGridHandler : ScrollableGridUiHandler;
|
||||
private cursorObj: Phaser.GameObjects.Image;
|
||||
|
||||
/** used to add a delay before which it is not possible to exit the summary */
|
||||
private blockExit: boolean;
|
||||
|
||||
/**
|
||||
* Allows subscribers to listen for events
|
||||
*
|
||||
@ -168,6 +171,13 @@ export default class EggSummaryUiHandler extends MessageUiHandler {
|
||||
this.setCursor(0);
|
||||
|
||||
this.scene.playSoundWithoutBgm("evolution_fanfare");
|
||||
|
||||
// Prevent exiting the egg summary for 2 seconds if the egg hatching
|
||||
// was skipped automatically and for 1 second otherwise
|
||||
const exitBlockingDuration = (this.scene.eggSkipPreference === 2) ? 2000 : 1000;
|
||||
this.blockExit = true;
|
||||
this.scene.time.delayedCall(exitBlockingDuration, () => this.blockExit = false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -203,13 +213,17 @@ export default class EggSummaryUiHandler extends MessageUiHandler {
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
const error = false;
|
||||
let error = false;
|
||||
if (button === Button.CANCEL) {
|
||||
const phase = this.scene.getCurrentPhase();
|
||||
if (phase instanceof EggSummaryPhase) {
|
||||
phase.end();
|
||||
if (!this.blockExit) {
|
||||
const phase = this.scene.getCurrentPhase();
|
||||
if (phase instanceof EggSummaryPhase) {
|
||||
phase.end();
|
||||
}
|
||||
success = true;
|
||||
} else {
|
||||
error = true;
|
||||
}
|
||||
success = true;
|
||||
} else {
|
||||
this.scrollGridHandler.processInput(button);
|
||||
}
|
||||
|
@ -2967,8 +2967,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
this.natureCursor = -1;
|
||||
|
||||
if (this.activeTooltip === "CANDY") {
|
||||
const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId);
|
||||
this.scene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`);
|
||||
if (this.lastSpecies) {
|
||||
const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId);
|
||||
this.scene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`);
|
||||
} else {
|
||||
this.scene.ui.hideTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
if (species?.forms?.find(f => f.formKey === "female")) {
|
||||
@ -3659,6 +3663,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
StarterPrefs.save(this.starterPreferences);
|
||||
this.cursor = -1;
|
||||
this.hideInstructions();
|
||||
this.activeTooltip = undefined;
|
||||
this.scene.ui.hideTooltip();
|
||||
|
||||
this.starterSelectContainer.setVisible(false);
|
||||
this.blockInput = false;
|
||||
|
||||
|