mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-03-21 17:25:10 -05:00
Compare commits
1055 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e66fb4fc3 | ||
|
|
54ac918828 | ||
|
|
815b5f260a | ||
|
|
2dfe57c13a | ||
|
|
6938f1f807 | ||
|
|
e57a806630 | ||
|
|
e7b13b7df3 | ||
|
|
307b84fe4c | ||
|
|
9e270bebe4 | ||
|
|
c7717be292 | ||
|
|
79483f6616 | ||
|
|
1832b39b7b | ||
|
|
84f6e93478 | ||
|
|
2b55cb90fc | ||
|
|
f01268f26c | ||
|
|
c0c337ec45 | ||
|
|
0c78853bc6 | ||
|
|
4ceb02536c | ||
|
|
6bd082af47 | ||
|
|
be33fc1ee6 | ||
|
|
bf6e6efbe7 | ||
|
|
3b326cfa83 | ||
|
|
2742d9dd47 | ||
|
|
c4d659391a | ||
|
|
400a7c54bc | ||
|
|
834cca8b8e | ||
|
|
4a736e5af1 | ||
|
|
03fc6de00e | ||
|
|
c6504627ec | ||
|
|
e5c7fe52ed | ||
|
|
8d87bb5a9c | ||
|
|
cc68e3e967 | ||
|
|
b809f86f09 | ||
|
|
7af1d0e48f | ||
|
|
3f071d4b8a | ||
|
|
8539330f7e | ||
|
|
802c1c1d99 | ||
|
|
d57d100065 | ||
|
|
e78411f6e7 | ||
|
|
55f9e85172 | ||
|
|
b36a3ea036 | ||
|
|
cb47056b1b | ||
|
|
59709dba6c | ||
|
|
04a026782d | ||
|
|
4415c0ffbe | ||
|
|
f494d48434 | ||
|
|
cf8cbd8f5d | ||
|
|
dd60398eac | ||
|
|
50ad403c5c | ||
|
|
7bd04f470c | ||
|
|
59529d79e0 | ||
|
|
5f698aaf74 | ||
|
|
4c8c7cbdef | ||
|
|
6545c74486 | ||
|
|
bf612bf9ee | ||
|
|
e4801e992a | ||
|
|
65e046529c | ||
|
|
8ce95e4a2c | ||
|
|
c9f530f412 | ||
|
|
e8bd7a5905 | ||
|
|
746d3ddf62 | ||
|
|
3a3c6739f2 | ||
|
|
c8ed448422 | ||
|
|
16675b07bc | ||
|
|
eaff3cf2a8 | ||
|
|
376da145ff | ||
|
|
1d8968acdf | ||
|
|
261dcddca6 | ||
|
|
be25932aff | ||
|
|
8a0685b03f | ||
|
|
76eb3eb3bf | ||
|
|
c30261be77 | ||
|
|
3ad40b4a5c | ||
|
|
95aad7df02 | ||
|
|
1091524b94 | ||
|
|
f4889cac74 | ||
|
|
42f591a330 | ||
|
|
a66fecae31 | ||
|
|
9cfe6c1333 | ||
|
|
686819e5e1 | ||
|
|
6b5cf272d6 | ||
|
|
a7f286ee0d | ||
|
|
c448db8692 | ||
|
|
7a55285dd1 | ||
|
|
ae43883ed1 | ||
|
|
2ad682ce28 | ||
|
|
84df91ed10 | ||
|
|
32f8ffecaa | ||
|
|
c55e84f7cb | ||
|
|
737a8095ac | ||
|
|
b9caaaa927 | ||
|
|
8f8c96915d | ||
|
|
f75c7e4ef8 | ||
|
|
df367633bc | ||
|
|
af4f85a33c | ||
|
|
2ca5d0f3ca | ||
|
|
0fd2b67850 | ||
|
|
08562488b0 | ||
|
|
a6c45ecb45 | ||
|
|
e847960a1b | ||
|
|
1cbbf9bf65 | ||
|
|
d769756639 | ||
|
|
ccdc32dd7c | ||
|
|
95416b29dc | ||
|
|
fcd41c87a1 | ||
|
|
d3f6885435 | ||
|
|
5f1667c2f4 | ||
|
|
d6cae36487 | ||
|
|
aa592f2742 | ||
|
|
4cb7ecf998 | ||
|
|
2180a5c998 | ||
|
|
12bb66810e | ||
|
|
42ceec9a6b | ||
|
|
117cb69c89 | ||
|
|
fc70a34fd3 | ||
|
|
faa549e02f | ||
|
|
550a9ad2a9 | ||
|
|
2b02955fdc | ||
|
|
b0dc94f196 | ||
|
|
712867050c | ||
|
|
b99ff0165a | ||
|
|
cd653397db | ||
|
|
feed5acb9c | ||
|
|
7a560fae3f | ||
|
|
973e1e0b96 | ||
|
|
daddd5793a | ||
|
|
dd3d52b838 | ||
|
|
ea160e1059 | ||
|
|
3619ad8eef | ||
|
|
cc37f4c724 | ||
|
|
56faffd46c | ||
|
|
3bd1a1e329 | ||
|
|
0e435f9887 | ||
|
|
7e557b7cf5 | ||
|
|
8ac23313bb | ||
|
|
5dfa67e248 | ||
|
|
ea822f8863 | ||
|
|
fe37e47d54 | ||
|
|
b5514e03af | ||
|
|
a86abb2b6b | ||
|
|
f5011b81ec | ||
|
|
9fd696977c | ||
|
|
f2883557ca | ||
|
|
6bcb0f7f32 | ||
|
|
275fc63851 | ||
|
|
d547152057 | ||
|
|
28fd76a151 | ||
|
|
2c13c40578 | ||
|
|
dd421f7466 | ||
|
|
684150d9d7 | ||
|
|
ee77cf98ae | ||
|
|
020da8412f | ||
|
|
35e871e1d1 | ||
|
|
6d9a1cd20f | ||
|
|
537afeea76 | ||
|
|
7a3f4dbbe2 | ||
|
|
c671f43d50 | ||
|
|
acdbd55ee5 | ||
|
|
1a18b3dd55 | ||
|
|
f5483a18d0 | ||
|
|
1b3275a22f | ||
|
|
de0358b763 | ||
|
|
c735c99724 | ||
|
|
cf82bac342 | ||
|
|
6304bec9dc | ||
|
|
cb910c6973 | ||
|
|
7fabf3ab4b | ||
|
|
190940fc58 | ||
|
|
d71eae4fc3 | ||
|
|
cec4772767 | ||
|
|
51eae1b871 | ||
|
|
df32a5f5bb | ||
|
|
a77084b6d5 | ||
|
|
02828be7b6 | ||
|
|
f2f5bb9786 | ||
|
|
0cf3933f8a | ||
|
|
4a6196f310 | ||
|
|
b7d8dee113 | ||
|
|
b7e25e9a09 | ||
|
|
5062101622 | ||
|
|
48727c319d | ||
|
|
ad9d7add4b | ||
|
|
61a7a3a675 | ||
|
|
6a2b1ad82e | ||
|
|
305fff4049 | ||
|
|
63bdcb392b | ||
|
|
cacd9a80bb | ||
|
|
ee8568588a | ||
|
|
b636814279 | ||
|
|
af4110abee | ||
|
|
021acd4c4c | ||
|
|
156ef64700 | ||
|
|
f10c7af9e5 | ||
|
|
07469afc59 | ||
|
|
e54906fe2c | ||
|
|
40efc83fa0 | ||
|
|
0abc64a1a6 | ||
|
|
16c2c7e90b | ||
|
|
7d2de8779e | ||
|
|
03f76488f4 | ||
|
|
d99280a578 | ||
|
|
29627552e8 | ||
|
|
66a6eec955 | ||
|
|
5b88ce0556 | ||
|
|
43cedf4025 | ||
|
|
2ed92845c9 | ||
|
|
2c58b396cb | ||
|
|
5a02f59339 | ||
|
|
fa3b107c95 | ||
|
|
11458b1bd3 | ||
|
|
0fc4e743bb | ||
|
|
9df62c450e | ||
|
|
9c6d0bf25d | ||
|
|
3498499a7f | ||
|
|
8e999f3c51 | ||
|
|
f245f28c83 | ||
|
|
cd95a13a78 | ||
|
|
39c43fc8b1 | ||
|
|
27ecc9e7d1 | ||
|
|
ce3cff6168 | ||
|
|
236833b92f | ||
|
|
4990f0a65e | ||
|
|
9df07a958d | ||
|
|
56a4b2a747 | ||
|
|
e13942b721 | ||
|
|
be5057c9e8 | ||
|
|
6f9b1e6213 | ||
|
|
30ff784f2c | ||
|
|
7828ec3220 | ||
|
|
13aa6355af | ||
|
|
787fd585e6 | ||
|
|
96904095bf | ||
|
|
533de76f4e | ||
|
|
5b3f2a121e | ||
|
|
3b8813e3a2 | ||
|
|
2f948d7a5d | ||
|
|
0faca2ef1d | ||
|
|
7112ed9564 | ||
|
|
df6ec6faa1 | ||
|
|
c6028d6458 | ||
|
|
b27e545e94 | ||
|
|
b2b885d68c | ||
|
|
3a5828895d | ||
|
|
fba466c13d | ||
|
|
7c154118e5 | ||
|
|
bccddf3975 | ||
|
|
9fae1b8a01 | ||
|
|
08bcb39912 | ||
|
|
526f4f17d5 | ||
|
|
aa1ff9fbe5 | ||
|
|
972f89fa28 | ||
|
|
e94ba6a848 | ||
|
|
f66eef5271 | ||
|
|
be4f2bd6ab | ||
|
|
8bae904193 | ||
|
|
1ee0986f67 | ||
|
|
5390fc1d20 | ||
|
|
5e542aae99 | ||
|
|
6b2b9e18ba | ||
|
|
c919f52630 | ||
|
|
8ebb431d6c | ||
|
|
90020fbf67 | ||
|
|
e8eda2446f | ||
|
|
c1e7db7735 | ||
|
|
a75e0b49e9 | ||
|
|
69081ea829 | ||
|
|
ba85377563 | ||
|
|
af7e9dbb3c | ||
|
|
b971dd072e | ||
|
|
ad3b40f1c9 | ||
|
|
ca306027fa | ||
|
|
039ee5a8ae | ||
|
|
bc580f98af | ||
|
|
bbad9183f2 | ||
|
|
0f4a8bd0c2 | ||
|
|
e06072ed8b | ||
|
|
9b9112c227 | ||
|
|
0e41bcfc6e | ||
|
|
59318c3f96 | ||
|
|
97c7a70bfd | ||
|
|
0005dd6a40 | ||
|
|
5421909ffc | ||
|
|
6e5e42e1d3 | ||
|
|
00fe920ec0 | ||
|
|
874aa6f73c | ||
|
|
7b0158b4ab | ||
|
|
e1eae4b88d | ||
|
|
142d2bb6c3 | ||
|
|
ae832da721 | ||
|
|
27f2a9d3b9 | ||
|
|
ac406bb3aa | ||
|
|
4737bb273f | ||
|
|
8fb533e4b9 | ||
|
|
c33bfbd004 | ||
|
|
bc044e3037 | ||
|
|
46980af8ce | ||
|
|
87a0f0fcde | ||
|
|
87dfb36c5c | ||
|
|
b6902782ab | ||
|
|
54d7abae08 | ||
|
|
963d49aa93 | ||
|
|
b2a85d2559 | ||
|
|
2f2e193dad | ||
|
|
31b555ee3f | ||
|
|
fd782a300b | ||
|
|
1aaa8137e6 | ||
|
|
caf0b9b9d3 | ||
|
|
f7e10ad94a | ||
|
|
85bfc60fe8 | ||
|
|
af9af342e1 | ||
|
|
44ded79364 | ||
|
|
0ef2d38ac3 | ||
|
|
6cfb5cfc98 | ||
|
|
34bd4c5d71 | ||
|
|
e8ecbc0518 | ||
|
|
cd23d6ff53 | ||
|
|
6b354689ca | ||
|
|
9562cec389 | ||
|
|
9e6f71c175 | ||
|
|
31d94e6d1e | ||
|
|
16bf2213c0 | ||
|
|
68596ed027 | ||
|
|
f083a5b45d | ||
|
|
7600085fc0 | ||
|
|
f532e74000 | ||
|
|
fcddb7fe21 | ||
|
|
5b5adadd66 | ||
|
|
332093b59e | ||
|
|
6d4985c51e | ||
|
|
0a2112b19b | ||
|
|
64a0978b8a | ||
|
|
93e8759892 | ||
|
|
f69ebf7fed | ||
|
|
b3374fb2e5 | ||
|
|
851acf73ba | ||
|
|
0c69a1f7e3 | ||
|
|
65c3bf81c6 | ||
|
|
1bc2d58eec | ||
|
|
debd7bebc3 | ||
|
|
5bef393f6f | ||
|
|
4b8c6a4d6d | ||
|
|
d0d1eab7b7 | ||
|
|
b7c444cee5 | ||
|
|
8a75295b1b | ||
|
|
558a799c81 | ||
|
|
f159beb578 | ||
|
|
051a404478 | ||
|
|
612707d654 | ||
|
|
c4cd55e397 | ||
|
|
0d555b62f4 | ||
|
|
dc48d8234e | ||
|
|
f1adacf0ee | ||
|
|
805b17ba3e | ||
|
|
ef70c3193a | ||
|
|
e3854f06e8 | ||
|
|
5ead2874eb | ||
|
|
c2162bd442 | ||
|
|
4425ec2719 | ||
|
|
c7bd8da8b6 | ||
|
|
afbe769358 | ||
|
|
4db305f846 | ||
|
|
859e6dcaa9 | ||
|
|
8890d95d61 | ||
|
|
57d62f664a | ||
|
|
d4e84d80d7 | ||
|
|
2f0fb74325 | ||
|
|
2dc477f9d8 | ||
|
|
03cf977b12 | ||
|
|
6dc97b208c | ||
|
|
912a4c1388 | ||
|
|
c75fe52753 | ||
|
|
05aa26d108 | ||
|
|
45e4f2e882 | ||
|
|
9292dd4546 | ||
|
|
f52bc482bb | ||
|
|
8f75a35759 | ||
|
|
f34f220a66 | ||
|
|
7554287821 | ||
|
|
ef80a83683 | ||
|
|
2dbd3e8772 | ||
|
|
b1192c40e5 | ||
|
|
1731cf159e | ||
|
|
fbe978a9c9 | ||
|
|
1d741a1209 | ||
|
|
42861c0c9b | ||
|
|
6f21617d42 | ||
|
|
343839efa0 | ||
|
|
2145f582c9 | ||
|
|
9b631af072 | ||
|
|
ae49cc9c66 | ||
|
|
96233e6576 | ||
|
|
16f3718c39 | ||
|
|
875eed575c | ||
|
|
f6120ffe4f | ||
|
|
7ad9c45191 | ||
|
|
658cb99fac | ||
|
|
3c1cb0912f | ||
|
|
7eca4741ab | ||
|
|
68c6f9aa35 | ||
|
|
1423bb6904 | ||
|
|
c164f85009 | ||
|
|
bd5fdfc68e | ||
|
|
a6d2c8cda5 | ||
|
|
6bf169523d | ||
|
|
def592aba0 | ||
|
|
ee81fdcca9 | ||
|
|
be2ea86180 | ||
|
|
ab4d6742d8 | ||
|
|
a157e3db0e | ||
|
|
56b9561219 | ||
|
|
ae6d677edc | ||
|
|
8af9d9cfab | ||
|
|
dbb10a22d3 | ||
|
|
42294611bb | ||
|
|
f20c0403bc | ||
|
|
9c52db4321 | ||
|
|
ac2d14a299 | ||
|
|
b8a526d479 | ||
|
|
1b2e721a37 | ||
|
|
84409bf462 | ||
|
|
32ce74568d | ||
|
|
10e3a12d4e | ||
|
|
02b461c848 | ||
|
|
336f1d58f1 | ||
|
|
4495da1c15 | ||
|
|
2eca53c782 | ||
|
|
79a073e2d8 | ||
|
|
8b37edc5ea | ||
|
|
3d4f34e784 | ||
|
|
8584c3cf50 | ||
|
|
421d35113c | ||
|
|
ad36e04327 | ||
|
|
e18740c70a | ||
|
|
da359b0d8f | ||
|
|
ce510af51f | ||
|
|
e4998fa279 | ||
|
|
318bc27ed2 | ||
|
|
de10d91321 | ||
|
|
af1833b74a | ||
|
|
743d259186 | ||
|
|
7255086287 | ||
|
|
f480b8c442 | ||
|
|
8b1efe7e45 | ||
|
|
f4a7f092f6 | ||
|
|
fde7a7962a | ||
|
|
7357f0fa8f | ||
|
|
c3e0bbd61d | ||
|
|
8797d4628c | ||
|
|
5fb1a1dd85 | ||
|
|
f50dc0f836 | ||
|
|
d2591ecc75 | ||
|
|
cec4e42f02 | ||
|
|
9c4a4277fb | ||
|
|
a35198aca7 | ||
|
|
2acecdb7bb | ||
|
|
62a399b347 | ||
|
|
919135f432 | ||
|
|
9f0e3584de | ||
|
|
38228cf1be | ||
|
|
139e57e56a | ||
|
|
c339b13ca6 | ||
|
|
79885b011a | ||
|
|
b27ddb4ae2 | ||
|
|
d0696157a3 | ||
|
|
7561ae90a9 | ||
|
|
0cda843116 | ||
|
|
2abd5c12d5 | ||
|
|
29612dd396 | ||
|
|
51c5cc594b | ||
|
|
2bc7166d4e | ||
|
|
2ece981dae | ||
|
|
c1b536d2f3 | ||
|
|
5f9ef6e4cb | ||
|
|
df1567a51a | ||
|
|
5205be2c5a | ||
|
|
73558a31f4 | ||
|
|
06325a0b57 | ||
|
|
16765c31f7 | ||
|
|
3ac9aa1121 | ||
|
|
ac20e7c438 | ||
|
|
ffe2f3111b | ||
|
|
f420a8ee12 | ||
|
|
3468744364 | ||
|
|
7143879536 | ||
|
|
9e13a9eec3 | ||
|
|
321c7bd112 | ||
|
|
60a4698695 | ||
|
|
643d650c03 | ||
|
|
3a67660d9e | ||
|
|
1ee9efa2c8 | ||
|
|
99c0799376 | ||
|
|
478faeeb69 | ||
|
|
a3932e114e | ||
|
|
368419d7d4 | ||
|
|
ace0df5c23 | ||
|
|
c1e292bf2a | ||
|
|
f1055d9c1c | ||
|
|
2ceb8375b6 | ||
|
|
4980b7c36c | ||
|
|
04454f58ac | ||
|
|
fdffa2abdd | ||
|
|
d1efa30cf4 | ||
|
|
73bf84e9b4 | ||
|
|
0d9a9f3ef8 | ||
|
|
b106dde6c0 | ||
|
|
5e2fb9b0a0 | ||
|
|
2e977534d4 | ||
|
|
9d85f6e687 | ||
|
|
ee5c3cee62 | ||
|
|
928ed14f07 | ||
|
|
7e6cea3605 | ||
|
|
c7c2f81ab2 | ||
|
|
dbdb492557 | ||
|
|
799d2e1f45 | ||
|
|
fcdefab367 | ||
|
|
ea3a0579bc | ||
|
|
ccd9b5cae7 | ||
|
|
2b834af990 | ||
|
|
b5d398e6d7 | ||
|
|
018ea4abef | ||
|
|
f891287bac | ||
|
|
7f1c827c28 | ||
|
|
21495a92f1 | ||
|
|
49676c06f7 | ||
|
|
2f03ce912d | ||
|
|
2586a8f39b | ||
|
|
f770b255f3 | ||
|
|
4a8341586a | ||
|
|
932350d503 | ||
|
|
a341d3c566 | ||
|
|
d32ad3dc98 | ||
|
|
70f9725113 | ||
|
|
18cdce9803 | ||
|
|
db07049c6c | ||
|
|
31a4289cc6 | ||
|
|
f753dbfdf0 | ||
|
|
15c2716034 | ||
|
|
3a82310b30 | ||
|
|
e473be87d1 | ||
|
|
7b8acfeadb | ||
|
|
3b5e0b558b | ||
|
|
d51d959669 | ||
|
|
5eee238838 | ||
|
|
9ae55bad0e | ||
|
|
bd0d0ebedb | ||
|
|
5fafd91d24 | ||
|
|
8d75112e4a | ||
|
|
1931b23006 | ||
|
|
936f9e4680 | ||
|
|
525d72e6fe | ||
|
|
6c053abea9 | ||
|
|
9873c3f32e | ||
|
|
d24a41bcca | ||
|
|
01286250cb | ||
|
|
8cc6743a47 | ||
|
|
03e1fb6dff | ||
|
|
503030c0d8 | ||
|
|
005d98993f | ||
|
|
c135ecdce8 | ||
|
|
20e5727112 | ||
|
|
a718a33227 | ||
|
|
3f0c9fe991 | ||
|
|
43bb532f48 | ||
|
|
909c8c51f1 | ||
|
|
f24d648c8a | ||
|
|
d757e52be0 | ||
|
|
aa2f2a306f | ||
|
|
e27ae66ec6 | ||
|
|
7f58261221 | ||
|
|
cd0b071a3e | ||
|
|
e716ef1aba | ||
|
|
4cd2f90abf | ||
|
|
455546c69f | ||
|
|
2467596832 | ||
|
|
8691ace824 | ||
|
|
6e2ca2b3ff | ||
|
|
7a9e535e35 | ||
|
|
1487d52db0 | ||
|
|
05de0574b7 | ||
|
|
ac3c06daf0 | ||
|
|
ef56c668d2 | ||
|
|
d97b176082 | ||
|
|
4d634394f5 | ||
|
|
fd21559ba8 | ||
|
|
f74586f765 | ||
|
|
99af09ba7c | ||
|
|
0899c4b7b3 | ||
|
|
46d77d4b06 | ||
|
|
48316b5864 | ||
|
|
33673d88bc | ||
|
|
b019954f68 | ||
|
|
9ca1b0c35f | ||
|
|
e9fd0b76dd | ||
|
|
3823ec2471 | ||
|
|
546dfd07ff | ||
|
|
4d314e3f5e | ||
|
|
67ca3b04eb | ||
|
|
ad3cedc8ad | ||
|
|
0c4298d29d | ||
|
|
c4a6e8de1f | ||
|
|
4012a4b532 | ||
|
|
2b7e1d48b5 | ||
|
|
4d4c541a57 | ||
|
|
20072695c1 | ||
|
|
fa5295db23 | ||
|
|
88726667a1 | ||
|
|
e81d70440e | ||
|
|
5f31e2efe3 | ||
|
|
29f0455878 | ||
|
|
450528489c | ||
|
|
19d279c9b5 | ||
|
|
38b0d9475e | ||
|
|
324966b811 | ||
|
|
53fe99a6ff | ||
|
|
6cf20d2101 | ||
|
|
c12111b5a8 | ||
|
|
beed07db0b | ||
|
|
b11d29db70 | ||
|
|
63c36a1dca | ||
|
|
eb6d580a90 | ||
|
|
85d60cefe6 | ||
|
|
fddbf8adb5 | ||
|
|
7d8f01f849 | ||
|
|
0b6c1dbeec | ||
|
|
3b7b1d2864 | ||
|
|
14f8677565 | ||
|
|
b3fd853052 | ||
|
|
613613b6b6 | ||
|
|
07b90b13cf | ||
|
|
3b6af0dd6d | ||
|
|
fccf112a61 | ||
|
|
e589a90ed5 | ||
|
|
0ad85d4127 | ||
|
|
2b32c8f57c | ||
|
|
9bcca73a33 | ||
|
|
2857a7b5ee | ||
|
|
014c77353e | ||
|
|
0bd2f3e778 | ||
|
|
481c3d14b7 | ||
|
|
ff8cc48ba2 | ||
|
|
eb550ea05c | ||
|
|
3bab394e1b | ||
|
|
6fc4ef4c45 | ||
|
|
2fffb4a3ca | ||
|
|
f92b63cc1a | ||
|
|
07a2820cf2 | ||
|
|
9ba1623c03 | ||
|
|
f8f08443ac | ||
|
|
4edd58a832 | ||
|
|
377838ccc0 | ||
|
|
f4380feffe | ||
|
|
2ce41f17f3 | ||
|
|
baf2ea69ac | ||
|
|
c49644c295 | ||
|
|
696811790c | ||
|
|
88d53617d6 | ||
|
|
a097a4265a | ||
|
|
a8794d47fb | ||
|
|
6733e2fc10 | ||
|
|
17e16863aa | ||
|
|
def62ad205 | ||
|
|
6a416d3cb2 | ||
|
|
99242d57bb | ||
|
|
6a44ac42b9 | ||
|
|
4e1b6e1d7f | ||
|
|
5771f65626 | ||
|
|
862f409e57 | ||
|
|
ac19dbb9e5 | ||
|
|
6397bfddb3 | ||
|
|
92482df250 | ||
|
|
d3d834c91a | ||
|
|
bc832df368 | ||
|
|
6533311382 | ||
|
|
c969dcb4e7 | ||
|
|
3b825333ea | ||
|
|
babf4f6576 | ||
|
|
8bcd2c2960 | ||
|
|
6e41ce15e3 | ||
|
|
5a4c785ec4 | ||
|
|
9cd93f2a0c | ||
|
|
c03510f909 | ||
|
|
687b1c4ae0 | ||
|
|
4979f9f91c | ||
|
|
5e65007240 | ||
|
|
063a19e6c1 | ||
|
|
a512048ae8 | ||
|
|
fdbe0e3b5b | ||
|
|
aab6b728cb | ||
|
|
3b4a2c9bf5 | ||
|
|
f795b5d750 | ||
|
|
e0ccfa1532 | ||
|
|
b598355b66 | ||
|
|
e982385e54 | ||
|
|
20717b7c67 | ||
|
|
dc7294ed6e | ||
|
|
7835b015d9 | ||
|
|
f68b7e94c4 | ||
|
|
d6e98c21fb | ||
|
|
36ae30160c | ||
|
|
1c28a150e7 | ||
|
|
08305c7497 | ||
|
|
1bbb8ec800 | ||
|
|
6903a2e2e7 | ||
|
|
e7b2be606a | ||
|
|
f8a4a61874 | ||
|
|
4536eee620 | ||
|
|
73a8b3188b | ||
|
|
4435fc48b8 | ||
|
|
acf0fb8a2e | ||
|
|
c73803efe7 | ||
|
|
0b6d2aa399 | ||
|
|
b5304c68b5 | ||
|
|
6007bdc0b9 | ||
|
|
2b027d9d5a | ||
|
|
f3c17bcf75 | ||
|
|
92f5871309 | ||
|
|
5e61465955 | ||
|
|
71041ecfe1 | ||
|
|
92ed7a4243 | ||
|
|
dd96c0de95 | ||
|
|
edd2068e23 | ||
|
|
48ba18608b | ||
|
|
5c9ccae9a0 | ||
|
|
6522f7987b | ||
|
|
9560f87ebd | ||
|
|
9f8e8acd53 | ||
|
|
8b6964f060 | ||
|
|
e26eadfa4c | ||
|
|
7f69e2893d | ||
|
|
bde88764cb | ||
|
|
9a2c4739b0 | ||
|
|
561fe5e375 | ||
|
|
a94972bbd2 | ||
|
|
6d1337ad0a | ||
|
|
fd1c2f1738 | ||
|
|
80996b1a3b | ||
|
|
db6107b462 | ||
|
|
de1d24e4eb | ||
|
|
2815ce3d62 | ||
|
|
5aca342e2f | ||
|
|
8dfed1fa21 | ||
|
|
a3a822d564 | ||
|
|
e1fb179e9c | ||
|
|
cf11f04043 | ||
|
|
372d05e49c | ||
|
|
af908a36b8 | ||
|
|
eb3c1f6a39 | ||
|
|
3e9d498805 | ||
|
|
909aefddbf | ||
|
|
085a67ee3a | ||
|
|
dbb7dcff8c | ||
|
|
64b80ca9f5 | ||
|
|
4ccaa1598d | ||
|
|
adbb32c71e | ||
|
|
6a8e18ec96 | ||
|
|
6513f4b18a | ||
|
|
a2f2f14ada | ||
|
|
d67f64d00e | ||
|
|
466be38a53 | ||
|
|
0bde1a1103 | ||
|
|
2b05770780 | ||
|
|
ee3d1805c9 | ||
|
|
fa88abb5d6 | ||
|
|
9c857973a2 | ||
|
|
da9a5c4d8d | ||
|
|
233c618f97 | ||
|
|
cf03724b91 | ||
|
|
0187007de5 | ||
|
|
10a58c0e16 | ||
|
|
13578bce64 | ||
|
|
cd20be423f | ||
|
|
66018a56b8 | ||
|
|
859f5f5be8 | ||
|
|
e08bc7abdf | ||
|
|
f616e48196 | ||
|
|
4b2ac032d6 | ||
|
|
17f8fbc46a | ||
|
|
a260a5f026 | ||
|
|
cb8381e2b9 | ||
|
|
0f663cd46f | ||
|
|
14b3c117b3 | ||
|
|
b81ff9a69a | ||
|
|
5669abc8c5 | ||
|
|
57dec7aa5e | ||
|
|
e07080ce5c | ||
|
|
8f57aa50bf | ||
|
|
d972d8e21b | ||
|
|
f94b419caa | ||
|
|
34295c1f6b | ||
|
|
99ff2921e5 | ||
|
|
df8a236c16 | ||
|
|
803be601e6 | ||
|
|
fc3ab2cf61 | ||
|
|
a58e184872 | ||
|
|
a87a05fc7f | ||
|
|
f54a9ed5e1 | ||
|
|
417a9183f8 | ||
|
|
99c69509ad | ||
|
|
7f51282b16 | ||
|
|
ef9e1d23e2 | ||
|
|
c4e1a4b154 | ||
|
|
5e9d392c28 | ||
|
|
0ee3291761 | ||
|
|
9b6bb90cb5 | ||
|
|
f09476998e | ||
|
|
337c3ed4dd | ||
|
|
7f4f4fe584 | ||
|
|
c5e63f84ab | ||
|
|
a7f7e9049c | ||
|
|
f13fe4495b | ||
|
|
9af6808163 | ||
|
|
c5ef8ea3e5 | ||
|
|
8158284427 | ||
|
|
ca3e6faaae | ||
|
|
27f55f7116 | ||
|
|
091241f1bb | ||
|
|
3db46c58eb | ||
|
|
4f270fa968 | ||
|
|
ec15de7e79 | ||
|
|
0e2a8001ff | ||
|
|
a4fbc8619b | ||
|
|
f23c953273 | ||
|
|
be76e2a686 | ||
|
|
d25aba9aff | ||
|
|
72d7d38568 | ||
|
|
012b6716fb | ||
|
|
fe45b7d1bf | ||
|
|
80c1460db8 | ||
|
|
48d4a386b7 | ||
|
|
ab3e4f4c50 | ||
|
|
a7489f0995 | ||
|
|
d044cd7bc5 | ||
|
|
a7e9d9883b | ||
|
|
fb65a43ced | ||
|
|
33f7b41d03 | ||
|
|
f2c7891775 | ||
|
|
b979451e76 | ||
|
|
23c387f4a0 | ||
|
|
9a670548fa | ||
|
|
d25ab4b4b3 | ||
|
|
548f6911e9 | ||
|
|
a01bb7d4a3 | ||
|
|
906cc41d41 | ||
|
|
42d52e36e0 | ||
|
|
a1e9066f9e | ||
|
|
79fd439fcd | ||
|
|
a8b794b1a7 | ||
|
|
ce7f05e240 | ||
|
|
8835f8b73d | ||
|
|
6d7778167d | ||
|
|
31e7e9bab5 | ||
|
|
9bd91a6dae | ||
|
|
751ac04a21 | ||
|
|
4ff71c51e0 | ||
|
|
1c805b8049 | ||
|
|
671f4edfad | ||
|
|
e015dc78e9 | ||
|
|
1f7d2a26f1 | ||
|
|
dcd7f2d8df | ||
|
|
a4d35be1f0 | ||
|
|
cabcc8d419 | ||
|
|
ed30b21165 | ||
|
|
2ea0348b66 | ||
|
|
9fac6d66cc | ||
|
|
4d227e26dc | ||
|
|
0f60b6458e | ||
|
|
fb1b7d040c | ||
|
|
78247527fd | ||
|
|
6668106730 | ||
|
|
7135b1d196 | ||
|
|
2dab03e2c0 | ||
|
|
0d07a671f2 | ||
|
|
4e188f3dd7 | ||
|
|
d6d74a3b8e | ||
|
|
591a83cd63 | ||
|
|
8167652d11 | ||
|
|
71759c417a | ||
|
|
58711d3511 | ||
|
|
e00df54850 | ||
|
|
e7c5f126da | ||
|
|
f2290ced37 | ||
|
|
3c2a45c68c | ||
|
|
60786853de | ||
|
|
db8576e2b3 | ||
|
|
78bd34e2d9 | ||
|
|
5a3e33257e | ||
|
|
f86f08cb9a | ||
|
|
6d455ab03e | ||
|
|
427e2deb6b | ||
|
|
36fb26649a | ||
|
|
6b3d0eefbd | ||
|
|
c273081062 | ||
|
|
6d98dfa237 | ||
|
|
74d9c773c2 | ||
|
|
9c1457ee9b | ||
|
|
3a08216317 | ||
|
|
33f2e8ffa3 | ||
|
|
0fcbe9fcec | ||
|
|
f3ed0ee66d | ||
|
|
793fee5467 | ||
|
|
535657e766 | ||
|
|
57380ae0b5 | ||
|
|
d249e388e4 | ||
|
|
6793b8a6ab | ||
|
|
cc1f5c043f | ||
|
|
a251474697 | ||
|
|
71f784c180 | ||
|
|
fa4cc97fa1 | ||
|
|
32f62518f7 | ||
|
|
777ce4d38a | ||
|
|
77d0732af3 | ||
|
|
ed9764bc23 | ||
|
|
49d81ab318 | ||
|
|
fc23103de1 | ||
|
|
789456572d | ||
|
|
61d5684b4d | ||
|
|
2186bc919f | ||
|
|
14ec078746 | ||
|
|
4079fe7846 | ||
|
|
2990bc79e2 | ||
|
|
0f8a31252b | ||
|
|
0cd19ed250 | ||
|
|
d758c21c64 | ||
|
|
ae542f3e0c | ||
|
|
c4a5ed50e4 | ||
|
|
89b976fe70 | ||
|
|
01d1ed0624 | ||
|
|
7d989abe8e | ||
|
|
81b3471cae | ||
|
|
0f64804714 | ||
|
|
9ff1398c69 | ||
|
|
40f4915925 | ||
|
|
60fad5523d | ||
|
|
8e1888b463 | ||
|
|
3bbdb4e00e | ||
|
|
5fdf220101 | ||
|
|
b7acdf9d3c | ||
|
|
291636a807 | ||
|
|
dc156eaff5 | ||
|
|
06d8a8963b | ||
|
|
c63f633f32 | ||
|
|
b48abbf09e | ||
|
|
cb81863dc5 | ||
|
|
7979ef12cc | ||
|
|
1a9d691493 | ||
|
|
6f1cd87732 | ||
|
|
65b08549d7 | ||
|
|
319d8060b7 | ||
|
|
cf7826be73 | ||
|
|
c654d83a0c | ||
|
|
991cc727f7 | ||
|
|
07cbce7ce0 | ||
|
|
d8fa1532f4 | ||
|
|
e9caabaec1 | ||
|
|
0c659c658c | ||
|
|
95e935b6af | ||
|
|
de52e37ac9 | ||
|
|
eccd7efd4c | ||
|
|
9ba3752d50 | ||
|
|
18b96a8d03 | ||
|
|
dba4211641 | ||
|
|
46b2ab79b4 | ||
|
|
87e6f20664 | ||
|
|
09facb8cbb | ||
|
|
152e7eed93 | ||
|
|
1a0953ffb6 | ||
|
|
dd5c134603 | ||
|
|
ef5ea9f0ff | ||
|
|
5383667f2c | ||
|
|
3dd18fdfa5 | ||
|
|
d7bfa16a36 | ||
|
|
e6658f6768 | ||
|
|
58ce1e6dfa | ||
|
|
26f3952930 | ||
|
|
c04e8118bc | ||
|
|
7e1622dc19 | ||
|
|
ff32395a86 | ||
|
|
a56b9801cf | ||
|
|
a337f2b4b4 | ||
|
|
415ae6be39 | ||
|
|
f5fffca889 | ||
|
|
e288deabc9 | ||
|
|
40b44b04ab | ||
|
|
4e6355837d | ||
|
|
bdeb19f26a | ||
|
|
c06500fbef | ||
|
|
673f5e11dd | ||
|
|
945f130e66 | ||
|
|
2f0ce9c423 | ||
|
|
8ff6033077 | ||
|
|
9b04fd7073 | ||
|
|
d0e3531e8b | ||
|
|
7279f81cc3 | ||
|
|
0f3eaaf2f1 | ||
|
|
0fe2067c9b | ||
|
|
243ca8b294 | ||
|
|
f6ccab5e83 | ||
|
|
f53e9995b7 | ||
|
|
ae22234ed0 | ||
|
|
75533cca60 | ||
|
|
dbf5830353 | ||
|
|
a5ae0ee42b | ||
|
|
232af5c19f | ||
|
|
e251645e11 | ||
|
|
eb3c7d1d61 | ||
|
|
39f90f25fd | ||
|
|
4cb442e33d | ||
|
|
ab1f7a2952 | ||
|
|
f2736e1a3f | ||
|
|
4346e3d34c | ||
|
|
7bf04ad1e1 | ||
|
|
f1ba8179c0 | ||
|
|
917bb0dd32 | ||
|
|
ae626838bf | ||
|
|
64b033a8c9 | ||
|
|
ef4029ce57 | ||
|
|
18ca337e13 | ||
|
|
6280f3366c | ||
|
|
10c692b174 | ||
|
|
f9a74915d3 | ||
|
|
c280cca53b | ||
|
|
d6e17ebc9e | ||
|
|
c90643efd0 | ||
|
|
99ea179aaa | ||
|
|
d9557375a0 | ||
|
|
c5b8ff7e47 | ||
|
|
285cf9e2e6 | ||
|
|
94f049ce19 | ||
|
|
b10f385d40 | ||
|
|
36aa7462af | ||
|
|
23c0ec34d2 | ||
|
|
74aa072bfb | ||
|
|
d5f4cbf053 | ||
|
|
c0b088f8e5 | ||
|
|
46ab6455c9 | ||
|
|
6e66cd2fff | ||
|
|
0cb51158aa | ||
|
|
7b32d0f8c7 | ||
|
|
95d6547739 | ||
|
|
5424ef069f | ||
|
|
2d4eecf5c4 | ||
|
|
af4ae79fa6 | ||
|
|
6200a86c3e | ||
|
|
cc1fa09b47 | ||
|
|
61b2544477 | ||
|
|
91198ac2c7 | ||
|
|
674defa1b1 | ||
|
|
719bc1a87f | ||
|
|
2a88d42831 | ||
|
|
21b368a88f | ||
|
|
be518c5025 | ||
|
|
557ed5008b | ||
|
|
d8a051e364 | ||
|
|
c0fcb03f4c | ||
|
|
d4fc262f7f |
12
.github/workflows/publish.yml
vendored
12
.github/workflows/publish.yml
vendored
|
|
@ -15,23 +15,23 @@ jobs:
|
|||
last_version: ${{ steps.last_version.outputs.version }}
|
||||
token_exists: ${{ steps.check_token.outputs.token }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 50
|
||||
# Check if the package.json version field has changed since the last push
|
||||
- name: Get current version from package.json
|
||||
id: current_version
|
||||
run: |
|
||||
echo "version=$(jq -r .version package.json)" >> $GITHUB_OUTPUT
|
||||
echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
|
||||
- name: Get the version from the last push
|
||||
id: last_version
|
||||
run: |
|
||||
git checkout ${{ github.event.before }}
|
||||
echo "version=$(jq -r .version package.json)" >> $GITHUB_OUTPUT
|
||||
echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
|
||||
- name: Check if NPM_TOKEN exists
|
||||
id: check_token
|
||||
run: |
|
||||
echo "token=$(if [ -n "${{ secrets.NPM_TOKEN }}" ]; then echo true; else echo false; fi)" >> $GITHUB_OUTPUT
|
||||
echo "token=$(if [ -n "${{ secrets.NPM_TOKEN }}" ]; then echo true; else echo false; fi)" >> "$GITHUB_OUTPUT"
|
||||
npm-publish:
|
||||
needs:
|
||||
- test
|
||||
|
|
@ -40,8 +40,8 @@ jobs:
|
|||
# We only want to publish if the package.json version field has changed
|
||||
if: needs.get-version.outputs.current_version != needs.get-version.outputs.last_version && needs.get-version.outputs.token_exists == 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 18
|
||||
cache: 'npm'
|
||||
|
|
|
|||
20
.github/workflows/test.yml
vendored
20
.github/workflows/test.yml
vendored
|
|
@ -17,15 +17,23 @@ jobs:
|
|||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
# Testing multiple Node versions makes CI take forever, and basically
|
||||
# never actually finds anything we care about. Testing one is enough.
|
||||
#
|
||||
# This number should be left at the oldest Node LTS version capable of
|
||||
# running Node without errors (it doesn't matter if it's unsupported).
|
||||
# Please freely bump this version (and the check in `pokemon-showdown`
|
||||
# and `server/index.ts`) if you want to use features from newer versions;
|
||||
# this is purely for our own reference, not to constrain programmers.
|
||||
node-version: ['18.x']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 100 # assumes PR/push to master is no larger than 100 commits. Other solutions are needlessly complex.
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
|
|
@ -35,7 +43,7 @@ jobs:
|
|||
- name: Determine which files to lint (if pull request)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v35
|
||||
uses: tj-actions/changed-files@v47
|
||||
with:
|
||||
files: |
|
||||
./config/*.ts
|
||||
|
|
@ -58,14 +66,14 @@ jobs:
|
|||
- name: Determine whether test/sim or test/random-battles need to run (if pull request)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
id: changed-directories
|
||||
uses: tj-actions/changed-files@v35
|
||||
uses: tj-actions/changed-files@v47
|
||||
with:
|
||||
files: |
|
||||
config/formats.ts
|
||||
data/**
|
||||
sim/**
|
||||
|
||||
- name: Run selective lint & neccessary tests (if pull request)
|
||||
- name: Run selective lint & necessary tests (if pull request)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
run: npm run full-test-ci
|
||||
env:
|
||||
|
|
|
|||
29
.github/workflows/update_version.yml
vendored
29
.github/workflows/update_version.yml
vendored
|
|
@ -3,12 +3,12 @@ name: Update the npm package version
|
|||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
type: choice
|
||||
description: Version type
|
||||
default: patch
|
||||
options:
|
||||
version:
|
||||
required: true
|
||||
type: choice
|
||||
description: Version type
|
||||
default: patch
|
||||
options:
|
||||
- major
|
||||
- minor
|
||||
- patch
|
||||
|
|
@ -16,27 +16,30 @@ on:
|
|||
- preminor
|
||||
- prepatch
|
||||
- prerelease
|
||||
|
||||
jobs:
|
||||
update_version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 18
|
||||
cache: 'npm'
|
||||
|
||||
- id: bump_version
|
||||
run: |
|
||||
echo "old_version=$(jq -r .version package.json)" >> $GITHUB_OUTPUT
|
||||
echo "old_version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
|
||||
npm version ${{ github.event.inputs.version }} --no-git-tag-version
|
||||
echo "new_version=$(jq -r .version package.json)" >> $GITHUB_OUTPUT
|
||||
echo "new_version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: peter-evans/create-pull-request@v4
|
||||
- uses: peter-evans/create-pull-request@v8
|
||||
with:
|
||||
title: Bump package.json version to v${{ steps.bump_version.outputs.new_version }}}
|
||||
title: Bump package.json version to v${{ steps.bump_version.outputs.new_version }}
|
||||
body: |
|
||||
Bump package.json version from `v${{ steps.bump_version.outputs.old_version }}` to `v${{ steps.bump_version.outputs.new_version }}`
|
||||
commit-message: Bump package.json version to v${{ steps.bump_version.outputs.new_version }}
|
||||
branch: npm-version-bump
|
||||
base: master
|
||||
|
||||
|
||||
|
|
|
|||
10
CODEOWNERS
10
CODEOWNERS
|
|
@ -1,25 +1,25 @@
|
|||
config/formats.ts @KrisXV @Marty-D
|
||||
data/mods/*/random-teams.ts @AnnikaCodes
|
||||
data/mods/gen9ssb/ @HoeenCoder @HisuianZoroark @KrisXV
|
||||
data/random-sets.json @MathyFurret @ACakeWearingAHat @livid-washed @adrivrie
|
||||
data/random-teams.ts @AnnikaCodes @KrisXV @MathyFurret @ACakeWearingAHat @livid-washed @adrivrie
|
||||
data/random-battles/ @KrisXV @MathyFurret @ACakeWearingAHat @livid-washed @adrivrie
|
||||
data/text/ @Marty-D
|
||||
databases/ @monsanto
|
||||
lib/sql.ts @mia-pi-git
|
||||
server/artemis/* @mia-pi-git
|
||||
server/chat-plugins/random-battles/ @KrisXV @AnnikaCodes
|
||||
server/chat-plugins/abuse-monitor.ts @mia-pi-git
|
||||
server/chat-plugins/auction.ts @Karthik99999
|
||||
server/chat-plugins/datasearch.ts @KrisXV
|
||||
server/chat-plugins/friends.ts @mia-pi-git
|
||||
server/chat-plugins/github.ts @mia-pi-git
|
||||
server/chat-plugins/hosts.ts @AnnikaCodes
|
||||
server/chat-plugins/helptickets*.ts @mia-pi-git
|
||||
server/chat-plugins/laddertours.ts @mia-pi-git
|
||||
server/chat-plugins/mafia.ts @HoeenCoder
|
||||
server/chat-plugins/othermetas.ts @KrisXV
|
||||
server/chat-plugins/permalocks.ts @mia-pi-git
|
||||
server/chat-plugins/quotes.ts @mia-pi-git @KrisXV
|
||||
server/chat-plugins/random-battles.ts @KrisXV @AnnikaCodes
|
||||
server/chat-plugins/repeats.ts @AnnikaCodes
|
||||
server/chat-plugins/responder.ts @mia-pi-git
|
||||
server/chat-plugins/rock-paper-scissors.ts @mia-pi-git
|
||||
server/chat-plugins/sample-teams.ts @KrisXV
|
||||
server/chat-plugins/scavenger*.ts @xfix @sparkychildcharlie @PartMan7
|
||||
sever/chat-plugins/teams.ts @mia-pi-git
|
||||
|
|
|
|||
|
|
@ -301,13 +301,13 @@ In general, we prefer modern ways of writing things as long as they're supported
|
|||
|
||||
- Multiline template strings: A frequent source of bugs (and also weird for readability), so we prefer to explicitly use `\n` and concatenate over multiple lines.
|
||||
|
||||
- `async`/`await`: We prefer it for readability, but in certain cases we use raw Promises or even callbacks for performance. Don't worry about it too much; we usually won't nitpick code that uses any async implementation (although we might insist on `async`/`await` if the readability difference is huge).
|
||||
- `async`/`await`: We prefer it for readability, but in certain cases we use raw Promises or even callbacks for performance. Don't worry about it too much; we usually won't nitpick code that uses either async implementation (although we might insist on `async`/`await` if the readability difference is huge).
|
||||
|
||||
- getters/setters/`Proxy`: We are generally very anti-magic. There are certain places in the code we do use magic where it's massively DRYer (or for historical reasons), but we prefer to explicitly mark that setting a variable is actually running a function with many and varied side effects. Please have a better reason than "`.foo` is less visual clutter than `.getFoo()`".
|
||||
|
||||
- Constant Enums: Don't use; we prefer constant union types, like `type Category = 'Physical' | 'Special' | 'Status'`
|
||||
|
||||
- Default Properties: Mediocre performance when compiled with `sucrase`. This is fine for objects that are rarely created, but prefer setting properties directly in a constructor, for objects created in inner loops.
|
||||
- Default Properties: Use.
|
||||
|
||||
|
||||
Dependencies
|
||||
|
|
|
|||
2
LICENSE
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2024 Guangcong Luo and other contributors http://pokemonshowdown.com/
|
||||
Copyright (c) 2011-2026 Guangcong Luo and other contributors http://pokemonshowdown.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ represented by a space), and the rest of the string being their username.
|
|||
|
||||
`|uhtml|NAME|HTML`
|
||||
|
||||
> We recieved an HTML message (NAME) that can change what it's displaying,
|
||||
> We received an HTML message (NAME) that can change what it's displaying,
|
||||
> this is used in things like our Polls system, for example.
|
||||
|
||||
`|uhtmlchange|NAME|HTML`
|
||||
|
|
@ -305,7 +305,7 @@ represented by a space), and the rest of the string being their username.
|
|||
`|tournament|update|JSON`
|
||||
|
||||
> `JSON` is a JSON object representing the changes in the tournament
|
||||
> since the last update you recieved or the start of the tournament.
|
||||
> since the last update you received or the start of the tournament.
|
||||
> These include:
|
||||
>
|
||||
format: the tournament's custom name or the format being used
|
||||
|
|
@ -478,7 +478,9 @@ If the challenge is accepted, you will receive a room initialization message.
|
|||
`JSON.searching` will be an array of format IDs you're currently searching for
|
||||
games in.
|
||||
|
||||
`JSON.games` will be a `{roomid: title}` table of games you're currently in.
|
||||
`JSON.games` will be a `{roomid: title}` table of games you're currently in,
|
||||
or `null` if you're in no games.
|
||||
|
||||
Note that this includes ALL games, so `|updatesearch|` will be sent when you
|
||||
start/end challenge battles, and even non-Pokémon games like Mafia.
|
||||
|
||||
|
|
|
|||
17
build
17
build
|
|
@ -2,10 +2,12 @@
|
|||
"use strict";
|
||||
|
||||
try {
|
||||
// technically this was introduced in Node 17, but we'll ask for the most recent LTS with it to be safe
|
||||
structuredClone({});
|
||||
// fetch was introduced in Node 18, which is EOL,
|
||||
// so we'll ask for the most recent "Active LTS" with it to be safe
|
||||
// https://nodejs.org/en/about/previous-releases
|
||||
fetch;
|
||||
} catch (e) {
|
||||
console.log("We require Node.js version 18 or later; you're using " + process.version);
|
||||
console.error("We require Node.js version 22 or later; you're using " + process.version);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -22,13 +24,10 @@ function shell(cmd) {
|
|||
|
||||
// Check to make sure the most recently added or updated dependency is installed at the correct version
|
||||
try {
|
||||
var version = require('esbuild').version.split('.');
|
||||
if (parseInt(version[1]) < 16) {
|
||||
throw new Error("esbuild version too old");
|
||||
}
|
||||
require.resolve('ts-chacha20');
|
||||
} catch (e) {
|
||||
console.log('Installing dependencies...');
|
||||
shell('npm install');
|
||||
shell('npm ci');
|
||||
}
|
||||
|
||||
// Make sure config.js exists. If not, copy it over synchronously from
|
||||
|
|
@ -48,7 +47,5 @@ try {
|
|||
// for some reason, esbuild won't be requirable until a tick has passed
|
||||
// see https://stackoverflow.com/questions/53270058/node-cant-find-certain-modules-after-synchronous-install
|
||||
setImmediate(() => {
|
||||
// npm package, don't rebuild
|
||||
if (process.argv[2] === 'postinstall' && fs.existsSync('dist')) return;
|
||||
require('./tools/build-utils').transpile(force, decl);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ Bans are just a `-` followed by the thing you want to ban.
|
|||
|
||||
`- Future` - ban things that only appears in a future generation (such as Arceus in Gen 1)
|
||||
|
||||
`- Custom` - ban made-up things other than CAP (such as Magikarp's Revenge, or Staff Bros moves)
|
||||
`- Custom` - (DEPRECATED) ban miscellaneous other things
|
||||
|
||||
`- Nonexistent` - catch-all to ban all nonexistent Pokémon, items, etc. Includes: `- CAP, - Past, - Future, - LGPE`
|
||||
|
||||
|
|
@ -83,10 +83,20 @@ Syntax is identical to bans, just replace `-` with `+`, like:
|
|||
|
||||
More specific always trumps less specific:
|
||||
|
||||
`- all Pokemon, + Uber, - Giratina, + Giratina-Altered` - allow only Ubers other than Giratina-Origin
|
||||
`- all pokemon, + Uber, - Giratina, + Giratina-Altered` - allow only Ubers other than Giratina-Origin
|
||||
|
||||
`- all pokemon, + Giratina-Altered, - Giratina, + Uber` - allow only Ubers other than Giratina-Origin
|
||||
|
||||
`- Nonexistent, + Necturna` - don't allow anything from outside the game, except the CAP Necturna
|
||||
|
||||
Except `all pokemon`, which removes all bans/unbans of pokemon before it:
|
||||
|
||||
`- all pokemon, + Pikachu, + Raichu` - allow Pikachu and Raichu
|
||||
|
||||
`+ Pikachu, - all pokemon, + Raichu` - allow only Raichu
|
||||
|
||||
(Note that `all pokemon` does not affect obtainability rules. `+ all pokemon` will not allow CAPs or anything like that.)
|
||||
|
||||
For equally specific rules, the last rule wins:
|
||||
|
||||
`- Pikachu, - Pikachu, + Pikachu` - allow Pikachu
|
||||
|
|
@ -128,7 +138,7 @@ Whitelisting
|
|||
|
||||
Instead of a banlist, you can have a list of allowed things:
|
||||
|
||||
`- all Pokemon, + Charmander, + Squirtle, + Bulbasaur` - allow only Kanto starters
|
||||
`- all pokemon, + Charmander, + Squirtle, + Bulbasaur` - allow only Kanto starters
|
||||
|
||||
`- all moves, + move: Metronome` - allow only the move Metronome
|
||||
|
||||
|
|
|
|||
|
|
@ -15,23 +15,6 @@ exports.port = 8000;
|
|||
*/
|
||||
exports.bindaddress = '0.0.0.0';
|
||||
|
||||
/**
|
||||
* workers - the number of networking child processes to spawn
|
||||
* This should be no greater than the number of threads available on your
|
||||
* server's CPU. If you're not sure how many you have, you can check from a
|
||||
* terminal by running:
|
||||
*
|
||||
* $ node -e "console.log(require('os').cpus().length)"
|
||||
*
|
||||
* Using more workers than there are available threads will cause performance
|
||||
* issues. Keeping a couple threads available for use for OS-related work and
|
||||
* other PS processes will likely give you the best performance, if your
|
||||
* server's CPU is capable of multithreading. If you don't know what any of
|
||||
* this means or you are unfamiliar with PS' networking code, leave this set
|
||||
* to 1.
|
||||
*/
|
||||
exports.workers = 1;
|
||||
|
||||
/**
|
||||
* wsdeflate - compresses WebSocket messages
|
||||
* Toggles use of the Sec-WebSocket-Extension permessage-deflate extension.
|
||||
|
|
@ -42,6 +25,15 @@ exports.workers = 1;
|
|||
*/
|
||||
exports.wsdeflate = null;
|
||||
|
||||
/**
|
||||
* lazysockets - disables eager initialization of network services
|
||||
* Turn this on if you'd prefer to manually connect Showdown to the network,
|
||||
* or you intend to run it offline.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
exports.lazysockets = false;
|
||||
|
||||
/*
|
||||
// example:
|
||||
exports.wsdeflate = {
|
||||
|
|
@ -92,6 +84,50 @@ Main's SSL deploy script from Let's Encrypt looks like:
|
|||
*/
|
||||
exports.proxyip = false;
|
||||
|
||||
// subprocesses - the number of child processes to use for various tasks.
|
||||
// Can be set to `0` instead of `{...}` to stop using subprocesses, if you're running out of RAM.
|
||||
exports.subprocesses = {
|
||||
/**
|
||||
* network - the number of networking child processes to spawn
|
||||
* This should be no greater than the number of threads available on your
|
||||
* server's CPU. If you're not sure how many you have, you can check from a
|
||||
* terminal by running:
|
||||
*
|
||||
* $ node -e "console.log(require('os').cpus().length)"
|
||||
*
|
||||
* Using more workers than there are available threads will cause performance
|
||||
* issues. Keeping a couple threads available for use for OS-related work and
|
||||
* other PS processes will likely give you the best performance, if your
|
||||
* server's CPU is capable of multithreading. If you don't know what any of
|
||||
* this means or you are unfamiliar with PS' networking code, leave this set
|
||||
* to 1.
|
||||
*/
|
||||
network: 1,
|
||||
/**
|
||||
* for simulating battles
|
||||
* You should leave this at 1 unless your server has a very large
|
||||
* amount of traffic (i.e. hundreds of concurrent battles).
|
||||
*/
|
||||
simulator: 1,
|
||||
|
||||
// beyond this point, it'd be very weird if you needed more than one of each of these
|
||||
|
||||
/** for validating teams */
|
||||
validator: 1,
|
||||
/** for user authentication */
|
||||
verifier: 1,
|
||||
localartemis: 1,
|
||||
remoteartemis: 1,
|
||||
friends: 1,
|
||||
chatdb: 1,
|
||||
modlog: 1,
|
||||
pm: 1,
|
||||
/** for the battlesearch chat plugin */
|
||||
battlesearch: 1,
|
||||
/** datasearch - for the datasearch chat plugin */
|
||||
datasearch: 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Various debug options
|
||||
*
|
||||
|
|
@ -401,15 +437,6 @@ exports.logchallenges = false;
|
|||
*/
|
||||
exports.loguserstats = 1000 * 60 * 10; // 10 minutes
|
||||
|
||||
/**
|
||||
* validatorprocesses - the number of processes to use for validating teams
|
||||
* simulatorprocesses - the number of processes to use for handling battles
|
||||
* You should leave both of these at 1 unless your server has a very large
|
||||
* amount of traffic (i.e. hundreds of concurrent battles).
|
||||
*/
|
||||
exports.validatorprocesses = 1;
|
||||
exports.simulatorprocesses = 1;
|
||||
|
||||
/**
|
||||
* inactiveuserthreshold - how long a user must be inactive before being pruned
|
||||
* from the `users` array. The default is 1 hour.
|
||||
|
|
@ -500,7 +527,7 @@ exports.lastfmkey = '';
|
|||
exports.chatlogreader = 'fs';
|
||||
/**
|
||||
* permissions and groups:
|
||||
* Each entry in `grouplist` is a seperate group. Some of the members are "special"
|
||||
* Each entry in `grouplist` is a separate group. Some of the members are "special"
|
||||
* while the rest is just a normal permission.
|
||||
* The order of the groups determines their ranking.
|
||||
* The special members are as follows:
|
||||
|
|
|
|||
2466
config/formats.ts
2466
config/formats.ts
File diff suppressed because it is too large
Load Diff
|
|
@ -127,6 +127,7 @@ List of all in-battle forme changes:
|
|||
- Darmanitan (Zen Mode)
|
||||
- Meloetta (Relic Song)
|
||||
- Shaymin-Sky (Frozen status)
|
||||
- Ramnarok (Polar Flare)
|
||||
- Mega evolutions
|
||||
- Primal reversions
|
||||
- Ultra Burst
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
const noModifyType = [
|
||||
'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'terrainpulse', 'weatherball',
|
||||
];
|
||||
if (move.type === 'Normal' && !noModifyType.includes(move.id) &&
|
||||
if (move.type === 'Normal' && (!noModifyType.includes(move.id) || this.activeMove?.isMax) &&
|
||||
!(move.isZ && move.category !== 'Status') && !(move.name === 'Tera Blast' && pokemon.terastallized)) {
|
||||
move.type = 'Flying';
|
||||
move.typeChangerBoosted = this.effect;
|
||||
|
|
@ -145,7 +145,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
if (
|
||||
effect.effectType === "Move" &&
|
||||
!effect.multihit &&
|
||||
(!effect.negateSecondary && !(effect.hasSheerForce && source.hasAbility('sheerforce')))
|
||||
!(effect.hasSheerForce && source.hasAbility('sheerforce'))
|
||||
) {
|
||||
this.effectState.checkedAngerShell = false;
|
||||
} else {
|
||||
|
|
@ -301,7 +301,6 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
aurabreak: {
|
||||
onStart(pokemon) {
|
||||
if (this.suppressingAbility(pokemon)) return;
|
||||
this.add('-ability', pokemon, 'Aura Break');
|
||||
},
|
||||
onAnyTryPrimaryHit(target, source, move) {
|
||||
|
|
@ -357,12 +356,19 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
battlebond: {
|
||||
onSourceAfterFaint(length, target, source, effect) {
|
||||
if (source.bondTriggered) return;
|
||||
if (effect?.effectType !== 'Move') return;
|
||||
if (source.abilityState.battleBondTriggered) return;
|
||||
if (source.species.id === 'greninjabond' && source.hp && !source.transformed && source.side.foePokemonLeft()) {
|
||||
this.boost({ atk: 1, spa: 1, spe: 1 }, source, source, this.effect);
|
||||
this.add('-activate', source, 'ability: Battle Bond');
|
||||
source.abilityState.battleBondTriggered = true;
|
||||
source.bondTriggered = true;
|
||||
}
|
||||
},
|
||||
onModifyMovePriority: -1,
|
||||
onModifyMove(move, attacker) {
|
||||
if (move.id === 'watershuriken' && attacker.species.name === 'Greninja-Ash' &&
|
||||
!attacker.transformed) {
|
||||
move.multihit = 3;
|
||||
}
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
|
||||
|
|
@ -405,7 +411,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
if (
|
||||
effect.effectType === "Move" &&
|
||||
!effect.multihit &&
|
||||
(!effect.negateSecondary && !(effect.hasSheerForce && source.hasAbility('sheerforce')))
|
||||
!(effect.hasSheerForce && source.hasAbility('sheerforce'))
|
||||
) {
|
||||
this.effectState.checkedBerserk = false;
|
||||
} else {
|
||||
|
|
@ -734,33 +740,29 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
num: 238,
|
||||
},
|
||||
cudchew: {
|
||||
onEatItem(item, pokemon) {
|
||||
if (item.isBerry && pokemon.addVolatile('cudchew')) {
|
||||
pokemon.volatiles['cudchew'].berry = item;
|
||||
onEatItem(item, pokemon, source, effect) {
|
||||
if (item.isBerry && (!effect || !['bugbite', 'pluck'].includes(effect.id))) {
|
||||
this.effectState.berry = item;
|
||||
this.effectState.counter = 2;
|
||||
// This is needed in case the berry was eaten during residuals, preventing the timer from decreasing this turn
|
||||
if (!this.queue.peek()) this.effectState.counter--;
|
||||
}
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
delete pokemon.volatiles['cudchew'];
|
||||
},
|
||||
condition: {
|
||||
noCopy: true,
|
||||
duration: 2,
|
||||
onRestart() {
|
||||
this.effectState.duration = 2;
|
||||
},
|
||||
onResidualOrder: 28,
|
||||
onResidualSubOrder: 2,
|
||||
onEnd(pokemon) {
|
||||
if (pokemon.hp) {
|
||||
const item = this.effectState.berry;
|
||||
this.add('-activate', pokemon, 'ability: Cud Chew');
|
||||
this.add('-enditem', pokemon, item.name, '[eat]');
|
||||
if (this.singleEvent('Eat', item, null, pokemon, null, null)) {
|
||||
this.runEvent('EatItem', pokemon, null, null, item);
|
||||
}
|
||||
if (item.onEat) pokemon.ateBerry = true;
|
||||
onResidualOrder: 28,
|
||||
onResidualSubOrder: 2,
|
||||
onResidual(pokemon) {
|
||||
if (!this.effectState.berry || !pokemon.hp) return;
|
||||
if (--this.effectState.counter <= 0) {
|
||||
const item = this.effectState.berry;
|
||||
this.add('-activate', pokemon, 'ability: Cud Chew');
|
||||
this.add('-enditem', pokemon, item.name, '[eat]');
|
||||
if (this.singleEvent('Eat', item, null, pokemon, null, null)) {
|
||||
this.runEvent('EatItem', pokemon, null, null, item);
|
||||
}
|
||||
},
|
||||
if (item.onEat) pokemon.ateBerry = true;
|
||||
delete this.effectState.berry;
|
||||
delete this.effectState.counter;
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Cud Chew",
|
||||
|
|
@ -982,7 +984,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
|
||||
if (hitSub) return;
|
||||
|
||||
if (!target.runImmunity(move.type)) return;
|
||||
if (!target.runImmunity(move)) return;
|
||||
return false;
|
||||
},
|
||||
onEffectiveness(typeMod, target, type, move) {
|
||||
|
|
@ -994,7 +996,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
|
||||
if (hitSub) return;
|
||||
|
||||
if (!target.runImmunity(move.type)) return;
|
||||
if (!target.runImmunity(move)) return;
|
||||
return 0;
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
|
|
@ -1159,9 +1161,9 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
embodyaspectcornerstone: {
|
||||
onStart(pokemon) {
|
||||
if (pokemon.baseSpecies.name === 'Ogerpon-Cornerstone-Tera' &&
|
||||
this.effectState.embodied !== pokemon.previouslySwitchedIn) {
|
||||
this.effectState.embodied = pokemon.previouslySwitchedIn;
|
||||
if (pokemon.baseSpecies.name === 'Ogerpon-Cornerstone-Tera' && pokemon.terastallized &&
|
||||
!this.effectState.embodied) {
|
||||
this.effectState.embodied = true;
|
||||
this.boost({ def: 1 }, pokemon);
|
||||
}
|
||||
},
|
||||
|
|
@ -1172,9 +1174,9 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
embodyaspecthearthflame: {
|
||||
onStart(pokemon) {
|
||||
if (pokemon.baseSpecies.name === 'Ogerpon-Hearthflame-Tera' &&
|
||||
this.effectState.embodied !== pokemon.previouslySwitchedIn) {
|
||||
this.effectState.embodied = pokemon.previouslySwitchedIn;
|
||||
if (pokemon.baseSpecies.name === 'Ogerpon-Hearthflame-Tera' && pokemon.terastallized &&
|
||||
!this.effectState.embodied) {
|
||||
this.effectState.embodied = true;
|
||||
this.boost({ atk: 1 }, pokemon);
|
||||
}
|
||||
},
|
||||
|
|
@ -1185,9 +1187,9 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
embodyaspectteal: {
|
||||
onStart(pokemon) {
|
||||
if (pokemon.baseSpecies.name === 'Ogerpon-Teal-Tera' &&
|
||||
this.effectState.embodied !== pokemon.previouslySwitchedIn) {
|
||||
this.effectState.embodied = pokemon.previouslySwitchedIn;
|
||||
if (pokemon.baseSpecies.name === 'Ogerpon-Teal-Tera' && pokemon.terastallized &&
|
||||
!this.effectState.embodied) {
|
||||
this.effectState.embodied = true;
|
||||
this.boost({ spe: 1 }, pokemon);
|
||||
}
|
||||
},
|
||||
|
|
@ -1198,9 +1200,9 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
embodyaspectwellspring: {
|
||||
onStart(pokemon) {
|
||||
if (pokemon.baseSpecies.name === 'Ogerpon-Wellspring-Tera' &&
|
||||
this.effectState.embodied !== pokemon.previouslySwitchedIn) {
|
||||
this.effectState.embodied = pokemon.previouslySwitchedIn;
|
||||
if (pokemon.baseSpecies.name === 'Ogerpon-Wellspring-Tera' && pokemon.terastallized &&
|
||||
!this.effectState.embodied) {
|
||||
this.effectState.embodied = true;
|
||||
this.boost({ spd: 1 }, pokemon);
|
||||
}
|
||||
},
|
||||
|
|
@ -1541,7 +1543,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
const noModifyType = [
|
||||
'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'terrainpulse', 'weatherball',
|
||||
];
|
||||
if (move.type === 'Normal' && !noModifyType.includes(move.id) &&
|
||||
if (move.type === 'Normal' && (!noModifyType.includes(move.id) || this.activeMove?.isMax) &&
|
||||
!(move.isZ && move.category !== 'Status') && !(move.name === 'Tera Blast' && pokemon.terastallized)) {
|
||||
move.type = 'Electric';
|
||||
move.typeChangerBoosted = this.effect;
|
||||
|
|
@ -1928,7 +1930,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
if (!target) return;
|
||||
if (move.category !== 'Physical' || target.species.id !== 'eiscue') return;
|
||||
if (target.volatiles['substitute'] && !(move.flags['bypasssub'] || move.infiltrates)) return;
|
||||
if (!target.runImmunity(move.type)) return;
|
||||
if (!target.runImmunity(move)) return;
|
||||
return false;
|
||||
},
|
||||
onEffectiveness(typeMod, target, type, move) {
|
||||
|
|
@ -1938,7 +1940,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
|
||||
if (hitSub) return;
|
||||
|
||||
if (!target.runImmunity(move.type)) return;
|
||||
if (!target.runImmunity(move)) return;
|
||||
return 0;
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
|
|
@ -2002,7 +2004,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
if (!possibleTarget.fainted) {
|
||||
// If Ogerpon is in the last slot while the Illusion Pokemon is Terastallized
|
||||
// Illusion will not disguise as anything
|
||||
if (!pokemon.terastallized || possibleTarget.species.baseSpecies !== 'Ogerpon') {
|
||||
if (!pokemon.terastallized || !['Ogerpon', 'Terapagos'].includes(possibleTarget.species.baseSpecies)) {
|
||||
pokemon.illusion = possibleTarget;
|
||||
}
|
||||
break;
|
||||
|
|
@ -2015,7 +2017,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
}
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
if (pokemon.illusion) {
|
||||
if (pokemon.illusion && !pokemon.beingCalledBack) {
|
||||
this.debug('illusion cleared');
|
||||
pokemon.illusion = null;
|
||||
const details = pokemon.getUpdatedDetails();
|
||||
|
|
@ -2257,12 +2259,12 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
libero: {
|
||||
onPrepareHit(source, target, move) {
|
||||
if (this.effectState.libero === source.previouslySwitchedIn) return;
|
||||
if (this.effectState.libero) return;
|
||||
if (move.hasBounced || move.flags['futuremove'] || move.sourceEffect === 'snatch' || move.callsMove) return;
|
||||
const type = move.type;
|
||||
if (type && type !== '???' && source.getTypes().join() !== type) {
|
||||
if (!source.setType(type)) return;
|
||||
this.effectState.libero = source.previouslySwitchedIn;
|
||||
this.effectState.libero = true;
|
||||
this.add('-start', source, 'typechange', type, '[from] ability: Libero');
|
||||
}
|
||||
},
|
||||
|
|
@ -2331,10 +2333,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
return;
|
||||
}
|
||||
if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
|
||||
const oldAbility = source.setAbility('lingeringaroma', target);
|
||||
if (oldAbility) {
|
||||
this.add('-activate', target, 'ability: Lingering Aroma', this.dex.abilities.get(oldAbility).name, `[of] ${source}`);
|
||||
}
|
||||
source.setAbility('lingeringaroma', target);
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
|
|
@ -2397,11 +2396,9 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
newMove.hasBounced = true;
|
||||
newMove.pranksterBoosted = false;
|
||||
this.actions.useMove(newMove, this.effectState.target, { target: source });
|
||||
move.hasBounced = true; // only bounce once in free-for-all battles
|
||||
return null;
|
||||
},
|
||||
condition: {
|
||||
duration: 1,
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Magic Bounce",
|
||||
rating: 4,
|
||||
|
|
@ -2421,16 +2418,21 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
magician: {
|
||||
onAfterMoveSecondarySelf(source, target, move) {
|
||||
if (!move || !target || source.switchFlag === true) return;
|
||||
if (target !== source && move.category !== 'Status') {
|
||||
if (source.item || source.volatiles['gem'] || move.id === 'fling') return;
|
||||
const yourItem = target.takeItem(source);
|
||||
if (!yourItem) return;
|
||||
if (!source.setItem(yourItem)) {
|
||||
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
|
||||
if (!move || source.switchFlag === true || !move.hitTargets || source.item || source.volatiles['gem'] ||
|
||||
move.id === 'fling' || move.category === 'Status') return;
|
||||
const hitTargets = move.hitTargets;
|
||||
this.speedSort(hitTargets);
|
||||
for (const pokemon of hitTargets) {
|
||||
if (pokemon !== source) {
|
||||
const yourItem = pokemon.takeItem(source);
|
||||
if (!yourItem) continue;
|
||||
if (!source.setItem(yourItem)) {
|
||||
pokemon.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
|
||||
continue;
|
||||
}
|
||||
this.add('-item', source, yourItem, '[from] ability: Magician', `[of] ${pokemon}`);
|
||||
return;
|
||||
}
|
||||
this.add('-item', source, yourItem, '[from] ability: Magician', `[of] ${target}`);
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
|
|
@ -2709,10 +2711,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
return;
|
||||
}
|
||||
if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
|
||||
const oldAbility = source.setAbility('mummy', target);
|
||||
if (oldAbility) {
|
||||
this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, `[of] ${source}`);
|
||||
}
|
||||
source.setAbility('mummy', target);
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
|
|
@ -2918,9 +2917,9 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
const noModifyType = [
|
||||
'hiddenpower', 'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'struggle', 'technoblast', 'terrainpulse', 'weatherball',
|
||||
];
|
||||
if (!(move.isZ && move.category !== 'Status') && !noModifyType.includes(move.id) &&
|
||||
if (!(move.isZ && move.category !== 'Status') &&
|
||||
// TODO: Figure out actual interaction
|
||||
!(move.name === 'Tera Blast' && pokemon.terastallized)) {
|
||||
(!noModifyType.includes(move.id) || this.activeMove?.isMax) && !(move.name === 'Tera Blast' && pokemon.terastallized)) {
|
||||
move.type = 'Normal';
|
||||
move.typeChangerBoosted = this.effect;
|
||||
}
|
||||
|
|
@ -2985,6 +2984,16 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
this.boost(this.effectState.boosts, this.effectState.target);
|
||||
delete this.effectState.boosts;
|
||||
},
|
||||
onAnyAfterMega() {
|
||||
if (!this.effectState.boosts) return;
|
||||
this.boost(this.effectState.boosts, this.effectState.target);
|
||||
delete this.effectState.boosts;
|
||||
},
|
||||
onAnyAfterTerastallization() {
|
||||
if (!this.effectState.boosts) return;
|
||||
this.boost(this.effectState.boosts, this.effectState.target);
|
||||
delete this.effectState.boosts;
|
||||
},
|
||||
onAnyAfterMove() {
|
||||
if (!this.effectState.boosts) return;
|
||||
this.boost(this.effectState.boosts, this.effectState.target);
|
||||
|
|
@ -3204,7 +3213,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
const noModifyType = [
|
||||
'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'terrainpulse', 'weatherball',
|
||||
];
|
||||
if (move.type === 'Normal' && !noModifyType.includes(move.id) &&
|
||||
if (move.type === 'Normal' && (!noModifyType.includes(move.id) || this.activeMove?.isMax) &&
|
||||
!(move.isZ && move.category !== 'Status') && !(move.name === 'Tera Blast' && pokemon.terastallized)) {
|
||||
move.type = 'Fairy';
|
||||
move.typeChangerBoosted = this.effect;
|
||||
|
|
@ -3294,13 +3303,8 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
if (pokemon.species.id === 'zygardecomplete' || pokemon.hp > pokemon.maxhp / 2) return;
|
||||
this.add('-activate', pokemon, 'ability: Power Construct');
|
||||
pokemon.formeChange('Zygarde-Complete', this.effect, true);
|
||||
pokemon.baseMaxhp = Math.floor(Math.floor(
|
||||
2 * pokemon.species.baseStats['hp'] + pokemon.set.ivs['hp'] + Math.floor(pokemon.set.evs['hp'] / 4) + 100
|
||||
) * pokemon.level / 100 + 10);
|
||||
const newMaxHP = pokemon.volatiles['dynamax'] ? (2 * pokemon.baseMaxhp) : pokemon.baseMaxhp;
|
||||
pokemon.hp = newMaxHP - (pokemon.maxhp - pokemon.hp);
|
||||
pokemon.maxhp = newMaxHP;
|
||||
this.add('-heal', pokemon, pokemon.getHealth, '[silent]');
|
||||
pokemon.canMegaEvo = pokemon.canMegaEvo === false ? false : this.actions.canMegaEvo(pokemon);
|
||||
pokemon.formeRegression = true;
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
|
||||
name: "Power Construct",
|
||||
|
|
@ -3312,9 +3316,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
if (!this.effectState.target.hp) return;
|
||||
const ability = target.getAbility();
|
||||
if (ability.flags['noreceiver'] || ability.id === 'noability') return;
|
||||
if (this.effectState.target.setAbility(ability)) {
|
||||
this.add('-ability', this.effectState.target, ability, '[from] ability: Power of Alchemy', `[of] ${target}`);
|
||||
}
|
||||
this.effectState.target.setAbility(ability, target);
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
|
||||
name: "Power of Alchemy",
|
||||
|
|
@ -3408,12 +3410,12 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
protean: {
|
||||
onPrepareHit(source, target, move) {
|
||||
if (this.effectState.protean === source.previouslySwitchedIn) return;
|
||||
if (this.effectState.protean) return;
|
||||
if (move.hasBounced || move.flags['futuremove'] || move.sourceEffect === 'snatch' || move.callsMove) return;
|
||||
const type = move.type;
|
||||
if (type && type !== '???' && source.getTypes().join() !== type) {
|
||||
if (!source.setType(type)) return;
|
||||
this.effectState.protean = source.previouslySwitchedIn;
|
||||
this.effectState.protean = true;
|
||||
this.add('-start', source, 'typechange', type, '[from] ability: Protean');
|
||||
}
|
||||
},
|
||||
|
|
@ -3701,9 +3703,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
if (!this.effectState.target.hp) return;
|
||||
const ability = target.getAbility();
|
||||
if (ability.flags['noreceiver'] || ability.id === 'noability') return;
|
||||
if (this.effectState.target.setAbility(ability)) {
|
||||
this.add('-ability', this.effectState.target, ability, '[from] ability: Receiver', `[of] ${target}`);
|
||||
}
|
||||
this.effectState.target.setAbility(ability, target);
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
|
||||
name: "Receiver",
|
||||
|
|
@ -3729,7 +3729,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
const noModifyType = [
|
||||
'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'terrainpulse', 'weatherball',
|
||||
];
|
||||
if (move.type === 'Normal' && !noModifyType.includes(move.id) &&
|
||||
if (move.type === 'Normal' && (!noModifyType.includes(move.id) || this.activeMove?.isMax) &&
|
||||
!(move.isZ && move.category !== 'Status') && !(move.name === 'Tera Blast' && pokemon.terastallized)) {
|
||||
move.type = 'Ice';
|
||||
move.typeChangerBoosted = this.effect;
|
||||
|
|
@ -4143,7 +4143,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
shielddust: {
|
||||
onModifySecondaries(secondaries) {
|
||||
this.debug('Shield Dust prevent secondary');
|
||||
return secondaries.filter(effect => !!(effect.self || effect.dustproof));
|
||||
return secondaries.filter(effect => !!effect.self);
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Shield Dust",
|
||||
|
|
@ -4224,35 +4224,35 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
slowstart: {
|
||||
onStart(pokemon) {
|
||||
pokemon.addVolatile('slowstart');
|
||||
this.add('-start', pokemon, 'ability: Slow Start');
|
||||
this.effectState.counter = 5;
|
||||
},
|
||||
onResidualOrder: 28,
|
||||
onResidualSubOrder: 2,
|
||||
onResidual(pokemon) {
|
||||
if (pokemon.activeTurns && this.effectState.counter) {
|
||||
this.effectState.counter--;
|
||||
if (!this.effectState.counter) {
|
||||
this.add('-end', pokemon, 'Slow Start');
|
||||
delete this.effectState.counter;
|
||||
}
|
||||
}
|
||||
},
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, pokemon) {
|
||||
if (this.effectState.counter) {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
onModifySpe(spe, pokemon) {
|
||||
if (this.effectState.counter) {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
delete pokemon.volatiles['slowstart'];
|
||||
if (pokemon.beingCalledBack) return;
|
||||
this.add('-end', pokemon, 'Slow Start', '[silent]');
|
||||
},
|
||||
condition: {
|
||||
duration: 5,
|
||||
onResidualOrder: 28,
|
||||
onResidualSubOrder: 2,
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'ability: Slow Start');
|
||||
},
|
||||
onResidual(pokemon) {
|
||||
if (!pokemon.activeTurns) {
|
||||
this.effectState.duration! += 1;
|
||||
}
|
||||
},
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, pokemon) {
|
||||
return this.chainModify(0.5);
|
||||
},
|
||||
onModifySpe(spe, pokemon) {
|
||||
return this.chainModify(0.5);
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Slow Start');
|
||||
},
|
||||
},
|
||||
flags: {},
|
||||
name: "Slow Start",
|
||||
rating: -1,
|
||||
|
|
@ -4720,6 +4720,24 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
rating: 3,
|
||||
num: 33,
|
||||
},
|
||||
swordofruin: {
|
||||
onStart(pokemon) {
|
||||
if (this.suppressingAbility(pokemon)) return;
|
||||
this.add('-ability', pokemon, 'Sword of Ruin');
|
||||
},
|
||||
onAnyModifyDef(def, target, source, move) {
|
||||
const abilityHolder = this.effectState.target;
|
||||
if (target.hasAbility('Sword of Ruin')) return;
|
||||
if (!move.ruinedDef?.hasAbility('Sword of Ruin')) move.ruinedDef = abilityHolder;
|
||||
if (move.ruinedDef !== abilityHolder) return;
|
||||
this.debug('Sword of Ruin Def drop');
|
||||
return this.chainModify(0.75);
|
||||
},
|
||||
flags: {},
|
||||
name: "Sword of Ruin",
|
||||
rating: 4.5,
|
||||
num: 285,
|
||||
},
|
||||
symbiosis: {
|
||||
onAllyAfterUseItem(item, pokemon) {
|
||||
if (pokemon.switchFlag) return;
|
||||
|
|
@ -4755,24 +4773,6 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
rating: 2,
|
||||
num: 28,
|
||||
},
|
||||
swordofruin: {
|
||||
onStart(pokemon) {
|
||||
if (this.suppressingAbility(pokemon)) return;
|
||||
this.add('-ability', pokemon, 'Sword of Ruin');
|
||||
},
|
||||
onAnyModifyDef(def, target, source, move) {
|
||||
const abilityHolder = this.effectState.target;
|
||||
if (target.hasAbility('Sword of Ruin')) return;
|
||||
if (!move.ruinedDef?.hasAbility('Sword of Ruin')) move.ruinedDef = abilityHolder;
|
||||
if (move.ruinedDef !== abilityHolder) return;
|
||||
this.debug('Sword of Ruin Def drop');
|
||||
return this.chainModify(0.75);
|
||||
},
|
||||
flags: {},
|
||||
name: "Sword of Ruin",
|
||||
rating: 4.5,
|
||||
num: 285,
|
||||
},
|
||||
tabletsofruin: {
|
||||
onStart(pokemon) {
|
||||
if (this.suppressingAbility(pokemon)) return;
|
||||
|
|
@ -4879,14 +4879,6 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
if (pokemon.species.forme !== 'Terastal') {
|
||||
this.add('-activate', pokemon, 'ability: Tera Shift');
|
||||
pokemon.formeChange('Terapagos-Terastal', this.effect, true);
|
||||
pokemon.regressionForme = false;
|
||||
pokemon.baseMaxhp = Math.floor(Math.floor(
|
||||
2 * pokemon.species.baseStats['hp'] + pokemon.set.ivs['hp'] + Math.floor(pokemon.set.evs['hp'] / 4) + 100
|
||||
) * pokemon.level / 100 + 10);
|
||||
const newMaxHP = pokemon.baseMaxhp;
|
||||
pokemon.hp = newMaxHP - (pokemon.maxhp - pokemon.hp);
|
||||
pokemon.maxhp = newMaxHP;
|
||||
this.add('-heal', pokemon, pokemon.getHealth, '[silent]');
|
||||
}
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
|
||||
|
|
@ -5061,9 +5053,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
|
||||
const target = this.sample(possibleTargets);
|
||||
const ability = target.getAbility();
|
||||
if (pokemon.setAbility(ability)) {
|
||||
this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
|
||||
}
|
||||
pokemon.setAbility(ability, target);
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
|
||||
name: "Trace",
|
||||
|
|
@ -5274,20 +5264,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
wanderingspirit: {
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (source.getAbility().flags['failskillswap'] || target.volatiles['dynamax']) return;
|
||||
|
||||
if (this.checkMoveMakesContact(move, source, target)) {
|
||||
const targetCanBeSet = this.runEvent('SetAbility', target, source, this.effect, source.ability);
|
||||
if (!targetCanBeSet) return targetCanBeSet;
|
||||
const sourceAbility = source.setAbility('wanderingspirit', target);
|
||||
if (!sourceAbility) return;
|
||||
if (target.isAlly(source)) {
|
||||
this.add('-activate', target, 'Skill Swap', '', '', `[of] ${source}`);
|
||||
} else {
|
||||
this.add('-activate', target, 'ability: Wandering Spirit', this.dex.abilities.get(sourceAbility).name, 'Wandering Spirit', `[of] ${source}`);
|
||||
}
|
||||
target.setAbility(sourceAbility);
|
||||
}
|
||||
if (this.checkMoveMakesContact(move, source, target)) this.skillSwap(source, target);
|
||||
},
|
||||
flags: {},
|
||||
name: "Wandering Spirit",
|
||||
|
|
@ -5447,7 +5424,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
target.addVolatile('charge');
|
||||
}
|
||||
},
|
||||
onAllySideConditionStart(target, source, sideCondition) {
|
||||
onSideConditionStart(side, source, sideCondition) {
|
||||
const pokemon = this.effectState.target;
|
||||
if (sideCondition.id === 'tailwind') {
|
||||
pokemon.addVolatile('charge');
|
||||
|
|
@ -5472,7 +5449,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
return null;
|
||||
}
|
||||
},
|
||||
onAllySideConditionStart(target, source, sideCondition) {
|
||||
onSideConditionStart(side, source, sideCondition) {
|
||||
const pokemon = this.effectState.target;
|
||||
if (sideCondition.id === 'tailwind') {
|
||||
this.boost({ atk: 1 }, pokemon, pokemon);
|
||||
|
|
@ -5486,10 +5463,10 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
wonderguard: {
|
||||
onTryHit(target, source, move) {
|
||||
if (target === source || move.category === 'Status' || move.type === '???' || move.id === 'struggle') return;
|
||||
if (target === source || move.category === 'Status' || move.id === 'struggle') return;
|
||||
if (move.id === 'skydrop' && !source.volatiles['skydrop']) return;
|
||||
this.debug('Wonder Guard immunity: ' + move.id);
|
||||
if (target.runEffectiveness(move) <= 0) {
|
||||
if (target.runEffectiveness(move) <= 0 || !target.runImmunity(move)) {
|
||||
if (move.smartTarget) {
|
||||
move.smartTarget = false;
|
||||
} else {
|
||||
|
|
@ -5561,14 +5538,14 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
if (pokemon.baseSpecies.baseSpecies !== 'Palafin') return;
|
||||
if (pokemon.species.forme !== 'Hero') {
|
||||
pokemon.formeChange('Palafin-Hero', this.effect, true);
|
||||
pokemon.regressionForme = false;
|
||||
pokemon.heroMessageDisplayed = false;
|
||||
}
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.baseSpecies.baseSpecies !== 'Palafin') return;
|
||||
if (!this.effectState.heroMessageDisplayed && pokemon.species.forme === 'Hero') {
|
||||
if (!pokemon.heroMessageDisplayed && pokemon.species.forme === 'Hero') {
|
||||
this.add('-activate', pokemon, 'ability: Zero to Hero');
|
||||
this.effectState.heroMessageDisplayed = true;
|
||||
pokemon.heroMessageDisplayed = true;
|
||||
}
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
|
||||
|
|
@ -5594,7 +5571,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
flags: { breakable: 1 },
|
||||
name: "Mountaineer",
|
||||
rating: 3,
|
||||
num: -2,
|
||||
num: -1,
|
||||
},
|
||||
rebound: {
|
||||
isNonstandard: "CAP",
|
||||
|
|
@ -5602,32 +5579,32 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
onTryHit(target, source, move) {
|
||||
if (this.effectState.target.activeTurns) return;
|
||||
|
||||
if (target === source || move.hasBounced || !move.flags['reflectable']) {
|
||||
if (target === source || move.hasBounced || !move.flags['reflectable'] || target.isSemiInvulnerable()) {
|
||||
return;
|
||||
}
|
||||
const newMove = this.dex.getActiveMove(move.id);
|
||||
newMove.hasBounced = true;
|
||||
newMove.pranksterBoosted = false;
|
||||
this.actions.useMove(newMove, target, { target: source });
|
||||
return null;
|
||||
},
|
||||
onAllyTryHitSide(target, source, move) {
|
||||
if (this.effectState.target.activeTurns) return;
|
||||
|
||||
if (target.isAlly(source) || move.hasBounced || !move.flags['reflectable']) {
|
||||
if (target.isAlly(source) || move.hasBounced || !move.flags['reflectable'] || target.isSemiInvulnerable()) {
|
||||
return;
|
||||
}
|
||||
const newMove = this.dex.getActiveMove(move.id);
|
||||
newMove.hasBounced = true;
|
||||
newMove.pranksterBoosted = false;
|
||||
this.actions.useMove(newMove, this.effectState.target, { target: source });
|
||||
move.hasBounced = true; // only bounce once in free-for-all battles
|
||||
return null;
|
||||
},
|
||||
condition: {
|
||||
duration: 1,
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Rebound",
|
||||
rating: 3,
|
||||
num: -3,
|
||||
num: -2,
|
||||
},
|
||||
persistent: {
|
||||
isNonstandard: "CAP",
|
||||
|
|
@ -5635,6 +5612,6 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
flags: {},
|
||||
name: "Persistent",
|
||||
rating: 3,
|
||||
num: -4,
|
||||
num: -3,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
1786
data/aliases.ts
1786
data/aliases.ts
File diff suppressed because it is too large
Load Diff
|
|
@ -1,78 +0,0 @@
|
|||
// Data for computer-generated teams
|
||||
|
||||
export const MOVE_PAIRINGS: { [moveID: IDEntry]: IDEntry } = {
|
||||
rest: 'sleeptalk',
|
||||
sleeptalk: 'rest',
|
||||
};
|
||||
|
||||
// Bonuses to move ratings by ability
|
||||
export const ABILITY_MOVE_BONUSES: { [abilityID: IDEntry]: { [moveID: IDEntry]: number } } = {
|
||||
contrary: { terablast: 2 },
|
||||
drought: { sunnyday: 0.2, solarbeam: 2 },
|
||||
drizzle: { raindance: 0.2, solarbeam: 0.2, hurricane: 2 },
|
||||
};
|
||||
// Bonuses to move ratings by move type
|
||||
export const ABILITY_MOVE_TYPE_BONUSES: { [abilityID: IDEntry]: { [typeName: string]: number } } = {
|
||||
darkaura: { Dark: 1.33 },
|
||||
dragonsmaw: { Dragon: 1.5 },
|
||||
fairyaura: { Fairy: 1.33 },
|
||||
steelworker: { Steel: 1.5 },
|
||||
steelyspirit: { Steel: 1.5 },
|
||||
transistor: { Electric: 1.3 },
|
||||
|
||||
// -ate moves
|
||||
pixilate: { Normal: 1.5 * 1.2 },
|
||||
refrigerate: { Normal: 1.5 * 1.2 },
|
||||
aerilate: { Normal: 1.5 * 1.2 },
|
||||
normalize: { Normal: 1.2 },
|
||||
|
||||
// weather
|
||||
drizzle: { Water: 1.4, Fire: 0.6 },
|
||||
drought: { Fire: 1.4, Water: 0.6 },
|
||||
};
|
||||
// For moves whose quality isn't obvious from data
|
||||
// USE SPARINGLY!
|
||||
export const HARDCODED_MOVE_WEIGHTS: { [moveID: IDEntry]: number } = {
|
||||
// Fails unless user is asleep
|
||||
snore: 0,
|
||||
// Hard to use
|
||||
lastresort: 0.1, dreameater: 0.1,
|
||||
// Useless without Berry + sucks even then
|
||||
belch: 0.2,
|
||||
|
||||
// Power increases in conditions out of our control that may occur
|
||||
avalanche: 1.2,
|
||||
ficklebeam: 1.3,
|
||||
hex: 1.2,
|
||||
stompingtantrum: 1.2,
|
||||
temperflare: 1.2,
|
||||
|
||||
// Attacks that set hazards on hit
|
||||
// We REALLY like hazards
|
||||
stoneaxe: 16,
|
||||
ceaselessedge: 16,
|
||||
|
||||
// screens
|
||||
lightscreen: 3, reflect: 3, auroraveil: 3, // TODO: make sure AVeil always gets Snow?
|
||||
tailwind: 2,
|
||||
|
||||
// mess with the opponent
|
||||
taunt: 2, disable: 2, encore: 3,
|
||||
|
||||
// healing moves
|
||||
// TODO: should healing moves be more common on bulkier pokemon?
|
||||
// 25%
|
||||
junglehealing: 3, lifedew: 3,
|
||||
// 50%
|
||||
milkdrink: 5, moonlight: 5, morningsun: 5, recover: 5, roost: 5,
|
||||
shoreup: 5, slackoff: 5, softboiled: 5, synthesis: 5,
|
||||
// delayed/consequence
|
||||
rest: 3, // has sleeptalk potential
|
||||
wish: 2,
|
||||
|
||||
// requires terrain
|
||||
steelroller: 0.1,
|
||||
};
|
||||
|
||||
export const WEIGHT_BASED_MOVES = ['heatcrash', 'heavyslam', 'lowkick', 'grassknot'];
|
||||
export const TARGET_HP_BASED_MOVES = ['crushgrip', 'hardpress'];
|
||||
1098
data/cg-teams.ts
1098
data/cg-teams.ts
File diff suppressed because it is too large
Load Diff
|
|
@ -91,12 +91,11 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
}
|
||||
if (target.species.name === 'Shaymin-Sky' && target.baseSpecies.baseSpecies === 'Shaymin') {
|
||||
target.formeChange('Shaymin', this.effect, true);
|
||||
target.regressionForme = false;
|
||||
}
|
||||
},
|
||||
onBeforeMovePriority: 10,
|
||||
onBeforeMove(pokemon, target, move) {
|
||||
if (move.flags['defrost']) return;
|
||||
if (move.flags['defrost'] && !(move.id === 'burnup' && !pokemon.hasType('Fire'))) return;
|
||||
if (this.randomChance(1, 5)) {
|
||||
pokemon.cureStatus();
|
||||
return;
|
||||
|
|
@ -116,7 +115,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
}
|
||||
},
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (move.type === 'Fire' && move.category !== 'Status') {
|
||||
if (move.type === 'Fire' && move.category !== 'Status' && move.id !== 'polarflare') {
|
||||
target.cureStatus();
|
||||
}
|
||||
},
|
||||
|
|
@ -271,6 +270,11 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
this.effectState.duration = 2;
|
||||
}
|
||||
},
|
||||
onAfterMove(pokemon) {
|
||||
if (this.effectState.duration === 1) {
|
||||
pokemon.removeVolatile('lockedmove');
|
||||
}
|
||||
},
|
||||
onEnd(target) {
|
||||
if (this.effectState.trueDuration > 1) return;
|
||||
target.addVolatile('confusion');
|
||||
|
|
@ -875,6 +879,65 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
|
|||
return [type];
|
||||
},
|
||||
},
|
||||
zacian: {
|
||||
name: 'Zacian',
|
||||
onBattleStart(pokemon) {
|
||||
if (pokemon.item !== 'rustedsword') return;
|
||||
const rawSpecies = this.dex.species.get('Zacian-Crowned');
|
||||
const species = pokemon.setSpecies(rawSpecies);
|
||||
if (!species) return;
|
||||
pokemon.baseSpecies = rawSpecies;
|
||||
pokemon.details = pokemon.getUpdatedDetails();
|
||||
pokemon.setAbility(species.abilities['0'], null, null, true);
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
|
||||
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
|
||||
if (ironHeadIndex >= 0) {
|
||||
const move = this.dex.moves.get('behemothblade');
|
||||
pokemon.baseMoveSlots[ironHeadIndex] = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
disabledSource: '',
|
||||
used: false,
|
||||
};
|
||||
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
|
||||
}
|
||||
},
|
||||
},
|
||||
zamazenta: {
|
||||
name: 'Zamazenta',
|
||||
onBattleStart(pokemon) {
|
||||
if (pokemon.item !== 'rustedshield') return;
|
||||
const rawSpecies = this.dex.species.get('Zamazenta-Crowned');
|
||||
const species = pokemon.setSpecies(rawSpecies);
|
||||
if (!species) return;
|
||||
pokemon.baseSpecies = rawSpecies;
|
||||
pokemon.details = pokemon.getUpdatedDetails();
|
||||
pokemon.setAbility(species.abilities['0'], null, null, true);
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
|
||||
const ironHeadIndex = pokemon.baseMoves.indexOf('ironhead');
|
||||
if (ironHeadIndex >= 0) {
|
||||
const move = this.dex.moves.get('behemothbash');
|
||||
pokemon.baseMoveSlots[ironHeadIndex] = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
disabledSource: '',
|
||||
used: false,
|
||||
};
|
||||
pokemon.moveSlots = pokemon.baseMoveSlots.slice();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
rolloutstorage: {
|
||||
name: 'rolloutstorage',
|
||||
duration: 2,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
1269
data/items.ts
1269
data/items.ts
File diff suppressed because it is too large
Load Diff
1040
data/learnsets.ts
1040
data/learnsets.ts
File diff suppressed because it is too large
Load Diff
206
data/mods/biomechmons/abilities.ts
Normal file
206
data/mods/biomechmons/abilities.ts
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
|
||||
magician: {
|
||||
inherit: true,
|
||||
onAfterMoveSecondarySelf(source, target, move) {
|
||||
if (!move || source.switchFlag === true || !move.hitTargets || source.item || source.volatiles['gem'] ||
|
||||
move.id === 'fling' || move.category === 'Status') return;
|
||||
const hitTargets = move.hitTargets;
|
||||
this.speedSort(hitTargets);
|
||||
for (const pokemon of hitTargets) {
|
||||
if (pokemon !== source) {
|
||||
const yourItem = pokemon.takeItem(source);
|
||||
if (!yourItem) continue;
|
||||
if (!source.setItem(yourItem)) {
|
||||
if (!this.dex.items.get(yourItem.id).exists) {
|
||||
pokemon.setItem(yourItem.id);
|
||||
continue;
|
||||
}
|
||||
pokemon.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
|
||||
continue;
|
||||
}
|
||||
this.add('-item', source, yourItem, '[from] ability: Magician', `[of] ${pokemon}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
neutralizinggas: {
|
||||
inherit: true,
|
||||
onSwitchIn(pokemon) {
|
||||
this.add('-ability', pokemon, 'Neutralizing Gas');
|
||||
pokemon.abilityState.ending = false;
|
||||
const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
|
||||
for (const target of this.getAllActive()) {
|
||||
if (target.hasItem('Ability Shield')) {
|
||||
this.add('-block', target, 'item: Ability Shield');
|
||||
continue;
|
||||
}
|
||||
// Can't suppress a Tatsugiri inside of Dondozo already
|
||||
if (target.volatiles['commanding']) {
|
||||
continue;
|
||||
}
|
||||
if (target.illusion) {
|
||||
this.singleEvent('End', this.dex.abilities.get('Illusion'), target.abilityState, target, pokemon, 'neutralizinggas');
|
||||
}
|
||||
if (target.volatiles['slowstart']) {
|
||||
delete target.volatiles['slowstart'];
|
||||
this.add('-end', target, 'Slow Start', '[silent]');
|
||||
}
|
||||
if (strongWeathers.includes(target.getAbility().id)) {
|
||||
this.singleEvent('End', this.dex.abilities.get(target.getAbility().id), target.abilityState, target, pokemon, 'neutralizinggas');
|
||||
}
|
||||
if (!this.dex.abilities.get(target.ability).exists) {
|
||||
const isItem = (target.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
if (isItem >= 0) {
|
||||
target.removeVolatile('item:' + this.toID(target.m.scrambled.items[isItem].thing));
|
||||
} else if ((target.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
|
||||
const isMove = (target.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
const indexOfMove = target.moveSlots.findIndex(m => this.toID(target.m.scrambled.moves[isMove].thing) === m.id);
|
||||
if (indexOfMove >= 0) target.moveSlots.splice(indexOfMove, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onEnd(source) {
|
||||
if (source.transformed) return;
|
||||
for (const pokemon of this.getAllActive()) {
|
||||
if (pokemon !== source && pokemon.hasAbility('Neutralizing Gas')) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.add('-end', source, 'ability: Neutralizing Gas');
|
||||
|
||||
// FIXME this happens before the pokemon switches out, should be the opposite order.
|
||||
// Not an easy fix since we cant use a supported event. Would need some kind of special event that
|
||||
// gathers events to run after the switch and then runs them when the ability is no longer accessible.
|
||||
// (If you're tackling this, do note extreme weathers have the same issue)
|
||||
|
||||
// Mark this pokemon's ability as ending so Pokemon#ignoringAbility skips it
|
||||
if (source.abilityState.ending) return;
|
||||
source.abilityState.ending = true;
|
||||
const sortedActive = this.getAllActive();
|
||||
this.speedSort(sortedActive);
|
||||
for (const pokemon of sortedActive) {
|
||||
if (pokemon !== source) {
|
||||
if (pokemon.getAbility().flags['cantsuppress']) continue; // does not interact with e.g Ice Face, Zen Mode
|
||||
if (pokemon.hasItem('abilityshield')) continue; // don't restart abilities that weren't suppressed
|
||||
|
||||
// Will be suppressed by Pokemon#ignoringAbility if needed
|
||||
this.singleEvent('Start', pokemon.getAbility(), pokemon.abilityState, pokemon);
|
||||
if (pokemon.ability === "gluttony") {
|
||||
pokemon.abilityState.gluttony = false;
|
||||
}
|
||||
}
|
||||
if (!this.dex.abilities.get(pokemon.ability).exists) {
|
||||
const isItem = (pokemon.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
if (isItem >= 0) {
|
||||
pokemon.addVolatile('item:' + this.toID(pokemon.m.scrambled.items[isItem].thing));
|
||||
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
|
||||
const findMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
const findSlot = pokemon.baseMoveSlots.find(e => e.id === this.toID(pokemon.m.scrambled.moves[findMove].thing));
|
||||
pokemon.moveSlots.push(this.dex.deepClone(findSlot));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
pickpocket: {
|
||||
inherit: true,
|
||||
onAfterMoveSecondary(target, source, move) {
|
||||
if (source && source !== target && move?.flags['contact']) {
|
||||
if (target.item || target.switchFlag || target.forceSwitchFlag || source.switchFlag === true) {
|
||||
return;
|
||||
}
|
||||
const yourItem = source.takeItem(target);
|
||||
if (!yourItem) {
|
||||
return;
|
||||
}
|
||||
if (!target.setItem(yourItem)) {
|
||||
if (!this.dex.items.get(yourItem.id).exists) {
|
||||
target.setItem(yourItem.id);
|
||||
return;
|
||||
}
|
||||
source.item = yourItem.id;
|
||||
return;
|
||||
}
|
||||
this.add('-enditem', source, yourItem, '[silent]', '[from] ability: Pickpocket', `[of] ${source}`);
|
||||
this.add('-item', target, yourItem, '[from] ability: Pickpocket', `[of] ${source}`);
|
||||
}
|
||||
},
|
||||
},
|
||||
trace: {
|
||||
inherit: true,
|
||||
onStart(pokemon) {
|
||||
this.effectState.seek = true;
|
||||
// n.b. only affects Hackmons
|
||||
// interaction with No Ability is complicated: https://www.smogon.com/forums/threads/pokemon-sun-moon-battle-mechanics-research.3586701/page-76#post-7790209
|
||||
if (pokemon.adjacentFoes().some(foeActive => foeActive.ability === 'noability')) {
|
||||
this.effectState.seek = false;
|
||||
}
|
||||
// interaction with Ability Shield is similar to No Ability
|
||||
if (pokemon.hasItem('Ability Shield') && this.toID(pokemon.ability) === 'trace') {
|
||||
this.add('-block', pokemon, 'item: Ability Shield');
|
||||
this.effectState.seek = false;
|
||||
}
|
||||
if (this.effectState.seek) {
|
||||
this.singleEvent('Update', this.effect, this.effectState, pokemon);
|
||||
}
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
if (!this.effectState.seek) return;
|
||||
|
||||
const possibleTargets = pokemon.adjacentFoes().filter(
|
||||
target => !target.getAbility().flags['notrace'] && target.ability !== 'noability'
|
||||
);
|
||||
if (!possibleTargets.length) return;
|
||||
|
||||
const target = this.sample(possibleTargets);
|
||||
const ability = target.getAbility();
|
||||
if (this.toID(pokemon.item) === 'trace') {
|
||||
this.add('-ability', pokemon, ability.name, 'Trace');
|
||||
pokemon.setItem(ability.name);
|
||||
return;
|
||||
} else if (pokemon.volatiles['ability:trace']?.inSlot === 'Move') {
|
||||
if (this.dex.abilities.get(ability.name).exists) {
|
||||
pokemon.removeVolatile('ability:trace');
|
||||
pokemon.m.scrambled.abilities.splice(
|
||||
(pokemon.m.scrambled.abilities as { thing: string, inSlot: string }[]).findIndex(e =>
|
||||
this.toID(e.thing) === 'trace' && e.inSlot === 'Move'), 1);
|
||||
this.add('-ability', pokemon, ability.name, 'Trace');
|
||||
pokemon.addVolatile(`ability:${ability.id}`);
|
||||
pokemon.m.scrambled.abilities.push({ thing: ability.name, inSlot: 'Move' });
|
||||
} else if (this.dex.items.get(ability.name).exists) {
|
||||
pokemon.removeVolatile('ability:trace');
|
||||
pokemon.m.scrambled.abilities.splice(
|
||||
(pokemon.m.scrambled.abilities as { thing: string, inSlot: string }[]).findIndex(e =>
|
||||
this.toID(e.thing) === 'trace' && e.inSlot === 'Move'), 1);
|
||||
this.add('-ability', pokemon, ability.name, 'Trace');
|
||||
pokemon.addVolatile(`item:${ability.id}`);
|
||||
pokemon.m.scrambled.items.push({ thing: this.dex.items.get(ability.name).name, inSlot: 'Move' });
|
||||
} else {
|
||||
const move = this.dex.moves.get(ability.name);
|
||||
if (move.exists) {
|
||||
pokemon.removeVolatile('ability:trace');
|
||||
pokemon.m.scrambled.abilities.splice(
|
||||
(pokemon.m.scrambled.abilities as { thing: string, inSlot: string }[]).findIndex(e =>
|
||||
this.toID(e.thing) === 'trace' && e.inSlot === 'Move'), 1);
|
||||
this.add('-ability', pokemon, move.name, 'Trace');
|
||||
const newMove = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
pokemon.baseMoveSlots.push(newMove);
|
||||
pokemon.moveSlots.push(newMove);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
pokemon.setAbility(ability, target);
|
||||
},
|
||||
},
|
||||
};
|
||||
44
data/mods/biomechmons/conditions.ts
Normal file
44
data/mods/biomechmons/conditions.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDataTable = {
|
||||
choicelock: {
|
||||
inherit: true,
|
||||
onBeforeMove(pokemon, target, move) {
|
||||
const choiceItem = pokemon.getItem().isChoice ||
|
||||
Object.keys(pokemon.volatiles).some(v => (
|
||||
v.startsWith('item:') && this.dex.items.get(v.split(':')[1]).isChoice
|
||||
));
|
||||
if (!choiceItem) {
|
||||
pokemon.removeVolatile('choicelock');
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!pokemon.ignoringItem() && !pokemon.volatiles['dynamax'] &&
|
||||
move.id !== this.effectState.move && move.id !== 'struggle'
|
||||
) {
|
||||
// Fails unless the Choice item is being ignored, and no PP is lost
|
||||
this.addMove('move', pokemon, move.name);
|
||||
this.attrLastMove('[still]');
|
||||
this.debug("Disabled by Choice item lock");
|
||||
this.add('-fail', pokemon);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
const choiceItem = pokemon.getItem().isChoice ||
|
||||
Object.keys(pokemon.volatiles).some(v => (
|
||||
v.startsWith('item:') && this.dex.items.get(v.split(':')[1]).isChoice
|
||||
));
|
||||
if (!choiceItem || !pokemon.hasMove(this.effectState.move)) {
|
||||
pokemon.removeVolatile('choicelock');
|
||||
return;
|
||||
}
|
||||
if (pokemon.ignoringItem() || pokemon.volatiles['dynamax']) {
|
||||
return;
|
||||
}
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id !== this.effectState.move) {
|
||||
pokemon.disableMove(moveSlot.id, false, this.effectState.sourceEffect);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
41
data/mods/biomechmons/items.ts
Normal file
41
data/mods/biomechmons/items.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
||||
airballoon: {
|
||||
inherit: true,
|
||||
// airborneness implemented in sim/pokemon.js:Pokemon#isGrounded
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
this.add('-enditem', target, 'Air Balloon');
|
||||
if (target.item === 'airballoon') {
|
||||
target.item = '';
|
||||
this.clearEffectState(target.itemState);
|
||||
} else {
|
||||
const isBMM = target.volatiles['item:airballoon']?.inSlot;
|
||||
if (isBMM) {
|
||||
target.removeVolatile('item:airballoon');
|
||||
target.m.scrambled.items.splice((target.m.scrambled.items as { thing: string, inSlot: string }[]).findIndex(e =>
|
||||
this.toID(e.thing) === 'airballoon' && e.inSlot === isBMM), 1);
|
||||
if (isBMM === 'Ability') target.setAbility('No Ability');
|
||||
}
|
||||
}
|
||||
this.runEvent('AfterUseItem', target, null, null, this.dex.items.get('airballoon'));
|
||||
},
|
||||
onAfterSubDamage(damage, target, source, effect) {
|
||||
this.debug('effect: ' + effect.id);
|
||||
if (effect.effectType === 'Move') {
|
||||
this.add('-enditem', target, 'Air Balloon');
|
||||
if (target.item === 'airballoon') {
|
||||
target.item = '';
|
||||
this.clearEffectState(target.itemState);
|
||||
} else {
|
||||
const isBMM = target.volatiles['item:airballoon']?.inSlot;
|
||||
if (isBMM) {
|
||||
target.removeVolatile('item:airballoon');
|
||||
target.m.scrambled.items.splice((target.m.scrambled.items as { thing: string, inSlot: string }[]).findIndex(e =>
|
||||
this.toID(e.thing) === 'airballoon' && e.inSlot === isBMM), 1);
|
||||
if (isBMM === 'Ability') target.setAbility('No Ability');
|
||||
}
|
||||
}
|
||||
this.runEvent('AfterUseItem', target, null, null, this.dex.items.get('airballoon'));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
419
data/mods/biomechmons/moves.ts
Normal file
419
data/mods/biomechmons/moves.ts
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||
// Remember, everything deals with SLOTS not with properties as they are!
|
||||
covet: {
|
||||
inherit: true,
|
||||
onAfterHit(target, source, move) {
|
||||
if (source.item || source.volatiles['gem']) {
|
||||
return;
|
||||
}
|
||||
const yourItem = target.takeItem(source);
|
||||
if (!yourItem) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!this.singleEvent('TakeItem', yourItem, target.itemState, source, target, move, yourItem) ||
|
||||
!source.setItem(yourItem)
|
||||
) {
|
||||
if (!this.dex.items.get(yourItem.id).exists) {
|
||||
target.setItem(yourItem.id);
|
||||
return;
|
||||
}
|
||||
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
|
||||
return;
|
||||
}
|
||||
this.add('-item', source, yourItem, '[from] move: Covet', `[of] ${target}`);
|
||||
},
|
||||
},
|
||||
embargo: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
onStart(pokemon) {
|
||||
this.add('-start', pokemon, 'Embargo');
|
||||
this.singleEvent('End', pokemon.getItem(), pokemon.itemState, pokemon);
|
||||
if (!this.dex.items.get(pokemon.item).exists) {
|
||||
const isAbil = (pokemon.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
if (isAbil >= 0) {
|
||||
pokemon.removeVolatile('ability:' + this.toID(pokemon.m.scrambled.abilities[isAbil].thing));
|
||||
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
|
||||
const isMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
const slotNo = pokemon.moveSlots.findIndex(m => this.toID(pokemon.m.scrambled.moves[isMove].thing) === m.id);
|
||||
if (slotNo >= 0) pokemon.moveSlots.splice(slotNo, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
|
||||
onResidualOrder: 21,
|
||||
onEnd(pokemon) {
|
||||
this.add('-end', pokemon, 'Embargo');
|
||||
if (!this.dex.items.get(pokemon.item).exists) {
|
||||
const isAbil = (pokemon.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
if (isAbil >= 0) {
|
||||
pokemon.addVolatile('ability:' + this.toID(pokemon.m.scrambled.abilities[isAbil].thing));
|
||||
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
|
||||
const findMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
const findSlot = pokemon.baseMoveSlots.find(e => e.id === this.toID(pokemon.m.scrambled.moves[findMove].thing));
|
||||
pokemon.moveSlots.push(this.dex.deepClone(findSlot));
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
magicroom: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
durationCallback(source, effect) {
|
||||
if (source?.hasAbility('persistent')) {
|
||||
this.add('-activate', source, 'ability: Persistent', '[move] Magic Room');
|
||||
return 7;
|
||||
}
|
||||
return 5;
|
||||
},
|
||||
onFieldStart(target, source) {
|
||||
if (source?.hasAbility('persistent')) {
|
||||
this.add('-fieldstart', 'move: Magic Room', `[of] ${source}`, '[persistent]');
|
||||
} else {
|
||||
this.add('-fieldstart', 'move: Magic Room', `[of] ${source}`);
|
||||
}
|
||||
for (const mon of this.getAllActive()) {
|
||||
this.singleEvent('End', mon.getItem(), mon.itemState, mon);
|
||||
if (!this.dex.items.get(mon.item).exists) {
|
||||
const isAbil = (mon.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
if (isAbil >= 0) {
|
||||
mon.removeVolatile('ability:' + this.toID(mon.m.scrambled.abilities[isAbil].thing));
|
||||
} else if ((mon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
|
||||
const isMove = (mon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
const slotNo = mon.moveSlots.findIndex(m => this.toID(mon.m.scrambled.moves[isMove].thing) === m.id);
|
||||
if (slotNo >= 0) mon.moveSlots.splice(slotNo, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onFieldRestart(target, source) {
|
||||
this.field.removePseudoWeather('magicroom');
|
||||
},
|
||||
// Item suppression implemented in Pokemon.ignoringItem() within sim/pokemon.js
|
||||
onFieldResidualOrder: 27,
|
||||
onFieldResidualSubOrder: 6,
|
||||
onFieldEnd() {
|
||||
this.add('-fieldend', 'move: Magic Room', '[of] ' + this.effectState.source);
|
||||
for (const pokemon of this.getAllActive()) {
|
||||
if (!this.dex.items.get(pokemon.item).exists) {
|
||||
const isAbil = (pokemon.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
if (isAbil >= 0) {
|
||||
pokemon.addVolatile('ability:' + this.toID(pokemon.m.scrambled.abilities[isAbil].thing));
|
||||
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
|
||||
const findMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
const findSlot = pokemon.baseMoveSlots.find(e => e.id === this.toID(pokemon.m.scrambled.moves[findMove].thing));
|
||||
pokemon.moveSlots.push(this.dex.deepClone(findSlot));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
gastroacid: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// Ability suppression implemented in Pokemon.ignoringAbility() within sim/pokemon.js
|
||||
onStart(pokemon) {
|
||||
this.add('-endability', pokemon);
|
||||
this.singleEvent('End', pokemon.getAbility(), pokemon.abilityState, pokemon, pokemon, 'gastroacid');
|
||||
if (!this.dex.abilities.get(pokemon.ability).exists) {
|
||||
const isItem = (pokemon.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
if (isItem >= 0) {
|
||||
pokemon.removeVolatile('item:' + this.toID(pokemon.m.scrambled.items[isItem].thing));
|
||||
} else if ((pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
|
||||
const isMove = (pokemon.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
const slotNo = pokemon.moveSlots.findIndex(m => this.toID(pokemon.m.scrambled.moves[isMove].thing) === m.id);
|
||||
if (slotNo >= 0) pokemon.moveSlots.splice(slotNo, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
trick: {
|
||||
inherit: true,
|
||||
onHit(target, source, move) {
|
||||
const yourItem = target.takeItem(source);
|
||||
const myItem = source.takeItem();
|
||||
if (target.item || source.item || (!yourItem && !myItem)) {
|
||||
if (yourItem) {
|
||||
if (!this.dex.items.get(yourItem.id).exists) {
|
||||
target.setItem(yourItem.id);
|
||||
} else {
|
||||
target.item = yourItem.id;
|
||||
}
|
||||
}
|
||||
if (myItem) {
|
||||
if (!this.dex.items.get(myItem.id).exists) {
|
||||
source.setItem(myItem.id);
|
||||
} else {
|
||||
source.item = myItem.id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
(myItem && !this.singleEvent('TakeItem', myItem, source.itemState, target, source, move, myItem)) ||
|
||||
(yourItem && !this.singleEvent('TakeItem', yourItem, target.itemState, source, target, move, yourItem))
|
||||
) {
|
||||
if (yourItem) {
|
||||
if (!this.dex.items.get(yourItem.id).exists) {
|
||||
target.setItem(yourItem.id);
|
||||
} else {
|
||||
target.item = yourItem.id;
|
||||
}
|
||||
}
|
||||
if (myItem) {
|
||||
if (!this.dex.items.get(myItem.id).exists) {
|
||||
source.setItem(myItem.id);
|
||||
} else {
|
||||
source.item = myItem.id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
this.add('-activate', source, 'move: Trick', `[of] ${target}`);
|
||||
if (myItem) {
|
||||
target.setItem(myItem);
|
||||
this.add('-item', target, myItem, '[from] move: Trick');
|
||||
} else {
|
||||
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Trick');
|
||||
}
|
||||
if (yourItem) {
|
||||
source.setItem(yourItem);
|
||||
this.add('-item', source, yourItem, '[from] move: Trick');
|
||||
} else {
|
||||
this.add('-enditem', source, myItem, '[silent]', '[from] move: Trick');
|
||||
}
|
||||
},
|
||||
},
|
||||
sketch: {
|
||||
inherit: true,
|
||||
onHit(target, source) {
|
||||
const move = target.lastMove;
|
||||
if (source.transformed || !move || source.moves.includes(move.id)) return false;
|
||||
if (move.flags['nosketch'] || move.isZ || move.isMax) return false;
|
||||
const sketchIndex = source.moves.indexOf('sketch');
|
||||
if (sketchIndex < 0) return false;
|
||||
if (this.toID(source.item) === 'sketch') {
|
||||
source.setItem(move.name);
|
||||
this.add('-activate', source, 'move: Sketch', move.name);
|
||||
return;
|
||||
} else if (this.toID(source.ability) === 'sketch') {
|
||||
source.setAbility(move.name);
|
||||
this.add('-activate', source, 'move: Sketch', move.name);
|
||||
return;
|
||||
}
|
||||
const sketchedMove = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.pp,
|
||||
maxpp: move.pp,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
source.moveSlots[sketchIndex] = sketchedMove;
|
||||
source.baseMoveSlots[sketchIndex] = sketchedMove;
|
||||
this.add('-activate', source, 'move: Sketch', move.name);
|
||||
},
|
||||
},
|
||||
skillswap: {
|
||||
inherit: true,
|
||||
onTryHit(target, source) {
|
||||
const targetAbility = target.getAbility();
|
||||
const sourceAbility = source.getAbility();
|
||||
if (sourceAbility.flags['failskillswap'] || targetAbility.flags['failskillswap'] || target.volatiles['dynamax']) {
|
||||
return false;
|
||||
}
|
||||
let sourceCanBeSet = this.runEvent('SetAbility', source, source, this.effect, targetAbility);
|
||||
if (!this.dex.abilities.get(sourceAbility).exists && this.dex.items.get(sourceAbility.id).exists) {
|
||||
sourceCanBeSet = this.runEvent('TakeItem', source, source, this.effect, this.dex.items.get(sourceAbility.id));
|
||||
}
|
||||
|
||||
if (!sourceCanBeSet) return sourceCanBeSet;
|
||||
let targetCanBeSet = this.runEvent('SetAbility', target, source, this.effect, sourceAbility);
|
||||
if (!this.dex.abilities.get(targetAbility).exists && this.dex.items.get(targetAbility.id).exists) {
|
||||
targetCanBeSet = this.runEvent('TakeItem', target, source, this.effect, this.dex.items.get(targetAbility.id));
|
||||
}
|
||||
if (!targetCanBeSet) return targetCanBeSet;
|
||||
},
|
||||
onHit(target, source, move) {
|
||||
const targetAbility = target.getAbility();
|
||||
const sourceAbility = source.getAbility();
|
||||
const sourceIsBMM = !this.dex.abilities.get(sourceAbility).exists;
|
||||
const targetIsBMM = !this.dex.abilities.get(targetAbility).exists;
|
||||
if (target.isAlly(source)) {
|
||||
this.add('-activate', source, 'move: Skill Swap', '', '', `[of] ${target}`);
|
||||
} else {
|
||||
this.add('-activate', source, 'move: Skill Swap', targetAbility, sourceAbility, `[of] ${target}`);
|
||||
}
|
||||
this.singleEvent('End', sourceAbility, source.abilityState, source);
|
||||
if (sourceIsBMM) {
|
||||
const isItem = (source.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
if (isItem >= 0) {
|
||||
source.removeVolatile('item:' + this.toID(source.m.scrambled.items[isItem].thing));
|
||||
source.m.scrambled.items.splice(isItem, 1);
|
||||
} else if ((source.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
|
||||
const isMove = (source.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
source.baseMoveSlots.splice(
|
||||
source.baseMoveSlots.findIndex(m => this.toID(source.m.scrambled.moves[isMove].thing) === m.id), 1);
|
||||
source.moveSlots.splice(source.moveSlots.findIndex(m => this.toID(source.m.scrambled.moves[isMove].thing) === m.id), 1);
|
||||
source.m.scrambled.moves.splice(isMove, 1);
|
||||
}
|
||||
}
|
||||
this.singleEvent('End', targetAbility, target.abilityState, target);
|
||||
if (targetIsBMM) {
|
||||
const isItem = (target.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
if (isItem >= 0) {
|
||||
target.removeVolatile('item:' + this.toID(target.m.scrambled.items[isItem].thing));
|
||||
target.m.scrambled.items.splice(isItem, 1);
|
||||
} else if ((target.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
|
||||
const isMove = (target.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
target.baseMoveSlots.splice(
|
||||
target.baseMoveSlots.findIndex(m => this.toID(target.m.scrambled.moves[isMove].thing) === m.id), 1);
|
||||
target.moveSlots.splice(target.moveSlots.findIndex(m => this.toID(target.m.scrambled.moves[isMove].thing) === m.id), 1);
|
||||
target.m.scrambled.moves.splice(isMove, 1);
|
||||
}
|
||||
}
|
||||
|
||||
source.ability = source.baseAbility = targetAbility.id;
|
||||
target.ability = target.baseAbility = sourceAbility.id;
|
||||
source.abilityState = this.initEffectState({ id: this.toID(source.ability), target: source });
|
||||
target.abilityState = this.initEffectState({ id: this.toID(target.ability), target });
|
||||
|
||||
source.volatileStaleness = undefined;
|
||||
if (!target.isAlly(source)) target.volatileStaleness = 'external';
|
||||
|
||||
this.singleEvent('Start', targetAbility, source.abilityState, source);
|
||||
if (targetIsBMM) {
|
||||
if (this.dex.items.get(targetAbility.id).exists) {
|
||||
source.m.scrambled.items.push({ thing: targetAbility.id, inSlot: 'Ability' });
|
||||
const effect = 'item:' + this.toID(targetAbility.id);
|
||||
source.addVolatile(effect);
|
||||
source.volatiles[effect].inSlot = 'Ability';
|
||||
} else {
|
||||
source.m.scrambled.moves.push({ thing: targetAbility.id, inSlot: 'Ability' });
|
||||
const bmmMove = Dex.moves.get(targetAbility.id);
|
||||
const newMove = {
|
||||
move: bmmMove.name,
|
||||
id: bmmMove.id,
|
||||
pp: bmmMove.noPPBoosts ? bmmMove.pp : bmmMove.pp * 8 / 5,
|
||||
maxpp: bmmMove.noPPBoosts ? bmmMove.pp : bmmMove.pp * 8 / 5,
|
||||
target: bmmMove.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
source.baseMoveSlots.push(newMove);
|
||||
source.moveSlots.push(newMove);
|
||||
}
|
||||
}
|
||||
this.singleEvent('Start', sourceAbility, target.abilityState, target);
|
||||
if (sourceIsBMM) {
|
||||
if (this.dex.items.get(sourceAbility.id).exists) {
|
||||
target.m.scrambled.items.push({ thing: sourceAbility.id, inSlot: 'Ability' });
|
||||
const effect = 'item:' + this.toID(sourceAbility.id);
|
||||
target.addVolatile(effect);
|
||||
target.volatiles[effect].inSlot = 'Ability';
|
||||
} else {
|
||||
target.m.scrambled.moves.push({ thing: sourceAbility.id, inSlot: 'Ability' });
|
||||
const bmmMove = Dex.moves.get(sourceAbility.id);
|
||||
const newMove = {
|
||||
move: bmmMove.name,
|
||||
id: bmmMove.id,
|
||||
pp: bmmMove.noPPBoosts ? bmmMove.pp : bmmMove.pp * 8 / 5,
|
||||
maxpp: bmmMove.noPPBoosts ? bmmMove.pp : bmmMove.pp * 8 / 5,
|
||||
target: bmmMove.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
target.baseMoveSlots.push(newMove);
|
||||
target.moveSlots.push(newMove);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
switcheroo: {
|
||||
inherit: true,
|
||||
onHit(target, source, move) {
|
||||
const yourItem = target.takeItem(source);
|
||||
const myItem = source.takeItem();
|
||||
if (target.item || source.item || (!yourItem && !myItem)) {
|
||||
if (yourItem) {
|
||||
if (!this.dex.items.get(yourItem.id).exists) {
|
||||
target.setItem(yourItem.id);
|
||||
} else {
|
||||
target.item = yourItem.id;
|
||||
}
|
||||
}
|
||||
if (myItem) {
|
||||
if (!this.dex.items.get(myItem.id).exists) {
|
||||
source.setItem(myItem.id);
|
||||
} else {
|
||||
source.item = myItem.id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
(myItem && !this.singleEvent('TakeItem', myItem, source.itemState, target, source, move, myItem)) ||
|
||||
(yourItem && !this.singleEvent('TakeItem', yourItem, target.itemState, source, target, move, yourItem))
|
||||
) {
|
||||
if (yourItem) {
|
||||
if (!this.dex.items.get(yourItem.id).exists) {
|
||||
target.setItem(yourItem.id);
|
||||
} else {
|
||||
target.item = yourItem.id;
|
||||
}
|
||||
}
|
||||
if (myItem) {
|
||||
if (!this.dex.items.get(myItem.id).exists) {
|
||||
source.setItem(myItem.id);
|
||||
} else {
|
||||
source.item = myItem.id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
this.add('-activate', source, 'move: Trick', `[of] ${target}`);
|
||||
if (myItem) {
|
||||
target.setItem(myItem);
|
||||
this.add('-item', target, myItem, '[from] move: Switcheroo');
|
||||
} else {
|
||||
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Switcheroo');
|
||||
}
|
||||
if (yourItem) {
|
||||
source.setItem(yourItem);
|
||||
this.add('-item', source, yourItem, '[from] move: Switcheroo');
|
||||
} else {
|
||||
this.add('-enditem', source, myItem, '[silent]', '[from] move: Switcheroo');
|
||||
}
|
||||
},
|
||||
},
|
||||
thief: {
|
||||
inherit: true,
|
||||
onAfterHit(target, source, move) {
|
||||
if (source.item || source.volatiles['gem']) {
|
||||
return;
|
||||
}
|
||||
const yourItem = target.takeItem(source);
|
||||
if (!yourItem) {
|
||||
return;
|
||||
}
|
||||
if (!this.singleEvent('TakeItem', yourItem, target.itemState, source, target, move, yourItem) ||
|
||||
!source.setItem(yourItem)) {
|
||||
if (!this.dex.items.get(yourItem.id).exists) {
|
||||
target.setItem(yourItem.id);
|
||||
return;
|
||||
}
|
||||
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
|
||||
return;
|
||||
}
|
||||
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Thief', `[of] ${source}`);
|
||||
this.add('-item', source, yourItem, '[from] move: Thief', `[of] ${target}`);
|
||||
},
|
||||
},
|
||||
};
|
||||
584
data/mods/biomechmons/scripts.ts
Normal file
584
data/mods/biomechmons/scripts.ts
Normal file
|
|
@ -0,0 +1,584 @@
|
|||
import { RESTORATIVE_BERRIES } from "../../../sim/pokemon";
|
||||
|
||||
export const Scripts: ModdedBattleScriptsData = {
|
||||
pokemon: {
|
||||
isGrounded(negateImmunity) {
|
||||
if ('gravity' in this.battle.field.pseudoWeather) return true;
|
||||
if ('ingrain' in this.volatiles && this.battle.gen >= 4) return true;
|
||||
if ('smackdown' in this.volatiles) return true;
|
||||
const item = (this.ignoringItem() ? '' : this.item);
|
||||
if (item === 'ironball' || (this.volatiles['item:ironball'] && !this.ignoringItem())) return true;
|
||||
// If a Fire/Flying type uses Burn Up and Roost, it becomes ???/Flying-type, but it's still grounded.
|
||||
if (!negateImmunity && this.hasType('Flying') && !(this.hasType('???') && 'roost' in this.volatiles)) return false;
|
||||
if (this.hasAbility('levitate') && !this.battle.suppressingAbility(this)) return null;
|
||||
if ('magnetrise' in this.volatiles) return false;
|
||||
if ('telekinesis' in this.volatiles) return false;
|
||||
if (item === 'airballoon' || (this.volatiles['item:airballoon'] && !this.ignoringItem())) return false;
|
||||
return true;
|
||||
},
|
||||
getAbility() {
|
||||
const ability = this.battle.dex.abilities.getByID(this.ability);
|
||||
if (ability.exists) return ability;
|
||||
let abil = this.battle.dex.items.getByID(this.ability) as Item | Move;
|
||||
if (!abil.exists) abil = this.battle.dex.moves.getByID(this.ability);
|
||||
return {
|
||||
id: this.ability,
|
||||
name: abil.name || this.ability,
|
||||
flags: {},
|
||||
effectType: "Ability",
|
||||
toString() {
|
||||
return abil.name || this.id;
|
||||
},
|
||||
} as Ability;
|
||||
},
|
||||
hasAbility(ability) {
|
||||
if (this.ignoringAbility()) return false;
|
||||
if (Array.isArray(ability)) return ability.some(abil => this.hasAbility(abil));
|
||||
const abilityid = this.battle.toID(ability);
|
||||
return this.ability === abilityid || !!this.volatiles['ability:' + abilityid];
|
||||
},
|
||||
ignoringAbility() {
|
||||
// Check if any active pokemon have the ability Neutralizing Gas
|
||||
let neutralizinggas = false;
|
||||
for (const pokemon of this.battle.getAllActive()) {
|
||||
// can't use hasAbility because it would lead to infinite recursion
|
||||
if (
|
||||
(pokemon.ability === ('neutralizinggas' as ID) ||
|
||||
(pokemon.m.scrambled.abilities as { thing: string }[]).some(
|
||||
abils => this.battle.toID(abils.thing) === 'neutralizinggas')) &&
|
||||
!pokemon.volatiles['gastroacid'] && !pokemon.abilityState.ending
|
||||
) {
|
||||
neutralizinggas = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !!(
|
||||
(this.battle.gen >= 5 && !this.isActive) ||
|
||||
((this.volatiles['gastroacid'] ||
|
||||
(neutralizinggas && (this.ability !== ('neutralizinggas' as ID) ||
|
||||
(this.m.scrambled.abilities as { thing: string }[]).some(abils => this.battle.toID(abils.thing) === 'neutralizinggas'))
|
||||
)) && !this.getAbility().flags['cantsuppress']
|
||||
)
|
||||
);
|
||||
},
|
||||
setAbility(ability, source, sourceEffect, isFromFormeChange = false, isTransform = false) {
|
||||
const allThings = new Set([
|
||||
...(this.m.scrambled.abilities as { thing: string }[]).map(e => e.thing),
|
||||
...(this.m.scrambled.items as { thing: string }[]).map(e => e.thing),
|
||||
...(this.m.scrambled.moves as { thing: string }[]).map(e => e.thing),
|
||||
this.ability, ...this.moveSlots.map(e => e.move), this.item,
|
||||
].map(this.battle.toID));
|
||||
|
||||
let isBMMAbil = false;
|
||||
let isOldBMMAbil = false;
|
||||
if (!this.hp) return false;
|
||||
if (typeof ability === 'string') {
|
||||
if (this.battle.dex.abilities.get(ability).exists) {
|
||||
ability = this.battle.dex.abilities.get(ability);
|
||||
} else {
|
||||
const abilString = ability;
|
||||
let abil = this.battle.dex.items.get(abilString) as Item | Move;
|
||||
if (!abil.exists) abil = this.battle.dex.moves.get(abilString);
|
||||
ability = {
|
||||
id: abil.id || abilString,
|
||||
name: abil.name || abilString,
|
||||
flags: {},
|
||||
effectType: "Ability",
|
||||
toString() {
|
||||
return abil.name || abilString;
|
||||
},
|
||||
} as Ability;
|
||||
}
|
||||
}
|
||||
if (ability.name.length && !this.battle.dex.abilities.get(ability).exists) isBMMAbil = true;
|
||||
if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect;
|
||||
let oldAbility;
|
||||
if (this.battle.dex.abilities.get(this.ability).exists) {
|
||||
oldAbility = this.battle.dex.abilities.get(this.ability);
|
||||
} else {
|
||||
let abil = this.battle.dex.items.getByID(this.ability) as Item | Move;
|
||||
if (!abil.exists) {
|
||||
abil = this.battle.dex.moves.getByID(this.ability);
|
||||
} else {
|
||||
if (!this.battle.runEvent('TakeItem', this, source, null, abil as Item)) return false;
|
||||
}
|
||||
oldAbility = {
|
||||
id: this.ability,
|
||||
name: abil.name || this.ability,
|
||||
flags: {},
|
||||
effectType: "Ability",
|
||||
toString() {
|
||||
return abil.name || this.id;
|
||||
},
|
||||
} as Ability;
|
||||
isOldBMMAbil = true;
|
||||
}
|
||||
|
||||
if (allThings.has(ability.id)) return false;
|
||||
|
||||
if (!isFromFormeChange) {
|
||||
if (ability.flags['cantsuppress'] || this.getAbility().flags['cantsuppress']) return false;
|
||||
}
|
||||
if (!isFromFormeChange && !isTransform) {
|
||||
const setAbilityEvent: boolean | null = this.battle.runEvent('SetAbility', this, source, sourceEffect, ability);
|
||||
if (!setAbilityEvent) return setAbilityEvent;
|
||||
}
|
||||
this.battle.singleEvent('End', oldAbility, this.abilityState, this, source);
|
||||
if (isOldBMMAbil) {
|
||||
const isItem = (this.m.scrambled.items as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
if (isItem >= 0) {
|
||||
this.removeVolatile('item:' + this.battle.toID(this.m.scrambled.items[isItem].thing));
|
||||
this.m.scrambled.items.splice(isItem, 1);
|
||||
} else if ((this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability') >= 0) {
|
||||
const isMove = (this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Ability');
|
||||
if (!isTransform) {
|
||||
let indexOfMove = this.baseMoveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[isMove].thing) === m.id);
|
||||
if (indexOfMove >= 0) this.baseMoveSlots.splice(indexOfMove, 1);
|
||||
if (oldAbility.id !== 'mimic') {
|
||||
indexOfMove = this.moveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[isMove].thing) === m.id);
|
||||
}
|
||||
if (indexOfMove >= 0) this.moveSlots.splice(indexOfMove, 1);
|
||||
}
|
||||
this.m.scrambled.moves.splice(isMove, 1);
|
||||
}
|
||||
}
|
||||
this.ability = ability.id;
|
||||
// ability changes are permanent in BioMechMons
|
||||
if (!isTransform && !this.transformed) this.baseAbility = ability.id;
|
||||
this.abilityState = this.battle.initEffectState({ id: ability.id, target: this });
|
||||
if (sourceEffect && !isFromFormeChange && !isTransform) {
|
||||
if (source) {
|
||||
this.battle.add('-ability', this, ability.name, oldAbility.name, `[from] ${sourceEffect.fullname}`, `[of] ${source}`);
|
||||
} else {
|
||||
this.battle.add('-ability', this, ability.name, oldAbility.name, `[from] ${sourceEffect.fullname}`);
|
||||
}
|
||||
}
|
||||
if (ability.id && this.battle.gen > 3 &&
|
||||
(!isTransform || oldAbility.id !== ability.id || this.battle.gen <= 4)) {
|
||||
this.battle.singleEvent('Start', ability, this.abilityState, this, source);
|
||||
}
|
||||
if (isBMMAbil) {
|
||||
if (this.battle.dex.items.get(ability.id).exists) {
|
||||
this.m.scrambled.items.push({ thing: ability.id, inSlot: 'Ability' });
|
||||
const effect = 'item:' + this.battle.toID(ability.id);
|
||||
this.addVolatile(effect);
|
||||
this.volatiles[effect].inSlot = 'Ability';
|
||||
} else {
|
||||
this.m.scrambled.moves.push({ thing: ability.id, inSlot: 'Ability' });
|
||||
const move = Dex.moves.get(ability.id);
|
||||
const newMove = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
if (!isTransform) {
|
||||
this.baseMoveSlots.push(newMove);
|
||||
this.moveSlots.push(newMove);
|
||||
}
|
||||
}
|
||||
}
|
||||
return oldAbility.id;
|
||||
},
|
||||
getItem() {
|
||||
const item = this.battle.dex.items.getByID(this.item);
|
||||
if (item.exists) return item;
|
||||
let bmmItem = this.battle.dex.abilities.getByID(this.item) as Ability | Move;
|
||||
if (!bmmItem.exists) bmmItem = this.battle.dex.moves.getByID(this.item);
|
||||
return {
|
||||
id: this.item,
|
||||
name: bmmItem.name || this.name,
|
||||
effectType: "Item",
|
||||
toString() {
|
||||
return bmmItem.name || this.id;
|
||||
},
|
||||
} as Item;
|
||||
},
|
||||
hasItem(item) {
|
||||
if (this.ignoringItem()) return false;
|
||||
if (Array.isArray(item)) return item.some(i => this.hasItem(i));
|
||||
const itemId = this.battle.toID(item);
|
||||
return this.item === itemId || !!this.volatiles['item:' + itemId];
|
||||
},
|
||||
takeItem(source) {
|
||||
if (!this.item) return false;
|
||||
if (!source) source = this;
|
||||
if (this.battle.gen <= 4) {
|
||||
if (source.itemKnockedOff) return false;
|
||||
if (this.battle.toID(this.ability) === 'multitype' || (this.m.scrambled.abilities as { thing: string }[])
|
||||
.findIndex(e => this.battle.toID(e.thing) === 'multitype') >= 0) {
|
||||
return false;
|
||||
}
|
||||
if (this.battle.toID(source.ability) === 'multitype' || (source.m.scrambled.abilities as { thing: string }[])
|
||||
.findIndex(e => this.battle.toID(e.thing) === 'multitype') >= 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const item = this.getItem();
|
||||
if (this.battle.runEvent('TakeItem', this, source, null, item)) {
|
||||
this.item = '';
|
||||
let wrongSlot = (this.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
if (wrongSlot >= 0) {
|
||||
const dexAbil = this.battle.dex.abilities.get(this.m.scrambled.abilities[wrongSlot].thing);
|
||||
if (dexAbil.flags['failskillswap']) return false;
|
||||
this.removeVolatile('ability:' + this.battle.toID(this.m.scrambled.abilities[wrongSlot].thing));
|
||||
this.m.scrambled.abilities.splice(wrongSlot, 1);
|
||||
} else if ((this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
|
||||
wrongSlot = (this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
let indexOfMove = this.baseMoveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[wrongSlot].thing) === m.id);
|
||||
if (indexOfMove >= 0) this.baseMoveSlots.splice(indexOfMove, 1);
|
||||
if (item.id !== 'mimic') {
|
||||
indexOfMove = this.moveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[wrongSlot].thing) === m.id);
|
||||
}
|
||||
if (indexOfMove >= 0) this.moveSlots.splice(indexOfMove, 1);
|
||||
this.m.scrambled.moves.splice(wrongSlot, 1);
|
||||
}
|
||||
const oldItemState = this.itemState;
|
||||
this.battle.clearEffectState(this.itemState);
|
||||
this.pendingStaleness = undefined;
|
||||
this.battle.singleEvent('End', item, oldItemState, this);
|
||||
this.battle.runEvent('AfterTakeItem', this, null, null, item);
|
||||
return item;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
setItem(item, source, effect) {
|
||||
const allThings = new Set([
|
||||
...(this.m.scrambled.abilities as { thing: string }[]).map(e => e.thing),
|
||||
...(this.m.scrambled.items as { thing: string }[]).map(e => e.thing),
|
||||
...(this.m.scrambled.moves as { thing: string }[]).map(e => e.thing),
|
||||
this.ability, ...this.moveSlots.map(e => e.move), this.item,
|
||||
].map(this.battle.toID));
|
||||
|
||||
let isBMMItem = false;
|
||||
let isOldBMMItem = false;
|
||||
if (!this.hp || !this.isActive) return false;
|
||||
if (typeof item === 'string') {
|
||||
if (!item.length || this.battle.dex.items.get(item).exists) {
|
||||
item = this.battle.dex.items.get(item);
|
||||
} else {
|
||||
const itemString = item;
|
||||
let newData = this.battle.dex.abilities.get(itemString) as Ability | Move;
|
||||
if (!newData.exists) {
|
||||
newData = this.battle.dex.moves.get(itemString);
|
||||
} else {
|
||||
if ((newData as Ability).flags['failskillswap']) return false;
|
||||
}
|
||||
item = {
|
||||
id: newData.id || itemString,
|
||||
name: newData.name || itemString,
|
||||
effectType: "Item",
|
||||
toString() {
|
||||
return newData.name || itemString;
|
||||
},
|
||||
} as Item;
|
||||
}
|
||||
}
|
||||
if (item.name.length && !this.battle.dex.items.get(item).exists) isBMMItem = true;
|
||||
if (allThings.has(item.id)) return false;
|
||||
const effectid = this.battle.effect ? this.battle.effect.id : '';
|
||||
if (RESTORATIVE_BERRIES.has('leppaberry' as ID)) {
|
||||
const inflicted = ['trick', 'switcheroo'].includes(effectid);
|
||||
const external = inflicted && source && !source.isAlly(this);
|
||||
this.pendingStaleness = external ? 'external' : 'internal';
|
||||
} else {
|
||||
this.pendingStaleness = undefined;
|
||||
}
|
||||
const oldItem = this.getItem();
|
||||
if (!this.battle.dex.items.get(oldItem).exists) isOldBMMItem = true;
|
||||
const oldItemState = this.itemState;
|
||||
this.item = item.id;
|
||||
this.itemState = this.battle.initEffectState({ id: item.id, target: this });
|
||||
if (oldItem.exists) this.battle.singleEvent('End', oldItem, oldItemState, this);
|
||||
if (isOldBMMItem) {
|
||||
const isAbil = (this.m.scrambled.abilities as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
if (isAbil >= 0) {
|
||||
this.removeVolatile('ability:' + this.battle.toID(this.m.scrambled.items[isAbil].thing));
|
||||
this.m.scrambled.abilities.splice(isAbil, 1);
|
||||
} else if ((this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item') >= 0) {
|
||||
const isMove = (this.m.scrambled.moves as { inSlot: string }[]).findIndex(e => e.inSlot === 'Item');
|
||||
let indexOfMove = this.baseMoveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[isMove].thing) === m.id);
|
||||
if (indexOfMove >= 0) this.baseMoveSlots.splice(indexOfMove, 1);
|
||||
if (oldItem.id !== 'mimic') {
|
||||
indexOfMove = this.moveSlots.findIndex(m => this.battle.toID(this.m.scrambled.moves[isMove].thing) === m.id);
|
||||
}
|
||||
if (indexOfMove >= 0) this.moveSlots.splice(indexOfMove, 1);
|
||||
this.m.scrambled.moves.splice(isMove, 1);
|
||||
}
|
||||
}
|
||||
if (item.id) {
|
||||
this.battle.singleEvent('Start', item, this.itemState, this, source, effect);
|
||||
}
|
||||
if (isBMMItem) {
|
||||
if (this.battle.dex.abilities.get(item.id).exists) {
|
||||
this.m.scrambled.abilities.push({ thing: item.id, inSlot: 'Item' });
|
||||
const abileffect = 'ability:' + this.battle.toID(item.id);
|
||||
this.addVolatile(abileffect);
|
||||
this.volatiles[abileffect].inSlot = 'Item';
|
||||
} else {
|
||||
this.m.scrambled.moves.push({ thing: item.id, inSlot: 'Item' });
|
||||
const move = Dex.moves.get(item.id);
|
||||
const newMove = {
|
||||
move: move.name,
|
||||
id: move.id,
|
||||
pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
|
||||
target: move.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
this.baseMoveSlots.push(newMove);
|
||||
this.moveSlots.push(newMove);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
eatItem(force, source, sourceEffect) {
|
||||
const item = sourceEffect?.effectType === 'Item' ? sourceEffect :
|
||||
this.battle.effect.effectType === 'Item' ? this.battle.effect : this.getItem();
|
||||
if (!item) return false;
|
||||
if ((!this.hp && this.battle.toID(item.name) !== 'jabocaberry' && this.battle.toID(item.name) !== 'rowapberry') ||
|
||||
!this.isActive) return false;
|
||||
|
||||
if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect;
|
||||
if (!source && this.battle.event?.target) source = this.battle.event.target;
|
||||
// if (sourceEffect?.effectType === 'Item' && this.item !== sourceEffect.id && source === this) {
|
||||
// // if an item is telling us to eat it but we aren't holding it, we probably shouldn't eat what we are holding
|
||||
// return false;
|
||||
// }
|
||||
if (
|
||||
this.battle.runEvent('UseItem', this, null, null, Dex.items.get(item.name)) &&
|
||||
(force || this.battle.runEvent('TryEatItem', this, null, null, Dex.items.get(item.name)))
|
||||
) {
|
||||
this.battle.add('-enditem', this, Dex.items.get(item.name), '[eat]');
|
||||
|
||||
this.battle.singleEvent('Eat', Dex.items.get(item.name), this.itemState, this, source, sourceEffect);
|
||||
this.battle.runEvent('EatItem', this, source, sourceEffect, Dex.items.get(item.name));
|
||||
|
||||
if (RESTORATIVE_BERRIES.has(item.id)) {
|
||||
switch (this.pendingStaleness) {
|
||||
case 'internal':
|
||||
if (this.staleness !== 'external') this.staleness = 'internal';
|
||||
break;
|
||||
case 'external':
|
||||
this.staleness = 'external';
|
||||
break;
|
||||
}
|
||||
this.pendingStaleness = undefined;
|
||||
}
|
||||
|
||||
const isBMM = this.volatiles[item.id]?.inSlot;
|
||||
if (isBMM) {
|
||||
const dexItem = this.battle.dex.items.get(item.name);
|
||||
this.removeVolatile(item.id);
|
||||
const itemIndex = (this.m.scrambled.items as { thing: string, inSlot: string }[]).findIndex(e =>
|
||||
this.battle.toID(e.thing) === dexItem.id && e.inSlot === isBMM);
|
||||
if (itemIndex >= 0) this.m.scrambled.items.splice(itemIndex, 1);
|
||||
if (isBMM === 'Ability') this.setAbility('No Ability');
|
||||
} else {
|
||||
this.lastItem = this.item;
|
||||
this.item = '';
|
||||
}
|
||||
this.battle.clearEffectState(this.itemState);
|
||||
this.usedItemThisTurn = true;
|
||||
this.ateBerry = true;
|
||||
this.battle.runEvent('AfterUseItem', this, null, null, Dex.items.get(item.name));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
useItem(source, sourceEffect) {
|
||||
const item = sourceEffect?.effectType === 'Item' ? sourceEffect :
|
||||
this.battle.effect.effectType === 'Item' ? this.battle.effect : this.getItem();
|
||||
if ((!this.hp && !item.isGem) || !this.isActive) return false;
|
||||
if (!item) return false;
|
||||
|
||||
if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect;
|
||||
if (!source && this.battle.event?.target) source = this.battle.event.target;
|
||||
// const item = this.getItem();
|
||||
// if (sourceEffect?.effectType === 'Item' && this.item !== sourceEffect.id && source === this) {
|
||||
// // if an item is telling us to eat it but we aren't holding it, we probably shouldn't eat what we are holding
|
||||
// return false;
|
||||
// }
|
||||
if (this.battle.runEvent('UseItem', this, null, null, Dex.items.get(item.name))) {
|
||||
switch (item.id) {
|
||||
case 'redcard':
|
||||
this.battle.add('-enditem', this, Dex.items.get(item.name), `[of] ${source}`);
|
||||
break;
|
||||
default:
|
||||
if (item.isGem) {
|
||||
this.battle.add('-enditem', this, Dex.items.get(item.name), '[from] gem');
|
||||
} else {
|
||||
this.battle.add('-enditem', this, Dex.items.get(item.name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (item.boosts) {
|
||||
this.battle.boost(item.boosts, this, source, Dex.items.get(item.name));
|
||||
}
|
||||
|
||||
this.battle.singleEvent('Use', Dex.items.get(item.name), this.itemState, this, source, sourceEffect);
|
||||
|
||||
const isBMM = this.volatiles[item.id]?.inSlot;
|
||||
if (isBMM) {
|
||||
const dexItem = this.battle.dex.items.get(item.name);
|
||||
this.removeVolatile(item.id);
|
||||
const itemIndex = (this.m.scrambled.items as { thing: string, inSlot: string }[]).findIndex(e =>
|
||||
this.battle.toID(e.thing) === dexItem.id && e.inSlot === isBMM);
|
||||
if (itemIndex >= 0) this.m.scrambled.items.splice(itemIndex, 1);
|
||||
if (isBMM === 'Ability') this.setAbility('No Ability');
|
||||
} else {
|
||||
this.lastItem = this.item;
|
||||
this.item = '';
|
||||
}
|
||||
this.battle.clearEffectState(this.itemState);
|
||||
this.usedItemThisTurn = true;
|
||||
this.battle.runEvent('AfterUseItem', this, null, null, item);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
transformInto(pokemon, effect) {
|
||||
const species = pokemon.species;
|
||||
if (
|
||||
pokemon.fainted || this.illusion || pokemon.illusion || (pokemon.volatiles['substitute'] && this.battle.gen >= 5) ||
|
||||
(pokemon.transformed && this.battle.gen >= 2) || (this.transformed && this.battle.gen >= 5) ||
|
||||
species.name === 'Eternatus-Eternamax' ||
|
||||
(['Ogerpon', 'Terapagos'].includes(species.baseSpecies) && (this.terastallized || pokemon.terastallized)) ||
|
||||
this.terastallized === 'Stellar'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.battle.dex.currentMod === 'gen1stadium' && (
|
||||
species.name === 'Ditto' ||
|
||||
(this.species.name === 'Ditto' && pokemon.moves.includes('transform'))
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.setSpecies(species, effect, true)) return false;
|
||||
|
||||
this.transformed = true;
|
||||
this.weighthg = pokemon.weighthg;
|
||||
|
||||
const types = pokemon.getTypes(true, true);
|
||||
this.setType(pokemon.volatiles['roost'] ? pokemon.volatiles['roost'].typeWas : types, true);
|
||||
this.addedType = pokemon.addedType;
|
||||
this.knownType = this.isAlly(pokemon) && pokemon.knownType;
|
||||
this.apparentType = pokemon.apparentType;
|
||||
|
||||
let statName: StatIDExceptHP;
|
||||
for (statName in this.storedStats) {
|
||||
this.storedStats[statName] = pokemon.storedStats[statName];
|
||||
if (this.modifiedStats) this.modifiedStats[statName] = pokemon.modifiedStats![statName]; // Gen 1: Copy modified stats.
|
||||
}
|
||||
this.moveSlots = [];
|
||||
this.hpType = (this.battle.gen >= 5 ? this.hpType : pokemon.hpType);
|
||||
this.hpPower = (this.battle.gen >= 5 ? this.hpPower : pokemon.hpPower);
|
||||
this.timesAttacked = pokemon.timesAttacked;
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
let moveName = moveSlot.move;
|
||||
if (moveSlot.id === 'hiddenpower') {
|
||||
moveName = 'Hidden Power ' + this.hpType;
|
||||
}
|
||||
this.moveSlots.push({
|
||||
move: moveName,
|
||||
id: moveSlot.id,
|
||||
pp: moveSlot.maxpp === 1 ? 1 : 5,
|
||||
maxpp: this.battle.gen >= 5 ? (moveSlot.maxpp === 1 ? 1 : 5) : moveSlot.maxpp,
|
||||
target: moveSlot.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
virtual: true,
|
||||
});
|
||||
}
|
||||
let boostName: BoostID;
|
||||
for (boostName in pokemon.boosts) {
|
||||
this.boosts[boostName] = pokemon.boosts[boostName];
|
||||
}
|
||||
if (this.battle.gen >= 6) {
|
||||
// we need to remove all of the overlapping crit volatiles before adding any of them
|
||||
const volatilesToCopy = ['dragoncheer', 'focusenergy', 'gmaxchistrike', 'laserfocus'];
|
||||
for (const volatile of volatilesToCopy) this.removeVolatile(volatile);
|
||||
for (const volatile of volatilesToCopy) {
|
||||
if (pokemon.volatiles[volatile]) {
|
||||
this.addVolatile(volatile);
|
||||
if (volatile === 'gmaxchistrike') this.volatiles[volatile].layers = pokemon.volatiles[volatile].layers;
|
||||
if (volatile === 'dragoncheer') this.volatiles[volatile].hasDragonType = pokemon.volatiles[volatile].hasDragonType;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (effect) {
|
||||
this.battle.add('-transform', this, pokemon, '[from] ' + effect.fullname);
|
||||
} else {
|
||||
this.battle.add('-transform', this, pokemon);
|
||||
}
|
||||
if (this.terastallized) {
|
||||
this.knownType = true;
|
||||
this.apparentType = this.terastallized;
|
||||
}
|
||||
if (this.battle.gen > 2) this.setAbility(pokemon.ability, this, null, true, true);
|
||||
|
||||
// Change formes based on held items (for Transform)
|
||||
// Only ever relevant in Generation 4 since Generation 3 didn't have item-based forme changes
|
||||
if (this.battle.gen === 4) {
|
||||
if (this.species.num === 487) {
|
||||
// Giratina formes
|
||||
if (this.species.name === 'Giratina' && this.item === 'griseousorb') {
|
||||
this.formeChange('Giratina-Origin');
|
||||
} else if (this.species.name === 'Giratina-Origin' && this.item !== 'griseousorb') {
|
||||
this.formeChange('Giratina');
|
||||
}
|
||||
}
|
||||
if (this.species.num === 493) {
|
||||
// Arceus formes
|
||||
const item = this.getItem();
|
||||
const targetForme = (item?.onPlate ? 'Arceus-' + item.onPlate : 'Arceus');
|
||||
if (this.species.name !== targetForme) {
|
||||
this.formeChange(targetForme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pokemon transformed into Ogerpon cannot Terastallize
|
||||
// restoring their ability to tera after they untransform is handled ELSEWHERE
|
||||
if (['Ogerpon', 'Terapagos'].includes(this.species.baseSpecies) && this.canTerastallize) this.canTerastallize = false;
|
||||
|
||||
for (const volatile in this.volatiles) {
|
||||
if (this.volatiles[volatile].inSlot && this.volatiles[volatile].inSlot === 'Move') {
|
||||
this.removeVolatile(volatile);
|
||||
}
|
||||
}
|
||||
|
||||
for (const volatile in pokemon.volatiles) {
|
||||
if (pokemon.volatiles[volatile].inSlot && pokemon.volatiles[volatile].inSlot === 'Move') {
|
||||
this.addVolatile(volatile);
|
||||
this.volatiles[volatile].inSlot = 'Move';
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
field: {
|
||||
suppressingWeather() {
|
||||
for (const pokemon of this.battle.getAllActive()) {
|
||||
const innates = Object.keys(pokemon.volatiles).filter(x => x.startsWith('ability:'));
|
||||
if (pokemon && !pokemon.ignoringAbility() &&
|
||||
(pokemon.getAbility().suppressWeather || innates.some(x => (
|
||||
this.battle.dex.abilities.get(x.replace('ability:', '')).suppressWeather
|
||||
)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
};
|
||||
993
data/mods/chatbats/abilities.ts
Normal file
993
data/mods/chatbats/abilities.ts
Normal file
|
|
@ -0,0 +1,993 @@
|
|||
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
|
||||
thickfat: {
|
||||
// prevents burning
|
||||
inherit: true,
|
||||
onUpdate(pokemon) {
|
||||
if (pokemon.status === 'brn') {
|
||||
this.add('-activate', pokemon, 'ability: Thick Fat');
|
||||
pokemon.cureStatus();
|
||||
}
|
||||
},
|
||||
onSetStatus(status, target, source, effect) {
|
||||
if (status.id !== 'brn') return;
|
||||
if ((effect as Move)?.status) {
|
||||
this.add('-immune', target, '[from] ability: Thick Fat');
|
||||
}
|
||||
return false;
|
||||
},
|
||||
shortDesc: "-50% damage from Fire and Ice. Burn immune.",
|
||||
},
|
||||
callillumise: {
|
||||
onDamagePriority: -30,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (damage >= target.hp) {
|
||||
this.add('-ability', target, 'Call Illumise');
|
||||
this.effectState.callillumise = true;
|
||||
return target.hp - 1;
|
||||
}
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
if (!this.effectState.callillumise) return;
|
||||
|
||||
this.add('-message', `Volbeat calls upon Illumise for aid!`);
|
||||
// Define new moves
|
||||
const newMoves = ['bugbuzz', 'icebeam', 'thunderbolt', 'quiverdance'];
|
||||
// Update move slots
|
||||
pokemon.moveSlots = newMoves.map(move => {
|
||||
const moveData = this.dex.moves.get(move);
|
||||
return {
|
||||
move: moveData.name,
|
||||
id: moveData.id,
|
||||
pp: moveData.pp,
|
||||
maxpp: moveData.pp,
|
||||
target: moveData.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
});
|
||||
// this forces the UI to update move slots visually
|
||||
(pokemon as any).baseMoveSlots = pokemon.moveSlots.slice();
|
||||
// removes status/boosts
|
||||
pokemon.cureStatus();
|
||||
pokemon.clearBoosts();
|
||||
// forces the UI to update part II
|
||||
this.add('-clearboost', pokemon, '[from] ability: Call Illumise', '[silent]');
|
||||
for (const volatile in pokemon.volatiles) {
|
||||
this.add('-end', pokemon, volatile);
|
||||
}
|
||||
pokemon.clearVolatile(true);
|
||||
// form change + heal
|
||||
pokemon.formeChange('Illumise', null, true);
|
||||
this.heal(pokemon.maxhp);
|
||||
// sets new ability
|
||||
pokemon.setAbility('Tinted Lens', null, null, true);
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
this.add('-ability', pokemon, 'Tinted Lens');
|
||||
},
|
||||
flags: {
|
||||
breakable: 1, failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1,
|
||||
},
|
||||
name: "Call Illumise",
|
||||
rating: 5,
|
||||
num: -100,
|
||||
shortDesc: "When Volbeat gets low on HP, it calls Illumise for aid.",
|
||||
},
|
||||
callvolbeat: {
|
||||
onDamagePriority: -30,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (damage >= target.hp) {
|
||||
this.add('-ability', target, 'Call Volbeat');
|
||||
this.effectState.callvolbeat = true;
|
||||
return target.hp - 1;
|
||||
}
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
if (!this.effectState.callvolbeat) return;
|
||||
|
||||
this.add('-message', `Illumise calls upon Volbeat for aid!`);
|
||||
// Define new moves
|
||||
const newMoves = ['victorydance', 'lunge', 'mightycleave', 'earthquake'];
|
||||
// Update move slots
|
||||
pokemon.moveSlots = newMoves.map(move => {
|
||||
const moveData = this.dex.moves.get(move);
|
||||
return {
|
||||
move: moveData.name,
|
||||
id: moveData.id,
|
||||
pp: moveData.pp,
|
||||
maxpp: moveData.pp,
|
||||
target: moveData.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
});
|
||||
// this forces the UI to update move slots visually
|
||||
(pokemon as any).baseMoveSlots = pokemon.moveSlots.slice();
|
||||
// removes status/boosts
|
||||
pokemon.cureStatus();
|
||||
pokemon.clearBoosts();
|
||||
// forces the UI to update part II
|
||||
this.add('-clearboost', pokemon, '[from] ability: Call Volbeat', '[silent]');
|
||||
for (const volatile in pokemon.volatiles) {
|
||||
this.add('-end', pokemon, volatile);
|
||||
}
|
||||
pokemon.clearVolatile(true);
|
||||
// form change + heal
|
||||
pokemon.formeChange('Volbeat', null, true);
|
||||
this.heal(pokemon.maxhp);
|
||||
// sets new ability
|
||||
pokemon.setAbility('Dancer', null, null, true);
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
this.add('-ability', pokemon, 'Dancer');
|
||||
},
|
||||
flags: {
|
||||
breakable: 1, failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1,
|
||||
},
|
||||
name: "Call Volbeat",
|
||||
rating: 5,
|
||||
num: -101,
|
||||
shortDesc: "When Illumise gets low on HP, it calls Volbeat for aid.",
|
||||
},
|
||||
shortfuse: {
|
||||
onDamagePriority: -30,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (damage >= target.hp) {
|
||||
this.add('-ability', target, 'Short Fuse');
|
||||
this.effectState.shortfuse = true;
|
||||
return target.hp - 1;
|
||||
}
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
if (this.effectState.shortfuse) {
|
||||
delete this.effectState.shortfuse;
|
||||
this.actions.useMove('explosion', pokemon);
|
||||
}
|
||||
this.checkFainted();
|
||||
},
|
||||
flags: {
|
||||
breakable: 1, failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1,
|
||||
},
|
||||
name: "Short Fuse",
|
||||
rating: 5,
|
||||
num: -102,
|
||||
shortDesc: "If KO'd, use Explosion instead.",
|
||||
},
|
||||
hydroelectricdam: {
|
||||
// Copied from the code for Sand Spit
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
this.field.setWeather('raindance');
|
||||
},
|
||||
flags: {},
|
||||
name: "Hydroelectric Dam",
|
||||
rating: 5,
|
||||
num: -103,
|
||||
shortDesc: "Starts Rain Dance when hit by an attack.",
|
||||
},
|
||||
frozenarmor: {
|
||||
onTryHit(target, source, move) {
|
||||
if (move.category !== 'Status') {
|
||||
this.add('-ability', target, 'Frozen Armor');
|
||||
// reduces base power of incoming moves by 20 (math.max prevents base power from reducing below 0)
|
||||
move.basePower = Math.max(move.basePower - 20, 0);
|
||||
}
|
||||
},
|
||||
onSwitchInPriority: -1,
|
||||
onUpdate(pokemon) {
|
||||
// checks if Glastrier is below 50% HP, if so transforms into Caly-Ice and sets ability to As One
|
||||
if (pokemon.species.id !== 'glastrier' || !pokemon.hp) return;
|
||||
if (pokemon.hp < pokemon.maxhp / 2) {
|
||||
if (pokemon.species.id !== 'calyrexice' && pokemon.ability === 'frozenarmor') {
|
||||
pokemon.formeChange('Calyrex-Ice', null, true);
|
||||
this.add('-message', `Glastrier's Frozen Armor has shattered!`);
|
||||
// pokemon.setAbility('As One (Glastrier)');
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
// this.add('-ability', pokemon, 'As One');
|
||||
}
|
||||
}
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1 },
|
||||
name: "Frozen Armor",
|
||||
rating: 5,
|
||||
num: -105,
|
||||
shortDesc: "-20 BP on attacks targeting Glastrier, at 50% HP become Calyrex-Ice.",
|
||||
},
|
||||
flipflop: {
|
||||
onDamagingHitOrder: 1,
|
||||
onTryHit(target, source, move) {
|
||||
if (move.flags['contact']) {
|
||||
let flipFlopBoosts = false;
|
||||
const invertedBoosts: SparseBoostsTable = {};
|
||||
for (const stat in source.boosts) {
|
||||
if (source.boosts[stat as BoostID] > 0) {
|
||||
// checks for boosts on source of move, inverts boosts and adds them to invertedBoosts table
|
||||
invertedBoosts[stat as BoostID] = -2 * source.boosts[stat as BoostID];
|
||||
if (!flipFlopBoosts) {
|
||||
this.add('-ability', target, 'Flip Flop');
|
||||
flipFlopBoosts = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// applies boosts
|
||||
this.boost(invertedBoosts, source, target);
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Flip Flop",
|
||||
rating: 5,
|
||||
num: -104,
|
||||
shortDesc: "When hit by contact move, invert attacker’s stat boosts.",
|
||||
},
|
||||
|
||||
grasspelt: {
|
||||
inherit: true,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
this.field.setTerrain('grassyterrain');
|
||||
},
|
||||
shortDesc: "Starts Grassy Terrain on hit. 1.5x Def in Grassy Terrain.",
|
||||
},
|
||||
aquaveil: {
|
||||
onSwitchInPriority: -1,
|
||||
// fakes the effect of aqua ring volatile lel
|
||||
onStart(pokemon) {
|
||||
this.add('-start', pokemon, 'Aqua Ring');
|
||||
},
|
||||
// provides effects of Water Bubble because Aqua Ring is modified to provide Water Bubble.
|
||||
onResidualOrder: 6,
|
||||
onResidual(pokemon) {
|
||||
this.heal(pokemon.baseMaxhp / 16);
|
||||
},
|
||||
onSourceModifyAtkPriority: 5,
|
||||
onSourceModifyAtk(atk, attacker, defender, move) {
|
||||
if (move.type === 'Fire') {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
onSourceModifySpAPriority: 5,
|
||||
onSourceModifySpA(atk, attacker, defender, move) {
|
||||
if (move.type === 'Fire') {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
onModifyAtk(atk, attacker, defender, move) {
|
||||
if (move.type === 'Water') {
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
onModifySpA(atk, attacker, defender, move) {
|
||||
if (move.type === 'Water') {
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
// this ability is supposed to just add Aqua Ring (the volatile) to the Pokemon on switch in
|
||||
flags: { cantsuppress: 1 },
|
||||
name: "Aqua Veil",
|
||||
rating: 5,
|
||||
num: -106,
|
||||
shortDesc: "Starts Aqua Ring on switch in.",
|
||||
},
|
||||
// unaware + water absorb
|
||||
stillwater: {
|
||||
onAnyModifyBoost(boosts, pokemon) {
|
||||
const unawareUser = this.effectState.target;
|
||||
if (unawareUser === pokemon) return;
|
||||
if (unawareUser === this.activePokemon && pokemon === this.activeTarget) {
|
||||
boosts['def'] = 0;
|
||||
boosts['spd'] = 0;
|
||||
boosts['evasion'] = 0;
|
||||
}
|
||||
if (pokemon === this.activePokemon && unawareUser === this.activeTarget) {
|
||||
boosts['atk'] = 0;
|
||||
boosts['def'] = 0;
|
||||
boosts['spa'] = 0;
|
||||
boosts['accuracy'] = 0;
|
||||
}
|
||||
},
|
||||
onTryHit(target, source, move) {
|
||||
if (target !== source && move.type === 'Water') {
|
||||
if (!this.heal(target.baseMaxhp / 4)) {
|
||||
this.add('-immune', target, '[from] ability: Still Water');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Still Water",
|
||||
rating: 5,
|
||||
num: -107,
|
||||
shortDesc: "Unaware + Water Absorb",
|
||||
},
|
||||
kingofthehill: {
|
||||
// sharpness + mountaineer + prevents hazard immunity
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (effect && effect.id === 'stealthrock') {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
onTryHit(target, source, move) {
|
||||
if (move.type === 'Rock' && !target.activeTurns) {
|
||||
this.add('-immune', target, '[from] ability: King of the Hill');
|
||||
return null;
|
||||
}
|
||||
},
|
||||
// sharpness
|
||||
onBasePowerPriority: 19,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.flags['slicing']) {
|
||||
this.debug('Sharpness boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
// starts side condition for foes, side condition interacts with hazard effects
|
||||
onStart(pokemon) {
|
||||
this.add('-ability', pokemon, 'King of the Hill');
|
||||
for (const side of pokemon.side.foeSidesWithConditions()) {
|
||||
side.addSideCondition('kingofthehill');
|
||||
}
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
for (const side of pokemon.side.foeSidesWithConditions()) {
|
||||
if (side.getSideCondition('kingofthehill')) {
|
||||
side.removeSideCondition('kingofthehill');
|
||||
}
|
||||
}
|
||||
},
|
||||
condition: {},
|
||||
flags: { breakable: 1 },
|
||||
name: "King of the Hill",
|
||||
rating: 5,
|
||||
num: -108,
|
||||
shortDesc: "Mountaineer + Sharpness. Opponent cannot ignore hazard damage.",
|
||||
},
|
||||
// stockpile on hit
|
||||
omnivore: {
|
||||
onDamagingHitOrder: 1,
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (!target.hp) return;
|
||||
this.add('-activate', target, 'ability: Omnivore');
|
||||
target.addVolatile('stockpile');
|
||||
},
|
||||
flags: {},
|
||||
name: "Omnivore",
|
||||
rating: 5,
|
||||
num: -109,
|
||||
shortDesc: "Gain Stockpile charge when hit by attack.",
|
||||
},
|
||||
// disguise clone
|
||||
pseudowoodo: {
|
||||
onDamagePriority: 1,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (effect?.effectType === 'Move' && ['sudowoodo'].includes(target.species.id)) {
|
||||
this.add('-activate', target, 'ability: Pseudowoodo');
|
||||
this.effectState.rock = true;
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
onCriticalHit(target, source, move) {
|
||||
if (!target) return;
|
||||
if (!['sudowoodo'].includes(target.species.id)) {
|
||||
return;
|
||||
}
|
||||
const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
|
||||
if (hitSub) return;
|
||||
|
||||
if (!target.runImmunity(move.type)) return;
|
||||
return false;
|
||||
},
|
||||
onEffectiveness(typeMod, target, type, move) {
|
||||
if (!target || move.category === 'Status') return;
|
||||
if (!['sudowoodo'].includes(target.species.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
|
||||
if (hitSub) return;
|
||||
|
||||
if (!target.runImmunity(move.type)) return;
|
||||
return 0;
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
if (['sudowoodo'].includes(pokemon.species.id) && this.effectState.rock) {
|
||||
const speciesid = 'Sudowoodo-Rock';
|
||||
pokemon.formeChange(speciesid, this.effect, true);
|
||||
this.damage(pokemon.baseMaxhp / 8, pokemon, pokemon, this.dex.species.get(speciesid));
|
||||
}
|
||||
},
|
||||
flags: {
|
||||
failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1,
|
||||
breakable: 1, notransform: 1,
|
||||
},
|
||||
name: "Pseudowoodo",
|
||||
rating: 5,
|
||||
num: -110,
|
||||
shortDesc: "Disguise. Becomes Rock type when it breaks.",
|
||||
},
|
||||
magicguard: {
|
||||
onDamage(damage, target, source, effect) {
|
||||
// prevents magic guard from blocking hazard damage while King of the Hill is active
|
||||
if (target.side.getSideCondition('kingofthehill')) {
|
||||
const hazards = ['stealthrock', 'spikes', 'toxicspikes', 'stickyweb'];
|
||||
if (effect && hazards.includes(effect.id)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (effect.effectType !== 'Move') {
|
||||
if (effect.effectType === 'Ability') this.add('-activate', source, 'ability: ' + effect.name);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Magic Guard",
|
||||
rating: 4,
|
||||
num: 98,
|
||||
},
|
||||
disguise: {
|
||||
onDamagePriority: 1,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (effect?.effectType === 'Move' && ['mimikyu', 'mimikyutotem'].includes(target.species.id)) {
|
||||
this.add('-activate', target, 'ability: Disguise');
|
||||
this.effectState.busted = true;
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
onCriticalHit(target, source, move) {
|
||||
if (!target) return;
|
||||
if (!['mimikyu', 'mimikyutotem'].includes(target.species.id)) {
|
||||
return;
|
||||
}
|
||||
const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
|
||||
if (hitSub) return;
|
||||
|
||||
if (!target.runImmunity(move.type)) return;
|
||||
return false;
|
||||
},
|
||||
onEffectiveness(typeMod, target, type, move) {
|
||||
if (!target || move.category === 'Status') return;
|
||||
if (!['mimikyu', 'mimikyutotem'].includes(target.species.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hitSub = target.volatiles['substitute'] && !move.flags['bypasssub'] && !(move.infiltrates && this.gen >= 6);
|
||||
if (hitSub) return;
|
||||
|
||||
if (!target.runImmunity(move.type)) return;
|
||||
return 0;
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
if (['mimikyu', 'mimikyutotem'].includes(pokemon.species.id) && this.effectState.busted) {
|
||||
const speciesid = pokemon.species.id === 'mimikyutotem' ? 'Mimikyu-Busted-Totem' : 'Mimikyu-Busted';
|
||||
pokemon.formeChange(speciesid, this.effect, true);
|
||||
this.damage(pokemon.baseMaxhp / 8, pokemon, pokemon, this.dex.species.get(speciesid));
|
||||
}
|
||||
// sets ability to perish body
|
||||
if (pokemon.species.id === 'mimikyubusted' && pokemon.ability === 'disguise') {
|
||||
pokemon.setAbility("Perish Body");
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
}
|
||||
},
|
||||
// cantsuppress flag removed to allow for ability change
|
||||
flags: {
|
||||
failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1,
|
||||
breakable: 1, notransform: 1,
|
||||
},
|
||||
name: "Disguise",
|
||||
rating: 3.5,
|
||||
num: 209,
|
||||
},
|
||||
gulpmissile: {
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
// Storm Drain effect while cramorant-gulping
|
||||
if (target !== source && move.type === 'Water' && target.species.id === 'cramorantgulping') {
|
||||
if (!this.boost({ spa: 1 })) {
|
||||
this.add('-immune', target, '[from] ability: Gulp Missile');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// Lightning Rod effect while cramorant-gorging
|
||||
if (target !== source && move.type === 'Electric' && target.species.id === 'cramorantgorging') {
|
||||
if (!this.boost({ spa: 1 })) {
|
||||
this.add('-immune', target, '[from] ability: Gulp Missile');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return;
|
||||
},
|
||||
},
|
||||
asoneglastrier: {
|
||||
inherit: true,
|
||||
// removing these flags allows Frozen Armor to correctly set Caly-Ice ability as As One
|
||||
flags: {},
|
||||
},
|
||||
protean: {
|
||||
inherit: true,
|
||||
onPrepareHit(source, target, move) {
|
||||
if (move.hasBounced || move.flags['futuremove'] || move.sourceEffect === 'snatch' || move.callsMove) return;
|
||||
const type = move.type;
|
||||
if (type && type !== '???' && source.getTypes().join() !== type) {
|
||||
if (!source.setType(type)) return;
|
||||
this.add('-start', source, 'typechange', type, '[from] ability: Protean');
|
||||
}
|
||||
},
|
||||
rating: 4.5,
|
||||
shortDesc: "Gen 8 Protean.",
|
||||
},
|
||||
berserk: {
|
||||
onUpdate(pokemon) {
|
||||
if (pokemon.species.id !== 'infernape' || !pokemon.hp || pokemon.m.triggeredBerserk) return;
|
||||
if (pokemon.hp < pokemon.maxhp / 2) {
|
||||
this.boost({ spa: 1 }, pokemon, pokemon);
|
||||
pokemon.m.triggeredBerserk = true;
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Berserk",
|
||||
rating: 2,
|
||||
num: 201,
|
||||
},
|
||||
bloodsoakedcrescent: {
|
||||
// modifies atk
|
||||
onStart(pokemon) {
|
||||
this.add('-ability', pokemon, 'Blood-Soaked Crescent');
|
||||
},
|
||||
onModifyAtkPriority: 1,
|
||||
onModifyAtk(atk, pokemon) {
|
||||
if (pokemon.volatiles['dynamax']) return;
|
||||
this.debug('bsc Attack boost');
|
||||
return this.chainModify(1.5);
|
||||
},
|
||||
// ends move lock properly
|
||||
onAfterMove(pokemon) {
|
||||
if (pokemon.volatiles['bloodsoakedcrescent']?.duration === 1) {
|
||||
pokemon.removeVolatile('bloodsoakedcrescent');
|
||||
this.add('-end', pokemon, 'Blood-Soaked Rage');
|
||||
}
|
||||
},
|
||||
// applies move lock
|
||||
onAfterMoveSecondarySelf(pokemon, source, move) {
|
||||
if (move.id === 'dragondance') return;
|
||||
if (!pokemon.volatiles['bloodsoakedcrescent']) {
|
||||
this.add('-start', pokemon, 'Blood-Soaked Rage');
|
||||
}
|
||||
pokemon.addVolatile('bloodsoakedcrescent');
|
||||
},
|
||||
// condition is just lockedmove with some changes
|
||||
condition: {
|
||||
// Outrage, Thrash, Petal Dance...
|
||||
duration: 2,
|
||||
onResidual(target) {
|
||||
if (target.status === 'slp') {
|
||||
// don't lock, and bypass confusion for calming
|
||||
delete target.volatiles['bloodsoakedcrescent'];
|
||||
}
|
||||
this.effectState.trueDuration--;
|
||||
},
|
||||
onStart(target, source, effect) {
|
||||
this.effectState.trueDuration = this.random(2, 4);
|
||||
this.effectState.move = this.activeMove;
|
||||
},
|
||||
onRestart() {
|
||||
if (this.effectState.trueDuration >= 2) {
|
||||
this.effectState.duration = 2;
|
||||
}
|
||||
},
|
||||
onEnd(target) {
|
||||
if (this.effectState.trueDuration > 1) return;
|
||||
target.addVolatile('confusion');
|
||||
},
|
||||
onLockMove(pokemon) {
|
||||
if (pokemon.volatiles['dynamax']) return;
|
||||
return this.effectState.move;
|
||||
},
|
||||
},
|
||||
flags: {},
|
||||
name: "Blood-Soaked Crescent",
|
||||
rating: 5,
|
||||
num: -111,
|
||||
shortDesc: "1.5x Attack, but attacks have the Outrage effect.",
|
||||
},
|
||||
powerspot: {
|
||||
onChargeMove(pokemon, target, move) {
|
||||
this.debug('power spot - remove charge turn for ' + move.id);
|
||||
this.attrLastMove('[still]');
|
||||
this.addMove('-anim', pokemon, move.name, target);
|
||||
return false; // skip charge turn
|
||||
},
|
||||
onAfterMoveSecondarySelf(pokemon, target, move) {
|
||||
if (pokemon.getVolatile('mustrecharge')) {
|
||||
pokemon.removeVolatile('mustrecharge');
|
||||
this.add('-end', pokemon, 'mustrecharge');
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Power Spot",
|
||||
rating: 5,
|
||||
num: 249,
|
||||
shortDesc: "Moves ignore charge/recharge turns.",
|
||||
},
|
||||
biogenesis: {
|
||||
onSwitchInPriority: -1,
|
||||
onBeforeSwitchIn(pokemon) {
|
||||
if (pokemon.m.didRandomMoves) return;
|
||||
const moves = this.dex.moves.all();
|
||||
const newMoves = [];
|
||||
while (newMoves.length < 8) {
|
||||
const newMove = this.sample(moves);
|
||||
if (newMove.basePower === 1) continue;
|
||||
if (newMove.isMax === true) continue;
|
||||
if (newMove.isNonstandard === "Gigantamax") continue;
|
||||
if (newMoves.map(x => x.id).includes(newMove.id)) continue;
|
||||
newMoves.push(newMove);
|
||||
}
|
||||
// Update move slots
|
||||
pokemon.moveSlots = newMoves.map(move => {
|
||||
const moveData = this.dex.moves.get(move);
|
||||
return {
|
||||
move: moveData.name,
|
||||
id: moveData.id,
|
||||
pp: moveData.pp,
|
||||
maxpp: moveData.pp,
|
||||
target: moveData.target,
|
||||
disabled: false,
|
||||
used: false,
|
||||
};
|
||||
});
|
||||
// this forces the UI to update move slots visually
|
||||
(pokemon as any).baseMoveSlots = pokemon.moveSlots.slice();
|
||||
pokemon.m.didRandomMoves = true;
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon) return; // Chat command
|
||||
if (!pokemon.m.hasTypeChanged) {
|
||||
this.add('-ability', pokemon, 'Biogenesis');
|
||||
this.add('-anim', pokemon, 'Growth', pokemon);
|
||||
this.add('-message', `Mew evolves into a new form with its Biogenesis!`);
|
||||
}
|
||||
const attackingMoves = pokemon.baseMoveSlots
|
||||
.map(slot => this.dex.moves.get(slot.id))
|
||||
.filter(move => move.category !== "Status");
|
||||
|
||||
// pick types of first 2 attacking moves (failsafe if there are none)
|
||||
const types = attackingMoves.length ?
|
||||
[...new Set(attackingMoves.slice(0, 2).map(move => move.type))] :
|
||||
pokemon.types;
|
||||
pokemon.setType(types);
|
||||
pokemon.baseTypes = pokemon.types;
|
||||
pokemon.m.hasTypeChanged = true;
|
||||
this.add('-start', pokemon, 'typechange', (pokemon.illusion || pokemon).getTypes(true).join('/'), '[silent]');
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1,
|
||||
breakable: 1, notransform: 1, cantsuppress: 1 },
|
||||
name: "Biogenesis",
|
||||
rating: 5,
|
||||
num: -112,
|
||||
shortDesc: "This Pokemon receives 8 completely random moves at the start of the game.",
|
||||
},
|
||||
orichalcumpulse: {
|
||||
onStart(pokemon) {
|
||||
pokemon.updateMaxHp();
|
||||
if (this.field.setWeather('sunnyday')) {
|
||||
this.add('-activate', pokemon, 'Orichalcum Pulse', '[source]');
|
||||
} else if (this.field.isWeather('sunnyday')) {
|
||||
this.add('-activate', pokemon, 'ability: Orichalcum Pulse');
|
||||
}
|
||||
},
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, pokemon) {
|
||||
if (['sunnyday', 'desolateland'].includes(pokemon.effectiveWeather())) {
|
||||
this.debug('Orichalcum boost');
|
||||
return this.chainModify([5461, 4096]);
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Orichalcum Pulse",
|
||||
rating: 4.5,
|
||||
num: 288,
|
||||
},
|
||||
hailmary: {
|
||||
onStart(pokemon) {
|
||||
this.add('-activate', pokemon, 'ability: Hail Mary');
|
||||
},
|
||||
onModifySpe(spe, pokemon) {
|
||||
if (this.field.isWeather(['hail', 'snowscape'])) {
|
||||
this.debug('hail mary spe boost');
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, pokemon) {
|
||||
if (this.field.isWeather(['hail', 'snowscape'])) {
|
||||
this.debug('hail mary atk boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onSourceModifyAccuracyPriority: -1,
|
||||
onSourceModifyAccuracy(accuracy, target, source, move) {
|
||||
if (this.field.isWeather(['hail', 'snowscape'])) {
|
||||
if (move.category === 'Physical' && typeof accuracy === 'number') {
|
||||
return this.chainModify([3277, 4096]);
|
||||
}
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Hail Mary",
|
||||
rating: 5,
|
||||
num: -113,
|
||||
shortDesc: "In Snowscape: 2x Speed, 1.5x Attack, 0.8x accuracy.",
|
||||
},
|
||||
brainfreeze: {
|
||||
onModifyCritRatio(critRatio, source, target) {
|
||||
if (target && (target.status === 'frostbite' || this.field.isWeather('snowscape'))) return 5;
|
||||
},
|
||||
flags: {},
|
||||
name: "Brain Freeze",
|
||||
rating: 5,
|
||||
num: -114,
|
||||
shortDesc: "If Snowscape or target is Frostbitten, attacks auto Crit.",
|
||||
},
|
||||
neutralizinggas: {
|
||||
inherit: true,
|
||||
onStart(pokemon) {
|
||||
// this makes Neutralizing Gas properly show as activated in the client when Typhlosion Mega evolves
|
||||
this.add('-ability', pokemon, 'Neutralizing Gas');
|
||||
},
|
||||
},
|
||||
terawheel: {
|
||||
onStart(pokemon) {
|
||||
pokemon.canTerastallize = null;
|
||||
},
|
||||
// copied from SSB High Performance Computing
|
||||
onResidualOrder: 6,
|
||||
onResidual(source) {
|
||||
const type = this.sample(this.dex.types.names().filter(i => i !== source.getTypes()[0]));
|
||||
if (source.setType(type)) {
|
||||
this.add('-start', source, 'typechange', type, '[from] ability: Tera Wheel');
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Tera Wheel",
|
||||
rating: 5,
|
||||
num: -115,
|
||||
shortDesc: "End of turn: this Pokemon switches to a random type (including Stellar).",
|
||||
},
|
||||
download: {
|
||||
inherit: true,
|
||||
onUpdate(pokemon) {
|
||||
if (pokemon.species.name === 'Genesect-Burn' && pokemon.terastallized) {
|
||||
pokemon.setAbility('Drought', null, null, true);
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
this.add('-ability', pokemon, 'Drought');
|
||||
}
|
||||
if (pokemon.species.name === 'Genesect-Chill' && pokemon.terastallized) {
|
||||
pokemon.setAbility('Snow Warning', null, null, true);
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
this.add('-ability', pokemon, 'Snow Warning');
|
||||
}
|
||||
if (pokemon.species.name === 'Genesect-Douse' && pokemon.terastallized) {
|
||||
pokemon.setAbility('Drizzle', null, null, true);
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
this.add('-ability', pokemon, 'Drizzle');
|
||||
}
|
||||
if (pokemon.species.name === 'Genesect-Shock' && pokemon.terastallized) {
|
||||
pokemon.setAbility('Electric Surge', null, null, true);
|
||||
pokemon.baseAbility = pokemon.ability;
|
||||
this.add('-ability', pokemon, 'Electric Surge');
|
||||
}
|
||||
},
|
||||
shortDesc: "Download + Gets weather setting move when Tera.",
|
||||
},
|
||||
battlerage: {
|
||||
onDamagingHit(damage, target, source, effect) {
|
||||
this.boost({ atk: 1 });
|
||||
},
|
||||
flags: {},
|
||||
name: "Battle Rage",
|
||||
rating: 5,
|
||||
num: -116,
|
||||
shortDesc: "+1 Atk when hit by an attack.",
|
||||
},
|
||||
terrainshift: {
|
||||
onStart(source) {
|
||||
if (source.hp >= source.maxhp) {
|
||||
source.setType("Electric");
|
||||
this.field.setTerrain('electricterrain');
|
||||
this.add('-start', source, 'typechange', 'Electric', '[silent]');
|
||||
} else if (source.hp >= (2 * source.maxhp) / 3) {
|
||||
source.setType("Fairy");
|
||||
this.field.setTerrain('mistyterrain');
|
||||
this.add('-start', source, 'typechange', 'Fairy', '[silent]');
|
||||
} else if (source.hp >= source.maxhp / 3) {
|
||||
source.setType("Grass");
|
||||
this.field.setTerrain('grassyterrain');
|
||||
this.add('-start', source, 'typechange', 'Grass', '[silent]');
|
||||
} else {
|
||||
source.setType("Psychic");
|
||||
this.field.setTerrain('psychicterrain');
|
||||
this.add('-start', source, 'typechange', 'Psychic', '[silent]');
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Terrain Shift",
|
||||
rating: 5,
|
||||
num: -117,
|
||||
shortDesc: "Sets terrain depending on HP value.",
|
||||
},
|
||||
dragonsjaw: {
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (defender.hasType('Dragon') && defender.hasType('Steel')) {
|
||||
return this.chainModify(1.5);
|
||||
} else if (defender.hasType('Dragon')) {
|
||||
return this.chainModify(2.25);
|
||||
} else if (defender.hasType('Steel')) {
|
||||
return;
|
||||
} else return this.chainModify(1.5);
|
||||
},
|
||||
onTryHit(target, source, move) {
|
||||
if (target.hasType('Fairy')) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
onModifyMovePriority: -2,
|
||||
onModifyMove(move) {
|
||||
if (move.secondaries) {
|
||||
this.debug('doubling secondary chance');
|
||||
for (const secondary of move.secondaries) {
|
||||
if (secondary.chance) secondary.chance *= 2;
|
||||
}
|
||||
}
|
||||
if (move.self?.chance) move.self.chance *= 2;
|
||||
},
|
||||
flags: {},
|
||||
name: "Dragon's Jaw",
|
||||
rating: 5,
|
||||
num: -118,
|
||||
shortDesc: "Serene Grace + Bite attacks are Dragon type.",
|
||||
},
|
||||
corrosivesoul: {
|
||||
onStart(source) {
|
||||
this.field.setTerrain('corrosivesoul');
|
||||
},
|
||||
condition: {
|
||||
effectType: 'Terrain',
|
||||
duration: 5,
|
||||
durationCallback(source, effect) {
|
||||
if (source?.hasItem('terrainextender')) {
|
||||
return 8;
|
||||
}
|
||||
return 5;
|
||||
},
|
||||
onFieldStart(field, source, effect) {
|
||||
if (effect?.effectType === 'Ability') {
|
||||
this.add('-fieldstart', 'move: Corrosive Soul', '[from] ability: ' + effect.name, `[of] ${source}`);
|
||||
} else {
|
||||
this.add('-fieldstart', 'move: Corrosive Soul');
|
||||
}
|
||||
},
|
||||
onResidualOrder: 5,
|
||||
onResidualSubOrder: 2,
|
||||
onResidual(pokemon) {
|
||||
const move = this.dex.getActiveMove('smog');
|
||||
move.accuracy = 100;
|
||||
const target = pokemon.foes()[0];
|
||||
if (target && !target.fainted) {
|
||||
this.actions.useMove(move, pokemon, { target });
|
||||
}
|
||||
},
|
||||
onFieldResidualOrder: 27,
|
||||
onFieldResidualSubOrder: 7,
|
||||
onFieldEnd() {
|
||||
this.add('-fieldend', 'move: Corrosive Soul');
|
||||
},
|
||||
},
|
||||
flags: {},
|
||||
name: "Corrosive Soul",
|
||||
rating: 5,
|
||||
num: -119,
|
||||
shortDesc: "Sets Corrosive Terrian: active Pokemon hit each other with Smog.",
|
||||
},
|
||||
oceanicblessing: {
|
||||
onSwitchInPriority: -2,
|
||||
onStart(pokemon) {
|
||||
this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon);
|
||||
},
|
||||
onWeatherChange(pokemon) {
|
||||
if (!pokemon.isActive || pokemon.baseSpecies.baseSpecies !== 'Kyogre' || pokemon.transformed) return;
|
||||
if (!pokemon.hp) return;
|
||||
if (['raindance', 'primordialsea'].includes(pokemon.effectiveWeather())) {
|
||||
if (pokemon.species.id !== 'kyogreprimal') {
|
||||
pokemon.formeChange('Kyogre-Primal', this.effect, false);
|
||||
}
|
||||
} else {
|
||||
if (pokemon.species.id === 'kyogreprimal') {
|
||||
pokemon.formeChange('kyogre', this.effect, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
onAllyModifyAtkPriority: 3,
|
||||
onAllyModifyAtk(atk, pokemon) {
|
||||
if (this.effectState.target.baseSpecies.baseSpecies !== 'Kyogre') return;
|
||||
if (['raindance', 'primordialsea'].includes(pokemon.effectiveWeather())) {
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onAllyModifySpDPriority: 4,
|
||||
onAllyModifySpD(spd, pokemon) {
|
||||
if (this.effectState.target.baseSpecies.baseSpecies !== 'Kyogre') return;
|
||||
if (['raindance', 'primordialsea'].includes(pokemon.effectiveWeather())) {
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, breakable: 1 },
|
||||
name: "Oceanic Blessing",
|
||||
rating: 5,
|
||||
num: -120,
|
||||
shortDesc: "Flower Gift but Kyogre",
|
||||
},
|
||||
autospin: {
|
||||
onResidual(pokemon, s, effect) {
|
||||
const move = this.dex.getActiveMove('metronome');
|
||||
const target = pokemon.foes()[0];
|
||||
if (target && !target.fainted && (pokemon.hp >= pokemon.maxhp / 2)) {
|
||||
this.actions.useMove(move, pokemon, { target, sourceEffect: effect });
|
||||
} else if (target && !target.fainted && (pokemon.hp <= pokemon.maxhp / 10)) {
|
||||
this.actions.useMove(move, pokemon, { target, sourceEffect: effect });
|
||||
this.actions.useMove(move, pokemon, { target, sourceEffect: effect });
|
||||
this.actions.useMove(move, pokemon, { target, sourceEffect: effect });
|
||||
} else if (target && !target.fainted) {
|
||||
this.actions.useMove(move, pokemon, { target, sourceEffect: effect });
|
||||
this.actions.useMove(move, pokemon, { target, sourceEffect: effect });
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Auto Spin",
|
||||
rating: 5,
|
||||
num: -121,
|
||||
shortDesc: "Use Metronome at end of turn.",
|
||||
},
|
||||
corrosion: {
|
||||
inherit: true,
|
||||
onModifyMovePriority: -5,
|
||||
onModifyMove(move) {
|
||||
if (!move.ignoreImmunity) move.ignoreImmunity = {};
|
||||
if (move.ignoreImmunity !== true) {
|
||||
move.ignoreImmunity['Poison'] = true;
|
||||
}
|
||||
},
|
||||
shortDesc: "This Pokemon can poison a Pokemon regardless of its typing and hit them with Poison moves.",
|
||||
},
|
||||
jellobody: {
|
||||
onTryHit(pokemon, target, move) {
|
||||
if (move.selfSwitch) {
|
||||
this.add('-immune', pokemon, '[from] ability: Jello Body');
|
||||
this.heal(target.baseMaxhp / 2);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
onModifyMove(move, source, target) {
|
||||
move.drain = [1, 2];
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Jello Body",
|
||||
rating: 5,
|
||||
num: -122,
|
||||
shortDesc: "Immune to pivot moves, heals 50% HP when hit by one. All moves drain 50%.",
|
||||
},
|
||||
nibblenibble: {
|
||||
onPrepareHit(source, target, move) {
|
||||
if (move.category === 'Status' || move.multihit || move.flags['noparentalbond'] || move.flags['charge'] ||
|
||||
move.flags['futuremove'] || move.spreadHit || move.isZ || move.isMax || !move.flags['bite']) return;
|
||||
move.multihit = 2;
|
||||
move.multihitType = 'parentalbond';
|
||||
},
|
||||
// Damage modifier implemented in BattleActions#modifyDamage()
|
||||
onSourceModifySecondaries(secondaries, target, source, move) {
|
||||
if (move.multihitType === 'parentalbond' && move.id === 'secretpower' && move.hit < 2) {
|
||||
// hack to prevent accidentally suppressing King's Rock/Razor Fang
|
||||
return secondaries.filter(effect => effect.volatileStatus === 'flinch');
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Nibble Nibble",
|
||||
rating: 5,
|
||||
num: -123,
|
||||
shortDesc: "Parental Bond but for Bite moves.",
|
||||
},
|
||||
};
|
||||
20
data/mods/chatbats/conditions.ts
Normal file
20
data/mods/chatbats/conditions.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDataTable = {
|
||||
frostbite: {
|
||||
name: 'frostbite',
|
||||
effectType: 'Status',
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'Frostbite', '[silent]');
|
||||
this.add('-message', `${target.species.name} is inflicted with frostbite!`);
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
this.add('-start', pokemon, 'Frostbite', '[silent]');
|
||||
},
|
||||
onResidualOrder: 10,
|
||||
onResidual(pokemon) {
|
||||
this.damage(pokemon.baseMaxhp / 16);
|
||||
},
|
||||
onBasePower(basePower, source, target) {
|
||||
return basePower / 2;
|
||||
},
|
||||
},
|
||||
};
|
||||
150
data/mods/chatbats/items.ts
Normal file
150
data/mods/chatbats/items.ts
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
||||
bigroot: {
|
||||
inherit: true,
|
||||
onTryHealPriority: 1,
|
||||
onTryHeal(damage, target, source, effect) {
|
||||
const heals = ['drain', 'leechseed', 'ingrain', 'aquaring', 'strengthsap'];
|
||||
if (heals.includes(effect.id)) {
|
||||
return this.chainModify([6144, 4096]);
|
||||
}
|
||||
},
|
||||
shortDesc: "Holder gains 1.5x HP from draining, Aqua Ring, Ingrain, Leech Seed, Strength Sap.",
|
||||
},
|
||||
masquerainite: {
|
||||
name: "Masquerainite",
|
||||
spritenum: 1,
|
||||
megaStone: { "Masquerain": "Masquerain-Mega" },
|
||||
itemUser: ["Masquerain"],
|
||||
onTakeItem(item, source) {
|
||||
return !item.megaStone?.[source.baseSpecies.baseSpecies];
|
||||
},
|
||||
num: -1,
|
||||
gen: 9,
|
||||
desc: "If held by a Masquerain, this item allows it to Mega Evolve in battle.",
|
||||
},
|
||||
starfberry: {
|
||||
name: "Starf Berry",
|
||||
spritenum: 472,
|
||||
isBerry: true,
|
||||
naturalGift: {
|
||||
basePower: 100,
|
||||
type: "Psychic",
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
if (pokemon.hp <= pokemon.maxhp / 2 ||
|
||||
((pokemon.hp <= pokemon.maxhp / 2 && pokemon.hasAbility('gluttony') && pokemon.abilityState.gluttony))) {
|
||||
pokemon.eatItem();
|
||||
}
|
||||
},
|
||||
onEat(pokemon) {
|
||||
const stats: BoostID[] = [];
|
||||
let stat: BoostID;
|
||||
for (stat in pokemon.boosts) {
|
||||
if (stat !== 'accuracy' && stat !== 'evasion' && pokemon.boosts[stat] < 6) {
|
||||
stats.push(stat);
|
||||
}
|
||||
}
|
||||
if (stats.length) {
|
||||
const randomStat = this.sample(stats);
|
||||
const boost: SparseBoostsTable = {};
|
||||
boost[randomStat] = 2;
|
||||
this.boost(boost);
|
||||
}
|
||||
},
|
||||
num: 207,
|
||||
gen: 3,
|
||||
},
|
||||
typhlosionite: {
|
||||
name: "Typhlosionite",
|
||||
spritenum: 1,
|
||||
megaStone: { "Typhlosion": "Typhlosion-Mega" },
|
||||
itemUser: ["Typhlosion"],
|
||||
onTakeItem(item, source) {
|
||||
return !item.megaStone?.[source.baseSpecies.baseSpecies];
|
||||
},
|
||||
num: -2,
|
||||
gen: 9,
|
||||
desc: "If held by a Typhlosion, this item allows it to Mega Evolve in battle.",
|
||||
},
|
||||
tartapple: {
|
||||
name: "Tart Apple",
|
||||
spritenum: 712,
|
||||
isBerry: true,
|
||||
fling: {
|
||||
basePower: 30,
|
||||
},
|
||||
onBasePowerPriority: 15,
|
||||
onBasePower(basePower, user, target, move) {
|
||||
if (
|
||||
move && (user.baseSpecies.num === 841) &&
|
||||
(move.type === 'Grass' || move.type === 'Ground')
|
||||
) {
|
||||
return this.chainModify([4915, 4096]);
|
||||
}
|
||||
},
|
||||
onUpdate(pokemon) {
|
||||
if (pokemon.hp <= pokemon.maxhp / 2) {
|
||||
pokemon.eatItem();
|
||||
}
|
||||
},
|
||||
onTryEatItem(item, pokemon) {
|
||||
if (!this.runEvent('TryHeal', pokemon, null, this.effect, pokemon.baseMaxhp / 4)) return false;
|
||||
},
|
||||
onEat(pokemon) {
|
||||
this.heal(pokemon.baseMaxhp / 4);
|
||||
},
|
||||
itemUser: ["Flapple"],
|
||||
num: 1117,
|
||||
gen: 8,
|
||||
desc: "Grass- and Ground-type moves have 1.2x power. Restores 1/4 max HP when at 1/2 max HP or less.",
|
||||
},
|
||||
thickclub: {
|
||||
name: "Thick Club",
|
||||
spritenum: 491,
|
||||
fling: {
|
||||
basePower: 130,
|
||||
},
|
||||
onModifyAtkPriority: 1,
|
||||
onModifyAtk(atk, pokemon) {
|
||||
if (pokemon.baseSpecies.baseSpecies === 'Mandibuzz' || pokemon.baseSpecies.baseSpecies === 'Mew') {
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
itemUser: ["Marowak", "Marowak-Alola", "Marowak-Alola-Totem", "Cubone", "Mandibuzz", "Mew"],
|
||||
num: 258,
|
||||
gen: 2,
|
||||
desc: "Doubles Attack.",
|
||||
},
|
||||
focusband: {
|
||||
name: "Focus Band",
|
||||
spritenum: 150,
|
||||
fling: {
|
||||
basePower: 10,
|
||||
},
|
||||
onDamagePriority: -40,
|
||||
onDamage(damage, target, source, effect) {
|
||||
const chance = Math.max(Math.floor(100 - (target.maxhp - target.hp)), 10);
|
||||
if (this.randomChance(chance, 100) && damage >= target.hp && effect && effect.effectType === 'Move') {
|
||||
this.add("-activate", target, "item: Focus Band");
|
||||
return target.hp - 1;
|
||||
} else {
|
||||
return damage;
|
||||
}
|
||||
},
|
||||
num: 230,
|
||||
gen: 2,
|
||||
desc: "Chance to survive attack equal to percentage of remaining HP, minimum 10%.",
|
||||
},
|
||||
raticite: {
|
||||
name: "Raticite",
|
||||
spritenum: 1,
|
||||
megaStone: { "Raticate": "Raticate-Mega" },
|
||||
itemUser: ["Raticate"],
|
||||
onTakeItem(item, source) {
|
||||
return !item.megaStone?.[source.baseSpecies.baseSpecies];
|
||||
},
|
||||
num: -3,
|
||||
gen: 9,
|
||||
desc: "If held by a Raticate, this item allows it to Mega Evolve in battle.",
|
||||
},
|
||||
};
|
||||
1752
data/mods/chatbats/moves.ts
Normal file
1752
data/mods/chatbats/moves.ts
Normal file
File diff suppressed because it is too large
Load Diff
514
data/mods/chatbats/pokedex.ts
Normal file
514
data/mods/chatbats/pokedex.ts
Normal file
|
|
@ -0,0 +1,514 @@
|
|||
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
|
||||
volcarona: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Fluffy" },
|
||||
},
|
||||
golemalola: {
|
||||
inherit: true,
|
||||
},
|
||||
lurantis: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 85, atk: 105, def: 90, spa: 95, spd: 90, spe: 75 },
|
||||
},
|
||||
ironcrown: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Queenly Majesty", H: "Battle Armor" },
|
||||
},
|
||||
mamoswine: {
|
||||
inherit: true,
|
||||
},
|
||||
ceruledge: {
|
||||
inherit: true,
|
||||
},
|
||||
carbink: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Magic Bounce" },
|
||||
},
|
||||
moltres: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Magic Guard" },
|
||||
},
|
||||
kommoo: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 75, atk: 100, def: 125, spa: 110, spd: 105, spe: 85 },
|
||||
abilities: { 0: "Punk Rock" },
|
||||
},
|
||||
illumise: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Call Volbeat" },
|
||||
},
|
||||
volbeat: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Call Illumise" },
|
||||
},
|
||||
abomasnow: {
|
||||
inherit: true,
|
||||
},
|
||||
abomasnowmega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 90, atk: 132, def: 105, spa: 92, spd: 105, spe: 70 },
|
||||
abilities: { 0: "Slush Rush" },
|
||||
},
|
||||
dugtrio: {
|
||||
inherit: true,
|
||||
},
|
||||
altaria: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Fluffy" },
|
||||
},
|
||||
altariamega: {
|
||||
inherit: true,
|
||||
},
|
||||
tyranitar: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Sand Stream", H: "Sharpness" },
|
||||
},
|
||||
tyranitarmega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 100, atk: 114, def: 150, spa: 155, spd: 110, spe: 71 },
|
||||
types: ["Rock", "Dragon"],
|
||||
},
|
||||
mimikyu: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 65, atk: 110, def: 80, spa: 50, spd: 105, spe: 96 },
|
||||
},
|
||||
mimikyubusted: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Perish Body" },
|
||||
baseStats: { hp: 65, atk: 90, def: 80, spa: 50, spd: 105, spe: 116 },
|
||||
},
|
||||
mesprit: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Liquid Voice" },
|
||||
types: ["Psychic", "Water"],
|
||||
},
|
||||
electrode: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Short Fuse" },
|
||||
types: ["Electric", "Normal"],
|
||||
},
|
||||
taurospaldeacombat: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Adaptability" },
|
||||
},
|
||||
chiyu: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Water Absorb" },
|
||||
baseStats: { hp: 55, atk: 135, def: 80, spa: 80, spd: 120, spe: 100 },
|
||||
},
|
||||
wochien: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Liquid Ooze" },
|
||||
types: ["Grass", "Water"],
|
||||
},
|
||||
staraptor: {
|
||||
inherit: true,
|
||||
types: ["Flying"],
|
||||
},
|
||||
archaludon: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Hydroelectric Dam", 1: "Stamina" },
|
||||
},
|
||||
malamar: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Flip Flop" },
|
||||
baseStats: { hp: 86, atk: 92, def: 88, spa: 88, spd: 75, spe: 73 },
|
||||
},
|
||||
empoleon: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Sharpness" },
|
||||
types: ["Water", "Steel", "Flying"],
|
||||
},
|
||||
glastrier: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Frozen Armor" },
|
||||
},
|
||||
calyrexice: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 100, atk: 165, def: 130, spa: 85, spd: 110, spe: 90 },
|
||||
},
|
||||
regieleki: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Galvanize" },
|
||||
},
|
||||
lycanrocmidnight: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Technician" },
|
||||
},
|
||||
lycanroc: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Drought" },
|
||||
},
|
||||
lycanrocdusk: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Strong Jaw" },
|
||||
},
|
||||
dodrio: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Speed Boost" },
|
||||
types: ["Flying", "Fighting"],
|
||||
},
|
||||
whiscash: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
baseStats: { hp: 110, atk: 78, def: 88, spa: 76, spd: 86, spe: 60 },
|
||||
},
|
||||
hippowdon: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Earth Eater" },
|
||||
},
|
||||
cramorant: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 90, atk: 85, def: 75, spa: 85, spd: 95, spe: 85 },
|
||||
},
|
||||
cramorantgulping: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 90, atk: 85, def: 75, spa: 85, spd: 95, spe: 85 },
|
||||
abilities: { 0: "Storm Drain" },
|
||||
},
|
||||
cramorantgorging: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 90, atk: 85, def: 75, spa: 85, spd: 95, spe: 85 },
|
||||
abilities: { 0: "Lightning Rod" },
|
||||
},
|
||||
grafaiai: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 83, atk: 95, def: 65, spa: 80, spd: 72, spe: 110 },
|
||||
},
|
||||
tatsugiri: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Regenerator" },
|
||||
baseStats: { hp: 78, atk: 50, def: 70, spa: 120, spd: 95, spe: 82 },
|
||||
},
|
||||
kyurem: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Skill Link" },
|
||||
},
|
||||
roaringmoon: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Shadow Shield" },
|
||||
},
|
||||
milotic: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Aqua Veil" },
|
||||
types: ["Water", "Fairy"],
|
||||
},
|
||||
gogoat: {
|
||||
inherit: true,
|
||||
types: ["Grass", "Rock"],
|
||||
},
|
||||
clodsire: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Still Water" },
|
||||
},
|
||||
masquerain: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Intimidate" },
|
||||
},
|
||||
masquerainmega: {
|
||||
num: -999,
|
||||
name: "Masquerain-Mega",
|
||||
baseSpecies: "Masquerain",
|
||||
forme: "Mega",
|
||||
types: ["Bug", "Dark"],
|
||||
genderRatio: { M: 0.5, F: 0.5 },
|
||||
baseStats: { hp: 70, atk: 60, def: 82, spa: 140, spd: 82, spe: 120 },
|
||||
abilities: { 0: "Primordial Sea" },
|
||||
heightm: 0.8,
|
||||
weightkg: 3.6,
|
||||
color: "Blue",
|
||||
eggGroups: ["Water 1", "Bug"],
|
||||
requiredItem: "Masquerainite",
|
||||
},
|
||||
kyuremblack: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Teravolt" },
|
||||
types: ["Dragon", "Ice", "Electric"],
|
||||
},
|
||||
ironthorns: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Iron Barbs" },
|
||||
},
|
||||
dudunsparce: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Earth Eater" },
|
||||
types: ["Normal", "Ground"],
|
||||
},
|
||||
dudunsparcethreesegment: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Earth Eater" },
|
||||
types: ["Normal", "Ground"],
|
||||
},
|
||||
chienpao: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Tablets of Ruin" },
|
||||
},
|
||||
pelipper: {
|
||||
inherit: true,
|
||||
},
|
||||
kleavor: {
|
||||
inherit: true,
|
||||
abilities: { 0: "King of the Hill" },
|
||||
baseStats: { hp: 120, atk: 135, def: 95, spa: 45, spd: 75, spe: 85 },
|
||||
},
|
||||
araquanid: {
|
||||
inherit: true,
|
||||
},
|
||||
avalugghisui: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Multiscale" },
|
||||
baseStats: { hp: 95, atk: 127, def: 184, spa: 68, spd: 72, spe: 76 },
|
||||
},
|
||||
swalot: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Omnivore" },
|
||||
},
|
||||
zapdosgalar: {
|
||||
inherit: true,
|
||||
types: ["Electric", "Fighting"],
|
||||
},
|
||||
phione: {
|
||||
inherit: true,
|
||||
},
|
||||
sudowoodo: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Pseudowoodo" },
|
||||
types: ["Grass"],
|
||||
baseForme: "Grass",
|
||||
otherFormes: ["Sudowoodo-Rock"],
|
||||
formeOrder: ["Sudowoodo", "Sudowoodo-Rock"],
|
||||
},
|
||||
sudowoodorock: {
|
||||
num: 185,
|
||||
name: "Sudowoodo-Rock",
|
||||
baseSpecies: "Sudowoodo",
|
||||
forme: "Rock",
|
||||
types: ["Rock"],
|
||||
baseStats: { hp: 70, atk: 100, def: 110, spa: 30, spd: 65, spe: 30 },
|
||||
abilities: { 0: "Pseudowoodo" },
|
||||
heightm: 1.7,
|
||||
weightkg: 38,
|
||||
color: "Brown",
|
||||
eggGroups: ["Mineral"],
|
||||
requiredAbility: "Pseudowoodo",
|
||||
battleOnly: "Sudowoodo",
|
||||
},
|
||||
dondozo: {
|
||||
inherit: true,
|
||||
},
|
||||
golurk: {
|
||||
inherit: true,
|
||||
},
|
||||
meowscarada: {
|
||||
inherit: true,
|
||||
},
|
||||
infernape: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Berserk" },
|
||||
},
|
||||
salamence: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Aerilate" },
|
||||
},
|
||||
salamencemega: {
|
||||
num: 373,
|
||||
name: "Salamence-Mega",
|
||||
baseSpecies: "Salamence",
|
||||
forme: "Mega",
|
||||
types: ["Dragon", "Flying"],
|
||||
baseStats: { hp: 95, atk: 145, def: 130, spa: 120, spd: 90, spe: 120 },
|
||||
abilities: { 0: "Blood-Soaked Crescent" },
|
||||
heightm: 1.8,
|
||||
weightkg: 112.6,
|
||||
color: "Blue",
|
||||
eggGroups: ["Dragon"],
|
||||
requiredItem: "Salamencite",
|
||||
},
|
||||
urshifu: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Sniper" },
|
||||
},
|
||||
urshifurapidstrike: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Sniper" },
|
||||
},
|
||||
stonjourner: {
|
||||
inherit: true,
|
||||
},
|
||||
veluza: {
|
||||
inherit: true,
|
||||
types: ["Water", "Ghost"],
|
||||
},
|
||||
ogerponhearthflame: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Intimidate" },
|
||||
},
|
||||
dachsbun: {
|
||||
inherit: true,
|
||||
},
|
||||
koraidon: {
|
||||
inherit: true,
|
||||
},
|
||||
mew: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Biogenesis" },
|
||||
},
|
||||
magneton: {
|
||||
inherit: true,
|
||||
},
|
||||
delibird: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Hail Mary" },
|
||||
baseStats: { hp: 45, atk: 90, def: 45, spa: 65, spd: 45, spe: 136 },
|
||||
},
|
||||
articunogalar: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Brain Freeze" },
|
||||
},
|
||||
vaporeon: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Marvel Scale" },
|
||||
},
|
||||
jolteon: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Quick Feet" },
|
||||
},
|
||||
flareon: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Guts" },
|
||||
baseStats: { hp: 65, atk: 130, def: 65, spa: 60, spd: 110, spe: 95 },
|
||||
},
|
||||
garganacl: {
|
||||
inherit: true,
|
||||
},
|
||||
swanna: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Serene Grace" },
|
||||
baseStats: { hp: 75, atk: 117, def: 93, spa: 117, spd: 93, spe: 128 },
|
||||
},
|
||||
typhlosion: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Magic Guard" },
|
||||
},
|
||||
typhlosionmega: {
|
||||
num: -998,
|
||||
name: "Typhlosion-Mega",
|
||||
baseSpecies: "Typhlosion",
|
||||
forme: "Mega",
|
||||
types: ["Fire", "Water"],
|
||||
genderRatio: { M: 0.5, F: 0.5 },
|
||||
baseStats: { hp: 78, atk: 103, def: 98, spa: 140, spd: 115, spe: 100 },
|
||||
abilities: { 0: "Neutralizing Gas" },
|
||||
heightm: 1.7,
|
||||
weightkg: 84.5,
|
||||
color: "Blue",
|
||||
eggGroups: ["Field"],
|
||||
requiredItem: "Typhlosionite",
|
||||
},
|
||||
terapagos: {
|
||||
inherit: true,
|
||||
},
|
||||
terapagosterastal: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Tera Wheel" },
|
||||
},
|
||||
terapagosstellar: {
|
||||
inherit: true,
|
||||
types: ["Stellar"],
|
||||
},
|
||||
flapple: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Ripen" },
|
||||
types: ["Grass", "Ground"],
|
||||
},
|
||||
genesect: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Download" },
|
||||
},
|
||||
honchkrow: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Supreme Overlord" },
|
||||
baseStats: { hp: 100, atk: 125, def: 52, spa: 125, spd: 52, spe: 71 },
|
||||
},
|
||||
primeape: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Battle Rage" },
|
||||
},
|
||||
rillaboom: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Terrain Shift" },
|
||||
},
|
||||
mandibuzz: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Weak Armor" },
|
||||
types: ["Dark", "Ground"],
|
||||
},
|
||||
feraligatr: {
|
||||
inherit: true,
|
||||
},
|
||||
feraligatrmega: {
|
||||
num: -988,
|
||||
name: "Feraligatr-Mega",
|
||||
baseSpecies: "Feraligatr",
|
||||
forme: "Mega",
|
||||
types: ["Dragon"],
|
||||
genderRatio: { M: 0.875, F: 0.125 },
|
||||
baseStats: { hp: 85, atk: 145, def: 120, spa: 99, spd: 103, spe: 78 },
|
||||
abilities: { 0: "Dragon's Jaw" },
|
||||
heightm: 2.3,
|
||||
weightkg: 108.8,
|
||||
color: "Blue",
|
||||
eggGroups: ["Monster", "Water 1"],
|
||||
requiredItem: "Feraligite",
|
||||
gen: 9,
|
||||
},
|
||||
salazzle: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Corrosive Soul" },
|
||||
},
|
||||
kyogre: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Oceanic Blessing" },
|
||||
},
|
||||
azelf: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Auto Spin" },
|
||||
types: ["Psychic", "Normal"],
|
||||
},
|
||||
decidueye: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Overgrow", 1: "Sniper" },
|
||||
},
|
||||
ogerponcornerstone: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Solid Rock" },
|
||||
},
|
||||
glimmora: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Corrosion" },
|
||||
},
|
||||
wobbuffet: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Jello Body" },
|
||||
},
|
||||
raticate: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Hustle" },
|
||||
baseStats: { hp: 90, atk: 81, def: 60, spa: 50, spd: 70, spe: 97 },
|
||||
},
|
||||
raticatemega: {
|
||||
num: -977,
|
||||
name: "Raticate-Mega",
|
||||
baseSpecies: "Raticate",
|
||||
forme: "Mega",
|
||||
types: ["Normal", "Ghost"],
|
||||
genderRatio: { M: 0.5, F: 0.5 },
|
||||
baseStats: { hp: 90, atk: 105, def: 60, spa: 50, spd: 70, spe: 173 },
|
||||
abilities: { 0: "Nibble Nibble" },
|
||||
heightm: 0.7,
|
||||
weightkg: 5,
|
||||
color: "Black",
|
||||
eggGroups: ["Field"],
|
||||
requiredItem: "Raticite",
|
||||
},
|
||||
};
|
||||
304
data/mods/chatbats/scripts.ts
Normal file
304
data/mods/chatbats/scripts.ts
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
gen: 9,
|
||||
|
||||
init() {
|
||||
this.modData('Learnsets', 'lurantis').learnset.icehammer = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'ironcrown').learnset.kingsshield = ['9L1'];
|
||||
this.modData('Learnsets', 'ironcrown').learnset.bodypress = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'carbink').learnset.moonlight = ['9L1'];
|
||||
this.modData('Learnsets', 'carbink').learnset.voltswitch = ['9L1'];
|
||||
this.modData('Learnsets', 'carbink').learnset.spikes = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'moltres').learnset.woodhammer = ['9L1'];
|
||||
this.modData('Learnsets', 'moltres').learnset.wavecrash = ['9L1'];
|
||||
this.modData('Learnsets', 'moltres').learnset.defog = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'kommoo').learnset.aurasphere = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'illumise').learnset.quiverdance = ['9L1'];
|
||||
this.modData('Learnsets', 'illumise').learnset.thunderbolt = ['9L1'];
|
||||
this.modData('Learnsets', 'illumise').learnset.icebeam = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'volbeat').learnset.victorydance = ['9L1'];
|
||||
this.modData('Learnsets', 'volbeat').learnset.mightycleave = ['9L1'];
|
||||
this.modData('Learnsets', 'volbeat').learnset.earthquake = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'abomasnow').learnset.glaciallance = ['9L1'];
|
||||
this.modData('Learnsets', 'abomasnow').learnset.appleacid = ['9L1'];
|
||||
this.modData('Learnsets', 'abomasnow').learnset.partingshot = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'dugtrio').learnset.mightycleave = ['9L1'];
|
||||
this.modData('Learnsets', 'dugtrio').learnset.saltcure = ['9L1'];
|
||||
this.modData('Learnsets', 'dugtrio').learnset.acrobatics = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'altaria').learnset.beakblast = ['9L1'];
|
||||
this.modData('Learnsets', 'altaria').learnset.return = ['9L1'];
|
||||
this.modData('Learnsets', 'altaria').learnset.explosion = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'tyranitar').learnset.stoneaxe = ['9L1'];
|
||||
this.modData('Learnsets', 'tyranitar').learnset.ceaselessedge = ['9L1'];
|
||||
this.modData('Learnsets', 'tyranitar').learnset.kowtowcleave = ['9L1'];
|
||||
this.modData('Learnsets', 'tyranitar').learnset.pursuit = ['9L1'];
|
||||
this.modData('Learnsets', 'tyranitar').learnset.switcheroo = ['9L1'];
|
||||
this.modData('Learnsets', 'tyranitar').learnset.accelerock = ['9L1'];
|
||||
this.modData('Learnsets', 'tyranitar').learnset.dracometeor = ['9L1'];
|
||||
this.modData('Learnsets', 'tyranitar').learnset.mysticalpower = ['9L1'];
|
||||
this.modData('Learnsets', 'tyranitar').learnset.sandsearstorm = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'mimikyu').learnset.spiritshackle = ['9L1'];
|
||||
this.modData('Learnsets', 'mimikyu').learnset.uturn = ['9L1'];
|
||||
this.modData('Learnsets', 'mimikyu').learnset.obstruct = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'mesprit').learnset.agility = ['9L1'];
|
||||
this.modData('Learnsets', 'mesprit').learnset.storedpower = ['9L1'];
|
||||
this.modData('Learnsets', 'mesprit').learnset.torchsong = ['9L1'];
|
||||
this.modData('Learnsets', 'mesprit').learnset.cosmicpower = ['9L1'];
|
||||
this.modData('Learnsets', 'mesprit').learnset.aquaring = ['9L1'];
|
||||
this.modData('Learnsets', 'mesprit').learnset.freezedry = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'electrode').learnset.encore = ['9L1'];
|
||||
this.modData('Learnsets', 'electrode').learnset.rapidspin = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'taurospaldeacombat').learnset.extremespeed = ['9L1'];
|
||||
this.modData('Learnsets', 'taurospaldeacombat').learnset.uturn = ['9L1'];
|
||||
this.modData('Learnsets', 'taurospaldeacombat').learnset.knockoff = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'chiyu').learnset.splash = ['9L1'];
|
||||
this.modData('Learnsets', 'chiyu').learnset.tripledive = ['9L1'];
|
||||
this.modData('Learnsets', 'chiyu').learnset.pyroball = ['9L1'];
|
||||
this.modData('Learnsets', 'chiyu').learnset.knockoff = ['9L1'];
|
||||
this.modData('Learnsets', 'chiyu').learnset.suckerpunch = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'wochien').learnset.partingshot = ['9L1'];
|
||||
this.modData('Learnsets', 'wochien').learnset.strengthsap = ['9L1'];
|
||||
this.modData('Learnsets', 'wochien').learnset.bouncingbubble = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'staraptor').learnset.jumpkick = ['9L1'];
|
||||
this.modData('Learnsets', 'staraptor').learnset.flareblitz = ['9L1'];
|
||||
this.modData('Learnsets', 'staraptor').learnset.wavecrash = ['9L1'];
|
||||
this.modData('Learnsets', 'staraptor').learnset.headsmash = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'archaludon').learnset.scald = ['9L1'];
|
||||
this.modData('Learnsets', 'archaludon').learnset.hydropump = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'malamar').learnset.willowisp = ['9L1'];
|
||||
this.modData('Learnsets', 'malamar').learnset.recover = ['9L1'];
|
||||
this.modData('Learnsets', 'malamar').learnset.eeriespell = ['9L1'];
|
||||
this.modData('Learnsets', 'malamar').learnset.sweetkiss = ['9L1'];
|
||||
this.modData('Learnsets', 'malamar').learnset.spiritbreak = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'empoleon').learnset.nastyplot = ['9L1'];
|
||||
this.modData('Learnsets', 'empoleon').learnset.watershuriken = ['9L1'];
|
||||
this.modData('Learnsets', 'empoleon').learnset.tachyoncutter = ['9L1'];
|
||||
this.modData('Learnsets', 'empoleon').learnset.secretsword = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'regieleki').learnset.blazingtorque = ['9L1'];
|
||||
this.modData('Learnsets', 'regieleki').learnset.soak = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'lycanrocmidnight').learnset.accelerock = ['9L1'];
|
||||
this.modData('Learnsets', 'lycanrocmidnight').learnset.bonerush = ['9L1'];
|
||||
this.modData('Learnsets', 'lycanrocmidnight').learnset.stormthrow = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'lycanroc').learnset.firelash = ['9L1'];
|
||||
this.modData('Learnsets', 'lycanroc').learnset.uturn = ['9L1'];
|
||||
this.modData('Learnsets', 'lycanroc').learnset.spikes = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'lycanrocdusk').learnset.mountainmaw = ['9L1'];
|
||||
this.modData('Learnsets', 'lycanrocdusk').learnset.icefang = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'dodrio').learnset.triplearrows = ['9L1'];
|
||||
this.modData('Learnsets', 'dodrio').learnset.obstruct = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'whiscash').learnset.toxic = ['9L1'];
|
||||
this.modData('Learnsets', 'whiscash').learnset.flipturn = ['9L1'];
|
||||
this.modData('Learnsets', 'whiscash').learnset.scald = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'hippowdon').learnset.saltcure = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'cramorant').learnset.beakblast = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'grafaiai').learnset.bulkup = ['9L1'];
|
||||
this.modData('Learnsets', 'grafaiai').learnset.scavenge = ['9L1'];
|
||||
this.modData('Learnsets', 'grafaiai').learnset.drainpunch = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'kyurem').learnset.earthquake = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'roaringmoon').learnset.firelash = ['9L1'];
|
||||
this.modData('Learnsets', 'roaringmoon').learnset.glaiverush = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'milotic').learnset.bouncybubble = ['9L1'];
|
||||
this.modData('Learnsets', 'milotic').learnset.moonblast = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'gogoat').learnset.headsmash = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'clodsire').learnset.barbbarrage = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'masquerain').learnset.roost = ['9L1'];
|
||||
this.modData('Learnsets', 'masquerain').learnset.darkpulse = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'kyuremblack').learnset.icehammer = ['9L1'];
|
||||
this.modData('Learnsets', 'kyuremblack').learnset.dragonhammer = ['9L1'];
|
||||
this.modData('Learnsets', 'kyuremblack').learnset.roost = ['9L1'];
|
||||
this.modData('Learnsets', 'kyuremblack').learnset.earthquake = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'ironthorns').learnset.ironstrike = ['9L1'];
|
||||
this.modData('Learnsets', 'ironthorns').learnset.knockoff = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'chienpao').learnset.bulkup = ['9L1'];
|
||||
this.modData('Learnsets', 'chienpao').learnset.iciclestorm = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'pelipper').learnset.bleakwindstorm = ['9L1'];
|
||||
this.modData('Learnsets', 'pelipper').learnset.sandsearstorm = ['9L1'];
|
||||
this.modData('Learnsets', 'pelipper').learnset.wildboltstorm = ['9L1'];
|
||||
this.modData('Learnsets', 'pelipper').learnset.springtidestorm = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'araquanid').learnset.surgingstrikes = ['9L1'];
|
||||
this.modData('Learnsets', 'araquanid').learnset.flipturn = ['9L1'];
|
||||
this.modData('Learnsets', 'araquanid').learnset.silktrap = ['9L1'];
|
||||
this.modData('Learnsets', 'araquanid').learnset.firstimpression = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'avalugghisui').learnset.mountainmaw = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'swalot').learnset.earthpower = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'zapdosgalar').learnset.wildcharge = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'phione').learnset.workup = ['9L1'];
|
||||
this.modData('Learnsets', 'phione').learnset.tidalsurge = ['9L1'];
|
||||
this.modData('Learnsets', 'phione').learnset.geyser = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'sudowoodo').learnset.bonsaibounce = ['9L1'];
|
||||
this.modData('Learnsets', 'sudowoodo').learnset.synthesis = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'dondozo').learnset.hornleech = ['9L1'];
|
||||
this.modData('Learnsets', 'dondozo').learnset.fishiousrend = ['9L1'];
|
||||
this.modData('Learnsets', 'dondozo').learnset.recover = ['9L1'];
|
||||
this.modData('Learnsets', 'dondozo').learnset.flipturn = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'golurk').learnset.shatteredseal = ['9L1'];
|
||||
this.modData('Learnsets', 'golurk').learnset.trickroom = ['9L1'];
|
||||
this.modData('Learnsets', 'golurk').learnset.headlongrush = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'meowscarada').learnset.encore = ['9L1'];
|
||||
this.modData('Learnsets', 'meowscarada').learnset.spectralthief = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'infernape').learnset.alloutassault = ['9L1'];
|
||||
this.modData('Learnsets', 'infernape').learnset.mindblown = ['9L1'];
|
||||
this.modData('Learnsets', 'infernape').learnset.bitterblade = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'salamence').learnset.uturn = ['9L1'];
|
||||
this.modData('Learnsets', 'salamence').learnset.dragonascent = ['9L1'];
|
||||
this.modData('Learnsets', 'salamence').learnset.bloodmoon = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'urshifu').learnset.agility = ['9L1'];
|
||||
this.modData('Learnsets', 'urshifu').learnset.aquajet = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'urshifurapidstrike').learnset.agility = ['9L1'];
|
||||
this.modData('Learnsets', 'urshifurapidstrike').learnset.suckerpunch = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'stonjourner').learnset.rockwrecker = ['9L1'];
|
||||
this.modData('Learnsets', 'stonjourner').learnset.meteorassault = ['9L1'];
|
||||
this.modData('Learnsets', 'stonjourner').learnset.skyattack = ['9L1'];
|
||||
this.modData('Learnsets', 'stonjourner').learnset.solarblade = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'veluza').learnset.ragefist = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'ogerpon').learnset.leafblade = ['9L1'];
|
||||
this.modData('Learnsets', 'ogerpon').learnset.crabhammer = ['9L1'];
|
||||
this.modData('Learnsets', 'ogerpon').learnset.stoneedge = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'dachsbun').learnset.nuzzle = ['9L1'];
|
||||
this.modData('Learnsets', 'dachsbun').learnset.spiritbreak = ['9L1'];
|
||||
this.modData('Learnsets', 'dachsbun').learnset.morningsun = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'magneton').learnset.magnetbomb = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'delibird').learnset.iciclestorm = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'hitmontop').learnset.bulletseed = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'articunogalar').learnset.aeroblast = ['9L1'];
|
||||
this.modData('Learnsets', 'articunogalar').learnset.oblivionwing = ['9L1'];
|
||||
this.modData('Learnsets', 'articunogalar').learnset.aurasphere = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'vaporeon').learnset.voltswitch = ['9L1'];
|
||||
this.modData('Learnsets', 'vaporeon').learnset.burnout = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'garganacl').learnset.thunderwave = ['9L1'];
|
||||
this.modData('Learnsets', 'garganacl').learnset.saltcurse = ['9L1'];
|
||||
this.modData('Learnsets', 'garganacl').learnset.purify = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'swanna').learnset.bleakwindstorm = ['9L1'];
|
||||
this.modData('Learnsets', 'swanna').learnset.steameruption = ['9L1'];
|
||||
this.modData('Learnsets', 'swanna').learnset.flyby = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'typhlosion').learnset.heatsink = ['9L1'];
|
||||
this.modData('Learnsets', 'typhlosion').learnset.steameruption = ['9L1'];
|
||||
this.modData('Learnsets', 'typhlosion').learnset.matchagotcha = ['9L1'];
|
||||
this.modData('Learnsets', 'typhlosion').learnset.calmmind = ['9L1'];
|
||||
this.modData('Learnsets', 'typhlosion').learnset.morningsun = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'terapagos').learnset.nastyplot = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'tatsugiri').learnset.switcheroo = ['9L1'];
|
||||
this.modData('Learnsets', 'tatsugiri').learnset.sashimishuffle = ['9L1'];
|
||||
this.modData('Learnsets', 'tatsugiri').learnset.twister = ['9L1'];
|
||||
this.modData('Learnsets', 'tatsugiri').learnset.waterspout = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'flapple').learnset.earthquake = ['9L1'];
|
||||
this.modData('Learnsets', 'flapple').learnset.grabapple = ['9L1'];
|
||||
this.modData('Learnsets', 'flapple').learnset.flareblitz = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'genesect').learnset.earthquake = ['9L1'];
|
||||
this.modData('Learnsets', 'genesect').learnset.sunsteelstrike = ['9L1'];
|
||||
this.modData('Learnsets', 'genesect').learnset.behemothblade = ['9L1'];
|
||||
this.modData('Learnsets', 'genesect').learnset.makeitrain = ['9L1'];
|
||||
this.modData('Learnsets', 'genesect').learnset.tachyoncutter = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'honchkrow').learnset.crowverload = ['9L1'];
|
||||
this.modData('Learnsets', 'honchkrow').learnset.oblivionwing = ['9L1'];
|
||||
this.modData('Learnsets', 'honchkrow').learnset.closecombat = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'primeape').learnset.knockoff = ['9L1'];
|
||||
this.modData('Learnsets', 'primeape').learnset.ironhead = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'rillaboom').learnset.naturesfury = ['9L1'];
|
||||
this.modData('Learnsets', 'rillaboom').learnset.landswrath = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'mandibuzz').learnset.fling = ['9L1'];
|
||||
this.modData('Learnsets', 'mandibuzz').learnset.scavenge = ['9L1'];
|
||||
this.modData('Learnsets', 'mandibuzz').learnset.bonemerang = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'feraligatr').learnset.firefang = ['9L1'];
|
||||
this.modData('Learnsets', 'feraligatr').learnset.thunderfang = ['9L1'];
|
||||
this.modData('Learnsets', 'feraligatr').learnset.poisonfang = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'salazzle').learnset.magmastorm = ['9L1'];
|
||||
this.modData('Learnsets', 'salazzle').learnset.malignantchain = ['9L1'];
|
||||
this.modData('Learnsets', 'salazzle').learnset.psychicnoise = ['9L1'];
|
||||
this.modData('Learnsets', 'salazzle').learnset.banefulbunker = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'kyogre').learnset.hurricane = ['9L1'];
|
||||
this.modData('Learnsets', 'kyogre').learnset.tidalsurge = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'azelf').learnset.rapidspin = ['9L1'];
|
||||
this.modData('Learnsets', 'azelf').learnset.lootbox = ['9L1'];
|
||||
this.modData('Learnsets', 'azelf').learnset.acupressure = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'decidueye').learnset.sinisterarrows = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'ogerpon').learnset.sappyseed = ['9L1'];
|
||||
this.modData('Learnsets', 'ogerpon').learnset.thousandwaves = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'glimmora').learnset.icebeam = ['9L1'];
|
||||
this.modData('Learnsets', 'glimmora').learnset.malignantchain = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'wobbuffet').learnset.nightshade = ['9L1'];
|
||||
this.modData('Learnsets', 'wobbuffet').learnset.guillotine = ['9L1'];
|
||||
this.modData('Learnsets', 'wobbuffet').learnset.shedtail = ['9L1'];
|
||||
|
||||
this.modData('Learnsets', 'raticate').learnset.lastbreakfast = ['9L1'];
|
||||
},
|
||||
};
|
||||
|
|
@ -15,10 +15,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
move.hit = 0;
|
||||
}
|
||||
|
||||
if (!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) {
|
||||
if (!target.runImmunity(move.type, !suppressMessages)) {
|
||||
return false;
|
||||
}
|
||||
if (!target.runImmunity(move, !suppressMessages)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (move.ohko) return target.maxhp;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ There were only 151 Pokémon plus MissingNo, just a handful of moves, no abiliti
|
|||
EVd to the max and we had some kind of different IVs, which maxed at 15 and every point gave 2 to the stat, so in
|
||||
a similar fashion, Pokes used to have 30 IVs on each stat.
|
||||
|
||||
The following sources have been used and extremly useful when developing this mod:
|
||||
The following sources have been used and extremely useful when developing this mod:
|
||||
https://raw.github.com/po-devs/pokemon-online/master/bin/database/rby-stuff.txt
|
||||
https://www.smogon.com/rb/articles/differences
|
||||
https://www.smogon.com/forums/threads/past-gens-research-thread.3506992/#post-5878612
|
||||
|
|
|
|||
|
|
@ -185,38 +185,98 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
},
|
||||
partiallytrapped: {
|
||||
name: 'partiallytrapped',
|
||||
// this is the duration of Wrap if it doesn't continue.
|
||||
// (i.e. if the attacker switches out.)
|
||||
// the full duration is tracked in partialtrappinglock
|
||||
duration: 2,
|
||||
// defender still takes PSN damage, etc
|
||||
// TODO: research exact mechanics
|
||||
onBeforeMovePriority: 9,
|
||||
onBeforeMove(pokemon) {
|
||||
this.add('cant', pokemon, 'partiallytrapped');
|
||||
return false;
|
||||
},
|
||||
onRestart() {
|
||||
this.effectState.duration = 2;
|
||||
},
|
||||
onAccuracy(accuracy, target, source, move) {
|
||||
if (source === this.effectState.source) return true;
|
||||
},
|
||||
onLockMove() {
|
||||
// exact move doesn't matter, no move is ever actually used
|
||||
return 'struggle';
|
||||
},
|
||||
onDisableMove(target) {
|
||||
target.maybeLocked = true;
|
||||
},
|
||||
},
|
||||
fakepartiallytrapped: {
|
||||
name: 'fakepartiallytrapped',
|
||||
// Wrap ended this turn, but you don't know that
|
||||
// until you try to use an attack
|
||||
duration: 2,
|
||||
onDisableMove(target) {
|
||||
target.maybeLocked = true;
|
||||
},
|
||||
},
|
||||
partialtrappinglock: {
|
||||
name: 'partialtrappinglock',
|
||||
durationCallback() {
|
||||
const duration = this.sample([2, 2, 2, 3, 3, 3, 4, 5]);
|
||||
return duration;
|
||||
return this.sample([2, 2, 2, 3, 3, 3, 4, 5]);
|
||||
},
|
||||
onStart(target, source, effect) {
|
||||
const foe = target.foes()[0];
|
||||
if (!foe) return false;
|
||||
|
||||
this.effectState.move = effect.id;
|
||||
this.effectState.totalDuration = this.effectState.duration!;
|
||||
this.effectState.damage = this.lastDamage;
|
||||
this.effectState.locked = foe;
|
||||
foe.addVolatile('partiallytrapped', target, effect);
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
if (!pokemon.hasMove(this.effectState.move)) {
|
||||
onOverrideAction(pokemon, target, move) {
|
||||
return this.effectState.move;
|
||||
},
|
||||
onBeforeMove(pokemon, target, move) {
|
||||
if (target !== this.effectState.locked) {
|
||||
pokemon.removeVolatile('partialtrappinglock');
|
||||
}
|
||||
},
|
||||
onAfterMove(pokemon, target, move) {
|
||||
if (target && target.hp <= 0) {
|
||||
delete pokemon.volatiles['partialtrappinglock'];
|
||||
return;
|
||||
}
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id !== this.effectState.move) {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
if (this.effectState.duration === 1) {
|
||||
if (this.effectState.totalDuration !== 5) {
|
||||
pokemon.addVolatile('fakepartiallytrapped');
|
||||
pokemon.volatiles['fakepartiallytrapped'].counterpart = target;
|
||||
target.addVolatile('fakepartiallytrapped');
|
||||
target.volatiles['fakepartiallytrapped'].counterpart = pokemon;
|
||||
}
|
||||
} else {
|
||||
target.addVolatile('partiallytrapped', pokemon, move);
|
||||
}
|
||||
},
|
||||
onLockMove() {
|
||||
return this.effectState.move;
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
pokemon.maybeLocked = true;
|
||||
},
|
||||
},
|
||||
mustrecharge: {
|
||||
inherit: true,
|
||||
duration: 0,
|
||||
onBeforeMovePriority: 7,
|
||||
onStart() {},
|
||||
onAfterMove(pokemon, target, move) {
|
||||
if (target && target.hp <= 0) {
|
||||
delete pokemon.volatiles['mustrecharge'];
|
||||
return;
|
||||
}
|
||||
this.add('-mustrecharge', pokemon);
|
||||
},
|
||||
},
|
||||
lockedmove: {
|
||||
// Thrash and Petal Dance.
|
||||
|
|
@ -236,6 +296,11 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
this.queue.changeAction(pokemon, { choice: 'move', moveid: move.id });
|
||||
}
|
||||
},
|
||||
onAfterMove(pokemon) {
|
||||
if (pokemon.volatiles['lockedmove'].time <= 0) {
|
||||
pokemon.removeVolatile('lockedmove');
|
||||
}
|
||||
},
|
||||
},
|
||||
twoturnmove: {
|
||||
// Skull Bash, Solar Beam, ...
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
wartortle: {
|
||||
tier: "ZU",
|
||||
tier: "NFE",
|
||||
},
|
||||
blastoise: {
|
||||
tier: "NU",
|
||||
|
|
@ -51,7 +51,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
pidgeot: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
rattata: {
|
||||
tier: "LC",
|
||||
|
|
@ -90,7 +90,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
nidoqueen: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
},
|
||||
nidoranm: {
|
||||
tier: "LC",
|
||||
|
|
@ -117,7 +117,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
wigglytuff: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
},
|
||||
zubat: {
|
||||
tier: "LC",
|
||||
|
|
@ -132,7 +132,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
vileplume: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
},
|
||||
paras: {
|
||||
tier: "LC",
|
||||
|
|
@ -168,7 +168,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
primeape: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
growlithe: {
|
||||
tier: "LC",
|
||||
|
|
@ -189,7 +189,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "PU",
|
||||
},
|
||||
kadabra: {
|
||||
tier: "UU",
|
||||
tier: "NU",
|
||||
},
|
||||
alakazam: {
|
||||
tier: "OU",
|
||||
|
|
@ -201,7 +201,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
machamp: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
},
|
||||
bellsprout: {
|
||||
tier: "LC",
|
||||
|
|
@ -210,13 +210,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
victreebel: {
|
||||
tier: "OU",
|
||||
tier: "NU",
|
||||
},
|
||||
tentacool: {
|
||||
tier: "ZU",
|
||||
},
|
||||
tentacruel: {
|
||||
tier: "UU",
|
||||
tier: "NU",
|
||||
},
|
||||
geodude: {
|
||||
tier: "LC",
|
||||
|
|
@ -225,19 +225,19 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "PU",
|
||||
},
|
||||
golem: {
|
||||
tier: "UU",
|
||||
tier: "NU",
|
||||
},
|
||||
ponyta: {
|
||||
tier: "ZU",
|
||||
tier: "LC",
|
||||
},
|
||||
rapidash: {
|
||||
tier: "PU",
|
||||
tier: "UU",
|
||||
},
|
||||
slowpoke: {
|
||||
tier: "ZU",
|
||||
},
|
||||
slowbro: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
},
|
||||
magnemite: {
|
||||
tier: "LC",
|
||||
|
|
@ -258,7 +258,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
dewgong: {
|
||||
tier: "UU",
|
||||
tier: "NU",
|
||||
},
|
||||
grimer: {
|
||||
tier: "LC",
|
||||
|
|
@ -288,19 +288,19 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "ZU",
|
||||
},
|
||||
hypno: {
|
||||
tier: "UUBL",
|
||||
tier: "UU",
|
||||
},
|
||||
krabby: {
|
||||
tier: "LC",
|
||||
},
|
||||
kingler: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
},
|
||||
voltorb: {
|
||||
tier: "LC",
|
||||
},
|
||||
electrode: {
|
||||
tier: "UU",
|
||||
tier: "NU",
|
||||
},
|
||||
exeggcute: {
|
||||
tier: "PU",
|
||||
|
|
@ -339,7 +339,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "OU",
|
||||
},
|
||||
tangela: {
|
||||
tier: "UU",
|
||||
tier: "NU",
|
||||
},
|
||||
kangaskhan: {
|
||||
tier: "UU",
|
||||
|
|
@ -366,7 +366,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NU",
|
||||
},
|
||||
scyther: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
jynx: {
|
||||
tier: "OU",
|
||||
|
|
@ -375,10 +375,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UU",
|
||||
},
|
||||
magmar: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
pinsir: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
},
|
||||
tauros: {
|
||||
tier: "OU",
|
||||
|
|
@ -390,7 +390,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UU",
|
||||
},
|
||||
lapras: {
|
||||
tier: "UUBL",
|
||||
tier: "UU",
|
||||
},
|
||||
ditto: {
|
||||
tier: "ZU",
|
||||
|
|
@ -399,7 +399,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
vaporeon: {
|
||||
tier: "UU",
|
||||
tier: "NU",
|
||||
},
|
||||
jolteon: {
|
||||
tier: "OU",
|
||||
|
|
@ -414,7 +414,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "ZU",
|
||||
},
|
||||
omastar: {
|
||||
tier: "UU",
|
||||
tier: "NU",
|
||||
},
|
||||
kabuto: {
|
||||
tier: "LC",
|
||||
|
|
@ -429,13 +429,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "OU",
|
||||
},
|
||||
articuno: {
|
||||
tier: "UUBL",
|
||||
tier: "UU",
|
||||
},
|
||||
zapdos: {
|
||||
tier: "OU",
|
||||
},
|
||||
moltres: {
|
||||
tier: "NU",
|
||||
tier: "UU",
|
||||
},
|
||||
dratini: {
|
||||
tier: "LC",
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
bind: {
|
||||
inherit: true,
|
||||
ignoreImmunity: true,
|
||||
volatileStatus: 'partiallytrapped',
|
||||
self: {
|
||||
volatileStatus: 'partialtrappinglock',
|
||||
},
|
||||
|
|
@ -86,19 +85,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.hint("In Gen 1, partial trapping moves negate the recharge turn of Hyper Beam, even if they miss.", true);
|
||||
}
|
||||
},
|
||||
onHit(target, source) {
|
||||
/**
|
||||
* The duration of the partially trapped must be always renewed to 2
|
||||
* so target doesn't move on trapper switch out as happens in gen 1.
|
||||
* However, this won't happen if there's no switch and the trapper is
|
||||
* about to end its partial trapping.
|
||||
**/
|
||||
if (target.volatiles['partiallytrapped']) {
|
||||
if (source.volatiles['partialtrappinglock'] && source.volatiles['partialtrappinglock'].duration! > 1) {
|
||||
target.volatiles['partiallytrapped'].duration = 2;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
bite: {
|
||||
inherit: true,
|
||||
|
|
@ -137,7 +123,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
accuracy: 75,
|
||||
pp: 10,
|
||||
volatileStatus: 'partiallytrapped',
|
||||
self: {
|
||||
volatileStatus: 'partialtrappinglock',
|
||||
},
|
||||
|
|
@ -147,19 +132,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.hint("In Gen 1, partial trapping moves negate the recharge turn of Hyper Beam, even if they miss.", true);
|
||||
}
|
||||
},
|
||||
onHit(target, source) {
|
||||
/**
|
||||
* The duration of the partially trapped must be always renewed to 2
|
||||
* so target doesn't move on trapper switch out as happens in gen 1.
|
||||
* However, this won't happen if there's no switch and the trapper is
|
||||
* about to end its partial trapping.
|
||||
**/
|
||||
if (target.volatiles['partiallytrapped']) {
|
||||
if (source.volatiles['partialtrappinglock'] && source.volatiles['partialtrappinglock'].duration! > 1) {
|
||||
target.volatiles['partiallytrapped'].duration = 2;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
constrict: {
|
||||
inherit: true,
|
||||
|
|
@ -239,22 +211,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
},
|
||||
disable: {
|
||||
num: 50,
|
||||
accuracy: 55,
|
||||
basePower: 0,
|
||||
category: "Status",
|
||||
name: "Disable",
|
||||
pp: 20,
|
||||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
|
||||
volatileStatus: 'disable',
|
||||
inherit: true,
|
||||
onTryHit(target) {
|
||||
// This function should not return if the checks are met. Adding && undefined ensures this happens.
|
||||
return target.moveSlots.some(ms => ms.pp > 0) &&
|
||||
!('disable' in target.volatiles) &&
|
||||
undefined;
|
||||
return target.moveSlots.some(ms => ms.pp > 0);
|
||||
},
|
||||
condition: {
|
||||
inherit: true,
|
||||
durationCallback: undefined,
|
||||
onStart(pokemon) {
|
||||
// disable can only select moves that have pp > 0, hence the onTryHit modification
|
||||
const moveSlot = this.sample(pokemon.moveSlots.filter(ms => ms.pp > 0));
|
||||
|
|
@ -263,9 +226,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
// 1-8 turns (which will in effect translate to 0-7 missed turns for the target)
|
||||
this.effectState.time = this.random(1, 9);
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
this.add('-end', pokemon, 'Disable');
|
||||
},
|
||||
onBeforeMovePriority: 6,
|
||||
onBeforeMove(pokemon, target, move) {
|
||||
pokemon.volatiles['disable'].time--;
|
||||
|
|
@ -280,17 +240,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
return false;
|
||||
}
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id === this.effectState.move) {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
secondary: null,
|
||||
target: "normal",
|
||||
type: "Normal",
|
||||
},
|
||||
dizzypunch: {
|
||||
inherit: true,
|
||||
|
|
@ -320,7 +270,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
accuracy: 70,
|
||||
basePower: 15,
|
||||
volatileStatus: 'partiallytrapped',
|
||||
self: {
|
||||
volatileStatus: 'partialtrappinglock',
|
||||
},
|
||||
|
|
@ -330,19 +279,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.hint("In Gen 1, partial trapping moves negate the recharge turn of Hyper Beam, even if they miss.", true);
|
||||
}
|
||||
},
|
||||
onHit(target, source) {
|
||||
/**
|
||||
* The duration of the partially trapped must be always renewed to 2
|
||||
* so target doesn't move on trapper switch out as happens in gen 1.
|
||||
* However, this won't happen if there's no switch and the trapper is
|
||||
* about to end its partial trapping.
|
||||
**/
|
||||
if (target.volatiles['partiallytrapped']) {
|
||||
if (source.volatiles['partialtrappinglock'] && source.volatiles['partialtrappinglock'].duration! > 1) {
|
||||
target.volatiles['partiallytrapped'].duration = 2;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
fly: {
|
||||
inherit: true,
|
||||
|
|
@ -361,11 +297,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
focusenergy: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onStart(pokemon) {
|
||||
this.add('-start', pokemon, 'move: Focus Energy');
|
||||
},
|
||||
inherit: true,
|
||||
// This does nothing as it's dealt with on critical hit calculation.
|
||||
onModifyMove() {},
|
||||
onModifyCritRatio() {},
|
||||
},
|
||||
},
|
||||
glare: {
|
||||
|
|
@ -450,9 +384,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
onHit() {},
|
||||
condition: {
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'move: Leech Seed');
|
||||
},
|
||||
inherit: true,
|
||||
onAfterMoveSelfPriority: 1,
|
||||
onAfterMoveSelf(pokemon) {
|
||||
const leecher = this.getAtSlot(pokemon.volatiles['leechseed'].sourceSlot);
|
||||
|
|
@ -478,15 +410,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
},
|
||||
lightscreen: {
|
||||
num: 113,
|
||||
accuracy: true,
|
||||
basePower: 0,
|
||||
category: "Status",
|
||||
name: "Light Screen",
|
||||
pp: 30,
|
||||
priority: 0,
|
||||
flags: { metronome: 1 },
|
||||
inherit: true,
|
||||
volatileStatus: 'lightscreen',
|
||||
sideCondition: undefined,
|
||||
onTryHit(pokemon) {
|
||||
if (pokemon.volatiles['lightscreen']) {
|
||||
return false;
|
||||
|
|
@ -498,7 +424,22 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
},
|
||||
target: "self",
|
||||
type: "Psychic",
|
||||
},
|
||||
metronome: {
|
||||
inherit: true,
|
||||
onHit(pokemon) {
|
||||
const moves = this.dex.moves.all().filter(move => (
|
||||
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') && move.flags['metronome']
|
||||
));
|
||||
let randomMove = '';
|
||||
if (moves.length) {
|
||||
moves.sort((a, b) => a.num - b.num);
|
||||
randomMove = this.sample(moves).id;
|
||||
}
|
||||
if (!randomMove) return false;
|
||||
pokemon.side.lastSelectedMove = this.toID(randomMove);
|
||||
this.actions.useMove(randomMove, pokemon);
|
||||
},
|
||||
},
|
||||
mimic: {
|
||||
inherit: true,
|
||||
|
|
@ -523,6 +464,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.add('-start', source, 'Mimic', move.name);
|
||||
},
|
||||
},
|
||||
minimize: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
inherit: true,
|
||||
onSourceModifyDamage() {},
|
||||
},
|
||||
},
|
||||
mirrormove: {
|
||||
inherit: true,
|
||||
onHit(pokemon) {
|
||||
|
|
@ -537,9 +485,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
mist: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onStart(pokemon) {
|
||||
this.add('-start', pokemon, 'Mist');
|
||||
},
|
||||
inherit: true,
|
||||
onTryBoost(boost, target, source, effect) {
|
||||
if (effect.effectType === 'Move' && effect.category !== 'Status') return;
|
||||
if (source && target !== source) {
|
||||
|
|
@ -655,15 +601,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
},
|
||||
reflect: {
|
||||
num: 115,
|
||||
accuracy: true,
|
||||
basePower: 0,
|
||||
category: "Status",
|
||||
name: "Reflect",
|
||||
pp: 20,
|
||||
priority: 0,
|
||||
flags: { metronome: 1 },
|
||||
inherit: true,
|
||||
volatileStatus: 'reflect',
|
||||
sideCondition: undefined,
|
||||
onTryHit(pokemon) {
|
||||
if (pokemon.volatiles['reflect']) {
|
||||
return false;
|
||||
|
|
@ -674,9 +614,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.add('-start', pokemon, 'Reflect');
|
||||
},
|
||||
},
|
||||
secondary: null,
|
||||
target: "self",
|
||||
type: "Psychic",
|
||||
},
|
||||
rest: {
|
||||
inherit: true,
|
||||
|
|
@ -808,15 +746,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
onModifyMove() {},
|
||||
},
|
||||
substitute: {
|
||||
num: 164,
|
||||
accuracy: true,
|
||||
basePower: 0,
|
||||
category: "Status",
|
||||
name: "Substitute",
|
||||
pp: 10,
|
||||
priority: 0,
|
||||
flags: { metronome: 1 },
|
||||
volatileStatus: 'substitute',
|
||||
inherit: true,
|
||||
onTryHit(target) {
|
||||
if (target.volatiles['substitute']) {
|
||||
this.add('-fail', target, 'move: Substitute');
|
||||
|
|
@ -836,11 +766,16 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
},
|
||||
condition: {
|
||||
inherit: true,
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'Substitute');
|
||||
this.effectState.hp = Math.floor(target.maxhp / 4) + 1;
|
||||
delete target.volatiles['partiallytrapped'];
|
||||
if (target.volatiles['partiallytrapped']) {
|
||||
this.add('-end', target, target.volatiles['partiallytrapped'].sourceEffect, '[partiallytrapped]', '[silent]');
|
||||
delete target.volatiles['partiallytrapped'];
|
||||
}
|
||||
},
|
||||
onTryPrimaryHit() {},
|
||||
onTryHitPriority: -1,
|
||||
onTryHit(target, source, move) {
|
||||
if (move.category === 'Status') {
|
||||
|
|
@ -862,8 +797,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
let uncappedDamage = move.hit > 1 ? this.lastDamage : this.actions.getDamage(source, target, move);
|
||||
if (move.id === 'bide') uncappedDamage = source.volatiles['bide'].damage * 2;
|
||||
if (!uncappedDamage && uncappedDamage !== 0) return null;
|
||||
uncappedDamage = this.runEvent('SubDamage', target, source, move, uncappedDamage);
|
||||
if (!uncappedDamage && uncappedDamage !== 0) return uncappedDamage;
|
||||
this.lastDamage = uncappedDamage;
|
||||
target.volatiles['substitute'].hp -= uncappedDamage > target.volatiles['substitute'].hp ?
|
||||
target.volatiles['substitute'].hp : uncappedDamage;
|
||||
|
|
@ -906,13 +839,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
return 0;
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Substitute');
|
||||
},
|
||||
},
|
||||
secondary: null,
|
||||
target: "self",
|
||||
type: "Normal",
|
||||
},
|
||||
superfang: {
|
||||
inherit: true,
|
||||
|
|
@ -950,7 +877,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
accuracy: 85,
|
||||
ignoreImmunity: true,
|
||||
volatileStatus: 'partiallytrapped',
|
||||
self: {
|
||||
volatileStatus: 'partialtrappinglock',
|
||||
},
|
||||
|
|
@ -960,18 +886,5 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.hint("In Gen 1, partial trapping moves negate the recharge turn of Hyper Beam, even if they miss.", true);
|
||||
}
|
||||
},
|
||||
onHit(target, source) {
|
||||
/**
|
||||
* The duration of the partially trapped must be always renewed to 2
|
||||
* so target doesn't move on trapper switch out as happens in gen 1.
|
||||
* However, this won't happen if there's no switch and the trapper is
|
||||
* about to end its partial trapping.
|
||||
**/
|
||||
if (target.volatiles['partiallytrapped']) {
|
||||
if (source.volatiles['partialtrappinglock'] && source.volatiles['partialtrappinglock'].duration! > 1) {
|
||||
target.volatiles['partiallytrapped'].duration = 2;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,17 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
standardag: {
|
||||
inherit: true,
|
||||
ruleset: [
|
||||
'Obtainable', 'Desync Clause Mod', 'HP Percentage Mod', 'Cancel Mod', 'Endless Battle Clause',
|
||||
],
|
||||
},
|
||||
standard: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard',
|
||||
ruleset: ['Obtainable', 'Desync Clause Mod', 'Sleep Clause Mod', 'Freeze Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Sleep Clause Mod', 'Freeze Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
banlist: ['Dig', 'Fly'],
|
||||
},
|
||||
'350cupmod': {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,25 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
// BattlePokemon scripts.
|
||||
pokemon: {
|
||||
inherit: true,
|
||||
// In gen 1, a Pokémon can have two instances of the same move using Mimic
|
||||
// we need to make sure to deduct PP from a move that has PP left
|
||||
deductPP(move, amount, target) {
|
||||
move = this.battle.dex.moves.get(move);
|
||||
// first loop: get the first instance with PP left
|
||||
// second loop: get the first instance, even if it has no PP left
|
||||
for (let i = 0; i < 2; i++) {
|
||||
for (const ppData of this.moveSlots) {
|
||||
if (ppData.id !== move.id) continue;
|
||||
ppData.used = true;
|
||||
if (!ppData.pp && i === 0) continue;
|
||||
|
||||
if (!amount) amount = 1;
|
||||
ppData.pp -= amount;
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
getStat(statName, unmodified) {
|
||||
// @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
|
||||
if (statName === 'hp') throw new Error("Please read `maxhp` directly");
|
||||
|
|
@ -129,16 +148,19 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
let sourceEffect = options?.sourceEffect;
|
||||
const target = this.battle.getTarget(pokemon, moveOrMoveName, targetLoc);
|
||||
let move = this.battle.dex.getActiveMove(moveOrMoveName);
|
||||
if (move.id !== 'struggle') {
|
||||
const changedMove = this.battle.runEvent('OverrideAction', pokemon, target, move);
|
||||
if (changedMove && changedMove !== true) {
|
||||
move = this.battle.dex.getActiveMove(changedMove);
|
||||
}
|
||||
}
|
||||
|
||||
// If a faster partial trapping move misses against a user of Hyper Beam during a recharge turn,
|
||||
// the user of Hyper Beam will automatically use Hyper Beam during that turn.
|
||||
const autoHyperBeam = (
|
||||
move.id === 'recharge' && !pokemon.volatiles['mustrecharge'] && !pokemon.volatiles['partiallytrapped']
|
||||
);
|
||||
if (autoHyperBeam) {
|
||||
if (move.id === 'recharge' && !pokemon.volatiles['mustrecharge'] && !pokemon.volatiles['partiallytrapped']) {
|
||||
move = this.battle.dex.getActiveMove('hyperbeam');
|
||||
this.battle.hint(`In Gen 1, If a faster partial trapping move misses against a user of Hyper Beam during a recharge turn, ` +
|
||||
`the user of Hyper Beam will automatically use Hyper Beam during that turn.`, true);
|
||||
this.battle.hint(`In Gen 1, partial trapping moves like Wrap remove Hyper Beam recharges. ` +
|
||||
`If the target would have recharged, it will automatically use Hyper Beam instead.`, true);
|
||||
}
|
||||
|
||||
if (target?.subFainted) target.subFainted = null;
|
||||
|
|
@ -151,41 +173,31 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
this.battle.runEvent('AfterMoveSelf', pokemon, target, move);
|
||||
return;
|
||||
}
|
||||
if (move.beforeMoveCallback) {
|
||||
if (move.beforeMoveCallback.call(this.battle, pokemon, target, move)) {
|
||||
this.battle.clearActiveMove(true);
|
||||
return;
|
||||
}
|
||||
if (move.beforeMoveCallback?.call(this.battle, pokemon, target, move)) {
|
||||
this.battle.clearActiveMove(true);
|
||||
return;
|
||||
}
|
||||
let lockedMove = this.battle.runEvent('LockMove', pokemon);
|
||||
if (lockedMove === true) lockedMove = false;
|
||||
if (
|
||||
!lockedMove &&
|
||||
(!pokemon.volatiles['partialtrappinglock'] || pokemon.volatiles['partialtrappinglock'].locked !== target)
|
||||
) {
|
||||
pokemon.deductPP(move, null, target);
|
||||
} else {
|
||||
sourceEffect = move;
|
||||
if (pokemon.volatiles['twoturnmove']) {
|
||||
// Two-turn moves like Sky Attack deduct PP on their second turn.
|
||||
pokemon.deductPP(pokemon.volatiles['twoturnmove'].originalMove, null, target);
|
||||
}
|
||||
}
|
||||
if (
|
||||
(pokemon.volatiles['partialtrappinglock'] && target !== pokemon.volatiles['partialtrappinglock'].locked) ||
|
||||
autoHyperBeam
|
||||
) {
|
||||
const moveSlot = pokemon.moveSlots.find(ms => ms.id === move.id);
|
||||
|
||||
const lockedMove = pokemon.getLockedMove();
|
||||
if (lockedMove) sourceEffect = move;
|
||||
|
||||
// Locked moves don't deduct PP
|
||||
// Two-turn moves like Sky Attack deduct PP on their second turn.
|
||||
if (!lockedMove || pokemon.volatiles['twoturnmove']) {
|
||||
const ppMove = pokemon.volatiles['twoturnmove']?.ppMove || move.id;
|
||||
pokemon.deductPP(ppMove, null, target);
|
||||
const moveSlot = pokemon.getMoveData(ppMove);
|
||||
if (moveSlot && moveSlot.pp < 0) {
|
||||
moveSlot.pp = 63;
|
||||
this.battle.hint("In Gen 1, if a player is forced to use a move with 0 PP, the move will underflow to have 63 PP.");
|
||||
moveSlot.pp += 64;
|
||||
this.battle.hint("In Gen 1, if a pokemon is forced to use a move with 0 PP, the move will underflow to have 63 PP.");
|
||||
}
|
||||
}
|
||||
|
||||
this.useMove(move, pokemon, { target, sourceEffect });
|
||||
// Restore PP if the move is the first turn of a charging move. Save the move from which PP should be deducted if the move succeeds.
|
||||
|
||||
if (pokemon.volatiles['twoturnmove']) {
|
||||
pokemon.deductPP(move, -1, target);
|
||||
pokemon.volatiles['twoturnmove'].originalMove = move.id;
|
||||
pokemon.volatiles['twoturnmove'].ppMove = move.id;
|
||||
}
|
||||
},
|
||||
// This function deals with AfterMoveSelf events.
|
||||
|
|
@ -223,37 +235,9 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
// The move is our 'final' move (a failed Mirror Move, or any move that isn't Metronome or Mirror Move).
|
||||
pokemon.side.lastMove = move;
|
||||
|
||||
if (pokemon.volatiles['lockedmove']?.time <= 0) pokemon.removeVolatile('lockedmove');
|
||||
|
||||
// If target fainted
|
||||
if (target && target.hp <= 0) {
|
||||
// We remove recharge
|
||||
if (pokemon.volatiles['mustrecharge']) pokemon.removeVolatile('mustrecharge');
|
||||
delete pokemon.volatiles['partialtrappinglock'];
|
||||
} else {
|
||||
if (pokemon.volatiles['mustrecharge']) this.battle.add('-mustrecharge', pokemon);
|
||||
if (pokemon.hp) this.battle.runEvent('AfterMoveSelf', pokemon, target, move);
|
||||
}
|
||||
|
||||
// For partial trapping moves, we are saving the target
|
||||
if (move.volatileStatus === 'partiallytrapped' && target && target.hp > 0) {
|
||||
// Let's check if the lock exists
|
||||
if (pokemon.volatiles['partialtrappinglock'] && target.volatiles['partiallytrapped']) {
|
||||
// Here the partialtrappinglock volatile has been already applied
|
||||
const sourceVolatile = pokemon.volatiles['partialtrappinglock'];
|
||||
const targetVolatile = target.volatiles['partiallytrapped'];
|
||||
if (!sourceVolatile.locked) {
|
||||
// If it's the first hit, we save the target
|
||||
sourceVolatile.locked = target;
|
||||
} else if (target !== pokemon && target !== sourceVolatile.locked) {
|
||||
// Our target switched out! Re-roll the duration, damage, and accuracy.
|
||||
const duration = this.battle.sample([2, 2, 2, 3, 3, 3, 4, 5]);
|
||||
sourceVolatile.duration = duration;
|
||||
sourceVolatile.locked = target;
|
||||
// Duration reset thus partially trapped at 2 always.
|
||||
targetVolatile.duration = 2;
|
||||
}
|
||||
} // If we move to here, the move failed and there's no partial trapping lock.
|
||||
this.battle.runEvent('AfterMove', pokemon, target, move);
|
||||
if (!target || target.hp > 0) {
|
||||
this.battle.runEvent('AfterMoveSelf', pokemon, target, move);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -293,7 +277,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (sourceEffect) attrs += `|[from]${this.battle.dex.conditions.get(sourceEffect)}`;
|
||||
if (sourceEffect) attrs += `|[from] ${this.battle.dex.conditions.get(sourceEffect).name}`;
|
||||
this.battle.addMove('move', pokemon, move.name, `${target}${attrs}`);
|
||||
|
||||
if (!this.battle.singleEvent('Try', move, null, pokemon, target, move)) {
|
||||
|
|
@ -332,10 +316,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!move.negateSecondary) {
|
||||
this.battle.singleEvent('AfterMoveSecondarySelf', move, null, pokemon, target, move);
|
||||
this.battle.runEvent('AfterMoveSecondarySelf', pokemon, target, move);
|
||||
}
|
||||
this.battle.singleEvent('AfterMoveSecondarySelf', move, null, pokemon, target, move);
|
||||
this.battle.runEvent('AfterMoveSecondarySelf', pokemon, target, move);
|
||||
return true;
|
||||
},
|
||||
// This function attempts a move hit and returns the attempt result before the actual hit happens.
|
||||
|
|
@ -370,10 +352,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
|
||||
// Then, check if the Pokémon is immune to this move.
|
||||
if (
|
||||
(!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) &&
|
||||
!target.runImmunity(move.type, true)
|
||||
) {
|
||||
if (!target.runImmunity(move, true)) {
|
||||
if (move.selfdestruct) {
|
||||
this.battle.faint(pokemon, pokemon, move);
|
||||
}
|
||||
|
|
@ -388,11 +367,6 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
// Now, let's calculate the accuracy.
|
||||
let accuracy = move.accuracy;
|
||||
|
||||
// Partial trapping moves: true accuracy while it lasts
|
||||
if (move.volatileStatus === 'partiallytrapped' && target === pokemon.volatiles['partialtrappinglock']?.locked) {
|
||||
accuracy = true;
|
||||
}
|
||||
|
||||
// If a sleep inducing move is used while the user is recharging, the accuracy is true.
|
||||
if (move.status === 'slp' && target?.volatiles['mustrecharge']) {
|
||||
accuracy = true;
|
||||
|
|
@ -499,10 +473,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
|
||||
if (move.ohko) this.battle.add('-ohko');
|
||||
|
||||
if (!move.negateSecondary) {
|
||||
this.battle.singleEvent('AfterMoveSecondary', move, null, target, pokemon, move);
|
||||
this.battle.runEvent('AfterMoveSecondary', target, pokemon, move);
|
||||
}
|
||||
this.battle.singleEvent('AfterMoveSecondary', move, null, target, pokemon, move);
|
||||
this.battle.runEvent('AfterMoveSecondary', target, pokemon, move);
|
||||
|
||||
return damage;
|
||||
},
|
||||
|
|
@ -527,14 +499,6 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
if (target) {
|
||||
hitResult = this.battle.singleEvent('TryHit', moveData, {}, target, pokemon, move);
|
||||
|
||||
// Handle here the applying of partial trapping moves to Pokémon with Substitute
|
||||
if (targetSub && moveData.volatileStatus && moveData.volatileStatus === 'partiallytrapped') {
|
||||
target.addVolatile(moveData.volatileStatus, pokemon, move);
|
||||
if (!pokemon.volatiles['partialtrappinglock'] || pokemon.volatiles['partialtrappinglock'].duration! > 1) {
|
||||
target.volatiles[moveData.volatileStatus].duration = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hitResult) {
|
||||
if (hitResult === false) this.battle.add('-fail', target);
|
||||
return false;
|
||||
|
|
@ -609,7 +573,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
didSomething = true;
|
||||
// Check the status of the Pokémon whose turn is not.
|
||||
// When a move that affects stat levels is used, if the Pokémon whose turn it is not right now is paralyzed or
|
||||
// burned, the correspoding stat penalties will be applied again to that Pokémon.
|
||||
// burned, the corresponding stat penalties will be applied again to that Pokémon.
|
||||
if (pokemon.side.foe.active[0].status) {
|
||||
// If it's paralysed, quarter its speed.
|
||||
if (pokemon.side.foe.active[0].status === 'par') {
|
||||
|
|
@ -700,11 +664,6 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
this.moveHit(pokemon, pokemon, move, moveData.self, isSecondary, true);
|
||||
}
|
||||
|
||||
// Now we can save the partial trapping damage.
|
||||
if (pokemon.volatiles['partialtrappinglock']) {
|
||||
pokemon.volatiles['partialtrappinglock'].damage = this.battle.lastDamage;
|
||||
}
|
||||
|
||||
// Apply move secondaries.
|
||||
if (moveData.secondaries && target && target.hp > 0) {
|
||||
for (const secondary of moveData.secondaries) {
|
||||
|
|
@ -751,10 +710,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
|
||||
// Let's see if the target is immune to the move.
|
||||
if (!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) {
|
||||
if (!target.runImmunity(move.type, true)) {
|
||||
return false;
|
||||
}
|
||||
if (!target.runImmunity(move, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is it an OHKO move?
|
||||
|
|
@ -778,7 +735,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
|
||||
// If it's the first hit on a Normal-type partially trap move, it hits Ghosts anyways but damage is 0.
|
||||
if (move.volatileStatus === 'partiallytrapped' && move.type === 'Normal' && target.hasType('Ghost')) {
|
||||
if (move.self?.volatileStatus === 'partialtrappinglock' && move.type === 'Normal' && target.hasType('Ghost')) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
substitute: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'Substitute');
|
||||
this.effectState.hp = Math.floor(target.maxhp / 4) + 1;
|
||||
delete target.volatiles['partiallytrapped'];
|
||||
},
|
||||
onTryHitPriority: -1,
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (move.drain) {
|
||||
this.add('-miss', source);
|
||||
|
|
@ -39,10 +34,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
// NOTE: In future generations the damage is capped to the remaining HP of the
|
||||
// Substitute, here we deliberately use the uncapped damage when tracking lastDamage etc.
|
||||
// Also, multi-hit moves must always deal the same damage as the first hit for any subsequent hits
|
||||
let uncappedDamage = move.hit > 1 ? this.lastDamage : this.actions.getDamage(source, target, move);
|
||||
const uncappedDamage = move.hit > 1 ? this.lastDamage : this.actions.getDamage(source, target, move);
|
||||
if (!uncappedDamage && uncappedDamage !== 0) return null;
|
||||
uncappedDamage = this.runEvent('SubDamage', target, source, move, uncappedDamage);
|
||||
if (!uncappedDamage && uncappedDamage !== 0) return uncappedDamage;
|
||||
this.lastDamage = uncappedDamage;
|
||||
target.volatiles['substitute'].hp -= uncappedDamage > target.volatiles['substitute'].hp ?
|
||||
target.volatiles['substitute'].hp : uncappedDamage;
|
||||
|
|
@ -78,9 +71,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
return accuracy;
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Substitute');
|
||||
},
|
||||
},
|
||||
},
|
||||
swift: {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
|
|||
standard: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard',
|
||||
ruleset: ['Obtainable', 'Desync Clause Mod', 'Sleep Clause Mod', 'Freeze Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Sleep Clause Mod', 'Freeze Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
banlist: ['Dig', 'Fly'],
|
||||
},
|
||||
nc1997movelegality: {
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
golem: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
},
|
||||
ponyta: {
|
||||
tier: "LC",
|
||||
|
|
@ -270,7 +270,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
cloyster: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
},
|
||||
gastly: {
|
||||
tier: "LC",
|
||||
|
|
@ -279,7 +279,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UU",
|
||||
},
|
||||
gengar: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
},
|
||||
onix: {
|
||||
tier: "UU",
|
||||
|
|
@ -342,7 +342,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UU",
|
||||
},
|
||||
kangaskhan: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
},
|
||||
horsea: {
|
||||
tier: "LC",
|
||||
|
|
@ -369,7 +369,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UU",
|
||||
},
|
||||
jynx: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
},
|
||||
electabuzz: {
|
||||
tier: "UU",
|
||||
|
|
@ -402,7 +402,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UU",
|
||||
},
|
||||
jolteon: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
},
|
||||
flareon: {
|
||||
tier: "UU",
|
||||
|
|
|
|||
|
|
@ -160,11 +160,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
volatileStatus: 'rage',
|
||||
},
|
||||
condition: {
|
||||
inherit: true,
|
||||
// Rage lock
|
||||
onStart(target, source, effect) {
|
||||
this.effectState.move = 'rage';
|
||||
},
|
||||
onLockMove: 'rage',
|
||||
onHit(target, source, move) {
|
||||
if (target.boosts.atk < 6 && (move.category !== 'Status' || move.id === 'disable')) {
|
||||
this.boost({ atk: 1 });
|
||||
|
|
@ -220,12 +220,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
},
|
||||
condition: {
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'Substitute');
|
||||
this.effectState.hp = Math.floor(target.maxhp / 4);
|
||||
delete target.volatiles['partiallytrapped'];
|
||||
},
|
||||
onTryHitPriority: -1,
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (target === source) {
|
||||
this.debug('sub bypass: self hit');
|
||||
|
|
@ -249,8 +244,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
damage = target.volatiles['substitute'].hp;
|
||||
}
|
||||
if (!damage && damage !== 0) return null;
|
||||
damage = this.runEvent('SubDamage', target, source, move, damage);
|
||||
if (!damage && damage !== 0) return damage;
|
||||
target.volatiles['substitute'].hp -= damage;
|
||||
this.lastDamage = damage;
|
||||
if (target.volatiles['substitute'].hp <= 0) {
|
||||
|
|
@ -277,9 +270,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
return 0;
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Substitute');
|
||||
},
|
||||
},
|
||||
secondary: null,
|
||||
target: "self",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,763 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
standardag: {
|
||||
inherit: true,
|
||||
ruleset: [
|
||||
'Obtainable', 'Exact HP Mod', 'Cancel Mod',
|
||||
],
|
||||
},
|
||||
standard: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard',
|
||||
ruleset: ['Obtainable', 'Stadium Sleep Clause', 'Freeze Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Exact HP Mod', 'Cancel Mod'],
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Stadium Sleep Clause', 'Freeze Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
},
|
||||
stadiumpokecuprentals: {
|
||||
inherit: true,
|
||||
onChangeSet(set, format, setHas, teamHas) {
|
||||
set.level = 50;
|
||||
switch (this.dex.species.get(set.species).name) {
|
||||
case 'Bulbasaur':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Leech Seed', 'Toxic', 'Body Slam', 'Razor Leaf'];
|
||||
break;
|
||||
case 'Ivysaur':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Razor Leaf', 'Sleep Powder', 'Growth', 'Double-Edge'];
|
||||
break;
|
||||
case 'Venusaur':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Psychic', 'Seismic Toss', 'Reflect', 'Thunder Wave'];
|
||||
break;
|
||||
case 'Charmander':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Flamethrower', 'Slash', 'Dig', 'Fire Spin'];
|
||||
break;
|
||||
case 'Charmeleon':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Flamethrower', 'Counter', 'Seismic Toss', 'Strength'];
|
||||
break;
|
||||
case 'Charizard':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Fly', 'Swords Dance', 'Fire Spin', 'Fire Blast'];
|
||||
break;
|
||||
case 'Squirtle':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Surf', 'Blizzard', 'Body Slam', 'Dig'];
|
||||
break;
|
||||
case 'Wartortle':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Surf', 'Strength', 'Rest', 'Ice Beam'];
|
||||
break;
|
||||
case 'Blastoise':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Hydro Pump', 'Skull Bash', 'Withdraw', 'Seismic Toss'];
|
||||
break;
|
||||
case 'Caterpie':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['String Shot', 'Tackle'];
|
||||
break;
|
||||
case 'Metapod':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['String Shot', 'Tackle'];
|
||||
break;
|
||||
case 'Butterfree':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Psychic', 'Supersonic', 'Mega Drain', 'Stun Spore'];
|
||||
break;
|
||||
case 'Weedle':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['String Shot', 'Poison Sting'];
|
||||
break;
|
||||
case 'Kakuna':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['String Shot', 'Poison Sting'];
|
||||
break;
|
||||
case 'Beedrill':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Twineedle', 'Hyper Beam', 'Toxic', 'Focus Energy'];
|
||||
break;
|
||||
case 'Pidgey':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Fly', 'Toxic', 'Double-Edge', 'Double Team'];
|
||||
break;
|
||||
case 'Pidgeotto':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Fly', 'Quick Attack', 'Sand Attack', 'Take Down'];
|
||||
break;
|
||||
case 'Pidgeot':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Mirror Move', 'Fly', 'Quick Attack', 'Sand Attack'];
|
||||
break;
|
||||
case 'Rattata':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Super Fang', 'Blizzard', 'Quick Attack', 'Hyper Fang'];
|
||||
break;
|
||||
case 'Raticate':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Hyper Fang', 'Hyper Beam', 'Focus Energy', 'Thunder'];
|
||||
break;
|
||||
case 'Spearow':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Drill Peck', 'Mirror Move', 'Double Team', 'Double-Edge'];
|
||||
break;
|
||||
case 'Fearow':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Drill Peck', 'Mirror Move', 'Fury Attack', 'Swift'];
|
||||
break;
|
||||
case 'Ekans':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Earthquake', 'Acid', 'Screech', 'Body Slam'];
|
||||
break;
|
||||
case 'Arbok':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Glare', 'Wrap', 'Dig', 'Strength'];
|
||||
break;
|
||||
case 'Pikachu':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Thunderbolt', 'Slam', 'Thunder Wave', 'Seismic Toss'];
|
||||
break;
|
||||
case 'Raichu':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Thunder', 'Thunder Wave', 'Flash', 'Mega Kick'];
|
||||
break;
|
||||
case 'Sandshrew':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Earthquake', 'Slash', 'Seismic Toss', 'Sand Attack'];
|
||||
break;
|
||||
case 'Sandslash':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Dig', 'Swift', 'Seismic Toss', 'Sand Attack'];
|
||||
break;
|
||||
case 'Nidoran-F':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Toxic', 'Thunderbolt', 'Body Slam', 'Blizzard'];
|
||||
break;
|
||||
case 'Nidorina':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Toxic', 'Thunder', 'Double-Edge', 'Ice Beam'];
|
||||
break;
|
||||
case 'Nidoqueen':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Toxic', 'Double Kick', 'Bite', 'Earthquake'];
|
||||
break;
|
||||
case 'Nidoran-M':
|
||||
set.evs = { hp: 177, atk: 176, def: 176, spa: 176, spd: 176, spe: 176 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Blizzard', 'Body Slam', 'Thunderbolt', 'Focus Energy'];
|
||||
break;
|
||||
case 'Nidorino':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Double-Edge', 'Horn Drill', 'Focus Energy', 'Thunder'];
|
||||
break;
|
||||
case 'Nidoking':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Earthquake', 'Horn Drill', 'Rage', 'Substitute'];
|
||||
break;
|
||||
case 'Clefairy':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Thunderbolt', 'Psychic', 'Body Slam', 'Blizzard'];
|
||||
break;
|
||||
case 'Clefable':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Sing', 'Tri Attack', 'Minimize', 'Ice Beam'];
|
||||
break;
|
||||
case 'Vulpix':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Flamethrower', 'Dig', 'Confuse Ray', 'Double-Edge'];
|
||||
break;
|
||||
case 'Ninetales':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Fire Blast', 'Skull Bash', 'Confuse Ray', 'Tail Whip'];
|
||||
break;
|
||||
case 'Jigglypuff':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Sing', 'Body Slam', 'Seismic Toss', 'Psychic'];
|
||||
break;
|
||||
case 'Wigglytuff':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Sing', 'Double-Edge', 'Submission', 'Thunderbolt'];
|
||||
break;
|
||||
case 'Zubat':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Confuse Ray', 'Mega Drain', 'Toxic', 'Double-Edge'];
|
||||
break;
|
||||
case 'Golbat':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Confuse Ray', 'Mega Drain', 'Bite', 'Haze'];
|
||||
break;
|
||||
case 'Oddish':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Petal Dance', 'Toxic', 'Mega Drain', 'Double-Edge'];
|
||||
break;
|
||||
case 'Gloom':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Petal Dance', 'Take Down', 'Mega Drain', 'Stun Spore'];
|
||||
break;
|
||||
case 'Vileplume':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Petal Dance', 'Sleep Powder', 'Acid', 'Cut'];
|
||||
break;
|
||||
case 'Paras':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Spore', 'Slash', 'Dig', 'Mega Drain'];
|
||||
break;
|
||||
case 'Parasect':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Spore', 'Take Down', 'Dig', 'Solar Beam'];
|
||||
break;
|
||||
case 'Venonat':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Psychic', 'Mega Drain', 'Double-Edge', 'Stun Spore'];
|
||||
break;
|
||||
case 'Venomoth':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Psychic', 'Supersonic', 'Solar Beam', 'Swift'];
|
||||
break;
|
||||
case 'Diglett':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Earthquake', 'Slash', 'Sand Attack', 'Rock Slide'];
|
||||
break;
|
||||
case 'Dugtrio':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Dig', 'Sand Attack', 'Toxic', 'Hyper Beam'];
|
||||
break;
|
||||
case 'Meowth':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Slash', 'Thunderbolt', 'Swift', 'Double Team'];
|
||||
break;
|
||||
case 'Persian':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Slash', 'Bubble Beam', 'Mimic', 'Growl'];
|
||||
break;
|
||||
case 'Psyduck':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Surf', 'Confusion', 'Dig', 'Blizzard'];
|
||||
break;
|
||||
case 'Golduck':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Ice Beam', 'Surf', 'Toxic', 'Disable'];
|
||||
break;
|
||||
case 'Mankey':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Submission', 'Rock Slide', 'Seismic Toss', 'Screech'];
|
||||
break;
|
||||
case 'Primeape':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Fury Swipes', 'Rock Slide', 'Low Kick', 'Screech'];
|
||||
break;
|
||||
case 'Growlithe':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Flamethrower', 'Body Slam', 'Reflect', 'Dig'];
|
||||
break;
|
||||
case 'Arcanine':
|
||||
set.evs = { hp: 105, atk: 104, def: 104, spa: 104, spd: 104, spe: 104 };
|
||||
set.ivs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 };
|
||||
set.moves = ['Fire Blast', 'Take Down', 'Dragon Rage', 'Substitute'];
|
||||
break;
|
||||
case 'Poliwag':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Body Slam', 'Blizzard', 'Surf', 'Amnesia'];
|
||||
break;
|
||||
case 'Poliwhirl':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Hypnosis', 'Surf', 'Ice Beam', 'Earthquake'];
|
||||
break;
|
||||
case 'Poliwrath':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Hypnosis', 'Submission', 'Counter', 'Hydro Pump'];
|
||||
break;
|
||||
case 'Abra':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Psychic', 'Seismic Toss', 'Reflect', 'Thunder Wave'];
|
||||
break;
|
||||
case 'Kadabra':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Psychic', 'Counter', 'Recover', 'Dig'];
|
||||
break;
|
||||
case 'Alakazam':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Psybeam', 'Metronome', 'Disable', 'Tri Attack'];
|
||||
break;
|
||||
case 'Machop':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Submission', 'Rock Slide', 'Earthquake', 'Focus Energy'];
|
||||
break;
|
||||
case 'Machoke':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Submission', 'Strength', 'Rock Slide', 'Focus Energy'];
|
||||
break;
|
||||
case 'Machamp':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Low Kick', 'Strength', 'Counter', 'Focus Energy'];
|
||||
break;
|
||||
case 'Bellsprout':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Razor Leaf', 'Growth', 'Mega Drain', 'Stun Spore'];
|
||||
break;
|
||||
case 'Weepinbell':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Razor Leaf', 'Acid', 'Wrap', 'Toxic'];
|
||||
break;
|
||||
case 'Victreebel':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Solar Beam', 'Acid', 'Reflect', 'Slam'];
|
||||
break;
|
||||
case 'Tentacool':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Surf', 'Supersonic', 'Mega Drain', 'Blizzard'];
|
||||
break;
|
||||
case 'Tentacruel':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Acid', 'Supersonic', 'Hydro Pump', 'Cut'];
|
||||
break;
|
||||
case 'Geodude':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Earthquake', 'Seismic Toss', 'Rock Slide', 'Explosion'];
|
||||
break;
|
||||
case 'Graveler':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Earthquake', 'Seismic Toss', 'Strength', 'Self-Destruct'];
|
||||
break;
|
||||
case 'Golem':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Dig', 'Seismic Toss', 'Fire Blast', 'Metronome'];
|
||||
break;
|
||||
case 'Ponyta':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Fire Blast', 'Agility', 'Horn Drill', 'Body Slam'];
|
||||
break;
|
||||
case 'Rapidash':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Fire Blast', 'Stomp', 'Toxic', 'Fire Spin'];
|
||||
break;
|
||||
case 'Slowpoke':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Surf', 'Psychic', 'Thunder Wave', 'Amnesia'];
|
||||
break;
|
||||
case 'Slowbro':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Surf', 'Psychic', 'Disable', 'Withdraw'];
|
||||
break;
|
||||
case 'Magnemite':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Thunderbolt', 'Thunder Wave', 'Supersonic', 'Double-Edge'];
|
||||
break;
|
||||
case 'Magneton':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Thunderbolt', 'Screech', 'Supersonic', 'Swift'];
|
||||
break;
|
||||
case 'Farfetch\u2019d':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Slash', 'Sand Attack', 'Toxic', 'Fly'];
|
||||
break;
|
||||
case 'Doduo':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Drill Peck', 'Tri Attack', 'Double Team', 'Reflect'];
|
||||
break;
|
||||
case 'Dodrio':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Fly', 'Tri Attack', 'Agility', 'Reflect'];
|
||||
break;
|
||||
case 'Seel':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Ice Beam', 'Body Slam', 'Horn Drill', 'Surf'];
|
||||
break;
|
||||
case 'Dewgong':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Aurora Beam', 'Heabutt', 'Rest', 'Surf'];
|
||||
break;
|
||||
case 'Grimer':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Sludge', 'Body Slam', 'Explosion', 'Screech'];
|
||||
break;
|
||||
case 'Muk':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Sludge', 'Thunderbolt', 'Hyper Beam', 'Self-Destruct'];
|
||||
break;
|
||||
case 'Shellder':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Surf', 'Explosion', 'Blizzard', 'Tri Attack'];
|
||||
break;
|
||||
case 'Cloyster':
|
||||
set.evs = { hp: 105, atk: 104, def: 104, spa: 104, spd: 104, spe: 104 };
|
||||
set.ivs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 };
|
||||
set.moves = ['Clamp', 'Spike Cannon', 'Ice Beam', 'Supersonic'];
|
||||
break;
|
||||
case 'Gastly':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Hypnosis', 'Dream Eater', 'Psychic', 'Confuse Ray'];
|
||||
break;
|
||||
case 'Haunter':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Mega Drain', 'Psychic', 'Explosion', 'Confuse Ray'];
|
||||
break;
|
||||
case 'Gengar':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Thunderbolt', 'Night Shade', 'Hypnosis', 'Confuse Ray'];
|
||||
break;
|
||||
case 'Onix':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Earthquake', 'Rock Slide', 'Strength', 'Explosion'];
|
||||
break;
|
||||
case 'Drowzee':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Hypnois', 'Dream Eater', 'Psychic', 'Tri Attack'];
|
||||
break;
|
||||
case 'Hypno':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Hypnosis', 'Headbutt', 'Dream Eater', 'Meditate'];
|
||||
break;
|
||||
case 'Krabby':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Crabhammer', 'Guillotine', 'Double-Edge', 'Blizzard'];
|
||||
break;
|
||||
case 'Kingler':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Crabhammer', 'Guillotine', 'Stomp', 'Substitute'];
|
||||
break;
|
||||
case 'Voltorb':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Thunderbolt', 'Thunder Wave', 'Swift', 'Explosion'];
|
||||
break;
|
||||
case 'Electrode':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Thunder', 'Thunder Wave', 'Swift', 'Self-Destruct'];
|
||||
break;
|
||||
case 'Exeggcute':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Psychic', 'Explosion', 'Leech Seed', 'Toxic'];
|
||||
break;
|
||||
case 'Exeggutor':
|
||||
set.evs = { hp: 105, atk: 104, def: 104, spa: 104, spd: 104, spe: 104 };
|
||||
set.ivs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 };
|
||||
set.moves = ['Mega Drain', 'Stun Spore', 'Leech Seed', 'Egg Bomb'];
|
||||
break;
|
||||
case 'Cubone':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Earthquake', 'Submission', 'Blizzard', 'Strength'];
|
||||
break;
|
||||
case 'Marowak':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Bonemerang', 'Thrash', 'Fire Blast', 'Focus Energy'];
|
||||
break;
|
||||
case 'Hitmonlee':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['High Jump Kick', 'Mega Kick', 'Metronome', 'Seismic Toss'];
|
||||
break;
|
||||
case 'Hitmonchan':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Submission', 'Thunder Punch', 'Ice Punch', 'Strength'];
|
||||
break;
|
||||
case 'Lickitung':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Strength', 'Blizzard', 'Thunder', 'Fire Blast'];
|
||||
break;
|
||||
case 'Koffing':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Sludge', 'Toxic', 'Thunderbolt', 'Explosion'];
|
||||
break;
|
||||
case 'Weezing':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Sludge', 'Hyper Beam', 'Fire Blast', 'Self-Destruct'];
|
||||
break;
|
||||
case 'Rhyhorn':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Earthquake', 'Body Slam', 'Rock Slide', 'Fire Blast'];
|
||||
break;
|
||||
case 'Rhydon':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Dig', 'Strength', 'Thunder', 'Surf'];
|
||||
break;
|
||||
case 'Chansey':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Thunder', 'Fire Blast', 'Minimize', 'Rest'];
|
||||
break;
|
||||
case 'Tangela':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Mega Drain', 'Growth', 'Toxic', 'Double-Edge'];
|
||||
break;
|
||||
case 'Kangaskhan':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Dizzy Punch', 'Rock Slide', 'Surf', 'Thunderbolt'];
|
||||
break;
|
||||
case 'Horsea':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Hydro Pump', 'Toxic', 'Smokescreen', 'Ice Beam'];
|
||||
break;
|
||||
case 'Seadra':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Surf', 'Toxic', 'Smokescreen', 'Swift'];
|
||||
break;
|
||||
case 'Goldeen':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Surf', 'Supersonic', 'Horn Drill', 'Blizzard'];
|
||||
break;
|
||||
case 'Seaking':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Waterfall', 'Supersonic', 'Horn Attack', 'Ice Beam'];
|
||||
break;
|
||||
case 'Staryu':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Hydro Pump', 'Recover', 'Thunderbolt', 'Psychic'];
|
||||
break;
|
||||
case 'Starmie':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Surf', 'Thunder', 'Swift', 'Harden'];
|
||||
break;
|
||||
case 'Mr. Mime':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Barrier', 'Psychic', 'Metronome', 'Seismic Toss'];
|
||||
break;
|
||||
case 'Scyther':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Slash', 'Wing Attack', 'Leer', 'Double Team'];
|
||||
break;
|
||||
case 'Jynx':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Ice Punch', 'Mega Punch', 'Psychic', 'Lovely Kiss'];
|
||||
break;
|
||||
case 'Electabuzz':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Thunder Punch', 'Mega Punch', 'Psychic', 'Thunder Wave'];
|
||||
break;
|
||||
case 'Magmar':
|
||||
set.evs = { hp: 121, atk: 120, def: 120, spa: 120, spd: 120, spe: 120 };
|
||||
set.ivs = { hp: 6, atk: 8, def: 8, spa: 6, spd: 6, spe: 6 };
|
||||
set.moves = ['Fire Punch', 'Mega Punch', 'Psychic', 'Smokescreen'];
|
||||
break;
|
||||
case 'Pinsir':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Strength', 'Harden', 'Seismic Toss', 'Guillotine'];
|
||||
break;
|
||||
case 'Tauros':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Double-Edge', 'Fire Blast', 'Tail Whip', 'Bide'];
|
||||
break;
|
||||
case 'Magikarp':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Splash', 'Tackle'];
|
||||
break;
|
||||
case 'Gyarados':
|
||||
set.evs = { hp: 105, atk: 104, def: 104, spa: 104, spd: 104, spe: 104 };
|
||||
set.ivs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 };
|
||||
set.moves = ['Surf', 'Dragon Rage', 'Bite', 'Fire Blast'];
|
||||
break;
|
||||
case 'Lapras':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Ice Beam', 'Solar Beam', 'Body Slam', 'Sing'];
|
||||
break;
|
||||
case 'Ditto':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Transform'];
|
||||
break;
|
||||
case 'Eevee':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Body Slam', 'Swift', 'Sand Attack', 'Toxic'];
|
||||
break;
|
||||
case 'Vaporeon':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Surf', 'Quick Attack', 'Sand Attack', 'Acid Armor'];
|
||||
break;
|
||||
case 'Jolteon':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Thunderbolt', 'Pin Missile', 'Toxic', 'Sand Attack'];
|
||||
break;
|
||||
case 'Flareon':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Fire Blast', 'Take Down', 'Smog', 'Sand Attack'];
|
||||
break;
|
||||
case 'Omanyte':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Surf', 'Ice Beam', 'Double Edge', 'Double Team'];
|
||||
break;
|
||||
case 'Omastar':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Hydro Pump', 'Submission', 'Spike Cannon', 'Withdraw'];
|
||||
break;
|
||||
case 'Kabuto':
|
||||
set.evs = { hp: 145, atk: 144, def: 144, spa: 144, spd: 144, spe: 144 };
|
||||
set.ivs = { hp: 12, atk: 12, def: 10, spa: 12, spd: 12, spe: 10 };
|
||||
set.moves = ['Hydro Pump', 'Blizzard', 'Slash', 'Double Team'];
|
||||
break;
|
||||
case 'Kabutops':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Surf', 'Swords Dance', 'Mega Kick', 'Submission'];
|
||||
break;
|
||||
case 'Aerodactyl':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Fly', 'Hyper Beam', 'Supersonic', 'Dragon Rage'];
|
||||
break;
|
||||
case 'Snorlax':
|
||||
set.evs = { hp: 113, atk: 112, def: 112, spa: 112, spd: 112, spe: 112 };
|
||||
set.ivs = { hp: 4, atk: 4, def: 4, spa: 4, spd: 4, spe: 6 };
|
||||
set.moves = ['Mega Kick', 'Rock Slide', 'Metronome', 'Rest'];
|
||||
break;
|
||||
case 'Articuno':
|
||||
set.evs = { hp: 97, atk: 96, def: 96, spa: 96, spd: 96, spe: 96 };
|
||||
set.ivs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 };
|
||||
set.moves = ['Ice Beam', 'Sky Attack', 'Razor Wind', 'Substitute'];
|
||||
break;
|
||||
case 'Zapdos':
|
||||
set.evs = { hp: 97, atk: 96, def: 96, spa: 96, spd: 96, spe: 96 };
|
||||
set.ivs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 };
|
||||
set.moves = ['Thunderbolt', 'Sky Attack', 'Thunder Wave', 'Flash'];
|
||||
break;
|
||||
case 'Moltres':
|
||||
set.evs = { hp: 97, atk: 96, def: 96, spa: 96, spd: 96, spe: 96 };
|
||||
set.ivs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 };
|
||||
set.moves = ['Fire Blast', 'Fly', 'Swift', 'Substitute'];
|
||||
break;
|
||||
case 'Dratini':
|
||||
set.evs = { hp: 161, atk: 160, def: 160, spa: 160, spd: 160, spe: 160 };
|
||||
set.ivs = { hp: 14, atk: 12, def: 14, spa: 14, spd: 14, spe: 14 };
|
||||
set.moves = ['Hyper Beam', 'Body Slam', 'Thunderbolt', 'Thunder Wave'];
|
||||
break;
|
||||
case 'Dragonair':
|
||||
set.evs = { hp: 129, atk: 128, def: 128, spa: 128, spd: 128, spe: 128 };
|
||||
set.ivs = { hp: 10, atk: 8, def: 10, spa: 10, spd: 10, spe: 8 };
|
||||
set.moves = ['Hyper Beam', 'Swift', 'Ice Beam', 'Thunder Wave'];
|
||||
break;
|
||||
case 'Dragonite':
|
||||
set.evs = { hp: 97, atk: 96, def: 96, spa: 96, spd: 96, spe: 96 };
|
||||
set.ivs = { hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0 };
|
||||
set.moves = ['Slam', 'Dragon Rage', 'Thunder', 'Agility'];
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (sourceEffect) attrs += `|[from]${this.battle.dex.conditions.get(sourceEffect)}`;
|
||||
if (sourceEffect) attrs += `|[from] ${this.battle.dex.conditions.get(sourceEffect).name}`;
|
||||
this.battle.addMove('move', pokemon, move.name, `${target}${attrs}`);
|
||||
|
||||
if (!this.battle.singleEvent('Try', move, null, pokemon, target, move)) {
|
||||
|
|
@ -231,10 +231,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!move.negateSecondary) {
|
||||
this.battle.singleEvent('AfterMoveSecondarySelf', move, null, pokemon, target, move);
|
||||
this.battle.runEvent('AfterMoveSecondarySelf', pokemon, target, move);
|
||||
}
|
||||
this.battle.singleEvent('AfterMoveSecondarySelf', move, null, pokemon, target, move);
|
||||
this.battle.runEvent('AfterMoveSecondarySelf', pokemon, target, move);
|
||||
return true;
|
||||
},
|
||||
tryMoveHit(target, pokemon, move) {
|
||||
|
|
@ -252,10 +250,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
|
||||
// Then, check if the Pokemon is immune to this move.
|
||||
if (
|
||||
(!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) &&
|
||||
!target.runImmunity(move.type, true)
|
||||
) {
|
||||
if (!target.runImmunity(move, true)) {
|
||||
if (move.selfdestruct) {
|
||||
this.battle.faint(pokemon, pokemon, move);
|
||||
}
|
||||
|
|
@ -305,10 +300,16 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
accuracy = this.battle.runEvent('Accuracy', target, pokemon, move, accuracy);
|
||||
|
||||
// Stadium fixes the 1/256 accuracy bug.
|
||||
if (accuracy !== true && !this.battle.randomChance(accuracy + 1, 256)) {
|
||||
// Stadium attempts to fix the 1/256 miss by rerolling if the first value
|
||||
// would trigger the 1/256 miss.
|
||||
let randomValue = this.battle.random(256);
|
||||
if (randomValue === 256) randomValue = this.battle.random(256);
|
||||
if (accuracy !== true && randomValue > accuracy) {
|
||||
this.battle.attrLastMove('[miss]');
|
||||
this.battle.add('-miss', pokemon);
|
||||
if (accuracy === 255) {
|
||||
this.battle.hint("In Pokemon Stadium, moves with 100% accuracy can still miss 1/65536 of the time.");
|
||||
}
|
||||
damage = false;
|
||||
this.battle.lastDamage = 0;
|
||||
}
|
||||
|
|
@ -365,10 +366,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
|
||||
if (move.ohko) this.battle.add('-ohko');
|
||||
|
||||
if (!move.negateSecondary) {
|
||||
this.battle.singleEvent('AfterMoveSecondary', move, null, target, pokemon, move);
|
||||
this.battle.runEvent('AfterMoveSecondary', target, pokemon, move);
|
||||
}
|
||||
this.battle.singleEvent('AfterMoveSecondary', move, null, target, pokemon, move);
|
||||
this.battle.runEvent('AfterMoveSecondary', target, pokemon, move);
|
||||
|
||||
return damage;
|
||||
},
|
||||
|
|
@ -549,10 +548,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
|
||||
// Let's see if the target is immune to the move.
|
||||
if (!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) {
|
||||
if (!target.runImmunity(move.type, true)) {
|
||||
return false;
|
||||
}
|
||||
if (!target.runImmunity(move, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is it an OHKO move?
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
inherit: true,
|
||||
onBeforeMovePriority: 2,
|
||||
onBeforeMove(pokemon) {
|
||||
if (this.randomChance(1, 4)) {
|
||||
if (this.randomChance(63, 256)) {
|
||||
this.add('cant', pokemon, 'par');
|
||||
return false;
|
||||
}
|
||||
|
|
@ -177,6 +177,11 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
onStart(target, source, effect) {
|
||||
this.effectState.move = effect.id;
|
||||
},
|
||||
onAfterMove(pokemon) {
|
||||
if (this.effectState.duration === 1) {
|
||||
pokemon.removeVolatile('lockedmove');
|
||||
}
|
||||
},
|
||||
onEnd(target) {
|
||||
// Confusion begins even if already confused
|
||||
delete target.volatiles['confusion'];
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
charmeleon: {
|
||||
tier: "ZU",
|
||||
tier: "ZUBL",
|
||||
},
|
||||
charizard: {
|
||||
tier: "UUBL",
|
||||
|
|
@ -21,7 +21,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
wartortle: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
blastoise: {
|
||||
tier: "UU",
|
||||
|
|
@ -57,7 +57,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
raticate: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
},
|
||||
spearow: {
|
||||
tier: "LC",
|
||||
|
|
@ -69,7 +69,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
arbok: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
},
|
||||
pichu: {
|
||||
tier: "LC",
|
||||
|
|
@ -162,7 +162,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "PU",
|
||||
},
|
||||
diglett: {
|
||||
tier: "ZU",
|
||||
tier: "LC",
|
||||
},
|
||||
dugtrio: {
|
||||
tier: "NU",
|
||||
|
|
@ -192,10 +192,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UU",
|
||||
},
|
||||
poliwag: {
|
||||
tier: "ZU",
|
||||
tier: "ZUBL",
|
||||
},
|
||||
poliwhirl: {
|
||||
tier: "ZUBL",
|
||||
tier: "PUBL",
|
||||
},
|
||||
poliwrath: {
|
||||
tier: "NUBL",
|
||||
|
|
@ -237,7 +237,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UUBL",
|
||||
},
|
||||
geodude: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
graveler: {
|
||||
tier: "NU",
|
||||
|
|
@ -246,13 +246,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "OU",
|
||||
},
|
||||
ponyta: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
},
|
||||
rapidash: {
|
||||
tier: "NU",
|
||||
},
|
||||
slowpoke: {
|
||||
tier: "ZU",
|
||||
tier: "LC",
|
||||
},
|
||||
slowbro: {
|
||||
tier: "UU",
|
||||
|
|
@ -267,7 +267,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UU",
|
||||
},
|
||||
farfetchd: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
},
|
||||
doduo: {
|
||||
tier: "ZU",
|
||||
|
|
@ -321,7 +321,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NU",
|
||||
},
|
||||
voltorb: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
electrode: {
|
||||
tier: "UU",
|
||||
|
|
@ -345,10 +345,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NU",
|
||||
},
|
||||
hitmonchan: {
|
||||
tier: "PUBL",
|
||||
tier: "PU",
|
||||
},
|
||||
hitmontop: {
|
||||
tier: "PU",
|
||||
tier: "NU",
|
||||
},
|
||||
lickitung: {
|
||||
tier: "NU",
|
||||
|
|
@ -513,7 +513,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
bayleef: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
meganium: {
|
||||
tier: "UUBL",
|
||||
|
|
@ -534,13 +534,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "ZU",
|
||||
},
|
||||
feraligatr: {
|
||||
tier: "NUBL",
|
||||
tier: "UU",
|
||||
},
|
||||
sentret: {
|
||||
tier: "LC",
|
||||
},
|
||||
furret: {
|
||||
tier: "PUBL",
|
||||
tier: "PU",
|
||||
},
|
||||
hoothoot: {
|
||||
tier: "LC",
|
||||
|
|
@ -558,7 +558,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
ariados: {
|
||||
tier: "PU",
|
||||
tier: "ZUBL",
|
||||
},
|
||||
chinchou: {
|
||||
tier: "NU",
|
||||
|
|
@ -591,7 +591,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
azumarill: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
},
|
||||
sudowoodo: {
|
||||
tier: "NU",
|
||||
|
|
@ -645,7 +645,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "OU",
|
||||
},
|
||||
dunsparce: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
},
|
||||
gligar: {
|
||||
tier: "UU",
|
||||
|
|
@ -699,13 +699,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "PU",
|
||||
},
|
||||
mantine: {
|
||||
tier: "ZU",
|
||||
tier: "ZUBL",
|
||||
},
|
||||
skarmory: {
|
||||
tier: "OU",
|
||||
},
|
||||
houndour: {
|
||||
tier: "NU",
|
||||
tier: "PU",
|
||||
},
|
||||
houndoom: {
|
||||
tier: "UUBL",
|
||||
|
|
|
|||
|
|
@ -252,11 +252,11 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
}
|
||||
},
|
||||
},
|
||||
berserkgene: {
|
||||
berry: {
|
||||
inherit: true,
|
||||
isNonstandard: null,
|
||||
},
|
||||
berry: {
|
||||
berserkgene: {
|
||||
inherit: true,
|
||||
isNonstandard: null,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -51,64 +51,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
bide: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 3,
|
||||
inherit: true,
|
||||
durationCallback(target, source, effect) {
|
||||
return this.random(3, 5);
|
||||
},
|
||||
onLockMove: 'bide',
|
||||
onStart(pokemon) {
|
||||
this.effectState.totalDamage = 0;
|
||||
this.add('-start', pokemon, 'move: Bide');
|
||||
},
|
||||
onDamagePriority: -101,
|
||||
onDamage(damage, target, source, move) {
|
||||
if (!move || move.effectType !== 'Move' || !source) return;
|
||||
this.effectState.totalDamage += damage;
|
||||
this.effectState.lastDamageSource = source;
|
||||
},
|
||||
onBeforeMove(pokemon, target, move) {
|
||||
if (this.effectState.duration === 1) {
|
||||
this.add('-end', pokemon, 'move: Bide');
|
||||
if (!this.effectState.totalDamage) {
|
||||
this.add('-fail', pokemon);
|
||||
return false;
|
||||
}
|
||||
target = this.effectState.lastDamageSource;
|
||||
if (!target) {
|
||||
this.add('-fail', pokemon);
|
||||
return false;
|
||||
}
|
||||
if (!target.isActive) {
|
||||
const possibleTarget = this.getRandomTarget(pokemon, this.dex.moves.get('pound'));
|
||||
if (!possibleTarget) {
|
||||
this.add('-miss', pokemon);
|
||||
return false;
|
||||
}
|
||||
target = possibleTarget;
|
||||
}
|
||||
const moveData = {
|
||||
id: 'bide',
|
||||
name: "Bide",
|
||||
accuracy: 100,
|
||||
damage: this.effectState.totalDamage * 2,
|
||||
category: "Physical",
|
||||
priority: 0,
|
||||
flags: { contact: 1, protect: 1 },
|
||||
effectType: 'Move',
|
||||
type: 'Normal',
|
||||
} as unknown as ActiveMove;
|
||||
this.actions.tryMoveHit(target, pokemon, moveData);
|
||||
pokemon.removeVolatile('bide');
|
||||
return false;
|
||||
}
|
||||
this.add('-activate', pokemon, 'move: Bide');
|
||||
},
|
||||
onMoveAborted(pokemon) {
|
||||
pokemon.removeVolatile('bide');
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
this.add('-end', pokemon, 'move: Bide', '[silent]');
|
||||
},
|
||||
},
|
||||
},
|
||||
counter: {
|
||||
|
|
@ -139,12 +85,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
curse: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onStart(pokemon, source) {
|
||||
this.add('-start', pokemon, 'Curse', `[of] ${source}`);
|
||||
},
|
||||
inherit: true,
|
||||
onAfterMoveSelfPriority: 0, // explicit
|
||||
onAfterMoveSelf(pokemon) {
|
||||
this.damage(pokemon.baseMaxhp / 4);
|
||||
},
|
||||
onResidual() {},
|
||||
},
|
||||
},
|
||||
detect: {
|
||||
|
|
@ -157,10 +103,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
return source.status !== 'slp';
|
||||
},
|
||||
condition: {
|
||||
duration: 2,
|
||||
onImmunity(type, pokemon) {
|
||||
if (type === 'sandstorm') return false;
|
||||
},
|
||||
inherit: true,
|
||||
onInvulnerability(target, source, move) {
|
||||
if (move.id === 'earthquake' || move.id === 'magnitude' || move.id === 'fissure') {
|
||||
return;
|
||||
|
|
@ -172,6 +115,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
if (source.volatiles['lockon'] && target === source.volatiles['lockon'].source) return;
|
||||
return false;
|
||||
},
|
||||
onSourceModifyDamage() {},
|
||||
onSourceBasePower(basePower, target, source, move) {
|
||||
if (move.id === 'earthquake' || move.id === 'magnitude') {
|
||||
return this.chainModify(2);
|
||||
|
|
@ -186,43 +130,19 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
encore: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
durationCallback() {
|
||||
return this.random(3, 7);
|
||||
},
|
||||
inherit: true,
|
||||
onStart(target) {
|
||||
const lockedMove = target.lastMoveEncore?.id || '';
|
||||
const moveIndex = lockedMove ? target.moves.indexOf(lockedMove) : -1;
|
||||
if (moveIndex < 0 || target.lastMoveEncore?.flags['failencore'] || target.moveSlots[moveIndex].pp <= 0) {
|
||||
const moveSlot = lockedMove ? target.getMoveData(lockedMove) : null;
|
||||
if (!moveSlot || target.lastMoveEncore?.flags['failencore'] || moveSlot.pp <= 0) {
|
||||
// it failed
|
||||
return false;
|
||||
}
|
||||
this.effectState.move = lockedMove;
|
||||
this.add('-start', target, 'Encore');
|
||||
},
|
||||
onOverrideAction(pokemon) {
|
||||
return this.effectState.move;
|
||||
},
|
||||
onResidualOrder: 13,
|
||||
onResidual(target) {
|
||||
const lockedMoveIndex = target.moves.indexOf(this.effectState.move);
|
||||
if (lockedMoveIndex >= 0 && target.moveSlots[lockedMoveIndex].pp <= 0) {
|
||||
// early termination if you run out of PP
|
||||
target.removeVolatile('encore');
|
||||
}
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Encore');
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) {
|
||||
return;
|
||||
}
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id !== this.effectState.move) {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
onResidualSubOrder: undefined,
|
||||
},
|
||||
},
|
||||
endure: {
|
||||
|
|
@ -244,7 +164,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
return source.status !== 'slp';
|
||||
},
|
||||
condition: {
|
||||
duration: 2,
|
||||
inherit: true,
|
||||
onInvulnerability(target, source, move) {
|
||||
if (move.id === 'gust' || move.id === 'twister' || move.id === 'thunder' || move.id === 'whirlwind') {
|
||||
return;
|
||||
|
|
@ -260,6 +180,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
if (source.volatiles['lockon'] && target === source.volatiles['lockon'].source) return;
|
||||
return false;
|
||||
},
|
||||
onSourceModifyDamage() {},
|
||||
onSourceBasePower(basePower, target, source, move) {
|
||||
if (move.id === 'gust' || move.id === 'twister') {
|
||||
return this.chainModify(2);
|
||||
|
|
@ -270,9 +191,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
focusenergy: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onStart(pokemon) {
|
||||
this.add('-start', pokemon, 'move: Focus Energy');
|
||||
},
|
||||
inherit: true,
|
||||
onModifyCritRatio(critRatio) {
|
||||
return critRatio + 1;
|
||||
},
|
||||
|
|
@ -284,17 +203,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
if (target.volatiles['foresight']) return false;
|
||||
},
|
||||
condition: {
|
||||
onStart(pokemon) {
|
||||
this.add('-start', pokemon, 'Foresight');
|
||||
},
|
||||
onNegateImmunity(pokemon, type) {
|
||||
if (pokemon.hasType('Ghost') && ['Normal', 'Fighting'].includes(type)) return false;
|
||||
},
|
||||
onModifyBoost(boosts) {
|
||||
if (boosts.evasion && boosts.evasion > 0) {
|
||||
boosts.evasion = 0;
|
||||
}
|
||||
},
|
||||
inherit: true,
|
||||
noCopy: false,
|
||||
},
|
||||
},
|
||||
frustration: {
|
||||
|
|
@ -340,9 +250,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
onHit() {},
|
||||
condition: {
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'move: Leech Seed');
|
||||
},
|
||||
inherit: true,
|
||||
onResidual() {},
|
||||
onAfterMoveSelfPriority: 2,
|
||||
onAfterMoveSelf(pokemon) {
|
||||
if (!pokemon.hp) return;
|
||||
|
|
@ -378,10 +287,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
if (target.volatiles['foresight'] || target.volatiles['lockon']) return false;
|
||||
},
|
||||
condition: {
|
||||
duration: 2,
|
||||
onSourceAccuracy(accuracy, target, source, move) {
|
||||
if (move && source === this.effectState.target && target === this.effectState.source) return true;
|
||||
},
|
||||
inherit: true,
|
||||
onSourceInvulnerability() {},
|
||||
},
|
||||
},
|
||||
lowkick: {
|
||||
|
|
@ -449,15 +356,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
},
|
||||
mist: {
|
||||
num: 54,
|
||||
accuracy: true,
|
||||
basePower: 0,
|
||||
category: "Status",
|
||||
name: "Mist",
|
||||
pp: 30,
|
||||
priority: 0,
|
||||
flags: { metronome: 1 },
|
||||
inherit: true,
|
||||
volatileStatus: 'mist',
|
||||
sideCondition: undefined,
|
||||
condition: {
|
||||
onStart(pokemon) {
|
||||
this.add('-start', pokemon, 'Mist');
|
||||
|
|
@ -478,9 +379,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
},
|
||||
},
|
||||
secondary: null,
|
||||
target: "self",
|
||||
type: "Ice",
|
||||
},
|
||||
moonlight: {
|
||||
inherit: true,
|
||||
|
|
@ -509,13 +408,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
nightmare: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
noCopy: true,
|
||||
onStart(pokemon) {
|
||||
if (pokemon.status !== 'slp') {
|
||||
return false;
|
||||
}
|
||||
this.add('-start', pokemon, 'Nightmare');
|
||||
},
|
||||
inherit: true,
|
||||
onResidual() {},
|
||||
onAfterMoveSelfPriority: 1,
|
||||
onAfterMoveSelf(pokemon) {
|
||||
if (pokemon.status === 'slp') this.damage(pokemon.baseMaxhp / 4);
|
||||
|
|
@ -527,11 +421,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
onMoveFail(target, source, move) {
|
||||
source.addVolatile('lockedmove');
|
||||
},
|
||||
onAfterMove(pokemon) {
|
||||
if (pokemon.volatiles['lockedmove'] && pokemon.volatiles['lockedmove'].duration === 1) {
|
||||
pokemon.removeVolatile('lockedmove');
|
||||
}
|
||||
},
|
||||
},
|
||||
painsplit: {
|
||||
inherit: true,
|
||||
|
|
@ -540,16 +429,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
perishsong: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 4,
|
||||
onEnd(target) {
|
||||
this.add('-start', target, 'perish0');
|
||||
target.faint();
|
||||
},
|
||||
inherit: true,
|
||||
onResidualOrder: 4,
|
||||
onResidual(pokemon) {
|
||||
const duration = pokemon.volatiles['perishsong'].duration;
|
||||
this.add('-start', pokemon, `perish${duration}`);
|
||||
},
|
||||
},
|
||||
},
|
||||
petaldance: {
|
||||
|
|
@ -557,11 +438,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
onMoveFail(target, source, move) {
|
||||
source.addVolatile('lockedmove');
|
||||
},
|
||||
onAfterMove(pokemon) {
|
||||
if (pokemon.volatiles['lockedmove'] && pokemon.volatiles['lockedmove'].duration === 1) {
|
||||
pokemon.removeVolatile('lockedmove');
|
||||
}
|
||||
},
|
||||
},
|
||||
poisongas: {
|
||||
inherit: true,
|
||||
|
|
@ -583,9 +459,18 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
pursuit: {
|
||||
inherit: true,
|
||||
beforeTurnCallback(pokemon, target) {
|
||||
if (pokemon.isAlly(target)) return;
|
||||
target.addVolatile('pursuit');
|
||||
const data = target.volatiles['pursuit'];
|
||||
if (!data.sources) {
|
||||
data.sources = [];
|
||||
}
|
||||
data.sources.push(pokemon);
|
||||
},
|
||||
onModifyMove() {},
|
||||
condition: {
|
||||
duration: 1,
|
||||
inherit: true,
|
||||
onBeforeSwitchOut(pokemon) {
|
||||
this.debug('Pursuit start');
|
||||
let alreadyAdded = false;
|
||||
|
|
@ -685,41 +570,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
safeguard: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
durationCallback(target, source, effect) {
|
||||
if (source?.hasAbility('persistent')) {
|
||||
this.add('-activate', source, 'ability: Persistent', effect);
|
||||
return 7;
|
||||
}
|
||||
return 5;
|
||||
},
|
||||
onSetStatus(status, target, source, effect) {
|
||||
if (!effect || !source) return;
|
||||
if (effect.id === 'yawn') return;
|
||||
if (effect.effectType === 'Move' && effect.infiltrates && !target.isAlly(source)) return;
|
||||
if (target !== source) {
|
||||
this.debug('interrupting setStatus');
|
||||
if (effect.id === 'synchronize' || (effect.effectType === 'Move' && !effect.secondaries)) {
|
||||
this.add('-activate', target, 'move: Safeguard');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
onTryAddVolatile(status, target, source, effect) {
|
||||
if (!effect || !source) return;
|
||||
if (effect.effectType === 'Move' && effect.infiltrates && !target.isAlly(source)) return;
|
||||
if ((status.id === 'confusion' || status.id === 'yawn') && target !== source) {
|
||||
if (effect.effectType === 'Move' && !effect.secondaries) this.add('-activate', target, 'move: Safeguard');
|
||||
return null;
|
||||
}
|
||||
},
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'Safeguard');
|
||||
},
|
||||
inherit: true,
|
||||
onSideResidualOrder: 8,
|
||||
onSideEnd(side) {
|
||||
this.add('-sideend', side, 'Safeguard');
|
||||
},
|
||||
},
|
||||
},
|
||||
selfdestruct: {
|
||||
|
|
@ -785,31 +637,14 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
spikes: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
if (!this.effectState.layers || this.effectState.layers === 0) {
|
||||
this.add('-sidestart', side, 'Spikes');
|
||||
this.effectState.layers = 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.runImmunity('Ground')) return;
|
||||
const damageAmounts = [0, 3];
|
||||
this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
|
||||
},
|
||||
inherit: true,
|
||||
onSideRestart: undefined,
|
||||
},
|
||||
},
|
||||
substitute: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'Substitute');
|
||||
this.effectState.hp = Math.floor(target.maxhp / 4);
|
||||
delete target.volatiles['partiallytrapped'];
|
||||
},
|
||||
onTryPrimaryHitPriority: -1,
|
||||
inherit: true,
|
||||
onTryPrimaryHit(target, source, move) {
|
||||
if (move.stallingMove) {
|
||||
this.add('-fail', source);
|
||||
|
|
@ -846,10 +681,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
if (!damage) {
|
||||
return null;
|
||||
}
|
||||
damage = this.runEvent('SubDamage', target, source, move, damage);
|
||||
if (!damage) {
|
||||
return damage;
|
||||
}
|
||||
if (damage > target.volatiles['substitute'].hp) {
|
||||
damage = target.volatiles['substitute'].hp as number;
|
||||
}
|
||||
|
|
@ -866,9 +697,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.runEvent('AfterSubDamage', target, source, move, damage);
|
||||
return this.HIT_SUBSTITUTE;
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Substitute');
|
||||
},
|
||||
},
|
||||
},
|
||||
swagger: {
|
||||
|
|
@ -918,11 +746,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
onMoveFail(target, source, move) {
|
||||
source.addVolatile('lockedmove');
|
||||
},
|
||||
onAfterMove(pokemon) {
|
||||
if (pokemon.volatiles['lockedmove'] && pokemon.volatiles['lockedmove'].duration === 1) {
|
||||
pokemon.removeVolatile('lockedmove');
|
||||
}
|
||||
},
|
||||
},
|
||||
toxic: {
|
||||
inherit: true,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
|
|||
standard: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard',
|
||||
ruleset: ['Obtainable', 'Sleep Clause Mod', 'Freeze Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause', 'Endless battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Sleep Clause Mod', 'Freeze Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
banlist: [
|
||||
'Hypnosis + Mean Look',
|
||||
'Hypnosis + Spider Web',
|
||||
|
|
|
|||
|
|
@ -187,10 +187,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
move.ignoreImmunity = (move.category === 'Status');
|
||||
}
|
||||
|
||||
if (
|
||||
(!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) &&
|
||||
!target.runImmunity(move.type, true)
|
||||
) {
|
||||
if (!target.runImmunity(move, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -206,6 +203,11 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (move.ohko && pokemon.level < target.level) {
|
||||
this.battle.add('-immune', target, '[ohko]');
|
||||
return false;
|
||||
}
|
||||
|
||||
let accuracy = move.accuracy;
|
||||
if (move.alwaysHit) {
|
||||
accuracy = true;
|
||||
|
|
@ -216,13 +218,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
if (accuracy !== true) {
|
||||
accuracy = Math.floor(accuracy * 255 / 100);
|
||||
if (move.ohko) {
|
||||
if (pokemon.level >= target.level) {
|
||||
accuracy += (pokemon.level - target.level) * 2;
|
||||
accuracy = Math.min(accuracy, 255);
|
||||
} else {
|
||||
this.battle.add('-immune', target, '[ohko]');
|
||||
return false;
|
||||
}
|
||||
accuracy += (pokemon.level - target.level) * 2;
|
||||
accuracy = Math.min(accuracy, 255);
|
||||
}
|
||||
if (!move.ignoreAccuracy) {
|
||||
if (pokemon.boosts.accuracy > 0) {
|
||||
|
|
@ -296,10 +293,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
if (move.ohko) this.battle.add('-ohko');
|
||||
|
||||
if (!move.negateSecondary) {
|
||||
this.battle.singleEvent('AfterMoveSecondary', move, null, target, pokemon, move);
|
||||
this.battle.runEvent('AfterMoveSecondary', target, pokemon, move);
|
||||
}
|
||||
this.battle.singleEvent('AfterMoveSecondary', move, null, target, pokemon, move);
|
||||
this.battle.runEvent('AfterMoveSecondary', target, pokemon, move);
|
||||
|
||||
if (move.recoil && move.totalDamage) {
|
||||
this.battle.damage(this.calcRecoilDamage(move.totalDamage, move, pokemon), pokemon, target, 'recoil');
|
||||
|
|
@ -497,10 +492,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
|
||||
// Let's test for immunities.
|
||||
if (!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) {
|
||||
if (!target.runImmunity(move.type, true)) {
|
||||
return false;
|
||||
}
|
||||
if (!target.runImmunity(move, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is it an OHKO move?
|
||||
|
|
|
|||
|
|
@ -1,898 +0,0 @@
|
|||
export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormatsDataTable = {
|
||||
bulbasaur: {
|
||||
tier: "LC",
|
||||
},
|
||||
ivysaur: {
|
||||
tier: "NFE",
|
||||
},
|
||||
venusaur: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
charmander: {
|
||||
tier: "LC",
|
||||
},
|
||||
charmeleon: {
|
||||
tier: "NFE",
|
||||
},
|
||||
charizard: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
squirtle: {
|
||||
tier: "LC",
|
||||
},
|
||||
wartortle: {
|
||||
tier: "NFE",
|
||||
},
|
||||
blastoise: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
caterpie: {
|
||||
tier: "LC",
|
||||
},
|
||||
metapod: {
|
||||
tier: "NFE",
|
||||
},
|
||||
butterfree: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
weedle: {
|
||||
tier: "LC",
|
||||
},
|
||||
kakuna: {
|
||||
tier: "NFE",
|
||||
},
|
||||
beedrill: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
pidgey: {
|
||||
tier: "LC",
|
||||
},
|
||||
pidgeotto: {
|
||||
tier: "NFE",
|
||||
},
|
||||
pidgeot: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
rattata: {
|
||||
tier: "LC",
|
||||
},
|
||||
raticate: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
spearow: {
|
||||
tier: "LC",
|
||||
},
|
||||
fearow: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
ekans: {
|
||||
tier: "LC",
|
||||
},
|
||||
arbok: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
pichu: {
|
||||
tier: "LC",
|
||||
},
|
||||
pikachu: {
|
||||
tier: "OU",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
raichu: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
sandshrew: {
|
||||
tier: "LC",
|
||||
},
|
||||
sandslash: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
nidoranf: {
|
||||
tier: "LC",
|
||||
},
|
||||
nidorina: {
|
||||
tier: "NFE",
|
||||
},
|
||||
nidoqueen: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
nidoranm: {
|
||||
tier: "LC",
|
||||
},
|
||||
nidorino: {
|
||||
tier: "NFE",
|
||||
},
|
||||
nidoking: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
cleffa: {
|
||||
tier: "LC",
|
||||
},
|
||||
clefairy: {
|
||||
tier: "NFE",
|
||||
},
|
||||
clefable: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
vulpix: {
|
||||
tier: "LC",
|
||||
},
|
||||
ninetales: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
igglybuff: {
|
||||
tier: "LC",
|
||||
},
|
||||
jigglypuff: {
|
||||
tier: "NFE",
|
||||
},
|
||||
wigglytuff: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
zubat: {
|
||||
tier: "LC",
|
||||
},
|
||||
golbat: {
|
||||
tier: "NFE",
|
||||
},
|
||||
crobat: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
oddish: {
|
||||
tier: "LC",
|
||||
},
|
||||
gloom: {
|
||||
tier: "NFE",
|
||||
},
|
||||
vileplume: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
bellossom: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
paras: {
|
||||
tier: "LC",
|
||||
},
|
||||
parasect: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
venonat: {
|
||||
tier: "LC",
|
||||
},
|
||||
venomoth: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
diglett: {
|
||||
tier: "LC",
|
||||
},
|
||||
dugtrio: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
meowth: {
|
||||
tier: "LC",
|
||||
},
|
||||
persian: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
psyduck: {
|
||||
tier: "LC",
|
||||
},
|
||||
golduck: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
mankey: {
|
||||
tier: "LC",
|
||||
},
|
||||
primeape: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
growlithe: {
|
||||
tier: "LC",
|
||||
},
|
||||
arcanine: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
poliwag: {
|
||||
tier: "LC",
|
||||
},
|
||||
poliwhirl: {
|
||||
tier: "NFE",
|
||||
},
|
||||
poliwrath: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
politoed: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
abra: {
|
||||
tier: "LC",
|
||||
},
|
||||
kadabra: {
|
||||
tier: "OU",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
alakazam: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
machop: {
|
||||
tier: "LC",
|
||||
},
|
||||
machoke: {
|
||||
tier: "NFE",
|
||||
},
|
||||
machamp: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
bellsprout: {
|
||||
tier: "LC",
|
||||
},
|
||||
weepinbell: {
|
||||
tier: "NFE",
|
||||
},
|
||||
victreebel: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
tentacool: {
|
||||
tier: "LC",
|
||||
},
|
||||
tentacruel: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
geodude: {
|
||||
tier: "LC",
|
||||
},
|
||||
graveler: {
|
||||
tier: "NFE",
|
||||
},
|
||||
golem: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
ponyta: {
|
||||
tier: "LC",
|
||||
},
|
||||
rapidash: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
slowpoke: {
|
||||
tier: "LC",
|
||||
},
|
||||
slowbro: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
slowking: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
magnemite: {
|
||||
tier: "LC",
|
||||
},
|
||||
magneton: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
farfetchd: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
doduo: {
|
||||
tier: "LC",
|
||||
},
|
||||
dodrio: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
seel: {
|
||||
tier: "LC",
|
||||
},
|
||||
dewgong: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
grimer: {
|
||||
tier: "LC",
|
||||
},
|
||||
muk: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
shellder: {
|
||||
tier: "LC",
|
||||
},
|
||||
cloyster: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
gastly: {
|
||||
tier: "LC",
|
||||
},
|
||||
haunter: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
gengar: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
onix: {
|
||||
tier: "LC",
|
||||
},
|
||||
steelix: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
drowzee: {
|
||||
tier: "LC",
|
||||
},
|
||||
hypno: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
krabby: {
|
||||
tier: "LC",
|
||||
},
|
||||
kingler: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
voltorb: {
|
||||
tier: "LC",
|
||||
},
|
||||
electrode: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
exeggcute: {
|
||||
tier: "LC",
|
||||
},
|
||||
exeggutor: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
cubone: {
|
||||
tier: "LC",
|
||||
},
|
||||
marowak: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
tyrogue: {
|
||||
tier: "LC",
|
||||
},
|
||||
hitmonlee: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
hitmonchan: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
hitmontop: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
lickitung: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
koffing: {
|
||||
tier: "LC",
|
||||
},
|
||||
weezing: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
rhyhorn: {
|
||||
tier: "LC",
|
||||
},
|
||||
rhydon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
chansey: {
|
||||
tier: "OU",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
blissey: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
tangela: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
kangaskhan: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
horsea: {
|
||||
tier: "LC",
|
||||
},
|
||||
seadra: {
|
||||
tier: "NFE",
|
||||
},
|
||||
kingdra: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
goldeen: {
|
||||
tier: "LC",
|
||||
},
|
||||
seaking: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
staryu: {
|
||||
tier: "LC",
|
||||
},
|
||||
starmie: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
mrmime: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
scyther: {
|
||||
tier: "OU",
|
||||
doublesTier: "NFE",
|
||||
},
|
||||
scizor: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
smoochum: {
|
||||
tier: "LC",
|
||||
},
|
||||
jynx: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
elekid: {
|
||||
tier: "LC",
|
||||
},
|
||||
electabuzz: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
magby: {
|
||||
tier: "LC",
|
||||
},
|
||||
magmar: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
pinsir: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
tauros: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
magikarp: {
|
||||
tier: "LC",
|
||||
},
|
||||
gyarados: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
lapras: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
ditto: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
eevee: {
|
||||
tier: "LC",
|
||||
},
|
||||
vaporeon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
jolteon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
flareon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
espeon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
umbreon: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
porygon: {
|
||||
tier: "LC",
|
||||
},
|
||||
porygon2: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
omanyte: {
|
||||
tier: "LC",
|
||||
},
|
||||
omastar: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
kabuto: {
|
||||
tier: "LC",
|
||||
},
|
||||
kabutops: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
aerodactyl: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
snorlax: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
articuno: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
zapdos: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
moltres: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
dratini: {
|
||||
tier: "LC",
|
||||
},
|
||||
dragonair: {
|
||||
tier: "NFE",
|
||||
},
|
||||
dragonite: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
mewtwo: {
|
||||
tier: "Uber",
|
||||
doublesTier: "DUber",
|
||||
},
|
||||
mew: {
|
||||
tier: "Uber",
|
||||
doublesTier: "DUber",
|
||||
},
|
||||
chikorita: {
|
||||
tier: "LC",
|
||||
},
|
||||
bayleef: {
|
||||
tier: "NFE",
|
||||
},
|
||||
meganium: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
cyndaquil: {
|
||||
tier: "LC",
|
||||
},
|
||||
quilava: {
|
||||
tier: "NFE",
|
||||
},
|
||||
typhlosion: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
totodile: {
|
||||
tier: "LC",
|
||||
},
|
||||
croconaw: {
|
||||
tier: "NFE",
|
||||
},
|
||||
feraligatr: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
sentret: {
|
||||
tier: "LC",
|
||||
},
|
||||
furret: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
hoothoot: {
|
||||
tier: "LC",
|
||||
},
|
||||
noctowl: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
ledyba: {
|
||||
tier: "LC",
|
||||
},
|
||||
ledian: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
spinarak: {
|
||||
tier: "LC",
|
||||
},
|
||||
ariados: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
chinchou: {
|
||||
tier: "LC",
|
||||
},
|
||||
lanturn: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
togepi: {
|
||||
tier: "LC",
|
||||
},
|
||||
togetic: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
natu: {
|
||||
tier: "LC",
|
||||
},
|
||||
xatu: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
mareep: {
|
||||
tier: "LC",
|
||||
},
|
||||
flaaffy: {
|
||||
tier: "NFE",
|
||||
},
|
||||
ampharos: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
marill: {
|
||||
tier: "LC",
|
||||
},
|
||||
azumarill: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
sudowoodo: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
hoppip: {
|
||||
tier: "LC",
|
||||
},
|
||||
skiploom: {
|
||||
tier: "NFE",
|
||||
},
|
||||
jumpluff: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
aipom: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
sunkern: {
|
||||
tier: "LC",
|
||||
},
|
||||
sunflora: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
yanma: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
wooper: {
|
||||
tier: "LC",
|
||||
},
|
||||
quagsire: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
murkrow: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
misdreavus: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
unown: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
wobbuffet: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
girafarig: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
pineco: {
|
||||
tier: "LC",
|
||||
},
|
||||
forretress: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
dunsparce: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
gligar: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
snubbull: {
|
||||
tier: "LC",
|
||||
},
|
||||
granbull: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
qwilfish: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
shuckle: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
heracross: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
sneasel: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
teddiursa: {
|
||||
tier: "LC",
|
||||
},
|
||||
ursaring: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
slugma: {
|
||||
tier: "LC",
|
||||
},
|
||||
magcargo: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
swinub: {
|
||||
tier: "LC",
|
||||
},
|
||||
piloswine: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
corsola: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
remoraid: {
|
||||
tier: "LC",
|
||||
},
|
||||
octillery: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
delibird: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
mantine: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
skarmory: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
houndour: {
|
||||
tier: "LC",
|
||||
},
|
||||
houndoom: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
phanpy: {
|
||||
tier: "LC",
|
||||
},
|
||||
donphan: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
stantler: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
smeargle: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
miltank: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
raikou: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
entei: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
suicune: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
larvitar: {
|
||||
tier: "LC",
|
||||
},
|
||||
pupitar: {
|
||||
tier: "NFE",
|
||||
},
|
||||
tyranitar: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
lugia: {
|
||||
tier: "Uber",
|
||||
doublesTier: "DUber",
|
||||
},
|
||||
hooh: {
|
||||
tier: "Uber",
|
||||
doublesTier: "DUber",
|
||||
},
|
||||
celebi: {
|
||||
tier: "OU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
};
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||
encore: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
durationCallback() {
|
||||
return this.random(3, 7);
|
||||
},
|
||||
onStart(target) {
|
||||
const lockedMove = target.lastMoveEncore?.id || '';
|
||||
const moveIndex = lockedMove ? target.moves.indexOf(lockedMove) : -1;
|
||||
if (moveIndex < 0 || target.lastMoveEncore?.flags['failencore'] || target.moveSlots[moveIndex].pp <= 0) {
|
||||
// it failed
|
||||
return false;
|
||||
}
|
||||
this.effectState.move = lockedMove;
|
||||
this.add('-start', target, 'Encore');
|
||||
},
|
||||
onOverrideAction(pokemon) {
|
||||
return this.effectState.move;
|
||||
},
|
||||
onModifyMove(move, pokemon) {
|
||||
if (['normal', 'any', 'adjacentFoe'].includes(move.target)) {
|
||||
move.target = 'randomNormal';
|
||||
}
|
||||
},
|
||||
onResidualOrder: 13,
|
||||
onResidual(target) {
|
||||
const lockedMoveIndex = target.moves.indexOf(this.effectState.move);
|
||||
if (lockedMoveIndex >= 0 && target.moveSlots[lockedMoveIndex].pp <= 0) {
|
||||
// early termination if you run out of PP
|
||||
target.removeVolatile('encore');
|
||||
}
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Encore');
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) {
|
||||
return;
|
||||
}
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id !== this.effectState.move) {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
standarddoubles: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard Doubles',
|
||||
ruleset: ['Obtainable', 'Sleep Clause Mod', 'Freeze Clause Mod', 'Species Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Endless battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
|
||||
banlist: [
|
||||
'Hypnosis + Mean Look',
|
||||
'Hypnosis + Spider Web',
|
||||
'Lovely Kiss + Mean Look',
|
||||
'Lovely Kiss + Spider Web',
|
||||
'Sing + Mean Look',
|
||||
'Sing + Spider Web',
|
||||
'Sleep Powder + Mean Look',
|
||||
'Sleep Powder + Spider Web',
|
||||
'Spore + Mean Look',
|
||||
'Spore + Spider Web',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -1,319 +0,0 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
inherit: 'gen2',
|
||||
gen: 2,
|
||||
pokemon: {
|
||||
inherit: true,
|
||||
getStat(statName, unboosted, unmodified, fastReturn) {
|
||||
// @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
|
||||
if (statName === 'hp') throw new Error("Please read `maxhp` directly");
|
||||
|
||||
// base stat
|
||||
let stat = this.storedStats[statName];
|
||||
|
||||
// Stat boosts.
|
||||
if (!unboosted) {
|
||||
let boost = this.boosts[statName];
|
||||
if (boost > 6) boost = 6;
|
||||
if (boost < -6) boost = -6;
|
||||
if (boost >= 0) {
|
||||
const boostTable = [1, 1.5, 2, 2.5, 3, 3.5, 4];
|
||||
stat = Math.floor(stat * boostTable[boost]);
|
||||
} else {
|
||||
const numerators = [100, 66, 50, 40, 33, 28, 25];
|
||||
stat = Math.floor(stat * numerators[-boost] / 100);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.status === 'par' && statName === 'spe') {
|
||||
stat = Math.floor(stat / 4);
|
||||
}
|
||||
|
||||
if (!unmodified) {
|
||||
// Burn attack drop is checked when you get the attack stat upon switch in and used until switch out.
|
||||
if (this.status === 'brn' && statName === 'atk') {
|
||||
stat = Math.floor(stat / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Gen 2 caps stats at 999 and min is 1.
|
||||
stat = this.battle.clampIntRange(stat, 1, 999);
|
||||
if (fastReturn) return stat;
|
||||
|
||||
// Screens
|
||||
if (!unboosted) {
|
||||
if (
|
||||
(statName === 'def' && this.side.sideConditions['reflect']) ||
|
||||
(statName === 'spd' && this.side.sideConditions['lightscreen'])
|
||||
) {
|
||||
if (this.side.active.length === 1) {
|
||||
stat *= 2;
|
||||
} else {
|
||||
stat *= 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle boosting items
|
||||
if (
|
||||
(['Cubone', 'Marowak'].includes(this.baseSpecies.name) && this.item === 'thickclub' && statName === 'atk') ||
|
||||
(this.baseSpecies.name === 'Pikachu' && this.item === 'lightball' && statName === 'spa')
|
||||
) {
|
||||
stat *= 2;
|
||||
} else if (this.baseSpecies.name === 'Ditto' && this.item === 'metalpowder' && ['def', 'spd'].includes(statName)) {
|
||||
stat = Math.floor(stat * 1.5);
|
||||
}
|
||||
|
||||
return stat;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
inherit: true,
|
||||
getDamage(source, target, move, suppressMessages) {
|
||||
// First of all, we get the move.
|
||||
if (typeof move === 'string') {
|
||||
move = this.dex.getActiveMove(move);
|
||||
} else if (typeof move === 'number') {
|
||||
move = {
|
||||
basePower: move,
|
||||
type: '???',
|
||||
category: 'Physical',
|
||||
willCrit: false,
|
||||
flags: {},
|
||||
} as unknown as ActiveMove;
|
||||
}
|
||||
|
||||
// Let's test for immunities.
|
||||
if (!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) {
|
||||
if (!target.runImmunity(move.type, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Is it an OHKO move?
|
||||
if (move.ohko) {
|
||||
return target.maxhp;
|
||||
}
|
||||
|
||||
// We edit the damage through move's damage callback
|
||||
if (move.damageCallback) {
|
||||
return move.damageCallback.call(this.battle, source, target);
|
||||
}
|
||||
|
||||
// We take damage from damage=level moves
|
||||
if (move.damage === 'level') {
|
||||
return source.level;
|
||||
}
|
||||
|
||||
// If there's a fix move damage, we run it
|
||||
if (move.damage) {
|
||||
return move.damage;
|
||||
}
|
||||
|
||||
// We check the category and typing to calculate later on the damage
|
||||
move.category = this.battle.getCategory(move);
|
||||
// '???' is typeless damage: used for Struggle and Confusion etc
|
||||
if (!move.type) move.type = '???';
|
||||
const type = move.type;
|
||||
|
||||
// We get the base power and apply basePowerCallback if necessary
|
||||
let basePower: number | false | null | undefined = move.basePower;
|
||||
if (move.basePowerCallback) {
|
||||
basePower = move.basePowerCallback.call(this.battle, source, target, move);
|
||||
}
|
||||
|
||||
// We check for Base Power
|
||||
if (!basePower) {
|
||||
if (basePower === 0) return; // Returning undefined means not dealing damage
|
||||
return basePower;
|
||||
}
|
||||
basePower = this.battle.clampIntRange(basePower, 1);
|
||||
|
||||
// Checking for the move's Critical Hit ratio
|
||||
let critRatio = this.battle.runEvent('ModifyCritRatio', source, target, move, move.critRatio || 0);
|
||||
critRatio = this.battle.clampIntRange(critRatio, 0, 5);
|
||||
const critMult = [0, 17, 32, 64, 85, 128];
|
||||
let isCrit = move.willCrit || false;
|
||||
if (typeof move.willCrit === 'undefined') {
|
||||
if (critRatio) {
|
||||
isCrit = this.battle.random(256) < critMult[critRatio];
|
||||
}
|
||||
}
|
||||
|
||||
if (isCrit && this.battle.runEvent('CriticalHit', target, null, move)) {
|
||||
target.getMoveHitData(move).crit = true;
|
||||
}
|
||||
|
||||
// Happens after crit calculation
|
||||
if (basePower) {
|
||||
// confusion damage
|
||||
if (move.isConfusionSelfHit) {
|
||||
move.type = move.baseMoveType!;
|
||||
basePower = this.battle.runEvent('BasePower', source, target, move, basePower, true);
|
||||
move.type = '???';
|
||||
} else {
|
||||
basePower = this.battle.runEvent('BasePower', source, target, move, basePower, true);
|
||||
}
|
||||
if (basePower && move.basePowerModifier) {
|
||||
basePower *= move.basePowerModifier;
|
||||
}
|
||||
}
|
||||
if (!basePower) return 0;
|
||||
basePower = this.battle.clampIntRange(basePower, 1);
|
||||
|
||||
// We now check for attacker and defender
|
||||
let level = source.level;
|
||||
|
||||
// Using Beat Up
|
||||
if (move.allies) {
|
||||
this.battle.add('-activate', source, 'move: Beat Up', '[of] ' + move.allies[0].name);
|
||||
level = move.allies[0].level;
|
||||
}
|
||||
|
||||
const attacker = move.overrideOffensivePokemon === 'target' ? target : source;
|
||||
const defender = move.overrideDefensivePokemon === 'source' ? source : target;
|
||||
|
||||
const isPhysical = move.category === 'Physical';
|
||||
const atkType: StatIDExceptHP = move.overrideOffensiveStat || (isPhysical ? 'atk' : 'spa');
|
||||
const defType: StatIDExceptHP = move.overrideDefensiveStat || (isPhysical ? 'def' : 'spd');
|
||||
|
||||
let unboosted = false;
|
||||
let noburndrop = false;
|
||||
|
||||
if (isCrit) {
|
||||
if (!suppressMessages) this.battle.add('-crit', target);
|
||||
// Stat level modifications are ignored if they are neutral to or favour the defender.
|
||||
// Reflect and Light Screen defensive boosts are only ignored if stat level modifications were also ignored as a result of that.
|
||||
if (attacker.boosts[atkType] <= defender.boosts[defType]) {
|
||||
unboosted = true;
|
||||
noburndrop = true;
|
||||
}
|
||||
}
|
||||
|
||||
let attack = attacker.getStat(atkType, unboosted, noburndrop);
|
||||
let defense = defender.getStat(defType, unboosted);
|
||||
|
||||
// Using Beat Up
|
||||
if (move.allies) {
|
||||
attack = move.allies[0].species.baseStats.atk;
|
||||
move.allies.shift();
|
||||
defense = defender.species.baseStats.def;
|
||||
}
|
||||
|
||||
// Moves that ignore offense and defense respectively.
|
||||
if (move.ignoreOffensive) {
|
||||
this.battle.debug('Negating (sp)atk boost/penalty.');
|
||||
// The attack drop from the burn is only applied when attacker's attack level is higher than defender's defense level.
|
||||
attack = attacker.getStat(atkType, true, true);
|
||||
}
|
||||
|
||||
if (move.ignoreDefensive) {
|
||||
this.battle.debug('Negating (sp)def boost/penalty.');
|
||||
defense = target.getStat(defType, true, true);
|
||||
}
|
||||
|
||||
if (move.id === 'present') {
|
||||
const typeIndexes: { [k: string]: number } = {
|
||||
Normal: 0, Fighting: 1, Flying: 2, Poison: 3, Ground: 4, Rock: 5, Bug: 7, Ghost: 8, Steel: 9,
|
||||
Fire: 20, Water: 21, Grass: 22, Electric: 23, Psychic: 24, Ice: 25, Dragon: 26, Dark: 27,
|
||||
};
|
||||
attack = 10;
|
||||
|
||||
const attackerLastType = attacker.getTypes().slice(-1)[0];
|
||||
const defenderLastType = defender.getTypes().slice(-1)[0];
|
||||
|
||||
defense = typeIndexes[attackerLastType] || 1;
|
||||
level = typeIndexes[defenderLastType] || 1;
|
||||
this.battle.hint("Gen 2 Present has a glitched damage calculation using the secondary types of the Pokemon for the Attacker's Level and Defender's Defense.", true);
|
||||
}
|
||||
|
||||
// When either attack or defense are higher than 256, they are both divided by 4 and modded by 256.
|
||||
// This is what causes the rollover bugs.
|
||||
if (attack >= 256 || defense >= 256) {
|
||||
if (attack >= 1024 || defense >= 1024) {
|
||||
this.battle.hint("In Gen 2, a stat will roll over to a small number if it is larger than 1024.");
|
||||
}
|
||||
attack = this.battle.clampIntRange(Math.floor(attack / 4) % 256, 1);
|
||||
defense = this.battle.clampIntRange(Math.floor(defense / 4) % 256, 1);
|
||||
}
|
||||
|
||||
// Self destruct moves halve defense at this point.
|
||||
if (move.selfdestruct && defType === 'def') {
|
||||
defense = this.battle.clampIntRange(Math.floor(defense / 2), 1);
|
||||
}
|
||||
|
||||
// Let's go with the calculation now that we have what we need.
|
||||
// We do it step by step just like the game does.
|
||||
let damage = level * 2;
|
||||
damage = Math.floor(damage / 5);
|
||||
damage += 2;
|
||||
damage *= basePower;
|
||||
damage *= attack;
|
||||
damage = Math.floor(damage / defense);
|
||||
damage = Math.floor(damage / 50);
|
||||
if (isCrit) damage *= 2;
|
||||
damage = Math.floor(this.battle.runEvent('ModifyDamage', attacker, defender, move, damage));
|
||||
damage = this.battle.clampIntRange(damage, 1, 997);
|
||||
damage += 2;
|
||||
|
||||
// Weather modifiers
|
||||
if (
|
||||
(type === 'Water' && this.battle.field.isWeather('raindance')) ||
|
||||
(type === 'Fire' && this.battle.field.isWeather('sunnyday'))
|
||||
) {
|
||||
damage = Math.floor(damage * 1.5);
|
||||
} else if (
|
||||
((type === 'Fire' || move.id === 'solarbeam') && this.battle.field.isWeather('raindance')) ||
|
||||
(type === 'Water' && this.battle.field.isWeather('sunnyday'))
|
||||
) {
|
||||
damage = Math.floor(damage / 2);
|
||||
}
|
||||
|
||||
// STAB damage bonus, the "???" type never gets STAB
|
||||
if (type !== '???' && source.hasType(type)) {
|
||||
damage += Math.floor(damage / 2);
|
||||
}
|
||||
|
||||
// Type effectiveness
|
||||
const totalTypeMod = target.runEffectiveness(move);
|
||||
// Super effective attack
|
||||
if (totalTypeMod > 0) {
|
||||
if (!suppressMessages) this.battle.add('-supereffective', target);
|
||||
damage *= 2;
|
||||
if (totalTypeMod >= 2) {
|
||||
damage *= 2;
|
||||
}
|
||||
}
|
||||
// Resisted attack
|
||||
if (totalTypeMod < 0) {
|
||||
if (!suppressMessages) this.battle.add('-resisted', target);
|
||||
damage = Math.floor(damage / 2);
|
||||
if (totalTypeMod <= -2) {
|
||||
damage = Math.floor(damage / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Attempting to add correct spread damage nerf
|
||||
const { targets } = source.getMoveTargets(move, target);
|
||||
if (targets.length > 1) move.spreadHit = true;
|
||||
if (move.spreadHit && move.target === 'allAdjacentFoes') {
|
||||
const spreadModifier = move.spreadModifier || 0.5;
|
||||
this.battle.debug(`Spread modifier: ${spreadModifier}`);
|
||||
damage = this.battle.modify(damage, spreadModifier);
|
||||
}
|
||||
|
||||
// Apply random factor if damage is greater than 1, except for Flail and Reversal
|
||||
if (!move.noDamageVariance && damage > 1) {
|
||||
damage *= this.battle.random(217, 256);
|
||||
damage = Math.floor(damage / 255);
|
||||
}
|
||||
|
||||
// If damage is less than 1, we return 1
|
||||
if (basePower && !Math.floor(damage)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// We are done, this is the final damage
|
||||
return damage;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -1,8 +1,17 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
standardag: {
|
||||
inherit: true,
|
||||
ruleset: [
|
||||
'Obtainable', 'Team Preview', 'Exact HP Mod', 'Cancel Mod', 'Beat Up Nicknames Mod',
|
||||
],
|
||||
},
|
||||
standard: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard',
|
||||
ruleset: ['Obtainable', 'Team Preview', 'Stadium Sleep Clause', 'Freeze Clause Mod', 'Self-KO Clause', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Exact HP Mod', 'Cancel Mod', 'Stadium Items Clause'],
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Stadium Sleep Clause', 'Freeze Clause Mod', 'Self-KO Clause', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Moves Clause', 'Stadium Items Clause',
|
||||
],
|
||||
},
|
||||
selfkoclause: {
|
||||
effectType: 'Rule',
|
||||
|
|
|
|||
|
|
@ -122,10 +122,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
move.ignoreImmunity = (move.category === 'Status');
|
||||
}
|
||||
|
||||
if (
|
||||
(!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) &&
|
||||
!target.runImmunity(move.type, true)
|
||||
) {
|
||||
if (!target.runImmunity(move, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -231,10 +228,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
if (move.ohko) this.battle.add('-ohko');
|
||||
|
||||
if (!move.negateSecondary) {
|
||||
this.battle.singleEvent('AfterMoveSecondary', move, null, target, pokemon, move);
|
||||
this.battle.runEvent('AfterMoveSecondary', target, pokemon, move);
|
||||
}
|
||||
this.battle.singleEvent('AfterMoveSecondary', move, null, target, pokemon, move);
|
||||
this.battle.runEvent('AfterMoveSecondary', target, pokemon, move);
|
||||
// Implementing Recoil mechanics from Stadium 2.
|
||||
// If a pokemon caused the other to faint with a recoil move and only one pokemon remains on both sides,
|
||||
// recoil damage will not be taken.
|
||||
|
|
@ -258,10 +253,8 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
}
|
||||
|
||||
// Let's test for immunities.
|
||||
if (!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) {
|
||||
if (!target.runImmunity(move.type, true)) {
|
||||
return false;
|
||||
}
|
||||
if (!target.runImmunity(move, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is it an OHKO move?
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
},
|
||||
},
|
||||
lightningrod: {
|
||||
inherit: true,
|
||||
onAnyRedirectTarget() {},
|
||||
onFoeRedirectTarget(target, source, source2, move) {
|
||||
// don't count Hidden Power as Electric-type
|
||||
if (this.dex.moves.get(move.id).type !== 'Electric') return;
|
||||
|
|
@ -98,10 +100,23 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
return this.effectState.target;
|
||||
}
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Lightning Rod",
|
||||
rating: 0,
|
||||
num: 32,
|
||||
},
|
||||
magnetpull: {
|
||||
inherit: true,
|
||||
onFoeTrapPokemon() {},
|
||||
onFoeMaybeTrapPokemon() {},
|
||||
onAnyTrapPokemon(pokemon) {
|
||||
if (pokemon.hasType('Steel') && pokemon.isAdjacent(this.effectState.target)) {
|
||||
pokemon.tryTrap(true);
|
||||
}
|
||||
},
|
||||
onAnyMaybeTrapPokemon(pokemon, source) {
|
||||
if (!source) source = this.effectState.target;
|
||||
if (!source || !pokemon.isAdjacent(source)) return;
|
||||
if (!pokemon.knownType || pokemon.hasType('Steel')) {
|
||||
pokemon.maybeTrapped = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
minus: {
|
||||
inherit: true,
|
||||
|
|
@ -181,9 +196,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
const target = pokemon.side.randomFoe();
|
||||
if (!target || target.fainted) return;
|
||||
const ability = target.getAbility();
|
||||
if (pokemon.setAbility(ability)) {
|
||||
this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
|
||||
}
|
||||
pokemon.setAbility(ability, target);
|
||||
},
|
||||
flags: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
ivysaur: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
},
|
||||
venusaur: {
|
||||
tier: "UUBL",
|
||||
|
|
@ -21,7 +21,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
wartortle: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
blastoise: {
|
||||
tier: "UU",
|
||||
|
|
@ -63,7 +63,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
fearow: {
|
||||
tier: "UU",
|
||||
tier: "RUBL",
|
||||
},
|
||||
ekans: {
|
||||
tier: "LC",
|
||||
|
|
@ -312,7 +312,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "ZU",
|
||||
},
|
||||
hypno: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
},
|
||||
krabby: {
|
||||
tier: "LC",
|
||||
|
|
@ -762,7 +762,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
grovyle: {
|
||||
tier: "PU",
|
||||
tier: "ZU",
|
||||
},
|
||||
sceptile: {
|
||||
tier: "UUBL",
|
||||
|
|
@ -879,7 +879,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "RUBL",
|
||||
},
|
||||
shedinja: {
|
||||
tier: "ZUBL",
|
||||
tier: "PU",
|
||||
},
|
||||
whismur: {
|
||||
tier: "LC",
|
||||
|
|
@ -924,13 +924,13 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "ZU",
|
||||
},
|
||||
medicham: {
|
||||
tier: "UUBL",
|
||||
tier: "OU",
|
||||
},
|
||||
electrike: {
|
||||
tier: "LC",
|
||||
},
|
||||
manectric: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
},
|
||||
plusle: {
|
||||
tier: "NU",
|
||||
|
|
@ -1056,13 +1056,10 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "ZU",
|
||||
},
|
||||
castformsunny: {
|
||||
tier: "ZU",
|
||||
},
|
||||
castformrainy: {
|
||||
tier: "ZU",
|
||||
},
|
||||
castformsnowy: {
|
||||
tier: "ZU",
|
||||
},
|
||||
kecleon: {
|
||||
tier: "NU",
|
||||
|
|
@ -1092,7 +1089,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
glalie: {
|
||||
tier: "NU",
|
||||
tier: "NUBL",
|
||||
},
|
||||
spheal: {
|
||||
tier: "LC",
|
||||
|
|
@ -1104,7 +1101,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "UU",
|
||||
},
|
||||
clamperl: {
|
||||
tier: "ZU",
|
||||
tier: "PU",
|
||||
},
|
||||
huntail: {
|
||||
tier: "NU",
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
num: 208,
|
||||
gen: 3,
|
||||
isNonstandard: "Unobtainable",
|
||||
// No competitive use
|
||||
},
|
||||
fastball: {
|
||||
inherit: true,
|
||||
|
|
@ -138,8 +139,8 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
inherit: true,
|
||||
onModifyMove(move) {
|
||||
const affectedByKingsRock = [
|
||||
'aerialace', 'aeroblast', 'aircutter', 'armthrust', 'barrage', 'beatup', 'bide', 'bind', 'blastburn', 'bonerush', 'bonemerang', 'bounce', 'brickbreak', 'bulletseed', 'clamp', 'cometpunch', 'crabhammer', 'crosschop', 'cut', 'dig', 'dive', 'doublekick', 'doubleslap', 'doubleedge', 'dragonbreath', 'dragonclaw', 'dragonrage', 'drillpeck', 'earthquake', 'eggbomb', 'endeavor', 'eruption', 'explosion', 'extremespeed', 'falseswipe', 'feintattack', 'firespin', 'flail', 'fly', 'frenzyplant', 'frustration', 'furyattack', 'furycutter', 'furyswipes', 'gust', 'hiddenpower', 'highjumpkick', 'hornattack', 'hydrocannon', 'hydropump', 'hyperbeam', 'iceball', 'iciclespear', 'jumpkick', 'karatechop', 'leafblade', 'lowkick', 'machpunch', 'magicalleaf', 'magnitude', 'megakick', 'megapunch', 'megahorn', 'meteormash', 'mudshot', 'muddywater', 'nightshade', 'outrage', 'overheat', 'payday', 'peck', 'petaldance', 'pinmissile', 'poisontail', 'pound', 'psychoboost', 'psywave', 'quickattack', 'rage', 'rapidspin', 'razorleaf', 'razorwind', 'return', 'revenge', 'reversal', 'rockblast', 'rockthrow', 'rollingkick', 'rollout', 'sandtomb', 'scratch', 'seismictoss', 'selfdestruct', 'shadowpunch', 'shockwave', 'signalbeam', 'silverwind', 'skullbash', 'skyattack', 'skyuppercut', 'slam', 'slash', 'snore', 'solarbeam', 'sonicboom', 'spikecannon', 'spitup', 'steelwing', 'strength', 'struggle', 'submission', 'surf', 'swift', 'tackle', 'takedown', 'thrash', 'tickle', 'triplekick', 'twister', 'uproar', 'visegrip', 'vinewhip', 'vitalthrow', 'volttackle', 'watergun', 'waterpulse', 'waterfall', 'weatherball', 'whirlpool', 'wingattack', 'wrap',
|
||||
];
|
||||
'aerialace', 'aeroblast', 'aircutter', 'armthrust', 'barrage', 'beatup', 'bide', 'bind', 'blastburn', 'bonerush', 'bonemerang', 'bounce', 'brickbreak', 'bulletseed', 'clamp', 'cometpunch', 'crabhammer', 'crosschop', 'cut', 'dig', 'dive', 'doublekick', 'doubleslap', 'doubleedge', 'dragonbreath', 'dragonclaw', 'dragonrage', 'drillpeck', 'earthquake', 'eggbomb', 'endeavor', 'eruption', 'explosion', 'extremespeed', 'falseswipe', 'feintattack', 'firespin', 'flail', 'fly', 'frenzyplant', 'frustration', 'furyattack', 'furycutter', 'furyswipes', 'gust', 'hiddenpower', 'highjumpkick', 'hornattack', 'hydrocannon', 'hydropump', 'hyperbeam', 'iceball', 'iciclespear', 'jumpkick', 'karatechop', 'leafblade', 'lowkick', 'machpunch', 'magicalleaf', 'magnitude', 'megakick', 'megapunch', 'megahorn', 'meteormash', 'mudshot', 'muddywater', 'nightshade', 'outrage', 'overheat', 'payday', 'peck', 'petaldance', 'pinmissile', 'poisontail', 'pound', 'psychoboost', 'psywave', 'quickattack', 'rage', 'rapidspin', 'razorleaf', 'razorwind', 'return', 'revenge', 'reversal', 'rockblast', 'rockthrow', 'rollingkick', 'rollout', 'sandtomb', 'scratch', 'seismictoss', 'selfdestruct', 'shadowpunch', 'shockwave', 'signalbeam', 'silverwind', 'skullbash', 'skyattack', 'skyuppercut', 'slam', 'slash', 'snore', 'solarbeam', 'sonicboom', 'spikecannon', 'spitup', 'steelwing', 'strength', 'struggle', 'submission', 'surf', 'swift', 'tackle', 'takedown', 'thrash', 'triplekick', 'twister', 'uproar', 'visegrip', 'vinewhip', 'vitalthrow', 'volttackle', 'watergun', 'waterpulse', 'waterfall', 'weatherball', 'whirlpool', 'wingattack', 'wrap',
|
||||
]; // Tickle also has the move flag, but can never flinch because King's Rock requires damage to trigger
|
||||
if (affectedByKingsRock.includes(move.id)) {
|
||||
if (!move.secondaries) move.secondaries = [];
|
||||
move.secondaries.push({
|
||||
|
|
|
|||
|
|
@ -26,10 +26,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
astonish: {
|
||||
inherit: true,
|
||||
basePowerCallback(pokemon, target) {
|
||||
if (target.volatiles['minimize']) return 60;
|
||||
return 30;
|
||||
},
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, minimize: 1 },
|
||||
},
|
||||
beatup: {
|
||||
inherit: true,
|
||||
|
|
@ -44,15 +41,16 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
duration: 1,
|
||||
onModifySpAPriority: -101,
|
||||
onModifySpA(atk, pokemon, defender, move) {
|
||||
// https://www.smogon.com/forums/posts/8992145/
|
||||
// this.add('-activate', pokemon, 'move: Beat Up', '[of] ' + move.allies![0].name);
|
||||
if (!this.ruleTable.has('beatupnicknamesmod')) {
|
||||
this.add('-activate', pokemon, 'move: Beat Up', '[of] ' + move.allies![0].name);
|
||||
}
|
||||
this.event.modifier = 1;
|
||||
return move.allies!.shift()!.species.baseStats.atk;
|
||||
return this.dex.species.get(move.allies!.shift()!.set.species).baseStats.atk;
|
||||
},
|
||||
onFoeModifySpDPriority: -101,
|
||||
onFoeModifySpD(def, pokemon) {
|
||||
this.event.modifier = 1;
|
||||
return pokemon.species.baseStats.def;
|
||||
return this.dex.species.get(pokemon.set.species).baseStats.def;
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -61,18 +59,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
accuracy: 100,
|
||||
priority: 0,
|
||||
condition: {
|
||||
duration: 3,
|
||||
onLockMove: 'bide',
|
||||
onStart(pokemon) {
|
||||
this.effectState.totalDamage = 0;
|
||||
this.add('-start', pokemon, 'move: Bide');
|
||||
},
|
||||
onDamagePriority: -101,
|
||||
onDamage(damage, target, source, move) {
|
||||
if (!move || move.effectType !== 'Move' || !source) return;
|
||||
this.effectState.totalDamage += damage;
|
||||
this.effectState.lastDamageSource = source;
|
||||
},
|
||||
inherit: true,
|
||||
onAfterSetStatus() {},
|
||||
onBeforeMove(pokemon, target, move) {
|
||||
if (this.effectState.duration === 1) {
|
||||
this.add('-end', pokemon, 'move: Bide');
|
||||
|
|
@ -110,12 +98,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
this.add('-activate', pokemon, 'move: Bide');
|
||||
},
|
||||
onMoveAborted(pokemon) {
|
||||
pokemon.removeVolatile('bide');
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
this.add('-end', pokemon, 'move: Bide', '[silent]');
|
||||
},
|
||||
},
|
||||
},
|
||||
blizzard: {
|
||||
|
|
@ -154,20 +136,39 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.add('-start', target, 'typechange', type);
|
||||
},
|
||||
},
|
||||
conversion2: {
|
||||
inherit: true,
|
||||
onHit(target, source) {
|
||||
if (!target.lastMoveUsed) {
|
||||
return false;
|
||||
}
|
||||
const possibleTypes = [];
|
||||
const lastMoveUsed = target.lastMoveUsed;
|
||||
const attackType = lastMoveUsed.id === 'struggle' ? 'Normal' : lastMoveUsed.type;
|
||||
for (const typeName of this.dex.types.names()) {
|
||||
const typeCheck = this.dex.types.get(typeName).damageTaken[attackType];
|
||||
if (typeCheck === 2 || typeCheck === 3) {
|
||||
possibleTypes.push(typeName);
|
||||
}
|
||||
}
|
||||
if (!possibleTypes.length) {
|
||||
return false;
|
||||
}
|
||||
const randomType = this.sample(possibleTypes);
|
||||
|
||||
if (!source.setType(randomType)) return false;
|
||||
this.add('-start', source, 'typechange', randomType);
|
||||
},
|
||||
},
|
||||
counter: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 1,
|
||||
noCopy: true,
|
||||
onStart(target, source, move) {
|
||||
this.effectState.slot = null;
|
||||
this.effectState.damage = 0;
|
||||
},
|
||||
onRedirectTargetPriority: -1,
|
||||
inherit: true,
|
||||
onRedirectTarget(target, source, source2) {
|
||||
if (source !== this.effectState.target || !this.effectState.slot) return;
|
||||
return this.getAtSlot(this.effectState.slot);
|
||||
},
|
||||
onDamagingHit() {},
|
||||
onDamagePriority: -101,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (
|
||||
|
|
@ -201,48 +202,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
accuracy: 55,
|
||||
flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
|
||||
volatileStatus: 'disable',
|
||||
condition: {
|
||||
inherit: true,
|
||||
durationCallback() {
|
||||
return this.random(2, 6);
|
||||
},
|
||||
noCopy: true,
|
||||
onStart(pokemon) {
|
||||
if (!this.queue.willMove(pokemon)) {
|
||||
this.effectState.duration!++;
|
||||
}
|
||||
if (!pokemon.lastMove) {
|
||||
return false;
|
||||
}
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id === pokemon.lastMove.id) {
|
||||
if (!moveSlot.pp) {
|
||||
return false;
|
||||
} else {
|
||||
this.add('-start', pokemon, 'Disable', moveSlot.move);
|
||||
this.effectState.move = pokemon.lastMove.id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
this.add('-end', pokemon, 'move: Disable');
|
||||
},
|
||||
onBeforeMove(attacker, defender, move) {
|
||||
if (move.id === this.effectState.move) {
|
||||
this.add('cant', attacker, 'Disable', move);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id === this.effectState.move) {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
"onResidualOrder": undefined,
|
||||
"onResidualSubOrder": undefined,
|
||||
},
|
||||
},
|
||||
dive: {
|
||||
|
|
@ -286,56 +252,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
volatileStatus: 'encore',
|
||||
condition: {
|
||||
inherit: true,
|
||||
durationCallback() {
|
||||
return this.random(3, 7);
|
||||
},
|
||||
onStart(target, source) {
|
||||
const moveIndex = target.lastMove ? target.moves.indexOf(target.lastMove.id) : -1;
|
||||
if (
|
||||
!target.lastMove || target.lastMove.flags['failencore'] ||
|
||||
!target.moveSlots[moveIndex] || target.moveSlots[moveIndex].pp <= 0
|
||||
) {
|
||||
// it failed
|
||||
return false;
|
||||
}
|
||||
this.effectState.move = target.lastMove.id;
|
||||
this.add('-start', target, 'Encore');
|
||||
},
|
||||
onOverrideAction(pokemon) {
|
||||
return this.effectState.move;
|
||||
},
|
||||
onResidualOrder: 10,
|
||||
onResidualSubOrder: 14,
|
||||
onResidual(target) {
|
||||
if (
|
||||
target.moves.includes(this.effectState.move) &&
|
||||
target.moveSlots[target.moves.indexOf(this.effectState.move)].pp <= 0
|
||||
) {
|
||||
// early termination if you run out of PP
|
||||
target.removeVolatile('encore');
|
||||
}
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Encore');
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) {
|
||||
return;
|
||||
}
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id !== this.effectState.move) {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
extrasensory: {
|
||||
inherit: true,
|
||||
basePowerCallback(pokemon, target) {
|
||||
if (target.volatiles['minimize']) return 160;
|
||||
return 80;
|
||||
},
|
||||
flags: { protect: 1, mirror: 1, metronome: 1, minimize: 1 },
|
||||
},
|
||||
fakeout: {
|
||||
inherit: true,
|
||||
|
|
@ -380,12 +305,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
volatileStatus: undefined,
|
||||
slotCondition: 'followme',
|
||||
condition: {
|
||||
duration: 1,
|
||||
inherit: true,
|
||||
onStart(target, source, effect) {
|
||||
this.add('-singleturn', target, 'move: Follow Me');
|
||||
this.effectState.slot = target.getSlot();
|
||||
},
|
||||
onFoeRedirectTargetPriority: 1,
|
||||
onFoeRedirectTarget(target, source, source2, move) {
|
||||
const userSlot = this.getAtSlot(this.effectState.slot);
|
||||
if (this.validTarget(userSlot, source, move.target)) {
|
||||
|
|
@ -412,6 +336,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
ignoreImmunity: false,
|
||||
},
|
||||
haze: {
|
||||
inherit: true,
|
||||
onHitField() {
|
||||
this.add('-clearallboost');
|
||||
for (const pokemon of this.getAllActive()) {
|
||||
pokemon.clearBoosts();
|
||||
}
|
||||
},
|
||||
},
|
||||
hiddenpower: {
|
||||
inherit: true,
|
||||
category: "Physical",
|
||||
|
|
@ -474,17 +407,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
mirrorcoat: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 1,
|
||||
noCopy: true,
|
||||
onStart(target, source, move) {
|
||||
this.effectState.slot = null;
|
||||
this.effectState.damage = 0;
|
||||
},
|
||||
onRedirectTargetPriority: -1,
|
||||
inherit: true,
|
||||
onRedirectTarget(target, source, source2) {
|
||||
if (source !== this.effectState.target || !this.effectState.slot) return;
|
||||
return this.getAtSlot(this.effectState.slot);
|
||||
},
|
||||
onDamagingHit() {},
|
||||
onDamagePriority: -101,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (
|
||||
|
|
@ -525,10 +453,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
needlearm: {
|
||||
inherit: true,
|
||||
basePowerCallback(pokemon, target) {
|
||||
if (target.volatiles['minimize']) return 120;
|
||||
return 60;
|
||||
},
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, minimize: 1 },
|
||||
},
|
||||
nightmare: {
|
||||
inherit: true,
|
||||
|
|
@ -550,6 +475,20 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
basePower: 70,
|
||||
},
|
||||
pursuit: {
|
||||
inherit: true,
|
||||
beforeTurnCallback(pokemon, target) {
|
||||
if (['frz', 'slp'].includes(pokemon.status) ||
|
||||
(pokemon.hasAbility('truant') && pokemon.truantTurn)) return;
|
||||
if (pokemon.isAlly(target)) return;
|
||||
target.addVolatile('pursuit');
|
||||
const data = target.volatiles['pursuit'];
|
||||
if (!data.sources) {
|
||||
data.sources = [];
|
||||
}
|
||||
data.sources.push(pokemon);
|
||||
},
|
||||
},
|
||||
recover: {
|
||||
inherit: true,
|
||||
pp: 20,
|
||||
|
|
@ -653,28 +592,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
flags: { protect: 1, bypasssub: 1, metronome: 1 },
|
||||
condition: {
|
||||
inherit: true,
|
||||
duration: 2,
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'move: Taunt');
|
||||
},
|
||||
onResidualOrder: 10,
|
||||
onResidualSubOrder: 15,
|
||||
durationCallback: undefined,
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'move: Taunt', '[silent]');
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (this.dex.moves.get(moveSlot.move).category === 'Status') {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
onBeforeMove(attacker, defender, move) {
|
||||
if (move.category === 'Status') {
|
||||
this.add('cant', attacker, 'move: Taunt', move);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
onBeforeMovePriority: undefined,
|
||||
},
|
||||
},
|
||||
teeterdance: {
|
||||
|
|
@ -688,37 +612,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
uproar: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'Uproar');
|
||||
// 2-5 turns
|
||||
this.effectState.duration = this.random(2, 6);
|
||||
},
|
||||
onResidual(target) {
|
||||
if (target.volatiles['throatchop']) {
|
||||
target.removeVolatile('uproar');
|
||||
return;
|
||||
}
|
||||
if (target.lastMove && target.lastMove.id === 'struggle') {
|
||||
// don't lock
|
||||
delete target.volatiles['uproar'];
|
||||
}
|
||||
this.add('-start', target, 'Uproar', '[upkeep]');
|
||||
},
|
||||
onResidualOrder: 10,
|
||||
onResidualSubOrder: 11,
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Uproar');
|
||||
},
|
||||
onLockMove: 'uproar',
|
||||
onAnySetStatus(status, pokemon) {
|
||||
if (status.id === 'slp') {
|
||||
if (pokemon === this.effectState.target) {
|
||||
this.add('-fail', pokemon, 'slp', '[from] Uproar', '[msg]');
|
||||
} else {
|
||||
this.add('-fail', pokemon, 'slp', '[from] Uproar');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
inherit: true,
|
||||
durationCallback() {
|
||||
return this.random(2, 6);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,7 +2,23 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
|
|||
standard: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard',
|
||||
desc: "The standard ruleset for all offical Smogon singles tiers (Ubers, OU, etc.)",
|
||||
ruleset: ['Obtainable', 'Sleep Clause Mod', 'Switch Priority Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
|
||||
desc: "The standard ruleset for all official Smogon singles tiers (Ubers, OU, etc.)",
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Sleep Clause Mod', 'Switch Priority Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
},
|
||||
standarddraft: {
|
||||
effectType: 'ValidatorRule',
|
||||
name: 'Standard Draft',
|
||||
desc: "The custom Draft League ruleset",
|
||||
ruleset: [
|
||||
'Obtainable', 'Nickname Clause', 'Beat Up Nicknames Mod', '+Unreleased', 'Sleep Clause Mod', 'OHKO Clause', 'Evasion Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod',
|
||||
'One Boost Passer Clause', 'Freeze Clause Mod', 'Accuracy Moves Clause', 'Baton Pass Trap Clause',
|
||||
],
|
||||
banlist: [
|
||||
'Uber', 'Smeargle + Ingrain', 'Swagger', 'Focus Band', 'King\'s Rock', 'Quick Claw', 'Baton Pass + Ancient Power', 'Baton Pass + Silver Wind',
|
||||
],
|
||||
// timer: {starting: 60 * 60, grace: 0, addPerTurn: 10, maxPerTurn: 100, timeoutAutoChoose: true},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
// In Generation 3, the spread move modifier is 0.5x instead of 0.75x. Moves that hit both foes
|
||||
// and the user's ally, like Earthquake and Explosion, don't get affected by spread modifiers
|
||||
if (move.spreadHit && move.target === 'allAdjacentFoes') {
|
||||
const spreadModifier = move.spreadModifier || 0.5;
|
||||
const spreadModifier = 0.5;
|
||||
this.battle.debug(`Spread modifier: ${spreadModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, spreadModifier);
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
|
||||
let movename = move.name;
|
||||
if (move.id === 'hiddenpower') movename = 'Hidden Power';
|
||||
if (sourceEffect) attrs += `|[from]${this.dex.conditions.get(sourceEffect)}`;
|
||||
if (sourceEffect) attrs += `|[from] ${this.dex.conditions.get(sourceEffect).name}`;
|
||||
this.battle.addMove('move', pokemon, movename, `${target}${attrs}`);
|
||||
|
||||
if (!target) {
|
||||
|
|
@ -256,7 +256,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!move.negateSecondary && !(move.hasSheerForce && pokemon.hasAbility('sheerforce'))) {
|
||||
if (!(move.hasSheerForce && pokemon.hasAbility('sheerforce'))) {
|
||||
this.battle.singleEvent('AfterMoveSecondarySelf', move, null, pokemon, target, move);
|
||||
this.battle.runEvent('AfterMoveSecondarySelf', pokemon, target, move);
|
||||
}
|
||||
|
|
@ -308,10 +308,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
move.ignoreImmunity = (move.category === 'Status');
|
||||
}
|
||||
|
||||
if (
|
||||
(!move.ignoreImmunity || (move.ignoreImmunity !== true && !move.ignoreImmunity[move.type])) &&
|
||||
!target.runImmunity(move.type)
|
||||
) {
|
||||
if (!target.runImmunity(move)) {
|
||||
naturalImmunity = true;
|
||||
} else {
|
||||
hitResult = this.battle.singleEvent('TryImmunity', move, {}, target, pokemon, move);
|
||||
|
|
@ -471,7 +468,7 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
|
||||
this.battle.eachEvent('Update');
|
||||
|
||||
if (target && !move.negateSecondary) {
|
||||
if (target) {
|
||||
this.battle.singleEvent('AfterMoveSecondary', move, null, target, pokemon, move);
|
||||
this.battle.runEvent('AfterMoveSecondary', target, pokemon, move);
|
||||
}
|
||||
|
|
|
|||
25
data/mods/gen3colosseum/moves.ts
Normal file
25
data/mods/gen3colosseum/moves.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* Gen 3 colosseum modifications (perish song should fail if it effects all remaining pokemon)
|
||||
*/
|
||||
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||
perishsong: {
|
||||
inherit: true,
|
||||
onTryMove(attacker, defender, move) {
|
||||
if (attacker.side.pokemonLeft === 1) {
|
||||
this.add('-fail', attacker, 'move: Perish Song');
|
||||
this.hint("Self KO Clause: The last pokemon on a team cannot use moves that force fainting");
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
destinybond: {
|
||||
inherit: true,
|
||||
onTryMove(attacker, defender, move) {
|
||||
if (attacker.side.pokemonLeft === 1) {
|
||||
this.add('-fail', attacker, 'move: Perish Song');
|
||||
this.hint("Self KO Clause: The last pokemon on a team cannot use moves that force fainting");
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
27
data/mods/gen3colosseum/scripts.ts
Normal file
27
data/mods/gen3colosseum/scripts.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
inherit: 'gen3',
|
||||
gen: 3,
|
||||
|
||||
checkWin(faintData?: Battle['faintQueue'][0]) {
|
||||
if (this.sides.every(side => !side.pokemonLeft)) {
|
||||
let isSelfKo = false;
|
||||
if (faintData?.effect) {
|
||||
isSelfKo = isSelfKo || this.dex.moves.getByID(faintData?.effect?.id).selfdestruct !== undefined;
|
||||
isSelfKo = isSelfKo || this.dex.moves.getByID(faintData?.effect?.id).recoil !== undefined;
|
||||
}
|
||||
if (isSelfKo) {
|
||||
this.win(faintData ? faintData.target.side : null);
|
||||
return true;
|
||||
} else {
|
||||
this.win(undefined);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (const side of this.sides) {
|
||||
if (!side.foePokemonLeft()) {
|
||||
this.win(side);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
1364
data/mods/gen3rs/formats-data.ts
Normal file
1364
data/mods/gen3rs/formats-data.ts
Normal file
File diff suppressed because it is too large
Load Diff
58
data/mods/gen3rs/items.ts
Normal file
58
data/mods/gen3rs/items.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
||||
apicotberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
berryjuice: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
fastball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
ganlonberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
heavyball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
lansatberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
levelball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
loveball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
lureball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
moonball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
petayaberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
salacberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
sportball: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
starfberry: {
|
||||
inherit: true,
|
||||
isNonstandard: "Unobtainable",
|
||||
},
|
||||
};
|
||||
7684
data/mods/gen3rs/learnsets.ts
Normal file
7684
data/mods/gen3rs/learnsets.ts
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,3 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
inherit: 'gen7',
|
||||
gen: 7,
|
||||
inherit: 'gen3',
|
||||
};
|
||||
|
|
@ -23,6 +23,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
onResidualSubOrder: 10,
|
||||
},
|
||||
blaze: {
|
||||
inherit: true,
|
||||
onModifyAtk() {},
|
||||
onModifySpA() {},
|
||||
onBasePowerPriority: 2,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.type === 'Fire' && attacker.hp <= attacker.maxhp / 3) {
|
||||
|
|
@ -30,9 +33,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
name: "Blaze",
|
||||
rating: 2,
|
||||
num: 66,
|
||||
},
|
||||
cloudnine: {
|
||||
inherit: true,
|
||||
|
|
@ -58,7 +58,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
onSourceModifyAccuracy(accuracy) {
|
||||
if (typeof accuracy !== 'number') return;
|
||||
this.debug('compoundeyes - enhancing accuracy');
|
||||
return accuracy * 1.3;
|
||||
return this.chainModify(1.3);
|
||||
},
|
||||
inherit: true,
|
||||
},
|
||||
|
|
@ -128,19 +128,15 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
}
|
||||
},
|
||||
condition: {
|
||||
noCopy: true, // doesn't get copied by Baton Pass
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'ability: Flash Fire');
|
||||
},
|
||||
inherit: true,
|
||||
onModifyAtk() {},
|
||||
onModifySpA() {},
|
||||
onModifyDamagePhase1(atk, attacker, defender, move) {
|
||||
if (move.type === 'Fire') {
|
||||
this.debug('Flash Fire boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'ability: Flash Fire', '[silent]');
|
||||
},
|
||||
},
|
||||
},
|
||||
flowergift: {
|
||||
|
|
@ -190,7 +186,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
inherit: true,
|
||||
onStart(pokemon) {
|
||||
const target = pokemon.side.randomFoe();
|
||||
if (target?.item && !target.itemState.knockedOff) {
|
||||
if (target?.item) {
|
||||
this.add('-item', '', target.getItem().name, '[from] ability: Frisk', `[of] ${pokemon}`);
|
||||
}
|
||||
},
|
||||
|
|
@ -200,20 +196,19 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
onSourceModifyAccuracyPriority: 7,
|
||||
onSourceModifyAccuracy(accuracy, target, source, move) {
|
||||
if (move.category === 'Physical' && typeof accuracy === 'number') {
|
||||
return accuracy * 0.8;
|
||||
return this.chainModify(0.8);
|
||||
}
|
||||
},
|
||||
},
|
||||
hydration: {
|
||||
inherit: true,
|
||||
onResidual() {},
|
||||
onWeather(target, source, effect) {
|
||||
if (effect.id === 'raindance' && target.status) {
|
||||
this.add('-activate', target, 'ability: Hydration');
|
||||
target.cureStatus();
|
||||
}
|
||||
},
|
||||
name: "Hydration",
|
||||
rating: 1.5,
|
||||
num: 93,
|
||||
},
|
||||
insomnia: {
|
||||
inherit: true,
|
||||
|
|
@ -270,31 +265,24 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
},
|
||||
},
|
||||
magicguard: {
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (effect.effectType !== 'Move') {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
inherit: true,
|
||||
onSetStatus(status, target, source, effect) {
|
||||
if (effect && effect.id === 'toxicspikes') {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
name: "Magic Guard",
|
||||
rating: 4.5,
|
||||
num: 98,
|
||||
},
|
||||
minus: {
|
||||
inherit: true,
|
||||
onModifySpAPriority: undefined,
|
||||
onModifySpA(spa, pokemon) {
|
||||
for (const ally of pokemon.allies()) {
|
||||
if (ally.ability === 'plus') {
|
||||
return spa * 1.5;
|
||||
for (const allyActive of pokemon.allies()) {
|
||||
if (allyActive.hasAbility('plus')) {
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
}
|
||||
},
|
||||
name: "Minus",
|
||||
rating: 0,
|
||||
num: 58,
|
||||
},
|
||||
naturalcure: {
|
||||
inherit: true,
|
||||
|
|
@ -318,6 +306,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
},
|
||||
},
|
||||
overgrow: {
|
||||
inherit: true,
|
||||
onModifyAtk() {},
|
||||
onModifySpA() {},
|
||||
onBasePowerPriority: 2,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.type === 'Grass' && attacker.hp <= attacker.maxhp / 3) {
|
||||
|
|
@ -325,26 +316,23 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
name: "Overgrow",
|
||||
rating: 2,
|
||||
num: 65,
|
||||
},
|
||||
pickup: {
|
||||
name: "Pickup",
|
||||
inherit: true,
|
||||
onResidual() {},
|
||||
rating: 0,
|
||||
num: 53,
|
||||
// No competitive use
|
||||
},
|
||||
plus: {
|
||||
inherit: true,
|
||||
onModifySpAPriority: undefined,
|
||||
onModifySpA(spa, pokemon) {
|
||||
for (const ally of pokemon.allies()) {
|
||||
if (ally.ability === 'minus') {
|
||||
return spa * 1.5;
|
||||
for (const allyActive of pokemon.allies()) {
|
||||
if (allyActive.hasAbility('minus')) {
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
}
|
||||
},
|
||||
name: "Plus",
|
||||
rating: 0,
|
||||
num: 57,
|
||||
},
|
||||
poisonpoint: {
|
||||
inherit: true,
|
||||
|
|
@ -357,16 +345,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
},
|
||||
},
|
||||
pressure: {
|
||||
onStart(pokemon) {
|
||||
this.add('-ability', pokemon, 'Pressure');
|
||||
},
|
||||
inherit: true,
|
||||
onDeductPP(target, source) {
|
||||
if (target === source) return;
|
||||
return 1;
|
||||
},
|
||||
name: "Pressure",
|
||||
rating: 1.5,
|
||||
num: 46,
|
||||
},
|
||||
roughskin: {
|
||||
inherit: true,
|
||||
|
|
@ -383,14 +367,14 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
if (typeof accuracy !== 'number') return;
|
||||
if (this.field.isWeather('sandstorm')) {
|
||||
this.debug('Sand Veil - decreasing accuracy');
|
||||
return accuracy * 0.8;
|
||||
return this.chainModify(0.8);
|
||||
}
|
||||
},
|
||||
},
|
||||
serenegrace: {
|
||||
inherit: true,
|
||||
onModifyMove(move) {
|
||||
if (move.secondaries) {
|
||||
if (move.secondaries && move.id !== 'chatter') {
|
||||
this.debug('doubling secondary chance');
|
||||
for (const secondary of move.secondaries) {
|
||||
if (secondary.chance) secondary.chance *= 2;
|
||||
|
|
@ -404,16 +388,14 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
onResidualSubOrder: 3,
|
||||
},
|
||||
simple: {
|
||||
inherit: true,
|
||||
onChangeBoost() {},
|
||||
onModifyBoost(boosts) {
|
||||
let key: BoostID;
|
||||
for (key in boosts) {
|
||||
boosts[key]! *= 2;
|
||||
}
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Simple",
|
||||
rating: 4,
|
||||
num: 86,
|
||||
},
|
||||
snowcloak: {
|
||||
inherit: true,
|
||||
|
|
@ -422,7 +404,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
if (typeof accuracy !== 'number') return;
|
||||
if (this.field.isWeather('hail')) {
|
||||
this.debug('Snow Cloak - decreasing accuracy');
|
||||
return accuracy * 0.8;
|
||||
return this.chainModify(0.8);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -442,9 +424,10 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
},
|
||||
},
|
||||
stench: {
|
||||
name: "Stench",
|
||||
inherit: true,
|
||||
onModifyMove() {},
|
||||
rating: 0,
|
||||
num: 1,
|
||||
// No competitive use
|
||||
},
|
||||
stickyhold: {
|
||||
inherit: true,
|
||||
|
|
@ -466,6 +449,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
rating: 0,
|
||||
},
|
||||
swarm: {
|
||||
inherit: true,
|
||||
onModifyAtk() {},
|
||||
onModifySpA() {},
|
||||
onBasePowerPriority: 2,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.type === 'Bug' && attacker.hp <= attacker.maxhp / 3) {
|
||||
|
|
@ -473,9 +459,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
name: "Swarm",
|
||||
rating: 2,
|
||||
num: 68,
|
||||
},
|
||||
synchronize: {
|
||||
inherit: true,
|
||||
|
|
@ -495,23 +478,25 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
if (typeof accuracy !== 'number') return;
|
||||
if (target?.volatiles['confusion']) {
|
||||
this.debug('Tangled Feet - decreasing accuracy');
|
||||
return accuracy * 0.5;
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
thickfat: {
|
||||
inherit: true,
|
||||
onSourceModifyAtk() {},
|
||||
onSourceModifySpA() {},
|
||||
onSourceBasePowerPriority: 1,
|
||||
onSourceBasePower(basePower, attacker, defender, move) {
|
||||
if (move.type === 'Ice' || move.type === 'Fire') {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Thick Fat",
|
||||
rating: 3.5,
|
||||
num: 47,
|
||||
},
|
||||
torrent: {
|
||||
inherit: true,
|
||||
onModifyAtk() {},
|
||||
onModifySpA() {},
|
||||
onBasePowerPriority: 2,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.type === 'Water' && attacker.hp <= attacker.maxhp / 3) {
|
||||
|
|
@ -519,9 +504,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
name: "Torrent",
|
||||
rating: 2,
|
||||
num: 67,
|
||||
},
|
||||
trace: {
|
||||
inherit: true,
|
||||
|
|
@ -534,22 +516,10 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
if (bannedAbilities.includes(target.ability)) {
|
||||
return;
|
||||
}
|
||||
if (pokemon.setAbility(ability)) {
|
||||
this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
|
||||
}
|
||||
pokemon.setAbility(ability, target);
|
||||
},
|
||||
flags: { notrace: 1 },
|
||||
},
|
||||
unburden: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onModifySpe(spe, pokemon) {
|
||||
if ((!pokemon.item || pokemon.itemState.knockedOff) && !pokemon.ignoringAbility()) {
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
vitalspirit: {
|
||||
inherit: true,
|
||||
rating: 2.5,
|
||||
|
|
@ -561,12 +531,16 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
this.hint("In Gen 4, Fire Fang is always able to hit through Wonder Guard.", true, target.side);
|
||||
return;
|
||||
}
|
||||
if (target === source || move.category === 'Status' || move.type === '???' || move.id === 'struggle') return;
|
||||
if (target === source || move.category === 'Status' || move.type === '???') return;
|
||||
this.debug('Wonder Guard immunity: ' + move.id);
|
||||
if (target.runEffectiveness(move) <= 0) {
|
||||
if (target.runEffectiveness(move) <= 0 || !target.runImmunity(move)) {
|
||||
this.add('-immune', target, '[from] ability: Wonder Guard');
|
||||
return null;
|
||||
}
|
||||
},
|
||||
},
|
||||
rebound: {
|
||||
inherit: true,
|
||||
onTryHitSide() {},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -116,6 +116,10 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
onResidualOrder: 10,
|
||||
onResidualSubOrder: 9,
|
||||
},
|
||||
lockedmove: {
|
||||
inherit: true,
|
||||
onAfterMove() {},
|
||||
},
|
||||
choicelock: {
|
||||
inherit: true,
|
||||
onStart(pokemon) {
|
||||
|
|
|
|||
|
|
@ -736,7 +736,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NU",
|
||||
},
|
||||
weavile: {
|
||||
tier: "OU",
|
||||
tier: "(OU)",
|
||||
},
|
||||
teddiursa: {
|
||||
tier: "LC",
|
||||
|
|
@ -1137,9 +1137,12 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
castform: {
|
||||
tier: "NU",
|
||||
},
|
||||
castformsunny: {},
|
||||
castformrainy: {},
|
||||
castformsnowy: {},
|
||||
castformsunny: {
|
||||
},
|
||||
castformrainy: {
|
||||
},
|
||||
castformsnowy: {
|
||||
},
|
||||
kecleon: {
|
||||
tier: "NU",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
},
|
||||
focussash: {
|
||||
inherit: true,
|
||||
onDamage() { },
|
||||
onDamage() {},
|
||||
onTryHit(target, source, move) {
|
||||
if (target !== source && target.hp === target.maxhp) {
|
||||
target.addVolatile('focussash');
|
||||
|
|
@ -306,11 +306,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
metronome: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onStart(pokemon) {
|
||||
this.effectState.numConsecutive = 0;
|
||||
this.effectState.lastMove = '';
|
||||
},
|
||||
onTryMovePriority: -2,
|
||||
inherit: true,
|
||||
onTryMove(pokemon, target, move) {
|
||||
if (!pokemon.hasItem('metronome')) {
|
||||
pokemon.removeVolatile('metronome');
|
||||
|
|
@ -323,6 +319,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
}
|
||||
this.effectState.lastMove = move.id;
|
||||
},
|
||||
onModifyDamage() {},
|
||||
onModifyDamagePhase2(damage, source, target, move) {
|
||||
return damage * (1 + (this.effectState.numConsecutive / 10));
|
||||
},
|
||||
|
|
@ -331,7 +328,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
|||
micleberry: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 2,
|
||||
inherit: true,
|
||||
onSourceModifyAccuracyPriority: 3,
|
||||
onSourceModifyAccuracy(accuracy, target, source) {
|
||||
this.add('-enditem', source, 'Micle Berry');
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,11 +1,20 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
standardag: {
|
||||
inherit: true,
|
||||
ruleset: [
|
||||
'Obtainable', 'HP Percentage Mod', 'Cancel Mod', 'Beat Up Nicknames Mod', 'Endless Battle Clause',
|
||||
],
|
||||
},
|
||||
standard: {
|
||||
inherit: true,
|
||||
ruleset: ['Obtainable', 'Sleep Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Sleep Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
},
|
||||
flatrules: {
|
||||
inherit: true,
|
||||
ruleset: ['Obtainable', 'Species Clause', 'Nickname Clause', 'Item Clause = 1', 'Adjust Level Down = 50', 'Cancel Mod'],
|
||||
ruleset: ['Obtainable', 'Species Clause', 'Nickname Clause', 'Beat Up Nicknames Mod', 'Item Clause = 1', 'Adjust Level Down = 50', 'Picked Team Size = Auto', 'Cancel Mod'],
|
||||
},
|
||||
teampreview: {
|
||||
inherit: true,
|
||||
|
|
|
|||
|
|
@ -55,10 +55,6 @@ export const Scripts: ModdedBattleScriptsData = {
|
|||
// Weather
|
||||
baseDamage = this.battle.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
|
||||
|
||||
if (this.battle.gen === 3 && move.category === 'Physical' && !Math.floor(baseDamage)) {
|
||||
baseDamage = 1;
|
||||
}
|
||||
|
||||
baseDamage += 2;
|
||||
|
||||
const isCrit = target.getMoveHitData(move).crit;
|
||||
|
|
|
|||
|
|
@ -1475,7 +1475,6 @@ export const Learnsets: import('../../../sim/dex-species').ModdedLearnsetDataTab
|
|||
hiddenpower: ["4M", "3M"],
|
||||
irontail: ["4M", "4S21", "3M"],
|
||||
knockoff: ["4T"],
|
||||
lastresort: ["4S18"],
|
||||
lightscreen: ["4M", "4L42", "4S11", "3M", "3L50", "3S0", "3S6", "3S7", "3S8"],
|
||||
magnetrise: ["4T"],
|
||||
megakick: ["3T"],
|
||||
|
|
@ -2916,7 +2915,6 @@ export const Learnsets: import('../../../sim/dex-species').ModdedLearnsetDataTab
|
|||
steelwing: ["4M", "3M"],
|
||||
substitute: ["4M", "3T"],
|
||||
sunnyday: ["4M", "3M"],
|
||||
superfang: ["4S0"],
|
||||
supersonic: ["4L1", "3L1"],
|
||||
swagger: ["4M", "3T"],
|
||||
swift: ["4T", "3T"],
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
newMove.hasBounced = true;
|
||||
newMove.pranksterBoosted = false;
|
||||
this.actions.useMove(newMove, this.effectState.target, { target: source });
|
||||
move.hasBounced = true; // only bounce once in free-for-all battles
|
||||
return null;
|
||||
},
|
||||
},
|
||||
|
|
@ -64,6 +65,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
},
|
||||
overcoat: {
|
||||
inherit: true,
|
||||
onImmunity(type, pokemon) {
|
||||
if (type === 'sandstorm' || type === 'hail') return false;
|
||||
},
|
||||
onTryHit() {},
|
||||
flags: {},
|
||||
rating: 0.5,
|
||||
|
|
@ -87,4 +91,20 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
inherit: true,
|
||||
onAllyTryHitSide() {},
|
||||
},
|
||||
rebound: {
|
||||
inherit: true,
|
||||
onAllyTryHitSide(target, source, move) {
|
||||
if (this.effectState.target.activeTurns) return;
|
||||
|
||||
if (target.isAlly(source) || move.hasBounced || !move.flags['reflectable']) {
|
||||
return;
|
||||
}
|
||||
const newMove = this.dex.getActiveMove(move.id);
|
||||
newMove.hasBounced = true;
|
||||
newMove.pranksterBoosted = false;
|
||||
this.actions.useMove(newMove, this.effectState.target, { target: source });
|
||||
move.hasBounced = true; // only bounce once in free-for-all battles
|
||||
return null;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
|
|||
const trapper = this.effectState.source;
|
||||
if (trapper && (!trapper.isActive || trapper.hp <= 0 || !trapper.activeTurns)) {
|
||||
delete pokemon.volatiles['partiallytrapped'];
|
||||
this.add('-end', pokemon, this.effectState.sourceEffect, '[partiallytrapped]', '[silent]');
|
||||
return;
|
||||
}
|
||||
this.damage(pokemon.baseMaxhp / this.effectState.boundDivisor);
|
||||
|
|
|
|||
|
|
@ -1347,7 +1347,8 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
},
|
||||
castformrainy: {
|
||||
},
|
||||
castformsnowy: {},
|
||||
castformsnowy: {
|
||||
},
|
||||
kecleon: {
|
||||
tier: "PU",
|
||||
doublesTier: "DUU",
|
||||
|
|
@ -1625,7 +1626,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
gastrodon: {
|
||||
tier: "OU",
|
||||
tier: "(OU)",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
drifloon: {
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
autotomize: {
|
||||
inherit: true,
|
||||
volatileStatus: 'autotomize',
|
||||
onHit(pokemon) {
|
||||
},
|
||||
onHit() {},
|
||||
condition: {
|
||||
noCopy: true, // doesn't get copied by Baton Pass
|
||||
onStart(pokemon) {
|
||||
|
|
@ -78,6 +77,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
flags: { protect: 1, reflectable: 1, mirror: 1, metronome: 1 },
|
||||
},
|
||||
bodyslam: {
|
||||
inherit: true,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 },
|
||||
},
|
||||
bounce: {
|
||||
inherit: true,
|
||||
flags: { contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, metronome: 1, nosleeptalk: 1 },
|
||||
|
|
@ -105,7 +108,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
basePower: 60,
|
||||
onModifyMove(move, pokemon) {
|
||||
if (pokemon.species.name !== 'Chatot') delete move.secondaries;
|
||||
if (pokemon.species.name !== 'Chatot') {
|
||||
const confusion = move.secondaries?.find(secondary => secondary.volatileStatus === 'confusion');
|
||||
if (confusion) confusion.chance = 0; // boosted by Sheer Force
|
||||
}
|
||||
},
|
||||
secondary: {
|
||||
chance: 10,
|
||||
|
|
@ -189,6 +195,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, punch: 1, metronome: 1 },
|
||||
},
|
||||
dragonrush: {
|
||||
inherit: true,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
|
||||
},
|
||||
dreameater: {
|
||||
inherit: true,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
|
|
@ -257,10 +267,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
basePower: 20,
|
||||
condition: {
|
||||
duration: 2,
|
||||
onStart() {
|
||||
this.effectState.multiplier = 1;
|
||||
},
|
||||
inherit: true,
|
||||
onRestart() {
|
||||
if (this.effectState.multiplier < 8) {
|
||||
this.effectState.multiplier <<= 1;
|
||||
|
|
@ -352,8 +359,17 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
healpulse: {
|
||||
inherit: true,
|
||||
heal: [1, 2],
|
||||
onHit() {},
|
||||
onHit(target, source) {
|
||||
const success = !!this.heal(Math.ceil(target.baseMaxhp * 0.5));
|
||||
if (success && !target.isAlly(source)) {
|
||||
target.staleness = 'external';
|
||||
}
|
||||
return success;
|
||||
},
|
||||
},
|
||||
heatcrash: {
|
||||
inherit: true,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 },
|
||||
},
|
||||
heatwave: {
|
||||
inherit: true,
|
||||
|
|
@ -486,13 +502,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
lightscreen: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
durationCallback(target, source, effect) {
|
||||
if (source?.hasItem('lightclay')) {
|
||||
return 8;
|
||||
}
|
||||
return 5;
|
||||
},
|
||||
inherit: true,
|
||||
onAnyModifyDamage(damage, source, target, move) {
|
||||
if (target !== source && this.effectState.target.hasAlly(target) && this.getCategory(move) === 'Special') {
|
||||
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
|
||||
|
|
@ -502,14 +512,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
}
|
||||
},
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Light Screen');
|
||||
},
|
||||
onSideResidualOrder: 26,
|
||||
onSideResidualSubOrder: 2,
|
||||
onSideEnd(side) {
|
||||
this.add('-sideend', side, 'move: Light Screen');
|
||||
},
|
||||
},
|
||||
},
|
||||
lowsweep: {
|
||||
|
|
@ -519,24 +521,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
magiccoat: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 1,
|
||||
onStart(target, source, effect) {
|
||||
this.add('-singleturn', target, 'move: Magic Coat');
|
||||
if (effect?.effectType === 'Move') {
|
||||
this.effectState.pranksterBoosted = effect.pranksterBoosted;
|
||||
}
|
||||
},
|
||||
onTryHitPriority: 2,
|
||||
onTryHit(target, source, move) {
|
||||
if (target === source || move.hasBounced || !move.flags['reflectable'] || target.isSemiInvulnerable()) {
|
||||
return;
|
||||
}
|
||||
const newMove = this.dex.getActiveMove(move.id);
|
||||
newMove.hasBounced = true;
|
||||
newMove.pranksterBoosted = this.effectState.pranksterBoosted;
|
||||
this.actions.useMove(newMove, target, { target: source });
|
||||
return null;
|
||||
},
|
||||
inherit: true,
|
||||
onAllyTryHitSide(target, source, move) {
|
||||
if (target.isAlly(source) || move.hasBounced || !move.flags['reflectable']) {
|
||||
return;
|
||||
|
|
@ -545,6 +530,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
newMove.hasBounced = true;
|
||||
newMove.pranksterBoosted = false;
|
||||
this.actions.useMove(newMove, this.effectState.target, { target: source });
|
||||
move.hasBounced = true; // only bounce once in free-for-all battles
|
||||
return null;
|
||||
},
|
||||
},
|
||||
|
|
@ -578,18 +564,18 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
pp: 20,
|
||||
condition: {
|
||||
noCopy: true,
|
||||
onSourceModifyDamage(damage, source, target, move) {
|
||||
if (['stomp', 'steamroller'].includes(move.id)) {
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
inherit: true,
|
||||
onAccuracy() {},
|
||||
},
|
||||
},
|
||||
moonlight: {
|
||||
inherit: true,
|
||||
type: "Normal",
|
||||
},
|
||||
muddywater: {
|
||||
inherit: true,
|
||||
basePower: 95,
|
||||
},
|
||||
mudsport: {
|
||||
inherit: true,
|
||||
pseudoWeather: undefined,
|
||||
|
|
@ -608,10 +594,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
},
|
||||
},
|
||||
muddywater: {
|
||||
inherit: true,
|
||||
basePower: 95,
|
||||
},
|
||||
naturepower: {
|
||||
inherit: true,
|
||||
onTryHit() {},
|
||||
|
|
@ -652,6 +634,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
basePower: 70,
|
||||
},
|
||||
psychoshift: {
|
||||
inherit: true,
|
||||
accuracy: 90,
|
||||
},
|
||||
psychup: {
|
||||
inherit: true,
|
||||
onHit(target, source) {
|
||||
|
|
@ -662,10 +648,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.add('-copyboost', source, target, '[from] move: Psych Up');
|
||||
},
|
||||
},
|
||||
psychoshift: {
|
||||
inherit: true,
|
||||
accuracy: 90,
|
||||
},
|
||||
psywave: {
|
||||
inherit: true,
|
||||
accuracy: 80,
|
||||
|
|
@ -680,11 +662,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
source.addVolatile('stall');
|
||||
},
|
||||
condition: {
|
||||
duration: 1,
|
||||
onSideStart(target, source) {
|
||||
this.add('-singleturn', source, 'Quick Guard');
|
||||
},
|
||||
onTryHitPriority: 4,
|
||||
inherit: true,
|
||||
onTryHit(target, source, effect) {
|
||||
// Quick Guard only blocks moves with a natural positive priority
|
||||
// (e.g. it doesn't block 0 priority moves boosted by Prankster)
|
||||
|
|
@ -711,13 +689,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
reflect: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
durationCallback(target, source, effect) {
|
||||
if (source?.hasItem('lightclay')) {
|
||||
return 8;
|
||||
}
|
||||
return 5;
|
||||
},
|
||||
inherit: true,
|
||||
onAnyModifyDamage(damage, source, target, move) {
|
||||
if (target !== source && this.effectState.target.hasAlly(target) && this.getCategory(move) === 'Physical') {
|
||||
if (!target.getMoveHitData(move).crit && !move.infiltrates) {
|
||||
|
|
@ -727,14 +699,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
}
|
||||
}
|
||||
},
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'Reflect');
|
||||
},
|
||||
onSideResidualOrder: 26,
|
||||
onSideResidualSubOrder: 1,
|
||||
onSideEnd(side) {
|
||||
this.add('-sideend', side, 'Reflect');
|
||||
},
|
||||
},
|
||||
},
|
||||
relicsong: {
|
||||
|
|
@ -785,19 +749,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1 },
|
||||
},
|
||||
skillswap: {
|
||||
inherit: true,
|
||||
onHit(target, source) {
|
||||
const targetAbility = target.ability;
|
||||
const sourceAbility = source.ability;
|
||||
if (targetAbility === sourceAbility) {
|
||||
return false;
|
||||
}
|
||||
this.add('-activate', source, 'move: Skill Swap', this.dex.abilities.get(targetAbility), this.dex.abilities.get(sourceAbility), `[of] ${target}`);
|
||||
source.setAbility(targetAbility);
|
||||
target.setAbility(sourceAbility);
|
||||
},
|
||||
},
|
||||
skullbash: {
|
||||
inherit: true,
|
||||
basePower: 100,
|
||||
|
|
@ -885,12 +836,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
substitute: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'Substitute');
|
||||
this.effectState.hp = Math.floor(target.maxhp / 4);
|
||||
delete target.volatiles['partiallytrapped'];
|
||||
},
|
||||
onTryPrimaryHitPriority: -1,
|
||||
inherit: true,
|
||||
onTryPrimaryHit(target, source, move) {
|
||||
if (target === source || move.flags['bypasssub']) {
|
||||
return;
|
||||
|
|
@ -901,10 +847,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.attrLastMove('[still]');
|
||||
return null;
|
||||
}
|
||||
damage = this.runEvent('SubDamage', target, source, move, damage);
|
||||
if (!damage) {
|
||||
return damage;
|
||||
}
|
||||
if (damage > target.volatiles['substitute'].hp) {
|
||||
damage = target.volatiles['substitute'].hp as number;
|
||||
}
|
||||
|
|
@ -926,9 +868,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.runEvent('AfterSubDamage', target, source, move, damage);
|
||||
return this.HIT_SUBSTITUTE;
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Substitute');
|
||||
},
|
||||
},
|
||||
},
|
||||
submission: {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
|
|||
standard: {
|
||||
inherit: true,
|
||||
ruleset: [
|
||||
'Obtainable', 'Team Preview', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Moody Clause', 'Evasion Items Clause', 'Evasion Moves Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod',
|
||||
'Standard AG',
|
||||
'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
},
|
||||
obtainablemoves: {
|
||||
|
|
|
|||
|
|
@ -2,39 +2,108 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
venusaur: {
|
||||
tier: "OU",
|
||||
},
|
||||
raichu: {
|
||||
tier: "PU",
|
||||
},
|
||||
golbat: {
|
||||
tier: "NFE",
|
||||
},
|
||||
vileplume: {
|
||||
tier: "NU",
|
||||
},
|
||||
dugtrio: {
|
||||
tier: "OU",
|
||||
},
|
||||
primeape: {
|
||||
tier: "RU",
|
||||
},
|
||||
cloyster: {
|
||||
tier: "OU",
|
||||
},
|
||||
electrode: {
|
||||
tier: "PU",
|
||||
},
|
||||
marowak: {
|
||||
tier: "NU",
|
||||
},
|
||||
chansey: {
|
||||
tier: "OU",
|
||||
},
|
||||
kangaskhan: {
|
||||
tier: "PU",
|
||||
},
|
||||
electabuzz: {
|
||||
tier: "PU",
|
||||
},
|
||||
lapras: {
|
||||
tier: "PU",
|
||||
},
|
||||
ditto: {
|
||||
tier: "PU",
|
||||
},
|
||||
vaporeon: {
|
||||
tier: "OU",
|
||||
},
|
||||
jolteon: {
|
||||
tier: "OU",
|
||||
},
|
||||
flareon: {
|
||||
tier: "NU",
|
||||
},
|
||||
ampharos: {
|
||||
tier: "PU",
|
||||
},
|
||||
quagsire: {
|
||||
tier: "NU",
|
||||
},
|
||||
espeon: {
|
||||
tier: "OU",
|
||||
},
|
||||
donphan: {
|
||||
tier: "OU",
|
||||
},
|
||||
linoone: {
|
||||
tier: "PU",
|
||||
},
|
||||
vigoroth: {
|
||||
tier: "NFE",
|
||||
},
|
||||
roselia: {
|
||||
tier: "RU",
|
||||
},
|
||||
zangoose: {
|
||||
tier: "PU",
|
||||
},
|
||||
cradily: {
|
||||
tier: "PU",
|
||||
},
|
||||
absol: {
|
||||
tier: "NU",
|
||||
},
|
||||
froslass: {
|
||||
tier: "UU",
|
||||
},
|
||||
metagross: {
|
||||
tier: "OU",
|
||||
},
|
||||
regice: {
|
||||
tier: "PU",
|
||||
},
|
||||
deoxysdefense: {
|
||||
tier: "UUBL",
|
||||
},
|
||||
torterra: {
|
||||
tier: "NU",
|
||||
},
|
||||
infernape: {
|
||||
tier: "OU",
|
||||
},
|
||||
luxray: {
|
||||
tier: "NU",
|
||||
},
|
||||
garchomp: {
|
||||
tier: "Uber",
|
||||
},
|
||||
lucario: {
|
||||
tier: "OU",
|
||||
},
|
||||
|
|
@ -50,27 +119,96 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
abomasnow: {
|
||||
tier: "UUBL",
|
||||
},
|
||||
garchomp: {
|
||||
tier: "Uber",
|
||||
magmortar: {
|
||||
tier: "NU",
|
||||
},
|
||||
leafeon: {
|
||||
tier: "NU",
|
||||
},
|
||||
porygonz: {
|
||||
tier: "RUBL",
|
||||
},
|
||||
rotomfrost: {
|
||||
tier: "PU",
|
||||
},
|
||||
emboar: {
|
||||
tier: "NU",
|
||||
},
|
||||
stoutland: {
|
||||
tier: "UU",
|
||||
},
|
||||
liepard: {
|
||||
tier: "PU",
|
||||
},
|
||||
simipour: {
|
||||
tier: "PU",
|
||||
},
|
||||
gigalith: {
|
||||
tier: "PU",
|
||||
},
|
||||
excadrill: {
|
||||
tier: "Uber",
|
||||
},
|
||||
seismitoad: {
|
||||
tier: "PU",
|
||||
},
|
||||
throh: {
|
||||
tier: "PU",
|
||||
},
|
||||
scolipede: {
|
||||
tier: "RU",
|
||||
},
|
||||
basculin: {
|
||||
tier: "NU",
|
||||
},
|
||||
scrafty: {
|
||||
tier: "OU",
|
||||
},
|
||||
cofagrigus: {
|
||||
tier: "RU",
|
||||
},
|
||||
carracosta: {
|
||||
tier: "PU",
|
||||
},
|
||||
cinccino: {
|
||||
tier: "NU",
|
||||
},
|
||||
gothorita: {
|
||||
tier: "NFE",
|
||||
},
|
||||
gothitelle: {
|
||||
tier: "PU",
|
||||
},
|
||||
swanna: {
|
||||
tier: "PU",
|
||||
},
|
||||
escavalier: {
|
||||
tier: "UU",
|
||||
},
|
||||
amoongus: {
|
||||
tier: "NU",
|
||||
},
|
||||
chandelure: {
|
||||
tier: "UU",
|
||||
},
|
||||
haxorus: {
|
||||
tier: "OU",
|
||||
},
|
||||
cryogonal: {
|
||||
tier: "NU",
|
||||
},
|
||||
mienshao: {
|
||||
tier: "OU",
|
||||
},
|
||||
golurk: {
|
||||
tier: "RU",
|
||||
},
|
||||
mandibuzz: {
|
||||
tier: "RU",
|
||||
},
|
||||
durant: {
|
||||
tier: "RUBL",
|
||||
},
|
||||
hydreigon: {
|
||||
tier: "OU",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1585,7 +1585,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
huntail: {
|
||||
tier: "ZU",
|
||||
tier: "ZUBL",
|
||||
doublesTier: "(DUU)",
|
||||
},
|
||||
gorebyss: {
|
||||
|
|
@ -1678,7 +1678,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
doublesTier: "DUber",
|
||||
},
|
||||
jirachi: {
|
||||
tier: "OU",
|
||||
tier: "(OU)",
|
||||
doublesTier: "DUber",
|
||||
},
|
||||
deoxys: {
|
||||
|
|
|
|||
|
|
@ -34,51 +34,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
},
|
||||
},
|
||||
},
|
||||
encore: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 3,
|
||||
onStart(target) {
|
||||
const moveIndex = target.lastMove ? target.moves.indexOf(target.lastMove.id) : -1;
|
||||
if (
|
||||
!target.lastMove || target.lastMove.flags['failencore'] ||
|
||||
!target.moveSlots[moveIndex] || target.moveSlots[moveIndex].pp <= 0
|
||||
) {
|
||||
// it failed
|
||||
return false;
|
||||
}
|
||||
this.effectState.move = target.lastMove.id;
|
||||
this.add('-start', target, 'Encore');
|
||||
if (!this.queue.willMove(target)) {
|
||||
this.effectState.duration!++;
|
||||
}
|
||||
},
|
||||
onOverrideAction(pokemon, target, move) {
|
||||
if (move.id !== this.effectState.move) return this.effectState.move;
|
||||
},
|
||||
onResidualOrder: 16,
|
||||
onResidual(target) {
|
||||
const lockedMoveIndex = target.moves.indexOf(this.effectState.move);
|
||||
if (lockedMoveIndex >= 0 && target.moveSlots[lockedMoveIndex].pp <= 0) {
|
||||
// Encore ends early if you run out of PP
|
||||
target.removeVolatile('encore');
|
||||
}
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Encore');
|
||||
},
|
||||
onDisableMove(pokemon) {
|
||||
if (!this.effectState.move || !pokemon.hasMove(this.effectState.move)) {
|
||||
return;
|
||||
}
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
if (moveSlot.id !== this.effectState.move) {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
fellstinger: {
|
||||
inherit: true,
|
||||
basePower: 30,
|
||||
|
|
@ -90,6 +45,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
basePower: 80,
|
||||
},
|
||||
heavyslam: {
|
||||
inherit: true,
|
||||
flags: { contact: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1 },
|
||||
},
|
||||
leechlife: {
|
||||
inherit: true,
|
||||
basePower: 20,
|
||||
|
|
@ -99,29 +58,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
flags: { protect: 1, bypasssub: 1, noassist: 1, failcopycat: 1, failmefirst: 1, nosleeptalk: 1 },
|
||||
},
|
||||
minimize: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
noCopy: true,
|
||||
onSourceModifyDamage(damage, source, target, move) {
|
||||
const boostedMoves = [
|
||||
'stomp', 'steamroller', 'bodyslam', 'flyingpress', 'dragonrush', 'phantomforce', 'heatcrash', 'shadowforce',
|
||||
];
|
||||
if (boostedMoves.includes(move.id)) {
|
||||
return this.chainModify(2);
|
||||
}
|
||||
},
|
||||
onAccuracy(accuracy, target, source, move) {
|
||||
const boostedMoves = [
|
||||
'stomp', 'steamroller', 'bodyslam', 'flyingpress', 'dragonrush', 'phantomforce', 'heatcrash', 'shadowforce',
|
||||
];
|
||||
if (boostedMoves.includes(move.id)) {
|
||||
return true;
|
||||
}
|
||||
return accuracy;
|
||||
},
|
||||
},
|
||||
},
|
||||
metronome: {
|
||||
inherit: true,
|
||||
flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1 },
|
||||
|
|
@ -129,38 +65,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
mistyterrain: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
durationCallback(source, effect) {
|
||||
if (source?.hasItem('terrainextender')) {
|
||||
return 8;
|
||||
}
|
||||
return 5;
|
||||
},
|
||||
onSetStatus(status, target, source, effect) {
|
||||
if (!target.isGrounded() || target.isSemiInvulnerable()) return;
|
||||
if (effect && ((effect as Move).status || effect.id === 'yawn')) {
|
||||
this.add('-activate', target, 'move: Misty Terrain');
|
||||
}
|
||||
return false;
|
||||
},
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.type === 'Dragon' && defender.isGrounded() && !defender.isSemiInvulnerable()) {
|
||||
this.debug('misty terrain weaken');
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
onFieldStart(field, source, effect) {
|
||||
if (effect?.effectType === 'Ability') {
|
||||
this.add('-fieldstart', 'move: Misty Terrain', `[from] ability: ${effect}`, `[of] ${source}`);
|
||||
} else {
|
||||
this.add('-fieldstart', 'move: Misty Terrain');
|
||||
}
|
||||
},
|
||||
onFieldResidualOrder: 27,
|
||||
onFieldResidualSubOrder: 7,
|
||||
onFieldEnd() {
|
||||
this.add('-fieldend', 'Misty Terrain');
|
||||
},
|
||||
inherit: true,
|
||||
onTryAddVolatile() {},
|
||||
},
|
||||
},
|
||||
mysticalfire: {
|
||||
|
|
@ -181,28 +87,25 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
this.boost({ atk: -1, spa: -1 }, target, source);
|
||||
},
|
||||
},
|
||||
phantomforce: {
|
||||
inherit: true,
|
||||
flags: { contact: 1, charge: 1, mirror: 1, metronome: 1, nosleeptalk: 1, noassist: 1, failinstruct: 1, minimize: 1 },
|
||||
},
|
||||
powder: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 1,
|
||||
onStart(target) {
|
||||
this.add('-singleturn', target, 'Powder');
|
||||
},
|
||||
inherit: true,
|
||||
onTryMovePriority: 1,
|
||||
onTryMove(pokemon, target, move) {
|
||||
if (move.type === 'Fire') {
|
||||
this.add('-activate', pokemon, 'move: Powder');
|
||||
this.damage(this.clampIntRange(Math.round(pokemon.maxhp / 4), 1));
|
||||
this.attrLastMove('[still]');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
rockblast: {
|
||||
inherit: true,
|
||||
flags: { protect: 1, mirror: 1, metronome: 1 },
|
||||
},
|
||||
shadowforce: {
|
||||
inherit: true,
|
||||
flags: { contact: 1, charge: 1, mirror: 1, metronome: 1, nosleeptalk: 1, noassist: 1, failinstruct: 1, minimize: 1 },
|
||||
},
|
||||
sheercold: {
|
||||
inherit: true,
|
||||
ohko: true,
|
||||
|
|
@ -265,11 +168,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
wideguard: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 1,
|
||||
onSideStart(target, source) {
|
||||
this.add('-singleturn', source, 'Wide Guard');
|
||||
},
|
||||
onTryHitPriority: 4,
|
||||
inherit: true,
|
||||
onTryHit(target, source, effect) {
|
||||
// Wide Guard blocks damaging spread moves
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -148,6 +148,14 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
color: "Gray",
|
||||
},
|
||||
burmysandy: {
|
||||
inherit: true,
|
||||
color: "Gray",
|
||||
},
|
||||
burmytrash: {
|
||||
inherit: true,
|
||||
color: "Gray",
|
||||
},
|
||||
wormadam: {
|
||||
inherit: true,
|
||||
color: "Gray",
|
||||
|
|
@ -164,6 +172,14 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
color: "Pink",
|
||||
},
|
||||
shelloseast: {
|
||||
inherit: true,
|
||||
color: "Purple",
|
||||
},
|
||||
gastrodoneast: {
|
||||
inherit: true,
|
||||
color: "Purple",
|
||||
},
|
||||
arceus: {
|
||||
inherit: true,
|
||||
color: "Gray",
|
||||
|
|
@ -297,6 +313,18 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
color: "Yellow",
|
||||
},
|
||||
deerlingsummer: {
|
||||
inherit: true,
|
||||
color: "Yellow",
|
||||
},
|
||||
deerlingautumn: {
|
||||
inherit: true,
|
||||
color: "Yellow",
|
||||
},
|
||||
deerlingwinter: {
|
||||
inherit: true,
|
||||
color: "Yellow",
|
||||
},
|
||||
cubchoo: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Snow Cloak", H: "Rattled" },
|
||||
|
|
@ -318,6 +346,82 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonicysnow: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonpolar: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillontundra: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivilloncontinental: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillongarden: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonelegant: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonmodern: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonmarine: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonarchipelago: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonhighplains: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonsandstorm: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonriver: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonmonsoon: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonsavanna: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonsun: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonocean: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonjungle: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonfancy: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
vivillonpokeball: {
|
||||
inherit: true,
|
||||
color: "Black",
|
||||
},
|
||||
meowstic: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
|
|
|
|||
369
data/mods/gen6megasrevisited/abilities.ts
Normal file
369
data/mods/gen6megasrevisited/abilities.ts
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
|
||||
merciless: {
|
||||
shortDesc: "This Pokemon's attacks are critical hits if the target is statused.",
|
||||
onModifyCritRatio(critRatio, source, target) {
|
||||
if (target?.status) return 5;
|
||||
},
|
||||
name: "Merciless",
|
||||
rating: 1.5,
|
||||
num: 196,
|
||||
gen: 6,
|
||||
},
|
||||
pocketdimension: {
|
||||
shortDesc: "This Pokemon switches out after using a status move.",
|
||||
onModifyMove(move, pokemon) {
|
||||
if (move.category === 'Status') {
|
||||
move.selfSwitch = true;
|
||||
this.add('-ability', pokemon, 'Pocket Dimension');
|
||||
this.add('-message', `${pokemon.name} will switch out if this moves lands!`);
|
||||
}
|
||||
},
|
||||
name: "Pocket Dimension",
|
||||
rating: 4.5,
|
||||
},
|
||||
grassysurge: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
mistysurge: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
neutralizinggas: {
|
||||
inherit: true,
|
||||
// Ability suppression cancelled in scripts.ts
|
||||
// new Ability suppression implemented in scripts.ts
|
||||
onSwitchIn(pokemon) {},
|
||||
onEnd(source) {},
|
||||
onStart(pokemon) {
|
||||
this.add('-ability', pokemon, 'Neutralizing Gas');
|
||||
},
|
||||
// onModifyPriority implemented in relevant abilities
|
||||
onFoeBeforeMovePriority: 13,
|
||||
onFoeBeforeMove(attacker, defender, move) {
|
||||
attacker.addVolatile('neutralizinggas');
|
||||
},
|
||||
condition: {
|
||||
onAfterMove(pokemon) {
|
||||
pokemon.removeVolatile('neutralizinggas');
|
||||
},
|
||||
},
|
||||
flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
|
||||
desc: "While this Pokemon is active, opposing Pokemon's moves and their effects ignore its own Ability. Does not affect the As One, Battle Bond, Comatose, Disguise, Gulp Missile, Ice Face, Multitype, Power Construct, RKS System, Schooling, Shields Down, Stance Change, or Zen Mode Abilities.",
|
||||
shortDesc: "While this Pokemon is active, opposing Pokemon's Ability has no effect when it uses moves.",
|
||||
gen: 6,
|
||||
},
|
||||
nostalgiatrip: {
|
||||
shortDesc: "This Pokemon's moves have the damage categories they would have in Gen 3. Fairy-type moves are Special.",
|
||||
onStart(pokemon) {
|
||||
this.add('-ability', pokemon, 'Nostalgia Trip');
|
||||
this.add('-message', `This Pokemon is experiencing a nostalgia trip!`);
|
||||
},
|
||||
onModifyMovePriority: 8,
|
||||
onModifyMove(move, pokemon) {
|
||||
if (move.category === "Status") return;
|
||||
if (['Fire', 'Water', 'Grass', 'Electric', 'Dark', 'Psychic', 'Dragon', 'Fairy', 'Ice'].includes(move.type)) {
|
||||
move.category = "Special";
|
||||
} else {
|
||||
move.category = "Physical";
|
||||
}
|
||||
},
|
||||
name: "Nostalgia Trip",
|
||||
rating: 4,
|
||||
gen: 6,
|
||||
},
|
||||
weatherreport: {
|
||||
onBeforeMovePriority: 0.5,
|
||||
onBeforeMove(target, source, move) {
|
||||
if (move.type === 'Fire') {
|
||||
this.field.setWeather('sunnyday');
|
||||
} else if (move.type === 'Water') {
|
||||
this.field.setWeather('raindance');
|
||||
}
|
||||
},
|
||||
name: "Weather Report",
|
||||
shortDesc: "Before using a Water or Fire-type move, this Pokemon sets Rain Dance or Sunny Day respectively.",
|
||||
rating: 4,
|
||||
gen: 6,
|
||||
},
|
||||
armortail: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
brainpower: {
|
||||
onModifySpAPriority: 5,
|
||||
onModifySpA(spa) {
|
||||
return this.chainModify(2);
|
||||
},
|
||||
name: "Brain Power",
|
||||
shortDesc: "This Pokemon's Special Attack is doubled.",
|
||||
rating: 5,
|
||||
},
|
||||
neuroforce: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
bugzapper: {
|
||||
onTryHit(target, source, move) {
|
||||
if (target !== source && move.type === 'Bug') {
|
||||
if (!source.addVolatile('trapped', target, move, 'trapper')) {
|
||||
this.add('-immune', target, '[from] ability: Bug Zapper');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
name: "Bug Zapper",
|
||||
shortDesc: "This Pokemon is immune to Bug-type moves and traps the foe if hit by one.",
|
||||
rating: 5,
|
||||
},
|
||||
exoskeleton: {
|
||||
onSourceModifyDamage(damage, source, target, move) {
|
||||
if (move.category === 'Physical') {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
name: "Exoskeleton",
|
||||
shortDesc: "This Pokemon receives 1/2 damage from physical attacks; Hazard immunity.",
|
||||
rating: 4,
|
||||
},
|
||||
icescales: {
|
||||
inherit: true,
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, attacker, defender, move) {
|
||||
if (move.type === 'Ice') {
|
||||
this.debug('Ice Scales boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onModifySpAPriority: 5,
|
||||
onModifySpA(atk, attacker, defender, move) {
|
||||
if (move.type === 'Ice') {
|
||||
this.debug('Ice Scales boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onImmunity(type, pokemon) {
|
||||
if (type === 'hail') return false;
|
||||
},
|
||||
shortDesc: "This Pokemon receives 1/2 damage from special attacks. Ice moves have 1.5x power. Hail immunity.",
|
||||
gen: 6,
|
||||
},
|
||||
eartheater: {
|
||||
inherit: true,
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (effect && (effect.id === 'stealthrock' || effect.id === 'spikes')) {
|
||||
this.heal(damage);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
shortDesc: "Heals 1/4 of its max HP when hit by Ground; Ground immunity. Healed by Spikes and Stealth Rock.",
|
||||
gen: 6,
|
||||
},
|
||||
toxicchain: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
shellejection: {
|
||||
onModifyMovePriority: -1,
|
||||
onModifyMove(move, attacker) {
|
||||
if (move.category === 'Special') {
|
||||
attacker.addVolatile('shellejection');
|
||||
this.add('-ability', attacker, 'Shell Ejection');
|
||||
this.add('-message', `${attacker.name} is getting ready to leave the battlefield!`);
|
||||
this.add('-message', `${attacker.name} can no longer use status moves!`);
|
||||
}
|
||||
},
|
||||
condition: {
|
||||
duration: 2,
|
||||
onDisableMove(pokemon) {
|
||||
for (const moveSlot of pokemon.moveSlots) {
|
||||
const move = this.dex.moves.get(moveSlot.id);
|
||||
if (move.category === 'Status' && move.id !== 'mefirst') {
|
||||
pokemon.disableMove(moveSlot.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
onSwitchOut(pokemon) {
|
||||
pokemon.heal(pokemon.baseMaxhp / 3);
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
this.add('-ability', pokemon, 'Shell Ejection');
|
||||
this.add('-message', `${pokemon.name} ejected itself from its shell!`);
|
||||
pokemon.heal(pokemon.baseMaxhp / 3);
|
||||
pokemon.switchFlag = true;
|
||||
},
|
||||
},
|
||||
name: "Shell Ejection",
|
||||
rating: 3.5,
|
||||
gen: 6,
|
||||
shortDesc: "On using Special move: switching heals 1/3, can't use status, switches out at end of next turn.",
|
||||
},
|
||||
sharpness: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
dauntlessshield: {
|
||||
onStart(pokemon) {
|
||||
this.boost({ def: 1 }, pokemon);
|
||||
pokemon.addVolatile('dauntlessshield');
|
||||
},
|
||||
onResidualOrder: 6,
|
||||
onResidual(pokemon) {
|
||||
if (pokemon.positiveBoosts()) {
|
||||
this.heal(pokemon.baseMaxhp / 16);
|
||||
this.add('-message', `${pokemon.name}'s shield gives it strength!`);
|
||||
}
|
||||
},
|
||||
name: "Dauntless Shield",
|
||||
rating: 5,
|
||||
num: 235,
|
||||
shortDesc: "+1 Defense on switch-in. Heals 1/16 of max HP if it has a positive boost.",
|
||||
gen: 6,
|
||||
},
|
||||
confidence: {
|
||||
onSourceAfterFaint(length, target, source, effect) {
|
||||
if (effect && effect.effectType === 'Move') {
|
||||
this.boost({ spa: length }, source);
|
||||
}
|
||||
},
|
||||
name: "Confidence",
|
||||
rating: 3,
|
||||
shortDesc: "This Pokemon's Sp. Atk is raised by 1 stage if it attacks and KOes another Pokemon.",
|
||||
gen: 6,
|
||||
},
|
||||
electricsurge: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
goodasgold: {
|
||||
inherit: true,
|
||||
gen: 6,
|
||||
},
|
||||
opportunist: {
|
||||
inherit: true,
|
||||
onUpdate(pokemon) {
|
||||
let activate = false;
|
||||
const boosts: SparseBoostsTable = {};
|
||||
let i: BoostID;
|
||||
for (i in pokemon.boosts) {
|
||||
if (pokemon.boosts[i] < 0) {
|
||||
activate = true;
|
||||
boosts[i] = 0;
|
||||
}
|
||||
}
|
||||
if (this.effectState.herb) return;
|
||||
if (activate) {
|
||||
pokemon.setBoost(boosts);
|
||||
this.effectState.herb = true;
|
||||
this.add('-ability', pokemon, 'Opportunist');
|
||||
this.add('-clearnegativeboost', pokemon, '[silent]');
|
||||
}
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
delete this.effectState.herb;
|
||||
},
|
||||
shortDesc: "Copies foe's stat gains as they happen. Resets negative stat changes once per switch-in.",
|
||||
gen: 6,
|
||||
},
|
||||
intoxicate: {
|
||||
onModifyTypePriority: -1,
|
||||
onModifyType(move, pokemon) {
|
||||
const noModifyType = [
|
||||
'judgment', 'multiattack', 'naturalgift', 'revelationdance', 'technoblast', 'terrainpulse', 'weatherball',
|
||||
];
|
||||
if (move.type === 'Normal' && !noModifyType.includes(move.id) &&
|
||||
!(move.isZ && move.category !== 'Status') && !(move.name === 'Tera Blast' && pokemon.terastallized)) {
|
||||
move.type = 'Poison';
|
||||
move.typeChangerBoosted = this.effect;
|
||||
}
|
||||
},
|
||||
onBasePowerPriority: 23,
|
||||
onBasePower(basePower, pokemon, target, move) {
|
||||
if (move.typeChangerBoosted) return this.chainModify([5325, 4096]);
|
||||
},
|
||||
name: "Intoxicate",
|
||||
rating: 4,
|
||||
shortDesc: "This Pokemon's Normal-type moves become Poison-type and have 1.3x power.",
|
||||
},
|
||||
dragonsgale: {
|
||||
onStart(source) {
|
||||
this.field.setWeather('deltastream');
|
||||
},
|
||||
onAnySetWeather(target, source, weather) {
|
||||
const strongWeathers = ['desolateland', 'primordialsea', 'deltastream'];
|
||||
if (this.field.getWeather().id === 'deltastream' && !strongWeathers.includes(weather.id)) return false;
|
||||
},
|
||||
onEnd(pokemon) {
|
||||
if (this.field.weatherState.source !== pokemon) return;
|
||||
for (const target of this.getAllActive()) {
|
||||
if (target === pokemon) continue;
|
||||
if (target.hasAbility('dragonsgale')) {
|
||||
this.field.weatherState.source = target;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.field.clearWeather();
|
||||
},
|
||||
onDamage(damage, target, source, effect) {
|
||||
if (effect && (effect.id === 'stealthrock' || effect.id === 'spikes')) {
|
||||
return damage / 2;
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
name: "Dragon's Gale",
|
||||
shortDesc: "On switch-in, sets Delta Stream. User takes halved damage from hazards.",
|
||||
rating: 5,
|
||||
},
|
||||
parentalbond: {
|
||||
onPrepareHit(source, target, move) {
|
||||
if (move.category === 'Status' || move.selfdestruct || move.multihit) return;
|
||||
if ([
|
||||
'endeavor', 'seismictoss', 'psywave', 'nightshade', 'sonicboom', 'dragonrage',
|
||||
'superfang', 'naturesmadness', 'bide', 'counter', 'mirrorcoat', 'metalburst',
|
||||
].includes(move.id)) return;
|
||||
if (!move.spreadHit && !move.isZ && !move.isMax) {
|
||||
move.multihit = 2;
|
||||
move.multihitType = 'parentalbond';
|
||||
}
|
||||
},
|
||||
onSourceModifySecondaries(secondaries, target, source, move) {
|
||||
if (move.multihitType === 'parentalbond' && move.id === 'secretpower' && move.hit < 2) {
|
||||
// hack to prevent accidentally suppressing King's Rock/Razor Fang
|
||||
return secondaries.filter(effect => effect.volatileStatus === 'flinch');
|
||||
}
|
||||
},
|
||||
name: "Parental Bond",
|
||||
rating: 4.5,
|
||||
shortDesc: "This Pokemon's damaging moves hit twice. The second hit has its damage quartered.",
|
||||
num: 184,
|
||||
},
|
||||
|
||||
// for ngas
|
||||
galewings: {
|
||||
// for ngas
|
||||
inherit: true,
|
||||
onModifyPriority(priority, pokemon, target, move) {
|
||||
for (const poke of this.getAllActive()) {
|
||||
if (poke.hasAbility('neutralizinggas') && poke.side.id !== pokemon.side.id && !poke.abilityState.ending) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (move && move.type === 'Flying') return priority + 1;
|
||||
},
|
||||
},
|
||||
prankster: {
|
||||
// for ngas
|
||||
inherit: true,
|
||||
onModifyPriority(priority, pokemon, target, move) {
|
||||
for (const poke of this.getAllActive()) {
|
||||
if (poke.hasAbility('neutralizinggas') && poke.side.id !== pokemon.side.id && !poke.abilityState.ending) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (move?.category === 'Status') {
|
||||
move.pranksterBoosted = true;
|
||||
return priority + 1;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
26
data/mods/gen6megasrevisited/formats-data.ts
Normal file
26
data/mods/gen6megasrevisited/formats-data.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormatsDataTable = {
|
||||
blaziken: {
|
||||
tier: "OU",
|
||||
},
|
||||
blazikenmega: {
|
||||
tier: "OU",
|
||||
},
|
||||
gengarmega: {
|
||||
tier: "OU",
|
||||
},
|
||||
kangaskhanmega: {
|
||||
tier: "OU",
|
||||
},
|
||||
lucariomega: {
|
||||
tier: "OU",
|
||||
},
|
||||
mawilemega: {
|
||||
tier: "OU",
|
||||
},
|
||||
sableyemega: {
|
||||
tier: "OU",
|
||||
},
|
||||
salamencemega: {
|
||||
tier: "OU",
|
||||
},
|
||||
};
|
||||
12
data/mods/gen6megasrevisited/items.ts
Normal file
12
data/mods/gen6megasrevisited/items.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
||||
meteorite: {
|
||||
name: "Meteorite",
|
||||
spritenum: 615,
|
||||
megaStone: { "Rayquaza": "Rayquaza-Mega" },
|
||||
itemUser: ["Rayquaza"],
|
||||
onTakeItem(item, source) {
|
||||
return !item.megaStone?.[source.baseSpecies.baseSpecies];
|
||||
},
|
||||
desc: "If held by a Rayquaza, this item allows it to Mega Evolve in battle.",
|
||||
},
|
||||
};
|
||||
77
data/mods/gen6megasrevisited/moves.ts
Normal file
77
data/mods/gen6megasrevisited/moves.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||
stealthrock: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Stealth Rock');
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) return;
|
||||
const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6);
|
||||
this.damage(pokemon.maxhp * (2 ** typeMod) / 8);
|
||||
},
|
||||
},
|
||||
},
|
||||
toxicspikes: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Toxic Spikes');
|
||||
this.effectState.layers = 1;
|
||||
},
|
||||
onSideRestart(side) {
|
||||
if (this.effectState.layers >= 2) return false;
|
||||
this.add('-sidestart', side, 'move: Toxic Spikes');
|
||||
this.effectState.layers++;
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded()) return;
|
||||
if (pokemon.hasType('Poison')) {
|
||||
this.add('-sideend', pokemon.side, 'move: Toxic Spikes', `[of] ${pokemon}`);
|
||||
pokemon.side.removeSideCondition('toxicspikes');
|
||||
} else if (pokemon.hasType('Steel') || pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) {
|
||||
// do nothing
|
||||
} else if (this.effectState.layers >= 2) {
|
||||
pokemon.trySetStatus('tox', pokemon.side.foe.active[0]);
|
||||
} else {
|
||||
pokemon.trySetStatus('psn', pokemon.side.foe.active[0]);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
spikes: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
// this is a side condition
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'Spikes');
|
||||
this.effectState.layers = 1;
|
||||
},
|
||||
onSideRestart(side) {
|
||||
if (this.effectState.layers >= 3) return false;
|
||||
this.add('-sidestart', side, 'Spikes');
|
||||
this.effectState.layers++;
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) return;
|
||||
const damageAmounts = [0, 3, 4, 6]; // 1/8, 1/6, 1/4
|
||||
this.damage(damageAmounts[this.effectState.layers] * pokemon.maxhp / 24);
|
||||
},
|
||||
},
|
||||
},
|
||||
stickyweb: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
onSideStart(side) {
|
||||
this.add('-sidestart', side, 'move: Sticky Web');
|
||||
},
|
||||
onSwitchIn(pokemon) {
|
||||
if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('exoskeleton')) return;
|
||||
this.add('-activate', pokemon, 'move: Sticky Web');
|
||||
this.boost({ spe: -1 }, pokemon, pokemon.side.foe.active[0], this.dex.getActiveMove('stickyweb'));
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
249
data/mods/gen6megasrevisited/pokedex.ts
Normal file
249
data/mods/gen6megasrevisited/pokedex.ts
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
|
||||
audinomega: {
|
||||
inherit: true,
|
||||
types: ["Normal", "Electric"],
|
||||
baseStats: { hp: 103, atk: 60, def: 120, spa: 110, spd: 97, spe: 55 },
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
houndoommega: {
|
||||
inherit: true,
|
||||
types: ["Dark", "Fire"],
|
||||
baseStats: { hp: 75, atk: 90, def: 90, spa: 140, spd: 90, spe: 115 },
|
||||
abilities: { 0: "Merciless" },
|
||||
},
|
||||
lucariomega: {
|
||||
inherit: true,
|
||||
types: ["Fighting", "Steel"],
|
||||
baseStats: { hp: 70, atk: 125, def: 70, spa: 140, spd: 94, spe: 126 },
|
||||
abilities: { 0: "Lightning Rod" },
|
||||
},
|
||||
banettemega: {
|
||||
inherit: true,
|
||||
types: ["Ghost", "Steel"],
|
||||
baseStats: { hp: 64, atk: 149, def: 75, spa: 83, spd: 83, spe: 101 },
|
||||
abilities: { 0: "Pocket Dimension" },
|
||||
},
|
||||
glaliemega: {
|
||||
inherit: true,
|
||||
types: ["Ice", "Steel"],
|
||||
baseStats: { hp: 80, atk: 160, def: 70, spa: 95, spd: 70, spe: 105 },
|
||||
abilities: { 0: "Refrigerate" },
|
||||
},
|
||||
venusaurmega: {
|
||||
inherit: true,
|
||||
types: ["Grass", "Poison"],
|
||||
baseStats: { hp: 80, atk: 82, def: 123, spa: 120, spd: 120, spe: 100 },
|
||||
abilities: { 0: "Grassy Surge" },
|
||||
},
|
||||
blastoisemega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Fairy"],
|
||||
baseStats: { hp: 79, atk: 83, def: 130, spa: 135, spd: 105, spe: 98 },
|
||||
abilities: { 0: "Misty Surge" },
|
||||
},
|
||||
charizardmegay: {
|
||||
inherit: true,
|
||||
types: ["Fire", "Flying"],
|
||||
baseStats: { hp: 78, atk: 94, def: 93, spa: 159, spd: 110, spe: 100 },
|
||||
abilities: { 0: "Dragon's Gale" },
|
||||
},
|
||||
alakazammega: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Ice"],
|
||||
baseStats: { hp: 55, atk: 50, def: 75, spa: 155, spd: 125, spe: 140 },
|
||||
abilities: { 0: "Magic Guard" },
|
||||
},
|
||||
pinsirmega: {
|
||||
inherit: true,
|
||||
types: ["Bug", "Ice"],
|
||||
baseStats: { hp: 65, atk: 150, def: 110, spa: 80, spd: 85, spe: 110 },
|
||||
abilities: { 0: "Mountaineer" },
|
||||
},
|
||||
gengarmega: {
|
||||
inherit: true,
|
||||
types: ["Ghost", "Poison"],
|
||||
baseStats: { hp: 60, atk: 65, def: 105, spa: 155, spd: 105, spe: 110 },
|
||||
abilities: { 0: "Neutralizing Gas" },
|
||||
},
|
||||
aerodactylmega: {
|
||||
inherit: true,
|
||||
types: ["Rock", "Flying"],
|
||||
baseStats: { hp: 80, atk: 140, def: 65, spa: 85, spd: 100, spe: 145 },
|
||||
abilities: { 0: "Nostalgia Trip" },
|
||||
},
|
||||
steelixmega: {
|
||||
inherit: true,
|
||||
types: ["Steel", "Ground"],
|
||||
baseStats: { hp: 75, atk: 135, def: 210, spa: 55, spd: 105, spe: 30 },
|
||||
abilities: { 0: "Flash Fire" },
|
||||
weightkg: 999.9,
|
||||
},
|
||||
altariamega: {
|
||||
inherit: true,
|
||||
types: ["Dragon", "Fairy"],
|
||||
baseStats: { hp: 75, atk: 90, def: 90, spa: 140, spd: 115, spe: 80 },
|
||||
abilities: { 0: "Weather Report" },
|
||||
},
|
||||
sceptilemega: {
|
||||
inherit: true,
|
||||
types: ["Grass", "Dragon"],
|
||||
baseStats: { hp: 70, atk: 95, def: 79, spa: 145, spd: 99, spe: 142 },
|
||||
abilities: { 0: "Armor Tail" },
|
||||
},
|
||||
swampertmega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Poison"],
|
||||
baseStats: { hp: 100, atk: 145, def: 110, spa: 85, spd: 110, spe: 85 },
|
||||
abilities: { 0: "Toxic Chain" },
|
||||
},
|
||||
manectricmega: {
|
||||
inherit: true,
|
||||
types: ["Electric"],
|
||||
baseStats: { hp: 70, atk: 75, def: 80, spa: 135, spd: 85, spe: 130 },
|
||||
abilities: { 0: "Bug Zapper" },
|
||||
},
|
||||
absolmega: {
|
||||
inherit: true,
|
||||
types: ["Dark", "Fairy"],
|
||||
baseStats: { hp: 65, atk: 130, def: 60, spa: 135, spd: 60, spe: 115 },
|
||||
abilities: { 0: "Neuroforce" },
|
||||
},
|
||||
medichammega: {
|
||||
inherit: true,
|
||||
types: ["Fighting", "Psychic"],
|
||||
baseStats: { hp: 60, atk: 60, def: 100, spa: 90, spd: 100, spe: 100 },
|
||||
abilities: { 0: "Brain Power" },
|
||||
},
|
||||
sableyemega: {
|
||||
inherit: true,
|
||||
types: ["Dark", "Ghost"],
|
||||
baseStats: { hp: 50, atk: 95, def: 115, spa: 85, spd: 115, spe: 20 },
|
||||
},
|
||||
beedrillmega: {
|
||||
inherit: true,
|
||||
types: ["Bug", "Rock"],
|
||||
baseStats: { hp: 65, atk: 140, def: 85, spa: 45, spd: 85, spe: 75 },
|
||||
abilities: { 0: "Exoskeleton" },
|
||||
},
|
||||
mawilemega: {
|
||||
inherit: true,
|
||||
types: ["Steel", "Fairy"],
|
||||
baseStats: { hp: 50, atk: 90, def: 125, spa: 70, spd: 95, spe: 50 },
|
||||
abilities: { 0: "Huge Power" },
|
||||
},
|
||||
abomasnowmega: {
|
||||
inherit: true,
|
||||
types: ["Grass"],
|
||||
abilities: { 0: "Ice Scales" },
|
||||
},
|
||||
cameruptmega: {
|
||||
inherit: true,
|
||||
types: ["Fire", "Ground"],
|
||||
baseStats: { hp: 70, atk: 80, def: 140, spa: 135, spd: 115, spe: 20 },
|
||||
abilities: { 0: "Earth Eater" },
|
||||
},
|
||||
slowbromega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Psychic"],
|
||||
baseStats: { hp: 95, atk: 75, def: 150, spa: 120, spd: 120, spe: 30 },
|
||||
abilities: { 0: "Shell Ejection" },
|
||||
},
|
||||
gallademega: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Fighting"],
|
||||
baseStats: { hp: 68, atk: 150, def: 100, spa: 75, spd: 127, spe: 98 },
|
||||
abilities: { 0: "Sharpness" },
|
||||
},
|
||||
ampharosmega: {
|
||||
inherit: true,
|
||||
types: ["Electric", "Dragon"],
|
||||
baseStats: { hp: 90, atk: 95, def: 95, spa: 165, spd: 110, spe: 55 },
|
||||
abilities: { 0: "Mega Launcher" },
|
||||
},
|
||||
gyaradosmega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Flying"],
|
||||
baseStats: { hp: 95, atk: 130, def: 109, spa: 85, spd: 130, spe: 91 },
|
||||
abilities: { 0: "Aerilate" },
|
||||
},
|
||||
heracrossmega: {
|
||||
inherit: true,
|
||||
types: ["Bug", "Fighting"],
|
||||
baseStats: { hp: 80, atk: 150, def: 150, spa: 40, spd: 110, spe: 70 },
|
||||
abilities: { 0: "Iron Barbs" },
|
||||
},
|
||||
sharpedomega: {
|
||||
inherit: true,
|
||||
types: ["Water", "Electric"],
|
||||
baseStats: { hp: 70, atk: 130, def: 55, spa: 145, spd: 55, spe: 105 },
|
||||
abilities: { 0: "No Guard" },
|
||||
},
|
||||
gardevoirmega: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Fairy"],
|
||||
baseStats: { hp: 68, atk: 65, def: 100, spa: 150, spd: 127, spe: 108 },
|
||||
},
|
||||
aggronmega: {
|
||||
inherit: true,
|
||||
types: ["Steel"],
|
||||
baseStats: { hp: 70, atk: 145, def: 185, spa: 85, spd: 85, spe: 60 },
|
||||
abilities: { 0: "Dauntless Shield" },
|
||||
},
|
||||
kangaskhanmega: {
|
||||
inherit: true,
|
||||
types: ["Normal", "Ground"],
|
||||
baseStats: { hp: 105, atk: 125, def: 105, spa: 50, spd: 105, spe: 100 },
|
||||
},
|
||||
salamencemega: {
|
||||
inherit: true,
|
||||
types: ["Dragon", "Flying"],
|
||||
baseStats: { hp: 95, atk: 135, def: 105, spa: 155, spd: 105, spe: 105 },
|
||||
abilities: { 0: "Confidence" },
|
||||
},
|
||||
garchompmega: {
|
||||
inherit: true,
|
||||
types: ["Dragon", "Ground"],
|
||||
baseStats: { hp: 108, atk: 150, def: 115, spa: 140, spd: 85, spe: 102 },
|
||||
abilities: { 0: "Water Absorb" },
|
||||
},
|
||||
tyranitarmega: {
|
||||
inherit: true,
|
||||
types: ["Rock", "Electric"],
|
||||
baseStats: { hp: 100, atk: 144, def: 120, spa: 110, spd: 144, spe: 82 },
|
||||
abilities: { 0: "Electric Surge" },
|
||||
},
|
||||
latiasmega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Trace" },
|
||||
},
|
||||
latiosmega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 80, atk: 140, def: 100, spa: 150, spd: 120, spe: 110 },
|
||||
abilities: { 0: "Opportunist" },
|
||||
},
|
||||
dianciemega: {
|
||||
inherit: true,
|
||||
abilities: { 0: "Good As Gold" },
|
||||
},
|
||||
blazikenmega: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 80, atk: 150, def: 80, spa: 120, spd: 90, spe: 110 },
|
||||
abilities: { 0: "Regenerator" },
|
||||
},
|
||||
mewtwomegax: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Poison"],
|
||||
baseStats: { hp: 106, atk: 140, def: 130, spa: 154, spd: 120, spe: 130 },
|
||||
abilities: { 0: "Intoxicate" },
|
||||
},
|
||||
mewtwomegay: {
|
||||
inherit: true,
|
||||
types: ["Psychic", "Water"],
|
||||
baseStats: { hp: 106, atk: 120, def: 110, spa: 194, spd: 130, spe: 120 },
|
||||
abilities: { 0: "Levitate" },
|
||||
},
|
||||
rayquazamega: {
|
||||
inherit: true,
|
||||
requiredItem: "Meteorite",
|
||||
},
|
||||
};
|
||||
33
data/mods/gen6megasrevisited/rulesets.ts
Normal file
33
data/mods/gen6megasrevisited/rulesets.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
megadatamod: {
|
||||
effectType: 'Rule',
|
||||
name: 'Mega Data Mod',
|
||||
desc: 'Gives data on stats, Ability and types when a Pokémon Mega Evolves or undergoes Ultra Burst.',
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.species.forme.startsWith('Mega') || pokemon.species.forme.startsWith('Ultra')) {
|
||||
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
|
||||
}
|
||||
},
|
||||
onAfterMega(pokemon) {
|
||||
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
|
||||
const species = pokemon.species;
|
||||
let buf = `<span class="col pokemonnamecol" style="white-space: nowrap">${species.name}</span> `;
|
||||
buf += `<span class="col typecol">`;
|
||||
buf += `<img src="https://${Config.routes.client}/sprites/types/${species.types[0]}.png" alt="${species.types[0]}" height="14" width="32">`;
|
||||
if (species.types[1]) {
|
||||
buf += `<img src="https://${Config.routes.client}/sprites/types/${species.types[1]}.png" alt="${species.types[1]}" height="14" width="32">`;
|
||||
}
|
||||
buf += `</span> `;
|
||||
buf += `<span style="float: left ; min-height: 26px"><span class="col abilitycol">${species.abilities[0]}</span><span class="col abilitycol"></span></span>`;
|
||||
const stats = [];
|
||||
let stat: StatID;
|
||||
for (stat in species.baseStats) {
|
||||
const statNames: { [k in StatID]: string } = { hp: "HP", atk: "Atk", def: "Def", spa: "SpA", spd: "SpD", spe: "Spe" };
|
||||
stats.push(`<span class="col statcol"><em>${statNames[stat]}</em><br>${species.baseStats[stat]}</span>`);
|
||||
}
|
||||
buf += `<span style="float: left ; min-height: 26px">${stats.join(' ')}</span>`;
|
||||
buf += `</span>`;
|
||||
this.add(`raw|<ul class="utilichart"><li class="result">${buf}</li><li style="clear: both"></li></ul>`);
|
||||
},
|
||||
},
|
||||
};
|
||||
237
data/mods/gen6megasrevisited/scripts.ts
Normal file
237
data/mods/gen6megasrevisited/scripts.ts
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
gen: 6,
|
||||
inherit: 'gen6',
|
||||
actions: {
|
||||
// for parental bond
|
||||
modifyDamage(
|
||||
baseDamage: number, pokemon: Pokemon, target: Pokemon, move: ActiveMove, suppressMessages = false
|
||||
) {
|
||||
const tr = this.battle.trunc;
|
||||
if (!move.type) move.type = '???';
|
||||
const type = move.type;
|
||||
baseDamage += 2;
|
||||
if (move.spreadHit) {
|
||||
// multi-target modifier (doubles only)
|
||||
const spreadModifier = this.battle.gameType === 'freeforall' ? 0.5 : 0.75;
|
||||
this.battle.debug(`Spread modifier: ${spreadModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, spreadModifier);
|
||||
} else if (move.multihitType === 'parentalbond' && move.hit > 1) {
|
||||
// Parental Bond modifier
|
||||
const bondModifier = 0.25;
|
||||
this.battle.debug(`Parental Bond modifier: ${bondModifier}`);
|
||||
baseDamage = this.battle.modify(baseDamage, bondModifier);
|
||||
}
|
||||
baseDamage = this.battle.runEvent('WeatherModifyDamage', pokemon, target, move, baseDamage);
|
||||
const isCrit = target.getMoveHitData(move).crit;
|
||||
if (isCrit) {
|
||||
baseDamage = tr(baseDamage * (move.critModifier || (this.battle.gen >= 6 ? 1.5 : 2)));
|
||||
}
|
||||
baseDamage = this.battle.randomizer(baseDamage);
|
||||
if (type !== '???') {
|
||||
let stab: number | [number, number] = 1;
|
||||
const isSTAB = move.forceSTAB || pokemon.hasType(type) || pokemon.getTypes(false, true).includes(type);
|
||||
if (isSTAB) {
|
||||
stab = 1.5;
|
||||
}
|
||||
if (pokemon.terastallized === 'Stellar') {
|
||||
if (!pokemon.stellarBoostedTypes.includes(type) || move.stellarBoosted) {
|
||||
stab = isSTAB ? 2 : [4915, 4096];
|
||||
move.stellarBoosted = true;
|
||||
if (pokemon.species.name !== 'Terapagos-Stellar') {
|
||||
pokemon.stellarBoostedTypes.push(type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pokemon.terastallized === type && pokemon.getTypes(false, true).includes(type)) {
|
||||
stab = 2;
|
||||
}
|
||||
stab = this.battle.runEvent('ModifySTAB', pokemon, target, move, stab);
|
||||
}
|
||||
baseDamage = this.battle.modify(baseDamage, stab);
|
||||
}
|
||||
let typeMod = target.runEffectiveness(move);
|
||||
typeMod = this.battle.clampIntRange(typeMod, -6, 6);
|
||||
target.getMoveHitData(move).typeMod = typeMod;
|
||||
if (typeMod > 0) {
|
||||
if (!suppressMessages) this.battle.add('-supereffective', target);
|
||||
for (let i = 0; i < typeMod; i++) {
|
||||
baseDamage *= 2;
|
||||
}
|
||||
}
|
||||
if (typeMod < 0) {
|
||||
if (!suppressMessages) this.battle.add('-resisted', target);
|
||||
|
||||
for (let i = 0; i > typeMod; i--) {
|
||||
baseDamage = tr(baseDamage / 2);
|
||||
}
|
||||
}
|
||||
if (isCrit && !suppressMessages) this.battle.add('-crit', target);
|
||||
if (pokemon.status === 'brn' && move.category === 'Physical' && !pokemon.hasAbility('guts')) {
|
||||
if (this.battle.gen < 6 || move.id !== 'facade') {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.5);
|
||||
}
|
||||
}
|
||||
// Generation 5, but nothing later, sets damage to 1 before the final damage modifiers
|
||||
if (this.battle.gen === 5 && !baseDamage) baseDamage = 1;
|
||||
// Final modifier. Modifiers that modify damage after min damage check, such as Life Orb.
|
||||
baseDamage = this.battle.runEvent('ModifyDamage', pokemon, target, move, baseDamage);
|
||||
if (move.isZOrMaxPowered && target.getMoveHitData(move).zBrokeProtect) {
|
||||
baseDamage = this.battle.modify(baseDamage, 0.25);
|
||||
this.battle.add('-zbroken', target);
|
||||
}
|
||||
// Generation 6-7 moves the check for minimum 1 damage after the final modifier...
|
||||
if (this.battle.gen !== 5 && !baseDamage) return 1;
|
||||
// ...but 16-bit truncation happens even later, and can truncate to 0
|
||||
return tr(baseDamage, 16);
|
||||
},
|
||||
},
|
||||
pokemon: {
|
||||
// for neutralizing gas
|
||||
ignoringAbility() {
|
||||
if (this.battle.gen >= 5 && !this.isActive) return true;
|
||||
if (this.getAbility().flags['notransform'] && this.transformed) return true;
|
||||
if (this.getAbility().flags['cantsuppress']) return false;
|
||||
if (this.volatiles['gastroacid']) return true;
|
||||
if (this.ability === ('neutralizinggas' as ID)) return false;
|
||||
if (this.volatiles['neutralizinggas']) return true;
|
||||
return false;
|
||||
},
|
||||
},
|
||||
init() {
|
||||
this.modData("Learnsets", "lucario").learnset.meteormash = ["6L1"];
|
||||
this.modData("Learnsets", "lucario").learnset.machpunch = ["6L1"];
|
||||
this.modData("Learnsets", "houndoom").learnset.toxicspikes = ["6L1"];
|
||||
this.modData("Learnsets", "houndoom").learnset.venoshock = ["6L1"];
|
||||
this.modData("Learnsets", "houndoom").learnset.hex = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.discharge = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.voltswitch = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.chargebeam = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.charge = ["6L1"];
|
||||
this.modData("Learnsets", "audino").learnset.zapcannon = ["6L1"];
|
||||
this.modData("Learnsets", "glalie").learnset.thunderfang = ["6L1"];
|
||||
this.modData("Learnsets", "glalie").learnset.partingshot = ["6L1"];
|
||||
this.modData("Learnsets", "glalie").learnset.boomburst = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.ironhead = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.metalsound = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.powder = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.stealthrock = ["6L1"];
|
||||
this.modData("Learnsets", "banette").learnset.defog = ["6L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.psychic = ["6L1"];
|
||||
this.modData("Learnsets", "venusaur").learnset.calmmind = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.moonblast = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.mistyterrain = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.taunt = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.drainingkiss = ["6L1"];
|
||||
this.modData("Learnsets", "blastoise").learnset.dazzlinggleam = ["6L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.calmmind = ["6L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.hurricane = ["6L1"];
|
||||
this.modData("Learnsets", "charizard").learnset.lavaplume = ["6L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.reflecttype = ["6L1"];
|
||||
this.modData("Learnsets", "gengar").learnset.calmmind = ["6L1"];
|
||||
this.modData("Learnsets", "alakazam").learnset.blizzard = ["6L1"];
|
||||
this.modData("Learnsets", "alakazam").learnset.flashcannon = ["6L1"];
|
||||
this.modData("Learnsets", "alakazam").learnset.icebeam = ["6L1"];
|
||||
this.modData("Learnsets", "alakazam").learnset.hail = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.hail = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.megahorn = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.uturn = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.iceshard = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.iciclecrash = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.icebeam = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.blizzard = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.roost = ["6L1"];
|
||||
this.modData("Learnsets", "pinsir").learnset.iciclespear = ["6L1"];
|
||||
this.modData("Learnsets", "aerodactyl").learnset.powergem = ["6L1"];
|
||||
this.modData("Learnsets", "aerodactyl").learnset.shadowball = ["6L1"];
|
||||
this.modData("Learnsets", "aerodactyl").learnset.hurricane = ["6L1"];
|
||||
this.modData("Learnsets", "steelix").learnset.heatcrash = ["6L1"];
|
||||
this.modData("Learnsets", "steelix").learnset.rapidspin = ["6L1"];
|
||||
this.modData("Learnsets", "steelix").learnset.smackdown = ["6L1"];
|
||||
this.modData("Learnsets", "altaria").learnset.scald = ["6L1"];
|
||||
this.modData("Learnsets", "altaria").learnset.hydropump = ["6L1"];
|
||||
this.modData("Learnsets", "altaria").learnset.thunder = ["6L1"];
|
||||
this.modData("Learnsets", "sceptile").learnset.calmmind = ["6L1"];
|
||||
this.modData("Learnsets", "sceptile").learnset.sludgewave = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.sludgebomb = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.bulkup = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.toxicspikes = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.aquajet = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.gunkshot = ["6L1"];
|
||||
this.modData("Learnsets", "swampert").learnset.poisonjab = ["6L1"];
|
||||
this.modData("Learnsets", "pidgeot").learnset.focusblast = ["6L1"];
|
||||
this.modData("Learnsets", "absol").learnset.closecombat = ["6L1"];
|
||||
this.modData("Learnsets", "absol").learnset.moonblast = ["6L1"];
|
||||
this.modData("Learnsets", "absol").learnset.moonlight = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.aurasphere = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.thunderbolt = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.closecombat = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.gunkshot = ["6L1"];
|
||||
this.modData("Learnsets", "medicham").learnset.healingwish = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.earthquake = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.stoneedge = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.rockslide = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.smackdown = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.stealthrock = ["6L1"];
|
||||
this.modData("Learnsets", "beedrill").learnset.diamondstorm = ["6L1"];
|
||||
this.modData("Learnsets", "mawile").learnset.firepunch = ["6L1"];
|
||||
this.modData("Learnsets", "mawile").learnset.rockslide = ["6L1"];
|
||||
this.modData("Learnsets", "mawile").learnset.slackoff = ["6L1"];
|
||||
this.modData("Learnsets", "camerupt").learnset.morningsun = ["6L1"];
|
||||
this.modData("Learnsets", "abomasnow").learnset.spikyshield = ["6L1"];
|
||||
this.modData("Learnsets", "abomasnow").learnset.earthpower = ["6L1"];
|
||||
this.modData("Learnsets", "abomasnow").learnset.hornleech = ["6L1"];
|
||||
this.modData("Learnsets", "gallade").learnset.sacredsword = ["6L1"];
|
||||
this.modData("Learnsets", "gallade").learnset.machpunch = ["6L1"];
|
||||
this.modData('Moves', 'aerialace').flags.slicing = 1;
|
||||
this.modData('Moves', 'aircutter').flags.slicing = 1;
|
||||
this.modData('Moves', 'airslash').flags.slicing = 1;
|
||||
this.modData('Moves', 'behemothblade').flags.slicing = 1;
|
||||
this.modData('Moves', 'crosspoison').flags.slicing = 1;
|
||||
this.modData('Moves', 'cut').flags.slicing = 1;
|
||||
this.modData('Moves', 'furycutter').flags.slicing = 1;
|
||||
this.modData('Moves', 'nightslash').flags.slicing = 1;
|
||||
this.modData('Moves', 'psychocut').flags.slicing = 1;
|
||||
this.modData('Moves', 'razorleaf').flags.slicing = 1;
|
||||
this.modData('Moves', 'razorshell').flags.slicing = 1;
|
||||
this.modData('Moves', 'sacredsword').flags.slicing = 1;
|
||||
this.modData('Moves', 'slash').flags.slicing = 1;
|
||||
this.modData('Moves', 'solarblade').flags.slicing = 1;
|
||||
this.modData('Moves', 'xscissor').flags.slicing = 1;
|
||||
this.modData("Learnsets", "ampharos").learnset.waterpulse = ["6L1"];
|
||||
this.modData("Learnsets", "ampharos").learnset.aurasphere = ["6L1"];
|
||||
this.modData("Learnsets", "ampharos").learnset.darkpulse = ["6L1"];
|
||||
this.modData("Learnsets", "ampharos").learnset.defog = ["6L1"];
|
||||
this.modData("Learnsets", "ampharos").learnset.slackoff = ["6L1"];
|
||||
this.modData("Learnsets", "heracross").learnset.healorder = ["6L1"];
|
||||
this.modData("Learnsets", "heracross").learnset.circlethrow = ["6L1"];
|
||||
this.modData("Learnsets", "heracross").learnset.spikes = ["6L1"];
|
||||
this.modData("Learnsets", "heracross").learnset.icepunch = ["6L1"];
|
||||
this.modData("Learnsets", "sharpedo").learnset.thunder = ["6L1"];
|
||||
this.modData("Learnsets", "gardevoir").learnset.rapidspin = ["6L1"];
|
||||
this.modData("Learnsets", "gardevoir").learnset.mysticalfire = ["6L1"];
|
||||
this.modData("Learnsets", "aggron").learnset.voltswitch = ["6L1"];
|
||||
this.modData("Learnsets", "kangaskhan").learnset.milkdrink = ["6L1"];
|
||||
this.modData("Learnsets", "salamence").learnset.hurricane = ["6L1"];
|
||||
this.modData("Learnsets", "salamence").learnset.airslash = ["6L1"];
|
||||
this.modData("Learnsets", "salamence").learnset.ironhead = ["6L1"];
|
||||
this.modData("Learnsets", "tyranitar").learnset.wildcharge = ["6L1"];
|
||||
this.modData("Learnsets", "tyranitar").learnset.waterfall = ["6L1"];
|
||||
this.modData("Learnsets", "diancie").learnset.spikyshield = ["6L1"];
|
||||
this.modData("Learnsets", "blaziken").learnset.uturn = ["6L1"];
|
||||
this.modData("Learnsets", "blaziken").learnset.spikes = ["6L1"];
|
||||
this.modData("Learnsets", "blaziken").learnset.roost = ["6L1"];
|
||||
this.modData("Learnsets", "blaziken").learnset.closecombat = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.extremespeed = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.sludgewave = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.swordsdance = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.uturn = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.closecombat = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.drainpunch = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.machpunch = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.scald = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.surf = ["6L1"];
|
||||
this.modData("Learnsets", "mewtwo").learnset.hydropump = ["6L1"];
|
||||
this.modData("Learnsets", "rayquaza").learnset.coil = ["6L1"];
|
||||
this.modData("Learnsets", "rayquaza").learnset.defog = ["6L1"];
|
||||
},
|
||||
};
|
||||
46
data/mods/gen6mixandmega/items.ts
Normal file
46
data/mods/gen6mixandmega/items.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
|
||||
blueorb: {
|
||||
inherit: true,
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) {
|
||||
// @ts-expect-error modded
|
||||
const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Kyogre-Primal', pokemon);
|
||||
if (pokemon.m.originalSpecies === 'Kyogre') {
|
||||
pokemon.formeChange(species, this.effect, true);
|
||||
} else {
|
||||
pokemon.formeChange(species, this.effect, true);
|
||||
pokemon.baseSpecies = species;
|
||||
this.add('-start', pokemon, 'Blue Orb', '[silent]');
|
||||
}
|
||||
}
|
||||
},
|
||||
onTakeItem: false,
|
||||
},
|
||||
redorb: {
|
||||
inherit: true,
|
||||
onSwitchIn(pokemon) {
|
||||
if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) {
|
||||
// @ts-expect-error modded
|
||||
const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Groudon-Primal', pokemon);
|
||||
if (pokemon.m.originalSpecies === 'Groudon') {
|
||||
pokemon.formeChange(species, this.effect, true);
|
||||
} else {
|
||||
pokemon.formeChange(species, this.effect, true);
|
||||
pokemon.baseSpecies = species;
|
||||
this.add('-start', pokemon, 'Red Orb', '[silent]');
|
||||
const apparentSpecies = pokemon.illusion ? pokemon.illusion.species.name : pokemon.m.originalSpecies;
|
||||
const oSpecies = this.dex.species.get(apparentSpecies);
|
||||
if (pokemon.illusion) {
|
||||
const types = oSpecies.types;
|
||||
if (types.length > 1 || types[types.length - 1] !== 'Fire') {
|
||||
this.add('-start', pokemon, 'typechange', (types[0] !== 'Fire' ? types[0] + '/' : '') + 'Fire', '[silent]');
|
||||
}
|
||||
} else if (oSpecies.types.length !== pokemon.species.types.length || oSpecies.types[1] !== pokemon.species.types[1]) {
|
||||
this.add('-start', pokemon, 'typechange', pokemon.species.types.join('/'), '[silent]');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onTakeItem: false,
|
||||
},
|
||||
};
|
||||
117
data/mods/gen6mixandmega/scripts.ts
Normal file
117
data/mods/gen6mixandmega/scripts.ts
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
export const Scripts: ModdedBattleScriptsData = {
|
||||
gen: 6,
|
||||
inherit: 'gen6',
|
||||
init() {
|
||||
for (const i in this.data.Items) {
|
||||
if (!this.data.Items[i].megaStone) continue;
|
||||
this.modData('Items', i).onTakeItem = false;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
canMegaEvo(pokemon) {
|
||||
if (pokemon.species.isMega || pokemon.species.isPrimal) return null;
|
||||
|
||||
const item = pokemon.getItem();
|
||||
if (item.megaStone) {
|
||||
const values = Object.values(item.megaStone);
|
||||
if (values.includes(pokemon.name)) return null;
|
||||
return values[0];
|
||||
} else if (pokemon.baseMoves.includes('dragonascent')) {
|
||||
return 'Rayquaza-Mega';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
runMegaEvo(pokemon) {
|
||||
if (pokemon.species.isMega || pokemon.species.isPrimal) return false;
|
||||
|
||||
const species: Species = (this as any).getMixedSpecies(pokemon.m.originalSpecies, pokemon.canMegaEvo, pokemon);
|
||||
|
||||
// Do we have a proper sprite for it? Code for when megas actually exist
|
||||
if (this.dex.species.get(pokemon.canMegaEvo as any).baseSpecies === pokemon.m.originalSpecies) {
|
||||
pokemon.formeChange(species, pokemon.getItem(), true);
|
||||
} else {
|
||||
const oSpecies = this.dex.species.get(pokemon.m.originalSpecies);
|
||||
const oMegaSpecies = this.dex.species.get((species as any).originalSpecies);
|
||||
pokemon.formeChange(species, pokemon.getItem(), true);
|
||||
this.battle.add('-start', pokemon, oMegaSpecies.requiredItem, '[silent]');
|
||||
if (oSpecies.types.join('/') !== pokemon.species.types.join('/')) {
|
||||
this.battle.add('-start', pokemon, 'typechange', pokemon.species.types.join('/'), '[silent]');
|
||||
}
|
||||
}
|
||||
|
||||
pokemon.canMegaEvo = false;
|
||||
return true;
|
||||
},
|
||||
getMixedSpecies(originalForme, formeChange, pokemon) {
|
||||
const originalSpecies = this.dex.species.get(originalForme);
|
||||
const formeChangeSpecies = this.dex.species.get(formeChange);
|
||||
if (originalSpecies.baseSpecies === formeChangeSpecies.baseSpecies) {
|
||||
return formeChangeSpecies;
|
||||
}
|
||||
const deltas = (this as any).getFormeChangeDeltas(formeChangeSpecies, pokemon);
|
||||
const species = (this as any).mutateOriginalSpecies(originalSpecies, deltas);
|
||||
return species;
|
||||
},
|
||||
getFormeChangeDeltas(formeChangeSpecies, pokemon) {
|
||||
// Should be fine as long as Necrozma-U doesn't get added or Game Freak makes me sad with some convoluted forme change
|
||||
const baseSpecies = this.dex.species.get(formeChangeSpecies.isMega ?
|
||||
formeChangeSpecies.battleOnly as string : formeChangeSpecies.baseSpecies);
|
||||
const deltas: {
|
||||
ability: string,
|
||||
baseStats: SparseStatsTable,
|
||||
weighthg: number,
|
||||
heightm: number,
|
||||
originalSpecies: string,
|
||||
requiredItem: string | undefined,
|
||||
type?: string,
|
||||
formeType?: string,
|
||||
isMega?: boolean,
|
||||
} = {
|
||||
ability: formeChangeSpecies.abilities['0'],
|
||||
baseStats: {},
|
||||
weighthg: formeChangeSpecies.weighthg - baseSpecies.weighthg,
|
||||
heightm: ((formeChangeSpecies.heightm * 10) - (baseSpecies.heightm * 10)) / 10,
|
||||
originalSpecies: formeChangeSpecies.name,
|
||||
requiredItem: formeChangeSpecies.requiredItem,
|
||||
};
|
||||
let statId: StatID;
|
||||
for (statId in formeChangeSpecies.baseStats) {
|
||||
deltas.baseStats[statId] = formeChangeSpecies.baseStats[statId] - baseSpecies.baseStats[statId];
|
||||
}
|
||||
let formeType: string | null = null;
|
||||
if (formeChangeSpecies.types.length > baseSpecies.types.length) {
|
||||
deltas.type = formeChangeSpecies.types[1];
|
||||
} else if (formeChangeSpecies.types.length < baseSpecies.types.length) {
|
||||
deltas.type = baseSpecies.types[0];
|
||||
} else if (formeChangeSpecies.types[1] !== baseSpecies.types[1]) {
|
||||
deltas.type = formeChangeSpecies.types[1];
|
||||
}
|
||||
if (formeChangeSpecies.isMega && !formeType) formeType = 'Mega';
|
||||
if (formeChangeSpecies.isPrimal) formeType = 'Primal';
|
||||
if (formeType) deltas.formeType = formeType;
|
||||
return deltas;
|
||||
},
|
||||
mutateOriginalSpecies(speciesOrForme, deltas) {
|
||||
if (!deltas) throw new TypeError("Must specify deltas!");
|
||||
const species = this.dex.deepClone(this.dex.species.get(speciesOrForme));
|
||||
species.abilities = { '0': deltas.ability };
|
||||
if (species.types[0] === deltas.type) {
|
||||
species.types = [deltas.type];
|
||||
} else if (deltas.type) {
|
||||
species.types = [species.types[0], deltas.type];
|
||||
}
|
||||
const baseStats = species.baseStats;
|
||||
for (const statName in baseStats) {
|
||||
baseStats[statName] = this.battle.clampIntRange(baseStats[statName] + deltas.baseStats[statName], 1, 255);
|
||||
}
|
||||
species.weighthg = Math.max(1, species.weighthg + deltas.weighthg);
|
||||
species.heightm = Math.max(0.1, ((species.heightm * 10) + (deltas.heightm * 10)) / 10);
|
||||
species.originalSpecies = deltas.originalSpecies;
|
||||
species.requiredItem = deltas.requiredItem;
|
||||
if (deltas.formeType === 'Mega' || deltas.isMega) species.isMega = true;
|
||||
if (deltas.formeType === 'Primal') species.isPrimal = true;
|
||||
return species;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -19,6 +19,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
if (['mimikyu', 'mimikyutotem'].includes(pokemon.species.id) && this.effectState.busted) {
|
||||
const speciesid = pokemon.species.id === 'mimikyutotem' ? 'Mimikyu-Busted-Totem' : 'Mimikyu-Busted';
|
||||
pokemon.formeChange(speciesid, this.effect, true);
|
||||
pokemon.formeRegression = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -71,14 +72,8 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
onTryBoost() {},
|
||||
},
|
||||
rattled: {
|
||||
onDamagingHit(damage, target, source, move) {
|
||||
if (['Dark', 'Bug', 'Ghost'].includes(move.type)) {
|
||||
this.boost({ spe: 1 });
|
||||
}
|
||||
},
|
||||
name: "Rattled",
|
||||
rating: 1.5,
|
||||
num: 155,
|
||||
inherit: true,
|
||||
onAfterBoost() {},
|
||||
},
|
||||
scrappy: {
|
||||
inherit: true,
|
||||
|
|
@ -86,33 +81,18 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
},
|
||||
slowstart: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
onResidualOrder: 28,
|
||||
onResidualSubOrder: 2,
|
||||
onStart(target) {
|
||||
this.add('-start', target, 'ability: Slow Start');
|
||||
},
|
||||
onModifyAtkPriority: 5,
|
||||
onModifyAtk(atk, pokemon, target, move) {
|
||||
// This is because the game checks the move's category in data, rather than what it is currently, unlike e.g. Huge Power
|
||||
if (this.dex.moves.get(move.id).category === 'Physical') {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
onModifySpAPriority: 5,
|
||||
onModifySpA(spa, pokemon, target, move) {
|
||||
// Ordinary Z-moves like Breakneck Blitz will halve the user's Special Attack as well
|
||||
if (this.dex.moves.get(move.id).category === 'Physical') {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
onModifySpe(spe, pokemon) {
|
||||
onModifyAtk(atk, pokemon, target, move) {
|
||||
// This is because the game checks the move's category in data, rather than what it is currently, unlike e.g. Huge Power
|
||||
if (this.effectState.counter && this.dex.moves.get(move.id).category === 'Physical') {
|
||||
return this.chainModify(0.5);
|
||||
},
|
||||
onEnd(target) {
|
||||
this.add('-end', target, 'Slow Start');
|
||||
},
|
||||
}
|
||||
},
|
||||
onModifySpAPriority: 5,
|
||||
onModifySpA(spa, pokemon, target, move) {
|
||||
// Ordinary Z-moves like Breakneck Blitz will halve the user's Special Attack as well
|
||||
if (this.effectState.counter && this.dex.moves.get(move.id).category === 'Physical') {
|
||||
return this.chainModify(0.5);
|
||||
}
|
||||
},
|
||||
},
|
||||
soundproof: {
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
vulpixalola: {
|
||||
tier: "LC",
|
||||
tier: "NFE",
|
||||
},
|
||||
ninetales: {
|
||||
tier: "RU",
|
||||
|
|
@ -592,7 +592,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
doublesTier: "NFE",
|
||||
},
|
||||
tangrowth: {
|
||||
tier: "OU",
|
||||
tier: "(OU)",
|
||||
doublesTier: "(DUU)",
|
||||
},
|
||||
kangaskhan: {
|
||||
|
|
@ -916,7 +916,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
azumarill: {
|
||||
tier: "OU",
|
||||
tier: "(OU)",
|
||||
doublesTier: "DUU",
|
||||
},
|
||||
bonsly: {
|
||||
|
|
|
|||
|
|
@ -127,10 +127,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
onHit(target, source, move) {
|
||||
let success = false;
|
||||
if (!target.volatiles['substitute'] || move.infiltrates) success = !!this.boost({ evasion: -1 });
|
||||
const removeTarget = [
|
||||
'reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb',
|
||||
];
|
||||
const removeAll = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb'];
|
||||
const removeTarget = ['reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', ...removeAll];
|
||||
for (const targetCondition of removeTarget) {
|
||||
if (target.side.removeSideCondition(targetCondition)) {
|
||||
if (!removeAll.includes(targetCondition)) continue;
|
||||
|
|
@ -184,46 +182,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
electricterrain: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
durationCallback(source, effect) {
|
||||
if (source?.hasItem('terrainextender')) {
|
||||
return 8;
|
||||
}
|
||||
return 5;
|
||||
},
|
||||
onSetStatus(status, target, source, effect) {
|
||||
if (status.id === 'slp' && target.isGrounded() && !target.isSemiInvulnerable()) {
|
||||
if (effect.id === 'yawn' || (effect.effectType === 'Move' && !effect.secondaries)) {
|
||||
this.add('-activate', target, 'move: Electric Terrain');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
onTryAddVolatile(status, target) {
|
||||
if (!target.isGrounded() || target.isSemiInvulnerable()) return;
|
||||
if (status.id === 'yawn') {
|
||||
this.add('-activate', target, 'move: Electric Terrain');
|
||||
return null;
|
||||
}
|
||||
},
|
||||
inherit: true,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.type === 'Electric' && attacker.isGrounded() && !attacker.isSemiInvulnerable()) {
|
||||
this.debug('electric terrain boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onFieldStart(field, source, effect) {
|
||||
if (effect && effect.effectType === 'Ability') {
|
||||
this.add('-fieldstart', 'move: Electric Terrain', `[from] ability: ${effect}`, `[of] ${source}`);
|
||||
} else {
|
||||
this.add('-fieldstart', 'move: Electric Terrain');
|
||||
}
|
||||
},
|
||||
onFieldResidualOrder: 27,
|
||||
onFieldResidualSubOrder: 7,
|
||||
onFieldEnd() {
|
||||
this.add('-fieldend', 'move: Electric Terrain');
|
||||
},
|
||||
},
|
||||
},
|
||||
embargo: {
|
||||
|
|
@ -317,13 +282,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
grassyterrain: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
durationCallback(source, effect) {
|
||||
if (source?.hasItem('terrainextender')) {
|
||||
return 8;
|
||||
}
|
||||
return 5;
|
||||
},
|
||||
inherit: true,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
const weakenedMoves = ['earthquake', 'bulldoze', 'magnitude'];
|
||||
if (weakenedMoves.includes(move.id) && defender.isGrounded() && !defender.isSemiInvulnerable()) {
|
||||
|
|
@ -335,27 +294,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onFieldStart(field, source, effect) {
|
||||
if (effect && effect.effectType === 'Ability') {
|
||||
this.add('-fieldstart', 'move: Grassy Terrain', `[from] ability: ${effect}`, `[of] ${source}`);
|
||||
} else {
|
||||
this.add('-fieldstart', 'move: Grassy Terrain');
|
||||
}
|
||||
},
|
||||
onResidualOrder: 5,
|
||||
onResidualSubOrder: 2,
|
||||
onResidual(pokemon) {
|
||||
if (pokemon.isGrounded() && !pokemon.isSemiInvulnerable()) {
|
||||
this.heal(pokemon.baseMaxhp / 16, pokemon, pokemon);
|
||||
} else {
|
||||
this.debug(`Pokemon semi-invuln or not grounded; Grassy Terrain skipped`);
|
||||
}
|
||||
},
|
||||
onFieldResidualOrder: 27,
|
||||
onFieldResidualSubOrder: 7,
|
||||
onFieldEnd() {
|
||||
this.add('-fieldend', 'move: Grassy Terrain');
|
||||
},
|
||||
},
|
||||
},
|
||||
guardianofalola: {
|
||||
|
|
@ -386,7 +324,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
condition: {
|
||||
duration: 2,
|
||||
onSwitchInPriority: 1,
|
||||
onSwitchIn(target) {
|
||||
if (!target.fainted) {
|
||||
target.heal(target.maxhp);
|
||||
|
|
@ -559,11 +496,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
kingsshield: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 1,
|
||||
onStart(target) {
|
||||
this.add('-singleturn', target, 'Protect');
|
||||
},
|
||||
onTryHitPriority: 3,
|
||||
inherit: true,
|
||||
onTryHit(target, source, move) {
|
||||
if (!move.flags['protect'] || move.category === 'Status') {
|
||||
if (move.isZ || move.isMax) target.getMoveHitData(move).zBrokeProtect = true;
|
||||
|
|
@ -613,7 +546,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
condition: {
|
||||
duration: 2,
|
||||
onSwitchInPriority: 1,
|
||||
onSwitchIn(target) {
|
||||
if (!target.fainted) {
|
||||
target.heal(target.maxhp);
|
||||
|
|
@ -782,47 +714,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
psychicterrain: {
|
||||
inherit: true,
|
||||
condition: {
|
||||
duration: 5,
|
||||
durationCallback(source, effect) {
|
||||
if (source?.hasItem('terrainextender')) {
|
||||
return 8;
|
||||
}
|
||||
return 5;
|
||||
},
|
||||
onTryHitPriority: 4,
|
||||
onTryHit(target, source, effect) {
|
||||
if (effect && (effect.priority <= 0.1 || effect.target === 'self')) {
|
||||
return;
|
||||
}
|
||||
if (target.isSemiInvulnerable() || target.isAlly(source)) return;
|
||||
if (!target.isGrounded()) {
|
||||
const baseMove = this.dex.moves.get(effect.id);
|
||||
if (baseMove.priority > 0) {
|
||||
this.hint("Psychic Terrain doesn't affect Pokémon immune to Ground.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.add('-activate', target, 'move: Psychic Terrain');
|
||||
return null;
|
||||
},
|
||||
inherit: true,
|
||||
onBasePower(basePower, attacker, defender, move) {
|
||||
if (move.type === 'Psychic' && attacker.isGrounded() && !attacker.isSemiInvulnerable()) {
|
||||
this.debug('psychic terrain boost');
|
||||
return this.chainModify(1.5);
|
||||
}
|
||||
},
|
||||
onFieldStart(field, source, effect) {
|
||||
if (effect && effect.effectType === 'Ability') {
|
||||
this.add('-fieldstart', 'move: Psychic Terrain', `[from] ability: ${effect}`, `[of] ${source}`);
|
||||
} else {
|
||||
this.add('-fieldstart', 'move: Psychic Terrain');
|
||||
}
|
||||
},
|
||||
onFieldResidualOrder: 27,
|
||||
onFieldResidualSubOrder: 7,
|
||||
onFieldEnd() {
|
||||
this.add('-fieldend', 'move: Psychic Terrain');
|
||||
},
|
||||
},
|
||||
},
|
||||
psychoboost: {
|
||||
|
|
@ -1154,39 +1052,6 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
|||
inherit: true,
|
||||
isNonstandard: null,
|
||||
},
|
||||
trick: {
|
||||
inherit: true,
|
||||
onHit(target, source, move) {
|
||||
const yourItem = target.takeItem(source);
|
||||
const myItem = source.takeItem();
|
||||
if (target.item || source.item || (!yourItem && !myItem)) {
|
||||
if (yourItem) target.item = yourItem.id;
|
||||
if (myItem) source.item = myItem.id;
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
(myItem && !this.singleEvent('TakeItem', myItem, source.itemState, target, source, move, myItem)) ||
|
||||
(yourItem && !this.singleEvent('TakeItem', yourItem, target.itemState, source, target, move, yourItem))
|
||||
) {
|
||||
if (yourItem) target.item = yourItem.id;
|
||||
if (myItem) source.item = myItem.id;
|
||||
return false;
|
||||
}
|
||||
this.add('-activate', source, 'move: Trick', `[of] ${target}`);
|
||||
if (myItem) {
|
||||
target.setItem(myItem);
|
||||
this.add('-item', target, myItem, '[from] move: Trick');
|
||||
} else {
|
||||
this.add('-enditem', target, yourItem, '[silent]', '[from] move: Trick');
|
||||
}
|
||||
if (yourItem) {
|
||||
source.setItem(yourItem);
|
||||
this.add('-item', source, yourItem, '[from] move: Trick');
|
||||
} else {
|
||||
this.add('-enditem', source, myItem, '[silent]', '[from] move: Trick');
|
||||
}
|
||||
},
|
||||
},
|
||||
trumpcard: {
|
||||
inherit: true,
|
||||
isNonstandard: null,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
inherit: true,
|
||||
eggGroups: ["Bug"],
|
||||
},
|
||||
burmysandy: {
|
||||
inherit: true,
|
||||
color: "Green",
|
||||
},
|
||||
burmytrash: {
|
||||
inherit: true,
|
||||
color: "Green",
|
||||
},
|
||||
magnezone: {
|
||||
inherit: true,
|
||||
evoType: "levelExtra",
|
||||
|
|
@ -83,6 +91,94 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
|
|||
abilities: { 0: "Flash Fire", H: "Flame Body" },
|
||||
unreleasedHidden: true,
|
||||
},
|
||||
deerlingsummer: {
|
||||
inherit: true,
|
||||
color: "Pink",
|
||||
},
|
||||
deerlingautumn: {
|
||||
inherit: true,
|
||||
color: "Pink",
|
||||
},
|
||||
deerlingwinter: {
|
||||
inherit: true,
|
||||
color: "Pink",
|
||||
},
|
||||
vivillonicysnow: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonpolar: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillontundra: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivilloncontinental: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillongarden: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonelegant: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonmodern: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonmarine: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonarchipelago: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonhighplains: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonsandstorm: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonriver: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonmonsoon: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonsavanna: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonsun: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonocean: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonjungle: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonfancy: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
vivillonpokeball: {
|
||||
inherit: true,
|
||||
color: "White",
|
||||
},
|
||||
aegislash: {
|
||||
inherit: true,
|
||||
baseStats: { hp: 60, atk: 50, def: 150, spa: 50, spd: 150, spe: 60 },
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
|
||||
standard: {
|
||||
inherit: true,
|
||||
ruleset: ['Obtainable', 'Team Preview', 'Sleep Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Moody Clause', 'Evasion Items Clause', 'Evasion Moves Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Sleep Clause Mod', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Items Clause', 'Evasion Moves Clause',
|
||||
],
|
||||
banlist: ['Moody'],
|
||||
},
|
||||
standarddoubles: {
|
||||
inherit: true,
|
||||
ruleset: ['Obtainable', 'Team Preview', 'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Moody Clause', 'Evasion Abilities Clause', 'Evasion Moves Clause', 'Gravity Sleep Clause', 'Endless Battle Clause', 'HP Percentage Mod', 'Cancel Mod'],
|
||||
ruleset: [
|
||||
'Standard AG',
|
||||
'Species Clause', 'Nickname Clause', 'OHKO Clause', 'Evasion Abilities Clause', 'Evasion Moves Clause', 'Gravity Sleep Clause',
|
||||
],
|
||||
banlist: ['Moody'],
|
||||
},
|
||||
obtainablemoves: {
|
||||
inherit: true,
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
},
|
||||
pikachustarter: {
|
||||
isNonstandard: null,
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
raichu: {
|
||||
|
|
@ -138,7 +138,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
doublesTier: "DOU",
|
||||
},
|
||||
sandslashalola: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
nidoranf: {
|
||||
|
|
@ -158,7 +158,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
nidoking: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
clefairy: {
|
||||
|
|
@ -186,7 +186,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
wigglytuff: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
zubat: {
|
||||
|
|
@ -203,7 +203,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
vileplume: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
paras: {
|
||||
|
|
@ -227,7 +227,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
dugtrio: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
dugtrioalola: {
|
||||
|
|
@ -245,7 +245,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
doublesTier: "DOU",
|
||||
},
|
||||
persianalola: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
psyduck: {
|
||||
|
|
@ -266,7 +266,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
arcanine: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
poliwag: {
|
||||
|
|
@ -276,7 +276,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "NFE",
|
||||
},
|
||||
poliwrath: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
abra: {
|
||||
|
|
@ -317,7 +317,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
tentacruel: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
geodude: {
|
||||
|
|
@ -401,7 +401,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
cloyster: {
|
||||
tier: "OU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
gastly: {
|
||||
|
|
@ -433,7 +433,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
kingler: {
|
||||
tier: "RU",
|
||||
tier: "UU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
voltorb: {
|
||||
|
|
@ -492,7 +492,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
doublesTier: "DOU",
|
||||
},
|
||||
chansey: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
tangela: {
|
||||
|
|
@ -572,7 +572,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
doublesTier: "DOU",
|
||||
},
|
||||
lapras: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
ditto: {
|
||||
|
|
@ -584,7 +584,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
},
|
||||
eeveestarter: {
|
||||
isNonstandard: null,
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
vaporeon: {
|
||||
|
|
@ -607,14 +607,14 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
tier: "LC",
|
||||
},
|
||||
omastar: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
kabuto: {
|
||||
tier: "LC",
|
||||
},
|
||||
kabutops: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
aerodactyl: {
|
||||
|
|
@ -626,7 +626,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
doublesTier: "DOU",
|
||||
},
|
||||
snorlax: {
|
||||
tier: "OU",
|
||||
tier: "UU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
articuno: {
|
||||
|
|
@ -638,7 +638,7 @@ export const FormatsData: import('../../../sim/dex-species').ModdedSpeciesFormat
|
|||
doublesTier: "DOU",
|
||||
},
|
||||
moltres: {
|
||||
tier: "UU",
|
||||
tier: "RU",
|
||||
doublesTier: "DOU",
|
||||
},
|
||||
dratini: {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user