Merge remote-tracking branch 'upstream/beta' into variant_update_oct
14
global.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import type { SetupServerApi } from "msw/node";
|
||||||
|
|
||||||
|
export {};
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
/**
|
||||||
|
* Only used in testing.
|
||||||
|
* Can technically be undefined/null but for ease of use we are going to assume it is always defined.
|
||||||
|
* Used to load i18n files exclusively.
|
||||||
|
*
|
||||||
|
* To set up your own server in a test see `game_data.test.ts`
|
||||||
|
*/
|
||||||
|
var i18nServer: SetupServerApi;
|
||||||
|
}
|
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 |
@ -3731,8 +3731,8 @@
|
|||||||
],
|
],
|
||||||
"6706": [
|
"6706": [
|
||||||
0,
|
0,
|
||||||
2,
|
1,
|
||||||
2
|
1
|
||||||
],
|
],
|
||||||
"6713": [
|
"6713": [
|
||||||
0,
|
0,
|
||||||
@ -7774,8 +7774,8 @@
|
|||||||
],
|
],
|
||||||
"6706": [
|
"6706": [
|
||||||
0,
|
0,
|
||||||
2,
|
1,
|
||||||
2
|
1
|
||||||
],
|
],
|
||||||
"6713": [
|
"6713": [
|
||||||
0,
|
0,
|
||||||
@ -8523,8 +8523,8 @@
|
|||||||
],
|
],
|
||||||
"705": [
|
"705": [
|
||||||
0,
|
0,
|
||||||
2,
|
1,
|
||||||
2
|
1
|
||||||
],
|
],
|
||||||
"706": [
|
"706": [
|
||||||
0,
|
0,
|
||||||
@ -9598,8 +9598,8 @@
|
|||||||
],
|
],
|
||||||
"6706": [
|
"6706": [
|
||||||
0,
|
0,
|
||||||
2,
|
1,
|
||||||
2
|
1
|
||||||
],
|
],
|
||||||
"female": {},
|
"female": {},
|
||||||
"back": {
|
"back": {
|
||||||
@ -11135,8 +11135,8 @@
|
|||||||
],
|
],
|
||||||
"6706": [
|
"6706": [
|
||||||
0,
|
0,
|
||||||
2,
|
1,
|
||||||
2
|
1
|
||||||
],
|
],
|
||||||
"6713": [
|
"6713": [
|
||||||
0,
|
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 |
@ -2676,7 +2676,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all modifiers from enemy of PersistentModifier type
|
* Removes all modifiers from enemy pokemon of {@linkcode PersistentModifier} type
|
||||||
*/
|
*/
|
||||||
clearEnemyModifiers(): void {
|
clearEnemyModifiers(): void {
|
||||||
const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PersistentModifier);
|
const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PersistentModifier);
|
||||||
@ -2687,10 +2687,11 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all modifiers from enemy of PokemonHeldItemModifier type
|
* Removes all modifiers from enemy pokemon of {@linkcode PokemonHeldItemModifier} type
|
||||||
|
* @param pokemon - If specified, only removes held items from that {@linkcode Pokemon}
|
||||||
*/
|
*/
|
||||||
clearEnemyHeldItemModifiers(): void {
|
clearEnemyHeldItemModifiers(pokemon?: Pokemon): void {
|
||||||
const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PokemonHeldItemModifier);
|
const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PokemonHeldItemModifier && (!pokemon || m.getPokemon(this) === pokemon));
|
||||||
for (const m of modifiersToRemove) {
|
for (const m of modifiersToRemove) {
|
||||||
this.enemyModifiers.splice(this.enemyModifiers.indexOf(m), 1);
|
this.enemyModifiers.splice(this.enemyModifiers.indexOf(m), 1);
|
||||||
}
|
}
|
||||||
@ -3161,13 +3162,17 @@ export default class BattleScene extends SceneBase {
|
|||||||
/**
|
/**
|
||||||
* Loads or generates a mystery encounter
|
* Loads or generates a mystery encounter
|
||||||
* @param encounterType used to load session encounter when restarting game, etc.
|
* @param encounterType used to load session encounter when restarting game, etc.
|
||||||
|
* @param canBypass optional boolean to indicate that the request is coming from a function that needs to access a Mystery Encounter outside of gameplay requirements
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
getMysteryEncounter(encounterType?: MysteryEncounterType): MysteryEncounter {
|
getMysteryEncounter(encounterType?: MysteryEncounterType, canBypass?: boolean): MysteryEncounter {
|
||||||
// Loading override or session encounter
|
// Loading override or session encounter
|
||||||
let encounter: MysteryEncounter | null;
|
let encounter: MysteryEncounter | null;
|
||||||
if (!isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_OVERRIDE) && allMysteryEncounters.hasOwnProperty(Overrides.MYSTERY_ENCOUNTER_OVERRIDE)) {
|
if (!isNullOrUndefined(Overrides.MYSTERY_ENCOUNTER_OVERRIDE) && allMysteryEncounters.hasOwnProperty(Overrides.MYSTERY_ENCOUNTER_OVERRIDE)) {
|
||||||
encounter = allMysteryEncounters[Overrides.MYSTERY_ENCOUNTER_OVERRIDE];
|
encounter = allMysteryEncounters[Overrides.MYSTERY_ENCOUNTER_OVERRIDE];
|
||||||
|
} else if (canBypass) {
|
||||||
|
encounter = allMysteryEncounters[encounterType ?? -1];
|
||||||
|
return encounter;
|
||||||
} else {
|
} else {
|
||||||
encounter = !isNullOrUndefined(encounterType) ? allMysteryEncounters[encounterType] : null;
|
encounter = !isNullOrUndefined(encounterType) ? allMysteryEncounters[encounterType] : null;
|
||||||
}
|
}
|
||||||
|
@ -634,15 +634,15 @@ export class ReverseDrainAbAttr extends PostDefendAbAttr {
|
|||||||
* Examples include: Absorb, Draining Kiss, Bitter Blade, etc.
|
* Examples include: Absorb, Draining Kiss, Bitter Blade, etc.
|
||||||
* Also displays a message to show this ability was activated.
|
* Also displays a message to show this ability was activated.
|
||||||
* @param pokemon {@linkcode Pokemon} with this ability
|
* @param pokemon {@linkcode Pokemon} with this ability
|
||||||
* @param passive N/A
|
* @param _passive N/A
|
||||||
* @param attacker {@linkcode Pokemon} that is attacking this Pokemon
|
* @param attacker {@linkcode Pokemon} that is attacking this Pokemon
|
||||||
* @param move {@linkcode PokemonMove} that is being used
|
* @param move {@linkcode PokemonMove} that is being used
|
||||||
* @param hitResult N/A
|
* @param _hitResult N/A
|
||||||
* @args N/A
|
* @param _args N/A
|
||||||
* @returns true if healing should be reversed on a healing move, false otherwise.
|
* @returns true if healing should be reversed on a healing move, false otherwise.
|
||||||
*/
|
*/
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.hasAttr(HitHealAttr)) {
|
if (move.hasAttr(HitHealAttr) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) }));
|
pokemon.scene.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) }));
|
||||||
}
|
}
|
||||||
@ -669,8 +669,8 @@ export class PostDefendStatStageChangeAbAttr extends PostDefendAbAttr {
|
|||||||
this.allOthers = allOthers;
|
this.allOthers = allOthers;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move)) {
|
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -707,13 +707,13 @@ export class PostDefendHpGatedStatStageChangeAbAttr extends PostDefendAbAttr {
|
|||||||
this.selfTarget = selfTarget;
|
this.selfTarget = selfTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
const hpGateFlat: integer = Math.ceil(pokemon.getMaxHp() * this.hpGate);
|
const hpGateFlat: number = Math.ceil(pokemon.getMaxHp() * this.hpGate);
|
||||||
const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1];
|
const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1];
|
||||||
const damageReceived = lastAttackReceived?.damage || 0;
|
const damageReceived = lastAttackReceived?.damage || 0;
|
||||||
|
|
||||||
if (this.condition(pokemon, attacker, move) && (pokemon.hp <= hpGateFlat && (pokemon.hp + damageReceived) > hpGateFlat)) {
|
if (this.condition(pokemon, attacker, move) && (pokemon.hp <= hpGateFlat && (pokemon.hp + damageReceived) > hpGateFlat) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (!simulated ) {
|
if (!simulated) {
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -734,8 +734,8 @@ export class PostDefendApplyArenaTrapTagAbAttr extends PostDefendAbAttr {
|
|||||||
this.tagType = tagType;
|
this.tagType = tagType;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move)) {
|
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
const tag = pokemon.scene.arena.getTag(this.tagType) as ArenaTrapTag;
|
const tag = pokemon.scene.arena.getTag(this.tagType) as ArenaTrapTag;
|
||||||
if (!pokemon.scene.arena.getTag(this.tagType) || tag.layers < tag.maxLayers) {
|
if (!pokemon.scene.arena.getTag(this.tagType) || tag.layers < tag.maxLayers) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
@ -758,8 +758,8 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr {
|
|||||||
this.tagType = tagType;
|
this.tagType = tagType;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move)) {
|
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (!pokemon.getTag(this.tagType) && !simulated) {
|
if (!pokemon.getTag(this.tagType) && !simulated) {
|
||||||
pokemon.addTag(this.tagType, undefined, undefined, pokemon.id);
|
pokemon.addTag(this.tagType, undefined, undefined, pokemon.id);
|
||||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }));
|
pokemon.scene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name }));
|
||||||
@ -771,8 +771,8 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
|
export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (hitResult < HitResult.NO_EFFECT) {
|
if (hitResult < HitResult.NO_EFFECT && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -787,7 +787,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string {
|
||||||
return i18next.t("abilityTriggers:postDefendTypeChange", {
|
return i18next.t("abilityTriggers:postDefendTypeChange", {
|
||||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||||
abilityName,
|
abilityName,
|
||||||
@ -805,8 +805,8 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr {
|
|||||||
this.terrainType = terrainType;
|
this.terrainType = terrainType;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (hitResult < HitResult.NO_EFFECT) {
|
if (hitResult < HitResult.NO_EFFECT && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return pokemon.scene.arena.terrain?.terrainType !== (this.terrainType || undefined);
|
return pokemon.scene.arena.terrain?.terrainType !== (this.terrainType || undefined);
|
||||||
} else {
|
} else {
|
||||||
@ -829,8 +829,9 @@ export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr {
|
|||||||
this.effects = effects;
|
this.effects = effects;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) {
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status
|
||||||
|
&& (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
|
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return attacker.canSetStatus(effect, true, false, pokemon);
|
return attacker.canSetStatus(effect, true, false, pokemon);
|
||||||
@ -869,8 +870,8 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr {
|
|||||||
this.turnCount = turnCount;
|
this.turnCount = turnCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance) {
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return attacker.canAddTag(this.tagType);
|
return attacker.canAddTag(this.tagType);
|
||||||
} else {
|
} else {
|
||||||
@ -893,7 +894,11 @@ export class PostDefendCritStatStageChangeAbAttr extends PostDefendAbAttr {
|
|||||||
this.stages = stages;
|
this.stages = stages;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
|
if (move.hitsSubstitute(attacker, pokemon)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.stages));
|
||||||
}
|
}
|
||||||
@ -901,7 +906,7 @@ export class PostDefendCritStatStageChangeAbAttr extends PostDefendAbAttr {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCondition(): AbAttrCondition {
|
override getCondition(): AbAttrCondition {
|
||||||
return (pokemon: Pokemon) => pokemon.turnData.attacksReceived.length !== 0 && pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1].critical;
|
return (pokemon: Pokemon) => pokemon.turnData.attacksReceived.length !== 0 && pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1].critical;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -915,8 +920,9 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr {
|
|||||||
this.damageRatio = damageRatio;
|
this.damageRatio = damageRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (!simulated && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
|
if (!simulated && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)
|
||||||
|
&& !attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
|
attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
|
||||||
attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio));
|
attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio));
|
||||||
return true;
|
return true;
|
||||||
@ -925,7 +931,7 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string {
|
||||||
return i18next.t("abilityTriggers:postDefendContactDamage", {
|
return i18next.t("abilityTriggers:postDefendContactDamage", {
|
||||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||||
abilityName
|
abilityName
|
||||||
@ -948,8 +954,8 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr {
|
|||||||
this.turns = turns;
|
this.turns = turns;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (pokemon.getTag(BattlerTagType.PERISH_SONG) || attacker.getTag(BattlerTagType.PERISH_SONG)) {
|
if (pokemon.getTag(BattlerTagType.PERISH_SONG) || attacker.getTag(BattlerTagType.PERISH_SONG)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -963,24 +969,24 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string {
|
||||||
return i18next.t("abilityTriggers:perishBody", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName });
|
return i18next.t("abilityTriggers:perishBody", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
|
export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
|
||||||
private weatherType: WeatherType;
|
private weatherType: WeatherType;
|
||||||
protected condition: PokemonDefendCondition | null;
|
protected condition?: PokemonDefendCondition;
|
||||||
|
|
||||||
constructor(weatherType: WeatherType, condition?: PokemonDefendCondition) {
|
constructor(weatherType: WeatherType, condition?: PokemonDefendCondition) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.weatherType = weatherType;
|
this.weatherType = weatherType;
|
||||||
this.condition = condition ?? null;
|
this.condition = condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (this.condition !== null && !this.condition(pokemon, attacker, move)) {
|
if (this.condition && !this.condition(pokemon, attacker, move) || move.hitsSubstitute(attacker, pokemon)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!pokemon.scene.arena.weather?.isImmutable()) {
|
if (!pokemon.scene.arena.weather?.isImmutable()) {
|
||||||
@ -999,8 +1005,9 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr)) {
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)
|
||||||
|
&& !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
const tempAbilityId = attacker.getAbility().id;
|
const tempAbilityId = attacker.getAbility().id;
|
||||||
attacker.summonData.ability = pokemon.getAbility().id;
|
attacker.summonData.ability = pokemon.getAbility().id;
|
||||||
@ -1012,7 +1019,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
override getTriggerMessage(pokemon: Pokemon, _abilityName: string, ..._args: any[]): string {
|
||||||
return i18next.t("abilityTriggers:postDefendAbilitySwap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
|
return i18next.t("abilityTriggers:postDefendAbilitySwap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1025,8 +1032,9 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
|
|||||||
this.ability = ability;
|
this.ability = ability;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr)) {
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr)
|
||||||
|
&& !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
attacker.summonData.ability = this.ability;
|
attacker.summonData.ability = this.ability;
|
||||||
}
|
}
|
||||||
@ -1037,7 +1045,7 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string {
|
||||||
return i18next.t("abilityTriggers:postDefendAbilityGive", {
|
return i18next.t("abilityTriggers:postDefendAbilityGive", {
|
||||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||||
abilityName
|
abilityName
|
||||||
@ -1056,8 +1064,8 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
|
|||||||
this.chance = chance;
|
this.chance = chance;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||||
if (attacker.getTag(BattlerTagType.DISABLED) === null) {
|
if (attacker.getTag(BattlerTagType.DISABLED) === null && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) {
|
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) {
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
return true;
|
return true;
|
||||||
@ -1724,17 +1732,17 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
||||||
private condition: PokemonDefendCondition | null;
|
private condition?: PokemonDefendCondition;
|
||||||
|
|
||||||
constructor(condition?: PokemonDefendCondition) {
|
constructor(condition?: PokemonDefendCondition) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.condition = condition ?? null;
|
this.condition = condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): Promise<boolean> {
|
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): Promise<boolean> {
|
||||||
return new Promise<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) {
|
if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move)) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable);
|
const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable);
|
||||||
if (heldItems.length) {
|
if (heldItems.length) {
|
||||||
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
|
||||||
@ -4476,7 +4484,7 @@ export class PostSummonStatStageChangeOnArenaAbAttr extends PostSummonStatStageC
|
|||||||
export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
||||||
private multiplier: number;
|
private multiplier: number;
|
||||||
private tagType: BattlerTagType;
|
private tagType: BattlerTagType;
|
||||||
private recoilDamageFunc: ((pokemon: Pokemon) => number) | undefined;
|
private recoilDamageFunc?: ((pokemon: Pokemon) => number);
|
||||||
private triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string;
|
private triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string;
|
||||||
|
|
||||||
constructor(condition: PokemonDefendCondition, multiplier: number, tagType: BattlerTagType, triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string, recoilDamageFunc?: (pokemon: Pokemon) => number) {
|
constructor(condition: PokemonDefendCondition, multiplier: number, tagType: BattlerTagType, triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string, recoilDamageFunc?: (pokemon: Pokemon) => number) {
|
||||||
@ -4492,16 +4500,16 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
|||||||
* Applies the pre-defense ability to the Pokémon.
|
* Applies the pre-defense ability to the Pokémon.
|
||||||
* Removes the appropriate `BattlerTagType` when hit by an attack and is in its defense form.
|
* Removes the appropriate `BattlerTagType` when hit by an attack and is in its defense form.
|
||||||
*
|
*
|
||||||
* @param {Pokemon} pokemon The Pokémon with the ability.
|
* @param pokemon The Pokémon with the ability.
|
||||||
* @param {boolean} passive n/a
|
* @param _passive n/a
|
||||||
* @param {Pokemon} attacker The attacking Pokémon.
|
* @param attacker The attacking Pokémon.
|
||||||
* @param {PokemonMove} move The move being used.
|
* @param move The move being used.
|
||||||
* @param {Utils.BooleanHolder} cancelled n/a
|
* @param _cancelled n/a
|
||||||
* @param {any[]} args Additional arguments.
|
* @param args Additional arguments.
|
||||||
* @returns {boolean} Whether the immunity was applied.
|
* @returns `true` if the immunity was applied.
|
||||||
*/
|
*/
|
||||||
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
override applyPreDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
if (this.condition(pokemon, attacker, move)) {
|
if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
(args[0] as Utils.NumberHolder).value = this.multiplier;
|
(args[0] as Utils.NumberHolder).value = this.multiplier;
|
||||||
pokemon.removeTag(this.tagType);
|
pokemon.removeTag(this.tagType);
|
||||||
@ -4517,12 +4525,12 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the message triggered when the Pokémon avoids damage using the form-changing ability.
|
* Gets the message triggered when the Pokémon avoids damage using the form-changing ability.
|
||||||
* @param {Pokemon} pokemon The Pokémon with the ability.
|
* @param pokemon The Pokémon with the ability.
|
||||||
* @param {string} abilityName The name of the ability.
|
* @param abilityName The name of the ability.
|
||||||
* @param {...any} args n/a
|
* @param _args n/a
|
||||||
* @returns {string} The trigger message.
|
* @returns The trigger message.
|
||||||
*/
|
*/
|
||||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string {
|
||||||
return this.triggerMessageFunc(pokemon, abilityName);
|
return this.triggerMessageFunc(pokemon, abilityName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5503,7 +5511,8 @@ export function initAbilities() {
|
|||||||
.attr(NoFusionAbilityAbAttr)
|
.attr(NoFusionAbilityAbAttr)
|
||||||
// Add BattlerTagType.DISGUISE if the pokemon is in its disguised form
|
// Add BattlerTagType.DISGUISE if the pokemon is in its disguised form
|
||||||
.conditionalAttr(pokemon => pokemon.formIndex === 0, PostSummonAddBattlerTagAbAttr, BattlerTagType.DISGUISE, 0, false)
|
.conditionalAttr(pokemon => pokemon.formIndex === 0, PostSummonAddBattlerTagAbAttr, BattlerTagType.DISGUISE, 0, false)
|
||||||
.attr(FormBlockDamageAbAttr, (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getMoveEffectiveness(user, move) > 0, 0, BattlerTagType.DISGUISE,
|
.attr(FormBlockDamageAbAttr,
|
||||||
|
(target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getMoveEffectiveness(user, move) > 0, 0, BattlerTagType.DISGUISE,
|
||||||
(pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }),
|
(pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }),
|
||||||
(pokemon) => Utils.toDmgValue(pokemon.getMaxHp() / 8))
|
(pokemon) => Utils.toDmgValue(pokemon.getMaxHp() / 8))
|
||||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||||
@ -5665,7 +5674,8 @@ export function initAbilities() {
|
|||||||
.conditionalAttr(getWeatherCondition(WeatherType.HAIL, WeatherType.SNOW), PostSummonAddBattlerTagAbAttr, BattlerTagType.ICE_FACE, 0)
|
.conditionalAttr(getWeatherCondition(WeatherType.HAIL, WeatherType.SNOW), PostSummonAddBattlerTagAbAttr, BattlerTagType.ICE_FACE, 0)
|
||||||
// When weather changes to HAIL or SNOW while pokemon is fielded, add BattlerTagType.ICE_FACE
|
// When weather changes to HAIL or SNOW while pokemon is fielded, add BattlerTagType.ICE_FACE
|
||||||
.attr(PostWeatherChangeAddBattlerTagAttr, BattlerTagType.ICE_FACE, 0, WeatherType.HAIL, WeatherType.SNOW)
|
.attr(PostWeatherChangeAddBattlerTagAttr, BattlerTagType.ICE_FACE, 0, WeatherType.HAIL, WeatherType.SNOW)
|
||||||
.attr(FormBlockDamageAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0, BattlerTagType.ICE_FACE,
|
.attr(FormBlockDamageAbAttr,
|
||||||
|
(target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0, BattlerTagType.ICE_FACE,
|
||||||
(pokemon, abilityName) => i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }))
|
(pokemon, abilityName) => i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }))
|
||||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||||
.bypassFaint()
|
.bypassFaint()
|
||||||
|
@ -28,20 +28,13 @@ export enum ArenaTagSide {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export abstract class ArenaTag {
|
export abstract class ArenaTag {
|
||||||
public tagType: ArenaTagType;
|
constructor(
|
||||||
public turnCount: integer;
|
public tagType: ArenaTagType,
|
||||||
public sourceMove?: Moves;
|
public turnCount: number,
|
||||||
public sourceId?: integer;
|
public sourceMove?: Moves,
|
||||||
public side: ArenaTagSide;
|
public sourceId?: number,
|
||||||
|
public side: ArenaTagSide = ArenaTagSide.BOTH
|
||||||
|
) {}
|
||||||
constructor(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId?: integer, side: ArenaTagSide = ArenaTagSide.BOTH) {
|
|
||||||
this.tagType = tagType;
|
|
||||||
this.turnCount = turnCount;
|
|
||||||
this.sourceMove = sourceMove;
|
|
||||||
this.sourceId = sourceId;
|
|
||||||
this.side = side;
|
|
||||||
}
|
|
||||||
|
|
||||||
apply(arena: Arena, args: any[]): boolean {
|
apply(arena: Arena, args: any[]): boolean {
|
||||||
return true;
|
return true;
|
||||||
@ -66,6 +59,18 @@ export abstract class ArenaTag {
|
|||||||
? allMoves[this.sourceMove].name
|
? allMoves[this.sourceMove].name
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a arena tag or json representing one, load the data for it.
|
||||||
|
* This is meant to be inherited from by any arena tag with custom attributes
|
||||||
|
* @param {ArenaTag | any} source An arena tag
|
||||||
|
*/
|
||||||
|
loadTag(source : ArenaTag | any) : void {
|
||||||
|
this.turnCount = source.turnCount;
|
||||||
|
this.sourceMove = source.sourceMove;
|
||||||
|
this.sourceId = source.sourceId;
|
||||||
|
this.side = source.side;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,7 +78,7 @@ export abstract class ArenaTag {
|
|||||||
* Prevents Pokémon on the opposing side from lowering the stats of the Pokémon in the Mist.
|
* Prevents Pokémon on the opposing side from lowering the stats of the Pokémon in the Mist.
|
||||||
*/
|
*/
|
||||||
export class MistTag extends ArenaTag {
|
export class MistTag extends ArenaTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.MIST, turnCount, Moves.MIST, sourceId, side);
|
super(ArenaTagType.MIST, turnCount, Moves.MIST, sourceId, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +122,7 @@ export class WeakenMoveScreenTag extends ArenaTag {
|
|||||||
* @param side - The side (player or enemy) the tag affects.
|
* @param side - The side (player or enemy) the tag affects.
|
||||||
* @param weakenedCategories - The categories of moves that are weakened by this tag.
|
* @param weakenedCategories - The categories of moves that are weakened by this tag.
|
||||||
*/
|
*/
|
||||||
constructor(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, weakenedCategories: MoveCategory[]) {
|
constructor(tagType: ArenaTagType, turnCount: number, sourceMove: Moves, sourceId: number, side: ArenaTagSide, weakenedCategories: MoveCategory[]) {
|
||||||
super(tagType, turnCount, sourceMove, sourceId, side);
|
super(tagType, turnCount, sourceMove, sourceId, side);
|
||||||
|
|
||||||
this.weakenedCategories = weakenedCategories;
|
this.weakenedCategories = weakenedCategories;
|
||||||
@ -148,7 +153,7 @@ export class WeakenMoveScreenTag extends ArenaTag {
|
|||||||
* Used by {@linkcode Moves.REFLECT}
|
* Used by {@linkcode Moves.REFLECT}
|
||||||
*/
|
*/
|
||||||
class ReflectTag extends WeakenMoveScreenTag {
|
class ReflectTag extends WeakenMoveScreenTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [ MoveCategory.PHYSICAL ]);
|
super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [ MoveCategory.PHYSICAL ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +169,7 @@ class ReflectTag extends WeakenMoveScreenTag {
|
|||||||
* Used by {@linkcode Moves.LIGHT_SCREEN}
|
* Used by {@linkcode Moves.LIGHT_SCREEN}
|
||||||
*/
|
*/
|
||||||
class LightScreenTag extends WeakenMoveScreenTag {
|
class LightScreenTag extends WeakenMoveScreenTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [ MoveCategory.SPECIAL ]);
|
super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [ MoveCategory.SPECIAL ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +185,7 @@ class LightScreenTag extends WeakenMoveScreenTag {
|
|||||||
* Used by {@linkcode Moves.AURORA_VEIL}
|
* Used by {@linkcode Moves.AURORA_VEIL}
|
||||||
*/
|
*/
|
||||||
class AuroraVeilTag extends WeakenMoveScreenTag {
|
class AuroraVeilTag extends WeakenMoveScreenTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [ MoveCategory.SPECIAL, MoveCategory.PHYSICAL ]);
|
super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [ MoveCategory.SPECIAL, MoveCategory.PHYSICAL ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +208,7 @@ export class ConditionalProtectTag extends ArenaTag {
|
|||||||
/** Does this apply to all moves, including those that ignore other forms of protection? */
|
/** Does this apply to all moves, including those that ignore other forms of protection? */
|
||||||
protected ignoresBypass: boolean;
|
protected ignoresBypass: boolean;
|
||||||
|
|
||||||
constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, condition: ProtectConditionFunc, ignoresBypass: boolean = false) {
|
constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: number, side: ArenaTagSide, condition: ProtectConditionFunc, ignoresBypass: boolean = false) {
|
||||||
super(tagType, 1, sourceMove, sourceId, side);
|
super(tagType, 1, sourceMove, sourceId, side);
|
||||||
|
|
||||||
this.protectConditionFunc = condition;
|
this.protectConditionFunc = condition;
|
||||||
@ -265,7 +270,7 @@ export class ConditionalProtectTag extends ArenaTag {
|
|||||||
*/
|
*/
|
||||||
const QuickGuardConditionFunc: ProtectConditionFunc = (arena, moveId) => {
|
const QuickGuardConditionFunc: ProtectConditionFunc = (arena, moveId) => {
|
||||||
const move = allMoves[moveId];
|
const move = allMoves[moveId];
|
||||||
const priority = new Utils.IntegerHolder(move.priority);
|
const priority = new Utils.NumberHolder(move.priority);
|
||||||
const effectPhase = arena.scene.getCurrentPhase();
|
const effectPhase = arena.scene.getCurrentPhase();
|
||||||
|
|
||||||
if (effectPhase instanceof MoveEffectPhase) {
|
if (effectPhase instanceof MoveEffectPhase) {
|
||||||
@ -281,7 +286,7 @@ const QuickGuardConditionFunc: ProtectConditionFunc = (arena, moveId) => {
|
|||||||
* Condition: The incoming move has increased priority.
|
* Condition: The incoming move has increased priority.
|
||||||
*/
|
*/
|
||||||
class QuickGuardTag extends ConditionalProtectTag {
|
class QuickGuardTag extends ConditionalProtectTag {
|
||||||
constructor(sourceId: integer, side: ArenaTagSide) {
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.QUICK_GUARD, Moves.QUICK_GUARD, sourceId, side, QuickGuardConditionFunc);
|
super(ArenaTagType.QUICK_GUARD, Moves.QUICK_GUARD, sourceId, side, QuickGuardConditionFunc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,7 +317,7 @@ const WideGuardConditionFunc: ProtectConditionFunc = (arena, moveId) : boolean =
|
|||||||
* can be an ally or enemy.
|
* can be an ally or enemy.
|
||||||
*/
|
*/
|
||||||
class WideGuardTag extends ConditionalProtectTag {
|
class WideGuardTag extends ConditionalProtectTag {
|
||||||
constructor(sourceId: integer, side: ArenaTagSide) {
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.WIDE_GUARD, Moves.WIDE_GUARD, sourceId, side, WideGuardConditionFunc);
|
super(ArenaTagType.WIDE_GUARD, Moves.WIDE_GUARD, sourceId, side, WideGuardConditionFunc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,7 +339,7 @@ const MatBlockConditionFunc: ProtectConditionFunc = (arena, moveId) : boolean =>
|
|||||||
* Condition: The incoming move is a Physical or Special attack move.
|
* Condition: The incoming move is a Physical or Special attack move.
|
||||||
*/
|
*/
|
||||||
class MatBlockTag extends ConditionalProtectTag {
|
class MatBlockTag extends ConditionalProtectTag {
|
||||||
constructor(sourceId: integer, side: ArenaTagSide) {
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.MAT_BLOCK, Moves.MAT_BLOCK, sourceId, side, MatBlockConditionFunc);
|
super(ArenaTagType.MAT_BLOCK, Moves.MAT_BLOCK, sourceId, side, MatBlockConditionFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +377,7 @@ const CraftyShieldConditionFunc: ProtectConditionFunc = (arena, moveId) => {
|
|||||||
* not target all Pokemon or sides of the field.
|
* not target all Pokemon or sides of the field.
|
||||||
*/
|
*/
|
||||||
class CraftyShieldTag extends ConditionalProtectTag {
|
class CraftyShieldTag extends ConditionalProtectTag {
|
||||||
constructor(sourceId: integer, side: ArenaTagSide) {
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.CRAFTY_SHIELD, Moves.CRAFTY_SHIELD, sourceId, side, CraftyShieldConditionFunc, true);
|
super(ArenaTagType.CRAFTY_SHIELD, Moves.CRAFTY_SHIELD, sourceId, side, CraftyShieldConditionFunc, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -384,12 +389,12 @@ class CraftyShieldTag extends ConditionalProtectTag {
|
|||||||
export class NoCritTag extends ArenaTag {
|
export class NoCritTag extends ArenaTag {
|
||||||
/**
|
/**
|
||||||
* Constructor method for the NoCritTag class
|
* Constructor method for the NoCritTag class
|
||||||
* @param turnCount `integer` the number of turns this effect lasts
|
* @param turnCount `number` the number of turns this effect lasts
|
||||||
* @param sourceMove {@linkcode Moves} the move that created this effect
|
* @param sourceMove {@linkcode Moves} the move that created this effect
|
||||||
* @param sourceId `integer` the ID of the {@linkcode Pokemon} that created this effect
|
* @param sourceId `number` the ID of the {@linkcode Pokemon} that created this effect
|
||||||
* @param side {@linkcode ArenaTagSide} the side to which this effect belongs
|
* @param side {@linkcode ArenaTagSide} the side to which this effect belongs
|
||||||
*/
|
*/
|
||||||
constructor(turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: number, sourceMove: Moves, sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.NO_CRIT, turnCount, sourceMove, sourceId, side);
|
super(ArenaTagType.NO_CRIT, turnCount, sourceMove, sourceId, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +424,7 @@ class WishTag extends ArenaTag {
|
|||||||
private triggerMessage: string;
|
private triggerMessage: string;
|
||||||
private healHp: number;
|
private healHp: number;
|
||||||
|
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.WISH, turnCount, Moves.WISH, sourceId, side);
|
super(ArenaTagType.WISH, turnCount, Moves.WISH, sourceId, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +465,7 @@ export class WeakenMoveTypeTag extends ArenaTag {
|
|||||||
* @param sourceMove - The move that created the tag.
|
* @param sourceMove - The move that created the tag.
|
||||||
* @param sourceId - The ID of the source of the tag.
|
* @param sourceId - The ID of the source of the tag.
|
||||||
*/
|
*/
|
||||||
constructor(tagType: ArenaTagType, turnCount: integer, type: Type, sourceMove: Moves, sourceId: integer) {
|
constructor(tagType: ArenaTagType, turnCount: number, type: Type, sourceMove: Moves, sourceId: number) {
|
||||||
super(tagType, turnCount, sourceMove, sourceId);
|
super(tagType, turnCount, sourceMove, sourceId);
|
||||||
|
|
||||||
this.weakenedType = type;
|
this.weakenedType = type;
|
||||||
@ -481,7 +486,7 @@ export class WeakenMoveTypeTag extends ArenaTag {
|
|||||||
* Weakens Electric type moves for a set amount of turns, usually 5.
|
* Weakens Electric type moves for a set amount of turns, usually 5.
|
||||||
*/
|
*/
|
||||||
class MudSportTag extends WeakenMoveTypeTag {
|
class MudSportTag extends WeakenMoveTypeTag {
|
||||||
constructor(turnCount: integer, sourceId: integer) {
|
constructor(turnCount: number, sourceId: number) {
|
||||||
super(ArenaTagType.MUD_SPORT, turnCount, Type.ELECTRIC, Moves.MUD_SPORT, sourceId);
|
super(ArenaTagType.MUD_SPORT, turnCount, Type.ELECTRIC, Moves.MUD_SPORT, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,7 +504,7 @@ class MudSportTag extends WeakenMoveTypeTag {
|
|||||||
* Weakens Fire type moves for a set amount of turns, usually 5.
|
* Weakens Fire type moves for a set amount of turns, usually 5.
|
||||||
*/
|
*/
|
||||||
class WaterSportTag extends WeakenMoveTypeTag {
|
class WaterSportTag extends WeakenMoveTypeTag {
|
||||||
constructor(turnCount: integer, sourceId: integer) {
|
constructor(turnCount: number, sourceId: number) {
|
||||||
super(ArenaTagType.WATER_SPORT, turnCount, Type.FIRE, Moves.WATER_SPORT, sourceId);
|
super(ArenaTagType.WATER_SPORT, turnCount, Type.FIRE, Moves.WATER_SPORT, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,8 +555,8 @@ export class IonDelugeTag extends ArenaTag {
|
|||||||
* Abstract class to implement arena traps.
|
* Abstract class to implement arena traps.
|
||||||
*/
|
*/
|
||||||
export class ArenaTrapTag extends ArenaTag {
|
export class ArenaTrapTag extends ArenaTag {
|
||||||
public layers: integer;
|
public layers: number;
|
||||||
public maxLayers: integer;
|
public maxLayers: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of the ArenaTrapTag class.
|
* Creates a new instance of the ArenaTrapTag class.
|
||||||
@ -562,7 +567,7 @@ export class ArenaTrapTag extends ArenaTag {
|
|||||||
* @param side - The side (player or enemy) the tag affects.
|
* @param side - The side (player or enemy) the tag affects.
|
||||||
* @param maxLayers - The maximum amount of layers this tag can have.
|
* @param maxLayers - The maximum amount of layers this tag can have.
|
||||||
*/
|
*/
|
||||||
constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, maxLayers: integer) {
|
constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: number, side: ArenaTagSide, maxLayers: number) {
|
||||||
super(tagType, 0, sourceMove, sourceId, side);
|
super(tagType, 0, sourceMove, sourceId, side);
|
||||||
|
|
||||||
this.layers = 1;
|
this.layers = 1;
|
||||||
@ -593,6 +598,12 @@ export class ArenaTrapTag extends ArenaTag {
|
|||||||
getMatchupScoreMultiplier(pokemon: Pokemon): number {
|
getMatchupScoreMultiplier(pokemon: Pokemon): number {
|
||||||
return pokemon.isGrounded() ? 1 : Phaser.Math.Linear(0, 1 / Math.pow(2, this.layers), Math.min(pokemon.getHpRatio(), 0.5) * 2);
|
return pokemon.isGrounded() ? 1 : Phaser.Math.Linear(0, 1 / Math.pow(2, this.layers), Math.min(pokemon.getHpRatio(), 0.5) * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadTag(source: any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.layers = source.layers;
|
||||||
|
this.maxLayers = source.maxLayers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -601,7 +612,7 @@ export class ArenaTrapTag extends ArenaTag {
|
|||||||
* in damage for 1, 2, or 3 layers of Spikes respectively if they are summoned into this trap.
|
* in damage for 1, 2, or 3 layers of Spikes respectively if they are summoned into this trap.
|
||||||
*/
|
*/
|
||||||
class SpikesTag extends ArenaTrapTag {
|
class SpikesTag extends ArenaTrapTag {
|
||||||
constructor(sourceId: integer, side: ArenaTagSide) {
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.SPIKES, Moves.SPIKES, sourceId, side, 3);
|
super(ArenaTagType.SPIKES, Moves.SPIKES, sourceId, side, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,7 +656,7 @@ class SpikesTag extends ArenaTrapTag {
|
|||||||
class ToxicSpikesTag extends ArenaTrapTag {
|
class ToxicSpikesTag extends ArenaTrapTag {
|
||||||
private neutralized: boolean;
|
private neutralized: boolean;
|
||||||
|
|
||||||
constructor(sourceId: integer, side: ArenaTagSide) {
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.TOXIC_SPIKES, Moves.TOXIC_SPIKES, sourceId, side, 2);
|
super(ArenaTagType.TOXIC_SPIKES, Moves.TOXIC_SPIKES, sourceId, side, 2);
|
||||||
this.neutralized = false;
|
this.neutralized = false;
|
||||||
}
|
}
|
||||||
@ -703,7 +714,7 @@ class ToxicSpikesTag extends ArenaTrapTag {
|
|||||||
class DelayedAttackTag extends ArenaTag {
|
class DelayedAttackTag extends ArenaTag {
|
||||||
public targetIndex: BattlerIndex;
|
public targetIndex: BattlerIndex;
|
||||||
|
|
||||||
constructor(tagType: ArenaTagType, sourceMove: Moves | undefined, sourceId: integer, targetIndex: BattlerIndex) {
|
constructor(tagType: ArenaTagType, sourceMove: Moves | undefined, sourceId: number, targetIndex: BattlerIndex) {
|
||||||
super(tagType, 3, sourceMove, sourceId);
|
super(tagType, 3, sourceMove, sourceId);
|
||||||
|
|
||||||
this.targetIndex = targetIndex;
|
this.targetIndex = targetIndex;
|
||||||
@ -728,7 +739,7 @@ class DelayedAttackTag extends ArenaTag {
|
|||||||
* who is summoned into the trap, based on the Rock type's type effectiveness.
|
* who is summoned into the trap, based on the Rock type's type effectiveness.
|
||||||
*/
|
*/
|
||||||
class StealthRockTag extends ArenaTrapTag {
|
class StealthRockTag extends ArenaTrapTag {
|
||||||
constructor(sourceId: integer, side: ArenaTagSide) {
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.STEALTH_ROCK, Moves.STEALTH_ROCK, sourceId, side, 1);
|
super(ArenaTagType.STEALTH_ROCK, Moves.STEALTH_ROCK, sourceId, side, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,7 +815,7 @@ class StealthRockTag extends ArenaTrapTag {
|
|||||||
* to any Pokémon who is summoned into this trap.
|
* to any Pokémon who is summoned into this trap.
|
||||||
*/
|
*/
|
||||||
class StickyWebTag extends ArenaTrapTag {
|
class StickyWebTag extends ArenaTrapTag {
|
||||||
constructor(sourceId: integer, side: ArenaTagSide) {
|
constructor(sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.STICKY_WEB, Moves.STICKY_WEB, sourceId, side, 1);
|
super(ArenaTagType.STICKY_WEB, Moves.STICKY_WEB, sourceId, side, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -838,7 +849,7 @@ class StickyWebTag extends ArenaTrapTag {
|
|||||||
* also reversing the turn order for all Pokémon on the field as well.
|
* also reversing the turn order for all Pokémon on the field as well.
|
||||||
*/
|
*/
|
||||||
export class TrickRoomTag extends ArenaTag {
|
export class TrickRoomTag extends ArenaTag {
|
||||||
constructor(turnCount: integer, sourceId: integer) {
|
constructor(turnCount: number, sourceId: number) {
|
||||||
super(ArenaTagType.TRICK_ROOM, turnCount, Moves.TRICK_ROOM, sourceId);
|
super(ArenaTagType.TRICK_ROOM, turnCount, Moves.TRICK_ROOM, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -866,7 +877,7 @@ export class TrickRoomTag extends ArenaTag {
|
|||||||
* {@linkcode Abilities.LEVITATE} for the duration of the arena tag, usually 5 turns.
|
* {@linkcode Abilities.LEVITATE} for the duration of the arena tag, usually 5 turns.
|
||||||
*/
|
*/
|
||||||
export class GravityTag extends ArenaTag {
|
export class GravityTag extends ArenaTag {
|
||||||
constructor(turnCount: integer) {
|
constructor(turnCount: number) {
|
||||||
super(ArenaTagType.GRAVITY, turnCount, Moves.GRAVITY);
|
super(ArenaTagType.GRAVITY, turnCount, Moves.GRAVITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -874,7 +885,8 @@ export class GravityTag extends ArenaTag {
|
|||||||
arena.scene.queueMessage(i18next.t("arenaTag:gravityOnAdd"));
|
arena.scene.queueMessage(i18next.t("arenaTag:gravityOnAdd"));
|
||||||
arena.scene.getField(true).forEach((pokemon) => {
|
arena.scene.getField(true).forEach((pokemon) => {
|
||||||
if (pokemon !== null) {
|
if (pokemon !== null) {
|
||||||
pokemon.removeTag(BattlerTagType.MAGNET_RISEN);
|
pokemon.removeTag(BattlerTagType.FLOATING);
|
||||||
|
pokemon.removeTag(BattlerTagType.TELEKINESIS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -890,7 +902,7 @@ export class GravityTag extends ArenaTag {
|
|||||||
* Applies this arena tag for 4 turns (including the turn the move was used).
|
* Applies this arena tag for 4 turns (including the turn the move was used).
|
||||||
*/
|
*/
|
||||||
class TailwindTag extends ArenaTag {
|
class TailwindTag extends ArenaTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.TAILWIND, turnCount, Moves.TAILWIND, sourceId, side);
|
super(ArenaTagType.TAILWIND, turnCount, Moves.TAILWIND, sourceId, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -928,7 +940,7 @@ class TailwindTag extends ArenaTag {
|
|||||||
* Doubles the prize money from trainers and money moves like {@linkcode Moves.PAY_DAY} and {@linkcode Moves.MAKE_IT_RAIN}.
|
* Doubles the prize money from trainers and money moves like {@linkcode Moves.PAY_DAY} and {@linkcode Moves.MAKE_IT_RAIN}.
|
||||||
*/
|
*/
|
||||||
class HappyHourTag extends ArenaTag {
|
class HappyHourTag extends ArenaTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.HAPPY_HOUR, turnCount, Moves.HAPPY_HOUR, sourceId, side);
|
super(ArenaTagType.HAPPY_HOUR, turnCount, Moves.HAPPY_HOUR, sourceId, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,7 +954,7 @@ class HappyHourTag extends ArenaTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SafeguardTag extends ArenaTag {
|
class SafeguardTag extends ArenaTag {
|
||||||
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
|
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
|
||||||
super(ArenaTagType.SAFEGUARD, turnCount, Moves.SAFEGUARD, sourceId, side);
|
super(ArenaTagType.SAFEGUARD, turnCount, Moves.SAFEGUARD, sourceId, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,6 +967,11 @@ class SafeguardTag extends ArenaTag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NoneTag extends ArenaTag {
|
||||||
|
constructor() {
|
||||||
|
super(ArenaTagType.NONE, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This arena tag facilitates the application of the move Imprison
|
* This arena tag facilitates the application of the move Imprison
|
||||||
* Imprison remains in effect as long as the source Pokemon is active and present on the field.
|
* Imprison remains in effect as long as the source Pokemon is active and present on the field.
|
||||||
@ -1102,7 +1119,8 @@ class GrassWaterPledgeTag extends ArenaTag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null {
|
// TODO: swap `sourceMove` and `sourceId` and make `sourceMove` an optional parameter
|
||||||
|
export function getArenaTag(tagType: ArenaTagType, turnCount: number, sourceMove: Moves | undefined, sourceId: number, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null {
|
||||||
switch (tagType) {
|
switch (tagType) {
|
||||||
case ArenaTagType.MIST:
|
case ArenaTagType.MIST:
|
||||||
return new MistTag(turnCount, sourceId, side);
|
return new MistTag(turnCount, sourceId, side);
|
||||||
@ -1163,3 +1181,16 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When given a battler tag or json representing one, creates an actual ArenaTag object with the same data.
|
||||||
|
* @param {ArenaTag | any} source An arena tag
|
||||||
|
* @return {ArenaTag} The valid arena tag
|
||||||
|
*/
|
||||||
|
export function loadArenaTag(source: ArenaTag | any): ArenaTag {
|
||||||
|
const tag = getArenaTag(source.tagType, source.turnCount, source.sourceMove, source.sourceId, source.targetIndex, source.side)
|
||||||
|
?? new NoneTag();
|
||||||
|
tag.loadTag(source);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
603
src/data/balance/species-egg-tiers.ts
Normal file
@ -0,0 +1,603 @@
|
|||||||
|
import { Species } from "#enums/species";
|
||||||
|
import { EggTier } from "#enums/egg-type";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of all starters and their respective {@linkcode EggTier}, which determines the type of egg the starter hatches from.
|
||||||
|
*/
|
||||||
|
export const speciesEggTiers = {
|
||||||
|
[Species.BULBASAUR]: EggTier.COMMON,
|
||||||
|
[Species.CHARMANDER]: EggTier.COMMON,
|
||||||
|
[Species.SQUIRTLE]: EggTier.COMMON,
|
||||||
|
[Species.CATERPIE]: EggTier.COMMON,
|
||||||
|
[Species.WEEDLE]: EggTier.COMMON,
|
||||||
|
[Species.PIDGEY]: EggTier.COMMON,
|
||||||
|
[Species.RATTATA]: EggTier.COMMON,
|
||||||
|
[Species.SPEAROW]: EggTier.COMMON,
|
||||||
|
[Species.EKANS]: EggTier.COMMON,
|
||||||
|
[Species.PIKACHU]: EggTier.COMMON,
|
||||||
|
[Species.SANDSHREW]: EggTier.COMMON,
|
||||||
|
[Species.NIDORAN_F]: EggTier.COMMON,
|
||||||
|
[Species.NIDORAN_M]: EggTier.COMMON,
|
||||||
|
[Species.CLEFAIRY]: EggTier.COMMON,
|
||||||
|
[Species.VULPIX]: EggTier.COMMON,
|
||||||
|
[Species.JIGGLYPUFF]: EggTier.COMMON,
|
||||||
|
[Species.ZUBAT]: EggTier.COMMON,
|
||||||
|
[Species.ODDISH]: EggTier.COMMON,
|
||||||
|
[Species.PARAS]: EggTier.COMMON,
|
||||||
|
[Species.VENONAT]: EggTier.COMMON,
|
||||||
|
[Species.DIGLETT]: EggTier.COMMON,
|
||||||
|
[Species.MEOWTH]: EggTier.COMMON,
|
||||||
|
[Species.PSYDUCK]: EggTier.COMMON,
|
||||||
|
[Species.MANKEY]: EggTier.RARE,
|
||||||
|
[Species.GROWLITHE]: EggTier.RARE,
|
||||||
|
[Species.POLIWAG]: EggTier.COMMON,
|
||||||
|
[Species.ABRA]: EggTier.RARE,
|
||||||
|
[Species.MACHOP]: EggTier.COMMON,
|
||||||
|
[Species.BELLSPROUT]: EggTier.COMMON,
|
||||||
|
[Species.TENTACOOL]: EggTier.COMMON,
|
||||||
|
[Species.GEODUDE]: EggTier.COMMON,
|
||||||
|
[Species.PONYTA]: EggTier.COMMON,
|
||||||
|
[Species.SLOWPOKE]: EggTier.COMMON,
|
||||||
|
[Species.MAGNEMITE]: EggTier.RARE,
|
||||||
|
[Species.FARFETCHD]: EggTier.COMMON,
|
||||||
|
[Species.DODUO]: EggTier.COMMON,
|
||||||
|
[Species.SEEL]: EggTier.COMMON,
|
||||||
|
[Species.GRIMER]: EggTier.COMMON,
|
||||||
|
[Species.SHELLDER]: EggTier.RARE,
|
||||||
|
[Species.GASTLY]: EggTier.RARE,
|
||||||
|
[Species.ONIX]: EggTier.COMMON,
|
||||||
|
[Species.DROWZEE]: EggTier.COMMON,
|
||||||
|
[Species.KRABBY]: EggTier.COMMON,
|
||||||
|
[Species.VOLTORB]: EggTier.COMMON,
|
||||||
|
[Species.EXEGGCUTE]: EggTier.COMMON,
|
||||||
|
[Species.CUBONE]: EggTier.COMMON,
|
||||||
|
[Species.HITMONLEE]: EggTier.RARE,
|
||||||
|
[Species.HITMONCHAN]: EggTier.RARE,
|
||||||
|
[Species.LICKITUNG]: EggTier.COMMON,
|
||||||
|
[Species.KOFFING]: EggTier.COMMON,
|
||||||
|
[Species.RHYHORN]: EggTier.COMMON,
|
||||||
|
[Species.CHANSEY]: EggTier.COMMON,
|
||||||
|
[Species.TANGELA]: EggTier.COMMON,
|
||||||
|
[Species.KANGASKHAN]: EggTier.RARE,
|
||||||
|
[Species.HORSEA]: EggTier.COMMON,
|
||||||
|
[Species.GOLDEEN]: EggTier.COMMON,
|
||||||
|
[Species.STARYU]: EggTier.COMMON,
|
||||||
|
[Species.MR_MIME]: EggTier.COMMON,
|
||||||
|
[Species.SCYTHER]: EggTier.RARE,
|
||||||
|
[Species.JYNX]: EggTier.RARE,
|
||||||
|
[Species.ELECTABUZZ]: EggTier.RARE,
|
||||||
|
[Species.MAGMAR]: EggTier.RARE,
|
||||||
|
[Species.PINSIR]: EggTier.RARE,
|
||||||
|
[Species.TAUROS]: EggTier.RARE,
|
||||||
|
[Species.MAGIKARP]: EggTier.RARE,
|
||||||
|
[Species.LAPRAS]: EggTier.RARE,
|
||||||
|
[Species.DITTO]: EggTier.COMMON,
|
||||||
|
[Species.EEVEE]: EggTier.COMMON,
|
||||||
|
[Species.PORYGON]: EggTier.RARE,
|
||||||
|
[Species.OMANYTE]: EggTier.COMMON,
|
||||||
|
[Species.KABUTO]: EggTier.COMMON,
|
||||||
|
[Species.AERODACTYL]: EggTier.RARE,
|
||||||
|
[Species.SNORLAX]: EggTier.RARE,
|
||||||
|
[Species.ARTICUNO]: EggTier.EPIC,
|
||||||
|
[Species.ZAPDOS]: EggTier.EPIC,
|
||||||
|
[Species.MOLTRES]: EggTier.EPIC,
|
||||||
|
[Species.DRATINI]: EggTier.RARE,
|
||||||
|
[Species.MEWTWO]: EggTier.LEGENDARY,
|
||||||
|
[Species.MEW]: EggTier.EPIC,
|
||||||
|
|
||||||
|
[Species.CHIKORITA]: EggTier.COMMON,
|
||||||
|
[Species.CYNDAQUIL]: EggTier.COMMON,
|
||||||
|
[Species.TOTODILE]: EggTier.COMMON,
|
||||||
|
[Species.SENTRET]: EggTier.COMMON,
|
||||||
|
[Species.HOOTHOOT]: EggTier.COMMON,
|
||||||
|
[Species.LEDYBA]: EggTier.COMMON,
|
||||||
|
[Species.SPINARAK]: EggTier.COMMON,
|
||||||
|
[Species.CHINCHOU]: EggTier.COMMON,
|
||||||
|
[Species.PICHU]: EggTier.COMMON,
|
||||||
|
[Species.CLEFFA]: EggTier.COMMON,
|
||||||
|
[Species.IGGLYBUFF]: EggTier.COMMON,
|
||||||
|
[Species.TOGEPI]: EggTier.COMMON,
|
||||||
|
[Species.NATU]: EggTier.COMMON,
|
||||||
|
[Species.MAREEP]: EggTier.COMMON,
|
||||||
|
[Species.MARILL]: EggTier.RARE,
|
||||||
|
[Species.SUDOWOODO]: EggTier.COMMON,
|
||||||
|
[Species.HOPPIP]: EggTier.COMMON,
|
||||||
|
[Species.AIPOM]: EggTier.COMMON,
|
||||||
|
[Species.SUNKERN]: EggTier.COMMON,
|
||||||
|
[Species.YANMA]: EggTier.COMMON,
|
||||||
|
[Species.WOOPER]: EggTier.COMMON,
|
||||||
|
[Species.MURKROW]: EggTier.COMMON,
|
||||||
|
[Species.MISDREAVUS]: EggTier.COMMON,
|
||||||
|
[Species.UNOWN]: EggTier.COMMON,
|
||||||
|
[Species.WOBBUFFET]: EggTier.COMMON,
|
||||||
|
[Species.GIRAFARIG]: EggTier.COMMON,
|
||||||
|
[Species.PINECO]: EggTier.COMMON,
|
||||||
|
[Species.DUNSPARCE]: EggTier.COMMON,
|
||||||
|
[Species.GLIGAR]: EggTier.COMMON,
|
||||||
|
[Species.SNUBBULL]: EggTier.COMMON,
|
||||||
|
[Species.QWILFISH]: EggTier.COMMON,
|
||||||
|
[Species.SHUCKLE]: EggTier.COMMON,
|
||||||
|
[Species.HERACROSS]: EggTier.RARE,
|
||||||
|
[Species.SNEASEL]: EggTier.RARE,
|
||||||
|
[Species.TEDDIURSA]: EggTier.RARE,
|
||||||
|
[Species.SLUGMA]: EggTier.COMMON,
|
||||||
|
[Species.SWINUB]: EggTier.COMMON,
|
||||||
|
[Species.CORSOLA]: EggTier.COMMON,
|
||||||
|
[Species.REMORAID]: EggTier.COMMON,
|
||||||
|
[Species.DELIBIRD]: EggTier.COMMON,
|
||||||
|
[Species.MANTINE]: EggTier.COMMON,
|
||||||
|
[Species.SKARMORY]: EggTier.RARE,
|
||||||
|
[Species.HOUNDOUR]: EggTier.COMMON,
|
||||||
|
[Species.PHANPY]: EggTier.COMMON,
|
||||||
|
[Species.STANTLER]: EggTier.COMMON,
|
||||||
|
[Species.SMEARGLE]: EggTier.COMMON,
|
||||||
|
[Species.TYROGUE]: EggTier.COMMON,
|
||||||
|
[Species.SMOOCHUM]: EggTier.COMMON,
|
||||||
|
[Species.ELEKID]: EggTier.COMMON,
|
||||||
|
[Species.MAGBY]: EggTier.COMMON,
|
||||||
|
[Species.MILTANK]: EggTier.RARE,
|
||||||
|
[Species.RAIKOU]: EggTier.EPIC,
|
||||||
|
[Species.ENTEI]: EggTier.EPIC,
|
||||||
|
[Species.SUICUNE]: EggTier.EPIC,
|
||||||
|
[Species.LARVITAR]: EggTier.RARE,
|
||||||
|
[Species.LUGIA]: EggTier.LEGENDARY,
|
||||||
|
[Species.HO_OH]: EggTier.LEGENDARY,
|
||||||
|
[Species.CELEBI]: EggTier.EPIC,
|
||||||
|
|
||||||
|
[Species.TREECKO]: EggTier.COMMON,
|
||||||
|
[Species.TORCHIC]: EggTier.RARE,
|
||||||
|
[Species.MUDKIP]: EggTier.COMMON,
|
||||||
|
[Species.POOCHYENA]: EggTier.COMMON,
|
||||||
|
[Species.ZIGZAGOON]: EggTier.COMMON,
|
||||||
|
[Species.WURMPLE]: EggTier.COMMON,
|
||||||
|
[Species.LOTAD]: EggTier.COMMON,
|
||||||
|
[Species.SEEDOT]: EggTier.COMMON,
|
||||||
|
[Species.TAILLOW]: EggTier.COMMON,
|
||||||
|
[Species.WINGULL]: EggTier.COMMON,
|
||||||
|
[Species.RALTS]: EggTier.COMMON,
|
||||||
|
[Species.SURSKIT]: EggTier.COMMON,
|
||||||
|
[Species.SHROOMISH]: EggTier.COMMON,
|
||||||
|
[Species.SLAKOTH]: EggTier.RARE,
|
||||||
|
[Species.NINCADA]: EggTier.RARE,
|
||||||
|
[Species.WHISMUR]: EggTier.COMMON,
|
||||||
|
[Species.MAKUHITA]: EggTier.COMMON,
|
||||||
|
[Species.AZURILL]: EggTier.RARE,
|
||||||
|
[Species.NOSEPASS]: EggTier.COMMON,
|
||||||
|
[Species.SKITTY]: EggTier.COMMON,
|
||||||
|
[Species.SABLEYE]: EggTier.COMMON,
|
||||||
|
[Species.MAWILE]: EggTier.COMMON,
|
||||||
|
[Species.ARON]: EggTier.COMMON,
|
||||||
|
[Species.MEDITITE]: EggTier.COMMON,
|
||||||
|
[Species.ELECTRIKE]: EggTier.COMMON,
|
||||||
|
[Species.PLUSLE]: EggTier.COMMON,
|
||||||
|
[Species.MINUN]: EggTier.COMMON,
|
||||||
|
[Species.VOLBEAT]: EggTier.COMMON,
|
||||||
|
[Species.ILLUMISE]: EggTier.COMMON,
|
||||||
|
[Species.ROSELIA]: EggTier.COMMON,
|
||||||
|
[Species.GULPIN]: EggTier.COMMON,
|
||||||
|
[Species.CARVANHA]: EggTier.COMMON,
|
||||||
|
[Species.WAILMER]: EggTier.COMMON,
|
||||||
|
[Species.NUMEL]: EggTier.COMMON,
|
||||||
|
[Species.TORKOAL]: EggTier.COMMON,
|
||||||
|
[Species.SPOINK]: EggTier.COMMON,
|
||||||
|
[Species.SPINDA]: EggTier.COMMON,
|
||||||
|
[Species.TRAPINCH]: EggTier.COMMON,
|
||||||
|
[Species.CACNEA]: EggTier.COMMON,
|
||||||
|
[Species.SWABLU]: EggTier.COMMON,
|
||||||
|
[Species.ZANGOOSE]: EggTier.RARE,
|
||||||
|
[Species.SEVIPER]: EggTier.COMMON,
|
||||||
|
[Species.LUNATONE]: EggTier.COMMON,
|
||||||
|
[Species.SOLROCK]: EggTier.COMMON,
|
||||||
|
[Species.BARBOACH]: EggTier.COMMON,
|
||||||
|
[Species.CORPHISH]: EggTier.COMMON,
|
||||||
|
[Species.BALTOY]: EggTier.COMMON,
|
||||||
|
[Species.LILEEP]: EggTier.COMMON,
|
||||||
|
[Species.ANORITH]: EggTier.COMMON,
|
||||||
|
[Species.FEEBAS]: EggTier.RARE,
|
||||||
|
[Species.CASTFORM]: EggTier.COMMON,
|
||||||
|
[Species.KECLEON]: EggTier.COMMON,
|
||||||
|
[Species.SHUPPET]: EggTier.COMMON,
|
||||||
|
[Species.DUSKULL]: EggTier.COMMON,
|
||||||
|
[Species.TROPIUS]: EggTier.COMMON,
|
||||||
|
[Species.CHIMECHO]: EggTier.COMMON,
|
||||||
|
[Species.ABSOL]: EggTier.RARE,
|
||||||
|
[Species.WYNAUT]: EggTier.COMMON,
|
||||||
|
[Species.SNORUNT]: EggTier.COMMON,
|
||||||
|
[Species.SPHEAL]: EggTier.COMMON,
|
||||||
|
[Species.CLAMPERL]: EggTier.COMMON,
|
||||||
|
[Species.RELICANTH]: EggTier.COMMON,
|
||||||
|
[Species.LUVDISC]: EggTier.COMMON,
|
||||||
|
[Species.BAGON]: EggTier.RARE,
|
||||||
|
[Species.BELDUM]: EggTier.RARE,
|
||||||
|
[Species.REGIROCK]: EggTier.EPIC,
|
||||||
|
[Species.REGICE]: EggTier.EPIC,
|
||||||
|
[Species.REGISTEEL]: EggTier.EPIC,
|
||||||
|
[Species.LATIAS]: EggTier.EPIC,
|
||||||
|
[Species.LATIOS]: EggTier.EPIC,
|
||||||
|
[Species.KYOGRE]: EggTier.LEGENDARY,
|
||||||
|
[Species.GROUDON]: EggTier.LEGENDARY,
|
||||||
|
[Species.RAYQUAZA]: EggTier.LEGENDARY,
|
||||||
|
[Species.JIRACHI]: EggTier.EPIC,
|
||||||
|
[Species.DEOXYS]: EggTier.EPIC,
|
||||||
|
|
||||||
|
[Species.TURTWIG]: EggTier.COMMON,
|
||||||
|
[Species.CHIMCHAR]: EggTier.COMMON,
|
||||||
|
[Species.PIPLUP]: EggTier.COMMON,
|
||||||
|
[Species.STARLY]: EggTier.COMMON,
|
||||||
|
[Species.BIDOOF]: EggTier.COMMON,
|
||||||
|
[Species.KRICKETOT]: EggTier.COMMON,
|
||||||
|
[Species.SHINX]: EggTier.COMMON,
|
||||||
|
[Species.BUDEW]: EggTier.COMMON,
|
||||||
|
[Species.CRANIDOS]: EggTier.COMMON,
|
||||||
|
[Species.SHIELDON]: EggTier.COMMON,
|
||||||
|
[Species.BURMY]: EggTier.COMMON,
|
||||||
|
[Species.COMBEE]: EggTier.COMMON,
|
||||||
|
[Species.PACHIRISU]: EggTier.COMMON,
|
||||||
|
[Species.BUIZEL]: EggTier.COMMON,
|
||||||
|
[Species.CHERUBI]: EggTier.COMMON,
|
||||||
|
[Species.SHELLOS]: EggTier.COMMON,
|
||||||
|
[Species.DRIFLOON]: EggTier.COMMON,
|
||||||
|
[Species.BUNEARY]: EggTier.COMMON,
|
||||||
|
[Species.GLAMEOW]: EggTier.COMMON,
|
||||||
|
[Species.CHINGLING]: EggTier.COMMON,
|
||||||
|
[Species.STUNKY]: EggTier.COMMON,
|
||||||
|
[Species.BRONZOR]: EggTier.COMMON,
|
||||||
|
[Species.BONSLY]: EggTier.COMMON,
|
||||||
|
[Species.MIME_JR]: EggTier.COMMON,
|
||||||
|
[Species.HAPPINY]: EggTier.COMMON,
|
||||||
|
[Species.CHATOT]: EggTier.COMMON,
|
||||||
|
[Species.SPIRITOMB]: EggTier.RARE,
|
||||||
|
[Species.GIBLE]: EggTier.RARE,
|
||||||
|
[Species.MUNCHLAX]: EggTier.RARE,
|
||||||
|
[Species.RIOLU]: EggTier.COMMON,
|
||||||
|
[Species.HIPPOPOTAS]: EggTier.COMMON,
|
||||||
|
[Species.SKORUPI]: EggTier.COMMON,
|
||||||
|
[Species.CROAGUNK]: EggTier.COMMON,
|
||||||
|
[Species.CARNIVINE]: EggTier.COMMON,
|
||||||
|
[Species.FINNEON]: EggTier.COMMON,
|
||||||
|
[Species.MANTYKE]: EggTier.COMMON,
|
||||||
|
[Species.SNOVER]: EggTier.COMMON,
|
||||||
|
[Species.ROTOM]: EggTier.RARE,
|
||||||
|
[Species.UXIE]: EggTier.EPIC,
|
||||||
|
[Species.MESPRIT]: EggTier.EPIC,
|
||||||
|
[Species.AZELF]: EggTier.EPIC,
|
||||||
|
[Species.DIALGA]: EggTier.LEGENDARY,
|
||||||
|
[Species.PALKIA]: EggTier.LEGENDARY,
|
||||||
|
[Species.HEATRAN]: EggTier.EPIC,
|
||||||
|
[Species.REGIGIGAS]: EggTier.EPIC,
|
||||||
|
[Species.GIRATINA]: EggTier.LEGENDARY,
|
||||||
|
[Species.CRESSELIA]: EggTier.EPIC,
|
||||||
|
[Species.PHIONE]: EggTier.RARE,
|
||||||
|
[Species.MANAPHY]: EggTier.EPIC,
|
||||||
|
[Species.DARKRAI]: EggTier.EPIC,
|
||||||
|
[Species.SHAYMIN]: EggTier.EPIC,
|
||||||
|
[Species.ARCEUS]: EggTier.LEGENDARY,
|
||||||
|
|
||||||
|
[Species.VICTINI]: EggTier.EPIC,
|
||||||
|
[Species.SNIVY]: EggTier.COMMON,
|
||||||
|
[Species.TEPIG]: EggTier.COMMON,
|
||||||
|
[Species.OSHAWOTT]: EggTier.COMMON,
|
||||||
|
[Species.PATRAT]: EggTier.COMMON,
|
||||||
|
[Species.LILLIPUP]: EggTier.COMMON,
|
||||||
|
[Species.PURRLOIN]: EggTier.COMMON,
|
||||||
|
[Species.PANSAGE]: EggTier.COMMON,
|
||||||
|
[Species.PANSEAR]: EggTier.COMMON,
|
||||||
|
[Species.PANPOUR]: EggTier.COMMON,
|
||||||
|
[Species.MUNNA]: EggTier.COMMON,
|
||||||
|
[Species.PIDOVE]: EggTier.COMMON,
|
||||||
|
[Species.BLITZLE]: EggTier.COMMON,
|
||||||
|
[Species.ROGGENROLA]: EggTier.COMMON,
|
||||||
|
[Species.WOOBAT]: EggTier.COMMON,
|
||||||
|
[Species.DRILBUR]: EggTier.RARE,
|
||||||
|
[Species.AUDINO]: EggTier.COMMON,
|
||||||
|
[Species.TIMBURR]: EggTier.RARE,
|
||||||
|
[Species.TYMPOLE]: EggTier.COMMON,
|
||||||
|
[Species.THROH]: EggTier.RARE,
|
||||||
|
[Species.SAWK]: EggTier.RARE,
|
||||||
|
[Species.SEWADDLE]: EggTier.COMMON,
|
||||||
|
[Species.VENIPEDE]: EggTier.COMMON,
|
||||||
|
[Species.COTTONEE]: EggTier.COMMON,
|
||||||
|
[Species.PETILIL]: EggTier.COMMON,
|
||||||
|
[Species.BASCULIN]: EggTier.RARE,
|
||||||
|
[Species.SANDILE]: EggTier.RARE,
|
||||||
|
[Species.DARUMAKA]: EggTier.RARE,
|
||||||
|
[Species.MARACTUS]: EggTier.COMMON,
|
||||||
|
[Species.DWEBBLE]: EggTier.COMMON,
|
||||||
|
[Species.SCRAGGY]: EggTier.COMMON,
|
||||||
|
[Species.SIGILYPH]: EggTier.RARE,
|
||||||
|
[Species.YAMASK]: EggTier.COMMON,
|
||||||
|
[Species.TIRTOUGA]: EggTier.COMMON,
|
||||||
|
[Species.ARCHEN]: EggTier.COMMON,
|
||||||
|
[Species.TRUBBISH]: EggTier.COMMON,
|
||||||
|
[Species.ZORUA]: EggTier.COMMON,
|
||||||
|
[Species.MINCCINO]: EggTier.COMMON,
|
||||||
|
[Species.GOTHITA]: EggTier.COMMON,
|
||||||
|
[Species.SOLOSIS]: EggTier.COMMON,
|
||||||
|
[Species.DUCKLETT]: EggTier.COMMON,
|
||||||
|
[Species.VANILLITE]: EggTier.COMMON,
|
||||||
|
[Species.DEERLING]: EggTier.COMMON,
|
||||||
|
[Species.EMOLGA]: EggTier.COMMON,
|
||||||
|
[Species.KARRABLAST]: EggTier.COMMON,
|
||||||
|
[Species.FOONGUS]: EggTier.COMMON,
|
||||||
|
[Species.FRILLISH]: EggTier.COMMON,
|
||||||
|
[Species.ALOMOMOLA]: EggTier.RARE,
|
||||||
|
[Species.JOLTIK]: EggTier.COMMON,
|
||||||
|
[Species.FERROSEED]: EggTier.COMMON,
|
||||||
|
[Species.KLINK]: EggTier.COMMON,
|
||||||
|
[Species.TYNAMO]: EggTier.COMMON,
|
||||||
|
[Species.ELGYEM]: EggTier.COMMON,
|
||||||
|
[Species.LITWICK]: EggTier.COMMON,
|
||||||
|
[Species.AXEW]: EggTier.RARE,
|
||||||
|
[Species.CUBCHOO]: EggTier.COMMON,
|
||||||
|
[Species.CRYOGONAL]: EggTier.RARE,
|
||||||
|
[Species.SHELMET]: EggTier.COMMON,
|
||||||
|
[Species.STUNFISK]: EggTier.COMMON,
|
||||||
|
[Species.MIENFOO]: EggTier.COMMON,
|
||||||
|
[Species.DRUDDIGON]: EggTier.RARE,
|
||||||
|
[Species.GOLETT]: EggTier.COMMON,
|
||||||
|
[Species.PAWNIARD]: EggTier.RARE,
|
||||||
|
[Species.BOUFFALANT]: EggTier.RARE,
|
||||||
|
[Species.RUFFLET]: EggTier.COMMON,
|
||||||
|
[Species.VULLABY]: EggTier.COMMON,
|
||||||
|
[Species.HEATMOR]: EggTier.COMMON,
|
||||||
|
[Species.DURANT]: EggTier.RARE,
|
||||||
|
[Species.DEINO]: EggTier.RARE,
|
||||||
|
[Species.LARVESTA]: EggTier.RARE,
|
||||||
|
[Species.COBALION]: EggTier.EPIC,
|
||||||
|
[Species.TERRAKION]: EggTier.EPIC,
|
||||||
|
[Species.VIRIZION]: EggTier.EPIC,
|
||||||
|
[Species.TORNADUS]: EggTier.EPIC,
|
||||||
|
[Species.THUNDURUS]: EggTier.EPIC,
|
||||||
|
[Species.RESHIRAM]: EggTier.LEGENDARY,
|
||||||
|
[Species.ZEKROM]: EggTier.LEGENDARY,
|
||||||
|
[Species.LANDORUS]: EggTier.EPIC,
|
||||||
|
[Species.KYUREM]: EggTier.LEGENDARY,
|
||||||
|
[Species.KELDEO]: EggTier.EPIC,
|
||||||
|
[Species.MELOETTA]: EggTier.EPIC,
|
||||||
|
[Species.GENESECT]: EggTier.EPIC,
|
||||||
|
|
||||||
|
[Species.CHESPIN]: EggTier.COMMON,
|
||||||
|
[Species.FENNEKIN]: EggTier.COMMON,
|
||||||
|
[Species.FROAKIE]: EggTier.RARE,
|
||||||
|
[Species.BUNNELBY]: EggTier.COMMON,
|
||||||
|
[Species.FLETCHLING]: EggTier.COMMON,
|
||||||
|
[Species.SCATTERBUG]: EggTier.COMMON,
|
||||||
|
[Species.LITLEO]: EggTier.COMMON,
|
||||||
|
[Species.FLABEBE]: EggTier.COMMON,
|
||||||
|
[Species.SKIDDO]: EggTier.COMMON,
|
||||||
|
[Species.PANCHAM]: EggTier.COMMON,
|
||||||
|
[Species.FURFROU]: EggTier.COMMON,
|
||||||
|
[Species.ESPURR]: EggTier.COMMON,
|
||||||
|
[Species.HONEDGE]: EggTier.RARE,
|
||||||
|
[Species.SPRITZEE]: EggTier.COMMON,
|
||||||
|
[Species.SWIRLIX]: EggTier.COMMON,
|
||||||
|
[Species.INKAY]: EggTier.COMMON,
|
||||||
|
[Species.BINACLE]: EggTier.COMMON,
|
||||||
|
[Species.SKRELP]: EggTier.COMMON,
|
||||||
|
[Species.CLAUNCHER]: EggTier.COMMON,
|
||||||
|
[Species.HELIOPTILE]: EggTier.COMMON,
|
||||||
|
[Species.TYRUNT]: EggTier.COMMON,
|
||||||
|
[Species.AMAURA]: EggTier.COMMON,
|
||||||
|
[Species.HAWLUCHA]: EggTier.RARE,
|
||||||
|
[Species.DEDENNE]: EggTier.COMMON,
|
||||||
|
[Species.CARBINK]: EggTier.COMMON,
|
||||||
|
[Species.GOOMY]: EggTier.RARE,
|
||||||
|
[Species.KLEFKI]: EggTier.COMMON,
|
||||||
|
[Species.PHANTUMP]: EggTier.COMMON,
|
||||||
|
[Species.PUMPKABOO]: EggTier.COMMON,
|
||||||
|
[Species.BERGMITE]: EggTier.COMMON,
|
||||||
|
[Species.NOIBAT]: EggTier.COMMON,
|
||||||
|
[Species.XERNEAS]: EggTier.LEGENDARY,
|
||||||
|
[Species.YVELTAL]: EggTier.LEGENDARY,
|
||||||
|
[Species.ZYGARDE]: EggTier.LEGENDARY,
|
||||||
|
[Species.DIANCIE]: EggTier.EPIC,
|
||||||
|
[Species.HOOPA]: EggTier.EPIC,
|
||||||
|
[Species.VOLCANION]: EggTier.EPIC,
|
||||||
|
[Species.ETERNAL_FLOETTE]: EggTier.RARE,
|
||||||
|
|
||||||
|
[Species.ROWLET]: EggTier.COMMON,
|
||||||
|
[Species.LITTEN]: EggTier.COMMON,
|
||||||
|
[Species.POPPLIO]: EggTier.RARE,
|
||||||
|
[Species.PIKIPEK]: EggTier.COMMON,
|
||||||
|
[Species.YUNGOOS]: EggTier.COMMON,
|
||||||
|
[Species.GRUBBIN]: EggTier.COMMON,
|
||||||
|
[Species.CRABRAWLER]: EggTier.COMMON,
|
||||||
|
[Species.ORICORIO]: EggTier.COMMON,
|
||||||
|
[Species.CUTIEFLY]: EggTier.COMMON,
|
||||||
|
[Species.ROCKRUFF]: EggTier.COMMON,
|
||||||
|
[Species.WISHIWASHI]: EggTier.COMMON,
|
||||||
|
[Species.MAREANIE]: EggTier.COMMON,
|
||||||
|
[Species.MUDBRAY]: EggTier.COMMON,
|
||||||
|
[Species.DEWPIDER]: EggTier.COMMON,
|
||||||
|
[Species.FOMANTIS]: EggTier.COMMON,
|
||||||
|
[Species.MORELULL]: EggTier.COMMON,
|
||||||
|
[Species.SALANDIT]: EggTier.COMMON,
|
||||||
|
[Species.STUFFUL]: EggTier.COMMON,
|
||||||
|
[Species.BOUNSWEET]: EggTier.COMMON,
|
||||||
|
[Species.COMFEY]: EggTier.RARE,
|
||||||
|
[Species.ORANGURU]: EggTier.RARE,
|
||||||
|
[Species.PASSIMIAN]: EggTier.RARE,
|
||||||
|
[Species.WIMPOD]: EggTier.COMMON,
|
||||||
|
[Species.SANDYGAST]: EggTier.COMMON,
|
||||||
|
[Species.PYUKUMUKU]: EggTier.COMMON,
|
||||||
|
[Species.TYPE_NULL]: EggTier.RARE,
|
||||||
|
[Species.MINIOR]: EggTier.RARE,
|
||||||
|
[Species.KOMALA]: EggTier.COMMON,
|
||||||
|
[Species.TURTONATOR]: EggTier.RARE,
|
||||||
|
[Species.TOGEDEMARU]: EggTier.COMMON,
|
||||||
|
[Species.MIMIKYU]: EggTier.RARE,
|
||||||
|
[Species.BRUXISH]: EggTier.RARE,
|
||||||
|
[Species.DRAMPA]: EggTier.RARE,
|
||||||
|
[Species.DHELMISE]: EggTier.RARE,
|
||||||
|
[Species.JANGMO_O]: EggTier.RARE,
|
||||||
|
[Species.TAPU_KOKO]: EggTier.EPIC,
|
||||||
|
[Species.TAPU_LELE]: EggTier.EPIC,
|
||||||
|
[Species.TAPU_BULU]: EggTier.EPIC,
|
||||||
|
[Species.TAPU_FINI]: EggTier.EPIC,
|
||||||
|
[Species.COSMOG]: EggTier.EPIC,
|
||||||
|
[Species.NIHILEGO]: EggTier.EPIC,
|
||||||
|
[Species.BUZZWOLE]: EggTier.EPIC,
|
||||||
|
[Species.PHEROMOSA]: EggTier.EPIC,
|
||||||
|
[Species.XURKITREE]: EggTier.EPIC,
|
||||||
|
[Species.CELESTEELA]: EggTier.EPIC,
|
||||||
|
[Species.KARTANA]: EggTier.EPIC,
|
||||||
|
[Species.GUZZLORD]: EggTier.EPIC,
|
||||||
|
[Species.NECROZMA]: EggTier.LEGENDARY,
|
||||||
|
[Species.MAGEARNA]: EggTier.EPIC,
|
||||||
|
[Species.MARSHADOW]: EggTier.EPIC,
|
||||||
|
[Species.POIPOLE]: EggTier.EPIC,
|
||||||
|
[Species.STAKATAKA]: EggTier.EPIC,
|
||||||
|
[Species.BLACEPHALON]: EggTier.EPIC,
|
||||||
|
[Species.ZERAORA]: EggTier.EPIC,
|
||||||
|
[Species.MELTAN]: EggTier.EPIC,
|
||||||
|
[Species.ALOLA_RATTATA]: EggTier.COMMON,
|
||||||
|
[Species.ALOLA_SANDSHREW]: EggTier.COMMON,
|
||||||
|
[Species.ALOLA_VULPIX]: EggTier.COMMON,
|
||||||
|
[Species.ALOLA_DIGLETT]: EggTier.COMMON,
|
||||||
|
[Species.ALOLA_MEOWTH]: EggTier.COMMON,
|
||||||
|
[Species.ALOLA_GEODUDE]: EggTier.COMMON,
|
||||||
|
[Species.ALOLA_GRIMER]: EggTier.COMMON,
|
||||||
|
|
||||||
|
[Species.GROOKEY]: EggTier.COMMON,
|
||||||
|
[Species.SCORBUNNY]: EggTier.RARE,
|
||||||
|
[Species.SOBBLE]: EggTier.COMMON,
|
||||||
|
[Species.SKWOVET]: EggTier.COMMON,
|
||||||
|
[Species.ROOKIDEE]: EggTier.COMMON,
|
||||||
|
[Species.BLIPBUG]: EggTier.COMMON,
|
||||||
|
[Species.NICKIT]: EggTier.COMMON,
|
||||||
|
[Species.GOSSIFLEUR]: EggTier.COMMON,
|
||||||
|
[Species.WOOLOO]: EggTier.COMMON,
|
||||||
|
[Species.CHEWTLE]: EggTier.COMMON,
|
||||||
|
[Species.YAMPER]: EggTier.COMMON,
|
||||||
|
[Species.ROLYCOLY]: EggTier.COMMON,
|
||||||
|
[Species.APPLIN]: EggTier.COMMON,
|
||||||
|
[Species.SILICOBRA]: EggTier.COMMON,
|
||||||
|
[Species.CRAMORANT]: EggTier.COMMON,
|
||||||
|
[Species.ARROKUDA]: EggTier.COMMON,
|
||||||
|
[Species.TOXEL]: EggTier.COMMON,
|
||||||
|
[Species.SIZZLIPEDE]: EggTier.COMMON,
|
||||||
|
[Species.CLOBBOPUS]: EggTier.COMMON,
|
||||||
|
[Species.SINISTEA]: EggTier.COMMON,
|
||||||
|
[Species.HATENNA]: EggTier.COMMON,
|
||||||
|
[Species.IMPIDIMP]: EggTier.COMMON,
|
||||||
|
[Species.MILCERY]: EggTier.COMMON,
|
||||||
|
[Species.FALINKS]: EggTier.RARE,
|
||||||
|
[Species.PINCURCHIN]: EggTier.COMMON,
|
||||||
|
[Species.SNOM]: EggTier.COMMON,
|
||||||
|
[Species.STONJOURNER]: EggTier.COMMON,
|
||||||
|
[Species.EISCUE]: EggTier.COMMON,
|
||||||
|
[Species.INDEEDEE]: EggTier.RARE,
|
||||||
|
[Species.MORPEKO]: EggTier.COMMON,
|
||||||
|
[Species.CUFANT]: EggTier.COMMON,
|
||||||
|
[Species.DRACOZOLT]: EggTier.RARE,
|
||||||
|
[Species.ARCTOZOLT]: EggTier.RARE,
|
||||||
|
[Species.DRACOVISH]: EggTier.RARE,
|
||||||
|
[Species.ARCTOVISH]: EggTier.RARE,
|
||||||
|
[Species.DURALUDON]: EggTier.RARE,
|
||||||
|
[Species.DREEPY]: EggTier.RARE,
|
||||||
|
[Species.ZACIAN]: EggTier.LEGENDARY,
|
||||||
|
[Species.ZAMAZENTA]: EggTier.LEGENDARY,
|
||||||
|
[Species.ETERNATUS]: EggTier.COMMON,
|
||||||
|
[Species.KUBFU]: EggTier.EPIC,
|
||||||
|
[Species.ZARUDE]: EggTier.EPIC,
|
||||||
|
[Species.REGIELEKI]: EggTier.EPIC,
|
||||||
|
[Species.REGIDRAGO]: EggTier.EPIC,
|
||||||
|
[Species.GLASTRIER]: EggTier.EPIC,
|
||||||
|
[Species.SPECTRIER]: EggTier.EPIC,
|
||||||
|
[Species.CALYREX]: EggTier.LEGENDARY,
|
||||||
|
[Species.GALAR_MEOWTH]: EggTier.COMMON,
|
||||||
|
[Species.GALAR_PONYTA]: EggTier.COMMON,
|
||||||
|
[Species.GALAR_SLOWPOKE]: EggTier.COMMON,
|
||||||
|
[Species.GALAR_FARFETCHD]: EggTier.COMMON,
|
||||||
|
[Species.GALAR_CORSOLA]: EggTier.COMMON,
|
||||||
|
[Species.GALAR_ZIGZAGOON]: EggTier.COMMON,
|
||||||
|
[Species.GALAR_DARUMAKA]: EggTier.RARE,
|
||||||
|
[Species.GALAR_YAMASK]: EggTier.COMMON,
|
||||||
|
[Species.GALAR_STUNFISK]: EggTier.COMMON,
|
||||||
|
[Species.GALAR_MR_MIME]: EggTier.COMMON,
|
||||||
|
[Species.GALAR_ARTICUNO]: EggTier.EPIC,
|
||||||
|
[Species.GALAR_ZAPDOS]: EggTier.EPIC,
|
||||||
|
[Species.GALAR_MOLTRES]: EggTier.EPIC,
|
||||||
|
[Species.HISUI_GROWLITHE]: EggTier.RARE,
|
||||||
|
[Species.HISUI_VOLTORB]: EggTier.COMMON,
|
||||||
|
[Species.HISUI_QWILFISH]: EggTier.RARE,
|
||||||
|
[Species.HISUI_SNEASEL]: EggTier.RARE,
|
||||||
|
[Species.HISUI_ZORUA]: EggTier.COMMON,
|
||||||
|
[Species.ENAMORUS]: EggTier.EPIC,
|
||||||
|
|
||||||
|
[Species.SPRIGATITO]: EggTier.RARE,
|
||||||
|
[Species.FUECOCO]: EggTier.RARE,
|
||||||
|
[Species.QUAXLY]: EggTier.RARE,
|
||||||
|
[Species.LECHONK]: EggTier.COMMON,
|
||||||
|
[Species.TAROUNTULA]: EggTier.COMMON,
|
||||||
|
[Species.NYMBLE]: EggTier.COMMON,
|
||||||
|
[Species.PAWMI]: EggTier.COMMON,
|
||||||
|
[Species.TANDEMAUS]: EggTier.RARE,
|
||||||
|
[Species.FIDOUGH]: EggTier.COMMON,
|
||||||
|
[Species.SMOLIV]: EggTier.COMMON,
|
||||||
|
[Species.SQUAWKABILLY]: EggTier.COMMON,
|
||||||
|
[Species.NACLI]: EggTier.RARE,
|
||||||
|
[Species.CHARCADET]: EggTier.RARE,
|
||||||
|
[Species.TADBULB]: EggTier.COMMON,
|
||||||
|
[Species.WATTREL]: EggTier.COMMON,
|
||||||
|
[Species.MASCHIFF]: EggTier.COMMON,
|
||||||
|
[Species.SHROODLE]: EggTier.COMMON,
|
||||||
|
[Species.BRAMBLIN]: EggTier.COMMON,
|
||||||
|
[Species.TOEDSCOOL]: EggTier.COMMON,
|
||||||
|
[Species.KLAWF]: EggTier.COMMON,
|
||||||
|
[Species.CAPSAKID]: EggTier.COMMON,
|
||||||
|
[Species.RELLOR]: EggTier.COMMON,
|
||||||
|
[Species.FLITTLE]: EggTier.COMMON,
|
||||||
|
[Species.TINKATINK]: EggTier.RARE,
|
||||||
|
[Species.WIGLETT]: EggTier.COMMON,
|
||||||
|
[Species.BOMBIRDIER]: EggTier.COMMON,
|
||||||
|
[Species.FINIZEN]: EggTier.COMMON,
|
||||||
|
[Species.VAROOM]: EggTier.RARE,
|
||||||
|
[Species.CYCLIZAR]: EggTier.RARE,
|
||||||
|
[Species.ORTHWORM]: EggTier.RARE,
|
||||||
|
[Species.GLIMMET]: EggTier.RARE,
|
||||||
|
[Species.GREAVARD]: EggTier.COMMON,
|
||||||
|
[Species.FLAMIGO]: EggTier.RARE,
|
||||||
|
[Species.CETODDLE]: EggTier.COMMON,
|
||||||
|
[Species.VELUZA]: EggTier.RARE,
|
||||||
|
[Species.DONDOZO]: EggTier.RARE,
|
||||||
|
[Species.TATSUGIRI]: EggTier.RARE,
|
||||||
|
[Species.GREAT_TUSK]: EggTier.EPIC,
|
||||||
|
[Species.SCREAM_TAIL]: EggTier.EPIC,
|
||||||
|
[Species.BRUTE_BONNET]: EggTier.EPIC,
|
||||||
|
[Species.FLUTTER_MANE]: EggTier.EPIC,
|
||||||
|
[Species.SLITHER_WING]: EggTier.EPIC,
|
||||||
|
[Species.SANDY_SHOCKS]: EggTier.EPIC,
|
||||||
|
[Species.IRON_TREADS]: EggTier.EPIC,
|
||||||
|
[Species.IRON_BUNDLE]: EggTier.EPIC,
|
||||||
|
[Species.IRON_HANDS]: EggTier.EPIC,
|
||||||
|
[Species.IRON_JUGULIS]: EggTier.EPIC,
|
||||||
|
[Species.IRON_MOTH]: EggTier.EPIC,
|
||||||
|
[Species.IRON_THORNS]: EggTier.EPIC,
|
||||||
|
[Species.FRIGIBAX]: EggTier.RARE,
|
||||||
|
[Species.GIMMIGHOUL]: EggTier.RARE,
|
||||||
|
[Species.WO_CHIEN]: EggTier.EPIC,
|
||||||
|
[Species.CHIEN_PAO]: EggTier.EPIC,
|
||||||
|
[Species.TING_LU]: EggTier.EPIC,
|
||||||
|
[Species.CHI_YU]: EggTier.EPIC,
|
||||||
|
[Species.ROARING_MOON]: EggTier.EPIC,
|
||||||
|
[Species.IRON_VALIANT]: EggTier.EPIC,
|
||||||
|
[Species.KORAIDON]: EggTier.LEGENDARY,
|
||||||
|
[Species.MIRAIDON]: EggTier.LEGENDARY,
|
||||||
|
[Species.WALKING_WAKE]: EggTier.EPIC,
|
||||||
|
[Species.IRON_LEAVES]: EggTier.EPIC,
|
||||||
|
[Species.POLTCHAGEIST]: EggTier.RARE,
|
||||||
|
[Species.OKIDOGI]: EggTier.EPIC,
|
||||||
|
[Species.MUNKIDORI]: EggTier.EPIC,
|
||||||
|
[Species.FEZANDIPITI]: EggTier.EPIC,
|
||||||
|
[Species.OGERPON]: EggTier.EPIC,
|
||||||
|
[Species.GOUGING_FIRE]: EggTier.EPIC,
|
||||||
|
[Species.RAGING_BOLT]: EggTier.EPIC,
|
||||||
|
[Species.IRON_BOULDER]: EggTier.EPIC,
|
||||||
|
[Species.IRON_CROWN]: EggTier.EPIC,
|
||||||
|
[Species.TERAPAGOS]: EggTier.LEGENDARY,
|
||||||
|
[Species.PECHARUNT]: EggTier.EPIC,
|
||||||
|
[Species.PALDEA_TAUROS]: EggTier.RARE,
|
||||||
|
[Species.PALDEA_WOOPER]: EggTier.COMMON,
|
||||||
|
[Species.BLOODMOON_URSALUNA]: EggTier.EPIC,
|
||||||
|
};
|
@ -1376,7 +1376,7 @@ export class ContactStatStageChangeProtectedTag extends DamageProtectedTag {
|
|||||||
const effectPhase = pokemon.scene.getCurrentPhase();
|
const effectPhase = pokemon.scene.getCurrentPhase();
|
||||||
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
|
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
|
||||||
const attacker = effectPhase.getPokemon();
|
const attacker = effectPhase.getPokemon();
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), true, [ this.stat ], this.levels));
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), false, [ this.stat ], this.levels));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1713,7 +1713,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) {
|
constructor(tagType: BattlerTagType, sourceMove: Moves) {
|
||||||
super(tagType, sourceMove, Type.GROUND, 5);
|
super(tagType, sourceMove, Type.GROUND, 5);
|
||||||
}
|
}
|
||||||
@ -1721,13 +1726,17 @@ export class MagnetRisenTag extends TypeImmuneTag {
|
|||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
super.onAdd(pokemon);
|
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 {
|
onRemove(pokemon: Pokemon): void {
|
||||||
super.onRemove(pokemon);
|
super.onRemove(pokemon);
|
||||||
|
if (this.sourceMove === Moves.MAGNET_RISE) {
|
||||||
pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2139,6 +2148,10 @@ export class GulpMissileTag extends BattlerTag {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (moveEffectPhase.move.getMove().hitsSubstitute(attacker, pokemon)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled);
|
applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled);
|
||||||
|
|
||||||
@ -2636,16 +2649,16 @@ export class ImprisonTag extends MoveRestrictionBattlerTag {
|
|||||||
/**
|
/**
|
||||||
* Battler Tag that applies the effects of Syrup Bomb to the target Pokemon.
|
* Battler Tag that applies the effects of Syrup Bomb to the target Pokemon.
|
||||||
* For three turns, starting from the turn of hit, at the end of each turn, the target Pokemon's speed will decrease by 1.
|
* For three turns, starting from the turn of hit, at the end of each turn, the target Pokemon's speed will decrease by 1.
|
||||||
* The tag can also expire by taking the target Pokemon off the field.
|
* The tag can also expire by taking the target Pokemon off the field, or the Pokemon that originally used the move.
|
||||||
*/
|
*/
|
||||||
export class SyrupBombTag extends BattlerTag {
|
export class SyrupBombTag extends BattlerTag {
|
||||||
constructor() {
|
constructor(sourceId: number) {
|
||||||
super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, Moves.SYRUP_BOMB);
|
super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, Moves.SYRUP_BOMB, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the Syrup Bomb battler tag to the target Pokemon.
|
* Adds the Syrup Bomb battler tag to the target Pokemon.
|
||||||
* @param {Pokemon} pokemon the target Pokemon
|
* @param pokemon - The target {@linkcode Pokemon}
|
||||||
*/
|
*/
|
||||||
override onAdd(pokemon: Pokemon) {
|
override onAdd(pokemon: Pokemon) {
|
||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
@ -2654,15 +2667,16 @@ export class SyrupBombTag extends BattlerTag {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the single-stage speed down to the target Pokemon and decrements the tag's turn count
|
* Applies the single-stage speed down to the target Pokemon and decrements the tag's turn count
|
||||||
* @param {Pokemon} pokemon the target Pokemon
|
* @param pokemon - The target {@linkcode Pokemon}
|
||||||
* @param {BattlerTagLapseType} _lapseType
|
* @param _lapseType - N/A
|
||||||
* @returns `true` if the turnCount is still greater than 0 | `false` if the turnCount is 0 or the target Pokemon has been removed from the field
|
* @returns `true` if the `turnCount` is still greater than `0`; `false` if the `turnCount` is `0` or the target or source Pokemon has been removed from the field
|
||||||
*/
|
*/
|
||||||
override lapse(pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean {
|
override lapse(pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean {
|
||||||
if (!pokemon.isActive(true)) {
|
if (this.sourceId && !pokemon.scene.getPokemonById(this.sourceId)?.isActive(true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); // Custom message in lieu of an animation in mainline
|
// Custom message in lieu of an animation in mainline
|
||||||
|
pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||||
pokemon.scene.unshiftPhase(new StatStageChangePhase(
|
pokemon.scene.unshiftPhase(new StatStageChangePhase(
|
||||||
pokemon.scene, pokemon.getBattlerIndex(), true,
|
pokemon.scene, pokemon.getBattlerIndex(), true,
|
||||||
[ Stat.SPD ], -1, true, false, true
|
[ Stat.SPD ], -1, true, false, true
|
||||||
@ -2671,14 +2685,26 @@ 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.
|
* 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
|
||||||
* @param {BattlerTagType} tagType the type of the {@linkcode BattlerTagType}.
|
* @returns The corresponding {@linkcode BattlerTag} object.
|
||||||
* @param turnCount the turn count.
|
|
||||||
* @param {Moves} sourceMove the source {@linkcode Moves}.
|
|
||||||
* @param sourceId the source ID.
|
|
||||||
* @returns {BattlerTag} the corresponding {@linkcode BattlerTag} object.
|
|
||||||
*/
|
*/
|
||||||
export function getBattlerTag(tagType: BattlerTagType, turnCount: number, sourceMove: Moves, sourceId: number): BattlerTag {
|
export function getBattlerTag(tagType: BattlerTagType, turnCount: number, sourceMove: Moves, sourceId: number): BattlerTag {
|
||||||
switch (tagType) {
|
switch (tagType) {
|
||||||
@ -2801,8 +2827,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
|||||||
return new CursedTag(sourceId);
|
return new CursedTag(sourceId);
|
||||||
case BattlerTagType.CHARGED:
|
case BattlerTagType.CHARGED:
|
||||||
return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true);
|
return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true);
|
||||||
case BattlerTagType.MAGNET_RISEN:
|
case BattlerTagType.FLOATING:
|
||||||
return new MagnetRisenTag(tagType, sourceMove);
|
return new FloatingTag(tagType, sourceMove);
|
||||||
case BattlerTagType.MINIMIZED:
|
case BattlerTagType.MINIMIZED:
|
||||||
return new MinimizeTag();
|
return new MinimizeTag();
|
||||||
case BattlerTagType.DESTINY_BOND:
|
case BattlerTagType.DESTINY_BOND:
|
||||||
@ -2847,7 +2873,9 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
|||||||
case BattlerTagType.IMPRISON:
|
case BattlerTagType.IMPRISON:
|
||||||
return new ImprisonTag(sourceId);
|
return new ImprisonTag(sourceId);
|
||||||
case BattlerTagType.SYRUP_BOMB:
|
case BattlerTagType.SYRUP_BOMB:
|
||||||
return new SyrupBombTag();
|
return new SyrupBombTag(sourceId);
|
||||||
|
case BattlerTagType.TELEKINESIS:
|
||||||
|
return new TelekinesisTag(sourceMove);
|
||||||
case BattlerTagType.NONE:
|
case BattlerTagType.NONE:
|
||||||
default:
|
default:
|
||||||
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
|
||||||
|
@ -11,6 +11,7 @@ import { EggTier } from "#enums/egg-type";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { EggSourceType } from "#enums/egg-source-types";
|
import { EggSourceType } from "#enums/egg-source-types";
|
||||||
import { MANAPHY_EGG_MANAPHY_RATE, SAME_SPECIES_EGG_HA_RATE, GACHA_EGG_HA_RATE, GACHA_DEFAULT_RARE_EGGMOVE_RATE, SAME_SPECIES_EGG_RARE_EGGMOVE_RATE, GACHA_MOVE_UP_RARE_EGGMOVE_RATE, GACHA_DEFAULT_SHINY_RATE, GACHA_SHINY_UP_SHINY_RATE, SAME_SPECIES_EGG_SHINY_RATE, EGG_PITY_LEGENDARY_THRESHOLD, EGG_PITY_EPIC_THRESHOLD, EGG_PITY_RARE_THRESHOLD, SHINY_VARIANT_CHANCE, SHINY_EPIC_CHANCE, GACHA_DEFAULT_COMMON_EGG_THRESHOLD, GACHA_DEFAULT_RARE_EGG_THRESHOLD, GACHA_DEFAULT_EPIC_EGG_THRESHOLD, GACHA_LEGENDARY_UP_THRESHOLD_OFFSET, HATCH_WAVES_MANAPHY_EGG, HATCH_WAVES_COMMON_EGG, HATCH_WAVES_RARE_EGG, HATCH_WAVES_EPIC_EGG, HATCH_WAVES_LEGENDARY_EGG } from "#app/data/balance/rates";
|
import { MANAPHY_EGG_MANAPHY_RATE, SAME_SPECIES_EGG_HA_RATE, GACHA_EGG_HA_RATE, GACHA_DEFAULT_RARE_EGGMOVE_RATE, SAME_SPECIES_EGG_RARE_EGGMOVE_RATE, GACHA_MOVE_UP_RARE_EGGMOVE_RATE, GACHA_DEFAULT_SHINY_RATE, GACHA_SHINY_UP_SHINY_RATE, SAME_SPECIES_EGG_SHINY_RATE, EGG_PITY_LEGENDARY_THRESHOLD, EGG_PITY_EPIC_THRESHOLD, EGG_PITY_RARE_THRESHOLD, SHINY_VARIANT_CHANCE, SHINY_EPIC_CHANCE, GACHA_DEFAULT_COMMON_EGG_THRESHOLD, GACHA_DEFAULT_RARE_EGG_THRESHOLD, GACHA_DEFAULT_EPIC_EGG_THRESHOLD, GACHA_LEGENDARY_UP_THRESHOLD_OFFSET, HATCH_WAVES_MANAPHY_EGG, HATCH_WAVES_COMMON_EGG, HATCH_WAVES_RARE_EGG, HATCH_WAVES_EPIC_EGG, HATCH_WAVES_LEGENDARY_EGG } from "#app/data/balance/rates";
|
||||||
|
import { speciesEggTiers } from "#app/data/balance/species-egg-tiers";
|
||||||
|
|
||||||
export const EGG_SEED = 1073741824;
|
export const EGG_SEED = 1073741824;
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ export class Egg {
|
|||||||
|
|
||||||
// Override egg tier and hatchwaves if species was given
|
// Override egg tier and hatchwaves if species was given
|
||||||
if (eggOptions?.species) {
|
if (eggOptions?.species) {
|
||||||
this._tier = this.getEggTierFromSpeciesStarterValue();
|
this._tier = this.getEggTier();
|
||||||
this._hatchWaves = eggOptions.hatchWaves ?? this.getEggTierDefaultHatchWaves();
|
this._hatchWaves = eggOptions.hatchWaves ?? this.getEggTierDefaultHatchWaves();
|
||||||
}
|
}
|
||||||
// If species has no variant, set variantTier to common. This needs to
|
// If species has no variant, set variantTier to common. This needs to
|
||||||
@ -261,11 +262,11 @@ export class Egg {
|
|||||||
return "Manaphy";
|
return "Manaphy";
|
||||||
}
|
}
|
||||||
switch (this.tier) {
|
switch (this.tier) {
|
||||||
case EggTier.GREAT:
|
case EggTier.RARE:
|
||||||
return i18next.t("egg:greatTier");
|
return i18next.t("egg:greatTier");
|
||||||
case EggTier.ULTRA:
|
case EggTier.EPIC:
|
||||||
return i18next.t("egg:ultraTier");
|
return i18next.t("egg:ultraTier");
|
||||||
case EggTier.MASTER:
|
case EggTier.LEGENDARY:
|
||||||
return i18next.t("egg:masterTier");
|
return i18next.t("egg:masterTier");
|
||||||
default:
|
default:
|
||||||
return i18next.t("egg:defaultTier");
|
return i18next.t("egg:defaultTier");
|
||||||
@ -336,9 +337,9 @@ export class Egg {
|
|||||||
switch (eggTier ?? this._tier) {
|
switch (eggTier ?? this._tier) {
|
||||||
case EggTier.COMMON:
|
case EggTier.COMMON:
|
||||||
return HATCH_WAVES_COMMON_EGG;
|
return HATCH_WAVES_COMMON_EGG;
|
||||||
case EggTier.GREAT:
|
case EggTier.RARE:
|
||||||
return HATCH_WAVES_RARE_EGG;
|
return HATCH_WAVES_RARE_EGG;
|
||||||
case EggTier.ULTRA:
|
case EggTier.EPIC:
|
||||||
return HATCH_WAVES_EPIC_EGG;
|
return HATCH_WAVES_EPIC_EGG;
|
||||||
}
|
}
|
||||||
return HATCH_WAVES_LEGENDARY_EGG;
|
return HATCH_WAVES_LEGENDARY_EGG;
|
||||||
@ -347,7 +348,7 @@ export class Egg {
|
|||||||
private rollEggTier(): EggTier {
|
private rollEggTier(): EggTier {
|
||||||
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
|
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
|
||||||
const tierValue = Utils.randInt(256);
|
const tierValue = Utils.randInt(256);
|
||||||
return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset ? EggTier.COMMON : tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset ? EggTier.GREAT : tierValue >= GACHA_DEFAULT_EPIC_EGG_THRESHOLD + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER;
|
return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset ? EggTier.COMMON : tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset ? EggTier.RARE : tierValue >= GACHA_DEFAULT_EPIC_EGG_THRESHOLD + tierValueOffset ? EggTier.EPIC : EggTier.LEGENDARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private rollSpecies(scene: BattleScene): Species | null {
|
private rollSpecies(scene: BattleScene): Species | null {
|
||||||
@ -367,7 +368,7 @@ export class Egg {
|
|||||||
*/
|
*/
|
||||||
const rand = (Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1);
|
const rand = (Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1);
|
||||||
return rand ? Species.PHIONE : Species.MANAPHY;
|
return rand ? Species.PHIONE : Species.MANAPHY;
|
||||||
} else if (this.tier === EggTier.MASTER
|
} else if (this.tier === EggTier.LEGENDARY
|
||||||
&& this._sourceType === EggSourceType.GACHA_LEGENDARY) {
|
&& this._sourceType === EggSourceType.GACHA_LEGENDARY) {
|
||||||
if (!Utils.randSeedInt(2)) {
|
if (!Utils.randSeedInt(2)) {
|
||||||
return getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp);
|
return getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp);
|
||||||
@ -378,15 +379,15 @@ export class Egg {
|
|||||||
let maxStarterValue: integer;
|
let maxStarterValue: integer;
|
||||||
|
|
||||||
switch (this.tier) {
|
switch (this.tier) {
|
||||||
case EggTier.GREAT:
|
case EggTier.RARE:
|
||||||
minStarterValue = 4;
|
minStarterValue = 4;
|
||||||
maxStarterValue = 5;
|
maxStarterValue = 5;
|
||||||
break;
|
break;
|
||||||
case EggTier.ULTRA:
|
case EggTier.EPIC:
|
||||||
minStarterValue = 6;
|
minStarterValue = 6;
|
||||||
maxStarterValue = 7;
|
maxStarterValue = 7;
|
||||||
break;
|
break;
|
||||||
case EggTier.MASTER:
|
case EggTier.LEGENDARY:
|
||||||
minStarterValue = 8;
|
minStarterValue = 8;
|
||||||
maxStarterValue = 9;
|
maxStarterValue = 9;
|
||||||
break;
|
break;
|
||||||
@ -398,8 +399,8 @@ export class Egg {
|
|||||||
|
|
||||||
const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ];
|
const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ];
|
||||||
|
|
||||||
let speciesPool = Object.keys(speciesStarterCosts)
|
let speciesPool = Object.keys(speciesEggTiers)
|
||||||
.filter(s => speciesStarterCosts[s] >= minStarterValue && speciesStarterCosts[s] <= maxStarterValue)
|
.filter(s => speciesEggTiers[s] === this.tier)
|
||||||
.map(s => parseInt(s) as Species)
|
.map(s => parseInt(s) as Species)
|
||||||
.filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
|
.filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
|
||||||
|
|
||||||
@ -430,7 +431,9 @@ export class Egg {
|
|||||||
let totalWeight = 0;
|
let totalWeight = 0;
|
||||||
const speciesWeights : number[] = [];
|
const speciesWeights : number[] = [];
|
||||||
for (const speciesId of speciesPool) {
|
for (const speciesId of speciesPool) {
|
||||||
let weight = Math.floor((((maxStarterValue - speciesStarterCosts[speciesId]) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100);
|
// Accounts for species that have starter costs outside of the normal range for their EggTier
|
||||||
|
const speciesCostClamped = Phaser.Math.Clamp(speciesStarterCosts[speciesId], minStarterValue, maxStarterValue);
|
||||||
|
let weight = Math.floor((((maxStarterValue - speciesCostClamped) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100);
|
||||||
const species = getPokemonSpecies(speciesId);
|
const species = getPokemonSpecies(speciesId);
|
||||||
if (species.isRegional()) {
|
if (species.isRegional()) {
|
||||||
weight = Math.floor(weight / 2);
|
weight = Math.floor(weight / 2);
|
||||||
@ -498,16 +501,16 @@ export class Egg {
|
|||||||
|
|
||||||
private checkForPityTierOverrides(scene: BattleScene): void {
|
private checkForPityTierOverrides(scene: BattleScene): void {
|
||||||
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
|
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
|
||||||
scene.gameData.eggPity[EggTier.GREAT] += 1;
|
scene.gameData.eggPity[EggTier.RARE] += 1;
|
||||||
scene.gameData.eggPity[EggTier.ULTRA] += 1;
|
scene.gameData.eggPity[EggTier.EPIC] += 1;
|
||||||
scene.gameData.eggPity[EggTier.MASTER] += 1 + tierValueOffset;
|
scene.gameData.eggPity[EggTier.LEGENDARY] += 1 + tierValueOffset;
|
||||||
// These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered.
|
// These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered.
|
||||||
if (scene.gameData.eggPity[EggTier.MASTER] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) {
|
if (scene.gameData.eggPity[EggTier.LEGENDARY] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) {
|
||||||
this._tier = EggTier.MASTER;
|
this._tier = EggTier.LEGENDARY;
|
||||||
} else if (scene.gameData.eggPity[EggTier.ULTRA] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) {
|
} else if (scene.gameData.eggPity[EggTier.EPIC] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) {
|
||||||
this._tier = EggTier.ULTRA;
|
this._tier = EggTier.EPIC;
|
||||||
} else if (scene.gameData.eggPity[EggTier.GREAT] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) {
|
} else if (scene.gameData.eggPity[EggTier.RARE] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) {
|
||||||
this._tier = EggTier.GREAT;
|
this._tier = EggTier.RARE;
|
||||||
}
|
}
|
||||||
scene.gameData.eggPity[this._tier] = 0;
|
scene.gameData.eggPity[this._tier] = 0;
|
||||||
}
|
}
|
||||||
@ -516,38 +519,24 @@ export class Egg {
|
|||||||
scene.gameData.gameStats.eggsPulled++;
|
scene.gameData.gameStats.eggsPulled++;
|
||||||
if (this.isManaphyEgg()) {
|
if (this.isManaphyEgg()) {
|
||||||
scene.gameData.gameStats.manaphyEggsPulled++;
|
scene.gameData.gameStats.manaphyEggsPulled++;
|
||||||
this._hatchWaves = this.getEggTierDefaultHatchWaves(EggTier.ULTRA);
|
this._hatchWaves = this.getEggTierDefaultHatchWaves(EggTier.EPIC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (this.tier) {
|
switch (this.tier) {
|
||||||
case EggTier.GREAT:
|
case EggTier.RARE:
|
||||||
scene.gameData.gameStats.rareEggsPulled++;
|
scene.gameData.gameStats.rareEggsPulled++;
|
||||||
break;
|
break;
|
||||||
case EggTier.ULTRA:
|
case EggTier.EPIC:
|
||||||
scene.gameData.gameStats.epicEggsPulled++;
|
scene.gameData.gameStats.epicEggsPulled++;
|
||||||
break;
|
break;
|
||||||
case EggTier.MASTER:
|
case EggTier.LEGENDARY:
|
||||||
scene.gameData.gameStats.legendaryEggsPulled++;
|
scene.gameData.gameStats.legendaryEggsPulled++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getEggTierFromSpeciesStarterValue(): EggTier {
|
private getEggTier(): EggTier {
|
||||||
const speciesStartValue = speciesStarterCosts[this.species];
|
return speciesEggTiers[this.species];
|
||||||
if (speciesStartValue >= 1 && speciesStartValue <= 3) {
|
|
||||||
return EggTier.COMMON;
|
|
||||||
}
|
|
||||||
if (speciesStartValue >= 4 && speciesStartValue <= 5) {
|
|
||||||
return EggTier.GREAT;
|
|
||||||
}
|
|
||||||
if (speciesStartValue >= 6 && speciesStartValue <= 7) {
|
|
||||||
return EggTier.ULTRA;
|
|
||||||
}
|
|
||||||
if (speciesStartValue >= 8) {
|
|
||||||
return EggTier.MASTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EggTier.COMMON;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////
|
////
|
||||||
@ -556,8 +545,8 @@ export class Egg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species {
|
export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species {
|
||||||
const legendarySpecies = Object.entries(speciesStarterCosts)
|
const legendarySpecies = Object.entries(speciesEggTiers)
|
||||||
.filter(s => s[1] >= 8 && s[1] <= 9)
|
.filter(s => s[1] === EggTier.LEGENDARY)
|
||||||
.map(s => parseInt(s[0]))
|
.map(s => parseInt(s[0]))
|
||||||
.filter(s => getPokemonSpecies(s).isObtainable());
|
.filter(s => getPokemonSpecies(s).isObtainable());
|
||||||
|
|
||||||
@ -579,17 +568,9 @@ export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timesta
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for a given species EggTier Value
|
* Check for a given species EggTier Value
|
||||||
* @param species - Species for wich we will check the egg tier it belongs to
|
* @param pokemonSpecies - Species for wich we will check the egg tier it belongs to
|
||||||
* @returns The egg tier of a given pokemon species
|
* @returns The egg tier of a given pokemon species
|
||||||
*/
|
*/
|
||||||
export function getEggTierForSpecies(pokemonSpecies :PokemonSpecies): EggTier {
|
export function getEggTierForSpecies(pokemonSpecies :PokemonSpecies): EggTier {
|
||||||
const speciesBaseValue = speciesStarterCosts[pokemonSpecies.getRootSpeciesId()];
|
return speciesEggTiers[pokemonSpecies.getRootSpeciesId()];
|
||||||
if (speciesBaseValue <= 3) {
|
|
||||||
return EggTier.COMMON;
|
|
||||||
} else if (speciesBaseValue <= 5) {
|
|
||||||
return EggTier.GREAT;
|
|
||||||
} else if (speciesBaseValue <= 7) {
|
|
||||||
return EggTier.ULTRA;
|
|
||||||
}
|
|
||||||
return EggTier.MASTER;
|
|
||||||
}
|
}
|
||||||
|
@ -1938,12 +1938,21 @@ export class IncrementMovePriorityAttr extends MoveAttr {
|
|||||||
* @see {@linkcode apply}
|
* @see {@linkcode apply}
|
||||||
*/
|
*/
|
||||||
export class MultiHitAttr extends MoveAttr {
|
export class MultiHitAttr extends MoveAttr {
|
||||||
|
/** This move's intrinsic multi-hit type. It should never be modified. */
|
||||||
|
private readonly intrinsicMultiHitType: MultiHitType;
|
||||||
|
/** This move's current multi-hit type. It may be temporarily modified by abilities (e.g., Battle Bond). */
|
||||||
private multiHitType: MultiHitType;
|
private multiHitType: MultiHitType;
|
||||||
|
|
||||||
constructor(multiHitType?: MultiHitType) {
|
constructor(multiHitType?: MultiHitType) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.multiHitType = multiHitType !== undefined ? multiHitType : MultiHitType._2_TO_5;
|
this.intrinsicMultiHitType = multiHitType !== undefined ? multiHitType : MultiHitType._2_TO_5;
|
||||||
|
this.multiHitType = this.intrinsicMultiHitType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Currently used by `battle_bond.test.ts`
|
||||||
|
getMultiHitType(): MultiHitType {
|
||||||
|
return this.multiHitType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1957,7 +1966,7 @@ export class MultiHitAttr extends MoveAttr {
|
|||||||
* @returns True
|
* @returns True
|
||||||
*/
|
*/
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const hitType = new Utils.NumberHolder(this.multiHitType);
|
const hitType = new Utils.NumberHolder(this.intrinsicMultiHitType);
|
||||||
applyMoveAttrs(ChangeMultiHitTypeAttr, user, target, move, hitType);
|
applyMoveAttrs(ChangeMultiHitTypeAttr, user, target, move, hitType);
|
||||||
this.multiHitType = hitType.value;
|
this.multiHitType = hitType.value;
|
||||||
|
|
||||||
@ -4107,11 +4116,11 @@ export class StatusCategoryOnAllyAttr extends VariableMoveCategoryAttr {
|
|||||||
* @param user {@linkcode Pokemon} using the move
|
* @param user {@linkcode Pokemon} using the move
|
||||||
* @param target {@linkcode Pokemon} target of the move
|
* @param target {@linkcode Pokemon} target of the move
|
||||||
* @param move {@linkcode Move} with this attribute
|
* @param move {@linkcode Move} with this attribute
|
||||||
* @param args [0] {@linkcode Utils.IntegerHolder} The category of the move
|
* @param args [0] {@linkcode Utils.NumberHolder} The category of the move
|
||||||
* @returns true if the function succeeds
|
* @returns true if the function succeeds
|
||||||
*/
|
*/
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const category = (args[0] as Utils.IntegerHolder);
|
const category = (args[0] as Utils.NumberHolder);
|
||||||
|
|
||||||
if (user.getAlly() === target) {
|
if (user.getAlly() === target) {
|
||||||
category.value = MoveCategory.STATUS;
|
category.value = MoveCategory.STATUS;
|
||||||
@ -4547,18 +4556,19 @@ export class WaterSuperEffectTypeMultiplierAttr extends VariableMoveTypeMultipli
|
|||||||
export class IceNoEffectTypeAttr extends VariableMoveTypeMultiplierAttr {
|
export class IceNoEffectTypeAttr extends VariableMoveTypeMultiplierAttr {
|
||||||
/**
|
/**
|
||||||
* Checks to see if the Target is Ice-Type or not. If so, the move will have no effect.
|
* 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 user n/a
|
||||||
* @param {Pokemon} target Pokemon that is being checked whether Ice-Type or not.
|
* @param target The {@linkcode Pokemon} targeted by the move
|
||||||
* @param {Move} move N/A
|
* @param move n/a
|
||||||
* @param {any[]} args Sets to false if the target is Ice-Type, so it should do no damage/no effect.
|
* @param args `[0]` a {@linkcode Utils.NumberHolder | NumberHolder} containing a type effectiveness multiplier
|
||||||
* @returns {boolean} Returns true if move is successful, false if Ice-Type.
|
* @returns `true` if this Ice-type immunity applies; `false` otherwise
|
||||||
*/
|
*/
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
|
const multiplier = args[0] as Utils.NumberHolder;
|
||||||
if (target.isOfType(Type.ICE)) {
|
if (target.isOfType(Type.ICE)) {
|
||||||
(args[0] as Utils.BooleanHolder).value = false;
|
multiplier.value = 0;
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4835,14 +4845,14 @@ export class GulpMissileTagAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds BattlerTagType from GulpMissileTag based on the Pokemon's HP ratio.
|
* Adds BattlerTagType from GulpMissileTag based on the Pokemon's HP ratio.
|
||||||
* @param {Pokemon} user The Pokemon using the move.
|
* @param user The Pokemon using the move.
|
||||||
* @param {Pokemon} target The Pokemon being targeted by the move.
|
* @param _target N/A
|
||||||
* @param {Move} move The move being used.
|
* @param move The move being used.
|
||||||
* @param {any[]} args Additional arguments, if any.
|
* @param _args N/A
|
||||||
* @returns Whether the BattlerTag is applied.
|
* @returns Whether the BattlerTag is applied.
|
||||||
*/
|
*/
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise<boolean> {
|
apply(user: Pokemon, _target: Pokemon, move: Move, _args: any[]): boolean {
|
||||||
if (!super.apply(user, target, move, args)) {
|
if (!super.apply(user, _target, move, _args)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7833,7 +7843,9 @@ export function initMoves() {
|
|||||||
.attr(RandomMovesetMoveAttr, true)
|
.attr(RandomMovesetMoveAttr, true)
|
||||||
.ignoresVirtual(),
|
.ignoresVirtual(),
|
||||||
new SelfStatusMove(Moves.INGRAIN, Type.GRASS, -1, 20, -1, 0, 3)
|
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)
|
new AttackMove(Moves.SUPERPOWER, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 3)
|
||||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF ], -1, true),
|
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF ], -1, true),
|
||||||
new SelfStatusMove(Moves.MAGIC_COAT, Type.PSYCHIC, -1, 15, -1, 4, 3)
|
new SelfStatusMove(Moves.MAGIC_COAT, Type.PSYCHIC, -1, 15, -1, 4, 3)
|
||||||
@ -8167,8 +8179,8 @@ export function initMoves() {
|
|||||||
new SelfStatusMove(Moves.AQUA_RING, Type.WATER, -1, 20, -1, 0, 4)
|
new SelfStatusMove(Moves.AQUA_RING, Type.WATER, -1, 20, -1, 0, 4)
|
||||||
.attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true),
|
.attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true),
|
||||||
new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4)
|
new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4)
|
||||||
.attr(AddBattlerTagAttr, BattlerTagType.MAGNET_RISEN, true, true)
|
.attr(AddBattlerTagAttr, BattlerTagType.FLOATING, 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))),
|
.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)
|
new AttackMove(Moves.FLARE_BLITZ, Type.FIRE, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 4)
|
||||||
.attr(RecoilAttr, false, 0.33)
|
.attr(RecoilAttr, false, 0.33)
|
||||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||||
@ -8393,7 +8405,11 @@ export function initMoves() {
|
|||||||
.attr(AddBattlerTagAttr, BattlerTagType.CENTER_OF_ATTENTION, true),
|
.attr(AddBattlerTagAttr, BattlerTagType.CENTER_OF_ATTENTION, true),
|
||||||
new StatusMove(Moves.TELEKINESIS, Type.PSYCHIC, -1, 15, -1, 0, 5)
|
new StatusMove(Moves.TELEKINESIS, Type.PSYCHIC, -1, 15, -1, 0, 5)
|
||||||
.condition(failOnGravityCondition)
|
.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)
|
new StatusMove(Moves.MAGIC_ROOM, Type.PSYCHIC, -1, 10, -1, 0, 5)
|
||||||
.ignoresProtect()
|
.ignoresProtect()
|
||||||
.target(MoveTarget.BOTH_SIDES)
|
.target(MoveTarget.BOTH_SIDES)
|
||||||
@ -8401,7 +8417,7 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.SMACK_DOWN, Type.ROCK, MoveCategory.PHYSICAL, 50, 100, 15, 100, 0, 5)
|
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.IGNORE_FLYING, false, false, 1, 1, true)
|
||||||
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
|
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
|
||||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN ])
|
.attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ])
|
||||||
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
||||||
.makesContact(false),
|
.makesContact(false),
|
||||||
new AttackMove(Moves.STORM_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5)
|
new AttackMove(Moves.STORM_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5)
|
||||||
@ -8834,9 +8850,9 @@ export function initMoves() {
|
|||||||
.attr(NeutralDamageAgainstFlyingTypeMultiplierAttr)
|
.attr(NeutralDamageAgainstFlyingTypeMultiplierAttr)
|
||||||
.attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true)
|
.attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true)
|
||||||
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
.attr(HitsTagAttr, BattlerTagType.FLYING)
|
||||||
.attr(HitsTagAttr, BattlerTagType.MAGNET_RISEN)
|
.attr(HitsTagAttr, BattlerTagType.FLOATING)
|
||||||
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
|
.attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED)
|
||||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN ])
|
.attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ])
|
||||||
.makesContact(false)
|
.makesContact(false)
|
||||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||||
new AttackMove(Moves.THOUSAND_WAVES, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6)
|
new AttackMove(Moves.THOUSAND_WAVES, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6)
|
||||||
|
@ -128,6 +128,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
@ -149,7 +150,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
pulled: false,
|
pulled: false,
|
||||||
sourceType: EggSourceType.EVENT,
|
sourceType: EggSourceType.EVENT,
|
||||||
eggDescriptor: encounter.misc.trainerEggDescription,
|
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||||
tier: EggTier.ULTRA
|
tier: EggTier.EPIC
|
||||||
};
|
};
|
||||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`));
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`));
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SACRED_ASH ], guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ULTRA ], fillRemaining: true }, [ eggOptions ]);
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SACRED_ASH ], guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ULTRA ], fillRemaining: true }, [ eggOptions ]);
|
||||||
@ -171,7 +172,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
pulled: false,
|
pulled: false,
|
||||||
sourceType: EggSourceType.EVENT,
|
sourceType: EggSourceType.EVENT,
|
||||||
eggDescriptor: encounter.misc.trainerEggDescription,
|
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||||
tier: EggTier.GREAT
|
tier: EggTier.RARE
|
||||||
};
|
};
|
||||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.rare`));
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.rare`));
|
||||||
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [ eggOptions ]);
|
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [ eggOptions ]);
|
||||||
|
@ -166,6 +166,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -64,6 +64,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
|||||||
speaker: `${namespace}:speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -110,6 +110,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -276,6 +276,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -148,6 +148,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -102,6 +102,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -117,6 +117,7 @@ export const DarkDealEncounter: MysteryEncounter =
|
|||||||
.withSceneWaveRangeRequirement(30, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
.withSceneWaveRangeRequirement(30, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
.withScenePartySizeRequirement(2, 6, true) // Must have at least 2 pokemon in party
|
.withScenePartySizeRequirement(2, 6, true) // Must have at least 2 pokemon in party
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -84,6 +84,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -51,6 +51,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -52,6 +52,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -122,6 +122,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -120,6 +120,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -76,6 +76,7 @@ export const FunAndGamesEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -96,6 +96,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -50,6 +50,7 @@ export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -125,6 +125,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -61,6 +61,7 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -69,6 +69,7 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -54,6 +54,7 @@ export const SafariZoneEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -62,6 +62,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
speaker: `${namespace}:speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -88,6 +88,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -58,6 +58,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -196,6 +196,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
@ -493,7 +494,7 @@ function getEggOptions(scene: BattleScene, commonEggs: number, rareEggs: number)
|
|||||||
pulled: false,
|
pulled: false,
|
||||||
sourceType: EggSourceType.EVENT,
|
sourceType: EggSourceType.EVENT,
|
||||||
eggDescriptor: eggDescription,
|
eggDescriptor: eggDescription,
|
||||||
tier: EggTier.GREAT
|
tier: EggTier.RARE
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
speaker: `${namespace}:speaker`,
|
speaker: `${namespace}:speaker`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -117,6 +117,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -94,6 +94,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -52,6 +52,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro`,
|
text: `${namespace}:intro`,
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -54,6 +54,7 @@ export const TrashToTreasureEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro`,
|
text: `${namespace}:intro`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -125,6 +125,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
scene.time.delayedCall(500, () => scene.playSound("battle_anims/PRSFX- Spotlight2"));
|
scene.time.delayedCall(500, () => scene.playSound("battle_anims/PRSFX- Spotlight2"));
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -125,6 +125,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}:intro_dialogue`,
|
text: `${namespace}:intro_dialogue`,
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
.setLocalizationKey(`${namespace}`)
|
||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
|
@ -190,7 +190,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
secondaryPokemon?: PlayerPokemon[];
|
secondaryPokemon?: PlayerPokemon[];
|
||||||
|
|
||||||
// #region Post-construct / Auto-populated params
|
// #region Post-construct / Auto-populated params
|
||||||
|
localizationKey: string;
|
||||||
/**
|
/**
|
||||||
* Dialogue object containing all the dialogue, messages, tooltips, etc. for an encounter
|
* Dialogue object containing all the dialogue, messages, tooltips, etc. for an encounter
|
||||||
*/
|
*/
|
||||||
@ -264,6 +264,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
Object.assign(this, encounter);
|
Object.assign(this, encounter);
|
||||||
}
|
}
|
||||||
this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON;
|
this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON;
|
||||||
|
this.localizationKey = this.localizationKey ?? "";
|
||||||
this.dialogue = this.dialogue ?? {};
|
this.dialogue = this.dialogue ?? {};
|
||||||
this.spriteConfigs = this.spriteConfigs ? [ ...this.spriteConfigs ] : [];
|
this.spriteConfigs = this.spriteConfigs ? [ ...this.spriteConfigs ] : [];
|
||||||
// Default max is 1 for ROGUE encounters, 2 for others
|
// Default max is 1 for ROGUE encounters, 2 for others
|
||||||
@ -528,6 +529,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
options: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]];
|
options: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]];
|
||||||
enemyPartyConfigs: EnemyPartyConfig[] = [];
|
enemyPartyConfigs: EnemyPartyConfig[] = [];
|
||||||
|
|
||||||
|
localizationKey: string = "";
|
||||||
dialogue: MysteryEncounterDialogue = {};
|
dialogue: MysteryEncounterDialogue = {};
|
||||||
requirements: EncounterSceneRequirement[] = [];
|
requirements: EncounterSceneRequirement[] = [];
|
||||||
primaryPokemonRequirements: EncounterPokemonRequirement[] = [];
|
primaryPokemonRequirements: EncounterPokemonRequirement[] = [];
|
||||||
@ -632,6 +634,16 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
return this.withIntroSpriteConfigs(spriteConfigs).withIntroDialogue(dialogue);
|
return this.withIntroSpriteConfigs(spriteConfigs).withIntroDialogue(dialogue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the localization key used by the encounter
|
||||||
|
* @param localizationKey the string used as the key
|
||||||
|
* @returns `this`
|
||||||
|
*/
|
||||||
|
setLocalizationKey(localizationKey: string): this {
|
||||||
|
this.localizationKey = localizationKey;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OPTIONAL
|
* OPTIONAL
|
||||||
*/
|
*/
|
||||||
|
@ -54,7 +54,7 @@ export enum BattlerTagType {
|
|||||||
CURSED = "CURSED",
|
CURSED = "CURSED",
|
||||||
CHARGED = "CHARGED",
|
CHARGED = "CHARGED",
|
||||||
ROOSTED = "ROOSTED",
|
ROOSTED = "ROOSTED",
|
||||||
MAGNET_RISEN = "MAGNET_RISEN",
|
FLOATING = "FLOATING",
|
||||||
MINIMIZED = "MINIMIZED",
|
MINIMIZED = "MINIMIZED",
|
||||||
DESTINY_BOND = "DESTINY_BOND",
|
DESTINY_BOND = "DESTINY_BOND",
|
||||||
CENTER_OF_ATTENTION = "CENTER_OF_ATTENTION",
|
CENTER_OF_ATTENTION = "CENTER_OF_ATTENTION",
|
||||||
@ -86,4 +86,5 @@ export enum BattlerTagType {
|
|||||||
IMPRISON = "IMPRISON",
|
IMPRISON = "IMPRISON",
|
||||||
SYRUP_BOMB = "SYRUP_BOMB",
|
SYRUP_BOMB = "SYRUP_BOMB",
|
||||||
ELECTRIFIED = "ELECTRIFIED",
|
ELECTRIFIED = "ELECTRIFIED",
|
||||||
|
TELEKINESIS = "TELEKINESIS"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export enum EggTier {
|
export enum EggTier {
|
||||||
COMMON,
|
COMMON,
|
||||||
GREAT,
|
RARE,
|
||||||
ULTRA,
|
EPIC,
|
||||||
MASTER
|
LEGENDARY
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ export function getStatStageChangeDescriptionKey(stages: number, isIncrease: boo
|
|||||||
return isIncrease ? "battle:statRose" : "battle:statFell";
|
return isIncrease ? "battle:statRose" : "battle:statFell";
|
||||||
} else if (stages === 2) {
|
} else if (stages === 2) {
|
||||||
return isIncrease ? "battle:statSharplyRose" : "battle:statHarshlyFell";
|
return isIncrease ? "battle:statSharplyRose" : "battle:statHarshlyFell";
|
||||||
} else if (stages <= 6) {
|
} else if (stages > 2 && stages <= 6) {
|
||||||
return isIncrease ? "battle:statRoseDrastically" : "battle:statSeverelyFell";
|
return isIncrease ? "battle:statRoseDrastically" : "battle:statSeverelyFell";
|
||||||
}
|
}
|
||||||
return isIncrease ? "battle:statWontGoAnyHigher" : "battle:statWontGoAnyLower";
|
return isIncrease ? "battle:statWontGoAnyHigher" : "battle:statWontGoAnyLower";
|
||||||
|
@ -983,7 +983,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder);
|
this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
statHolder.value = Utils.clampInt(statHolder.value, 1, Number.MAX_SAFE_INTEGER);
|
statHolder.value = Phaser.Math.Clamp(statHolder.value, 1, Number.MAX_SAFE_INTEGER);
|
||||||
|
|
||||||
this.setStat(s, statHolder.value);
|
this.setStat(s, statHolder.value);
|
||||||
}
|
}
|
||||||
@ -1417,10 +1417,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @returns {boolean} Whether the ability is present and active
|
* @returns {boolean} Whether the ability is present and active
|
||||||
*/
|
*/
|
||||||
hasAbility(ability: Abilities, canApply: boolean = true, ignoreOverride?: boolean): boolean {
|
hasAbility(ability: Abilities, canApply: boolean = true, ignoreOverride?: boolean): boolean {
|
||||||
if ((!canApply || this.canApplyAbility()) && this.getAbility(ignoreOverride).id === ability) {
|
if (this.getAbility(ignoreOverride).id === ability && (!canApply || this.canApplyAbility())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (this.hasPassive() && (!canApply || this.canApplyAbility(true)) && this.getPassiveAbility().id === ability) {
|
if (this.getPassiveAbility().id === ability && this.hasPassive() && (!canApply || this.canApplyAbility(true))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -1488,7 +1488,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isGrounded(): boolean {
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2684,7 +2684,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
*/
|
*/
|
||||||
apply(source: Pokemon, move: Move): HitResult {
|
apply(source: Pokemon, move: Move): HitResult {
|
||||||
const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||||
if (move.category === MoveCategory.STATUS) {
|
const moveCategory = new Utils.NumberHolder(move.category);
|
||||||
|
applyMoveAttrs(VariableMoveCategoryAttr, source, this, move, moveCategory);
|
||||||
|
if (moveCategory.value === MoveCategory.STATUS) {
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
const typeMultiplier = this.getMoveEffectiveness(source, move, false, false, cancelled);
|
const typeMultiplier = this.getMoveEffectiveness(source, move, false, false, cancelled);
|
||||||
|
|
||||||
|
@ -3084,11 +3084,12 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier {
|
|||||||
* Steals an item from a set of target Pokemon.
|
* Steals an item from a set of target Pokemon.
|
||||||
* This prioritizes high-tier held items when selecting the item to steal.
|
* This prioritizes high-tier held items when selecting the item to steal.
|
||||||
* @param pokemon The {@linkcode Pokemon} holding this item
|
* @param pokemon The {@linkcode Pokemon} holding this item
|
||||||
|
* @param target The {@linkcode Pokemon} to steal from (optional)
|
||||||
* @param _args N/A
|
* @param _args N/A
|
||||||
* @returns `true` if an item was stolen; false otherwise.
|
* @returns `true` if an item was stolen; false otherwise.
|
||||||
*/
|
*/
|
||||||
override apply(pokemon: Pokemon, ..._args: unknown[]): boolean {
|
override apply(pokemon: Pokemon, target?: Pokemon, ..._args: unknown[]): boolean {
|
||||||
const opponents = this.getTargets(pokemon);
|
const opponents = this.getTargets(pokemon, target);
|
||||||
|
|
||||||
if (!opponents.length) {
|
if (!opponents.length) {
|
||||||
return false;
|
return false;
|
||||||
@ -3187,7 +3188,7 @@ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier {
|
|||||||
* @see {@linkcode HeldItemTransferModifier}
|
* @see {@linkcode HeldItemTransferModifier}
|
||||||
*/
|
*/
|
||||||
export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModifier {
|
export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModifier {
|
||||||
private chance: number;
|
public readonly chance: number;
|
||||||
|
|
||||||
constructor(type: ModifierType, pokemonId: number, chancePercent: number, stackCount?: number) {
|
constructor(type: ModifierType, pokemonId: number, chancePercent: number, stackCount?: number) {
|
||||||
super(type, pokemonId, stackCount);
|
super(type, pokemonId, stackCount);
|
||||||
@ -3634,7 +3635,7 @@ export function overrideHeldItems(scene: BattleScene, pokemon: Pokemon, isPlayer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isPlayer) {
|
if (!isPlayer) {
|
||||||
scene.clearEnemyHeldItemModifiers();
|
scene.clearEnemyHeldItemModifiers(pokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
heldItemsOverride.forEach(item => {
|
heldItemsOverride.forEach(item => {
|
||||||
|
23
src/phases/check-status-effect-phase.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { PostTurnStatusEffectPhase } from "#app/phases/post-turn-status-effect-phase";
|
||||||
|
import { Phase } from "#app/phase";
|
||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import BattleScene from "#app/battle-scene";
|
||||||
|
|
||||||
|
export class CheckStatusEffectPhase extends Phase {
|
||||||
|
private order : BattlerIndex[];
|
||||||
|
constructor(scene : BattleScene, order : BattlerIndex[]) {
|
||||||
|
super(scene);
|
||||||
|
this.scene = scene;
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
const field = this.scene.getField();
|
||||||
|
for (const o of this.order) {
|
||||||
|
if (field[o].status && field[o].status.isPostTurn()) {
|
||||||
|
this.scene.unshiftPhase(new PostTurnStatusEffectPhase(this.scene, o));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.end();
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr,
|
|||||||
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag";
|
import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag";
|
||||||
import { MoveAnim } from "#app/data/battle-anims";
|
import { MoveAnim } from "#app/data/battle-anims";
|
||||||
import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags";
|
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 { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms";
|
||||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
||||||
import { Moves } from "#app/enums/moves";
|
import { Moves } from "#app/enums/moves";
|
||||||
@ -404,6 +404,10 @@ export class MoveEffectPhase extends PokemonPhase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target.getTag(BattlerTagType.TELEKINESIS) && !target.getTag(SemiInvulnerableTag) && !this.move.getMove().hasAttr(OneHitKOAttr)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const semiInvulnerableTag = target.getTag(SemiInvulnerableTag);
|
const semiInvulnerableTag = target.getTag(SemiInvulnerableTag);
|
||||||
if (semiInvulnerableTag
|
if (semiInvulnerableTag
|
||||||
&& !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType)
|
&& !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType)
|
||||||
|
@ -8,10 +8,6 @@ import { SpeciesFormChangePreMoveTrigger } from "#app/data/pokemon-forms";
|
|||||||
import { getStatusEffectActivationText, getStatusEffectHealText } from "#app/data/status-effect";
|
import { getStatusEffectActivationText, getStatusEffectHealText } from "#app/data/status-effect";
|
||||||
import { Type } from "#app/data/type";
|
import { Type } from "#app/data/type";
|
||||||
import { getTerrainBlockMessage } from "#app/data/weather";
|
import { getTerrainBlockMessage } from "#app/data/weather";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
|
||||||
import { BattlerTagType } from "#app/enums/battler-tag-type";
|
|
||||||
import { Moves } from "#app/enums/moves";
|
|
||||||
import { StatusEffect } from "#app/enums/status-effect";
|
|
||||||
import { MoveUsedEvent } from "#app/events/battle-scene";
|
import { MoveUsedEvent } from "#app/events/battle-scene";
|
||||||
import Pokemon, { MoveResult, PokemonMove, TurnMove } from "#app/field/pokemon";
|
import Pokemon, { MoveResult, PokemonMove, TurnMove } from "#app/field/pokemon";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
@ -20,7 +16,11 @@ import { CommonAnimPhase } from "#app/phases/common-anim-phase";
|
|||||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
||||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||||
import * as Utils from "#app/utils";
|
import { BooleanHolder, NumberHolder } from "#app/utils";
|
||||||
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class MovePhase extends BattlePhase {
|
export class MovePhase extends BattlePhase {
|
||||||
@ -89,7 +89,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
this.cancelled = true;
|
this.cancelled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public start() {
|
public start(): void {
|
||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
console.log(Moves[this.move.moveId]);
|
console.log(Moves[this.move.moveId]);
|
||||||
@ -140,7 +140,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Check for cancellation edge cases - no targets remaining, or {@linkcode Moves.NONE} is in the queue */
|
/** Check for cancellation edge cases - no targets remaining, or {@linkcode Moves.NONE} is in the queue */
|
||||||
protected resolveFinalPreMoveCancellationChecks() {
|
protected resolveFinalPreMoveCancellationChecks(): void {
|
||||||
const targets = this.getActiveTargetPokemon();
|
const targets = this.getActiveTargetPokemon();
|
||||||
const moveQueue = this.pokemon.getMoveQueue();
|
const moveQueue = this.pokemon.getMoveQueue();
|
||||||
|
|
||||||
@ -150,14 +150,14 @@ export class MovePhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getActiveTargetPokemon() {
|
public getActiveTargetPokemon(): Pokemon[] {
|
||||||
return this.scene.getField(true).filter(p => this.targets.includes(p.getBattlerIndex()));
|
return this.scene.getField(true).filter(p => this.targets.includes(p.getBattlerIndex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles {@link StatusEffect.SLEEP Sleep}/{@link StatusEffect.PARALYSIS Paralysis}/{@link StatusEffect.FREEZE Freeze} rolls and side effects.
|
* Handles {@link StatusEffect.SLEEP Sleep}/{@link StatusEffect.PARALYSIS Paralysis}/{@link StatusEffect.FREEZE Freeze} rolls and side effects.
|
||||||
*/
|
*/
|
||||||
protected resolvePreMoveStatusEffects() {
|
protected resolvePreMoveStatusEffects(): void {
|
||||||
if (!this.followUp && this.pokemon.status && !this.pokemon.status.isPostTurn()) {
|
if (!this.followUp && this.pokemon.status && !this.pokemon.status.isPostTurn()) {
|
||||||
this.pokemon.status.incrementTurn();
|
this.pokemon.status.incrementTurn();
|
||||||
let activated = false;
|
let activated = false;
|
||||||
@ -198,7 +198,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
* Lapse {@linkcode BattlerTagLapseType.PRE_MOVE PRE_MOVE} tags that trigger before a move is used, regardless of whether or not it failed.
|
* Lapse {@linkcode BattlerTagLapseType.PRE_MOVE PRE_MOVE} tags that trigger before a move is used, regardless of whether or not it failed.
|
||||||
* Also lapse {@linkcode BattlerTagLapseType.MOVE MOVE} tags if the move should be successful.
|
* Also lapse {@linkcode BattlerTagLapseType.MOVE MOVE} tags if the move should be successful.
|
||||||
*/
|
*/
|
||||||
protected lapsePreMoveAndMoveTags() {
|
protected lapsePreMoveAndMoveTags(): void {
|
||||||
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
|
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
|
||||||
|
|
||||||
// TODO: does this intentionally happen before the no targets/Moves.NONE on queue cancellation case is checked?
|
// TODO: does this intentionally happen before the no targets/Moves.NONE on queue cancellation case is checked?
|
||||||
@ -207,7 +207,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected useMove() {
|
protected useMove(): void {
|
||||||
const targets = this.getActiveTargetPokemon();
|
const targets = this.getActiveTargetPokemon();
|
||||||
const moveQueue = this.pokemon.getMoveQueue();
|
const moveQueue = this.pokemon.getMoveQueue();
|
||||||
|
|
||||||
@ -217,7 +217,8 @@ export class MovePhase extends BattlePhase {
|
|||||||
this.showMoveText();
|
this.showMoveText();
|
||||||
|
|
||||||
// TODO: Clean up implementation of two-turn moves.
|
// TODO: Clean up implementation of two-turn moves.
|
||||||
if (moveQueue.length > 0) { // Using .shift here clears out two turn moves once they've been used
|
if (moveQueue.length > 0) {
|
||||||
|
// Using .shift here clears out two turn moves once they've been used
|
||||||
this.ignorePp = moveQueue.shift()?.ignorePP ?? false;
|
this.ignorePp = moveQueue.shift()?.ignorePP ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +227,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
const ppUsed = 1 + this.getPpIncreaseFromPressure(targets);
|
const ppUsed = 1 + this.getPpIncreaseFromPressure(targets);
|
||||||
|
|
||||||
this.move.usePp(ppUsed);
|
this.move.usePp(ppUsed);
|
||||||
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed));
|
this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the battle's "last move" pointer, unless we're currently mimicking a move.
|
// Update the battle's "last move" pointer, unless we're currently mimicking a move.
|
||||||
@ -275,7 +276,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual });
|
this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual });
|
||||||
|
|
||||||
let failedText: string | undefined;
|
let failedText: string | undefined;
|
||||||
const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new Utils.BooleanHolder(false));
|
const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new BooleanHolder(false));
|
||||||
|
|
||||||
if (failureMessage) {
|
if (failureMessage) {
|
||||||
failedText = failureMessage;
|
failedText = failureMessage;
|
||||||
@ -299,7 +300,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
* Queues a {@linkcode MoveEndPhase} if the move wasn't a {@linkcode followUp} and {@linkcode canMove()} returns `true`,
|
* Queues a {@linkcode MoveEndPhase} if the move wasn't a {@linkcode followUp} and {@linkcode canMove()} returns `true`,
|
||||||
* then ends the phase.
|
* then ends the phase.
|
||||||
*/
|
*/
|
||||||
public end() {
|
public end(): void {
|
||||||
if (!this.followUp && this.canMove()) {
|
if (!this.followUp && this.canMove()) {
|
||||||
this.scene.unshiftPhase(new MoveEndPhase(this.scene, this.pokemon.getBattlerIndex()));
|
this.scene.unshiftPhase(new MoveEndPhase(this.scene, this.pokemon.getBattlerIndex()));
|
||||||
}
|
}
|
||||||
@ -313,7 +314,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
*
|
*
|
||||||
* TODO: This hardcodes the PP increase at 1 per opponent, rather than deferring to the ability.
|
* TODO: This hardcodes the PP increase at 1 per opponent, rather than deferring to the ability.
|
||||||
*/
|
*/
|
||||||
public getPpIncreaseFromPressure(targets: Pokemon[]) {
|
public getPpIncreaseFromPressure(targets: Pokemon[]): number {
|
||||||
const foesWithPressure = this.pokemon.getOpponents().filter(o => targets.includes(o) && o.isActive(true) && o.hasAbilityWithAttr(IncreasePpAbAttr));
|
const foesWithPressure = this.pokemon.getOpponents().filter(o => targets.includes(o) && o.isActive(true) && o.hasAbilityWithAttr(IncreasePpAbAttr));
|
||||||
return foesWithPressure.length;
|
return foesWithPressure.length;
|
||||||
}
|
}
|
||||||
@ -323,10 +324,10 @@ export class MovePhase extends BattlePhase {
|
|||||||
* - Move redirection abilities, effects, etc.
|
* - Move redirection abilities, effects, etc.
|
||||||
* - Counterattacks, which pass a special value into the `targets` constructor param (`[`{@linkcode BattlerIndex.ATTACKER}`]`).
|
* - Counterattacks, which pass a special value into the `targets` constructor param (`[`{@linkcode BattlerIndex.ATTACKER}`]`).
|
||||||
*/
|
*/
|
||||||
protected resolveRedirectTarget() {
|
protected resolveRedirectTarget(): void {
|
||||||
if (this.targets.length === 1) {
|
if (this.targets.length === 1) {
|
||||||
const currentTarget = this.targets[0];
|
const currentTarget = this.targets[0];
|
||||||
const redirectTarget = new Utils.NumberHolder(currentTarget);
|
const redirectTarget = new NumberHolder(currentTarget);
|
||||||
|
|
||||||
// check move redirection abilities of every pokemon *except* the user.
|
// check move redirection abilities of every pokemon *except* the user.
|
||||||
this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, redirectTarget));
|
this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, redirectTarget));
|
||||||
@ -372,7 +373,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
* If there is no last attacker, or they are no longer on the field, a message is displayed and the
|
* If there is no last attacker, or they are no longer on the field, a message is displayed and the
|
||||||
* move is marked for failure.
|
* move is marked for failure.
|
||||||
*/
|
*/
|
||||||
protected resolveCounterAttackTarget() {
|
protected resolveCounterAttackTarget(): void {
|
||||||
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
|
if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) {
|
||||||
if (this.pokemon.turnData.attacksReceived.length) {
|
if (this.pokemon.turnData.attacksReceived.length) {
|
||||||
this.targets[0] = this.pokemon.turnData.attacksReceived[0].sourceBattlerIndex;
|
this.targets[0] = this.pokemon.turnData.attacksReceived[0].sourceBattlerIndex;
|
||||||
@ -411,7 +412,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
*
|
*
|
||||||
* TODO: handle charge moves more gracefully
|
* TODO: handle charge moves more gracefully
|
||||||
*/
|
*/
|
||||||
protected handlePreMoveFailures() {
|
protected handlePreMoveFailures(): void {
|
||||||
if (this.cancelled || this.failed) {
|
if (this.cancelled || this.failed) {
|
||||||
if (this.failed) {
|
if (this.failed) {
|
||||||
const ppUsed = this.ignorePp ? 0 : 1;
|
const ppUsed = this.ignorePp ? 0 : 1;
|
||||||
|
@ -6,7 +6,6 @@ import { StatusEffect } from "#app/enums/status-effect";
|
|||||||
import Pokemon from "#app/field/pokemon";
|
import Pokemon from "#app/field/pokemon";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { PokemonPhase } from "./pokemon-phase";
|
import { PokemonPhase } from "./pokemon-phase";
|
||||||
import { PostTurnStatusEffectPhase } from "./post-turn-status-effect-phase";
|
|
||||||
|
|
||||||
export class ObtainStatusEffectPhase extends PokemonPhase {
|
export class ObtainStatusEffectPhase extends PokemonPhase {
|
||||||
private statusEffect?: StatusEffect | undefined;
|
private statusEffect?: StatusEffect | undefined;
|
||||||
@ -33,9 +32,6 @@ export class ObtainStatusEffectPhase extends PokemonPhase {
|
|||||||
pokemon.updateInfo(true);
|
pokemon.updateInfo(true);
|
||||||
new CommonBattleAnim(CommonAnim.POISON + (this.statusEffect! - 1), pokemon).play(this.scene, false, () => {
|
new CommonBattleAnim(CommonAnim.POISON + (this.statusEffect! - 1), pokemon).play(this.scene, false, () => {
|
||||||
this.scene.queueMessage(getStatusEffectObtainText(this.statusEffect, getPokemonNameWithAffix(pokemon), this.sourceText ?? undefined));
|
this.scene.queueMessage(getStatusEffectObtainText(this.statusEffect, getPokemonNameWithAffix(pokemon), this.sourceText ?? undefined));
|
||||||
if (pokemon.status?.isPostTurn()) {
|
|
||||||
this.scene.pushPhase(new PostTurnStatusEffectPhase(this.scene, this.battlerIndex));
|
|
||||||
}
|
|
||||||
this.end();
|
this.end();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -196,7 +196,7 @@ export class TitlePhase extends Phase {
|
|||||||
this.scene.gameMode = getGameMode(GameModes.DAILY);
|
this.scene.gameMode = getGameMode(GameModes.DAILY);
|
||||||
|
|
||||||
this.scene.setSeed(seed);
|
this.scene.setSeed(seed);
|
||||||
this.scene.resetSeed(1);
|
this.scene.resetSeed(0);
|
||||||
|
|
||||||
this.scene.money = this.scene.gameMode.getStartingMoney();
|
this.scene.money = this.scene.gameMode.getStartingMoney();
|
||||||
|
|
||||||
|
@ -13,10 +13,10 @@ import { BerryPhase } from "./berry-phase";
|
|||||||
import { FieldPhase } from "./field-phase";
|
import { FieldPhase } from "./field-phase";
|
||||||
import { MoveHeaderPhase } from "./move-header-phase";
|
import { MoveHeaderPhase } from "./move-header-phase";
|
||||||
import { MovePhase } from "./move-phase";
|
import { MovePhase } from "./move-phase";
|
||||||
import { PostTurnStatusEffectPhase } from "./post-turn-status-effect-phase";
|
|
||||||
import { SwitchSummonPhase } from "./switch-summon-phase";
|
import { SwitchSummonPhase } from "./switch-summon-phase";
|
||||||
import { TurnEndPhase } from "./turn-end-phase";
|
import { TurnEndPhase } from "./turn-end-phase";
|
||||||
import { WeatherEffectPhase } from "./weather-effect-phase";
|
import { WeatherEffectPhase } from "./weather-effect-phase";
|
||||||
|
import { CheckStatusEffectPhase } from "#app/phases/check-status-effect-phase";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { TrickRoomTag } from "#app/data/arena-tag";
|
import { TrickRoomTag } from "#app/data/arena-tag";
|
||||||
import { SwitchType } from "#enums/switch-type";
|
import { SwitchType } from "#enums/switch-type";
|
||||||
@ -158,7 +158,7 @@ export class TurnStartPhase extends FieldPhase {
|
|||||||
if (!queuedMove) {
|
if (!queuedMove) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move) || new PokemonMove(queuedMove.move);
|
const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move && m?.ppUsed < m?.getMovePp()) || new PokemonMove(queuedMove.move);
|
||||||
if (move.getMove().hasAttr(MoveHeaderAttr)) {
|
if (move.getMove().hasAttr(MoveHeaderAttr)) {
|
||||||
this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move));
|
this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move));
|
||||||
}
|
}
|
||||||
@ -206,11 +206,8 @@ export class TurnStartPhase extends FieldPhase {
|
|||||||
|
|
||||||
this.scene.pushPhase(new WeatherEffectPhase(this.scene));
|
this.scene.pushPhase(new WeatherEffectPhase(this.scene));
|
||||||
|
|
||||||
for (const o of moveOrder) {
|
/** Add a new phase to check who should be taking status damage */
|
||||||
if (field[o].status && field[o].status.isPostTurn()) {
|
this.scene.pushPhase(new CheckStatusEffectPhase(this.scene, moveOrder));
|
||||||
this.scene.pushPhase(new PostTurnStatusEffectPhase(this.scene, o));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.scene.pushPhase(new BerryPhase(this.scene));
|
this.scene.pushPhase(new BerryPhase(this.scene));
|
||||||
this.scene.pushPhase(new TurnEndPhase(this.scene));
|
this.scene.pushPhase(new TurnEndPhase(this.scene));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Arena } from "../field/arena";
|
import { Arena } from "../field/arena";
|
||||||
import { ArenaTag } from "../data/arena-tag";
|
import { ArenaTag, loadArenaTag } from "../data/arena-tag";
|
||||||
import { Biome } from "#enums/biome";
|
import { Biome } from "#enums/biome";
|
||||||
import { Weather } from "../data/weather";
|
import { Weather } from "../data/weather";
|
||||||
import { Terrain } from "#app/data/terrain";
|
import { Terrain } from "#app/data/terrain";
|
||||||
@ -15,6 +15,10 @@ export default class ArenaData {
|
|||||||
this.biome = sourceArena ? sourceArena.biomeType : source.biome;
|
this.biome = sourceArena ? sourceArena.biomeType : source.biome;
|
||||||
this.weather = sourceArena ? sourceArena.weather : source.weather ? new Weather(source.weather.weatherType, source.weather.turnsLeft) : null;
|
this.weather = sourceArena ? sourceArena.weather : source.weather ? new Weather(source.weather.weatherType, source.weather.turnsLeft) : null;
|
||||||
this.terrain = sourceArena ? sourceArena.terrain : source.terrain ? new Terrain(source.terrain.terrainType, source.terrain.turnsLeft) : null;
|
this.terrain = sourceArena ? sourceArena.terrain : source.terrain ? new Terrain(source.terrain.terrainType, source.terrain.turnsLeft) : null;
|
||||||
this.tags = sourceArena ? sourceArena.tags : [];
|
this.tags = [];
|
||||||
|
|
||||||
|
if (source.tags) {
|
||||||
|
this.tags = source.tags.map(t => loadArenaTag(t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import { TrainerVariant } from "#app/field/trainer";
|
|||||||
import { Variant } from "#app/data/variant";
|
import { Variant } from "#app/data/variant";
|
||||||
import { setSettingGamepad, SettingGamepad, settingGamepadDefaults } from "#app/system/settings/settings-gamepad";
|
import { setSettingGamepad, SettingGamepad, settingGamepadDefaults } from "#app/system/settings/settings-gamepad";
|
||||||
import { setSettingKeyboard, SettingKeyboard } from "#app/system/settings/settings-keyboard";
|
import { setSettingKeyboard, SettingKeyboard } from "#app/system/settings/settings-keyboard";
|
||||||
import { TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena";
|
import { TagAddedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena";
|
||||||
import * as Modifier from "#app/modifier/modifier";
|
import * as Modifier from "#app/modifier/modifier";
|
||||||
import { StatusEffect } from "#app/data/status-effect";
|
import { StatusEffect } from "#app/data/status-effect";
|
||||||
import ChallengeData from "#app/system/challenge-data";
|
import ChallengeData from "#app/system/challenge-data";
|
||||||
@ -50,6 +50,7 @@ import { applySessionDataPatches, applySettingsDataPatches, applySystemDataPatch
|
|||||||
import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data";
|
import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { PokerogueApiClearSessionData } from "#app/@types/pokerogue-api";
|
import { PokerogueApiClearSessionData } from "#app/@types/pokerogue-api";
|
||||||
|
import { ArenaTrapTag } from "#app/data/arena-tag";
|
||||||
|
|
||||||
export const defaultStarterSpecies: Species[] = [
|
export const defaultStarterSpecies: Species[] = [
|
||||||
Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE,
|
Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE,
|
||||||
@ -1085,8 +1086,18 @@ export class GameData {
|
|||||||
|
|
||||||
scene.arena.terrain = sessionData.arena.terrain;
|
scene.arena.terrain = sessionData.arena.terrain;
|
||||||
scene.arena.eventTarget.dispatchEvent(new TerrainChangedEvent(TerrainType.NONE, scene.arena.terrain?.terrainType!, scene.arena.terrain?.turnsLeft!)); // TODO: is this bang correct?
|
scene.arena.eventTarget.dispatchEvent(new TerrainChangedEvent(TerrainType.NONE, scene.arena.terrain?.terrainType!, scene.arena.terrain?.turnsLeft!)); // TODO: is this bang correct?
|
||||||
// TODO
|
|
||||||
//scene.arena.tags = sessionData.arena.tags;
|
scene.arena.tags = sessionData.arena.tags;
|
||||||
|
if (scene.arena.tags) {
|
||||||
|
for (const tag of scene.arena.tags) {
|
||||||
|
if (tag instanceof ArenaTrapTag) {
|
||||||
|
const { tagType, side, turnCount, layers, maxLayers } = tag as ArenaTrapTag;
|
||||||
|
scene.arena.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, layers, maxLayers));
|
||||||
|
} else {
|
||||||
|
scene.arena.eventTarget.dispatchEvent(new TagAddedEvent(tag.tagType, tag.side, tag.turnCount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const modifierData of sessionData.modifiers) {
|
for (const modifierData of sessionData.modifiers) {
|
||||||
const modifier = modifierData.toModifier(scene, Modifier[modifierData.className]);
|
const modifier = modifierData.toModifier(scene, Modifier[modifierData.className]);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { BattleStyle } from "#app/enums/battle-style";
|
import { BattleStyle } from "#app/enums/battle-style";
|
||||||
import { CommandPhase } from "#app/phases/command-phase";
|
import { CommandPhase } from "#app/phases/command-phase";
|
||||||
import { TurnInitPhase } from "#app/phases/turn-init-phase";
|
import { TurnInitPhase } from "#app/phases/turn-init-phase";
|
||||||
import i18next, { initI18n } from "#app/plugins/i18n";
|
import i18next from "#app/plugins/i18n";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
|
||||||
describe("Ability Timing", () => {
|
describe("Ability Timing", () => {
|
||||||
@ -32,11 +32,10 @@ describe("Ability Timing", () => {
|
|||||||
.enemySpecies(Species.MAGIKARP)
|
.enemySpecies(Species.MAGIKARP)
|
||||||
.enemyAbility(Abilities.INTIMIDATE)
|
.enemyAbility(Abilities.INTIMIDATE)
|
||||||
.ability(Abilities.BALL_FETCH);
|
.ability(Abilities.BALL_FETCH);
|
||||||
|
vi.spyOn(i18next, "t");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should trigger after switch check", async () => {
|
it("should trigger after switch check", async () => {
|
||||||
initI18n();
|
|
||||||
i18next.changeLanguage("en");
|
|
||||||
game.settings.battleStyle = BattleStyle.SWITCH;
|
game.settings.battleStyle = BattleStyle.SWITCH;
|
||||||
await game.classicMode.runToSummon([ Species.EEVEE, Species.FEEBAS ]);
|
await game.classicMode.runToSummon([ Species.EEVEE, Species.FEEBAS ]);
|
||||||
|
|
||||||
@ -46,7 +45,6 @@ describe("Ability Timing", () => {
|
|||||||
}, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase));
|
}, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase));
|
||||||
|
|
||||||
await game.phaseInterceptor.to("MessagePhase");
|
await game.phaseInterceptor.to("MessagePhase");
|
||||||
const message = game.textInterceptor.getLatestMessage();
|
expect(i18next.t).toHaveBeenCalledWith("battle:statFell", expect.objectContaining({ count: 1 }));
|
||||||
expect(message).toContain("battle:statFell");
|
|
||||||
}, 5000);
|
}, 5000);
|
||||||
});
|
});
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
|
import { allMoves, MultiHitAttr, MultiHitType } from "#app/data/move";
|
||||||
import { Status, StatusEffect } from "#app/data/status-effect";
|
import { Status, StatusEffect } from "#app/data/status-effect";
|
||||||
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
|
|
||||||
import { TurnEndPhase } from "#app/phases/turn-end-phase";
|
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
|
||||||
describe("Abilities - BATTLE BOND", () => {
|
describe("Abilities - BATTLE BOND", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
|
const baseForm = 1;
|
||||||
|
const ashForm = 2;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
phaserGame = new Phaser.Game({
|
phaserGame = new Phaser.Game({
|
||||||
type: Phaser.HEADLESS,
|
type: Phaser.HEADLESS,
|
||||||
@ -24,40 +26,68 @@ describe("Abilities - BATTLE BOND", () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
const moveToUse = Moves.SPLASH;
|
game.override.battleType("single")
|
||||||
game.override.battleType("single");
|
.startingWave(4) // Leads to arena reset on Wave 5 trainer battle
|
||||||
game.override.ability(Abilities.BATTLE_BOND);
|
.ability(Abilities.BATTLE_BOND)
|
||||||
game.override.moveset([ moveToUse ]);
|
.starterForms({ [Species.GRENINJA]: ashForm, })
|
||||||
game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]);
|
.moveset([ Moves.SPLASH, Moves.WATER_SHURIKEN ])
|
||||||
|
.enemySpecies(Species.BULBASAUR)
|
||||||
|
.enemyMoveset(Moves.SPLASH)
|
||||||
|
.startingLevel(100) // Avoid levelling up
|
||||||
|
.enemyLevel(1000); // Avoid opponent dying before `doKillOpponents()`
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
it("check if fainted pokemon switches to base form on arena reset", async () => {
|
||||||
"check if fainted pokemon switches to base form on arena reset",
|
await game.classicMode.startBattle([ Species.MAGIKARP, Species.GRENINJA ]);
|
||||||
async () => {
|
|
||||||
const baseForm = 1;
|
|
||||||
const ashForm = 2;
|
|
||||||
game.override.startingWave(4);
|
|
||||||
game.override.starterForms({
|
|
||||||
[Species.GRENINJA]: ashForm,
|
|
||||||
});
|
|
||||||
|
|
||||||
await game.startBattle([ Species.MAGIKARP, Species.GRENINJA ]);
|
const greninja = game.scene.getParty()[1];
|
||||||
|
expect(greninja.formIndex).toBe(ashForm);
|
||||||
|
|
||||||
const greninja = game.scene.getParty().find((p) => p.species.speciesId === Species.GRENINJA);
|
greninja.hp = 0;
|
||||||
expect(greninja).toBeDefined();
|
greninja.status = new Status(StatusEffect.FAINT);
|
||||||
expect(greninja!.formIndex).toBe(ashForm);
|
expect(greninja.isFainted()).toBe(true);
|
||||||
|
|
||||||
greninja!.hp = 0;
|
game.move.select(Moves.SPLASH);
|
||||||
greninja!.status = new Status(StatusEffect.FAINT);
|
await game.doKillOpponents();
|
||||||
expect(greninja!.isFainted()).toBe(true);
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
|
game.doSelectModifier();
|
||||||
|
await game.phaseInterceptor.to("QuietFormChangePhase");
|
||||||
|
|
||||||
game.move.select(Moves.SPLASH);
|
expect(greninja.formIndex).toBe(baseForm);
|
||||||
await game.doKillOpponents();
|
});
|
||||||
await game.phaseInterceptor.to(TurnEndPhase);
|
|
||||||
game.doSelectModifier();
|
|
||||||
await game.phaseInterceptor.to(QuietFormChangePhase);
|
|
||||||
|
|
||||||
expect(greninja!.formIndex).toBe(baseForm);
|
it("should not keep buffing Water Shuriken after Greninja switches to base form", async () => {
|
||||||
},
|
await game.classicMode.startBattle([ Species.GRENINJA ]);
|
||||||
);
|
|
||||||
|
const waterShuriken = allMoves[Moves.WATER_SHURIKEN];
|
||||||
|
vi.spyOn(waterShuriken, "calculateBattlePower");
|
||||||
|
|
||||||
|
let actualMultiHitType: MultiHitType | null = null;
|
||||||
|
const multiHitAttr = waterShuriken.getAttrs(MultiHitAttr)[0];
|
||||||
|
vi.spyOn(multiHitAttr, "getHitCount").mockImplementation(() => {
|
||||||
|
actualMultiHitType = multiHitAttr.getMultiHitType();
|
||||||
|
return 3;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wave 4: Use Water Shuriken in Ash form
|
||||||
|
let expectedBattlePower = 20;
|
||||||
|
let expectedMultiHitType = MultiHitType._3;
|
||||||
|
|
||||||
|
game.move.select(Moves.WATER_SHURIKEN);
|
||||||
|
await game.phaseInterceptor.to("BerryPhase", false);
|
||||||
|
expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower);
|
||||||
|
expect(actualMultiHitType).toBe(expectedMultiHitType);
|
||||||
|
|
||||||
|
await game.doKillOpponents();
|
||||||
|
await game.toNextWave();
|
||||||
|
|
||||||
|
// Wave 5: Use Water Shuriken in base form
|
||||||
|
expectedBattlePower = 15;
|
||||||
|
expectedMultiHitType = MultiHitType._2_TO_5;
|
||||||
|
|
||||||
|
game.move.select(Moves.WATER_SHURIKEN);
|
||||||
|
await game.phaseInterceptor.to("BerryPhase", false);
|
||||||
|
expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower);
|
||||||
|
expect(actualMultiHitType).toBe(expectedMultiHitType);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { StatusEffect } from "#app/data/status-effect";
|
||||||
import { toDmgValue } from "#app/utils";
|
import { toDmgValue } from "#app/utils";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { StatusEffect } from "#app/data/status-effect";
|
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
@ -222,4 +223,17 @@ describe("Abilities - Disguise", () => {
|
|||||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||||
expect(mimikyu.hp).toBe(maxHp - disguiseDamage);
|
expect(mimikyu.hp).toBe(maxHp - disguiseDamage);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("doesn't trigger if user is behind a substitute", async () => {
|
||||||
|
game.override
|
||||||
|
.enemyMoveset(Moves.SUBSTITUTE)
|
||||||
|
.moveset(Moves.POWER_TRIP);
|
||||||
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
|
game.move.select(Moves.POWER_TRIP);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(game.scene.getEnemyPokemon()!.formIndex).toBe(disguisedForm);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
|
||||||
import Pokemon from "#app/field/pokemon";
|
import Pokemon from "#app/field/pokemon";
|
||||||
import GameManager from "#test/utils/gameManager";
|
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
|
import { Stat } from "#enums/stat";
|
||||||
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
|
import GameManager from "#test/utils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import { Stat } from "#enums/stat";
|
|
||||||
|
|
||||||
describe("Abilities - Gulp Missile", () => {
|
describe("Abilities - Gulp Missile", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
@ -40,8 +41,9 @@ describe("Abilities - Gulp Missile", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
|
.disableCrits()
|
||||||
.battleType("single")
|
.battleType("single")
|
||||||
.moveset([ Moves.SURF, Moves.DIVE, Moves.SPLASH ])
|
.moveset([ Moves.SURF, Moves.DIVE, Moves.SPLASH, Moves.SUBSTITUTE ])
|
||||||
.enemySpecies(Species.SNORLAX)
|
.enemySpecies(Species.SNORLAX)
|
||||||
.enemyAbility(Abilities.BALL_FETCH)
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
.enemyMoveset(Moves.SPLASH)
|
.enemyMoveset(Moves.SPLASH)
|
||||||
@ -234,6 +236,25 @@ describe("Abilities - Gulp Missile", () => {
|
|||||||
expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.DEF)).toBe(-1);
|
expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.DEF)).toBe(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("doesn't trigger if user is behind a substitute", async () => {
|
||||||
|
game.override
|
||||||
|
.enemyAbility(Abilities.STURDY)
|
||||||
|
.enemyMoveset([ Moves.SPLASH, Moves.POWER_TRIP ]);
|
||||||
|
await game.classicMode.startBattle([ Species.CRAMORANT ]);
|
||||||
|
|
||||||
|
game.move.select(Moves.SURF);
|
||||||
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(game.scene.getPlayerPokemon()!.formIndex).toBe(GULPING_FORM);
|
||||||
|
|
||||||
|
game.move.select(Moves.SUBSTITUTE);
|
||||||
|
await game.forceEnemyMove(Moves.POWER_TRIP);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(game.scene.getPlayerPokemon()!.formIndex).toBe(GULPING_FORM);
|
||||||
|
});
|
||||||
|
|
||||||
it("cannot be suppressed", async () => {
|
it("cannot be suppressed", async () => {
|
||||||
game.override.enemyMoveset(Moves.GASTRO_ACID);
|
game.override.enemyMoveset(Moves.GASTRO_ACID);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
||||||
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
|
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
|
||||||
@ -36,7 +37,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("takes no damage from physical move and transforms to Noice", async () => {
|
it("takes no damage from physical move and transforms to Noice", async () => {
|
||||||
await game.startBattle([ Species.HITMONLEE ]);
|
await game.classicMode.startBattle([ Species.HITMONLEE ]);
|
||||||
|
|
||||||
game.move.select(Moves.TACKLE);
|
game.move.select(Moves.TACKLE);
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
it("takes no damage from the first hit of multihit physical move and transforms to Noice", async () => {
|
it("takes no damage from the first hit of multihit physical move and transforms to Noice", async () => {
|
||||||
game.override.moveset([ Moves.SURGING_STRIKES ]);
|
game.override.moveset([ Moves.SURGING_STRIKES ]);
|
||||||
game.override.enemyLevel(1);
|
game.override.enemyLevel(1);
|
||||||
await game.startBattle([ Species.HITMONLEE ]);
|
await game.classicMode.startBattle([ Species.HITMONLEE ]);
|
||||||
|
|
||||||
game.move.select(Moves.SURGING_STRIKES);
|
game.move.select(Moves.SURGING_STRIKES);
|
||||||
|
|
||||||
@ -78,7 +79,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("takes damage from special moves", async () => {
|
it("takes damage from special moves", async () => {
|
||||||
await game.startBattle([ Species.MAGIKARP ]);
|
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||||
|
|
||||||
game.move.select(Moves.ICE_BEAM);
|
game.move.select(Moves.ICE_BEAM);
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("takes effects from status moves", async () => {
|
it("takes effects from status moves", async () => {
|
||||||
await game.startBattle([ Species.MAGIKARP ]);
|
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||||
|
|
||||||
game.move.select(Moves.TOXIC_THREAD);
|
game.move.select(Moves.TOXIC_THREAD);
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
game.override.moveset([ Moves.QUICK_ATTACK ]);
|
game.override.moveset([ Moves.QUICK_ATTACK ]);
|
||||||
game.override.enemyMoveset([ Moves.HAIL, Moves.HAIL, Moves.HAIL, Moves.HAIL ]);
|
game.override.enemyMoveset([ Moves.HAIL, Moves.HAIL, Moves.HAIL, Moves.HAIL ]);
|
||||||
|
|
||||||
await game.startBattle([ Species.MAGIKARP ]);
|
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||||
|
|
||||||
game.move.select(Moves.QUICK_ATTACK);
|
game.move.select(Moves.QUICK_ATTACK);
|
||||||
|
|
||||||
@ -130,7 +131,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]);
|
game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]);
|
||||||
game.override.moveset([ Moves.SNOWSCAPE ]);
|
game.override.moveset([ Moves.SNOWSCAPE ]);
|
||||||
|
|
||||||
await game.startBattle([ Species.EISCUE, Species.NINJASK ]);
|
await game.classicMode.startBattle([ Species.EISCUE, Species.NINJASK ]);
|
||||||
|
|
||||||
game.move.select(Moves.SNOWSCAPE);
|
game.move.select(Moves.SNOWSCAPE);
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
game.override.enemySpecies(Species.SHUCKLE);
|
game.override.enemySpecies(Species.SHUCKLE);
|
||||||
game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]);
|
game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]);
|
||||||
|
|
||||||
await game.startBattle([ Species.EISCUE ]);
|
await game.classicMode.startBattle([ Species.EISCUE ]);
|
||||||
|
|
||||||
game.move.select(Moves.HAIL);
|
game.move.select(Moves.HAIL);
|
||||||
const eiscue = game.scene.getPlayerPokemon()!;
|
const eiscue = game.scene.getPlayerPokemon()!;
|
||||||
@ -176,7 +177,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
it("persists form change when switched out", async () => {
|
it("persists form change when switched out", async () => {
|
||||||
game.override.enemyMoveset([ Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK ]);
|
game.override.enemyMoveset([ Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK ]);
|
||||||
|
|
||||||
await game.startBattle([ Species.EISCUE, Species.MAGIKARP ]);
|
await game.classicMode.startBattle([ Species.EISCUE, Species.MAGIKARP ]);
|
||||||
|
|
||||||
game.move.select(Moves.ICE_BEAM);
|
game.move.select(Moves.ICE_BEAM);
|
||||||
|
|
||||||
@ -205,7 +206,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
[Species.EISCUE]: noiceForm,
|
[Species.EISCUE]: noiceForm,
|
||||||
});
|
});
|
||||||
|
|
||||||
await game.startBattle([ Species.EISCUE ]);
|
await game.classicMode.startBattle([ Species.EISCUE ]);
|
||||||
|
|
||||||
const eiscue = game.scene.getPlayerPokemon()!;
|
const eiscue = game.scene.getPlayerPokemon()!;
|
||||||
|
|
||||||
@ -222,10 +223,23 @@ describe("Abilities - Ice Face", () => {
|
|||||||
expect(eiscue.getTag(BattlerTagType.ICE_FACE)).not.toBe(undefined);
|
expect(eiscue.getTag(BattlerTagType.ICE_FACE)).not.toBe(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("doesn't trigger if user is behind a substitute", async () => {
|
||||||
|
game.override
|
||||||
|
.enemyMoveset(Moves.SUBSTITUTE)
|
||||||
|
.moveset(Moves.POWER_TRIP);
|
||||||
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
|
game.move.select(Moves.POWER_TRIP);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(game.scene.getEnemyPokemon()!.formIndex).toBe(icefaceForm);
|
||||||
|
});
|
||||||
|
|
||||||
it("cannot be suppressed", async () => {
|
it("cannot be suppressed", async () => {
|
||||||
game.override.moveset([ Moves.GASTRO_ACID ]);
|
game.override.moveset([ Moves.GASTRO_ACID ]);
|
||||||
|
|
||||||
await game.startBattle([ Species.MAGIKARP ]);
|
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||||
|
|
||||||
game.move.select(Moves.GASTRO_ACID);
|
game.move.select(Moves.GASTRO_ACID);
|
||||||
|
|
||||||
@ -241,7 +255,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
it("cannot be swapped with another ability", async () => {
|
it("cannot be swapped with another ability", async () => {
|
||||||
game.override.moveset([ Moves.SKILL_SWAP ]);
|
game.override.moveset([ Moves.SKILL_SWAP ]);
|
||||||
|
|
||||||
await game.startBattle([ Species.MAGIKARP ]);
|
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||||
|
|
||||||
game.move.select(Moves.SKILL_SWAP);
|
game.move.select(Moves.SKILL_SWAP);
|
||||||
|
|
||||||
@ -257,7 +271,7 @@ describe("Abilities - Ice Face", () => {
|
|||||||
it("cannot be copied", async () => {
|
it("cannot be copied", async () => {
|
||||||
game.override.ability(Abilities.TRACE);
|
game.override.ability(Abilities.TRACE);
|
||||||
|
|
||||||
await game.startBattle([ Species.MAGIKARP ]);
|
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||||
|
|
||||||
game.move.select(Moves.SIMPLE_BEAM);
|
game.move.select(Moves.SIMPLE_BEAM);
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import { Species } from "#enums/species";
|
|||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
import { allMoves } from "#app/data/move";
|
||||||
|
|
||||||
|
|
||||||
describe("Abilities - Sheer Force", () => {
|
describe("Abilities - Sheer Force", () => {
|
||||||
@ -174,5 +175,31 @@ describe("Abilities - Sheer Force", () => {
|
|||||||
|
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
|
it("Two Pokemon with abilities disabled by Sheer Force hitting each other should not cause a crash", async () => {
|
||||||
|
const moveToUse = Moves.CRUNCH;
|
||||||
|
game.override.enemyAbility(Abilities.COLOR_CHANGE)
|
||||||
|
.ability(Abilities.COLOR_CHANGE)
|
||||||
|
.moveset(moveToUse)
|
||||||
|
.enemyMoveset(moveToUse);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([
|
||||||
|
Species.PIDGEOT
|
||||||
|
]);
|
||||||
|
|
||||||
|
const pidgeot = game.scene.getParty()[0];
|
||||||
|
const onix = game.scene.getEnemyParty()[0];
|
||||||
|
|
||||||
|
pidgeot.stats[Stat.DEF] = 10000;
|
||||||
|
onix.stats[Stat.DEF] = 10000;
|
||||||
|
|
||||||
|
game.move.select(moveToUse);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
// Check that both Pokemon's Color Change activated
|
||||||
|
const expectedTypes = [ allMoves[moveToUse].type ];
|
||||||
|
expect(pidgeot.getTypes()).toStrictEqual(expectedTypes);
|
||||||
|
expect(onix.getTypes()).toStrictEqual(expectedTypes);
|
||||||
|
});
|
||||||
|
|
||||||
//TODO King's Rock Interaction Unit Test
|
//TODO King's Rock Interaction Unit Test
|
||||||
});
|
});
|
||||||
|
@ -55,7 +55,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
let gachaSpeciesCount = 0;
|
let gachaSpeciesCount = 0;
|
||||||
|
|
||||||
for (let i = 0; i < EGG_HATCH_COUNT; i++) {
|
for (let i = 0; i < EGG_HATCH_COUNT; i++) {
|
||||||
const result = new Egg({ scene, timestamp, sourceType: EggSourceType.GACHA_LEGENDARY, tier: EggTier.MASTER }).generatePlayerPokemon(scene).species.speciesId;
|
const result = new Egg({ scene, timestamp, sourceType: EggSourceType.GACHA_LEGENDARY, tier: EggTier.LEGENDARY }).generatePlayerPokemon(scene).species.speciesId;
|
||||||
if (result === expectedSpecies) {
|
if (result === expectedSpecies) {
|
||||||
gachaSpeciesCount++;
|
gachaSpeciesCount++;
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
});
|
});
|
||||||
it("should return an rare tier egg", () => {
|
it("should return an rare tier egg", () => {
|
||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
const expectedTier = EggTier.GREAT;
|
const expectedTier = EggTier.RARE;
|
||||||
|
|
||||||
const result = new Egg({ scene, tier: expectedTier }).tier;
|
const result = new Egg({ scene, tier: expectedTier }).tier;
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
});
|
});
|
||||||
it("should return an epic tier egg", () => {
|
it("should return an epic tier egg", () => {
|
||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
const expectedTier = EggTier.ULTRA;
|
const expectedTier = EggTier.EPIC;
|
||||||
|
|
||||||
const result = new Egg({ scene, tier: expectedTier }).tier;
|
const result = new Egg({ scene, tier: expectedTier }).tier;
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
});
|
});
|
||||||
it("should return an legendary tier egg", () => {
|
it("should return an legendary tier egg", () => {
|
||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
const expectedTier = EggTier.MASTER;
|
const expectedTier = EggTier.LEGENDARY;
|
||||||
|
|
||||||
const result = new Egg({ scene, tier: expectedTier }).tier;
|
const result = new Egg({ scene, tier: expectedTier }).tier;
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
const expectedEggTier = EggTier.COMMON;
|
const expectedEggTier = EggTier.COMMON;
|
||||||
|
|
||||||
const result = new Egg({ scene, tier: EggTier.MASTER, species: Species.BULBASAUR }).tier;
|
const result = new Egg({ scene, tier: EggTier.LEGENDARY, species: Species.BULBASAUR }).tier;
|
||||||
|
|
||||||
expect(result).toBe(expectedEggTier);
|
expect(result).toBe(expectedEggTier);
|
||||||
});
|
});
|
||||||
@ -208,7 +208,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
const expectedHatchWaves = 10;
|
const expectedHatchWaves = 10;
|
||||||
|
|
||||||
const result = new Egg({ scene, tier: EggTier.MASTER, species: Species.BULBASAUR }).hatchWaves;
|
const result = new Egg({ scene, tier: EggTier.LEGENDARY, species: Species.BULBASAUR }).hatchWaves;
|
||||||
|
|
||||||
expect(result).toBe(expectedHatchWaves);
|
expect(result).toBe(expectedHatchWaves);
|
||||||
});
|
});
|
||||||
@ -229,7 +229,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
|
|
||||||
const result = new EggData(legacyEgg).toEgg();
|
const result = new EggData(legacyEgg).toEgg();
|
||||||
|
|
||||||
expect(result.tier).toBe(EggTier.GREAT);
|
expect(result.tier).toBe(EggTier.RARE);
|
||||||
expect(result.id).toBe(legacyEgg.id);
|
expect(result.id).toBe(legacyEgg.id);
|
||||||
expect(result.timestamp).toBe(legacyEgg.timestamp);
|
expect(result.timestamp).toBe(legacyEgg.timestamp);
|
||||||
expect(result.hatchWaves).toBe(legacyEgg.hatchWaves);
|
expect(result.hatchWaves).toBe(legacyEgg.hatchWaves);
|
||||||
@ -241,9 +241,9 @@ describe("Egg Generation Tests", () => {
|
|||||||
|
|
||||||
new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.COMMON });
|
new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.COMMON });
|
||||||
|
|
||||||
expect(scene.gameData.eggPity[EggTier.GREAT]).toBe(startPityValues[EggTier.GREAT] + 1);
|
expect(scene.gameData.eggPity[EggTier.RARE]).toBe(startPityValues[EggTier.RARE] + 1);
|
||||||
expect(scene.gameData.eggPity[EggTier.ULTRA]).toBe(startPityValues[EggTier.ULTRA] + 1);
|
expect(scene.gameData.eggPity[EggTier.EPIC]).toBe(startPityValues[EggTier.EPIC] + 1);
|
||||||
expect(scene.gameData.eggPity[EggTier.MASTER]).toBe(startPityValues[EggTier.MASTER] + 1);
|
expect(scene.gameData.eggPity[EggTier.LEGENDARY]).toBe(startPityValues[EggTier.LEGENDARY] + 1);
|
||||||
});
|
});
|
||||||
it("should increase legendary egg pity by two", () => {
|
it("should increase legendary egg pity by two", () => {
|
||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
@ -251,9 +251,9 @@ describe("Egg Generation Tests", () => {
|
|||||||
|
|
||||||
new Egg({ scene, sourceType: EggSourceType.GACHA_LEGENDARY, pulled: true, tier: EggTier.COMMON });
|
new Egg({ scene, sourceType: EggSourceType.GACHA_LEGENDARY, pulled: true, tier: EggTier.COMMON });
|
||||||
|
|
||||||
expect(scene.gameData.eggPity[EggTier.GREAT]).toBe(startPityValues[EggTier.GREAT] + 1);
|
expect(scene.gameData.eggPity[EggTier.RARE]).toBe(startPityValues[EggTier.RARE] + 1);
|
||||||
expect(scene.gameData.eggPity[EggTier.ULTRA]).toBe(startPityValues[EggTier.ULTRA] + 1);
|
expect(scene.gameData.eggPity[EggTier.EPIC]).toBe(startPityValues[EggTier.EPIC] + 1);
|
||||||
expect(scene.gameData.eggPity[EggTier.MASTER]).toBe(startPityValues[EggTier.MASTER] + 2);
|
expect(scene.gameData.eggPity[EggTier.LEGENDARY]).toBe(startPityValues[EggTier.LEGENDARY] + 2);
|
||||||
});
|
});
|
||||||
it("should not increase manaphy egg count if bulbasaurs are pulled", () => {
|
it("should not increase manaphy egg count if bulbasaurs are pulled", () => {
|
||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
@ -277,7 +277,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
const startingRareEggsPulled = scene.gameData.gameStats.rareEggsPulled;
|
const startingRareEggsPulled = scene.gameData.gameStats.rareEggsPulled;
|
||||||
|
|
||||||
new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.GREAT });
|
new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.RARE });
|
||||||
|
|
||||||
expect(scene.gameData.gameStats.rareEggsPulled).toBe(startingRareEggsPulled + 1);
|
expect(scene.gameData.gameStats.rareEggsPulled).toBe(startingRareEggsPulled + 1);
|
||||||
});
|
});
|
||||||
@ -285,7 +285,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
const startingEpicEggsPulled = scene.gameData.gameStats.epicEggsPulled;
|
const startingEpicEggsPulled = scene.gameData.gameStats.epicEggsPulled;
|
||||||
|
|
||||||
new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.ULTRA });
|
new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.EPIC });
|
||||||
|
|
||||||
expect(scene.gameData.gameStats.epicEggsPulled).toBe(startingEpicEggsPulled + 1);
|
expect(scene.gameData.gameStats.epicEggsPulled).toBe(startingEpicEggsPulled + 1);
|
||||||
});
|
});
|
||||||
@ -293,7 +293,7 @@ describe("Egg Generation Tests", () => {
|
|||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
const startingLegendaryEggsPulled = scene.gameData.gameStats.legendaryEggsPulled;
|
const startingLegendaryEggsPulled = scene.gameData.gameStats.legendaryEggsPulled;
|
||||||
|
|
||||||
new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.MASTER });
|
new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.LEGENDARY });
|
||||||
|
|
||||||
expect(scene.gameData.gameStats.legendaryEggsPulled).toBe(startingLegendaryEggsPulled + 1);
|
expect(scene.gameData.gameStats.legendaryEggsPulled).toBe(startingLegendaryEggsPulled + 1);
|
||||||
});
|
});
|
||||||
@ -301,8 +301,8 @@ describe("Egg Generation Tests", () => {
|
|||||||
vi.spyOn(Utils, "randInt").mockReturnValue(1);
|
vi.spyOn(Utils, "randInt").mockReturnValue(1);
|
||||||
|
|
||||||
const scene = game.scene;
|
const scene = game.scene;
|
||||||
const expectedTier1 = EggTier.MASTER;
|
const expectedTier1 = EggTier.LEGENDARY;
|
||||||
const expectedTier2 = EggTier.ULTRA;
|
const expectedTier2 = EggTier.EPIC;
|
||||||
|
|
||||||
const result1 = new Egg({ scene, sourceType: EggSourceType.GACHA_LEGENDARY, pulled: true }).tier;
|
const result1 = new Egg({ scene, sourceType: EggSourceType.GACHA_LEGENDARY, pulled: true }).tier;
|
||||||
const result2 = new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true }).tier;
|
const result2 = new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true }).tier;
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { allMoves } from "#app/data/move";
|
import Pokemon from "#app/field/pokemon";
|
||||||
import { Abilities } from "#app/enums/abilities";
|
import { ContactHeldItemTransferChanceModifier } from "#app/modifier/modifier";
|
||||||
import { BerryType } from "#app/enums/berry-type";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#app/enums/moves";
|
import { BerryType } from "#enums/berry-type";
|
||||||
import { Species } from "#app/enums/species";
|
import { Moves } from "#enums/moves";
|
||||||
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
import { Species } from "#enums/species";
|
||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import Phase from "phaser";
|
import Phase from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
// 20 seconds
|
|
||||||
|
|
||||||
describe("Items - Grip Claw", () => {
|
describe("Items - Grip Claw", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
@ -30,39 +28,85 @@ describe("Items - Grip Claw", () => {
|
|||||||
|
|
||||||
game.override
|
game.override
|
||||||
.battleType("double")
|
.battleType("double")
|
||||||
.moveset([ Moves.POPULATION_BOMB, Moves.SPLASH ])
|
.moveset([ Moves.TACKLE, Moves.SPLASH, Moves.ATTRACT ])
|
||||||
.startingHeldItems([
|
.startingHeldItems([
|
||||||
{ name: "GRIP_CLAW", count: 5 }, // TODO: Find a way to mock the steal chance of grip claw
|
{ name: "GRIP_CLAW", count: 1 },
|
||||||
{ name: "MULTI_LENS", count: 3 },
|
|
||||||
])
|
])
|
||||||
.enemySpecies(Species.SNORLAX)
|
.enemySpecies(Species.SNORLAX)
|
||||||
.ability(Abilities.KLUTZ)
|
.enemyAbility(Abilities.UNNERVE)
|
||||||
|
.ability(Abilities.UNNERVE)
|
||||||
.enemyMoveset(Moves.SPLASH)
|
.enemyMoveset(Moves.SPLASH)
|
||||||
.enemyHeldItems([
|
.enemyHeldItems([
|
||||||
{ name: "BERRY", type: BerryType.SITRUS, count: 2 },
|
{ name: "BERRY", type: BerryType.SITRUS, count: 2 },
|
||||||
{ name: "BERRY", type: BerryType.LUM, count: 2 },
|
{ name: "BERRY", type: BerryType.LUM, count: 2 },
|
||||||
])
|
])
|
||||||
.startingLevel(100)
|
|
||||||
.enemyLevel(100);
|
.enemyLevel(100);
|
||||||
|
|
||||||
vi.spyOn(allMoves[Moves.POPULATION_BOMB], "accuracy", "get").mockReturnValue(100);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it("should steal items on contact and only from the attack target", async () => {
|
||||||
"should only steal items from the attack target",
|
await game.classicMode.startBattle([ Species.FEEBAS, Species.MILOTIC ]);
|
||||||
async () => {
|
|
||||||
await game.startBattle([ Species.PANSEAR, Species.ROWLET ]);
|
|
||||||
|
|
||||||
const enemyPokemon = game.scene.getEnemyField();
|
const [ playerPokemon, ] = game.scene.getPlayerField();
|
||||||
|
|
||||||
const enemyHeldItemCt = enemyPokemon.map(p => p.getHeldItems.length);
|
const gripClaw = playerPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier;
|
||||||
|
vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100);
|
||||||
|
|
||||||
game.move.select(Moves.POPULATION_BOMB, 0, BattlerIndex.ENEMY);
|
const enemyPokemon = game.scene.getEnemyField();
|
||||||
game.move.select(Moves.SPLASH, 1);
|
|
||||||
|
|
||||||
await game.phaseInterceptor.to(MoveEndPhase, false);
|
const playerHeldItemCount = getHeldItemCount(playerPokemon);
|
||||||
|
const enemy1HeldItemCount = getHeldItemCount(enemyPokemon[0]);
|
||||||
|
const enemy2HeldItemCount = getHeldItemCount(enemyPokemon[1]);
|
||||||
|
expect(enemy2HeldItemCount).toBeGreaterThan(0);
|
||||||
|
|
||||||
expect(enemyPokemon[1].getHeldItems.length).toBe(enemyHeldItemCt[1]);
|
game.move.select(Moves.TACKLE, 0, BattlerIndex.ENEMY_2);
|
||||||
}
|
game.move.select(Moves.SPLASH, 1);
|
||||||
);
|
|
||||||
|
await game.phaseInterceptor.to("BerryPhase", false);
|
||||||
|
|
||||||
|
const playerHeldItemCountAfter = getHeldItemCount(playerPokemon);
|
||||||
|
const enemy1HeldItemCountsAfter = getHeldItemCount(enemyPokemon[0]);
|
||||||
|
const enemy2HeldItemCountsAfter = getHeldItemCount(enemyPokemon[1]);
|
||||||
|
|
||||||
|
expect(playerHeldItemCountAfter).toBe(playerHeldItemCount + 1);
|
||||||
|
expect(enemy1HeldItemCountsAfter).toBe(enemy1HeldItemCount);
|
||||||
|
expect(enemy2HeldItemCountsAfter).toBe(enemy2HeldItemCount - 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not steal items when using a targetted, non attack move", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.FEEBAS, Species.MILOTIC ]);
|
||||||
|
|
||||||
|
const [ playerPokemon, ] = game.scene.getPlayerField();
|
||||||
|
|
||||||
|
const gripClaw = playerPokemon.getHeldItems()[0] as ContactHeldItemTransferChanceModifier;
|
||||||
|
vi.spyOn(gripClaw, "chance", "get").mockReturnValue(100);
|
||||||
|
|
||||||
|
const enemyPokemon = game.scene.getEnemyField();
|
||||||
|
|
||||||
|
const playerHeldItemCount = getHeldItemCount(playerPokemon);
|
||||||
|
const enemy1HeldItemCount = getHeldItemCount(enemyPokemon[0]);
|
||||||
|
const enemy2HeldItemCount = getHeldItemCount(enemyPokemon[1]);
|
||||||
|
expect(enemy2HeldItemCount).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
game.move.select(Moves.ATTRACT, 0, BattlerIndex.ENEMY_2);
|
||||||
|
game.move.select(Moves.SPLASH, 1);
|
||||||
|
|
||||||
|
await game.phaseInterceptor.to("BerryPhase", false);
|
||||||
|
|
||||||
|
const playerHeldItemCountAfter = getHeldItemCount(playerPokemon);
|
||||||
|
const enemy1HeldItemCountsAfter = getHeldItemCount(enemyPokemon[0]);
|
||||||
|
const enemy2HeldItemCountsAfter = getHeldItemCount(enemyPokemon[1]);
|
||||||
|
|
||||||
|
expect(playerHeldItemCountAfter).toBe(playerHeldItemCount);
|
||||||
|
expect(enemy1HeldItemCountsAfter).toBe(enemy1HeldItemCount);
|
||||||
|
expect(enemy2HeldItemCountsAfter).toBe(enemy2HeldItemCount);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets the total number of items a Pokemon holds
|
||||||
|
*/
|
||||||
|
function getHeldItemCount(pokemon: Pokemon) {
|
||||||
|
return pokemon.getHeldItems().reduce((currentTotal, item) => currentTotal + item.getStackCount(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
import { StatusEffect } from "#app/data/status-effect";
|
import { StatusEffect } from "#app/data/status-effect";
|
||||||
import { EnemyCommandPhase } from "#app/phases/enemy-command-phase";
|
import i18next from "#app/plugins/i18n";
|
||||||
import { MessagePhase } from "#app/phases/message-phase";
|
|
||||||
import { TurnEndPhase } from "#app/phases/turn-end-phase";
|
|
||||||
import i18next, { initI18n } from "#app/plugins/i18n";
|
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
const TIMEOUT = 20 * 1000;
|
||||||
|
|
||||||
describe("Items - Toxic orb", () => {
|
describe("Items - Toxic orb", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
@ -27,41 +25,36 @@ describe("Items - Toxic orb", () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
const moveToUse = Moves.GROWTH;
|
game.override
|
||||||
const oppMoveToUse = Moves.TACKLE;
|
.battleType("single")
|
||||||
game.override.battleType("single");
|
.enemySpecies(Species.RATTATA)
|
||||||
game.override.enemySpecies(Species.RATTATA);
|
.ability(Abilities.BALL_FETCH)
|
||||||
game.override.ability(Abilities.INSOMNIA);
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
game.override.enemyAbility(Abilities.INSOMNIA);
|
.moveset([ Moves.SPLASH ])
|
||||||
game.override.startingLevel(2000);
|
.enemyMoveset(Moves.SPLASH)
|
||||||
game.override.moveset([ moveToUse ]);
|
.startingHeldItems([{
|
||||||
game.override.enemyMoveset([ oppMoveToUse, oppMoveToUse, oppMoveToUse, oppMoveToUse ]);
|
name: "TOXIC_ORB",
|
||||||
game.override.startingHeldItems([{
|
}]);
|
||||||
name: "TOXIC_ORB",
|
|
||||||
}]);
|
vi.spyOn(i18next, "t");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("TOXIC ORB", async () => {
|
it("badly poisons the holder", async () => {
|
||||||
initI18n();
|
await game.classicMode.startBattle([ Species.MIGHTYENA ]);
|
||||||
i18next.changeLanguage("en");
|
|
||||||
const moveToUse = Moves.GROWTH;
|
|
||||||
await game.startBattle([
|
|
||||||
Species.MIGHTYENA,
|
|
||||||
Species.MIGHTYENA,
|
|
||||||
]);
|
|
||||||
expect(game.scene.modifiers[0].type.id).toBe("TOXIC_ORB");
|
|
||||||
|
|
||||||
game.move.select(moveToUse);
|
const player = game.scene.getPlayerField()[0];
|
||||||
|
|
||||||
// will run the 13 phase from enemyCommandPhase to TurnEndPhase
|
game.move.select(Moves.SPLASH);
|
||||||
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnEndPhase);
|
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
// Toxic orb should trigger here
|
// Toxic orb should trigger here
|
||||||
await game.phaseInterceptor.run(MessagePhase);
|
await game.phaseInterceptor.run("MessagePhase");
|
||||||
const message = game.textInterceptor.getLatestMessage();
|
expect(i18next.t).toHaveBeenCalledWith("statusEffect:toxic.obtainSource", expect.anything());
|
||||||
expect(message).toContain("statusEffect:toxic.obtainSource");
|
|
||||||
await game.phaseInterceptor.run(MessagePhase);
|
await game.toNextTurn();
|
||||||
const message2 = game.textInterceptor.getLatestMessage();
|
|
||||||
expect(message2).toBe("statusEffect:toxic.activation");
|
expect(player.status?.effect).toBe(StatusEffect.TOXIC);
|
||||||
expect(game.scene.getParty()[0].status!.effect).toBe(StatusEffect.TOXIC);
|
// Damage should not have ticked yet.
|
||||||
}, 20000);
|
expect(player.status?.turnCount).toBe(0);
|
||||||
|
}, TIMEOUT);
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Moves } from "#app/enums/moves";
|
|
||||||
import { Stat } from "#app/enums/stat";
|
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import { Stat } from "#enums/stat";
|
||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
@ -22,13 +23,15 @@ describe("Moves - Obstruct", () => {
|
|||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.battleType("single")
|
.battleType("single")
|
||||||
|
.enemySpecies(Species.MAGIKARP)
|
||||||
|
.enemyMoveset(Moves.TACKLE)
|
||||||
.enemyAbility(Abilities.BALL_FETCH)
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
.ability(Abilities.BALL_FETCH)
|
.ability(Abilities.BALL_FETCH)
|
||||||
.moveset([ Moves.OBSTRUCT ]);
|
.moveset([ Moves.OBSTRUCT ])
|
||||||
|
.starterSpecies(Species.FEEBAS);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("protects from contact damaging moves and lowers the opponent's defense by 2 stages", async () => {
|
it("protects from contact damaging moves and lowers the opponent's defense by 2 stages", async () => {
|
||||||
game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH));
|
|
||||||
await game.classicMode.startBattle();
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
game.move.select(Moves.OBSTRUCT);
|
game.move.select(Moves.OBSTRUCT);
|
||||||
@ -42,7 +45,6 @@ describe("Moves - Obstruct", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("bypasses accuracy checks when applying protection and defense reduction", async () => {
|
it("bypasses accuracy checks when applying protection and defense reduction", async () => {
|
||||||
game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH));
|
|
||||||
await game.classicMode.startBattle();
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
game.move.select(Moves.OBSTRUCT);
|
game.move.select(Moves.OBSTRUCT);
|
||||||
@ -59,7 +61,7 @@ describe("Moves - Obstruct", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
it("protects from non-contact damaging moves and doesn't lower the opponent's defense by 2 stages", async () => {
|
it("protects from non-contact damaging moves and doesn't lower the opponent's defense by 2 stages", async () => {
|
||||||
game.override.enemyMoveset(Array(4).fill(Moves.WATER_GUN));
|
game.override.enemyMoveset(Moves.WATER_GUN);
|
||||||
await game.classicMode.startBattle();
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
game.move.select(Moves.OBSTRUCT);
|
game.move.select(Moves.OBSTRUCT);
|
||||||
@ -73,7 +75,7 @@ describe("Moves - Obstruct", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("doesn't protect from status moves", async () => {
|
it("doesn't protect from status moves", async () => {
|
||||||
game.override.enemyMoveset(Array(4).fill(Moves.GROWL));
|
game.override.enemyMoveset(Moves.GROWL);
|
||||||
await game.classicMode.startBattle();
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
game.move.select(Moves.OBSTRUCT);
|
game.move.select(Moves.OBSTRUCT);
|
||||||
@ -83,4 +85,14 @@ describe("Moves - Obstruct", () => {
|
|||||||
|
|
||||||
expect(player.getStatStage(Stat.ATK)).toBe(-1);
|
expect(player.getStatStage(Stat.ATK)).toBe(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("doesn't reduce the stats of an opponent with Clear Body/etc", async () => {
|
||||||
|
game.override.enemyAbility(Abilities.CLEAR_BODY);
|
||||||
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
|
game.move.select(Moves.OBSTRUCT);
|
||||||
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
|
expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.DEF)).toBe(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
53
src/test/moves/sketch.test.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
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, expect, it } from "vitest";
|
||||||
|
|
||||||
|
describe("Moves - Sketch", () => {
|
||||||
|
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
|
||||||
|
.ability(Abilities.BALL_FETCH)
|
||||||
|
.battleType("single")
|
||||||
|
.disableCrits()
|
||||||
|
.enemySpecies(Species.SHUCKLE)
|
||||||
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.enemyMoveset(Moves.SPLASH);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Sketch should not fail even if a previous Sketch failed to retrieve a valid move and ran out of PP", async () => {
|
||||||
|
game.override.moveset([ Moves.SKETCH, Moves.SKETCH ]);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([ Species.REGIELEKI ]);
|
||||||
|
const playerPokemon = game.scene.getPlayerPokemon();
|
||||||
|
|
||||||
|
game.move.select(Moves.SKETCH);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
|
expect(playerPokemon?.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
||||||
|
const moveSlot0 = playerPokemon?.getMoveset()[0];
|
||||||
|
expect(moveSlot0?.moveId).toBe(Moves.SKETCH);
|
||||||
|
expect(moveSlot0?.getPpRatio()).toBe(0);
|
||||||
|
|
||||||
|
await game.toNextTurn();
|
||||||
|
game.move.select(Moves.SKETCH);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase");
|
||||||
|
expect(playerPokemon?.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS);
|
||||||
|
// Can't verify if the player Pokemon's moveset was successfully changed because of overrides.
|
||||||
|
});
|
||||||
|
});
|
@ -1,4 +1,3 @@
|
|||||||
import { allMoves } from "#app/data/move";
|
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
@ -7,7 +6,7 @@ import { Stat } from "#enums/stat";
|
|||||||
import GameManager from "#test/utils/gameManager";
|
import GameManager from "#test/utils/gameManager";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
describe("Moves - SYRUP BOMB", () => {
|
describe("Moves - SYRUP BOMB", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
@ -26,20 +25,21 @@ describe("Moves - SYRUP BOMB", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override
|
||||||
.starterSpecies(Species.MAGIKARP)
|
.battleType("single")
|
||||||
.enemySpecies(Species.SNORLAX)
|
.enemySpecies(Species.SNORLAX)
|
||||||
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.ability(Abilities.BALL_FETCH)
|
||||||
.startingLevel(30)
|
.startingLevel(30)
|
||||||
.enemyLevel(100)
|
.enemyLevel(100)
|
||||||
.moveset([ Moves.SYRUP_BOMB, Moves.SPLASH ])
|
.moveset([ Moves.SYRUP_BOMB, Moves.SPLASH ])
|
||||||
.enemyMoveset(Moves.SPLASH);
|
.enemyMoveset(Moves.SPLASH);
|
||||||
vi.spyOn(allMoves[Moves.SYRUP_BOMB], "accuracy", "get").mockReturnValue(100);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/syrup_bomb_(move)
|
//Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/syrup_bomb_(move)
|
||||||
|
|
||||||
it("decreases the target Pokemon's speed stat once per turn for 3 turns",
|
it("decreases the target Pokemon's speed stat once per turn for 3 turns",
|
||||||
async () => {
|
async () => {
|
||||||
await game.startBattle([ Species.MAGIKARP ]);
|
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||||
|
|
||||||
const targetPokemon = game.scene.getEnemyPokemon()!;
|
const targetPokemon = game.scene.getEnemyPokemon()!;
|
||||||
expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0);
|
expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0);
|
||||||
@ -66,7 +66,7 @@ describe("Moves - SYRUP BOMB", () => {
|
|||||||
it("does not affect Pokemon with the ability Bulletproof",
|
it("does not affect Pokemon with the ability Bulletproof",
|
||||||
async () => {
|
async () => {
|
||||||
game.override.enemyAbility(Abilities.BULLETPROOF);
|
game.override.enemyAbility(Abilities.BULLETPROOF);
|
||||||
await game.startBattle([ Species.MAGIKARP ]);
|
await game.classicMode.startBattle([ Species.MAGIKARP ]);
|
||||||
|
|
||||||
const targetPokemon = game.scene.getEnemyPokemon()!;
|
const targetPokemon = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
@ -79,4 +79,18 @@ describe("Moves - SYRUP BOMB", () => {
|
|||||||
expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0);
|
expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
it("stops lowering the target's speed if the user leaves the field", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.FEEBAS, Species.MILOTIC ]);
|
||||||
|
|
||||||
|
game.move.select(Moves.SYRUP_BOMB);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
|
await game.move.forceHit();
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
game.doSwitchPokemon(1);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.SPD)).toBe(-1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|