mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-30 13:58:53 -04:00
Compare commits
781
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ada7f0faf8 | ||
|
|
e1eff89259 | ||
|
|
cc149a0ff2 | ||
|
|
3fea718766 | ||
|
|
c99bf99052 | ||
|
|
e8019a0623 | ||
|
|
4c95cfc1b3 | ||
|
|
51a096913d | ||
|
|
980d95819e | ||
|
|
24aa65b2f1 | ||
|
|
19f33fe530 | ||
|
|
bbe8a6948a | ||
|
|
e46aaa5725 | ||
|
|
fc6c302c71 | ||
|
|
76cf856907 | ||
|
|
145d56e205 | ||
|
|
969b070300 | ||
|
|
e474ef607c | ||
|
|
a2ecccfac4 | ||
|
|
1a475bff87 | ||
|
|
8b6f5f55e6 | ||
|
|
39ed65e8ca | ||
|
|
35dab86ef4 | ||
|
|
2cc14d26b1 | ||
|
|
c29da11541 | ||
|
|
8188ce0ed2 | ||
|
|
301de140e3 | ||
|
|
4a41060533 | ||
|
|
ac55636c51 | ||
|
|
18eb50d4d2 | ||
|
|
87276de14d | ||
|
|
b7dc9ea6f6 | ||
|
|
ff59604526 | ||
|
|
b620ad27b6 | ||
|
|
78daec9c7b | ||
|
|
5565f22610 | ||
|
|
7582b08d56 | ||
|
|
2e101f023f | ||
|
|
d98cccfc0f | ||
|
|
07f087c35c | ||
|
|
f83bde399c | ||
|
|
19f0bc29f4 | ||
|
|
531f64394a | ||
|
|
af77534b96 | ||
|
|
fa5193a3db | ||
|
|
e3c95aa4a5 | ||
|
|
72740fb418 | ||
|
|
250f9e3cec | ||
|
|
26078ec29d | ||
|
|
5b68889689 | ||
|
|
bb3e86ac02 | ||
|
|
b96a6282d8 | ||
|
|
14ee3cd754 | ||
|
|
9c66c65b9e | ||
|
|
9ffbd14a81 | ||
|
|
7044cb35b2 | ||
|
|
e258d6439f | ||
|
|
221e51b023 | ||
|
|
5053c765fb | ||
|
|
bfe8d41102 | ||
|
|
c9fe117916 | ||
|
|
af3b6e3f2a | ||
|
|
1b7759b77d | ||
|
|
698c07f0b8 | ||
|
|
a4a094a624 | ||
|
|
b0d2df2917 | ||
|
|
f6ad1ab7aa | ||
|
|
3f85ce0c81 | ||
|
|
e25c3c3d7c | ||
|
|
0215a30c8d | ||
|
|
f16ec1d6d3 | ||
|
|
73e59159a0 | ||
|
|
5b7b430e5f | ||
|
|
4e6f2973c2 | ||
|
|
4f5799e5df | ||
|
|
822794230d | ||
|
|
54ea4903ba | ||
|
|
28ad0cce83 | ||
|
|
7fe1929609 | ||
|
|
e03082a75e | ||
|
|
8d0c27f0e4 | ||
|
|
91fc2dc896 | ||
|
|
d58603ff33 | ||
|
|
ab1ca295a3 | ||
|
|
157532f372 | ||
|
|
5cbe937e23 | ||
|
|
4fa196da94 | ||
|
|
3a1c3fc934 | ||
|
|
43aa0ec04a | ||
|
|
b4bf044f76 | ||
|
|
d35db46c1b | ||
|
|
b8a6c94fcb | ||
|
|
b069e448c1 | ||
|
|
18f41407c8 | ||
|
|
b659a662a2 | ||
|
|
dbb2e45e14 | ||
|
|
da491015a6 | ||
|
|
55db0d8af1 | ||
|
|
211821bc0f | ||
|
|
16a21f9d2e | ||
|
|
e69060bde6 | ||
|
|
ebdbbd5176 | ||
|
|
6e163d08f0 | ||
|
|
13c7b75b19 | ||
|
|
1ad36e39c5 | ||
|
|
f4d67b9b64 | ||
|
|
3c84afb95d | ||
|
|
2e615800ae | ||
|
|
0fc1239c77 | ||
|
|
38a0d149c5 | ||
|
|
4a4aaf3a94 | ||
|
|
53ca8f009d | ||
|
|
5b5c756d3c | ||
|
|
75410c3a72 | ||
|
|
87d001da80 | ||
|
|
8fee0e7f91 | ||
|
|
7985aed6bf | ||
|
|
5543b8a660 | ||
|
|
d7d855adc2 | ||
|
|
4fd50b8d2b | ||
|
|
be466ad252 | ||
|
|
53749e014b | ||
|
|
b4cdf371fe | ||
|
|
e0e30e7e11 | ||
|
|
cfec4e10cb | ||
|
|
614799cfcb | ||
|
|
ec367fd4df | ||
|
|
e415b281ee | ||
|
|
265aa6e124 | ||
|
|
2765a5584f | ||
|
|
d77cb36149 | ||
|
|
d37d95ee70 | ||
|
|
63f8e6251e | ||
|
|
5a3e9bb236 | ||
|
|
2fce916f05 | ||
|
|
52c4c35c0d | ||
|
|
40f4f80d6e | ||
|
|
721025281f | ||
|
|
08e6f68693 | ||
|
|
1e3fcf3e84 | ||
|
|
92a67ca0ca | ||
|
|
42600fc840 | ||
|
|
9917b57e1a | ||
|
|
b5e2f69207 | ||
|
|
c6c83c065b | ||
|
|
687381dc1b | ||
|
|
f088dd62bc | ||
|
|
3d1f9458f6 | ||
|
|
470d3807f1 | ||
|
|
1c74d498e6 | ||
|
|
4d3c46acc4 | ||
|
|
fbec87d2e0 | ||
|
|
397f8db5a0 | ||
|
|
36cd5f3894 | ||
|
|
b86f08b069 | ||
|
|
026897719d | ||
|
|
c4451ffb4f | ||
|
|
710b6404e7 | ||
|
|
b8f59110f0 | ||
|
|
75927fc1a9 | ||
|
|
0a0c1edffc | ||
|
|
18403c833d | ||
|
|
b9824e5708 | ||
|
|
57c1201ad0 | ||
|
|
4637bef5d2 | ||
|
|
37e0030d08 | ||
|
|
628db514b3 | ||
|
|
6207a01ae3 | ||
|
|
9046217867 | ||
|
|
40aaef68f9 | ||
|
|
09c7bd8e61 | ||
|
|
8df8cb9cfe | ||
|
|
c048e5752b | ||
|
|
e8aa06d633 | ||
|
|
64979ff742 | ||
|
|
0163619e87 | ||
|
|
258ffd25ea | ||
|
|
2dd0d3dcf1 | ||
|
|
cc5b65a1dd | ||
|
|
b7de250457 | ||
|
|
8d0c5bc05c | ||
|
|
f4e242a270 | ||
|
|
da3a513905 | ||
|
|
33af6a1557 | ||
|
|
62b07f7f8a | ||
|
|
7bddbcfc67 | ||
|
|
993c7a5cf0 | ||
|
|
44da19f3e0 | ||
|
|
6d97c6ea34 | ||
|
|
2a55ef114d | ||
|
|
c236d8147a | ||
|
|
cf90bf0b0f | ||
|
|
b109ff6edf | ||
|
|
4ea288cc34 | ||
|
|
98540294b1 | ||
|
|
5535a6a7cb | ||
|
|
dd426423a1 | ||
|
|
6237e44e7c | ||
|
|
09561f736a | ||
|
|
14e4fe66ac | ||
|
|
975c68cea0 | ||
|
|
6b77adbcef | ||
|
|
d12a8704a9 | ||
|
|
52fc6b2575 | ||
|
|
68ffe0bdbc | ||
|
|
4734c0a3cb | ||
|
|
1ed4d9ff9a | ||
|
|
8d0fc77be2 | ||
|
|
c45ef65645 | ||
|
|
0adfc64e35 | ||
|
|
80b4238c7e | ||
|
|
e16ae2544c | ||
|
|
f182cf4335 | ||
|
|
f5840c4794 | ||
|
|
cff65ab22e | ||
|
|
1d550b2cac | ||
|
|
c859cbae76 | ||
|
|
10e7962d85 | ||
|
|
767f820b7a | ||
|
|
06e4783f16 | ||
|
|
fe83b9d58e | ||
|
|
709e6f4a63 | ||
|
|
17f686488e | ||
|
|
db574332e5 | ||
|
|
73b72ff19d | ||
|
|
15aac5e20a | ||
|
|
b88f4335ee | ||
|
|
6916cd51f7 | ||
|
|
b2ebfcc3b0 | ||
|
|
3b73493801 | ||
|
|
bfb48e8583 | ||
|
|
1bfe5e2044 | ||
|
|
ace65eda66 | ||
|
|
01c44537d0 | ||
|
|
e414dd94c3 | ||
|
|
2d4800a733 | ||
|
|
90e193e5a0 | ||
|
|
c7e86cf767 | ||
|
|
d8906992a3 | ||
|
|
972c259f6d | ||
|
|
8228424191 | ||
|
|
9bb67087b3 | ||
|
|
0f08446732 | ||
|
|
af09a6a0c7 | ||
|
|
b4d2f39c48 | ||
|
|
1a12bbd493 | ||
|
|
8a24f635cf | ||
|
|
d6e066ddcd | ||
|
|
50335135c9 | ||
|
|
1ee6f83a5b | ||
|
|
e8b747a432 | ||
|
|
8f8804f3f4 | ||
|
|
ef826158ce | ||
|
|
d32314742d | ||
|
|
e8e0ca47dd | ||
|
|
ebcac6e782 | ||
|
|
63bfa634ae | ||
|
|
c3d482c78f | ||
|
|
7ea85dbd1e | ||
|
|
6cdb14d2f8 | ||
|
|
f041049576 | ||
|
|
e1aa6445fa | ||
|
|
f1b7ee5b9c | ||
|
|
9ea0f7e4f8 | ||
|
|
d0edd6ecbc | ||
|
|
1372505486 | ||
|
|
a4ce4bf99b | ||
|
|
7effc4c853 | ||
|
|
4cd504126b | ||
|
|
60ee7b819c | ||
|
|
28548d5b19 | ||
|
|
e6ec690811 | ||
|
|
dac49c2f42 | ||
|
|
d72dad355c | ||
|
|
40b5726c5b | ||
|
|
d32aa46832 | ||
|
|
5068e66fa7 | ||
|
|
482b682595 | ||
|
|
ffecc58979 | ||
|
|
eaaf2ca05c | ||
|
|
e91651553b | ||
|
|
874a5d2e8f | ||
|
|
70e49bbbdb | ||
|
|
39fce8ca06 | ||
|
|
d288fe46da | ||
|
|
cefc97320a | ||
|
|
a2094677cd | ||
|
|
eae4eb5121 | ||
|
|
ed3a008515 | ||
|
|
462074ce43 | ||
|
|
d54a85aa68 | ||
|
|
bf8433f6e9 | ||
|
|
374fc44089 | ||
|
|
f7664a04db | ||
|
|
51b0f768a0 | ||
|
|
106e487035 | ||
|
|
2d772f5bf7 | ||
|
|
63af1713b9 | ||
|
|
8fecb12829 | ||
|
|
d0b50a1ee0 | ||
|
|
07497d653e | ||
|
|
2ecbe28c87 | ||
|
|
80112e0b70 | ||
|
|
dfb28ed185 | ||
|
|
0cc9a75255 | ||
|
|
abfd718681 | ||
|
|
8271b7a979 | ||
|
|
251c2df78e | ||
|
|
c03e30bd9c | ||
|
|
f776542365 | ||
|
|
ecc793350a | ||
|
|
045ca3a07f | ||
|
|
a71bad07bd | ||
|
|
2085f12fef | ||
|
|
36c4ea3b1a | ||
|
|
804ad75ede | ||
|
|
be11568041 | ||
|
|
863b43f902 | ||
|
|
8ad54287e4 | ||
|
|
179d90d482 | ||
|
|
c3fb661f49 | ||
|
|
dccffe311f | ||
|
|
1769af7385 | ||
|
|
d7d8d766d1 | ||
|
|
54b2cc0a59 | ||
|
|
62696931df | ||
|
|
bfc7f83e07 | ||
|
|
db573455ea | ||
|
|
3af002a39c | ||
|
|
a15c44325d | ||
|
|
33fc67ed58 | ||
|
|
b9f2bcc3a3 | ||
|
|
8a5a88b4f1 | ||
|
|
af6b1190c1 | ||
|
|
7f0a6d4d48 | ||
|
|
d7e4298a91 | ||
|
|
923b4e4266 | ||
|
|
88e38bfa1a | ||
|
|
507a9a54b5 | ||
|
|
0b72a072bd | ||
|
|
c927cae609 | ||
|
|
474918e414 | ||
|
|
30f82bbad6 | ||
|
|
0e93383c90 | ||
|
|
1823eb4979 | ||
|
|
abb44cf696 | ||
|
|
ae4af68797 | ||
|
|
e6bd7cad72 | ||
|
|
da7f4a2682 | ||
|
|
73c4762801 | ||
|
|
43abfa3c17 | ||
|
|
fb87220fe9 | ||
|
|
07bba37c03 | ||
|
|
5896a74d1f | ||
|
|
2a0de32854 | ||
|
|
406097c1ff | ||
|
|
14ec3c00e6 | ||
|
|
18b17b0638 | ||
|
|
59c96fe30d | ||
|
|
565667aa1c | ||
|
|
3955283425 | ||
|
|
beee02033c | ||
|
|
e2db59c837 | ||
|
|
10bf69a79b | ||
|
|
172293c813 | ||
|
|
9bb653b8b7 | ||
|
|
7d06f1e2cd | ||
|
|
74d2f4f700 | ||
|
|
6ed4504273 | ||
|
|
8ee6799653 | ||
|
|
96cbc4eca6 | ||
|
|
ad24e529f5 | ||
|
|
86902b69e1 | ||
|
|
2ac102a3b6 | ||
|
|
a54ff5f0a7 | ||
|
|
edc5ae741c | ||
|
|
70bed4f299 | ||
|
|
e24b20546d | ||
|
|
eb071d4d01 | ||
|
|
625a31e7e8 | ||
|
|
2b14931709 | ||
|
|
2c32b50182 | ||
|
|
b5230a8d3c | ||
|
|
5ff3d163c0 | ||
|
|
82e6e01978 | ||
|
|
a6b5f2d64c | ||
|
|
6408b60dde | ||
|
|
a7b55e5d03 | ||
|
|
28db655376 | ||
|
|
006736cd71 | ||
|
|
2f4bdb336b | ||
|
|
f240dc1963 | ||
|
|
b6308e6c6c | ||
|
|
535c5f2e67 | ||
|
|
8b209e081b | ||
|
|
f7f276ecfb | ||
|
|
da7dbeaaec | ||
|
|
84a0ceb7e1 | ||
|
|
ccde7ffbb1 | ||
|
|
4e79ed9f7e | ||
|
|
dea2ad4b12 | ||
|
|
ecefea005d | ||
|
|
4c787f547c | ||
|
|
f0755cc73f | ||
|
|
e215d751c4 | ||
|
|
aac4669ec1 | ||
|
|
7b0b41d192 | ||
|
|
7e38fefa14 | ||
|
|
fc0cd0dac4 | ||
|
|
c1491daf63 | ||
|
|
068b55be7b | ||
|
|
3f6bd52d43 | ||
|
|
019245472f | ||
|
|
cefb502f10 | ||
|
|
4ca3f25ab2 | ||
|
|
70e81f1cbe | ||
|
|
df8abf4ddb | ||
|
|
26dd0b9d42 | ||
|
|
307d8bad1d | ||
|
|
866332e62c | ||
|
|
c54466f6b1 | ||
|
|
ee5e4d33b2 | ||
|
|
0fd954ffa5 | ||
|
|
60d3d737f9 | ||
|
|
fb570404c0 | ||
|
|
d22602dac5 | ||
|
|
63da8fed2d | ||
|
|
2f16ba5470 | ||
|
|
af36d4a365 | ||
|
|
d153ec155b | ||
|
|
7ca7cc089a | ||
|
|
cbdfbc9745 | ||
|
|
ac210e027b | ||
|
|
1fc91a794f | ||
|
|
f78b289171 | ||
|
|
c46461c843 | ||
|
|
386a897295 | ||
|
|
8328f741d8 | ||
|
|
2b19943416 | ||
|
|
7dd38bf043 | ||
|
|
4caba2fbeb | ||
|
|
5239de2cea | ||
|
|
296355f744 | ||
|
|
e9d9a109c0 | ||
|
|
8a3789fc35 | ||
|
|
05fd7bec36 | ||
|
|
e6b1529f27 | ||
|
|
550b99be36 | ||
|
|
a42ba8de43 | ||
|
|
8960c6dddc | ||
|
|
bfbee7b1d7 | ||
|
|
bc1f9f8cb4 | ||
|
|
f5d71390dd | ||
|
|
6ff5d3df06 | ||
|
|
988766894a | ||
|
|
3d5a365a6e | ||
|
|
4b64b4307a | ||
|
|
382f741db8 | ||
|
|
6d62d911d6 | ||
|
|
a1d40084c5 | ||
|
|
8b1b63e110 | ||
|
|
a7956531ff | ||
|
|
4b0919223b | ||
|
|
9e2e95e287 | ||
|
|
6694680c50 | ||
|
|
8cafce0a4a | ||
|
|
de271f81b1 | ||
|
|
feb78c5c58 | ||
|
|
8aedac3474 | ||
|
|
1caf963323 | ||
|
|
bb94f872a9 | ||
|
|
ca133a20c0 | ||
|
|
acc601d414 | ||
|
|
e5d052a6bf | ||
|
|
2e05b25061 | ||
|
|
cf9d794fe1 | ||
|
|
14a3e7afb1 | ||
|
|
8aeb7a43c8 | ||
|
|
0ea4641536 | ||
|
|
4de32b8bf4 | ||
|
|
9d6447af9a | ||
|
|
7eb5f93595 | ||
|
|
3b54fa488e | ||
|
|
69e9cb3f22 | ||
|
|
4eb268c4af | ||
|
|
909b5b7f7f | ||
|
|
e2c28ab5a0 | ||
|
|
890d0a2099 | ||
|
|
74075e6be9 | ||
|
|
b8ae6aa889 | ||
|
|
a499e8593a | ||
|
|
08633c223e | ||
|
|
bc4699e354 | ||
|
|
c50b149e83 | ||
|
|
63252f4d35 | ||
|
|
1c024f881e | ||
|
|
93f0337399 | ||
|
|
7e8fb07f55 | ||
|
|
7a8856c34c | ||
|
|
63d516953a | ||
|
|
07faf6600f | ||
|
|
08e79d71bf | ||
|
|
9270119675 | ||
|
|
0058906022 | ||
|
|
6c836663f4 | ||
|
|
eeae26492e | ||
|
|
9e67a82816 | ||
|
|
c09295231c | ||
|
|
6c7d61c9f2 | ||
|
|
01f8a5c6d7 | ||
|
|
14d2a76211 | ||
|
|
7669000962 | ||
|
|
f11f88c71a | ||
|
|
8912911800 | ||
|
|
660be08eea | ||
|
|
62ecfaf54a | ||
|
|
6684177236 | ||
|
|
deca5cf55b | ||
|
|
769a9ac845 | ||
|
|
0f75797759 | ||
|
|
c194aefce5 | ||
|
|
f4798c8783 | ||
|
|
2178a5f10e | ||
|
|
f5e3945cf6 | ||
|
|
bb121cbee7 | ||
|
|
cee9adc782 | ||
|
|
bc145a56d5 | ||
|
|
476ef3bb2f | ||
|
|
460050289b | ||
|
|
0a2e9f6530 | ||
|
|
01fd4dcc68 | ||
|
|
0392eb3b7e | ||
|
|
038a21556e | ||
|
|
493f423a2f | ||
|
|
cbcfa1bbfb | ||
|
|
17a3ff15db | ||
|
|
9c14cccc98 | ||
|
|
57539775e0 | ||
|
|
eb71a20a19 | ||
|
|
850cfbe755 | ||
|
|
28afa6a9e8 | ||
|
|
7a76d95ce7 | ||
|
|
54707d0618 | ||
|
|
307c400e28 | ||
|
|
5c9b3ab25d | ||
|
|
532e991fb2 | ||
|
|
b1bf817329 | ||
|
|
c091f90487 | ||
|
|
a49d4715ff | ||
|
|
652b15532e | ||
|
|
e4064897b0 | ||
|
|
f9ca8222da | ||
|
|
67480a945f | ||
|
|
e6e811e6e6 | ||
|
|
4635c531b9 | ||
|
|
3bdfac9a46 | ||
|
|
2b7a71cb1c | ||
|
|
d47a500a0e | ||
|
|
33e6dbb4c1 | ||
|
|
482c57dd2e | ||
|
|
503c62d78d | ||
|
|
708d0ab6d3 | ||
|
|
19727542bd | ||
|
|
c4e6714a95 | ||
|
|
c116e612c6 | ||
|
|
215a055ce6 | ||
|
|
9c0b6b8d26 | ||
|
|
5c4462ee94 | ||
|
|
04edd6f9e2 | ||
|
|
52821cc051 | ||
|
|
0029deb029 | ||
|
|
c6360e2a36 | ||
|
|
2e77c647b6 | ||
|
|
ee28cf554a | ||
|
|
30dcb9a4da | ||
|
|
ffc9fdfa6d | ||
|
|
c3d3b19788 | ||
|
|
219cd61beb | ||
|
|
207e5a9142 | ||
|
|
4f86c6f322 | ||
|
|
c721fb534d | ||
|
|
dba2622fd7 | ||
|
|
33c8ecd908 | ||
|
|
93367fb0e8 | ||
|
|
694f74be13 | ||
|
|
79d097b17c | ||
|
|
7ef30653bb | ||
|
|
1ecb13f7fc | ||
|
|
da68675133 | ||
|
|
9aea5a7daf | ||
|
|
d19878edf6 | ||
|
|
4f98d1e054 | ||
|
|
7b8e07aef3 | ||
|
|
10402575fb | ||
|
|
0f82ade57c | ||
|
|
450b041118 | ||
|
|
770c349ac4 | ||
|
|
f76648b6f2 | ||
|
|
56e60667db | ||
|
|
1442bf5c34 | ||
|
|
2ac37f6c4d | ||
|
|
9795dce227 | ||
|
|
c4a60951c5 | ||
|
|
814eee8125 | ||
|
|
2a9ff3bfbd | ||
|
|
83350cb0db | ||
|
|
778761dbee | ||
|
|
e9881b748a | ||
|
|
d9cf802a9e | ||
|
|
dabaeefa23 | ||
|
|
0e0bec2712 | ||
|
|
48fe160334 | ||
|
|
7d599e12d0 | ||
|
|
3fbf2595cc | ||
|
|
6665285253 | ||
|
|
61ae29b745 | ||
|
|
a17bf5eeeb | ||
|
|
c71d91a46d | ||
|
|
c86103fd31 | ||
|
|
5190bbe723 | ||
|
|
3663ce2555 | ||
|
|
b5fc52d9b1 | ||
|
|
ca79b70815 | ||
|
|
898c956f17 | ||
|
|
2ce48c9dff | ||
|
|
f64ec12a6a | ||
|
|
474d3f3b55 | ||
|
|
c87e6a391d | ||
|
|
192fd4dba7 | ||
|
|
c26786c644 | ||
|
|
ebb0277d80 | ||
|
|
2a73efa479 | ||
|
|
6e68d22d4a | ||
|
|
dee08e6572 | ||
|
|
2383686e42 | ||
|
|
b8de9c415e | ||
|
|
f0269a3638 | ||
|
|
dbbbd309dc | ||
|
|
b7a905ad79 | ||
|
|
60c8049459 | ||
|
|
8c395b6fee | ||
|
|
e9935a41e3 | ||
|
|
f0ecd4d50d | ||
|
|
c0661022ab | ||
|
|
e7305a3dfb | ||
|
|
86f52f176a | ||
|
|
beb9796e75 | ||
|
|
6bb55adebc | ||
|
|
011bc85d18 | ||
|
|
fad75c498b | ||
|
|
915c69b443 | ||
|
|
05b574543c | ||
|
|
5198b2a709 | ||
|
|
509973a027 | ||
|
|
0253475f50 | ||
|
|
6961c92c8d | ||
|
|
906d7b361d | ||
|
|
54121199b6 | ||
|
|
78b3e0a1aa | ||
|
|
aa45795944 | ||
|
|
353209c72c | ||
|
|
d07eaefdd4 | ||
|
|
2ead9f6f02 | ||
|
|
472a349709 | ||
|
|
9043520364 | ||
|
|
88ea77e2f3 | ||
|
|
a609e2d561 | ||
|
|
6f1c791df4 | ||
|
|
dc41e7b50f | ||
|
|
1b22da8bd9 | ||
|
|
773eb9e1c3 | ||
|
|
87deea9748 | ||
|
|
556636f41e | ||
|
|
daab3dd3dd | ||
|
|
5535390298 | ||
|
|
f54eaf3101 | ||
|
|
1d86ace385 | ||
|
|
4a02a0a67d | ||
|
|
7f193c11e1 | ||
|
|
9f90a08276 | ||
|
|
f49a114f0f | ||
|
|
281fc300a6 | ||
|
|
ea7078b749 | ||
|
|
03aabb55ca | ||
|
|
078da5b213 | ||
|
|
22af77c7e6 | ||
|
|
7ee7a6624f | ||
|
|
85c9fcd28e | ||
|
|
619da2e19a | ||
|
|
c457cdfe5e | ||
|
|
a87c319d10 | ||
|
|
db5bdb0ef1 | ||
|
|
adc79a34d1 | ||
|
|
8776dffed4 | ||
|
|
77f5434b78 | ||
|
|
0191373ff5 | ||
|
|
0daf995c70 | ||
|
|
dd9437c663 | ||
|
|
752675ffb0 | ||
|
|
5bcc0fb343 | ||
|
|
2cd726c003 | ||
|
|
f911ad57b9 | ||
|
|
bc2a547b86 | ||
|
|
d5ba9bc3f5 | ||
|
|
3dc8493b76 | ||
|
|
0b991c4ae3 | ||
|
|
1352508070 | ||
|
|
87d467ec67 | ||
|
|
c020deb728 | ||
|
|
d5e15f7bf2 | ||
|
|
59622a1bfb | ||
|
|
1c237503a0 | ||
|
|
138a83c844 | ||
|
|
e8c86f4b4e | ||
|
|
344d2ae3e6 | ||
|
|
19a571147b | ||
|
|
2f369fb6ee | ||
|
|
c1d16f5185 | ||
|
|
2382895a42 | ||
|
|
68adae082b | ||
|
|
eac1b573c9 | ||
|
|
71024481f4 | ||
|
|
7c191981bd | ||
|
|
0be9ac9f59 | ||
|
|
c69f1e6adc | ||
|
|
a26a07337a | ||
|
|
a29a17a28b | ||
|
|
4805659a68 | ||
|
|
fbdcfb20ed | ||
|
|
4a2b186ef7 | ||
|
|
91f9af1bed | ||
|
|
b32c2e1274 | ||
|
|
400f764054 | ||
|
|
5b6900b74a | ||
|
|
05d0adc947 | ||
|
|
fa41b30a4c | ||
|
|
505282986e | ||
|
|
9e6e74db7c | ||
|
|
cf68e88103 | ||
|
|
84ae73d0d1 | ||
|
|
9bb0f13793 | ||
|
|
912485067b | ||
|
|
128f7c15a6 | ||
|
|
24c2ac116a | ||
|
|
4f558d36e6 | ||
|
|
5d67d0fdfc | ||
|
|
38218e4001 | ||
|
|
3f90d19801 | ||
|
|
bd8e533bbd | ||
|
|
52b756c33d | ||
|
|
91ce0d9eab | ||
|
|
17ea2bb80f | ||
|
|
e76b047ed3 | ||
|
|
33be35f27b | ||
|
|
ea73382ea3 | ||
|
|
897e1651c5 | ||
|
|
9c5bb2fcdb | ||
|
|
8ee8d84c8b | ||
|
|
b25fbf42ab | ||
|
|
f9f3392901 | ||
|
|
35249f5804 | ||
|
|
b32fdeda9c | ||
|
|
1d033701ed | ||
|
|
6422cffde3 | ||
|
|
e8588370e5 | ||
|
|
a96692e5cf | ||
|
|
81c272778f | ||
|
|
31351116b5 | ||
|
|
fd18e4d7f1 | ||
|
|
7eb5364ba7 | ||
|
|
97b679bbe0 | ||
|
|
85dc3ad1d7 | ||
|
|
a90e9544be | ||
|
|
6261163728 | ||
|
|
9288ae8776 | ||
|
|
f887f678f1 | ||
|
|
59ba74606e | ||
|
|
130b1c99db | ||
|
|
adc4b424c5 | ||
|
|
4ad140f7a3 | ||
|
|
65ab0f48e4 |
No files matched your search
@@ -2,6 +2,9 @@
|
||||
- Rebuilt Pokémon AI to use Minecraft's Brain system, allowing for more complex behaviours and interactions.
|
||||
- As an early pass of this, pastured Pokémon will now sleep when appropriate, and may come up to you when they see you.
|
||||
- Probably also added a whole bunch of bugs.
|
||||
- Dog Pokémon (Growlithe, Arcanine, etc.) intimidate Skeletons.
|
||||
- Cat Pokémon (Meowth, Persian, etc.) intimidate Creepers and Phantoms.
|
||||
- Sleep-related Pokémon (Munsharna, Komala, etc.) intimidate Phantoms.
|
||||
- Added a Behaviour Editor to the NPC editing screen.
|
||||
- Added /behaviouredit command for opening the Behaviour Editor on Pokémon and NPCs.
|
||||
- Editing variables for Pokémon is not yet supported.
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
### Additions
|
||||
- Added the Campfire Pot, made from apricorns and placed onto campfires.
|
||||
- This pot can be used to make bait for fishing, Poké Cakes, Lure Cakes, local specialties, and potions (less efficiently than a brewing stand).
|
||||
- There is a different pot for each apricorn colour because at this point I think we may have an addiction.
|
||||
- Added Aprijuice, made from the Campfire Pot using apricorns with seasoning to give flavours.
|
||||
- Aprijuice can be fed to ride-able Pokémon to improve their riding characteristics, depending on the flavour and the Pokémon's nature.
|
||||
- Added Lure Cakes, made from the Campfire Pot using honey and berries.
|
||||
- Lure Cakes can be used to modify the spawn rate of Pokémon in the wild.
|
||||
- Added the Saccharine Tree, which can be found in the wild and is used to obtain Honey Bottles.
|
||||
- The leaves of the tree can be harvested to obtain honey, which can be used in the Campfire Pot to make Lure Cakes.
|
||||
- The Log of the tree can be clicked on with honey to create a Honey Log, which increases the change of spawning a Pokemon with an Hidden Ability.
|
||||
- Clicking on the Progress Arrow will show the JEI Recipe Book for the Campfire Pot, which will show all recipes that can be made with it.
|
||||
- Added a Ton of Redstone Compatibility.
|
||||
- Dispenser can now Honey and Unhoney:
|
||||
- Saccharine Log
|
||||
- Saccharine Leaves
|
||||
- Redstone can Close and Open the Lid of a Cooking Pot
|
||||
- Powered = Closed
|
||||
- Unpowered = Open
|
||||
- Hoppers can be used to insert items into a Cooking pot
|
||||
- Top = Seasonals
|
||||
- All Sides = Crafting
|
||||
- Bottom = Extract the Result
|
||||
- Observer will recognise when a Cooking pot is Closed or Opened
|
||||
- Comparator Calculates a Signal Strength depending on the items inside the cooking pot
|
||||
- Sculk Sensor
|
||||
- Saccharine Leaves
|
||||
- Opening and Closing the Cooking Pot
|
||||
- Saccharine Log
|
||||
|
||||
### Datapack and Addon Changes
|
||||
- Renamed the fishing_baits datapack folder to spawn_bait_effects.
|
||||
- Added `seasonings` datapack folder for controlling usable items in the campfire pot and what colour and flavour they apply.
|
||||
- Added campfire pot recipe type, which you could use to make anything work as fishing bait.
|
||||
@@ -6,6 +6,8 @@
|
||||
- Added filter functionality in PC UI, which supports `PokemonProperties` (e.g. `shiny=yes` shows all shiny Pokémon).
|
||||
- Added `/changewallpaper <player> <boxNumber> <wallpaper>` command to change a box wallpaper through commands.
|
||||
- Added `/renamebox <player> <boxNumber> <name>` command to rename a PC box through commands.
|
||||
- Added IVs and EVs stat displays in PC.
|
||||
- improved filter by Name, now is available search by exact names or partial matches, for example "cha" will show Charmander, Charmeleon and Charizard among others that match.
|
||||
|
||||
### Developer
|
||||
- Added `RenamePCBoxEvent.Pre` and `RenamePCBoxEvent.Post` events to prevent players from renaming a box or changing their input.
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
### Additions
|
||||
- Pokémon can now spawn in herds, either as distinct herd groupings or simply several Pokémon spawning at once.
|
||||
|
||||
### Fixes
|
||||
- Fixed the "enabled" property in spawn files not actually being respected. Where do they find these devs?
|
||||
|
||||
### Developer
|
||||
- Spawning Influences now have the context of what the other buckets are when adjusting bucket weights. This will break existing influences that do bucket weight adjustment.
|
||||
- Renamed heaps of things in the spawning system to make more sense.
|
||||
- SpawningContext is now SpawnablePosition
|
||||
- WorldSlice is SpawningZone
|
||||
- SpawningProspector is now SpawningZoneGenerator
|
||||
- Renamed things in Spawn Rules to go with the other renames:
|
||||
- contextSelector is now spawnablePositionSelector
|
||||
- context is now spawnable_position
|
||||
+132
-5
@@ -19,6 +19,17 @@
|
||||
- The player executing the command must be facing the target pokemon entity. Transformations are not persistent and will revert when resources are reloaded.
|
||||
- Added lang keys for all moves and abilities up to Generation 9.
|
||||
- Fixed Moon Ball moon phase logic to actually work correctly
|
||||
- Added `translucent_cull` boolean option into resolver's layer to allow for translucent textures with culling
|
||||
- Added [LambDynamicLights](https://modrinth.com/mod/lambdynamiclights) support for items held by Pokémon.
|
||||
- Added the Clear Amulet, Grip Claw, Lagging Tail, Luminous Moss, Metal Alloy, Scroll of Darkness, Scroll of Waters
|
||||
- Added Recipes for Masterpiece Cup, Eject Pack
|
||||
- Added modification to Minecraft Creative Inventory search to account for item names that contain `poké` when input contains `poke`.
|
||||
- Added Campfire Pot as well as loads of new food items (Poke Puffs, Ponigiri, Sinister Tea, etc)
|
||||
- Added Hearty Grains, a new crop used in the new cooking mechanic
|
||||
- Added Tatami blocks and Tatami Mat blocks, made from Hearty Grain, for decorating builds
|
||||
- Added `/pcsearch <player> <pokemonProperties>` command that searches for a specific Pokémon within a player's PC.
|
||||
- Added `/pctake <player> <box> <slot>` command that takes a specific Pokémon from a player's PC. Removes the pokemon if target is self or ran from the server.
|
||||
- Added Hyper Training items (IV Modification) as well as some additional candy items to do so (Health Candy, Sickly Candy)
|
||||
|
||||
### Pokémon Added
|
||||
|
||||
@@ -30,12 +41,17 @@
|
||||
- Grumpig
|
||||
- Snorunt
|
||||
- Glalie
|
||||
- Latias
|
||||
- Latios
|
||||
|
||||
#### Gen 4
|
||||
- Bronzor
|
||||
- Bronzong
|
||||
- Croagunk
|
||||
- Toxicroak
|
||||
- Froslass
|
||||
- Glameow
|
||||
- Purugly
|
||||
|
||||
#### Gen 5
|
||||
- Pansage
|
||||
@@ -48,10 +64,22 @@
|
||||
- Musharna
|
||||
- Blitzle
|
||||
- Zebstrika
|
||||
- Drilbur
|
||||
- Excadrill
|
||||
- Trubbish
|
||||
- Garbodor
|
||||
- Gothita
|
||||
- Gothorita
|
||||
- Gothitelle
|
||||
- Solosis
|
||||
- Duosion
|
||||
- Reuniclus
|
||||
|
||||
#### Gen 6
|
||||
- Inkay
|
||||
- Malamar
|
||||
- Hawlucha
|
||||
- Dedenne
|
||||
- Noibat
|
||||
- Noivern
|
||||
|
||||
@@ -61,13 +89,20 @@
|
||||
#### Gen 8
|
||||
- Silicobra
|
||||
- Sandaconda
|
||||
- Sinistea
|
||||
- Polteageist
|
||||
|
||||
#### Gen 9
|
||||
- Smoliv
|
||||
- Dolliv
|
||||
- Arboliva
|
||||
- Tarountula
|
||||
- Spidops
|
||||
- Orthworm
|
||||
- Dudunsparce
|
||||
- Cyclizar
|
||||
- Poltchageist
|
||||
- Sinistcha
|
||||
|
||||
### Animation updates for the following Pokémon
|
||||
- Garchomp
|
||||
@@ -80,6 +115,15 @@
|
||||
- Delphox
|
||||
- Cinderace
|
||||
- Kangaskhan
|
||||
- Gossifleur
|
||||
- Eldegoss
|
||||
- Stonjourner
|
||||
- Wailmer
|
||||
- Lechonk
|
||||
- Oinkologne
|
||||
- Dratini
|
||||
- Dragonair
|
||||
- Dragonite
|
||||
|
||||
### Model updates for the following Pokémon
|
||||
- Gyarados
|
||||
@@ -97,27 +141,52 @@
|
||||
- Grovyle
|
||||
- Sceptile
|
||||
- Honchkrow
|
||||
- Gible
|
||||
- Gabite
|
||||
- Garchomp
|
||||
- Pidgeot
|
||||
- Nosepass
|
||||
- Probopass
|
||||
- Kangaskhan
|
||||
- Cinderace
|
||||
- Magnemite
|
||||
- Magneton
|
||||
- Magnezone
|
||||
- Beldum
|
||||
- Metang
|
||||
- Metagross
|
||||
- Hoothoot
|
||||
- Noctowl
|
||||
- Teddiursa
|
||||
- Ursaring
|
||||
- Ursaluna
|
||||
- Heatmor
|
||||
- Bouffalant
|
||||
- Sigilyph
|
||||
- Sharpedo
|
||||
- Maractus
|
||||
- Clodsire
|
||||
- Scyther
|
||||
- Scizor
|
||||
- Cacturne
|
||||
- Taillow
|
||||
- Swellow
|
||||
- Added Syrupy Apples.
|
||||
- Seel
|
||||
- Dewgong
|
||||
|
||||
### Changes
|
||||
- Renamed `chargeGainedPerTick` config to `secondsToChargeHealingMachine`.
|
||||
- Made Blocks of Gold count as Big Nuggets when held by a Pokémon (for Fling functionality)
|
||||
- Players can now eat Sweet and Tart Apples, Whipped Dreams, and the Alcremie Sweets.
|
||||
- Updated Sweet and Tart Apple sprites
|
||||
- Updated the following recipes: Air Balloon, Assault Vest, Binding Band, Black Belt, Blunder Policy, Choice Band, Choice Scarf, Cleanse Tag, Covert Cloak, Destiny Knot, Eject Button, Expert Belt, Focus Band, Focus Sash, Magnet, Metronome, Muscle Band, Power Anklet, Power Band, Power Belt, Power Bracer, Power Lens, Power Weight, Protective Pads, Protein, Punching Glove, Reaper Cloth, Rocky Helmet, Room Service, Sachet, Safety Goggles, Silk Scarf, Spell Tag, Utility Umbrella, Weakness Policy, Zinc
|
||||
- Added alternate ingredient options to the following recipes: Cell Battery, Charcoal Stick, Dragon Fang, Miracle Seed, Mystic Water, Never Melt Ice, Twisted Spoon, Damp Rock, Heat Rock, Icy Rock, Smooth Rock
|
||||
- Updated the following recipes: Air Balloon, Assault Vest, Binding Band, Black Belt, Blunder Policy, Choice Band, Choice Scarf, Cleanse Tag, Covert Cloak, Destiny Knot, Eject Button, Expert Belt, Focus Band, Focus Sash, Magnet, Metronome, Muscle Band, Power Anklet, Power Band, Power Belt, Power Bracer, Power Lens, Power Weight, Protective Pads, Protein, Punching Glove, Reaper Cloth, Rocky Helmet, Room Service, Sachet, Safety Goggles, Silk Scarf, Spell Tag, Utility Umbrella, Weakness Policy, Zinc, Chipped Pot, Cracked Pot, Unremarkable Cup, Loaded Dice, Charcoal Stick, Dragon Fang, Miracle Seed, Mystic Water, Never Melt Ice, Twisted Spoon, Black Glasses, Fairy Feather, Hard Stone, Silver Powder, Soft Sand
|
||||
- Added alternate ingredient options to the following recipes: Cell Battery, Damp Rock, Heat Rock, Icy Rock, Smooth Rock
|
||||
- Grouped together some recipes within the Recipe Book. Groups include: the seven basic Poké Balls, the seven basic Ancient Poké Balls, Gilded Chests, Pokedexes, and the Weather Rocks.
|
||||
- Updated some item tags to better integrate behaviours between Cobblemon, Vanilla Minecraft, and other mods
|
||||
- Removed Cooked Meat, Raw Meat, Protein Ingredients, and Zinc Ingredients, the first two are now using `c` namespace tags, the latter have better integrated use of tags within their recipes which removes need for custom tags.
|
||||
- Added our seeds tag into `#c:seeds`, which is now made use of for the Miracle Seed recipe.
|
||||
- Added our seeds tag into `#c:seeds`, which is now made use of for the Miracle Seed recipe.
|
||||
- Added herbs and snowballs to the consumable in PvE and Wild battle tags
|
||||
- Tweaked the Natural Materials Vanilla file to fit with the changes to tags
|
||||
- Substantially optimised spawning checks mainly by front-loading biome filtering.
|
||||
- When using the `cobblemon` or `generation_9` capture calculators a critical capture with a single shake will always play for successful captures when you've already registered the Pokémon as caught in your Pokédex.
|
||||
@@ -127,6 +196,23 @@
|
||||
- Shulker shell Forretress is now a cosmetic rather than a special evo and thus all shulker Forretress will revert back to normal until a shulker shell is put in their cosmetic slot.
|
||||
- Updated `doPokemonSpawning` gamerule to support per-dimension configurations.
|
||||
- The Pokedex now displays a form name of a "normal" Pokémon for when the base form is still a named form.
|
||||
- Improved the zoom functionality of the Pokédex Scanner by giving the levels logarithmic scaling.
|
||||
- Added a subtle rotation effect to the Pokédex Scanner's wheel when zooming.
|
||||
- Improved parity with vanilla mobs' drop behavior; loot and XP drop on death instead of after the entire death sequence finishes.
|
||||
- Quirk animations no longer play in the battle GUI since they were pretty distracting.
|
||||
- A number of Pokemon that float above the ground visually (Gastly, Klingklang, etc.) are no longer considered to be touching the ground
|
||||
- Changed the recipes for Level, Lure, and Moon Balls to be cleaner
|
||||
- Renamed `pokemonId` and `type` to `species` in relevant Advancement triggers for conformity, this is a breaking change.
|
||||
- Added a separate `species` argument to the `pick_starter`, `pasture_use` and `resurrect_pokemon` Advancement triggers.
|
||||
- Made `CobblemonAgingDespawner` thresholds configurable via the config file.
|
||||
- Tweaked Berry flavor data to balance cooking pot mechanics
|
||||
- Made Red, Yellow, Green, Blue, Pink, Black, and White Apricorn Sprout and Saccharine Sapling able to be placed into flower pots.
|
||||
- Added all Potted Apricorn Sprouts, Potted Saccharine Saplings, and Potted Pep-Up Flowers to the `#minecraft:flower_pots` block tag
|
||||
- Corrected the healing values of the remedies and energy root, and reintroduced the friendship lowering mechanics for them, revivl herb, and heal powder
|
||||
- Updated battle language keys for side effects to use position-specific formats, improving grammatical consistency
|
||||
- Saccharine Leaves are now Collectable
|
||||
- Saccharine Leaves Age 1 or higher will now show Yellow particles when broken
|
||||
- Destroying a Saccharine Honey Log will now drop a Saccharine Log in stead of nothing
|
||||
|
||||
### Fixes
|
||||
- Fixed Particles sometimes facing the wrong direction (looking at you, Swords Dance)
|
||||
@@ -156,8 +242,27 @@
|
||||
- Fixed an issue with newer versions of Fabric API where underground Pokémon were spawning in The End.
|
||||
- Fixed spawning not working well when you're at high points surrounded by lower altitude spawning areas, such as flying.
|
||||
- Fixed certain Pokémon with forms not having appropriate stock Pokédex entries.
|
||||
- Fixed issue with Pokédex Scanner that caused the open/close overlay to have the wrong opacity values
|
||||
- Fixed dragon's breath not being usable on the restoration tank when it should be
|
||||
- Fixed Moon Stones not interacting properly with dripstone blocks.
|
||||
- Fixed some effects like particles from fishing rods appearing for players in the same coordinates in another world.
|
||||
- Fixed an issue with Sketch where the Pokémon using Sketch would not properly learn moves with special characters in their name (e.g. King's Shield, Baby-Doll Eyes, etc.)
|
||||
- Fixed wild Pokémon sometimes spawning with incorrect friendship values
|
||||
- Fixed typo while saving/loading NPCEntity causes data loss
|
||||
- Fixed an issue where catching a Pokémon while it was leashed to a fence would not update the fence.
|
||||
- Fixed the `dimensions` spawning condition using the incorrect ResourceLocation, causing it to not function properly.
|
||||
- Fix issue where locator X axis was not aligned with blockbench.
|
||||
- Fix issue where particle effects that play on frame 1 on sendout would never play (Gastly)
|
||||
- The Wiglett line will now sink in water again.
|
||||
- Fixed the Sprigatito line's portraits being zoomed in too far.
|
||||
- Fixed Floragato's battle cry animation from breaking.
|
||||
- Fixed the block texture name for the Pep-Up Flower being inaccurate
|
||||
- Fixed issue where the restoration tank would not accept valid items from a hopper.
|
||||
- Fixed energy root not being shearable
|
||||
- Fixed energy root always spreading into more energy roots instead of by chance (same as big root)
|
||||
- Fixed issue where Pokémon spawned by the "spawnallpokemon" command potentially receiving a raft.
|
||||
- Fixed logspam on NeoForge when adorn is not installed
|
||||
- Fixed Cobblemon crashing if it tries to load a bedrock model not meant for cobblemon (example: Qlipoth Awakening)
|
||||
|
||||
### Developer
|
||||
- A finished battle now has winners and losers set inside of `PokemonBattle` instead of them always being empty.
|
||||
@@ -176,7 +281,19 @@
|
||||
- Updated NPCEntity pokeball throw positioning to properly account for the baseScale property.
|
||||
- Fixed `[Pokemon].copyFrom` error causing forms, IVs, and EVs to not be applied properly when using `[Pokemon].loadFromJSON` or `[Pokemon].loadFromNBT`
|
||||
- Added new item class, `WearableItem`. Instances of this class should have a corresponding 3D model. These models render when the items display context is `HEAD`.
|
||||
|
||||
- Pokemon now have a fireImmune attribute in their behaviour that can be set to true to ignore all fire damage (lava, magma blocks, etc.)
|
||||
`JSON
|
||||
{
|
||||
"behaviour": {
|
||||
"fireImmune": true
|
||||
}
|
||||
}
|
||||
`
|
||||
- The IVs class has now been extended to include Hyper Trained values.
|
||||
- Added `Pokemon#hyperTrainIV()` and `IVs#setHyperTrainedIV(Stat, Int)`.
|
||||
- Added `HyperTrainedIvEvent.Pre` and `HyperTrainedIvEvent.Post`.
|
||||
- Added a `hoverText` option to PartySelectCallback, to display a tooltip on hovering over a Pokémon in the selection screen.
|
||||
|
||||
### MoLang & Datapacks
|
||||
- The following usages for item predicates can now use item conditions like advancements do, you can learn about them in the [Minecraft wiki](https://minecraft.wiki/w/Advancement_definition#minecraft:filled_bucket)
|
||||
- The `requiredContext` for an item interaction evolution
|
||||
@@ -195,6 +312,15 @@
|
||||
- Fixed `heldItem` property inside spawn files not working and causing crashes
|
||||
- Fixed `spawn_bedrock_particles` MoLang causing crashes when used in a server environment
|
||||
- The Pokédex form lang key definition now follows `cobblemon.ui.pokedex.info.form.{species}-{formname}` instead of `cobblemon.ui.pokedex.info.form.{formname}`.
|
||||
- Added `play_sound_on_server` as an available Molang function for the `worldHolder` & `player` functions.
|
||||
- Added `run_molang_after` as an available Molang function for the `entity` functions when schedulable.
|
||||
- Added an optional parameter for `run_molang` to schedule the function.
|
||||
- Added `labels` & `has_label` as available Molang functions for the `speciesFunctions`
|
||||
- Added datapack-defined starter categories via `data/<namespace>/starters/*.json`, with built-in fallback and `useConfigStarters` merge option.
|
||||
- The format of the `remedies.json` file has changed to allow for individual friendshipDrop amounts per remedy
|
||||
- Fixed `entity.find_nearby_block` causing crashes when attempting to use a block tag
|
||||
- Spawn Filters can now access `v.spawn.class` to get the identifier of an NPC class for when trying to influence NPC spawns
|
||||
- Added `pokemon.hyper_train_iv` as an available Molang function.
|
||||
|
||||
## [1.6.1 (January 26th, 2025)](#1-6-1)
|
||||
|
||||
@@ -1009,6 +1135,7 @@
|
||||
}
|
||||
`
|
||||
- Added support for custom stashes, similar to Gimmighoul's coin and scrap stashes.
|
||||
- Added the ability to create custom brewing stand recipes.
|
||||
|
||||
### Localization
|
||||
- Updated translations for:
|
||||
@@ -2316,4 +2443,4 @@ Thank you so much to all of our community translators that bring the mod to the
|
||||
- Added species, ability, and move translations for `ko_ko`, `jp_jp`, `fr_fr`, `es_es`, `it_it`, and `zh_cn`.
|
||||
|
||||
## [1.0.0 (November 12th, 2022)](#1-0-0)
|
||||
- Initial release.
|
||||
- Initial release.
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
import utilities.isSnapshot
|
||||
import utilities.version
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import utilities.isSnapshot
|
||||
import utilities.version
|
||||
|
||||
/*
|
||||
*
|
||||
|
||||
@@ -13,10 +13,12 @@ import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokemon.FormData;
|
||||
import com.cobblemon.mod.common.pokemon.lighthing.LightingData;
|
||||
import dev.lambdaurora.lambdynlights.LambDynLights;
|
||||
import dev.lambdaurora.lambdynlights.api.DynamicLightHandler;
|
||||
import dev.lambdaurora.lambdynlights.api.DynamicLightHandlers;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -53,15 +55,19 @@ public class LambDynamicLightsCompat {
|
||||
|
||||
private static int resolvedPokemonLightLevel(PokemonEntity pokemon) {
|
||||
var underwater = !pokemon.level().getFluidState(BlockPos.containing(pokemon.getX(), pokemon.getEyeY(), pokemon.getZ())).isEmpty();
|
||||
return extractFormLightLevel(pokemon.getForm(), underwater).orElse(0);
|
||||
|
||||
ItemStack item = pokemon.getShownItem();
|
||||
int itemLightLevel = item.isEmpty()?0:LambDynLights.getLuminanceFromItemStack(item, underwater);
|
||||
int formLightLevel = extractFormLightLevel(pokemon.getForm(), underwater).orElse(0);
|
||||
|
||||
return Math.max(itemLightLevel, formLightLevel);
|
||||
}
|
||||
|
||||
private static int resolvedShoulderLightLevel(Player player) {
|
||||
final var shoulderDataPair = PokemonOnShoulderRenderer.shoulderDataOf(player);
|
||||
var underwater = !player.level().getFluidState(BlockPos.containing(player.getX(), player.getEyeY(), player.getZ())).isEmpty();
|
||||
final Optional<Integer> leftLightLevel = extractShoulderLightLevel(shoulderDataPair.getFirst(), underwater);
|
||||
final Optional<Integer> rightLightLevel = extractShoulderLightLevel(shoulderDataPair.getSecond(), underwater);
|
||||
return Math.max(leftLightLevel.orElse(0), rightLightLevel.orElse(0));
|
||||
final int leftLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityLeft()), underwater);
|
||||
final int rightLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityRight()), underwater);
|
||||
return Math.max(leftLightLevel, rightLightLevel);
|
||||
}
|
||||
|
||||
private static Optional<Integer> extractFormLightLevel(@NotNull FormData form, boolean underwater) {
|
||||
@@ -71,11 +77,16 @@ public class LambDynamicLightsCompat {
|
||||
return Optional.of(form.getLightingData().getLightLevel());
|
||||
}
|
||||
|
||||
private static Optional<Integer> extractShoulderLightLevel(@Nullable PokemonOnShoulderRenderer.ShoulderData shoulderData, boolean underwater) {
|
||||
private static int extractShoulderLightLevel(@Nullable PokemonOnShoulderRenderer.ShoulderData shoulderData, boolean underwater) {
|
||||
if (shoulderData == null) {
|
||||
return Optional.empty();
|
||||
return 0;
|
||||
}
|
||||
return extractFormLightLevel(shoulderData.getForm(), underwater);
|
||||
|
||||
ItemStack item = shoulderData.getShownItem();
|
||||
int itemLightLevel = item.isEmpty()?0:LambDynLights.getLuminanceFromItemStack(item, underwater);
|
||||
int formLightLevel = extractFormLightLevel(shoulderData.getForm(), underwater).orElse(0);
|
||||
|
||||
return Math.max(itemLightLevel, formLightLevel);
|
||||
}
|
||||
|
||||
private static boolean liquidGlowModeSupport(@NotNull LightingData.LiquidGlowMode liquidGlowMode, boolean underwater) {
|
||||
|
||||
+7
@@ -6,3 +6,10 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.duck;
|
||||
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
|
||||
public interface RecipeAwareSlot {
|
||||
void setRecipeManager(RecipeManager recipeManager);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.block.SaccharineLeafBlock;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Desc;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.Slice;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
|
||||
@Mixin(targets = "net.minecraft.world.entity.animal.Bee$BeeGrowCropGoal")
|
||||
public abstract class BeeEntityMixin {
|
||||
|
||||
@Unique
|
||||
private BlockState cobblemon$result = null;
|
||||
|
||||
@Inject(method = "tick()V", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/BonemealableBlock;performBonemeal(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/util/RandomSource;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V",
|
||||
shift = At.Shift.BY,
|
||||
by = 2
|
||||
),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private void injectCustomGrowth(CallbackInfo ci, int i, BlockPos blockPos, BlockState blockState, Block block) {
|
||||
if (block instanceof SaccharineLeafBlock) {
|
||||
|
||||
int age = blockState.getValue(SaccharineLeafBlock.Companion.getAGE());
|
||||
|
||||
if (age < 2) {
|
||||
this.cobblemon$result = blockState.setValue(SaccharineLeafBlock.Companion.getAGE(), age + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "tick", at = @At(value = "LOAD", ordinal = 0), index = 5)
|
||||
private BlockState applyCustomBlockState(BlockState before) {
|
||||
if(this.cobblemon$result != null && before == null) {
|
||||
BlockState result = this.cobblemon$result;
|
||||
this.cobblemon$result = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
return before;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public class EntitySkeletonMixin extends Mob {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
@Inject(method = "registerGoals", at = @At(value = "TAIL"), cancellable = false)
|
||||
@Inject(method = "registerGoals", at = @At(value = "TAIL"))
|
||||
private void cobblemon$initGoals(CallbackInfo callbackInfo) {
|
||||
final AbstractSkeleton skeleton = (AbstractSkeleton) (Object) this;
|
||||
// Pokemon Entities
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(LocalPlayer.class)
|
||||
public abstract class LocalPlayerMixin {
|
||||
@Shadow
|
||||
private float jumpRidingScale;
|
||||
|
||||
@Inject(method = "getJumpRidingScale", at = @At("HEAD"), cancellable = true)
|
||||
public void modifyJumpRidingScale(CallbackInfoReturnable<Float> cir) {
|
||||
LocalPlayer player = (LocalPlayer) (Object) this;
|
||||
if (player.isPassenger() && player.getVehicle() instanceof PokemonEntity pokemonEntity) {
|
||||
var rideValue = pokemonEntity.<Float>ifRidingAvailableSupply(null, (behaviour, settings, state) -> {
|
||||
if (behaviour.canJump(settings, state, pokemonEntity, player)) return null;
|
||||
return behaviour.setRideBar(settings, state, pokemonEntity, player);
|
||||
});
|
||||
if (rideValue != null) {
|
||||
cir.setReturnValue(rideValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,9 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents;
|
||||
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent;
|
||||
import com.cobblemon.mod.common.api.orientation.OrientationController;
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies;
|
||||
import com.cobblemon.mod.common.api.riding.Seat;
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyStore;
|
||||
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore;
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate;
|
||||
import com.cobblemon.mod.common.client.render.MatrixWrapper;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.ScannableEntity;
|
||||
@@ -40,18 +37,16 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.*;
|
||||
import net.minecraft.world.entity.EntityDimensions;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.Pose;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.food.FoodProperties;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Vector3f;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -284,41 +279,4 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
|
||||
public OrientationController getOrientationController() {
|
||||
return cobblemon$orientationController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HitResult pick(double hitDistance, float partialTicks, boolean hitFluids) {
|
||||
Entity vehicle = this.getVehicle();
|
||||
if (vehicle instanceof PokemonEntity pokemonEntity) {
|
||||
int seatIndex = pokemonEntity.getPassengers().indexOf(this);
|
||||
Seat seat = pokemonEntity.getSeats().get(seatIndex);
|
||||
|
||||
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemonEntity.getDelegate();
|
||||
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
|
||||
|
||||
if (locator == null) {
|
||||
super.pick(hitDistance, partialTicks, hitFluids);
|
||||
}
|
||||
|
||||
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
|
||||
|
||||
OrientationController controller = this.getOrientationController();
|
||||
|
||||
float currEyeHeight = this.getEyeHeight();
|
||||
Matrix3f orientation = controller.isActive() && controller.getOrientation() != null ? controller.getOrientation() : new Matrix3f();
|
||||
Vec3 rotatedEyeHeight = new Vec3(orientation.transform(new Vector3f(0f, currEyeHeight - (this.getBbHeight() / 2), 0f)));
|
||||
|
||||
Vec3 eyePosition = locatorOffset.add(pokemonEntity.position()).add(rotatedEyeHeight);
|
||||
|
||||
Vec3 viewVector = this.getViewVector(partialTicks);
|
||||
Vec3 viewDistanceVector = eyePosition.add(viewVector.x * hitDistance, viewVector.y * hitDistance, viewVector.z * hitDistance);
|
||||
return this.level()
|
||||
.clip(
|
||||
new ClipContext(
|
||||
eyePosition, viewDistanceVector, ClipContext.Block.OUTLINE, hitFluids ? net.minecraft.world.level.ClipContext.Fluid.ANY : net.minecraft.world.level.ClipContext.Fluid.NONE, this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return super.pick(hitDistance, partialTicks, hitFluids);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import net.minecraft.stats.RecipeBookSettings;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(RecipeBookSettings.class)
|
||||
public class RecipeBookSettingsMixin {
|
||||
|
||||
|
||||
@Shadow @Final public Map<RecipeBookType, RecipeBookSettings.TypeSettings> states;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void cobblemon$init(CallbackInfo ci) {
|
||||
states.put(RecipeBookType.valueOf("COOKING_POT"), new RecipeBookSettings.TypeSettings(true, true));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(value = RecipeBookType.class)
|
||||
public class RecipeBookTypeMixin {
|
||||
|
||||
@Final
|
||||
@Mutable
|
||||
@Shadow
|
||||
private static RecipeBookType[] $VALUES; // moj
|
||||
|
||||
@Invoker("<init>")
|
||||
private static RecipeBookType cobblemon$createBookType(String name, int ordinal) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "<clinit>",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
|
||||
ArrayList<RecipeBookType> types = new ArrayList<>(List.of($VALUES));
|
||||
types.add(cobblemon$createBookType("COOKING_POT", $VALUES.length));
|
||||
$VALUES = types.toArray(RecipeBookType[]::new);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.world.CobblemonStructureIDs;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.StructurePiece;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Mixin(Structure.class)
|
||||
public abstract class StructureMixin {
|
||||
// Define a set of structures that should not spawn below Sea Level
|
||||
@Unique
|
||||
private static final Set<ResourceLocation> RESTRICTED_STRUCTURES = new HashSet<>(Arrays.asList(
|
||||
CobblemonStructureIDs.STONJOURNER_HENGE,
|
||||
CobblemonStructureIDs.LUNA_HENGE,
|
||||
CobblemonStructureIDs.SOL_HENGE
|
||||
));
|
||||
|
||||
@Inject(method = "generate", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/structure/StructureStart;isValid()Z"),
|
||||
cancellable = true)
|
||||
public void cobblemon$isValid(RegistryAccess registryAccess, ChunkGenerator chunkGenerator, BiomeSource biomeSource,
|
||||
RandomState randomState, StructureTemplateManager structureTemplateManager, long seed,
|
||||
ChunkPos chunkPos, int references, LevelHeightAccessor heightAccessor,
|
||||
Predicate<Holder<Biome>> validBiome,
|
||||
CallbackInfoReturnable<StructureStart> cir,
|
||||
@Local StructureStart structureStart) {
|
||||
ResourceLocation structureKey = registryAccess.registryOrThrow(Registries.STRUCTURE).getKey((Structure) (Object) this);
|
||||
if(!RESTRICTED_STRUCTURES.contains(structureKey)) {
|
||||
return;
|
||||
}
|
||||
for (StructurePiece piece : structureStart.getPieces()) {
|
||||
if (piece.getBoundingBox().minY() < chunkGenerator.getSeaLevel()) {
|
||||
cir.setReturnValue(StructureStart.INVALID_START);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.accessor;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(Camera.class)
|
||||
public interface CameraAccessor {
|
||||
@Accessor("level")
|
||||
BlockGetter getLevel();
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.accessor;
|
||||
|
||||
import net.minecraft.client.gui.components.StateSwitchingButton;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(RecipeBookComponent.class)
|
||||
public interface RecipeBookComponentAccessor {
|
||||
@Accessor("filterButton")
|
||||
StateSwitchingButton getFilterButton();
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.brewing;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonRecipeTypes;
|
||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandInput;
|
||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.Containers;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.alchemy.PotionBrewing;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.LevelEvent;
|
||||
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@Mixin(BrewingStandBlockEntity.class)
|
||||
public class BrewingStandBlockEntityMixin {
|
||||
|
||||
@WrapOperation(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BrewingStandBlockEntity;doBrew(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/NonNullList;)V"))
|
||||
private static void cobblemon$doBrew(Level level, BlockPos pos, NonNullList<ItemStack> slots, Operation<Void> original) {
|
||||
var recipe = cobblemon$fetchBrewingRecipe(slots, level);
|
||||
if(recipe == null) {
|
||||
original.call(level, pos, slots);
|
||||
return;
|
||||
}
|
||||
//copied from vanilla doBrew logic, but slightly tweaked to work for cobblemon, this was needed as replacing the loop was not quite possible inside doBrew
|
||||
ItemStack itemStack = slots.get(3);
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
slots.set(i, recipe.getResult().copy());
|
||||
}
|
||||
|
||||
itemStack.shrink(1);
|
||||
if (itemStack.getItem().hasCraftingRemainingItem()) {
|
||||
ItemStack itemStack2 = new ItemStack(itemStack.getItem().getCraftingRemainingItem());
|
||||
if (itemStack.isEmpty()) {
|
||||
itemStack = itemStack2;
|
||||
} else {
|
||||
Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), itemStack2);
|
||||
}
|
||||
}
|
||||
|
||||
slots.set(3, itemStack);
|
||||
level.levelEvent(LevelEvent.SOUND_BREWING_STAND_BREW, pos, 0);
|
||||
}
|
||||
|
||||
@WrapOperation(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BrewingStandBlockEntity;isBrewable(Lnet/minecraft/world/item/alchemy/PotionBrewing;Lnet/minecraft/core/NonNullList;)Z"))
|
||||
private static boolean cobblemon$isBrewable(PotionBrewing potionBrewing, NonNullList<ItemStack> items, Operation<Boolean> original,
|
||||
@Local(argsOnly = true) Level level) {
|
||||
return cobblemon$fetchBrewingRecipe(items, level) != null || original.call(potionBrewing, items);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static BrewingStandRecipe cobblemon$fetchBrewingRecipe(NonNullList<ItemStack> items, Level level) {
|
||||
ItemStack ingredient = items.get(3);
|
||||
List<ItemStack> bottles = items.subList(0, 3);
|
||||
|
||||
boolean allBottlesEmpty = true;
|
||||
for (ItemStack bottle : bottles) {
|
||||
if (!bottle.isEmpty()) {
|
||||
allBottlesEmpty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ingredient.isEmpty() || allBottlesEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BrewingStandInput input = new BrewingStandInput(ingredient, bottles);
|
||||
RecipeManager recipeManager = level.getRecipeManager();
|
||||
|
||||
Optional<RecipeHolder<BrewingStandRecipe>> recipeHolder =
|
||||
recipeManager.getRecipeFor(CobblemonRecipeTypes.INSTANCE.getBREWING_STAND(), input, level);
|
||||
|
||||
return recipeHolder.map(RecipeHolder::value).orElse(null);
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.brewing;
|
||||
|
||||
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
|
||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.BrewingStandMenu;
|
||||
import net.minecraft.world.inventory.ContainerData;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(BrewingStandMenu.class)
|
||||
public abstract class BrewingStandMenuMixin {
|
||||
|
||||
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/Container;Lnet/minecraft/world/inventory/ContainerData;)V", at = @At("TAIL"))
|
||||
private void captureLevel(int containerId, Inventory playerInventory, Container brewingStandContainer, ContainerData brewingStandData, CallbackInfo ci) {
|
||||
var recipeManager = playerInventory.player.level().getRecipeManager();
|
||||
for (Slot slot : ((BrewingStandMenu) (Object) this).slots) {
|
||||
if (slot instanceof RecipeAwareSlot awareSlot) {
|
||||
awareSlot.setRecipeManager(recipeManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@WrapOperation(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/BrewingStandMenu$PotionSlot;mayPlaceItem(Lnet/minecraft/world/item/ItemStack;)Z"))
|
||||
private boolean cobblemon$isPotionBottle(ItemStack stack, Operation<Boolean> original, @Local(argsOnly = true) Player player) {
|
||||
return BrewingStandRecipe.Companion.isBottle(stack, player.level().getRecipeManager()) || original.call(stack);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.brewing;
|
||||
|
||||
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
|
||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
|
||||
import net.minecraft.world.inventory.BrewingStandMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(BrewingStandMenu.IngredientsSlot.class)
|
||||
public class IngredientSlotMixin implements RecipeAwareSlot {
|
||||
|
||||
@Unique
|
||||
private RecipeManager cobblemon$recipeManager;
|
||||
|
||||
@Override
|
||||
public void setRecipeManager(RecipeManager recipeManager) {
|
||||
this.cobblemon$recipeManager = recipeManager;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "mayPlace",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$mayPlace(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (BrewingStandRecipe.Companion.isInput(stack, cobblemon$recipeManager)) {
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.brewing;
|
||||
|
||||
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
|
||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
|
||||
import net.minecraft.world.inventory.BrewingStandMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(BrewingStandMenu.PotionSlot.class)
|
||||
public class PotionSlotMixin implements RecipeAwareSlot {
|
||||
|
||||
@Unique
|
||||
private RecipeManager cobblemon$recipeManager;
|
||||
|
||||
@Override
|
||||
public void setRecipeManager(RecipeManager recipeManager) {
|
||||
this.cobblemon$recipeManager = recipeManager;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "mayPlace",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$mayPlace(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (BrewingStandRecipe.Companion.isBottle(stack, cobblemon$recipeManager)) {
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,24 +12,15 @@ import com.cobblemon.mod.common.Cobblemon;
|
||||
import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.api.orientation.OrientationController;
|
||||
import com.cobblemon.mod.common.api.riding.Rideable;
|
||||
import com.cobblemon.mod.common.api.riding.Seat;
|
||||
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController;
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate;
|
||||
import com.cobblemon.mod.common.client.render.MatrixWrapper;
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState;
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel;
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository;
|
||||
import com.cobblemon.mod.common.client.render.camera.MountedCameraRenderer;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Quaternionf;
|
||||
@@ -42,8 +33,6 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(Camera.class)
|
||||
public abstract class CameraMixin {
|
||||
@Shadow private Entity entity;
|
||||
@@ -59,19 +48,14 @@ public abstract class CameraMixin {
|
||||
|
||||
@Shadow protected abstract void setPosition(Vec3 pos);
|
||||
|
||||
@Shadow
|
||||
private BlockGetter level;
|
||||
|
||||
@Shadow private float partialTickTime;
|
||||
@Unique private float returnTimer = 0;
|
||||
@Unique private float rollAngleStart = 0;
|
||||
@Unique Minecraft minecraft = Minecraft.getInstance();
|
||||
|
||||
@Unique boolean disableRollableCameraDebug = false;
|
||||
|
||||
@Inject(method = "setRotation", at = @At("HEAD"), cancellable = true)
|
||||
|
||||
public void cobblemon$setRotation(float f, float g, CallbackInfo ci) {
|
||||
if (!(this.entity instanceof OrientationControllable controllable) || disableRollableCameraDebug) return;
|
||||
if (!(this.entity instanceof OrientationControllable controllable) || Cobblemon.config.getDisableRoll()) return;
|
||||
var controller = controllable.getOrientationController();
|
||||
if (!controller.isActive() && controller.getOrientation() != null) {
|
||||
if(this.returnTimer < 1) {
|
||||
@@ -105,7 +89,6 @@ public abstract class CameraMixin {
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
//If you want to move this to a delagate you need an AW for position
|
||||
@WrapOperation(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setPosition(DDD)V"))
|
||||
public void cobblemon$positionCamera(Camera instance, double x, double y, double z, Operation<Void> original, @Local(ordinal = 1, argsOnly = true) boolean thirdPersonReverse) {
|
||||
Entity entity = instance.getEntity();
|
||||
@@ -113,75 +96,25 @@ public abstract class CameraMixin {
|
||||
MountedPokemonAnimationRenderController.INSTANCE.reset();
|
||||
|
||||
if(vehicle instanceof Rideable){
|
||||
//RidingCameraDelagate.INSTANCE.positionCamera(instance, x, y, z, original);
|
||||
if (!(vehicle instanceof PokemonEntity pokemon)) {
|
||||
original.call(instance, x, y, z);
|
||||
Vec3 position = MountedCameraRenderer.INSTANCE.getCameraPosition(
|
||||
instance,
|
||||
entity,
|
||||
vehicle,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
thirdPersonReverse,
|
||||
eyeHeightOld,
|
||||
eyeHeight
|
||||
);
|
||||
|
||||
if(position != null){
|
||||
setPosition(position);
|
||||
return;
|
||||
}
|
||||
|
||||
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemon.getDelegate();
|
||||
Vec3 entityPos = new Vec3(
|
||||
Mth.lerp(instance.getPartialTickTime(), pokemon.xOld, pokemon.getX()),
|
||||
Mth.lerp(instance.getPartialTickTime(), pokemon.yOld, pokemon.getY()),
|
||||
Mth.lerp(instance.getPartialTickTime(), pokemon.zOld, pokemon.getZ())
|
||||
);
|
||||
MountedPokemonAnimationRenderController.INSTANCE.setup(pokemon, partialTickTime);
|
||||
int seatIndex = pokemon.getPassengers().indexOf(entity);
|
||||
Seat seat = pokemon.getSeats().get(seatIndex);
|
||||
|
||||
OrientationControllable rollable = (OrientationControllable) entity;
|
||||
OrientationController controller = rollable.getOrientationController();
|
||||
|
||||
if (!instance.isDetached() || Cobblemon.config.getThirdPartyViewBobbing()) {
|
||||
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
|
||||
|
||||
if (locator == null) {
|
||||
original.call(instance, x, y, z);
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
|
||||
|
||||
float currEyeHeight = Mth.lerp(instance.getPartialTickTime(), eyeHeightOld, eyeHeight);
|
||||
var rotatedEyeHeight = new Vector3f(0f, currEyeHeight - (entity.getBbHeight() / 2), 0f);
|
||||
if (controller.isActive()) {
|
||||
rotatedEyeHeight = controller.getRenderOrientation(partialTickTime).transform(rotatedEyeHeight);
|
||||
}
|
||||
|
||||
Vec3 position = locatorOffset.add(entityPos).add(new Vec3(rotatedEyeHeight));
|
||||
setPosition(position);
|
||||
} else {
|
||||
Vector3f pos = entityPos.add(new Vec3(0, pokemon.getBbHeight() / 2, 0)).toVector3f();
|
||||
|
||||
PosableModel model = VaryingModelRepository.INSTANCE.getPoser(pokemon.getPokemon().getSpecies().getResourceIdentifier(), new FloatingState());
|
||||
Map<String, Vec3> cameraOffsets = model.getSeatToCameraOffset();
|
||||
|
||||
Vec3 cameraOffset;
|
||||
if (thirdPersonReverse && cameraOffsets.containsKey(seat.getLocator() + "_reverse")) {
|
||||
cameraOffset = cameraOffsets.get(seat.getLocator() + "_reverse");
|
||||
} else if (cameraOffsets.containsKey(seat.getLocator())) {
|
||||
cameraOffset = cameraOffsets.get(seat.getLocator());
|
||||
} else {
|
||||
cameraOffset = new Vec3(0f, 2f, 4f);
|
||||
}
|
||||
|
||||
Vector3f offset = cameraOffset.toVector3f();
|
||||
|
||||
if (thirdPersonReverse) offset.z *= -1;
|
||||
float xRot = (float) (-1 * Math.toRadians(instance.getXRot()));
|
||||
|
||||
Matrix3f orientation = controller.isActive() && controller.getOrientation() != null ? controller.getOrientation() : new Matrix3f().rotateY((float) Math.toRadians(180f - instance.getYRot())).rotateX(xRot);
|
||||
Vector3f rotatedOffset = orientation.transform(offset);
|
||||
float offsetDistance = rotatedOffset.length();
|
||||
Vector3f offsetDirection = rotatedOffset.mul(1 / offsetDistance);
|
||||
|
||||
float maxZoom = cobblemon$getMaxZoom(offsetDistance, offsetDirection, pos);
|
||||
|
||||
setPosition(new Vec3(offsetDirection.mul(maxZoom).add(pos)));
|
||||
}
|
||||
} else {
|
||||
original.call(instance, x, y, z);
|
||||
}
|
||||
|
||||
original.call(instance, x, y, z);
|
||||
}
|
||||
|
||||
@Unique
|
||||
@@ -195,9 +128,9 @@ public abstract class CameraMixin {
|
||||
this.rotation.set(newRotation);
|
||||
this.xRot = controller.getPitch();
|
||||
this.yRot = controller.getYaw();
|
||||
this.forwards.set(controller.getForwardVector());
|
||||
this.up.set(controller.getUpVector());
|
||||
this.left.set(controller.getLeftVector());
|
||||
OrientationController.Companion.getFORWARDS().rotate(this.rotation, this.forwards);
|
||||
OrientationController.Companion.getUP().rotate(this.rotation, this.up);
|
||||
OrientationController.Companion.getLEFT().rotate(this.rotation, this.left);
|
||||
}
|
||||
|
||||
@WrapOperation(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;move(FFF)V", ordinal = 0))
|
||||
@@ -205,30 +138,8 @@ public abstract class CameraMixin {
|
||||
Entity entity = instance.getEntity();
|
||||
Entity vehicle = entity.getVehicle();
|
||||
|
||||
if (!(vehicle instanceof PokemonEntity) || Cobblemon.config.getThirdPartyViewBobbing()) {
|
||||
if (!(vehicle instanceof PokemonEntity) || Cobblemon.config.getThirdPersonViewBobbing()) {
|
||||
original.call(instance, zoom, dy, dx);
|
||||
}
|
||||
}
|
||||
|
||||
//Modified vanilla code
|
||||
@Unique
|
||||
private float cobblemon$getMaxZoom(float maxZoom, Vector3f directionVector, Vector3f positionVector) {
|
||||
Vec3 pos = new Vec3(positionVector);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
float g = (float) ((i & 1) * 2 - 1);
|
||||
float h = (float) ((i >> 1 & 1) * 2 - 1);
|
||||
float j = (float) ((i >> 2 & 1) * 2 - 1);
|
||||
Vec3 vec3 = pos.add(g * 0.1F, h * 0.1F, j * 0.1F);
|
||||
Vec3 vec32 = vec3.add(new Vec3(directionVector).scale(maxZoom));
|
||||
HitResult hitResult = this.level.clip(new ClipContext(vec3, vec32, ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, this.entity));
|
||||
if (hitResult.getType() != HitResult.Type.MISS) {
|
||||
float k = (float) hitResult.getLocation().distanceToSqr(pos);
|
||||
if (k < Mth.square(maxZoom)) {
|
||||
maxZoom = Mth.sqrt(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxZoom;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories;
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotBookCategory;
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe;
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import net.minecraft.client.ClientRecipeBook;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(ClientRecipeBook.class)
|
||||
public abstract class ClientRecipeBookMixin {
|
||||
|
||||
@Shadow
|
||||
protected static Map<RecipeBookCategories, List<List<RecipeHolder<?>>>> categorizeAndGroupRecipes(Iterable<RecipeHolder<?>> recipes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Shadow
|
||||
private Map<RecipeBookCategories, List<RecipeCollection>> collectionsByTab;
|
||||
|
||||
@Shadow
|
||||
private List<RecipeCollection> allCollections;
|
||||
|
||||
@Inject(method = "getCategory", at = @At(value = "HEAD"), cancellable = true)
|
||||
private static void addCustomCategory(RecipeHolder<?> recipe, CallbackInfoReturnable<RecipeBookCategories> cir) {
|
||||
Recipe<?> recipe2 = recipe.value();
|
||||
if (recipe2 instanceof CookingPotRecipe || recipe2 instanceof CookingPotShapelessRecipe) {
|
||||
CookingPotBookCategory category = recipe2 instanceof CookingPotRecipe
|
||||
? ((CookingPotRecipe) recipe2).getCategory()
|
||||
: ((CookingPotShapelessRecipe) recipe2).category();
|
||||
RecipeBookCategories var7;
|
||||
switch (category) {
|
||||
case MISC -> var7 = CobblemonRecipeCategories.COOKING_POT_MISC.toVanillaCategory();
|
||||
case FOODS -> var7 = CobblemonRecipeCategories.COOKING_POT_FOODS.toVanillaCategory();
|
||||
case MEDICINES -> var7 = CobblemonRecipeCategories.COOKING_POT_MEDICINES.toVanillaCategory();
|
||||
case COMPLEX_DISHES -> var7 = CobblemonRecipeCategories.COOKING_POT_COMPLEX_DISHES.toVanillaCategory();
|
||||
default -> throw new MatchException(null, null);
|
||||
}
|
||||
cir.setReturnValue(var7);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "setupCollections", at = @At("RETURN"))
|
||||
private void addCustomAggregateCategories(Iterable<RecipeHolder<?>> recipes, RegistryAccess registryAccess, CallbackInfo ci) {
|
||||
Map<RecipeBookCategories, List<List<RecipeHolder<?>>>> map = categorizeAndGroupRecipes(recipes);
|
||||
Map<RecipeBookCategories, List<RecipeCollection>> map2 = Maps.newHashMap();
|
||||
ImmutableList.Builder<RecipeCollection> builder = ImmutableList.builder();
|
||||
|
||||
map.forEach((recipeBookCategories, list) -> {
|
||||
List<RecipeCollection> collections = list.stream()
|
||||
.map(listx -> new RecipeCollection(registryAccess, listx))
|
||||
.peek(builder::add)
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
map2.put(recipeBookCategories, collections);
|
||||
});
|
||||
RecipeBookCategories.AGGREGATE_CATEGORIES.forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
|
||||
CobblemonRecipeCategories.Companion.getCustomAggregateCategories().forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
|
||||
|
||||
this.collectionsByTab = ImmutableMap.copyOf(map2);
|
||||
this.allCollections = builder.build();
|
||||
}
|
||||
}
|
||||
@@ -10,27 +10,51 @@ package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonNetwork;
|
||||
import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.api.orientation.OrientationController;
|
||||
import com.cobblemon.mod.common.api.riding.Seat;
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate;
|
||||
import com.cobblemon.mod.common.client.render.MatrixWrapper;
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState;
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel;
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.net.messages.server.orientation.ServerboundUpdateOrientationPacket;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.client.CameraType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Vector3f;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(LocalPlayer.class)
|
||||
public abstract class LocalPlayerMixin extends LivingEntity {
|
||||
public abstract class LocalPlayerMixin extends AbstractClientPlayer implements OrientationControllable{
|
||||
|
||||
@Unique Matrix3f cobblemon$lastOrientation;
|
||||
|
||||
protected LocalPlayerMixin(EntityType<? extends LivingEntity> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
@Shadow
|
||||
private float jumpRidingScale;
|
||||
|
||||
public LocalPlayerMixin(ClientLevel clientLevel, GameProfile gameProfile) {
|
||||
super(clientLevel, gameProfile);
|
||||
}
|
||||
|
||||
// @Inject(method = "sendPosition", at = @At("TAIL"))
|
||||
@@ -76,4 +100,73 @@ public abstract class LocalPlayerMixin extends LivingEntity {
|
||||
if (!(this instanceof OrientationControllable controllable)) return;
|
||||
controllable.getOrientationController().setActive(false);
|
||||
}
|
||||
|
||||
@Inject(method = "getJumpRidingScale", at = @At("HEAD"), cancellable = true)
|
||||
public void modifyJumpRidingScale(CallbackInfoReturnable<Float> cir) {
|
||||
LocalPlayer player = (LocalPlayer) (Object) this;
|
||||
if (player.isPassenger() && player.getVehicle() instanceof PokemonEntity pokemonEntity) {
|
||||
var rideValue = pokemonEntity.<Float>ifRidingAvailableSupply(null, (behaviour, settings, state) -> {
|
||||
if (behaviour.canJump(settings, state, pokemonEntity, player)) return null;
|
||||
return behaviour.setRideBar(settings, state, pokemonEntity, player);
|
||||
});
|
||||
if (rideValue != null) {
|
||||
cir.setReturnValue(rideValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HitResult pick(double hitDistance, float partialTicks, boolean hitFluids) {
|
||||
Entity vehicle = this.getVehicle();
|
||||
if (vehicle instanceof PokemonEntity pokemonEntity) {
|
||||
int seatIndex = pokemonEntity.getPassengers().indexOf(this);
|
||||
Seat seat = pokemonEntity.getSeats().get(seatIndex);
|
||||
|
||||
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemonEntity.getDelegate();
|
||||
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
|
||||
|
||||
if (locator == null) {
|
||||
super.pick(hitDistance, partialTicks, hitFluids);
|
||||
}
|
||||
|
||||
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
|
||||
|
||||
OrientationController controller = this.getOrientationController();
|
||||
|
||||
float currEyeHeight = this.getEyeHeight();
|
||||
Vector3f offset = new Vector3f(new Vector3f(0f, currEyeHeight - (this.getBbHeight() / 2), 0f));
|
||||
|
||||
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) {
|
||||
PosableModel model = VaryingModelRepository.INSTANCE.getPoser(pokemonEntity.getPokemon().getSpecies().getResourceIdentifier(), new FloatingState());
|
||||
offset.add(cobblemon$getFirstPersonOffset(model, seat));
|
||||
}
|
||||
|
||||
Matrix3f orientation = controller.isActive() && controller.getOrientation() != null ? controller.getOrientation() : new Matrix3f();
|
||||
Vec3 rotatedEyeHeight = new Vec3(orientation.transform(offset));
|
||||
|
||||
Vec3 eyePosition = locatorOffset.add(pokemonEntity.position()).add(rotatedEyeHeight);
|
||||
|
||||
Vec3 viewVector = this.getViewVector(partialTicks);
|
||||
Vec3 viewDistanceVector = eyePosition.add(viewVector.x * hitDistance, viewVector.y * hitDistance, viewVector.z * hitDistance);
|
||||
return this.level()
|
||||
.clip(
|
||||
new ClipContext(
|
||||
eyePosition, viewDistanceVector, ClipContext.Block.OUTLINE, hitFluids ? net.minecraft.world.level.ClipContext.Fluid.ANY : net.minecraft.world.level.ClipContext.Fluid.NONE, this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return super.pick(hitDistance, partialTicks, hitFluids);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static @NotNull Vector3f cobblemon$getFirstPersonOffset(PosableModel model, Seat seat) {
|
||||
Map<String, Vec3> cameraOffsets = model.getFirstPersonCameraOffset();
|
||||
|
||||
if (cameraOffsets.containsKey(seat.getLocator())) {
|
||||
return cameraOffsets.get(seat.getLocator()).toVector3f();
|
||||
} else {
|
||||
return new Vector3f(0f, 0f, 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems;
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mixin(RecipeBookCategories.class)
|
||||
public class RecipeBookCategoriesMixin {
|
||||
|
||||
@Final
|
||||
@Mutable
|
||||
@Shadow
|
||||
private static RecipeBookCategories[] $VALUES;
|
||||
|
||||
@Invoker("<init>")
|
||||
private static RecipeBookCategories cobblemon$createCategory(String name, int ordinal, ItemStack... icons) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "<clinit>",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
|
||||
ArrayList<RecipeBookCategories> types = new ArrayList<>(List.of($VALUES));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_SEARCH", $VALUES.length, new ItemStack(Items.COMPASS)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.POTION)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_COMPLEX_DISHES", $VALUES.length + 3, new ItemStack(CobblemonItems.POKE_PUFF)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.PROTEIN)));
|
||||
$VALUES = types.toArray(RecipeBookCategories[]::new);
|
||||
}
|
||||
|
||||
@Inject(method = "getCategories", at = @At("HEAD"), cancellable = true)
|
||||
private static void modifyCategories(RecipeBookType recipeBookType, CallbackInfoReturnable<List<RecipeBookCategories>> cir) {
|
||||
if (recipeBookType == RecipeBookType.valueOf("COOKING_POT")) {
|
||||
List var10000 = ImmutableList.of(
|
||||
CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_FOODS.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_MEDICINES.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_COMPLEX_DISHES.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_MISC.toVanillaCategory());
|
||||
cir.setReturnValue(var10000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories;
|
||||
import net.minecraft.client.ClientRecipeBook;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeBookPage;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(RecipeBookComponent.class)
|
||||
public class RecipeBookComponentMixin {
|
||||
|
||||
@Shadow private ClientRecipeBook book;
|
||||
|
||||
@Shadow protected Minecraft minecraft;
|
||||
|
||||
@Shadow private int width;
|
||||
|
||||
@Shadow private int xOffset;
|
||||
|
||||
@Shadow private int height;
|
||||
|
||||
@Shadow @Final private RecipeBookPage recipeBookPage;
|
||||
|
||||
@Inject(method = "updateTabs", at = @At("HEAD"), cancellable = true)
|
||||
private void customUpdateTabs(CallbackInfo ci) {
|
||||
RecipeBookComponent instance = (RecipeBookComponent) (Object) this;
|
||||
int i = (width - 147) / 2 - xOffset - 30;
|
||||
int j = (height - 166) / 2 + 3;
|
||||
int k = 27;
|
||||
int l = 0;
|
||||
|
||||
for (RecipeBookTabButton recipeBookTabButton : instance.tabButtons) {
|
||||
RecipeBookCategories recipeBookCategories = recipeBookTabButton.getCategory();
|
||||
if (recipeBookCategories != RecipeBookCategories.CRAFTING_SEARCH && recipeBookCategories != RecipeBookCategories.FURNACE_SEARCH && recipeBookCategories != CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory()) {
|
||||
if (recipeBookTabButton.updateVisibility(book)) {
|
||||
recipeBookTabButton.setPosition(i, j + 27 * l++);
|
||||
recipeBookTabButton.startAnimation(minecraft);
|
||||
}
|
||||
} else {
|
||||
recipeBookTabButton.visible = true;
|
||||
recipeBookTabButton.setPosition(i, j + k * l++);
|
||||
}
|
||||
}
|
||||
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import net.minecraft.client.ClientRecipeBook;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton;
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(RecipeBookTabButton.class)
|
||||
public class RecipeBookTabButtonMixin {
|
||||
|
||||
@Inject(method = "updateVisibility", at = @At("HEAD"), cancellable = true)
|
||||
private void customUpdateVisibility(ClientRecipeBook recipeBook, CallbackInfoReturnable<Boolean> cir) {
|
||||
RecipeBookTabButton instance = (RecipeBookTabButton) (Object) this;
|
||||
List<RecipeCollection> list = recipeBook.getCollection(instance.getCategory());
|
||||
boolean visible = false;
|
||||
if (list != null) {
|
||||
for (RecipeCollection recipeCollection : list) {
|
||||
if (recipeCollection.hasKnownRecipes() && recipeCollection.hasFitting()) {
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
instance.visible = visible;
|
||||
cir.setReturnValue(visible);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
|
||||
import net.minecraft.stats.RecipeBook;
|
||||
import net.minecraft.world.entity.player.StackedContents;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Mixin(RecipeCollection.class)
|
||||
public class RecipeCollectionMixin {
|
||||
|
||||
@Shadow @Final private Set<RecipeHolder<?>> fitsDimensions;
|
||||
|
||||
@Shadow @Final private Set<RecipeHolder<?>> craftable;
|
||||
|
||||
@Shadow @Final private List<RecipeHolder<?>> recipes;
|
||||
|
||||
@Inject(method = "canCraft", at = @At("HEAD"), cancellable = true)
|
||||
private void customCanCraft(StackedContents handler, int width, int height, RecipeBook book, CallbackInfo ci) {
|
||||
for (RecipeHolder<?> recipeHolder : recipes) {
|
||||
boolean bl = recipeHolder.value().canCraftInDimensions(width, height) && book.contains(recipeHolder);
|
||||
if (bl) {
|
||||
fitsDimensions.add(recipeHolder);
|
||||
} else {
|
||||
fitsDimensions.remove(recipeHolder);
|
||||
}
|
||||
|
||||
if (bl && handler.canCraft(recipeHolder.value(), null)) {
|
||||
craftable.add(recipeHolder);
|
||||
} else {
|
||||
craftable.remove(recipeHolder);
|
||||
}
|
||||
}
|
||||
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import net.minecraft.client.searchtree.IdSearchTree;
|
||||
import net.minecraft.client.searchtree.SearchTree;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Mixin(IdSearchTree.class)
|
||||
public abstract class SearchTreeMixin {
|
||||
@Unique
|
||||
private static final ThreadLocal<Boolean> reentryFlag = ThreadLocal.withInitial(() -> false);
|
||||
|
||||
/**
|
||||
* Runs an additional search using the original search term where every instance of 'e' is replaced with 'é'
|
||||
* Appends additional search results to original search results.
|
||||
*/
|
||||
@Inject(method = "search(Ljava/lang/String;)Ljava/util/List;", at = @At("RETURN"), cancellable = true)
|
||||
private void onSearch(String string, CallbackInfoReturnable<List> cir) {
|
||||
// If flag is true, skip to avoid infinite loop
|
||||
if (reentryFlag.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
reentryFlag.set(true);
|
||||
List originalResults = cir.getReturnValue();
|
||||
|
||||
if (!string.contains("poke")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String modifiedString = string.replace("poke", "poké");
|
||||
List additionalResults = ((SearchTree)this).search(modifiedString);
|
||||
|
||||
Set combinedSet = new LinkedHashSet<>();
|
||||
combinedSet.addAll(originalResults);
|
||||
combinedSet.addAll(additionalResults);
|
||||
|
||||
cir.setReturnValue(new ArrayList<>(combinedSet));
|
||||
} finally {
|
||||
reentryFlag.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.client.render.TextClipping;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
/**
|
||||
* This mixin facilitates the gradual reveal of text with NPC dialogue. If there is a better way
|
||||
* to do this, I'd love to hear it.
|
||||
*
|
||||
* The idea is that somewhere static in the mod we have a control for how many characters can be drawn
|
||||
* and how many have been drawn so far, and this mixin will add to the latter and stop drawing characters
|
||||
* once it reaches the former.
|
||||
*
|
||||
* This relies STRONGLY on the code that sets the character cap to reset it to -1 after the text is rendered,
|
||||
* otherwise all text in Minecraft will stop drawing.
|
||||
*
|
||||
* Sites that take advantage of this mixin will do the following:
|
||||
* 1: Set the character cap, which resets the drawn counter to zero.
|
||||
* 2: Call whatever Minecraft function draws your text.
|
||||
* 3: Reset the character cap to -1, which will allow regular text to draw again.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since April 18th, 2025
|
||||
*/
|
||||
@Mixin(Font.StringRenderOutput.class)
|
||||
public class StringRenderOutputMixin {
|
||||
@Inject(method = "accept", at = @At(value = "HEAD"), cancellable = true)
|
||||
public void onAccept(int i, Style style, int j, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (!TextClipping.canDrawAnotherCharacter()) {
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,9 +40,9 @@ import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
|
||||
import com.cobblemon.mod.common.api.scheduling.ServerRealTimeTaskTracker
|
||||
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
|
||||
import com.cobblemon.mod.common.api.spawning.BestSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.CobblemonSpawningProspector
|
||||
import com.cobblemon.mod.common.api.spawning.context.AreaContextResolver
|
||||
import com.cobblemon.mod.common.api.spawning.prospecting.SpawningProspector
|
||||
import com.cobblemon.mod.common.api.spawning.CobblemonSpawningZoneGenerator
|
||||
import com.cobblemon.mod.common.api.spawning.position.AreaSpawnablePositionResolver
|
||||
import com.cobblemon.mod.common.api.spawning.SpawningZoneGenerator
|
||||
import com.cobblemon.mod.common.api.starter.StarterHandler
|
||||
import com.cobblemon.mod.common.api.storage.PokemonStoreManager
|
||||
import com.cobblemon.mod.common.api.storage.adapter.conversions.ReforgedConversion
|
||||
@@ -63,13 +63,10 @@ import com.cobblemon.mod.common.api.storage.player.adapter.PlayerDataMongoBacken
|
||||
import com.cobblemon.mod.common.api.storage.player.factory.CachedPlayerDataStoreFactory
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonEntityTypeTags
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.battles.BagItems
|
||||
import com.cobblemon.mod.common.battles.BattleFormat
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
import com.cobblemon.mod.common.battles.BattleSide
|
||||
import com.cobblemon.mod.common.battles.ShowdownThread
|
||||
import com.cobblemon.mod.common.battles.*
|
||||
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.block.DispenserBehaviorRegistry
|
||||
import com.cobblemon.mod.common.client.CobblemonPack
|
||||
import com.cobblemon.mod.common.command.argument.*
|
||||
import com.cobblemon.mod.common.config.CobblemonConfig
|
||||
@@ -91,23 +88,11 @@ import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
|
||||
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
|
||||
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||
import com.cobblemon.mod.common.pokemon.properties.AspectPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.BattleCloneProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.FreezeFrameProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.NoAIProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.UnaspectPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.*
|
||||
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
|
||||
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
|
||||
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.ifDedicatedServer
|
||||
import com.cobblemon.mod.common.util.isLaterVersion
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import com.cobblemon.mod.common.util.requestWallpapers
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import com.cobblemon.mod.common.world.feature.CobblemonPlacedFeatures
|
||||
import com.cobblemon.mod.common.world.feature.ore.CobblemonOrePlacedFeatures
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
|
||||
@@ -115,17 +100,6 @@ import com.mongodb.ConnectionString
|
||||
import com.mongodb.MongoClientSettings
|
||||
import com.mongodb.client.MongoClient
|
||||
import com.mongodb.client.MongoClients
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
import java.io.FileWriter
|
||||
import java.io.PrintWriter
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
import kotlin.reflect.jvm.javaField
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.commands.synchronization.SingletonArgumentInfo
|
||||
import net.minecraft.resources.ResourceKey
|
||||
@@ -138,6 +112,17 @@ import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.storage.LevelResource
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
import java.io.FileWriter
|
||||
import java.io.PrintWriter
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
import kotlin.reflect.jvm.javaField
|
||||
|
||||
object Cobblemon {
|
||||
const val MODID = CobblemonBuildDetails.MOD_ID
|
||||
@@ -159,8 +144,8 @@ object Cobblemon {
|
||||
var isDedicatedServer = false
|
||||
val showdownThread = ShowdownThread()
|
||||
lateinit var config: CobblemonConfig
|
||||
var prospector: SpawningProspector = CobblemonSpawningProspector
|
||||
var areaContextResolver: AreaContextResolver = object : AreaContextResolver {}
|
||||
var spawningZoneGenerator: SpawningZoneGenerator = CobblemonSpawningZoneGenerator
|
||||
var areaSpawnablePositionResolver: AreaSpawnablePositionResolver = object : AreaSpawnablePositionResolver {}
|
||||
val bestSpawner = BestSpawner
|
||||
val battleRegistry = BattleRegistry
|
||||
var storage = PokemonStoreManager()
|
||||
@@ -194,6 +179,8 @@ object Cobblemon {
|
||||
this.LOGGER.info(" - Branch: ${CobblemonBuildDetails.BRANCH}")
|
||||
}
|
||||
|
||||
implementation.registerRecipeSerializers()
|
||||
implementation.registerRecipeTypes()
|
||||
implementation.registerPermissionValidator()
|
||||
implementation.registerSoundEvents()
|
||||
implementation.registerDataComponents()
|
||||
@@ -202,12 +189,15 @@ object Cobblemon {
|
||||
implementation.registerEntityTypes()
|
||||
implementation.registerEntityAttributes()
|
||||
implementation.registerBlockEntityTypes()
|
||||
implementation.registerPoiTypes()
|
||||
implementation.registerVillagers()
|
||||
implementation.registerWorldGenFeatures()
|
||||
implementation.registerParticles()
|
||||
implementation.registerMenu()
|
||||
implementation.registerEntityDataSerializers()
|
||||
implementation.registerCriteria()
|
||||
implementation.registerEntitySubPredicates()
|
||||
DispenserBehaviorRegistry.registerDispenserBehaviors()
|
||||
|
||||
DropEntry.register("command", CommandDropEntry::class.java)
|
||||
DropEntry.register("item", ItemDropEntry::class.java, isDefault = true)
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.BehaviourSyncPacket
|
||||
import com.cobblemon.mod.common.util.adapters.ActivityAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.BrainConfigAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.BehaviourConfigAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionOrEntityVariableAdapter
|
||||
@@ -47,7 +47,7 @@ object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
|
||||
.registerTypeAdapter(Activity::class.java, ActivityAdapter)
|
||||
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(BehaviourConfig::class.java, BrainConfigAdapter)
|
||||
.registerTypeAdapter(BehaviourConfig::class.java, BehaviourConfigAdapter)
|
||||
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
|
||||
.registerTypeAdapter(
|
||||
TypeToken.getParameterized(Either::class.java, Expression::class.java, MoLangConfigVariable::class.java).type,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.block.entity.PokeCakeBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.HealingMachineBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.PCBlockEntity
|
||||
@@ -45,9 +46,9 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
|
||||
@JvmField
|
||||
val PASTURE: BlockEntityType<PokemonPastureBlockEntity> = this.create("pasture", BlockEntityType.Builder.of(::PokemonPastureBlockEntity, CobblemonBlocks.PASTURE).build(null))
|
||||
@JvmField
|
||||
val SIGN: BlockEntityType<CobblemonSignBlockEntity> = this.create("sign", BlockEntityType.Builder.of(::CobblemonSignBlockEntity, CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN).build(null))
|
||||
val SIGN: BlockEntityType<CobblemonSignBlockEntity> = this.create("sign", BlockEntityType.Builder.of(::CobblemonSignBlockEntity, CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN, CobblemonBlocks.SACCHARINE_SIGN, CobblemonBlocks.SACCHARINE_WALL_SIGN).build(null))
|
||||
@JvmField
|
||||
val HANGING_SIGN: BlockEntityType<CobblemonHangingSignBlockEntity> = this.create("hanging_sign", BlockEntityType.Builder.of(::CobblemonHangingSignBlockEntity, CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN).build(null))
|
||||
val HANGING_SIGN: BlockEntityType<CobblemonHangingSignBlockEntity> = this.create("hanging_sign", BlockEntityType.Builder.of(::CobblemonHangingSignBlockEntity, CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN, CobblemonBlocks.SACCHARINE_HANGING_SIGN, CobblemonBlocks.SACCHARINE_WALL_HANGING_SIGN).build(null))
|
||||
|
||||
@JvmField
|
||||
val GILDED_CHEST: BlockEntityType<GildedChestBlockEntity> = this.create("chest", BlockEntityType.Builder.of(::GildedChestBlockEntity,
|
||||
@@ -86,4 +87,48 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
|
||||
val DISPLAY_CASE: BlockEntityType<DisplayCaseBlockEntity> = this.create("display_case",
|
||||
BlockEntityType.Builder.of(::DisplayCaseBlockEntity, CobblemonBlocks.DISPLAY_CASE).build(null)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val INCENSE_SWEET: BlockEntityType<SweetIncenseBlockEntity> = this.create("incense_sweet",
|
||||
BlockEntityType.Builder.of(::SweetIncenseBlockEntity, CobblemonBlocks.INCENSE_SWEET).build(null)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val CAMPFIRE: BlockEntityType<CampfireBlockEntity> = this.create("campfire_pot",
|
||||
BlockEntityType.Builder.of(::CampfireBlockEntity, CobblemonBlocks.CAMPFIRE).build(null)
|
||||
)
|
||||
@JvmField
|
||||
val COPPER_OVEN: BlockEntityType<CopperOvenBlockEntity> = this.create("copper_oven",
|
||||
BlockEntityType.Builder.of(::CopperOvenBlockEntity, CobblemonBlocks.COPPER_OVEN).build(null)
|
||||
)
|
||||
@JvmField
|
||||
val COPPER_WASHER: BlockEntityType<CopperWasherBlockEntity> = this.create("copper_washer",
|
||||
BlockEntityType.Builder.of(::CopperWasherBlockEntity, CobblemonBlocks.COPPER_WASHER).build(null)
|
||||
)
|
||||
@JvmField
|
||||
val COPPER_FRIDGE: BlockEntityType<CopperFridgeBlockEntity> = this.create("copper_fridge",
|
||||
BlockEntityType.Builder.of(::CopperFridgeBlockEntity, CobblemonBlocks.COPPER_FRIDGE).build(null)
|
||||
)
|
||||
|
||||
/*@JvmField
|
||||
val LURE_CAKE: BlockEntityType<LureCakeBlockEntity> =
|
||||
BlockEntityType.Builder.of({ pos, state -> LureCakeBlockEntity(pos, state) },
|
||||
CobblemonBlocks.LURE_CAKE
|
||||
).build(null)*/
|
||||
|
||||
@JvmField
|
||||
val LURE_CAKE: BlockEntityType<LureCakeBlockEntity> = this.create(
|
||||
"lure_cake",
|
||||
BlockEntityType.Builder.of(::LureCakeBlockEntity, CobblemonBlocks.LURE_CAKE).build(null)
|
||||
)
|
||||
@JvmField
|
||||
val POKE_CAKE: BlockEntityType<PokeCakeBlockEntity> = this.create(
|
||||
"poke_cake",
|
||||
BlockEntityType.Builder.of(::PokeCakeBlockEntity, CobblemonBlocks.POKE_CAKE).build(null)
|
||||
)
|
||||
@JvmField
|
||||
val CANDLE_POKE_CAKE: BlockEntityType<CandlePokeCakeBlockEntity> = this.create(
|
||||
"candle_poke_cake",
|
||||
BlockEntityType.Builder.of(::CandlePokeCakeBlockEntity, CobblemonBlocks.CANDLE_POKE_CAKE).build(null)
|
||||
)
|
||||
}
|
||||
@@ -10,16 +10,23 @@ package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.api.apricorn.Apricorn
|
||||
import com.cobblemon.mod.common.block.*
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
|
||||
import com.cobblemon.mod.common.block.LecternBlock
|
||||
import com.cobblemon.mod.common.block.MintBlock.MintType
|
||||
import com.cobblemon.mod.common.block.campfirepot.CampfirePotBlock
|
||||
import com.cobblemon.mod.common.block.chest.GildedChestBlock
|
||||
import com.cobblemon.mod.common.block.general.BaleBlock
|
||||
import com.cobblemon.mod.common.block.grower.SaccharineTreeGrower
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
|
||||
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
|
||||
import com.cobblemon.mod.common.block.general.HorizontalRotationCarpetBlock
|
||||
import com.cobblemon.mod.common.block.general.HorizontalRotationalBlock
|
||||
import com.cobblemon.mod.common.mixin.invoker.*
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
@@ -27,9 +34,13 @@ import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.valueproviders.UniformInt
|
||||
import net.minecraft.world.effect.MobEffects
|
||||
import net.minecraft.world.entity.EntityType
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.block.state.properties.BlockSetType
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.LIT
|
||||
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument
|
||||
import net.minecraft.world.level.block.state.properties.WoodType
|
||||
import net.minecraft.world.level.material.MapColor
|
||||
@@ -43,6 +54,8 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
|
||||
val APRICORN_BLOCK_SET_TYPE = BlockSetType("apricorn")
|
||||
val APRICORN_WOOD_TYPE = WoodType.register(WoodType("apricorn", APRICORN_BLOCK_SET_TYPE))
|
||||
val SACCHARINE_BLOCK_SET_TYPE = BlockSetType("saccharine")
|
||||
val SACCHARINE_WOOD_TYPE = WoodType.register(WoodType("saccharine", SACCHARINE_BLOCK_SET_TYPE))
|
||||
|
||||
// Evolution Ores
|
||||
@JvmField
|
||||
@@ -159,15 +172,80 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val YELLOW_APRICORN_SAPLING = this.create("yellow_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.YELLOW))
|
||||
|
||||
// Saccharines
|
||||
@JvmField
|
||||
val SACCHARINE_LOG = this.create("saccharine_log", SaccharineLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
|
||||
@JvmField
|
||||
val SACCHARINE_HONEY_LOG = this.create("saccharine_honey_log", SaccharineHoneyLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
|
||||
|
||||
@JvmField
|
||||
val STRIPPED_SACCHARINE_LOG = this.create("stripped_saccharine_log", RotatedPillarBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
|
||||
@JvmField
|
||||
val SACCHARINE_WOOD = log("saccharine_wood")
|
||||
@JvmField
|
||||
val STRIPPED_SACCHARINE_WOOD = this.create("stripped_saccharine_wood", RotatedPillarBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
|
||||
@JvmField
|
||||
val SACCHARINE_PLANKS = this.create("saccharine_planks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val SACCHARINE_LEAVES = this.create("saccharine_leaves", SaccharineLeafBlock(
|
||||
BlockBehaviour.Properties.of().mapColor(
|
||||
MapColor.PLANT
|
||||
).strength(0.2f).randomTicks().sound(SoundType.GRASS).noOcclusion()
|
||||
.isValidSpawn { _: BlockState?, _: BlockGetter?, _: BlockPos?, entity: EntityType<*>? ->
|
||||
entity === EntityType.OCELOT || entity === EntityType.PARROT
|
||||
}.isSuffocating { _: BlockState?, _: BlockGetter?, _: BlockPos? ->
|
||||
false
|
||||
}.isViewBlocking { _: BlockState?, _: BlockGetter?, _: BlockPos? ->
|
||||
false
|
||||
}.ignitedByLava().pushReaction(PushReaction.DESTROY)
|
||||
.isRedstoneConductor { _: BlockState?, _: BlockGetter?, _: BlockPos? ->
|
||||
false
|
||||
}))
|
||||
@JvmField
|
||||
val SACCHARINE_FENCE = this.create("saccharine_fence", FenceBlock(BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val SACCHARINE_FENCE_GATE = this.create("saccharine_fence_gate", FenceGateBlock(SACCHARINE_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||
|
||||
val SACCHARINE_BUTTON = this.create("saccharine_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
|
||||
@JvmField
|
||||
val SACCHARINE_PRESSURE_PLATE = this.create("saccharine_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).noCollission().strength(0.5f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val SACCHARINE_SIGN = this.create("saccharine_sign", CobblemonSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_WALL_SIGN = this.create("saccharine_wall_sign", CobblemonWallSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_WALL_HANGING_SIGN = this.create("saccharine_wall_hanging_sign", CobblemonWallHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_SLAB = this.create("saccharine_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||
@JvmField
|
||||
val SACCHARINE_STAIRS = this.create("saccharine_stairs", StairsBlockInvoker.`cobblemon$create`(SACCHARINE_PLANKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SACCHARINE_PLANKS)))
|
||||
@JvmField
|
||||
val SACCHARINE_DOOR = this.create("saccharine_door", DoorBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(3.0F).sound(SoundType.WOOD).noOcclusion()))
|
||||
@JvmField
|
||||
val SACCHARINE_TRAPDOOR = this.create("saccharine_trapdoor", TrapdoorBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(3.0F).sound(SoundType.WOOD).noOcclusion()))
|
||||
@JvmField
|
||||
val SACCHARINE_SAPLING = this.create("saccharine_sapling", SaplingBlock(SaccharineTreeGrower(), PLANT_PROPERTIES))
|
||||
|
||||
@JvmField
|
||||
val MEDICINAL_LEEK = this.create("medicinal_leek", MedicinalLeekBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.CRIMSON_NYLIUM).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MEDICINAL_LEEK_SOUNDS)))
|
||||
@JvmField
|
||||
val BUGWORT = this.create("bugwort", BugwortBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.COLOR_PURPLE).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MEDICINAL_LEEK_SOUNDS)))
|
||||
@JvmField
|
||||
val ENERGY_ROOT = this.create("energy_root", EnergyRootBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.DIRT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.ENERGY_ROOT_SOUNDS)))
|
||||
@JvmField
|
||||
val BIG_ROOT = this.create("big_root", BigRootBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.PLANT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.BIG_ROOT_SOUNDS)))
|
||||
@JvmField
|
||||
val REVIVAL_HERB = this.create("revival_herb", RevivalHerbBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).mapColor(MapColor.PLANT).ignitedByLava().noCollission().instabreak().sound(CobblemonSounds.REVIVAL_HERB_SOUNDS)))
|
||||
|
||||
@JvmField
|
||||
val LURE_CAKE = this.create("lure_cake", LureCakeBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY)))
|
||||
@JvmField
|
||||
val POKE_CAKE = this.create("poke_cake", PokeCakeBlock(BlockBehaviour.Properties.ofFullCopy(LURE_CAKE)))
|
||||
@JvmField
|
||||
val CANDLE_POKE_CAKE = this.create("candle_poke_cake", CandlePokeCakeBlock(BlockBehaviour.Properties.ofFullCopy(LURE_CAKE).lightLevel { blockState -> if (blockState.getValue(LIT) == true) 3 else 0 }))
|
||||
|
||||
@JvmField
|
||||
val TUMBLESTONE_CLUSTER = tumblestoneBlock("tumblestone_cluster", GrowableStoneBlock.STAGE_3, 7, 3, null)
|
||||
@JvmField
|
||||
@@ -319,6 +397,60 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val YELLOW_APRICORN = apricornBlock("yellow_apricorn", Apricorn.YELLOW)
|
||||
|
||||
@JvmField
|
||||
val BLACK_CAMPFIRE_POT = create("campfire_pot_black",
|
||||
CampfirePotBlock(
|
||||
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLACK).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
|
||||
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
|
||||
)
|
||||
)
|
||||
@JvmField
|
||||
val BLUE_CAMPFIRE_POT = create("campfire_pot_blue",
|
||||
CampfirePotBlock(
|
||||
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
|
||||
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
|
||||
)
|
||||
)
|
||||
@JvmField
|
||||
val GREEN_CAMPFIRE_POT = create("campfire_pot_green",
|
||||
CampfirePotBlock(
|
||||
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_GREEN).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
|
||||
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
|
||||
)
|
||||
)
|
||||
@JvmField
|
||||
val PINK_CAMPFIRE_POT = create("campfire_pot_pink",
|
||||
CampfirePotBlock(
|
||||
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_PINK).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
|
||||
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
|
||||
)
|
||||
)
|
||||
@JvmField
|
||||
val RED_CAMPFIRE_POT = create("campfire_pot_red",
|
||||
CampfirePotBlock(
|
||||
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_RED).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
|
||||
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
|
||||
)
|
||||
)
|
||||
@JvmField
|
||||
val WHITE_CAMPFIRE_POT = create("campfire_pot_white",
|
||||
CampfirePotBlock(
|
||||
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_GRAY)
|
||||
.sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS).strength(0.5F).pushReaction(PushReaction.BLOCK)
|
||||
.noOcclusion()
|
||||
)
|
||||
)
|
||||
@JvmField
|
||||
val YELLOW_CAMPFIRE_POT = create("campfire_pot_yellow",
|
||||
CampfirePotBlock(
|
||||
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_YELLOW).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
|
||||
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val CAMPFIRE = create("campfire", CampfireBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOD).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.PODZOL).strength(2.0F).lightLevel { if ((it.getValue(CampfireBlock.SOUL) as Boolean)) 9 else 14 }))
|
||||
|
||||
@JvmField
|
||||
val RELIC_COIN_POUCH = create("relic_coin_pouch", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS).pushReaction(PushReaction.DESTROY).noOcclusion(), true))
|
||||
@JvmField
|
||||
@@ -360,6 +492,20 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val DISPLAY_CASE = create("display_case", DisplayCaseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F)))
|
||||
|
||||
@JvmField
|
||||
val COPPER_FAN = create("copper_fan", CopperFanBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
|
||||
@JvmField
|
||||
val COPPER_MOWER = create("copper_mower", CopperMowerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
|
||||
@JvmField
|
||||
val COPPER_OVEN = create("copper_oven", CopperOvenBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
|
||||
@JvmField
|
||||
val COPPER_WASHER = this.create("copper_washer", CopperWasherBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
|
||||
@JvmField
|
||||
val COPPER_FRIDGE = this.create("copper_fridge", CopperFridgeBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_ORANGE).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(3.0F, 6.0F).sound(SoundType.COPPER)))
|
||||
|
||||
@JvmField
|
||||
val INCENSE_SWEET = create("incense_sweet", SweetIncenseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3f)))
|
||||
|
||||
@JvmField
|
||||
val PASTURE = create("pasture", PastureBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BROWN).sound(SoundType.WOOD).strength(2F).noOcclusion().pushReaction(PushReaction.BLOCK).lightLevel { if ((it.getValue(PastureBlock.ON) as Boolean) && (it.getValue(PastureBlock.PART) == PastureBlock.PasturePart.TOP)) 10 else 0 }))
|
||||
|
||||
@@ -381,6 +527,32 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
val PEP_UP_FLOWER = this.create("pep_up_flower", FlowerBlock(MobEffects.LEVITATION, 10F, BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().instabreak().sound(SoundType.GRASS).offsetType(BlockBehaviour.OffsetType.XZ).pushReaction(PushReaction.DESTROY)))
|
||||
@JvmField
|
||||
val POTTED_PEP_UP_FLOWER = this.create("potted_pep_up_flower", BlocksInvoker.createFlowerPotBlock(PEP_UP_FLOWER))
|
||||
@JvmField
|
||||
val HEARTY_GRAINS = this.create("hearty_grains", HeartyGrainsBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.PLANT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.VIVICHOKE_SOUNDS)))
|
||||
|
||||
@JvmField
|
||||
val POTTED_RED_APRICORN_SAPLING = this.create("potted_red_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(RED_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val POTTED_YELLOW_APRICORN_SAPLING = this.create("potted_yellow_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(YELLOW_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val POTTED_GREEN_APRICORN_SAPLING = this.create("potted_green_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(GREEN_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val POTTED_BLUE_APRICORN_SAPLING = this.create("potted_blue_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(BLUE_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val POTTED_PINK_APRICORN_SAPLING = this.create("potted_pink_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(PINK_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val POTTED_BLACK_APRICORN_SAPLING = this.create("potted_black_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(BLACK_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val POTTED_WHITE_APRICORN_SAPLING = this.create("potted_white_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(WHITE_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val POTTED_SACCHARINE_SAPLING = this.create("potted_saccharine_sapling", BlocksInvoker.createFlowerPotBlock(SACCHARINE_SAPLING))
|
||||
|
||||
@JvmField
|
||||
val HEARTY_GRAIN_BALE = this.create("hearty_grain_bale", BaleBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).instrument(NoteBlockInstrument.BANJO).strength(0.5F).sound(SoundType.GRASS)))
|
||||
@JvmField
|
||||
val TATAMI_BLOCK = this.create("tatami_block", HorizontalRotationalBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).sound(SoundType.GRASS)))
|
||||
@JvmField
|
||||
val TATAMI_MAT = this.create("tatami_mat", HorizontalRotationCarpetBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).sound(SoundType.GRASS)))
|
||||
|
||||
/**
|
||||
* Returns a map of all the blocks that can be stripped with an axe in the format of input - output.
|
||||
@@ -389,7 +561,10 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
*/
|
||||
fun strippedBlocks(): Map<Block, Block> = mapOf(
|
||||
APRICORN_WOOD to STRIPPED_APRICORN_WOOD,
|
||||
APRICORN_LOG to STRIPPED_APRICORN_LOG
|
||||
APRICORN_LOG to STRIPPED_APRICORN_LOG,
|
||||
SACCHARINE_WOOD to STRIPPED_SACCHARINE_WOOD,
|
||||
SACCHARINE_LOG to STRIPPED_SACCHARINE_LOG,
|
||||
SACCHARINE_HONEY_LOG to STRIPPED_SACCHARINE_LOG
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -68,6 +68,8 @@ object CobblemonCommands {
|
||||
MarkGiveCommand.register(dispatcher)
|
||||
MarkTakeCommand.register(dispatcher)
|
||||
MarkGiveAllCommand.register(dispatcher)
|
||||
PcSearchCommand.register(dispatcher)
|
||||
PcTakeCommand.register(dispatcher)
|
||||
|
||||
// Possibly lock down registration if and only if under dev environment or running in an environment
|
||||
// with a certain system environment variable set
|
||||
|
||||
@@ -94,12 +94,17 @@ interface CobblemonImplementation {
|
||||
*/
|
||||
fun registerBlockEntityTypes()
|
||||
|
||||
fun registerPoiTypes()
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
fun registerVillagers()
|
||||
|
||||
fun registerRecipeSerializers()
|
||||
fun registerRecipeTypes()
|
||||
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
@@ -108,6 +113,8 @@ interface CobblemonImplementation {
|
||||
|
||||
fun registerParticles()
|
||||
|
||||
fun registerMenu()
|
||||
|
||||
fun registerEntitySubPredicates()
|
||||
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.item.components.HeldItemCapableComponent
|
||||
import com.cobblemon.mod.common.item.components.PokemonItemComponent
|
||||
import com.cobblemon.mod.common.item.RodBaitComponent
|
||||
import com.cobblemon.mod.common.item.components.*
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.mojang.serialization.Codec
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.component.DataComponentType
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.network.codec.ByteBufCodecs
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
@@ -36,11 +36,56 @@ object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>
|
||||
.networkSynchronized(RodBaitComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
val POT_DATA: DataComponentType<PotComponent> = create("cooking_pot_item", DataComponentType.builder<PotComponent>()
|
||||
.persistent(PotComponent.CODEC)
|
||||
.networkSynchronized(PotComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
val BAIT_EFFECTS: DataComponentType<BaitEffectsComponent> = create("bait_effects", DataComponentType.builder<BaitEffectsComponent>()
|
||||
.persistent(BaitEffectsComponent.CODEC)
|
||||
.networkSynchronized(BaitEffectsComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
val FLAVOUR: DataComponentType<FlavourComponent> = create("flavour", DataComponentType.builder<FlavourComponent>()
|
||||
.persistent(FlavourComponent.CODEC)
|
||||
.networkSynchronized(FlavourComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
val FOOD_COLOUR: DataComponentType<FoodColourComponent> = create("food_colour", DataComponentType.builder<FoodColourComponent>()
|
||||
.persistent(FoodColourComponent.CODEC)
|
||||
.networkSynchronized(FoodColourComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
val INGREDIENT: DataComponentType<IngredientComponent> = create("ingredient", DataComponentType.builder<IngredientComponent>()
|
||||
.persistent(IngredientComponent.CODEC)
|
||||
.networkSynchronized(IngredientComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
val FOOD: DataComponentType<FoodComponent> = create("food", DataComponentType.builder<FoodComponent>()
|
||||
.persistent(FoodComponent.CODEC)
|
||||
.networkSynchronized(FoodComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
val MOB_EFFECTS: DataComponentType<MobEffectsComponent> = create("mob_effects", DataComponentType.builder<MobEffectsComponent>()
|
||||
.persistent(MobEffectsComponent.CODEC)
|
||||
.networkSynchronized(MobEffectsComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
val CRAFTED: DataComponentType<Boolean> = create("crafted", DataComponentType.builder<Boolean>()
|
||||
.persistent(Codec.BOOL)
|
||||
.networkSynchronized(ByteBufCodecs.BOOL)
|
||||
.build())
|
||||
|
||||
fun register() {
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:pokemon_item"), POKEMON_ITEM)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:bait"), BAIT)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:cooking_pot_item"), POT_DATA)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:bait_effects"), BAIT_EFFECTS)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:flavour"), FLAVOUR)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:food_colour"), FOOD_COLOUR)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:ingredient"), INGREDIENT)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:food"), FOOD)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:mob_effects"), MOB_EFFECTS)
|
||||
}
|
||||
|
||||
override val registry = BuiltInRegistries.DATA_COMPONENT_TYPE
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.api.apricorn.Apricorn
|
||||
import com.cobblemon.mod.common.api.item.ability.AbilityChanger
|
||||
import com.cobblemon.mod.common.api.mulch.MulchVariant
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.api.pokemon.Natures
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stat
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.api.text.blue
|
||||
@@ -26,12 +28,20 @@ import com.cobblemon.mod.common.item.armor.CobblemonArmorTrims
|
||||
import com.cobblemon.mod.common.item.battle.DireHitItem
|
||||
import com.cobblemon.mod.common.item.battle.GuardSpecItem
|
||||
import com.cobblemon.mod.common.item.battle.XStatItem
|
||||
import com.cobblemon.mod.common.item.berry.*
|
||||
import com.cobblemon.mod.common.item.berry.BerryItem
|
||||
import com.cobblemon.mod.common.item.berry.FriendshipRaisingBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.HealingBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.PPRestoringBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.PortionHealingBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.StatusCuringBerryItem
|
||||
import com.cobblemon.mod.common.item.berry.VolatileCuringBerryItem
|
||||
import com.cobblemon.mod.common.item.food.PonigiriItem
|
||||
import com.cobblemon.mod.common.item.food.SinisterTeaItem
|
||||
import com.cobblemon.mod.common.item.interactive.*
|
||||
import com.cobblemon.mod.common.item.interactive.PotionItem
|
||||
import com.cobblemon.mod.common.item.interactive.ability.AbilityChangeItem
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.pokemon.IVs
|
||||
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.core.Registry
|
||||
@@ -44,7 +54,16 @@ import net.minecraft.world.effect.MobEffectInstance
|
||||
import net.minecraft.world.effect.MobEffects
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.food.FoodProperties
|
||||
import net.minecraft.world.item.*
|
||||
import net.minecraft.world.item.BlockItem
|
||||
import net.minecraft.world.item.HangingSignItem
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.Item.Properties
|
||||
import net.minecraft.world.item.ItemNameBlockItem
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.item.Rarity
|
||||
import net.minecraft.world.item.SignItem
|
||||
import net.minecraft.world.item.SmithingTemplateItem
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
|
||||
@@ -171,6 +190,32 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val POKEDEX_WHITE = pokedexItem(PokedexType.WHITE)
|
||||
|
||||
val campfire_pots = mutableListOf<CampfirePotItem>()
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_RED = campfirePotItem(CobblemonBlocks.RED_CAMPFIRE_POT, "red")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_YELLOW = campfirePotItem(CobblemonBlocks.YELLOW_CAMPFIRE_POT, "yellow")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_GREEN = campfirePotItem(CobblemonBlocks.GREEN_CAMPFIRE_POT, "green")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_BLUE = campfirePotItem(CobblemonBlocks.BLUE_CAMPFIRE_POT, "blue")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_PINK = campfirePotItem(CobblemonBlocks.PINK_CAMPFIRE_POT, "pink")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_BLACK = campfirePotItem(CobblemonBlocks.BLACK_CAMPFIRE_POT, "black")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_WHITE = campfirePotItem(CobblemonBlocks.WHITE_CAMPFIRE_POT, "white")
|
||||
|
||||
@JvmField
|
||||
val HEARTY_GRAINS = compostableItem("hearty_grains", ItemNameBlockItem(CobblemonBlocks.HEARTY_GRAINS, Properties().rarity(Rarity.COMMON)))
|
||||
@JvmField
|
||||
val HEARTY_GRAIN_BALE = compostableBlockItem("hearty_grain_bale", CobblemonBlocks.HEARTY_GRAIN_BALE, 0.85f)
|
||||
|
||||
@JvmField
|
||||
val TATAMI_BLOCK = blockItem("tatami_block", CobblemonBlocks.TATAMI_BLOCK)
|
||||
@JvmField
|
||||
val TATAMI_MAT = blockItem("tatami_mat", CobblemonBlocks.TATAMI_MAT)
|
||||
|
||||
@JvmField
|
||||
val VIVICHOKE = compostableItem("vivichoke")
|
||||
|
||||
@@ -261,6 +306,166 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val GIMMIGHOUL_CHEST = this.create("gimmighoul_chest", BlockItem(CobblemonBlocks.GIMMIGHOUL_CHEST, Item.Properties()))
|
||||
|
||||
// Saccharines
|
||||
@JvmField
|
||||
val SACCHARINE_LOG = blockItem("saccharine_log", CobblemonBlocks.SACCHARINE_LOG)
|
||||
@JvmField
|
||||
val SACCHARINE_HONEY_LOG = blockItem("saccharine_honey_log", CobblemonBlocks.SACCHARINE_HONEY_LOG)
|
||||
@JvmField
|
||||
val STRIPPED_SACCHARINE_LOG = blockItem("stripped_saccharine_log", CobblemonBlocks.STRIPPED_SACCHARINE_LOG)
|
||||
@JvmField
|
||||
val SACCHARINE_WOOD = blockItem("saccharine_wood", CobblemonBlocks.SACCHARINE_WOOD)
|
||||
@JvmField
|
||||
val STRIPPED_SACCHARINE_WOOD = blockItem("stripped_saccharine_wood", CobblemonBlocks.STRIPPED_SACCHARINE_WOOD)
|
||||
@JvmField
|
||||
val SACCHARINE_PLANKS = blockItem("saccharine_planks", CobblemonBlocks.SACCHARINE_PLANKS)
|
||||
@JvmField
|
||||
val SACCHARINE_LEAVES = compostableBlockItem("saccharine_leaves", CobblemonBlocks.SACCHARINE_LEAVES)
|
||||
@JvmField
|
||||
val SACCHARINE_BOAT = create("saccharine_boat", CobblemonBoatItem(CobblemonBoatType.SACCHARINE, false, Item.Properties().stacksTo(1)))
|
||||
@JvmField
|
||||
val SACCHARINE_CHEST_BOAT = create("saccharine_chest_boat", CobblemonBoatItem(CobblemonBoatType.SACCHARINE, true, Item.Properties().stacksTo(1)))
|
||||
|
||||
@JvmField
|
||||
val SACCHARINE_DOOR = blockItem("saccharine_door", CobblemonBlocks.SACCHARINE_DOOR)
|
||||
@JvmField
|
||||
val SACCHARINE_TRAPDOOR = blockItem("saccharine_trapdoor", CobblemonBlocks.SACCHARINE_TRAPDOOR)
|
||||
@JvmField
|
||||
val SACCHARINE_FENCE = blockItem("saccharine_fence", CobblemonBlocks.SACCHARINE_FENCE)
|
||||
@JvmField
|
||||
val SACCHARINE_FENCE_GATE = blockItem("saccharine_fence_gate", CobblemonBlocks.SACCHARINE_FENCE_GATE)
|
||||
@JvmField
|
||||
val SACCHARINE_BUTTON = blockItem("saccharine_button", CobblemonBlocks.SACCHARINE_BUTTON)
|
||||
@JvmField
|
||||
val SACCHARINE_PRESSURE_PLATE = blockItem("saccharine_pressure_plate", CobblemonBlocks.SACCHARINE_PRESSURE_PLATE)
|
||||
@JvmField
|
||||
val SACCHARINE_SLAB = blockItem("saccharine_slab", CobblemonBlocks.SACCHARINE_SLAB)
|
||||
@JvmField
|
||||
val SACCHARINE_STAIRS = blockItem("saccharine_stairs", CobblemonBlocks.SACCHARINE_STAIRS)
|
||||
@JvmField
|
||||
val SACCHARINE_SIGN = this.create("saccharine_sign", SignItem(Item.Properties().stacksTo(16), CobblemonBlocks.SACCHARINE_SIGN, CobblemonBlocks.SACCHARINE_WALL_SIGN))
|
||||
@JvmField
|
||||
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", HangingSignItem(CobblemonBlocks.SACCHARINE_HANGING_SIGN, CobblemonBlocks.SACCHARINE_WALL_HANGING_SIGN, Item.Properties().stacksTo(16)))
|
||||
@JvmField
|
||||
val SACCHARINE_SAPLING = compostableBlockItem("saccharine_sapling", CobblemonBlocks.SACCHARINE_SAPLING)
|
||||
|
||||
@JvmField
|
||||
val BUGWORT = compostableBlockItem("bugwort", CobblemonBlocks.BUGWORT)
|
||||
@JvmField
|
||||
val POKE_BAIT = noSettingsItem("poke_bait")
|
||||
|
||||
@JvmField
|
||||
val LURE_CAKE = blockItem("lure_cake", CobblemonBlocks.LURE_CAKE)
|
||||
@JvmField
|
||||
val POKE_CAKE = blockItem("poke_cake", CobblemonBlocks.POKE_CAKE)
|
||||
|
||||
val aprijuices = mutableListOf<AprijuiceItem>()
|
||||
@JvmField
|
||||
val APRIJUICE_RED = aprijuiceItem(Apricorn.RED)
|
||||
@JvmField
|
||||
val APRIJUICE_YELLOW = aprijuiceItem(Apricorn.YELLOW)
|
||||
@JvmField
|
||||
val APRIJUICE_GREEN = aprijuiceItem(Apricorn.GREEN)
|
||||
@JvmField
|
||||
val APRIJUICE_BLUE = aprijuiceItem(Apricorn.BLUE)
|
||||
@JvmField
|
||||
val APRIJUICE_PINK = aprijuiceItem(Apricorn.PINK)
|
||||
@JvmField
|
||||
val APRIJUICE_BLACK = aprijuiceItem(Apricorn.BLACK)
|
||||
@JvmField
|
||||
val APRIJUICE_WHITE = aprijuiceItem(Apricorn.WHITE)
|
||||
|
||||
@JvmField
|
||||
val PONIGIRI = create("ponigiri", PonigiriItem())
|
||||
|
||||
@JvmField
|
||||
val SINISTER_TEA = create("sinister_tea", SinisterTeaItem())
|
||||
|
||||
@JvmField
|
||||
val POKE_PUFF = pokepuffItem("poke_puff")
|
||||
|
||||
// FOODS
|
||||
@JvmField
|
||||
val SWEET_HEART = noSettingsItem("sweet_heart") // todo make a SweetHeartItem class for breeding purposes
|
||||
|
||||
@JvmField
|
||||
val TASTY_TAIL = noSettingsItem("tasty_tail")
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val PEWTER_CRUNCHIES = regionalFoodItem("pewter_crunchies", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f, false)
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val RAGE_CANDY_BAR = regionalFoodItem("rage_candy_bar", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f, false)
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val LAVA_COOKIE = regionalFoodItem("lava_cookie", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val OLD_GATEAU = regionalFoodItem("old_gateau", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val CASTELIACONE = regionalFoodItem("casteliacone", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val SHALOUR_SABLE = regionalFoodItem("shalour_sable", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val LUMIOSE_GALETTE = regionalFoodItem("lumiose_galette", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val BIG_MALASADA = regionalFoodItem("big_malasada", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val SMOKED_TAIL_CURRY = regionalFoodItem("smoked_tail_curry", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f, false, ItemStack(Items.BOWL, 1))
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val JUBILIFE_MUFFIN = regionalFoodItem("jubilife_muffin", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
|
||||
|
||||
@JvmField // todo get final values for this from vera
|
||||
val OPEN_FACED_SANDWICH = regionalFoodItem("open_faced_sandwich", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
|
||||
|
||||
// todo we might need to wait on these for later? These impact battles and may be harder to do
|
||||
/*@JvmField
|
||||
val CHOICE_DUMPLING = noSettingsItem("choice_dumpling") // todo make a ChoiceDumpingItem class for battle purposes
|
||||
@JvmField
|
||||
val SWAP_SNACK = noSettingsItem("swap_snack") // todo make a SwapSnackItem class for battle purposes
|
||||
@JvmField
|
||||
val TWICE_SPICED_BEETROOT = noSettingsItem("twice_spiced_beetroot") // todo make a TwiceSpiceBeetrootItem class for battle purposes
|
||||
*/
|
||||
@JvmField
|
||||
val POTATO_MOCHI = create("potato_mochi", CobblemonItem(Properties().stacksTo(16)
|
||||
.food(FoodProperties.Builder()
|
||||
.nutrition(10) // todo get final values for this from vera
|
||||
.saturationModifier(1.2F) // todo get final values for this from vera
|
||||
.alwaysEdible()
|
||||
.build())))
|
||||
@JvmField
|
||||
val FRIED_RICE = create("fried_rice", CobblemonItem(Properties().stacksTo(16)
|
||||
.food(FoodProperties.Builder()
|
||||
.nutrition(10) // todo get final values for this from vera
|
||||
.saturationModifier(1.2F) // todo get final values for this from vera
|
||||
.alwaysEdible()
|
||||
.build())))
|
||||
@JvmField
|
||||
val CANDIED_APPLE = create("candied_apple", CobblemonItem(Properties().stacksTo(16)
|
||||
.food(FoodProperties.Builder()
|
||||
.nutrition(10) // todo get final values for this from vera
|
||||
.saturationModifier(1.2F) // todo get final values for this from vera
|
||||
.alwaysEdible()
|
||||
.build())))
|
||||
@JvmField
|
||||
val CANDIED_BERRY = create("candied_berry", CobblemonItem(Properties().stacksTo(16)
|
||||
.food(FoodProperties.Builder()
|
||||
.nutrition(10) // todo get final values for this from vera
|
||||
.saturationModifier(1.2F) // todo get final values for this from vera
|
||||
.alwaysEdible()
|
||||
.build())))
|
||||
|
||||
//@JvmField
|
||||
//val SCATTER_BANG = this.create("scatter_bang", ScatterBangItem(Item.Settings()))
|
||||
//@JvmField
|
||||
//val STICKY_GLOB = this.create("sticky_glob", StickyGlobItem(Item.Settings()))
|
||||
|
||||
@JvmField
|
||||
val RESTORATION_TANK = blockItem("restoration_tank", CobblemonBlocks.RESTORATION_TANK)
|
||||
@JvmField
|
||||
@@ -276,7 +481,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val DISPLAY_CASE = blockItem("display_case", CobblemonBlocks.DISPLAY_CASE)
|
||||
@JvmField
|
||||
val LECTERN = blockItem("lectern", CobblemonBlocks.LECTERN)
|
||||
val INCENSE_SWEET = blockItem("incense_sweet", CobblemonBlocks.INCENSE_SWEET)
|
||||
|
||||
@JvmField
|
||||
val COPPER_FAN = blockItem("copper_fan", CobblemonBlocks.COPPER_FAN)
|
||||
@JvmField
|
||||
val COPPER_MOWER = blockItem("copper_mower", CobblemonBlocks.COPPER_MOWER)
|
||||
@JvmField
|
||||
val COPPER_OVEN = blockItem("copper_oven", CobblemonBlocks.COPPER_OVEN)
|
||||
@JvmField
|
||||
val COPPER_WASHER = blockItem("copper_washer", CobblemonBlocks.COPPER_WASHER)
|
||||
@JvmField
|
||||
val COPPER_FRIDGE = blockItem("copper_fridge", CobblemonBlocks.COPPER_FRIDGE)
|
||||
|
||||
|
||||
// Evolution items
|
||||
@JvmField val LINK_CABLE = create("link_cable", LinkCableItem())
|
||||
@@ -317,6 +534,9 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField val AUSPICIOUS_ARMOR = heldItem("auspicious_armor")
|
||||
@JvmField val MALICIOUS_ARMOR = heldItem("malicious_armor")
|
||||
@JvmField val SHELL_HELMET = heldItem("shell_helmet")
|
||||
@JvmField val METAL_ALLOY = noSettingsItem("metal_alloy")
|
||||
@JvmField val SCROLL_OF_DARKNESS = noSettingsItem("scroll_of_darkness")
|
||||
@JvmField val SCROLL_OF_WATERS = noSettingsItem("scroll_of_waters")
|
||||
|
||||
private val berries = mutableMapOf<ResourceLocation, BerryItem>()
|
||||
// Plants
|
||||
@@ -395,6 +615,33 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val GALARICA_NUTS = create("galarica_nuts", GalaricaNutItem())
|
||||
|
||||
// Hyper Training Items
|
||||
val hyperTrainingItems = mutableListOf<HyperTrainingItem>()
|
||||
@JvmField
|
||||
val HEALTH_CANDY = hyperTrainingItem("health_candy", 1, setOf(Stats.HP), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val MIGHTY_CANDY = hyperTrainingItem("mighty_candy", 1, setOf(Stats.ATTACK), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val TOUGH_CANDY = hyperTrainingItem("tough_candy", 1, setOf(Stats.DEFENCE), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val SMART_CANDY = hyperTrainingItem("smart_candy", 1, setOf(Stats.SPECIAL_ATTACK), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val COURAGE_CANDY = hyperTrainingItem("courage_candy", 1, setOf(Stats.SPECIAL_DEFENCE), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val QUICK_CANDY = hyperTrainingItem("quick_candy", 1, setOf(Stats.SPEED), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val SICKLY_CANDY = hyperTrainingItem("sickly_candy", -1, setOf(Stats.HP), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val WEAK_CANDY = hyperTrainingItem("weak_candy", -1, setOf(Stats.ATTACK), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val BRITTLE_CANDY = hyperTrainingItem("brittle_candy", -1, setOf(Stats.DEFENCE), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val NUMB_CANDY = hyperTrainingItem("numb_candy", -1, setOf(Stats.SPECIAL_ATTACK), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val COWARD_CANDY = hyperTrainingItem("coward_candy", -1, setOf(Stats.SPECIAL_DEFENCE), 0..IVs.MAX_VALUE)
|
||||
@JvmField
|
||||
val SLOW_CANDY = hyperTrainingItem("slow_candy", -1, setOf(Stats.SPEED), 0..IVs.MAX_VALUE)
|
||||
|
||||
// Medicine
|
||||
@JvmField
|
||||
val RARE_CANDY = candyItem("rare_candy", Rarity.RARE) { _, pokemon -> pokemon.getExperienceToNextLevel() }
|
||||
@@ -421,6 +668,20 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val ZINC = create("zinc", VitaminItem(Stats.SPECIAL_DEFENCE))
|
||||
@JvmField
|
||||
val HEALTH_MOCHI = create("health_mochi", MochiItem(Stats.HP))
|
||||
@JvmField
|
||||
val MUSCLE_MOCHI = create("muscle_mochi", MochiItem(Stats.ATTACK))
|
||||
@JvmField
|
||||
val RESIST_MOCHI = create("resist_mochi", MochiItem(Stats.DEFENCE))
|
||||
@JvmField
|
||||
val GENIUS_MOCHI = create("genius_mochi", MochiItem(Stats.SPECIAL_ATTACK))
|
||||
@JvmField
|
||||
val CLEVER_MOCHI = create("clever_mochi", MochiItem(Stats.SPECIAL_DEFENCE))
|
||||
@JvmField
|
||||
val SWIFT_MOCHI = create("swift_mochi", MochiItem(Stats.SPEED))
|
||||
@JvmField
|
||||
val FRESH_START_MOCHI = create("fresh_start_mochi", FreshStartMochiItem())
|
||||
@JvmField
|
||||
val GENIUS_FEATHER = create("genius_feather", FeatherItem(Stats.SPECIAL_ATTACK))
|
||||
@JvmField
|
||||
val SWIFT_FEATHER = create("swift_feather", FeatherItem(Stats.SPEED))
|
||||
@@ -435,11 +696,11 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val MEDICINAL_LEEK = heldItem("medicinal_leek", MedicinalLeekItem(CobblemonBlocks.MEDICINAL_LEEK, Item.Properties().food(FoodProperties.Builder().fast().nutrition(1).saturationModifier(0.2f).build())), "leek")
|
||||
@JvmField
|
||||
val ROASTED_LEEK = create("roasted_leek", Item(Item.Properties().food(FoodProperties.Builder().fast().nutrition(3).saturationModifier(0.3f).build())))
|
||||
val ROASTED_LEEK = create("roasted_leek", CobblemonItem(Item.Properties().food(FoodProperties.Builder().fast().nutrition(3).saturationModifier(0.3f).build())))
|
||||
@JvmField
|
||||
val BRAISED_VIVICHOKE = create("braised_vivichoke", Item(Item.Properties().food(FoodProperties.Builder().nutrition(6).saturationModifier(0.6f).build())))
|
||||
val BRAISED_VIVICHOKE = create("braised_vivichoke", foodItem(6, 0.6F))
|
||||
@JvmField
|
||||
val VIVICHOKE_DIP = create("vivichoke_dip", object : Item(Properties().stacksTo(1)
|
||||
val VIVICHOKE_DIP = create("vivichoke_dip", object : CobblemonItem(Properties().stacksTo(1)
|
||||
.food(FoodProperties.Builder()
|
||||
.nutrition(10)
|
||||
.saturationModifier(1.2F)
|
||||
@@ -459,13 +720,15 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val PEP_UP_FLOWER = compostableBlockItem("pep_up_flower", CobblemonBlocks.PEP_UP_FLOWER)
|
||||
@JvmField
|
||||
val MEDICINAL_BREW = create("medicinal_brew", Item(Item.Properties()))
|
||||
val MEDICINAL_BREW = noSettingsItem("medicinal_brew")
|
||||
@JvmField
|
||||
val REMEDY = create("remedy", RemedyItem(RemedyItem.NORMAL))
|
||||
@JvmField
|
||||
val FINE_REMEDY = create("fine_remedy", RemedyItem(RemedyItem.FINE))
|
||||
@JvmField
|
||||
val SUPERB_REMEDY = create("superb_remedy", RemedyItem(RemedyItem.SUPERB))
|
||||
@JvmField
|
||||
val MOOMOO_MILK = noSettingsItem("moomoo_milk")
|
||||
|
||||
@JvmField
|
||||
val POTION = create("potion", PotionItem(PotionType.POTION))
|
||||
@@ -481,7 +744,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField
|
||||
val HEAL_POWDER = create("heal_powder", HealPowderItem())
|
||||
@JvmField
|
||||
val LEEK_AND_POTATO_STEW = create("leek_and_potato_stew", Item(Item.Properties().food(FoodProperties.Builder().nutrition(8).saturationModifier(0.6f).usingConvertsTo(Items.BOWL).build()).stacksTo(1)))
|
||||
val LEEK_AND_POTATO_STEW = create("leek_and_potato_stew", CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(8).saturationModifier(0.6f).usingConvertsTo(Items.BOWL).build()).stacksTo(1)))
|
||||
@JvmField
|
||||
val REVIVE = create("revive", ReviveItem(max = false))
|
||||
@JvmField
|
||||
@@ -700,8 +963,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
val CHOICE_SCARF = heldItem("choice_scarf")
|
||||
@JvmField
|
||||
val CLEANSE_TAG = heldItem("cleanse_tag")
|
||||
// @JvmField
|
||||
// val CLEAR_AMULET = heldItem("clear_amulet")
|
||||
@JvmField
|
||||
val CLEAR_AMULET = heldItem("clear_amulet")
|
||||
@JvmField
|
||||
val COVERT_CLOAK = heldItem("covert_cloak")
|
||||
@JvmField
|
||||
@@ -730,16 +993,16 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
val FOCUS_SASH = heldItem("focus_sash")
|
||||
@JvmField
|
||||
val GRASSY_SEED = heldItem("grassy_seed")
|
||||
// @JvmField
|
||||
// val GRIP_CLAW = heldItem("grip_claw")
|
||||
@JvmField
|
||||
val GRIP_CLAW = heldItem("grip_claw")
|
||||
@JvmField
|
||||
val HARD_STONE = heldItem("hard_stone")
|
||||
@JvmField
|
||||
val HEAVY_DUTY_BOOTS = heldItem("heavy_duty_boots")
|
||||
@JvmField
|
||||
val IRON_BALL = heldItem("iron_ball")
|
||||
// @JvmField
|
||||
// val LAGGING_TAIL = heldItem("lagging_tail")
|
||||
@JvmField
|
||||
val LAGGING_TAIL = heldItem("lagging_tail")
|
||||
@JvmField
|
||||
val LEFTOVERS = heldItem("leftovers")
|
||||
@JvmField
|
||||
@@ -752,8 +1015,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
val LOADED_DICE = heldItem("loaded_dice")
|
||||
@JvmField
|
||||
val LUCKY_EGG = heldItem("lucky_egg")
|
||||
// @JvmField
|
||||
// val LUMINOUS_MOSS = heldItem("luminous_moss")
|
||||
@JvmField
|
||||
val LUMINOUS_MOSS = heldItem("luminous_moss")
|
||||
@JvmField
|
||||
val MAGNET = heldItem("magnet")
|
||||
@JvmField
|
||||
@@ -1268,6 +1531,56 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
}
|
||||
)
|
||||
|
||||
private fun campfirePotItem(block: Block, type: String): CampfirePotItem {
|
||||
val item = create("campfire_pot_${type}", CampfirePotItem(block))
|
||||
campfire_pots.add(item)
|
||||
return item
|
||||
}
|
||||
|
||||
private fun aprijuiceItem(type: Apricorn): AprijuiceItem {
|
||||
val item = create("aprijuice_${type.name.lowercase()}", AprijuiceItem(type))
|
||||
aprijuices.add(item)
|
||||
return item
|
||||
}
|
||||
|
||||
private fun pokepuffItem(name: String): PokePuffItem {
|
||||
val item = create("poke_puff", PokePuffItem())
|
||||
return item
|
||||
}
|
||||
|
||||
private fun regionalFoodItem(
|
||||
name: String,
|
||||
stacksTo: Int,
|
||||
nutrition: Int,
|
||||
saturationModifier: Float,
|
||||
effect: MobEffectInstance? = null,
|
||||
effectChance: Float? = null,
|
||||
alwaysEdible: Boolean = false,
|
||||
convertsToOnUse: ItemStack? = null
|
||||
): RegionalFoodItem {
|
||||
val foodPropertiesBuilder = FoodProperties.Builder()
|
||||
.nutrition(nutrition)
|
||||
.saturationModifier(saturationModifier)
|
||||
|
||||
if (effect != null && effectChance != null) {
|
||||
foodPropertiesBuilder.effect(effect, effectChance)
|
||||
}
|
||||
|
||||
if (alwaysEdible == true) {
|
||||
foodPropertiesBuilder.alwaysEdible()
|
||||
}
|
||||
|
||||
if (convertsToOnUse != null && !convertsToOnUse.isEmpty) {
|
||||
foodPropertiesBuilder.usingConvertsTo(convertsToOnUse.item)
|
||||
}
|
||||
|
||||
val properties = Item.Properties()
|
||||
.stacksTo(stacksTo)
|
||||
.food(foodPropertiesBuilder.build())
|
||||
|
||||
return create(name, RegionalFoodItem(properties))
|
||||
}
|
||||
|
||||
private fun heldItem(name: String, remappedName: String? = null): CobblemonItem = create(
|
||||
name,
|
||||
CobblemonItem(Item.Properties()).also {
|
||||
@@ -1279,11 +1592,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
private fun heldItem(name: String, item: Item, remappedName: String? = null) = create(
|
||||
name = name,
|
||||
entry = item.also {
|
||||
if (remappedName != null) {
|
||||
remappedName?.let { remappedName ->
|
||||
CobblemonHeldItemManager.registerRemap(it, remappedName)
|
||||
CobblemonHeldItemManager.registerRemap(Items.BONE, "thickclub")
|
||||
CobblemonHeldItemManager.registerRemap(Items.SNOWBALL, "snowball")
|
||||
CobblemonHeldItemManager.registerRemap(Items.GOLD_BLOCK, "bignugget")
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -1313,6 +1623,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
return item
|
||||
}
|
||||
|
||||
private fun hyperTrainingItem(name: String, increaseAmount: Int, targetStats: Set<Stat>, validRange: IntRange): HyperTrainingItem {
|
||||
val item = this.create(name, HyperTrainingItem(increaseAmount, targetStats, validRange))
|
||||
hyperTrainingItems.add(item)
|
||||
return item
|
||||
}
|
||||
|
||||
private fun apricornItem(name: String, apricornItem: ApricornItem): ApricornItem {
|
||||
val finalName = "${name}_apricorn"
|
||||
val item = this.create(finalName, apricornItem)
|
||||
@@ -1327,6 +1643,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
return item
|
||||
}
|
||||
|
||||
|
||||
private fun mintSeed(name: String, mintBlock: MintBlock): Item {
|
||||
val finalName = "${name}_mint_seeds"
|
||||
val item = this.blockItem(finalName, mintBlock)
|
||||
@@ -1342,7 +1659,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
}
|
||||
|
||||
private fun compostableItem(name: String, item: Item? = null, increaseLevelChance: Float = .65f): Item {
|
||||
val createdItem = this.create(name, item ?: Item(Item.Properties()))
|
||||
val createdItem = this.create(name, item ?: CobblemonItem(Item.Properties()))
|
||||
compostable(createdItem, increaseLevelChance)
|
||||
return createdItem
|
||||
}
|
||||
@@ -1360,6 +1677,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
}
|
||||
|
||||
private fun foodItem(nutrition: Int, saturationModifier: Float): Item {
|
||||
return Item(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
|
||||
return CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
|
||||
import com.cobblemon.mod.common.block.campfirepot.CookingPotMenu
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.world.inventory.MenuType
|
||||
|
||||
object CobblemonMenuType : PlatformRegistry<Registry<MenuType<*>>, ResourceKey<Registry<MenuType<*>>>, MenuType<*>>() {
|
||||
|
||||
val COOKING_POT = MenuType.register("cooking_pot", ::CookingPotMenu)
|
||||
|
||||
override val registry: Registry<MenuType<*>>
|
||||
get() = BuiltInRegistries.MENU
|
||||
override val resourceKey: ResourceKey<Registry<MenuType<*>>>
|
||||
get() = Registries.MENU
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import com.cobblemon.mod.common.client.net.battle.*
|
||||
import com.cobblemon.mod.common.client.net.callback.move.OpenMoveCallbackHandler
|
||||
import com.cobblemon.mod.common.client.net.callback.party.OpenPartyCallbackHandler
|
||||
import com.cobblemon.mod.common.client.net.callback.partymove.OpenPartyMoveCallbackHandler
|
||||
import com.cobblemon.mod.common.client.net.cooking.ToggleCookingPotLidHandler
|
||||
import com.cobblemon.mod.common.client.net.data.DataRegistrySyncPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.data.UnlockReloadPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.dialogue.DialogueClosedHandler
|
||||
@@ -69,6 +70,8 @@ import com.cobblemon.mod.common.net.messages.client.battle.*
|
||||
import com.cobblemon.mod.common.net.messages.client.callback.OpenMoveCallbackPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyCallbackPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyMoveCallbackPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.cooking.SeasoningRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.cooking.ToggleCookingPotLidPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.*
|
||||
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueClosedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
|
||||
@@ -145,6 +148,8 @@ import com.cobblemon.mod.common.net.messages.server.callback.party.PartyPokemonS
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.party.PartySelectCancelledPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.partymove.PartyMoveSelectCancelledPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.partymove.PartyPokemonMoveSelectedPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingStatRangePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingStatsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.dialogue.EscapeDialoguePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.dialogue.InputToDialoguePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.npc.SaveNPCPacket
|
||||
@@ -190,6 +195,8 @@ import com.cobblemon.mod.common.net.serverhandling.callback.party.PartyPokemonSe
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.party.PartySelectCancelledHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.partymove.PartyMoveSelectCancelledHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.partymove.PartyPokemonMoveSelectedHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRidingStatRangeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRidingStatsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.dialogue.EscapeDialogueHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.dialogue.InputToDialogueHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.evolution.AcceptEvolutionHandler
|
||||
@@ -252,6 +259,7 @@ object CobblemonNetwork {
|
||||
|
||||
// Pokemon Update Packets
|
||||
list.add(PacketRegisterInfo(FriendshipUpdatePacket.ID, FriendshipUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(FullnessUpdatePacket.ID, FullnessUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(MoveSetUpdatePacket.ID, MoveSetUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(NatureUpdatePacket.ID, NatureUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(ShinyUpdatePacket.ID, ShinyUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
@@ -285,6 +293,7 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(MarksUpdatePacket.ID, MarksUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(MarksPotentialUpdatePacket.ID, MarksPotentialUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(MarkingsUpdatePacket.ID, MarkingsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
list.add(PacketRegisterInfo(RideBoostsUpdatePacket.ID, RideBoostsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||
|
||||
// Evolution start
|
||||
list.add(PacketRegisterInfo(AddEvolutionPacket.ID, AddEvolutionPacket::decode, PokemonUpdatePacketHandler()))
|
||||
@@ -374,7 +383,8 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(ScriptRegistrySyncPacket.ID, ScriptRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(PokedexDexSyncPacket.ID, PokedexDexSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(DexEntrySyncPacket.ID, DexEntrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(FishingBaitRegistrySyncPacket.ID, FishingBaitRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(SpawnBaitRegistrySyncPacket.ID, SpawnBaitRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(SeasoningRegistrySyncPacket.ID, SeasoningRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(FlowRegistrySyncPacket.ID, FlowRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(CosmeticItemAssignmentSyncPacket.ID, CosmeticItemAssignmentSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(BehaviourSyncPacket.ID, BehaviourSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
@@ -544,6 +554,11 @@ object CobblemonNetwork {
|
||||
// Riding packet(s)
|
||||
list.add(PacketRegisterInfo(ServerboundUpdateOrientationPacket.ID, ServerboundUpdateOrientationPacket::decode, OrientationPacketHandler))
|
||||
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatePacket.ID, ServerboundUpdateRidingStatePacket::decode, ServerboundUpdateRidingStateHandler))
|
||||
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatsPacket.ID, ServerboundUpdateRidingStatsPacket::decode, ServerboundUpdateRidingStatsHandler))
|
||||
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatRangePacket.ID, ServerboundUpdateRidingStatRangePacket::decode, ServerboundUpdateRidingStatRangeHandler))
|
||||
|
||||
// Cooking
|
||||
list.add(PacketRegisterInfo(ToggleCookingPotLidPacket.ID, ToggleCookingPotLidPacket::decode, ToggleCookingPotLidHandler))
|
||||
|
||||
// Behaviour Packets
|
||||
list.add(PacketRegisterInfo(SetEntityBehaviourPacket.ID, SetEntityBehaviourPacket::decode, SetEntityBehaviourHandler))
|
||||
|
||||
+14
-2
@@ -19,7 +19,7 @@ import net.minecraft.world.entity.ai.village.poi.PoiType
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
|
||||
object CobblemonVillagerPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Registry<PoiType>>, PoiType>() {
|
||||
object CobblemonPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Registry<PoiType>>, PoiType>() {
|
||||
override val registry: Registry<PoiType> = BuiltInRegistries.POINT_OF_INTEREST_TYPE
|
||||
override val resourceKey: ResourceKey<Registry<PoiType>> = Registries.POINT_OF_INTEREST_TYPE
|
||||
|
||||
@@ -27,8 +27,20 @@ object CobblemonVillagerPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKe
|
||||
val NURSE_KEY: ResourceKey<PoiType> = createKey("nurse")
|
||||
@JvmField
|
||||
val NURSE = create(NURSE_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.HEALING_MACHINE), 1, 1))
|
||||
@JvmField
|
||||
val LURE_CAKE_KEY: ResourceKey<PoiType> = createKey("lure_cake")
|
||||
@JvmField
|
||||
val LURE_CAKE = create(LURE_CAKE_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.LURE_CAKE), 0, 1))
|
||||
@JvmField
|
||||
val SACCHARINE_HONEY_LOG_KEY: ResourceKey<PoiType> = createKey("saccharine_honey_log")
|
||||
@JvmField
|
||||
val SACCHARINE_HONEY_LOG = create(SACCHARINE_HONEY_LOG_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.SACCHARINE_HONEY_LOG), 0, 1))
|
||||
@JvmField
|
||||
val INCENSE_SWEET_KEY: ResourceKey<PoiType> = createKey("incense_sweet")
|
||||
@JvmField
|
||||
val INCENSE_SWEET = create(INCENSE_SWEET_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.INCENSE_SWEET), 0, 1))
|
||||
|
||||
private fun createKey(string: String): ResourceKey<PoiType> = ResourceKey.create(Registries.POINT_OF_INTEREST_TYPE, cobblemonResource(string))
|
||||
|
||||
private fun getBlockStates(block: Block): Set<BlockState> = ImmutableSet.copyOf(block.stateDefinition.possibleStates)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import net.minecraft.client.RecipeBookCategories
|
||||
|
||||
enum class CobblemonRecipeCategories {
|
||||
|
||||
COOKING_POT_SEARCH("COOKING_POT_SEARCH"),
|
||||
COOKING_POT_FOODS("COOKING_POT_FOODS"),
|
||||
COOKING_POT_MEDICINES("COOKING_POT_MEDICINES"),
|
||||
COOKING_POT_COMPLEX_DISHES("COOKING_POT_COMPLEX_DISHES"),
|
||||
COOKING_POT_MISC("COOKING_POT_MISC");
|
||||
|
||||
companion object {
|
||||
val customAggregateCategories: Map<RecipeBookCategories, List<RecipeBookCategories>> = mapOf(
|
||||
COOKING_POT_SEARCH.toVanillaCategory() to listOf(
|
||||
COOKING_POT_FOODS.toVanillaCategory(), COOKING_POT_MISC.toVanillaCategory(), COOKING_POT_MEDICINES.toVanillaCategory(), COOKING_POT_COMPLEX_DISHES.toVanillaCategory()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
var id: String
|
||||
|
||||
constructor(id: String) {
|
||||
this.id = id
|
||||
}
|
||||
|
||||
fun toVanillaCategory(): RecipeBookCategories {
|
||||
return RecipeBookCategories.valueOf(this.id)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.world.item.crafting.Recipe
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer
|
||||
|
||||
object CobblemonRecipeSerializers : PlatformRegistry<Registry<RecipeSerializer<*>>, ResourceKey<Registry<RecipeSerializer<*>>>, RecipeSerializer<*>>() {
|
||||
|
||||
val COOKING_POT_COOKING: RecipeSerializer<*> = register("cobblemon:cooking_pot", CookingPotRecipe.Serializer())
|
||||
val COOKING_POT_SHAPELESS: RecipeSerializer<*> = register("cobblemon:cooking_pot_shapeless", CookingPotShapelessRecipe.Serializer())
|
||||
|
||||
val BREWING_STAND: RecipeSerializer<*> = register("cobblemon:brewing_stand", BrewingStandRecipe.Serializer())
|
||||
|
||||
override val registry: Registry<RecipeSerializer<*>>
|
||||
get() = BuiltInRegistries.RECIPE_SERIALIZER
|
||||
override val resourceKey: ResourceKey<Registry<RecipeSerializer<*>>>
|
||||
get() = Registries.RECIPE_SERIALIZER
|
||||
|
||||
fun <S : RecipeSerializer<T>, T : Recipe<*>> register(key: String, recipeSerializer: S): S {
|
||||
return Registry.register(BuiltInRegistries.RECIPE_SERIALIZER, key, recipeSerializer) as S
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
|
||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceKey
|
||||
import net.minecraft.world.item.crafting.Recipe
|
||||
import net.minecraft.world.item.crafting.RecipeType
|
||||
|
||||
object CobblemonRecipeTypes : PlatformRegistry<Registry<RecipeType<*>>, ResourceKey<Registry<RecipeType<*>>>, RecipeType<*>>() {
|
||||
|
||||
val COOKING_POT_COOKING: RecipeType<CookingPotRecipe> = register("cobblemon:cooking_pot")
|
||||
val COOKING_POT_SHAPELESS: RecipeType<CookingPotShapelessRecipe> = register("cobblemon:cooking_pot_shapeless")
|
||||
|
||||
val BREWING_STAND: RecipeType<BrewingStandRecipe> = register("cobblemon:brewing_stand")
|
||||
|
||||
override val registry: Registry<RecipeType<*>>
|
||||
get() = BuiltInRegistries.RECIPE_TYPE
|
||||
override val resourceKey: ResourceKey<Registry<RecipeType<*>>>
|
||||
get() = Registries.RECIPE_TYPE
|
||||
|
||||
fun <T : Recipe<*>> register(identifier: String): RecipeType<T> {
|
||||
return Registry.register(
|
||||
BuiltInRegistries.RECIPE_TYPE,
|
||||
identifier,
|
||||
object : RecipeType<T> {
|
||||
override fun toString(): String {
|
||||
return identifier
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,8 +43,18 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
@JvmField
|
||||
val PC_WALLPAPER_UNLOCK = this.create("pc.wallpaper.unlock")
|
||||
|
||||
@JvmField
|
||||
val NPC_GIBBER_GENERIC = this.create("entity.npc.gibber.generic")
|
||||
@JvmField
|
||||
val NPC_GIBBER_SPEECH_TYPE_1_1 = this.create("entity.npc.gibber.speech_type_1_1")
|
||||
@JvmField
|
||||
val NPC_GIBBER_SPEECH_TYPE_1_2 = this.create("entity.npc.gibber.speech_type_1_2")
|
||||
@JvmField
|
||||
val NPC_GIBBER_SPEECH_TYPE_1_3 = this.create("entity.npc.gibber.speech_type_1_3")
|
||||
|
||||
@JvmField
|
||||
val VILLAGER_WORK_NURSE = this.create("entity.villager.work_nurse")
|
||||
|
||||
@JvmField
|
||||
val HEALING_MACHINE_ACTIVE = this.create("block.healing_machine.active")
|
||||
|
||||
@@ -112,6 +122,9 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
val MEDICINE_SPRAY_USE = this.create("item.medicine.spray.use")
|
||||
@JvmField
|
||||
val MEDICINE_FEATHER_USE = this.create("item.medicine.feather.use")
|
||||
@JvmField
|
||||
val MOCHI_USE = this.create("item.medicine.feather.use")
|
||||
|
||||
|
||||
@JvmField
|
||||
val MULCH_PLACE = this.create("block.mulch.place")
|
||||
@@ -204,6 +217,8 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
val BERRY_HARVEST = this.create("block.berry_bush.harvest")
|
||||
@JvmField
|
||||
val BERRY_EAT = this.create("item.berry.eat")
|
||||
@JvmField
|
||||
val BERRY_EAT_FULL = this.create("item.berry.eat.full")
|
||||
|
||||
@JvmField
|
||||
val BIG_ROOT_BREAK = this.create("block.big_root.break")
|
||||
@@ -425,5 +440,37 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
|
||||
DISPLAY_CASE_STEP
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_PLACE_CAMPFIRE = this.create("block.campfire_pot.place_campfire")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_RETRIEVE = this.create("block.campfire_pot.retrieve")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_OPEN = this.create("block.campfire_pot.open")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_CLOSE = this.create("block.campfire_pot.close")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_USE = this.create("block.campfire_pot.use")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_COOK = this.create("block.campfire_pot.cook")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_CRAFT = this.create("block.campfire_pot.craft")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_PLACE = this.create("block.campfire_pot.place")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_BREAK = this.create("block.campfire_pot.break")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_HIT = this.create("block.campfire_pot.hit")
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_STEP = this.create("block.campfire_pot.step")
|
||||
|
||||
@JvmField
|
||||
val CAMPFIRE_POT_SOUNDS = SoundType(1f, 1.1f,
|
||||
CAMPFIRE_POT_BREAK,
|
||||
CAMPFIRE_POT_STEP,
|
||||
CAMPFIRE_POT_PLACE,
|
||||
CAMPFIRE_POT_HIT,
|
||||
CAMPFIRE_POT_STEP
|
||||
)
|
||||
|
||||
private fun create(name: String): SoundEvent = this.create(name, SoundEvent.createVariableRangeEvent(cobblemonResource(name)))
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ object CobblemonVillagerProfessions: PlatformRegistry<Registry<VillagerProfessio
|
||||
override val resourceKey: ResourceKey<Registry<VillagerProfession>> = Registries.VILLAGER_PROFESSION
|
||||
|
||||
@JvmField
|
||||
val NURSE = profession(CobblemonVillagerPoiTypes.NURSE_KEY, CobblemonSounds.VILLAGER_WORK_NURSE)
|
||||
val NURSE = profession(CobblemonPoiTypes.NURSE_KEY, CobblemonSounds.VILLAGER_WORK_NURSE)
|
||||
|
||||
/**
|
||||
* Register a villager profession texture override for Cobblemon villagers of the given [VillagerProfession] for specified names.
|
||||
|
||||
+3
-32
@@ -18,7 +18,7 @@ import java.util.Optional
|
||||
|
||||
class AspectCriterion(
|
||||
playerCtx: Optional<ContextAwarePredicate>,
|
||||
val pokemon: ResourceLocation,
|
||||
val species: ResourceLocation,
|
||||
val aspects: List<String>
|
||||
): SimpleCriterionCondition<MutableMap<ResourceLocation, MutableSet<String>>>(playerCtx) {
|
||||
|
||||
@@ -26,42 +26,13 @@ class AspectCriterion(
|
||||
val CODEC: Codec<AspectCriterion> = RecordCodecBuilder.create { it.group(
|
||||
//All three of these codecs used to use Codecs.createStrictOptionalFieldCodec, that no longer exists
|
||||
ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(AspectCriterion::playerCtx),
|
||||
ResourceLocation.CODEC.optionalFieldOf("pokemon", cobblemonResource("pikachu")).forGetter(AspectCriterion::pokemon),
|
||||
ResourceLocation.CODEC.optionalFieldOf("species", cobblemonResource("pikachu")).forGetter(AspectCriterion::species),
|
||||
Codec.STRING.listOf().optionalFieldOf("aspects", listOf()).forGetter(AspectCriterion::aspects)
|
||||
) .apply(it, ::AspectCriterion) }
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer, context: MutableMap<ResourceLocation, MutableSet<String>>): Boolean {
|
||||
val caughtAspects = context.getOrDefault(pokemon, mutableSetOf())
|
||||
val caughtAspects = context.getOrDefault(species, mutableSetOf())
|
||||
return this.aspects.all { it in caughtAspects }
|
||||
}
|
||||
}
|
||||
|
||||
//open class AspectCriterionTrigger(identifier: Identifier, criterionClass: Class<AspectCriterionCondition>) : SimpleCriterionTrigger<MutableMap<Identifier, MutableSet<String>>, AspectCriterionCondition>(identifier, criterionClass) {
|
||||
//
|
||||
//}
|
||||
//
|
||||
//class AspectCriterionCondition(id: Identifier, predicate: LootContextPredicate) : SimpleCriterionCondition<MutableMap<Identifier, MutableSet<String>>>(id, predicate) {
|
||||
// var pokemon = Identifier.of("cobblemon:pikachu")
|
||||
// var aspects = mutableListOf<String>()
|
||||
// override fun toJson(json: JsonObject) {
|
||||
// json.add("aspects", JsonArray(aspects.size).also {
|
||||
// aspects.forEach { aspect -> it.add(aspect) }
|
||||
// })
|
||||
// json.addProperty("pokemon", pokemon.toString())
|
||||
// }
|
||||
//
|
||||
// override fun fromJson(json: JsonObject) {
|
||||
// aspects.clear()
|
||||
// json.getAsJsonArray("aspects").forEach { element ->
|
||||
// aspects.add(element.asString)
|
||||
// }
|
||||
// pokemon = json.get("pokemon").asString.asIdentifierDefaultingNamespace()
|
||||
// }
|
||||
//
|
||||
// override fun matches(player: ServerPlayer, context: MutableMap<Identifier, MutableSet<String>>): Boolean {
|
||||
// val caughtAspects = context.getOrDefault(pokemon, mutableSetOf())
|
||||
// return this.aspects.all { it in caughtAspects }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
+2
-2
@@ -20,8 +20,8 @@ import net.minecraft.resources.ResourceLocation
|
||||
class CastPokeRodContext(val baitId: ResourceLocation)
|
||||
|
||||
class CastPokeRodCriterionCondition(
|
||||
playerCtx: Optional<ContextAwarePredicate>,
|
||||
val baitId: String
|
||||
playerCtx: Optional<ContextAwarePredicate>,
|
||||
val baitId: String
|
||||
): SimpleCriterionCondition<CastPokeRodContext>(playerCtx) {
|
||||
|
||||
companion object {
|
||||
|
||||
+4
-21
@@ -21,40 +21,23 @@ import java.util.Optional
|
||||
* @author Hiroku
|
||||
* @since November 4th, 2022
|
||||
*/
|
||||
open class CountablePokemonTypeContext(times: Int, var type: String) : CountableContext(times)
|
||||
open class CountablePokemonTypeContext(times: Int, var species: String) : CountableContext(times)
|
||||
|
||||
class CaughtPokemonCriterion(
|
||||
playerCtx: Optional<ContextAwarePredicate>,
|
||||
val type: String,
|
||||
val species: String,
|
||||
count: Int
|
||||
): CountableCriterion<CountablePokemonTypeContext>(playerCtx, count) {
|
||||
|
||||
companion object {
|
||||
val CODEC: Codec<CaughtPokemonCriterion> = RecordCodecBuilder.create { it.group(
|
||||
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(CaughtPokemonCriterion::playerCtx),
|
||||
Codec.STRING.optionalFieldOf("type", "any").forGetter(CaughtPokemonCriterion::type),
|
||||
Codec.STRING.optionalFieldOf("species", "any").forGetter(CaughtPokemonCriterion::species),
|
||||
Codec.INT.optionalFieldOf("count", 0).forGetter(CaughtPokemonCriterion::count)
|
||||
).apply(it, ::CaughtPokemonCriterion) }
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer, context: CountablePokemonTypeContext): Boolean {
|
||||
return super.matches(player, context) && (context.type == type || type == "any")
|
||||
return super.matches(player, context) && (context.species == species || species == "any")
|
||||
}
|
||||
}
|
||||
|
||||
//class CaughtPokemonCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<CountablePokemonTypeContext>(id, predicate) {
|
||||
// var type = "any"
|
||||
// override fun toJson(json: JsonObject) {
|
||||
// super.toJson(json)
|
||||
// json.addProperty("type", type)
|
||||
// }
|
||||
//
|
||||
// override fun fromJson(json: JsonObject) {
|
||||
// super.fromJson(json)
|
||||
// type = json.get("type")?.asString ?: "any"
|
||||
// }
|
||||
//
|
||||
// override fun matches(player: ServerPlayer, context: CountablePokemonTypeContext): Boolean {
|
||||
// return super.matches(player, context) && (context.type == type || type == "any")
|
||||
// }
|
||||
//}
|
||||
+5
-2
@@ -19,17 +19,20 @@ import java.util.Optional
|
||||
|
||||
class PokemonCriterion(
|
||||
playerCtx: Optional<ContextAwarePredicate>,
|
||||
val species: String,
|
||||
val properties: PokemonProperties
|
||||
): SimpleCriterionCondition<Pokemon>(playerCtx) {
|
||||
|
||||
companion object {
|
||||
val CODEC: Codec<PokemonCriterion> = RecordCodecBuilder.create { it.group(
|
||||
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(PokemonCriterion::playerCtx),
|
||||
Codec.STRING.optionalFieldOf("species", "any").forGetter(PokemonCriterion::species),
|
||||
PokemonProperties.CODEC.optionalFieldOf("properties", PokemonProperties()).forGetter(PokemonCriterion::properties)
|
||||
).apply(it, ::PokemonCriterion) }
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer, context: Pokemon): Boolean {
|
||||
return properties.matches(context)
|
||||
var speciesCheck = (species.equals(context.species.resourceIdentifier.path) || species.equals(context.species.resourceIdentifier.toString())) || species.equals("any")
|
||||
return speciesCheck && properties.matches(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -17,22 +17,22 @@ import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import java.util.Optional
|
||||
|
||||
class PokemonInteractContext(val type: ResourceLocation, val item: ResourceLocation)
|
||||
class PokemonInteractContext(val species: ResourceLocation, val item: ResourceLocation)
|
||||
|
||||
class PokemonInteractCriterion(
|
||||
playerCtx: Optional<ContextAwarePredicate>,
|
||||
val type: String,
|
||||
val species: String,
|
||||
val item: String
|
||||
): SimpleCriterionCondition<PokemonInteractContext>(playerCtx) {
|
||||
companion object {
|
||||
val CODEC: Codec<PokemonInteractCriterion> = RecordCodecBuilder.create { it.group(
|
||||
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(PokemonInteractCriterion::playerCtx),
|
||||
Codec.STRING.optionalFieldOf("type", "any").forGetter(PokemonInteractCriterion::type),
|
||||
Codec.STRING.optionalFieldOf("species", "any").forGetter(PokemonInteractCriterion::species),
|
||||
Codec.STRING.optionalFieldOf("item", "any").forGetter(PokemonInteractCriterion::item)
|
||||
).apply(it, ::PokemonInteractCriterion) }
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer, context: PokemonInteractContext): Boolean {
|
||||
return (context.type == this.type.asIdentifierDefaultingNamespace() || this.type == "any") && (context.item == this.item.asIdentifierDefaultingNamespace() || this.item == "any")
|
||||
return (context.species == this.species.asIdentifierDefaultingNamespace() || this.species == "any") && (context.item == this.item.asIdentifierDefaultingNamespace() || this.item == "any")
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -17,23 +17,23 @@ import net.minecraft.advancements.critereon.EntityPredicate
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
class ReelInPokemonContext(val pokemonId : ResourceLocation, val baitId: ResourceLocation)
|
||||
class ReelInPokemonContext(val species : ResourceLocation, val baitId: ResourceLocation)
|
||||
|
||||
class ReelInPokemonCriterionCondition(
|
||||
playerCtx: Optional<ContextAwarePredicate>,
|
||||
val pokemonId: String,
|
||||
val species: String,
|
||||
val baitId: String
|
||||
) : SimpleCriterionCondition<ReelInPokemonContext>(playerCtx) {
|
||||
|
||||
companion object {
|
||||
val CODEC: Codec<ReelInPokemonCriterionCondition> = RecordCodecBuilder.create { it.group(
|
||||
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter { it.playerCtx },
|
||||
Codec.STRING.optionalFieldOf("pokemonId", "any").forGetter { it.pokemonId },
|
||||
Codec.STRING.optionalFieldOf("species", "any").forGetter { it.species },
|
||||
Codec.STRING.optionalFieldOf("baitId", "empty_bait").forGetter { it.baitId }
|
||||
).apply(it, { playerCtx, pokemonId, baitId -> ReelInPokemonCriterionCondition(playerCtx, pokemonId, baitId.ifEmpty { "empty_bait" }) }) }
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayer, context: ReelInPokemonContext): Boolean {
|
||||
return (context.pokemonId == this.pokemonId.asIdentifierDefaultingNamespace() || this.pokemonId == "any") && (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId == "empty_bait")
|
||||
return (context.species == this.species.asIdentifierDefaultingNamespace() || this.species == "any") && (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId == "empty_bait")
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@ import net.minecraft.world.entity.schedule.Activity
|
||||
import net.minecraft.world.entity.schedule.Schedule
|
||||
|
||||
class BehaviourConfigurationContext {
|
||||
var appliedBehaviours: MutableSet<ResourceLocation> = mutableSetOf()
|
||||
var appliedBehaviours: Set<ResourceLocation> = setOf()
|
||||
|
||||
var defaultActivity = Activity.IDLE
|
||||
var coreActivities = setOf(Activity.CORE)
|
||||
|
||||
@@ -15,8 +15,10 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangV
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
/**
|
||||
@@ -33,17 +35,16 @@ import net.minecraft.world.entity.LivingEntity
|
||||
*/
|
||||
interface BehaviourConfig {
|
||||
companion object {
|
||||
val types = mutableMapOf<String, Class<out BehaviourConfig>>(
|
||||
"script" to ScriptBehaviourConfig::class.java,
|
||||
"custom_script" to CustomScriptBehaviourConfig::class.java,
|
||||
"add_tasks_to_activity" to AddTasksToActivity::class.java,
|
||||
"apply_behaviours" to ApplyBehaviours::class.java,
|
||||
"set_default_activity" to SetDefaultActivity::class.java,
|
||||
"set_core_activities" to SetCoreActivities::class.java,
|
||||
"add_variables" to AddVariablesConfig::class.java,
|
||||
"set_variables" to SetVariablesConfig::class.java,
|
||||
val types = mutableMapOf<ResourceLocation, Class<out BehaviourConfig>>(
|
||||
cobblemonResource("script") to ScriptBehaviourConfig::class.java,
|
||||
cobblemonResource("custom_script") to CustomScriptBehaviourConfig::class.java,
|
||||
cobblemonResource("add_tasks_to_activity") to AddTasksToActivity::class.java,
|
||||
cobblemonResource("apply_behaviours") to ApplyBehaviours::class.java,
|
||||
cobblemonResource("set_default_activity") to SetDefaultActivity::class.java,
|
||||
cobblemonResource("set_core_activities") to SetCoreActivities::class.java,
|
||||
cobblemonResource("add_variables") to AddVariablesConfig::class.java,
|
||||
cobblemonResource("set_variables") to SetVariablesConfig::class.java,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
fun checkCondition(entity: LivingEntity, expressionOrEntityVariable: ExpressionOrEntityVariable): Boolean {
|
||||
|
||||
+3
-1
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.api.ai.config.task.WanderTaskConfig.Companion.WA
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
@@ -46,6 +47,7 @@ class AirWanderTaskConfig : SingleTaskConfig {
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
|
||||
|
||||
return BehaviorBuilder.create {
|
||||
it.group(
|
||||
@@ -58,7 +60,7 @@ class AirWanderTaskConfig : SingleTaskConfig {
|
||||
}
|
||||
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
val wanderChance = wanderChance.resolveFloat()
|
||||
val wanderChance = runtime.resolveFloat(wanderChanceExpression)
|
||||
if (wanderChance <= 0 || world.random.nextFloat() > wanderChance) return@Trigger false
|
||||
|
||||
val rotVec = entity.getViewVector(0F)
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.npc.ai.MeleeAttackTask
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.BattleFlightTask
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class BattleFlightTaskConfig : SingleTaskConfig {
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
if (entity !is PokemonEntity) {
|
||||
return null
|
||||
}
|
||||
return BattleFlightTask.create()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
# Task Configuration
|
||||
|
||||
A task configuration is responsible for producing one or multiple tasks as part of a
|
||||
[BrainConfiguration](../README.md). Tasks are the smallest unit of behaviour in a brain and are executed
|
||||
[Behaviour Configuration](../README.md). Tasks are the smallest unit of behaviour in a brain and are executed
|
||||
as part of an activity.
|
||||
|
||||
A task configuration can be a simple string that represents the type of task to create, or a JSON object
|
||||
|
||||
@@ -50,7 +50,10 @@ class RunScript : SingleTaskConfig {
|
||||
).apply(it) { _ ->
|
||||
Trigger { world, entity, _ ->
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
return@Trigger CobblemonScripts.run(script.resolveString().asIdentifierDefaultingNamespace(), runtime) == DoubleValue.ONE
|
||||
return@Trigger CobblemonScripts.run(
|
||||
identifier = script.resolveString().asIdentifierDefaultingNamespace(),
|
||||
runtime = runtime
|
||||
) == DoubleValue.ONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-10
@@ -14,25 +14,27 @@ import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.TamableAnimal
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
|
||||
class SwitchFromSleepOnTrainerBedTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||
): BehaviorControl<in LivingEntity> {
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
// Why'd you give them this task then, dipshit?
|
||||
if (entity !is PokemonEntity) {
|
||||
return null
|
||||
}
|
||||
|
||||
return BehaviorBuilder.create {
|
||||
it.group(
|
||||
it.registered(CobblemonMemories.POKEMON_SLEEPING)
|
||||
).apply(it) { pokemonSleeping ->
|
||||
Trigger { world, entity, _ ->
|
||||
// Why'd you give them this task then, dipshit?
|
||||
if (entity !is TamableAnimal) {
|
||||
return@Trigger false
|
||||
}
|
||||
entity as PokemonEntity
|
||||
|
||||
// If they're owner is gone then we can consider that a reason to wake up, dogs do this too
|
||||
val owner = entity.owner
|
||||
@@ -41,7 +43,7 @@ class SwitchFromSleepOnTrainerBedTaskConfig : SingleTaskConfig {
|
||||
// If we should move back to regular behaviours...
|
||||
if (owner == null || !owner.isSleeping) {
|
||||
// If it's willingly sleeping then it can lose the sleeping memory
|
||||
if (isCurrentlySleeping && (entity !is PokemonEntity || entity.pokemon.status?.status != Statuses.SLEEP)) {
|
||||
if (isCurrentlySleeping && entity.pokemon.status?.status != Statuses.SLEEP) {
|
||||
pokemonSleeping.erase()
|
||||
return@Trigger false
|
||||
}
|
||||
@@ -57,7 +59,4 @@ class SwitchFromSleepOnTrainerBedTaskConfig : SingleTaskConfig {
|
||||
}
|
||||
}
|
||||
|
||||
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -32,8 +32,9 @@ class SwitchToFightTaskConfig : SingleTaskConfig {
|
||||
it.present(MemoryModuleType.ATTACK_TARGET)
|
||||
).apply(it) { _ ->
|
||||
Trigger { world, entity, _ ->
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (entity.commandSenderWorld.getCurrentDifficultyAt(entity.blockPosition()).difficulty == Difficulty.PEACEFUL) return@Trigger false
|
||||
if (entity.commandSenderWorld.getCurrentDifficultyAt(entity.blockPosition()).difficulty == Difficulty.PEACEFUL) {
|
||||
return@Trigger false
|
||||
}
|
||||
|
||||
entity.brain.setActiveActivityIfPossible(activity)
|
||||
return@Trigger true
|
||||
|
||||
@@ -8,13 +8,20 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.ast.NumberExpression
|
||||
import com.bedrockk.molang.ast.StringExpression
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveDouble
|
||||
@@ -22,6 +29,7 @@ import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.util.resolveString
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
@@ -36,59 +44,60 @@ import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
*/
|
||||
interface TaskConfig {
|
||||
companion object {
|
||||
val types = mutableMapOf<String, Class<out TaskConfig>>(
|
||||
"one_of" to OneOfTaskConfig::class.java,
|
||||
"wander" to WanderTaskConfig::class.java,
|
||||
"water_wander" to WaterWanderTaskConfig::class.java,
|
||||
"air_wander" to AirWanderTaskConfig::class.java,
|
||||
"look_at_target" to LookAtTargetTaskConfig::class.java,
|
||||
"follow_walk_target" to FollowWalkTargetTaskConfig::class.java,
|
||||
"random" to RandomTaskConfig::class.java,
|
||||
"stay_afloat" to StayAfloatTaskConfig::class.java,
|
||||
"look_at_entities" to LookAtEntitiesTaskConfig::class.java,
|
||||
"do_nothing" to DoNothingTaskConfig::class.java,
|
||||
"get_angry_at_attacker" to GetAngryAtAttackerTaskConfig::class.java,
|
||||
"stop_being_angry_if_attacker_dead" to StopBeingAngryIfAttackerDeadTaskConfig::class.java,
|
||||
"switch_npc_to_battle" to SwitchToNPCBattleTaskConfig::class.java,
|
||||
"look_at_battling_pokemon" to LookAtBattlingPokemonTaskConfig::class.java,
|
||||
"switch_npc_from_battle" to SwitchFromNPCBattleTaskConfig::class.java,
|
||||
"switch_pokemon_to_battle" to SwitchToPokemonBattleTaskConfig::class.java,
|
||||
"look_at_targeted_battle_pokemon" to LookAtTargetedBattlePokemonTaskConfig::class.java,
|
||||
"switch_pokemon_from_battle" to SwitchFromPokemonBattleTaskConfig::class.java,
|
||||
"go_to_healing_machine" to GoToHealingMachineTaskConfig::class.java,
|
||||
"heal_using_healing_machine" to HealUsingHealingMachineTaskConfig::class.java,
|
||||
"all_of" to AllOfTaskConfig::class.java,
|
||||
"attack_angry_at" to AttackAngryAtTaskConfig::class.java,
|
||||
"move_to_attack_target" to MoveToAttackTargetTaskConfig::class.java,
|
||||
"melee_attack" to MeleeAttackTaskConfig::class.java,
|
||||
"switch_from_fight" to SwitchFromFightTaskConfig::class.java,
|
||||
"switch_to_fight" to SwitchToFightTaskConfig::class.java,
|
||||
"switch_to_chatting" to SwitchToChattingTaskConfig::class.java,
|
||||
"switch_from_chatting" to SwitchFromChattingTaskConfig::class.java,
|
||||
"look_at_speaker" to LookAtSpeakerTaskConfig::class.java,
|
||||
"switch_to_action_effect" to SwitchToActionEffectTaskConfig::class.java,
|
||||
"switch_from_action_effect" to SwitchFromActionEffectTaskConfig::class.java,
|
||||
"exit_battle_when_hurt" to ExitBattleWhenHurtTaskConfig::class.java,
|
||||
"switch_to_panic_when_hurt" to SwitchToPanicWhenHurtTaskConfig::class.java,
|
||||
"switch_to_panic_when_hostiles_nearby" to SwitchToPanicWhenHostilesNearbyTaskConfig::class.java,
|
||||
"calm_down" to CalmDownTaskConfig::class.java,
|
||||
"flee_attacker" to FleeAttackerTaskConfig::class.java,
|
||||
"flee_nearest_hostile" to FleeNearestHostileTaskConfig::class.java,
|
||||
"run_script" to RunScript::class.java,
|
||||
"look_in_direction" to LookInDirectionTaskConfig::class.java,
|
||||
"wake_up" to WakeUpTaskConfig::class.java,
|
||||
"go_to_sleep" to GoToSleepTaskConfig::class.java,
|
||||
"find_resting_place" to FindRestingPlaceTaskConfig::class.java,
|
||||
"move_to_owner" to MoveToOwnerTaskConfig::class.java,
|
||||
"switch_to_sleep_on_trainer_bed" to SwitchToSleepOnTrainerBedTaskConfig::class.java,
|
||||
"switch_from_sleep_on_trainer_bed" to SwitchFromSleepOnTrainerBedTaskConfig::class.java,
|
||||
"sleep_if_on_trainer_bed" to SleepIfOnTrainerBedTaskConfig::class.java,
|
||||
"point_to_spawn" to PointToSpawnTaskConfig::class.java,
|
||||
"eat_grass" to EatGrassTaskConfig::class.java,
|
||||
"find_air" to FindAirTaskConfig::class.java,
|
||||
"go_to_land" to GoToLandTaskConfig::class.java
|
||||
val types = mutableMapOf<ResourceLocation, Class<out TaskConfig>>(
|
||||
cobblemonResource("one_of") to OneOfTaskConfig::class.java,
|
||||
cobblemonResource("wander") to WanderTaskConfig::class.java,
|
||||
cobblemonResource("water_wander") to WaterWanderTaskConfig::class.java,
|
||||
cobblemonResource("air_wander") to AirWanderTaskConfig::class.java,
|
||||
cobblemonResource("look_at_target") to LookAtTargetTaskConfig::class.java,
|
||||
cobblemonResource("follow_walk_target") to FollowWalkTargetTaskConfig::class.java,
|
||||
cobblemonResource("random") to RandomTaskConfig::class.java,
|
||||
cobblemonResource("stay_afloat") to StayAfloatTaskConfig::class.java,
|
||||
cobblemonResource("look_at_entities") to LookAtEntitiesTaskConfig::class.java,
|
||||
cobblemonResource("do_nothing") to DoNothingTaskConfig::class.java,
|
||||
cobblemonResource("get_angry_at_attacker") to GetAngryAtAttackerTaskConfig::class.java,
|
||||
cobblemonResource("stop_being_angry_if_attacker_dead") to StopBeingAngryIfAttackerDeadTaskConfig::class.java,
|
||||
cobblemonResource("switch_npc_to_battle") to SwitchToNPCBattleTaskConfig::class.java,
|
||||
cobblemonResource("look_at_battling_pokemon") to LookAtBattlingPokemonTaskConfig::class.java,
|
||||
cobblemonResource("switch_npc_from_battle") to SwitchFromNPCBattleTaskConfig::class.java,
|
||||
cobblemonResource("switch_pokemon_to_battle") to SwitchToPokemonBattleTaskConfig::class.java,
|
||||
cobblemonResource("look_at_targeted_battle_pokemon") to LookAtTargetedBattlePokemonTaskConfig::class.java,
|
||||
cobblemonResource("switch_pokemon_from_battle") to SwitchFromPokemonBattleTaskConfig::class.java,
|
||||
cobblemonResource("go_to_healing_machine") to GoToHealingMachineTaskConfig::class.java,
|
||||
cobblemonResource("heal_using_healing_machine") to HealUsingHealingMachineTaskConfig::class.java,
|
||||
cobblemonResource("all_of") to AllOfTaskConfig::class.java,
|
||||
cobblemonResource("attack_angry_at") to AttackAngryAtTaskConfig::class.java,
|
||||
cobblemonResource("move_to_attack_target") to MoveToAttackTargetTaskConfig::class.java,
|
||||
cobblemonResource("melee_attack") to MeleeAttackTaskConfig::class.java,
|
||||
cobblemonResource("switch_from_fight") to SwitchFromFightTaskConfig::class.java,
|
||||
cobblemonResource("switch_to_fight") to SwitchToFightTaskConfig::class.java,
|
||||
cobblemonResource("switch_to_chatting") to SwitchToChattingTaskConfig::class.java,
|
||||
cobblemonResource("switch_from_chatting") to SwitchFromChattingTaskConfig::class.java,
|
||||
cobblemonResource("look_at_speaker") to LookAtSpeakerTaskConfig::class.java,
|
||||
cobblemonResource("switch_to_action_effect") to SwitchToActionEffectTaskConfig::class.java,
|
||||
cobblemonResource("switch_from_action_effect") to SwitchFromActionEffectTaskConfig::class.java,
|
||||
cobblemonResource("exit_battle_when_hurt") to ExitBattleWhenHurtTaskConfig::class.java,
|
||||
cobblemonResource("switch_to_panic_when_hurt") to SwitchToPanicWhenHurtTaskConfig::class.java,
|
||||
cobblemonResource("switch_to_panic_when_hostiles_nearby") to SwitchToPanicWhenHostilesNearbyTaskConfig::class.java,
|
||||
cobblemonResource("calm_down") to CalmDownTaskConfig::class.java,
|
||||
cobblemonResource("flee_attacker") to FleeAttackerTaskConfig::class.java,
|
||||
cobblemonResource("flee_nearest_hostile") to FleeNearestHostileTaskConfig::class.java,
|
||||
cobblemonResource("run_script") to RunScript::class.java,
|
||||
cobblemonResource("look_in_direction") to LookInDirectionTaskConfig::class.java,
|
||||
cobblemonResource("wake_up") to WakeUpTaskConfig::class.java,
|
||||
cobblemonResource("go_to_sleep") to GoToSleepTaskConfig::class.java,
|
||||
cobblemonResource("find_resting_place") to FindRestingPlaceTaskConfig::class.java,
|
||||
cobblemonResource("move_to_owner") to MoveToOwnerTaskConfig::class.java,
|
||||
cobblemonResource("switch_to_sleep_on_trainer_bed") to SwitchToSleepOnTrainerBedTaskConfig::class.java,
|
||||
cobblemonResource("switch_from_sleep_on_trainer_bed") to SwitchFromSleepOnTrainerBedTaskConfig::class.java,
|
||||
cobblemonResource("sleep_if_on_trainer_bed") to SleepIfOnTrainerBedTaskConfig::class.java,
|
||||
cobblemonResource("point_to_spawn") to PointToSpawnTaskConfig::class.java,
|
||||
cobblemonResource("eat_grass") to EatGrassTaskConfig::class.java,
|
||||
cobblemonResource("find_air") to FindAirTaskConfig::class.java,
|
||||
cobblemonResource("go_to_land") to GoToLandTaskConfig::class.java,
|
||||
cobblemonResource("battle_flight_task") to BattleFlightTaskConfig::class.java
|
||||
)
|
||||
|
||||
|
||||
val runtime = MoLangRuntime().setup()
|
||||
}
|
||||
|
||||
@@ -100,6 +109,23 @@ interface TaskConfig {
|
||||
return expressionOrEntityVariable.resolveBoolean()
|
||||
}
|
||||
|
||||
fun ExpressionOrEntityVariable.asSimplifiedExpression(entity: LivingEntity): Expression {
|
||||
return map(
|
||||
{ it },
|
||||
{
|
||||
if (entity is MoLangScriptingEntity) {
|
||||
val variable = entity.config.map[it.variableName]
|
||||
if (variable is DoubleValue) {
|
||||
return@map NumberExpression(variable.value)
|
||||
} else if (variable is StringValue) {
|
||||
return@map StringExpression(variable)
|
||||
}
|
||||
}
|
||||
return@map "q.entity.config.${it.variableName}".asExpression()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun ExpressionOrEntityVariable.asExpression() = map({ it }, { "q.entity.config.${it.variableName}".asExpression() })
|
||||
fun ExpressionOrEntityVariable.resolveString() = runtime.resolveString(asExpression())
|
||||
fun ExpressionOrEntityVariable.resolveBoolean() = runtime.resolveBoolean(asExpression())
|
||||
|
||||
+4
-1
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.entity.ai.CobblemonWalkTarget
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
@@ -51,6 +52,8 @@ class WanderTaskConfig : SingleTaskConfig {
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
|
||||
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
|
||||
|
||||
return BehaviorBuilder.create {
|
||||
it.group(
|
||||
it.absent(MemoryModuleType.WALK_TARGET),
|
||||
@@ -63,7 +66,7 @@ class WanderTaskConfig : SingleTaskConfig {
|
||||
}
|
||||
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
val wanderChance = wanderChance.resolveFloat()
|
||||
val wanderChance = runtime.resolveFloat(wanderChanceExpression)
|
||||
if (wanderChance <= 0 || world.random.nextFloat() > wanderChance) return@Trigger false
|
||||
|
||||
pathCooldown.setWithExpiry(true, 40L)
|
||||
|
||||
+4
-1
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.api.ai.config.task.WanderTaskConfig.Companion.WA
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
@@ -45,6 +46,8 @@ class WaterWanderTaskConfig : SingleTaskConfig {
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
|
||||
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
|
||||
|
||||
return BehaviorBuilder.create {
|
||||
it.group(
|
||||
it.absent(MemoryModuleType.WALK_TARGET),
|
||||
@@ -56,7 +59,7 @@ class WaterWanderTaskConfig : SingleTaskConfig {
|
||||
}
|
||||
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
val wanderChance = wanderChance.resolveFloat()
|
||||
val wanderChance = runtime.resolveFloat(wanderChanceExpression)
|
||||
if (wanderChance <= 0 || world.random.nextFloat() > wanderChance) {
|
||||
return@Trigger false
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.api.apricorn
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlocks
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.cooking.Flavour
|
||||
import com.cobblemon.mod.common.block.ApricornBlock
|
||||
import com.cobblemon.mod.common.block.ApricornSaplingBlock
|
||||
import com.cobblemon.mod.common.item.ApricornItem
|
||||
@@ -27,15 +28,43 @@ import net.minecraft.world.level.material.MapColor
|
||||
* @author Licious
|
||||
* @since October 29th, 2022
|
||||
*/
|
||||
enum class Apricorn : StringRepresentable {
|
||||
enum class Apricorn(
|
||||
/** A value of true means it buffs that flavour, a value of false means it weakens that flavour. */
|
||||
val flavourStrength: Map<Flavour, Boolean> = emptyMap()
|
||||
) : StringRepresentable {
|
||||
|
||||
BLACK,
|
||||
BLUE,
|
||||
GREEN,
|
||||
PINK,
|
||||
RED,
|
||||
BLUE(
|
||||
mapOf(
|
||||
Flavour.DRY to true,
|
||||
Flavour.BITTER to false
|
||||
)
|
||||
),
|
||||
GREEN(
|
||||
mapOf(
|
||||
Flavour.BITTER to true,
|
||||
Flavour.SWEET to false
|
||||
)
|
||||
),
|
||||
PINK(
|
||||
mapOf(
|
||||
Flavour.SWEET to true,
|
||||
Flavour.SPICY to false
|
||||
)
|
||||
),
|
||||
RED(
|
||||
mapOf(
|
||||
Flavour.SPICY to true,
|
||||
Flavour.SOUR to false
|
||||
)
|
||||
),
|
||||
WHITE,
|
||||
YELLOW;
|
||||
YELLOW(
|
||||
mapOf(
|
||||
Flavour.SOUR to true,
|
||||
Flavour.DRY to false
|
||||
)
|
||||
);
|
||||
|
||||
fun item(): ApricornItem = when(this) {
|
||||
BLACK -> CobblemonItems.BLACK_APRICORN
|
||||
|
||||
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.berry
|
||||
import com.cobblemon.mod.common.CobblemonBlocks
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.berry.spawncondition.BerrySpawnCondition
|
||||
import com.cobblemon.mod.common.api.cooking.Flavour
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.berry.BerryYieldCalculationEvent
|
||||
import com.cobblemon.mod.common.api.mulch.MulchVariant
|
||||
@@ -20,16 +21,10 @@ import com.cobblemon.mod.common.item.berry.BerryItem
|
||||
import com.cobblemon.mod.common.pokemon.Nature
|
||||
import com.cobblemon.mod.common.util.readBox
|
||||
import com.cobblemon.mod.common.util.readEnumConstant
|
||||
import com.cobblemon.mod.common.util.readEnumSet
|
||||
import com.cobblemon.mod.common.util.readIdentifier
|
||||
import com.cobblemon.mod.common.util.readList
|
||||
import com.cobblemon.mod.common.util.readMap
|
||||
import com.cobblemon.mod.common.util.writeBox
|
||||
import com.cobblemon.mod.common.util.writeCollection
|
||||
import com.cobblemon.mod.common.util.writeEnumConstant
|
||||
import com.cobblemon.mod.common.util.writeEnumSet
|
||||
import com.cobblemon.mod.common.util.writeIdentifier
|
||||
import com.cobblemon.mod.common.util.writeMap
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
@@ -38,6 +33,7 @@ import java.util.EnumSet
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.biome.Biome
|
||||
import net.minecraft.world.level.block.Block
|
||||
@@ -61,7 +57,7 @@ import net.minecraft.world.phys.shapes.VoxelShape
|
||||
* @property growthPoints A collection of [GrowthPoint]s for the berry flowers and fruit.
|
||||
* @property sproutShapeBoxes A collection of [Box]es that make up the tree [VoxelShape] during the sprouting stages.
|
||||
* @property matureShapeBoxes A collection of [Box]es that make up the tree [VoxelShape] during the mature stages.
|
||||
* @property flavors The [Flavor] values.
|
||||
* @property flavours The [com.cobblemon.mod.common.api.cooking.Flavour] values.
|
||||
* @property tintIndexes Determines tints at specific indexes if any.
|
||||
* @property flowerModelIdentifier The [ResourceLocation] for the model of the berry in flower form.
|
||||
* @property flowerTexture The [ResourceLocation] for the texture of the berry in flower form. This is resolved into a [ModelPart] on the client.
|
||||
@@ -87,7 +83,10 @@ class Berry(
|
||||
private val sproutShapeBoxes: Collection<AABB>,
|
||||
@SerializedName("matureShape")
|
||||
private val matureShapeBoxes: Collection<AABB>,
|
||||
private val flavors: Map<Flavor, Int>,
|
||||
@SerializedName("flavours", alternate = ["flavor"])
|
||||
val flavours: Map<Flavour, Int>,
|
||||
@SerializedName("colour", alternate = ["color"])
|
||||
val colour: DyeColor,
|
||||
val tintIndexes: Map<Int, Color>,
|
||||
@SerializedName("flowerModel")
|
||||
val flowerModelIdentifier: ResourceLocation,
|
||||
@@ -144,13 +143,13 @@ class Berry(
|
||||
/**
|
||||
* Query the value of a certain flavor.
|
||||
*
|
||||
* @param flavor The [Flavor] being queried.
|
||||
* @param flavour The [Flavour] being queried.
|
||||
* @return The value if any or 0.
|
||||
*/
|
||||
fun flavor(flavor: Flavor): Int = this.flavors[flavor] ?: 0
|
||||
fun flavor(flavour: Flavour): Int = this.flavours[flavour] ?: 0
|
||||
|
||||
fun dislikedBy(nature: Nature): Boolean {
|
||||
val dislikedFlavor = nature.dislikedFlavor ?: return false
|
||||
val dislikedFlavor = nature.dislikedFlavour ?: return false
|
||||
return flavor(dislikedFlavor) > 0
|
||||
}
|
||||
|
||||
@@ -281,7 +280,8 @@ class Berry(
|
||||
buffer.writeCollection(this.matureShapeBoxes) { writer, value ->
|
||||
writer.writeBox(value)
|
||||
}
|
||||
buffer.writeMap(this.flavors, { writer, key -> writer.writeEnumConstant(key) }, { writer, value -> writer.writeInt(value) })
|
||||
buffer.writeMap(this.flavours, { writer, key -> writer.writeEnumConstant(key) }, { writer, value -> writer.writeInt(value) })
|
||||
buffer.writeEnumConstant(colour)
|
||||
buffer.writeMap(this.tintIndexes, { writer, key -> writer.writeInt(key) }, { writer, value -> writer.writeInt(value.rgb) })
|
||||
buffer.writeIdentifier(this.flowerModelIdentifier)
|
||||
buffer.writeIdentifier(this.flowerTexture)
|
||||
@@ -353,7 +353,8 @@ class Berry(
|
||||
val mutations = buffer.readMap({ reader -> reader.readIdentifier() }, { reader -> reader.readIdentifier() })
|
||||
val sproutShapeBoxes = buffer.readList { it.readBox() }
|
||||
val matureShapeBoxes = buffer.readList { it.readBox() }
|
||||
val flavors = buffer.readMap({ reader -> reader.readEnumConstant(Flavor::class.java) }, { reader -> reader.readInt() })
|
||||
val flavors = buffer.readMap({ reader -> reader.readEnumConstant(Flavour::class.java) }, { reader -> reader.readInt() })
|
||||
val colour = buffer.readEnumConstant(DyeColor::class.java)
|
||||
val tintIndexes = buffer.readMap({ reader -> reader.readInt() }, { reader -> Color(reader.readInt()) })
|
||||
val flowerModelIdentifier = buffer.readIdentifier()
|
||||
val flowerTexture = buffer.readIdentifier()
|
||||
@@ -361,7 +362,7 @@ class Berry(
|
||||
val fruitTexture = buffer.readIdentifier()
|
||||
val stageOneYPos = GrowthPoint(Vec3(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()), Vec3(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()))
|
||||
val boneMealChance = buffer.readFloat()
|
||||
return Berry(identifier, baseYield, emptyList(), growthTime, refreshRate, favMulchs, emptySet(), emptyList(), growthPoints, randomizedGrowthPoints, mutations, sproutShapeBoxes, matureShapeBoxes, flavors, tintIndexes, flowerModelIdentifier, flowerTexture, fruitModelIdentifier, fruitTexture, stageOneYPos, 0F, boneMealChance)
|
||||
return Berry(identifier, baseYield, emptyList(), growthTime, refreshRate, favMulchs, emptySet(), emptyList(), growthPoints, randomizedGrowthPoints, mutations, sproutShapeBoxes, matureShapeBoxes, flavors, colour, tintIndexes, flowerModelIdentifier, flowerTexture, fruitModelIdentifier, fruitTexture, stageOneYPos, 0F, boneMealChance)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.berry
|
||||
|
||||
/**
|
||||
* Represents the different flavors associated with berries and other Pokémon consumables.
|
||||
* See the [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Flavor) article for more information.
|
||||
*
|
||||
* @author Licious
|
||||
* @since November 28th, 2022
|
||||
*/
|
||||
enum class Flavor(val colour: Int) {
|
||||
SPICY(0x00FF00),
|
||||
DRY(0xFF0000),
|
||||
SWEET(0x0000FF),
|
||||
BITTER(0xFFFF00),
|
||||
SOUR(0xFF00FF);
|
||||
}
|
||||
@@ -125,10 +125,11 @@ open class PartySelectPokemonDTO(
|
||||
val heldItem: ItemStack = ItemStack.EMPTY,
|
||||
var currentHealth: Int,
|
||||
var maxHealth: Int,
|
||||
var enabled: Boolean
|
||||
var enabled: Boolean,
|
||||
var hoverText: List<Component> = emptyList()
|
||||
) {
|
||||
@JvmOverloads
|
||||
constructor(pokemon: Pokemon, enabled: Boolean = true): this(
|
||||
constructor(pokemon: Pokemon, enabled: Boolean = true, hoverText: List<Component> = emptyList()): this(
|
||||
pokemonProperties = pokemon.createPokemonProperties(
|
||||
PokemonPropertyExtractor.SPECIES,
|
||||
PokemonPropertyExtractor.LEVEL,
|
||||
@@ -140,7 +141,8 @@ open class PartySelectPokemonDTO(
|
||||
heldItem = pokemon.heldItemNoCopy(),
|
||||
currentHealth = pokemon.currentHealth,
|
||||
maxHealth = pokemon.maxHealth,
|
||||
enabled = enabled
|
||||
enabled = enabled,
|
||||
hoverText = hoverText
|
||||
)
|
||||
|
||||
constructor(buffer: RegistryFriendlyByteBuf): this(
|
||||
@@ -149,7 +151,8 @@ open class PartySelectPokemonDTO(
|
||||
heldItem = buffer.readItemStack(),
|
||||
currentHealth = buffer.readInt(),
|
||||
maxHealth = buffer.readInt(),
|
||||
enabled = buffer.readBoolean()
|
||||
enabled = buffer.readBoolean(),
|
||||
hoverText = buffer.readList { buffer.readText() }
|
||||
)
|
||||
|
||||
fun writeToBuffer(buffer: RegistryFriendlyByteBuf) {
|
||||
@@ -159,6 +162,6 @@ open class PartySelectPokemonDTO(
|
||||
buffer.writeInt(currentHealth)
|
||||
buffer.writeInt(maxHealth)
|
||||
buffer.writeBoolean(enabled)
|
||||
buffer.writeCollection(hoverText) { _, text -> buffer.writeText(text) }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.util.StringRepresentable
|
||||
|
||||
/**
|
||||
* Represents the different flavors associated with berries and other Pokémon consumables.
|
||||
* See the [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Flavor) article for more information.
|
||||
*
|
||||
* @author Licious
|
||||
* @since November 28th, 2022
|
||||
*/
|
||||
enum class Flavour(val colour: Int, val chatFormatting: ChatFormatting): StringRepresentable {
|
||||
SPICY(0x00FF00, ChatFormatting.RED),
|
||||
DRY(0xFF0000, ChatFormatting.DARK_AQUA),
|
||||
SWEET(0x0000FF, ChatFormatting.LIGHT_PURPLE),
|
||||
BITTER(0xFFFF00, ChatFormatting.GREEN),
|
||||
SOUR(0xFF00FF, ChatFormatting.YELLOW),
|
||||
MILD(0xFF00FF, ChatFormatting.DARK_PURPLE);
|
||||
|
||||
override fun getSerializedName() = name
|
||||
companion object {
|
||||
val CODEC = StringRepresentable.fromEnum<Flavour> { Flavour.entries.toTypedArray() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import net.minecraft.util.FastColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
private val colourMap = mapOf(
|
||||
Flavour.SPICY to 0xFEB37D,
|
||||
Flavour.DRY to 0x8AE9FC,
|
||||
Flavour.SWEET to 0xFFBEED,
|
||||
Flavour.BITTER to 0x9EED8F,
|
||||
Flavour.SOUR to 0xFCF38A
|
||||
)
|
||||
|
||||
private val bubbleColourMap = mapOf(
|
||||
Flavour.SPICY to 0xFFD9AD,
|
||||
Flavour.DRY to 0xBCF8FE,
|
||||
Flavour.SWEET to 0xFEE3F9,
|
||||
Flavour.BITTER to 0xC8F7BC,
|
||||
Flavour.SOUR to 0xFDFAB8
|
||||
)
|
||||
|
||||
fun getColourMixFromSeasonings(seasonings: List<ItemStack>, forBubbles: Boolean = false): Int? {
|
||||
val flavors = seasonings
|
||||
.mapNotNull { Seasonings.getFlavoursFromItemStack(it) }
|
||||
.flatMap { it.entries }
|
||||
.groupingBy { it.key }
|
||||
.fold(0) { acc, entry -> acc + entry.value }
|
||||
|
||||
if (flavors.isEmpty()) return null
|
||||
|
||||
val maxFlavorValue = flavors.values.maxOrNull()
|
||||
val dominantFlavors = flavors.filter { it.value == maxFlavorValue }.map { it.key }
|
||||
|
||||
return getColourMixFromFlavours(dominantFlavors, forBubbles)
|
||||
}
|
||||
|
||||
fun getColourMixFromFlavours(dominantFlavours: List<Flavour>, forBubbles: Boolean = false): Int? {
|
||||
val colors =
|
||||
dominantFlavours.mapNotNull { if (forBubbles) bubbleColourMap[it] else colourMap[it] }
|
||||
.map { FastColor.ARGB32.opaque(it) }
|
||||
|
||||
if (colors.isEmpty()) return null
|
||||
|
||||
val (alphaSum, redSum, greenSum, blueSum) = colors.fold(IntArray(4)) { acc, color ->
|
||||
acc[0] += FastColor.ARGB32.alpha(color)
|
||||
acc[1] += FastColor.ARGB32.red(color)
|
||||
acc[2] += FastColor.ARGB32.green(color)
|
||||
acc[3] += FastColor.ARGB32.blue(color)
|
||||
acc
|
||||
}
|
||||
|
||||
return FastColor.ARGB32.color(
|
||||
alphaSum / colors.size,
|
||||
redSum / colors.size,
|
||||
greenSum / colors.size,
|
||||
blueSum / colors.size
|
||||
)
|
||||
}
|
||||
|
||||
fun getColourMixFromColors(colors: List<Int>): Int? {
|
||||
if (colors.isEmpty()) return null
|
||||
|
||||
val (alphaSum, redSum, greenSum, blueSum) = colors.fold(IntArray(4)) { acc, color ->
|
||||
acc[0] += FastColor.ARGB32.alpha(color)
|
||||
acc[1] += FastColor.ARGB32.red(color)
|
||||
acc[2] += FastColor.ARGB32.green(color)
|
||||
acc[3] += FastColor.ARGB32.blue(color)
|
||||
acc
|
||||
}
|
||||
|
||||
return FastColor.ARGB32.color(
|
||||
alphaSum / colors.size,
|
||||
redSum / colors.size,
|
||||
greenSum / colors.size,
|
||||
blueSum / colors.size
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import com.cobblemon.mod.common.item.components.FoodComponent
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
|
||||
data class Food(
|
||||
val hunger: Int = 0,
|
||||
val saturation: Float = 0f,
|
||||
) {
|
||||
companion object {
|
||||
val CODEC: Codec<Food> = RecordCodecBuilder.create { builder ->
|
||||
builder.group(
|
||||
Codec.INT.optionalFieldOf("hunger", 0).forGetter { it.hunger },
|
||||
Codec.FLOAT.optionalFieldOf("saturation", 0f).forGetter { it.saturation },
|
||||
).apply(builder, ::Food)
|
||||
}
|
||||
}
|
||||
|
||||
fun toComponent(): FoodComponent = FoodComponent(hunger, saturation)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import com.cobblemon.mod.common.item.components.FoodComponent
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.round
|
||||
|
||||
object FoodUtils {
|
||||
fun merge(components: List<FoodComponent>, extraHunger: Int = 0, extraSaturation: Float = 0f): FoodComponent {
|
||||
if (components.isEmpty()) return FoodComponent(0, 0f)
|
||||
|
||||
val count = components.size
|
||||
val totalHunger = components.sumOf { it.hunger.toDouble() } + extraHunger
|
||||
val totalSaturation = components.sumOf { it.saturation.toDouble() } + extraSaturation
|
||||
|
||||
val multiplier = when (count) {
|
||||
1 -> 1.0
|
||||
2 -> 0.8
|
||||
3 -> 0.6
|
||||
else -> 0.4
|
||||
}
|
||||
|
||||
val adjustedHunger = ceil(totalHunger * multiplier)
|
||||
val adjustedSaturation = totalSaturation * multiplier
|
||||
|
||||
return FoodComponent(
|
||||
hunger = adjustedHunger.toInt(),
|
||||
saturation = (round(adjustedSaturation * 100) / 100f).toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import net.minecraft.world.effect.MobEffectInstance
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
|
||||
object MobEffectUtils {
|
||||
fun mergeEffects(effects: List<SerializableMobEffectInstance>): List<SerializableMobEffectInstance> {
|
||||
val grouped = effects.groupBy { it.effect }
|
||||
|
||||
return grouped.map { (effectId, group) ->
|
||||
val amplifier = mergeAmplifiers(group.map { it.amplifier })
|
||||
val duration = mergeDurations(group.map { it.duration })
|
||||
|
||||
val first = group.first()
|
||||
SerializableMobEffectInstance(
|
||||
effect = effectId,
|
||||
duration = duration,
|
||||
amplifier = amplifier,
|
||||
ambient = first.ambient,
|
||||
visible = first.visible,
|
||||
showIcon = first.showIcon
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun mergeDurations(durations: List<Int>): Int {
|
||||
if (durations.isEmpty()) return 0
|
||||
|
||||
val sorted = durations.sortedDescending()
|
||||
var result = 0.0
|
||||
|
||||
for ((index, value) in sorted.withIndex()) {
|
||||
val multiplier = when (index) {
|
||||
0 -> 1.0
|
||||
1 -> 0.75
|
||||
2 -> 0.5
|
||||
else -> 0.25
|
||||
}
|
||||
result += value * multiplier
|
||||
}
|
||||
|
||||
return ceil(result).toInt()
|
||||
}
|
||||
|
||||
private fun mergeAmplifiers(amplifiers: List<Int>): Int {
|
||||
return amplifiers.maxOrNull() ?: 0 // we do not want the power of the effects to combine, just take the highest one used of that type
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItemComponents
|
||||
import com.cobblemon.mod.common.item.PokePuffItem
|
||||
import com.cobblemon.mod.common.item.PokePuffItem.Companion.DISLIKED_FLAVOR_MULTIPLIER
|
||||
import com.cobblemon.mod.common.item.PokePuffItem.Companion.LIKED_FLAVOR_MULTIPLIER
|
||||
import com.cobblemon.mod.common.pokemon.Nature
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
|
||||
object PokePuffUtils {
|
||||
|
||||
fun calculateFriendshipChange(stack: ItemStack, nature: Nature): Int {
|
||||
val dominantFlavour = getDominantFlavour(stack) ?: return 0
|
||||
val isNeutralNature = nature.favouriteFlavour == nature.dislikedFlavour
|
||||
|
||||
val (baseFriendship) = calculateBaseFriendship(stack)
|
||||
|
||||
return when {
|
||||
dominantFlavour == nature.favouriteFlavour -> (baseFriendship / LIKED_FLAVOR_MULTIPLIER).toInt()
|
||||
dominantFlavour == Flavour.MILD && isNeutralNature -> (baseFriendship / 2.0).coerceAtLeast(1.0).toInt()
|
||||
else -> (-baseFriendship / DISLIKED_FLAVOR_MULTIPLIER).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
fun calculateBaseFriendship(stack: ItemStack): Pair<Double, Double> {
|
||||
val ingredientIds = stack.get(CobblemonItemComponents.INGREDIENT)?.ingredientIds ?: emptyList()
|
||||
var baseFriendship = 0.0
|
||||
|
||||
for (id in ingredientIds) {
|
||||
val item = BuiltInRegistries.ITEM.get(id)
|
||||
val itemStack = ItemStack(item)
|
||||
val seasoning = Seasonings.getFromItemStack(itemStack) ?: continue
|
||||
val dominantValue = seasoning.flavours?.values?.maxOrNull() ?: 0
|
||||
baseFriendship += dominantValue
|
||||
}
|
||||
|
||||
val ingredientStrings = ingredientIds.map { it.toString() }
|
||||
val hasSugar = "minecraft:sugar" in ingredientStrings
|
||||
val hasSweet = ingredientStrings.any { it.startsWith("cobblemon:") && it.endsWith("_sweet") }
|
||||
|
||||
val multiplier = when {
|
||||
hasSugar && hasSweet -> 5.0
|
||||
hasSweet -> 2.25
|
||||
hasSugar -> 1.75
|
||||
else -> 1.0
|
||||
}
|
||||
|
||||
val finalBaseFriendship = baseFriendship * multiplier
|
||||
|
||||
return finalBaseFriendship to multiplier
|
||||
}
|
||||
|
||||
fun getDominantFlavour(stack: ItemStack): Flavour? {
|
||||
val flavours = stack.get(CobblemonItemComponents.FLAVOUR)?.flavours ?: return null
|
||||
val max = flavours.values.maxOrNull() ?: return null
|
||||
val dominant = flavours.filterValues { it == max }.keys
|
||||
|
||||
return when {
|
||||
dominant.isEmpty() -> null
|
||||
dominant.size > 1 -> Flavour.MILD
|
||||
else -> dominant.first()
|
||||
}
|
||||
}
|
||||
|
||||
fun getFlavorNatureLabel(flavour: Flavour): String {
|
||||
return when (flavour) {
|
||||
Flavour.SPICY -> "attack"
|
||||
Flavour.DRY -> "special_attack"
|
||||
Flavour.SWEET -> "speed"
|
||||
Flavour.BITTER -> "special_defense"
|
||||
Flavour.SOUR -> "defense"
|
||||
Flavour.MILD -> "neutral"
|
||||
}
|
||||
}
|
||||
|
||||
fun getFriendshipChangeLiked(stack: ItemStack): Int {
|
||||
val (baseFriendship) = calculateBaseFriendship(stack)
|
||||
return (baseFriendship / LIKED_FLAVOR_MULTIPLIER).toInt()
|
||||
}
|
||||
|
||||
fun getFriendshipChangeDisliked(stack: ItemStack): Int {
|
||||
val (baseFriendship) = calculateBaseFriendship(stack)
|
||||
return (baseFriendship / DISLIKED_FLAVOR_MULTIPLIER).toInt()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import com.cobblemon.mod.common.api.conditional.ITEM_REGISTRY_LIKE_CODEC
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeIdentifierCondition
|
||||
import com.cobblemon.mod.common.api.fishing.SpawnBait
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import io.netty.buffer.ByteBuf
|
||||
import net.minecraft.network.codec.ByteBufCodecs
|
||||
import net.minecraft.network.codec.StreamCodec
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.Item
|
||||
import java.util.Optional
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
data class Seasoning(
|
||||
val ingredient: RegistryLikeCondition<Item>,
|
||||
@SerializedName("flavours", alternate = ["flavors"])
|
||||
val flavours: Map<Flavour, Int>? = null,
|
||||
@SerializedName("colour", alternate = ["color"])
|
||||
val colour: DyeColor,
|
||||
@SerializedName("baitEffects")
|
||||
val baitEffects: List<SpawnBait.Effect>? = null,
|
||||
@SerializedName("food")
|
||||
val food: Food? = null,
|
||||
@SerializedName("mobEffects")
|
||||
val mobEffects: List<SerializableMobEffectInstance>? = null
|
||||
) {
|
||||
companion object {
|
||||
val CODEC: Codec<Seasoning> = RecordCodecBuilder.create { builder ->
|
||||
builder.group(
|
||||
ITEM_REGISTRY_LIKE_CODEC.fieldOf("ingredient").forGetter { it.ingredient },
|
||||
Codec.unboundedMap(Flavour.CODEC, Codec.INT).optionalFieldOf("flavours").forGetter { Optional.ofNullable(it.flavours) },
|
||||
DyeColor.CODEC.fieldOf("colour").forGetter { it.colour },
|
||||
SpawnBait.Effect.CODEC.listOf().optionalFieldOf("baitEffects").forGetter { Optional.ofNullable(it.baitEffects) },
|
||||
Food.CODEC.optionalFieldOf("food").forGetter { Optional.ofNullable(it.food) },
|
||||
SerializableMobEffectInstance.CODEC.listOf().optionalFieldOf("mobEffects").forGetter { Optional.ofNullable(it.mobEffects) }
|
||||
).apply(builder) { item, flavours, colour, baitEffects, food, mobEffects ->
|
||||
Seasoning(
|
||||
item,
|
||||
flavours.getOrNull(),
|
||||
colour,
|
||||
baitEffects.getOrNull(),
|
||||
food.getOrNull(),
|
||||
mobEffects.getOrNull()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val STREAM_CODEC: StreamCodec<ByteBuf, Seasoning> = ByteBufCodecs.fromCodec(CODEC)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItemComponents
|
||||
import com.cobblemon.mod.common.api.berry.Berries
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeIdentifierCondition
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.fishing.SpawnBait
|
||||
import com.cobblemon.mod.common.api.fishing.SpawnBaitEffects
|
||||
import com.cobblemon.mod.common.api.fishing.SpawnBaitUtils
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.item.components.FoodComponent
|
||||
import com.cobblemon.mod.common.net.messages.client.cooking.SeasoningRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ItemLikeConditionAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
object Seasonings : JsonDataRegistry<Seasoning> {
|
||||
override val id = cobblemonResource("seasonings")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val observable = SimpleObservable<Seasonings>()
|
||||
override val typeToken: TypeToken<Seasoning> = TypeToken.get(Seasoning::class.java)
|
||||
override val resourcePath = "seasonings"
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
|
||||
val seasonings = mutableListOf<Seasoning>()
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
SeasoningRegistrySyncPacket(seasonings.toList()).sendToPlayer(player)
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, Seasoning>) {
|
||||
// this needs to sideload the berry data so we don't get duplicate JSONs.
|
||||
val finalData = Berries.all().associate {
|
||||
it.identifier to Seasoning(
|
||||
ingredient = RegistryLikeIdentifierCondition(it.identifier),
|
||||
flavours = it.flavours.toMap(),
|
||||
colour = it.colour,
|
||||
baitEffects = emptyList(),
|
||||
food = Food(),
|
||||
mobEffects = emptyList()
|
||||
)
|
||||
}.toMutableMap()
|
||||
finalData.putAll(data)
|
||||
seasonings.addAll(finalData.values)
|
||||
}
|
||||
|
||||
fun reloadEntries(seasonings: Collection<Seasoning>) {
|
||||
this.seasonings.clear()
|
||||
this.seasonings.addAll(seasonings)
|
||||
}
|
||||
|
||||
fun getFlavoursFromItemStack(stack: ItemStack): Map<Flavour, Int>? {
|
||||
val holder = stack.itemHolder
|
||||
val seasoning = seasonings.find { it.ingredient.fits(holder) }
|
||||
val inherentFlavours = stack.get(CobblemonItemComponents.FLAVOUR)?.flavours
|
||||
val seasoningFlavours = seasoning?.flavours
|
||||
|
||||
if (seasoningFlavours.isNullOrEmpty() && inherentFlavours.isNullOrEmpty())
|
||||
return null
|
||||
|
||||
return (seasoningFlavours ?: emptyMap()).mapValues { (flavour, value) ->
|
||||
value + (inherentFlavours?.getOrDefault(flavour, 0) ?: 0)
|
||||
}
|
||||
}
|
||||
|
||||
fun hasFlavors(stack: ItemStack): Boolean {
|
||||
val flavors = getFlavoursFromItemStack(stack)
|
||||
return !flavors.isNullOrEmpty() && flavors.any { it.value != 0 }
|
||||
}
|
||||
|
||||
fun getFoodComponentFromItemStack(stack: ItemStack): FoodComponent? {
|
||||
return getFromItemStack(stack)?.food?.toComponent()
|
||||
}
|
||||
|
||||
fun hasFood(stack: ItemStack): Boolean {
|
||||
val effects = getFromItemStack(stack)?.food ?: return false
|
||||
return effects.hunger > 0 || effects.saturation > 0f
|
||||
}
|
||||
|
||||
fun getMobEffectsFromItemStack(stack: ItemStack): List<SerializableMobEffectInstance> {
|
||||
return getFromItemStack(stack)?.mobEffects ?: emptyList()
|
||||
}
|
||||
|
||||
fun hasMobEffect(stack: ItemStack): Boolean {
|
||||
return !getFromItemStack(stack)?.mobEffects.isNullOrEmpty()
|
||||
}
|
||||
|
||||
fun getBaitEffectsFromItemStack(stack: ItemStack): List<SpawnBait.Effect> {
|
||||
val primaryEffects = SpawnBaitEffects.getEffectsFromItemStack(stack)
|
||||
return if (primaryEffects.isNotEmpty()) {
|
||||
primaryEffects
|
||||
} else {
|
||||
getFromItemStack(stack)?.baitEffects ?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
fun hasBaitEffects(stack: ItemStack): Boolean {
|
||||
return SpawnBaitEffects.getEffectsFromItemStack(stack).isNotEmpty() ||
|
||||
!(getFromItemStack(stack)?.baitEffects.isNullOrEmpty())
|
||||
}
|
||||
|
||||
fun getFromItemStack(stack: ItemStack): Seasoning? {
|
||||
val holder = stack.itemHolder
|
||||
return seasonings.find { it.ingredient.fits(holder) }
|
||||
}
|
||||
|
||||
fun isSeasoning(stack: ItemStack) = getFromItemStack(stack) != null
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.effect.MobEffect
|
||||
import net.minecraft.world.effect.MobEffectInstance
|
||||
|
||||
data class SerializableMobEffectInstance(
|
||||
val effect: ResourceLocation,
|
||||
val duration: Int,
|
||||
val amplifier: Int = 0,
|
||||
val ambient: Boolean = false,
|
||||
val visible: Boolean = true,
|
||||
val showIcon: Boolean = true
|
||||
) {
|
||||
fun toInstance(): MobEffectInstance {
|
||||
val holder = BuiltInRegistries.MOB_EFFECT.getHolder(effect)
|
||||
.orElseThrow { IllegalArgumentException("Unknown MobEffect: $effect") }
|
||||
return MobEffectInstance(holder, duration, amplifier, ambient, visible, showIcon)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val CODEC: Codec<SerializableMobEffectInstance> = RecordCodecBuilder.create { builder ->
|
||||
builder.group(
|
||||
ResourceLocation.CODEC.fieldOf("effect").forGetter { it.effect },
|
||||
Codec.INT.fieldOf("duration").forGetter { it.duration },
|
||||
Codec.INT.fieldOf("amplifier").forGetter { it.amplifier },
|
||||
Codec.BOOL.optionalFieldOf("ambient", false).forGetter { it.ambient },
|
||||
Codec.BOOL.optionalFieldOf("visible", true).forGetter { it.visible },
|
||||
Codec.BOOL.optionalFieldOf("showIcon", true).forGetter { it.showIcon }
|
||||
).apply(builder, ::SerializableMobEffectInstance)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ sealed interface DialogueFaceProvider {
|
||||
|
||||
companion object {
|
||||
val types = mutableMapOf(
|
||||
"artificial" to ArtificialDialogueFaceProvider::class.java,
|
||||
"player" to PlayerDialogueFaceProvider::class.java,
|
||||
"standard" to ArtificialDialogueFaceProvider::class.java,
|
||||
"expression" to ExpressionLikeDialogueFaceProvider::class.java
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.dialogue
|
||||
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* Settings for the gibbering sound effect that plays gradually as dialogue appears.
|
||||
*
|
||||
* @author Hiroku, landonjw
|
||||
* @since April 19th, 2025
|
||||
*/
|
||||
class DialogueGibber(
|
||||
/** Whether text will gradually appear while the gibbering occurs. */
|
||||
val graduallyShowText: Boolean = true,
|
||||
/** Whether clicking will make the gibber skip to the end. */
|
||||
val allowSkip: Boolean = true,
|
||||
/** The space between gibbers in terms of characters. 'Holy cow' would play 2 sounds if step = 4. */
|
||||
val step: Int = 4,
|
||||
/** The time (in seconds) between gibbers. The smaller this is, the faster the text will progress. */
|
||||
val interval: Double = 0.1,
|
||||
val minPitch: Float = 0.9F,
|
||||
val maxPitch: Float = 1.1F,
|
||||
val minVolume: Float = 0.9F,
|
||||
val maxVolume: Float = 1.0F,
|
||||
/** The possible sounds to play when gibbering. */
|
||||
val sounds: List<ResourceLocation> = listOf(
|
||||
cobblemonResource("entity.npc.gibber.generic")
|
||||
)
|
||||
)
|
||||
@@ -31,6 +31,7 @@ class DialoguePage(
|
||||
var lines: MutableList<DialogueText> = mutableListOf(),
|
||||
var input: DialogueInput = DialogueNoInput(),
|
||||
var background: ResourceLocation? = null,
|
||||
var gibber: DialogueGibber? = null,
|
||||
var clientActions: MutableList<Expression> = mutableListOf(),
|
||||
var escapeAction: DialogueAction? = null,
|
||||
) {
|
||||
@@ -42,6 +43,7 @@ class DialoguePage(
|
||||
speaker: String? = null,
|
||||
lines: Iterable<MutableComponent>,
|
||||
input: DialogueInput = DialogueNoInput(),
|
||||
gibber: DialogueGibber? = null,
|
||||
background: ResourceLocation? = null,
|
||||
clientActions: Iterable<Expression> = emptyList(),
|
||||
/** The thing to do when the player presses ESC while on this page. If null, falls back to the same property on [Dialogue]. */
|
||||
@@ -52,6 +54,7 @@ class DialoguePage(
|
||||
speaker = speaker,
|
||||
lines = lines.map { WrappedDialogueText(it) }.toMutableList(),
|
||||
input = input,
|
||||
gibber = gibber,
|
||||
background = background,
|
||||
clientActions = clientActions.toMutableList(),
|
||||
escapeAction = escapeAction?.let { func -> FunctionDialogueAction { activeDialogue, _ -> func(activeDialogue) } }
|
||||
|
||||
@@ -19,7 +19,16 @@ import net.minecraft.network.chat.MutableComponent
|
||||
*/
|
||||
class DialogueSpeaker(
|
||||
val name: DialogueText? = null,
|
||||
val face: DialogueFaceProvider? = null
|
||||
val face: DialogueFaceProvider? = null,
|
||||
val gibber: DialogueGibber? = null
|
||||
) {
|
||||
fun of(name: MutableComponent = "".text(), face: DialogueFaceProvider? = null) = DialogueSpeaker(WrappedDialogueText(name), face)
|
||||
fun of(
|
||||
name: MutableComponent = "".text(),
|
||||
face: DialogueFaceProvider? = null,
|
||||
gibber: DialogueGibber? = null
|
||||
) = DialogueSpeaker(
|
||||
name = WrappedDialogueText(name),
|
||||
face = face,
|
||||
gibber = gibber
|
||||
)
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import com.cobblemon.mod.common.api.events.drops.LootDroppedEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.PokemonEntityLoadEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.PokemonEntitySaveEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.PokemonEntitySaveToWorldEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.SpawnBucketChosenEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.SpawnEvent
|
||||
import com.cobblemon.mod.common.api.events.farming.ApricornHarvestEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.*
|
||||
@@ -71,6 +72,8 @@ object CobblemonEvents {
|
||||
@JvmField
|
||||
val FRIENDSHIP_UPDATED = EventObservable<FriendshipUpdatedEvent>()
|
||||
@JvmField
|
||||
val FULLNESS_UPDATED = EventObservable<FullnessUpdatedEvent>()
|
||||
@JvmField
|
||||
val POKEMON_FAINTED = EventObservable<PokemonFaintedEvent>()
|
||||
@JvmField
|
||||
val EVOLUTION_ACCEPTED = CancelableObservable<EvolutionAcceptedEvent>()
|
||||
@@ -168,6 +171,11 @@ object CobblemonEvents {
|
||||
@JvmField
|
||||
val EV_GAINED_EVENT_POST = EventObservable<EvGainedEvent.Post>()
|
||||
|
||||
@JvmField
|
||||
val HYPER_TRAINED_IV_PRE = CancelableObservable<HyperTrainedIvEvent.Pre>()
|
||||
@JvmField
|
||||
val HYPER_TRAINED_IV_POST = EventObservable<HyperTrainedIvEvent.Post>()
|
||||
|
||||
@JvmField
|
||||
val POKEMON_RELEASED_EVENT_PRE = CancelableObservable<ReleasePokemonEvent.Pre>()
|
||||
@JvmField
|
||||
@@ -245,8 +253,6 @@ object CobblemonEvents {
|
||||
@JvmField
|
||||
val POKEROD_REEL = CancelableObservable<PokerodReelEvent>()
|
||||
@JvmField
|
||||
val BOBBER_BUCKET_CHOSEN = EventObservable<BobberBucketChosenEvent>()
|
||||
@JvmField
|
||||
val BOBBER_SPAWN_POKEMON_PRE = CancelableObservable<BobberSpawnPokemonEvent.Pre>()
|
||||
@JvmField
|
||||
val BOBBER_SPAWN_POKEMON_MODIFY = EventObservable<BobberSpawnPokemonEvent.Modify>()
|
||||
@@ -255,6 +261,14 @@ object CobblemonEvents {
|
||||
@JvmField
|
||||
val BAIT_EFFECT_REGISTRATION = EventObservable<BaitEffectFunctionRegistryEvent>()
|
||||
|
||||
@JvmField
|
||||
val SPAWN_BUCKET_CHOSEN = EventObservable<SpawnBucketChosenEvent>()
|
||||
|
||||
// Baits and Lures
|
||||
@JvmField
|
||||
val BAIT_SPAWN_POKEMON_MODIFY = EventObservable<BaitSpawnPokemonEvent.Modify>()
|
||||
|
||||
|
||||
@JvmField
|
||||
val COLLECT_EGG = CancelableObservable<CollectEggEvent>()
|
||||
@JvmField
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.events.entity
|
||||
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnCause
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.Spawner
|
||||
|
||||
/**
|
||||
* Event fired when the spawning system makes a decision on which bucket to spawn from.
|
||||
*/
|
||||
class SpawnBucketChosenEvent(
|
||||
/** The spawner this is happening within. */
|
||||
val spawner: Spawner,
|
||||
/** The cause of the spawn. */
|
||||
val spawnCause: SpawnCause,
|
||||
/** The bucket that was chosen. You can alter this. */
|
||||
var bucket: SpawnBucket,
|
||||
/** The final weights that were used to make the choice. */
|
||||
val bucketWeights: Map<SpawnBucket, Float>
|
||||
)
|
||||
@@ -10,15 +10,15 @@ package com.cobblemon.mod.common.api.events.entity
|
||||
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.spawning.BestSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.position.SpawnablePosition
|
||||
import net.minecraft.world.entity.Entity
|
||||
|
||||
/**
|
||||
* Event fired when an entity is spawned using the [BestSpawner]. The entity that was spawned
|
||||
* and the [SpawningContext] of the spawn are provided. Cancelling this event will prevent the
|
||||
* and the [SpawnablePosition] of the spawn are provided. Cancelling this event will prevent the
|
||||
* entity from spawning.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since April 22nd, 2023
|
||||
*/
|
||||
class SpawnEvent<T : Entity>(val entity: T, val ctx: SpawningContext) : Cancelable()
|
||||
class SpawnEvent<T : Entity>(val entity: T, val spawnablePosition: SpawnablePosition) : Cancelable()
|
||||
+5
-5
@@ -8,19 +8,19 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.events.fishing
|
||||
|
||||
import com.cobblemon.mod.common.api.fishing.FishingBait
|
||||
import com.cobblemon.mod.common.api.fishing.SpawnBait
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* Event to register code-based functions for bait effects.
|
||||
* @see FishingBait.Effect
|
||||
* @see FishingBait.Effects
|
||||
* @see SpawnBait.Effect
|
||||
* @see SpawnBait.Effects
|
||||
*/
|
||||
class BaitEffectFunctionRegistryEvent {
|
||||
val functions = mutableMapOf<ResourceLocation, (PokemonEntity, FishingBait.Effect) -> Unit>()
|
||||
val functions = mutableMapOf<ResourceLocation, (PokemonEntity, SpawnBait.Effect) -> Unit>()
|
||||
|
||||
fun registerFunction(id: ResourceLocation, function: (PokemonEntity, FishingBait.Effect) -> Unit) {
|
||||
fun registerFunction(id: ResourceLocation, function: (PokemonEntity, SpawnBait.Effect) -> Unit) {
|
||||
functions[id] = function
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.events.fishing
|
||||
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
/**
|
||||
* Event that is fired when a Pokemon is spawned by a bobber.
|
||||
*/
|
||||
interface BaitSpawnPokemonEvent {
|
||||
|
||||
/**
|
||||
* Event that is fired before a Pokemon is spawned by a bobber.
|
||||
* @param bobber The PokeRodFishingBobberEntity that is spawning the Pokemon.
|
||||
* @param chosenBucket The bucket that is chosen.
|
||||
* @param rod The ItemStack of the rod that the bobber is attached to.
|
||||
*/
|
||||
data class Pre(
|
||||
val bobber: PokeRodFishingBobberEntity, // todo replace this with the bait entity
|
||||
val chosenBucket: SpawnBucket,
|
||||
val rod: ItemStack
|
||||
) : Cancelable(), BobberSpawnPokemonEvent
|
||||
|
||||
/**
|
||||
* Event that is fired when a Pokemon is modified before it is spawned by a bobber.
|
||||
* @param chosenBucket The bucket that is chosen.
|
||||
* @param rod The ItemStack of the rod that the bobber is attached to.
|
||||
* @param pokemon The Pokemon that is modified.
|
||||
*/
|
||||
data class Modify(
|
||||
val chosenBucket: SpawnBucket,
|
||||
val rod: ItemStack,
|
||||
val pokemon: PokemonEntity
|
||||
) : BobberSpawnPokemonEvent
|
||||
|
||||
/**
|
||||
* Event that is fired after a Pokemon is spawned by a bobber.
|
||||
* @param bobber The PokeRodFishingBobberEntity that is spawning the Pokemon.
|
||||
* @param chosenBucket The bucket that is chosen.
|
||||
* @param bait The ItemStack of the bait that is set on the rod.
|
||||
* @param pokemon The Pokemon that is spawned.
|
||||
*/
|
||||
data class Post(
|
||||
val bobber: PokeRodFishingBobberEntity,
|
||||
val chosenBucket: SpawnBucket,
|
||||
val bait: ItemStack,
|
||||
val pokemon: PokemonEntity
|
||||
) : BobberSpawnPokemonEvent
|
||||
}
|
||||
+7
-7
@@ -8,12 +8,12 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.events.fishing
|
||||
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||
import com.cobblemon.mod.common.api.spawning.SpawnBucket
|
||||
import com.cobblemon.mod.common.api.spawning.detail.SpawnAction
|
||||
import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.itemRegistry
|
||||
@@ -28,23 +28,23 @@ interface BobberSpawnPokemonEvent {
|
||||
/**
|
||||
* Event that is fired before a Pokemon is spawned by a bobber.
|
||||
* @param bobber The PokeRodFishingBobberEntity that is spawning the Pokemon.
|
||||
* @param chosenBucket The bucket that is chosen.
|
||||
* @param spawnAction The spawn that is planned.
|
||||
* @param rod The ItemStack of the rod that the bobber is attached to.
|
||||
*/
|
||||
data class Pre(
|
||||
val bobber: PokeRodFishingBobberEntity,
|
||||
val chosenBucket: SpawnBucket,
|
||||
val spawnAction: SpawnAction<*>,
|
||||
val rod: ItemStack
|
||||
) : Cancelable(), BobberSpawnPokemonEvent
|
||||
|
||||
/**
|
||||
* Event that is fired when a Pokemon is modified before it is spawned by a bobber.
|
||||
* @param chosenBucket The bucket that is chosen.
|
||||
* @param spawnAction The [SpawnAction] that is motivating the spawn.
|
||||
* @param rod The ItemStack of the rod that the bobber is attached to.
|
||||
* @param pokemon The Pokemon that is modified.
|
||||
*/
|
||||
data class Modify(
|
||||
val chosenBucket: SpawnBucket,
|
||||
val spawnAction: SpawnAction<*>,
|
||||
val rod: ItemStack,
|
||||
val pokemon: PokemonEntity
|
||||
) : BobberSpawnPokemonEvent
|
||||
@@ -58,12 +58,12 @@ interface BobberSpawnPokemonEvent {
|
||||
*/
|
||||
data class Post(
|
||||
val bobber: PokeRodFishingBobberEntity,
|
||||
val chosenBucket: SpawnBucket,
|
||||
val spawnAction: SpawnAction<*>,
|
||||
val bait: ItemStack,
|
||||
val pokemon: PokemonEntity
|
||||
) : BobberSpawnPokemonEvent {
|
||||
val context = mutableMapOf<String, MoValue>(
|
||||
"chosen_bucket" to ObjectValue(chosenBucket, { it.name }),
|
||||
"chosen_bucket" to ObjectValue(spawnAction.bucket, { it.name }),
|
||||
"bait" to pokemon.level().itemRegistry.wrapAsHolder(bait.item).asMoLangValue(Registries.ITEM),
|
||||
"pokemon_entity" to pokemon.asMoLangValue()
|
||||
)
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.events.pokemon
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
/**
|
||||
* Event that is fired when a player owned Pokémon has its fullness changed
|
||||
*/
|
||||
data class FullnessUpdatedEvent(
|
||||
val pokemon: Pokemon,
|
||||
val newFullnessInitial: Int
|
||||
) {
|
||||
var newFullness: Int = newFullnessInitial
|
||||
set(value) {
|
||||
field = value.coerceIn(0, pokemon.getMaxFullness())
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.events.pokemon
|
||||
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stat
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
/**
|
||||
* Fired during a Hyper Training mutation.
|
||||
*
|
||||
* @see [Pre]
|
||||
* @see [Post]
|
||||
*/
|
||||
interface HyperTrainedIvEvent {
|
||||
|
||||
/**
|
||||
* The [Stat] having whose IV is being hyper-trained.
|
||||
*/
|
||||
val stat: Stat
|
||||
|
||||
/**
|
||||
* The [Pokemon] being hyper-trained.
|
||||
*/
|
||||
val pokemon: Pokemon
|
||||
|
||||
/**
|
||||
* Fired before Hyper Training occurs, cancelling will cause the mutation to be flagged as not successful.
|
||||
*/
|
||||
class Pre(override val pokemon: Pokemon, override val stat: Stat, var value: Int) : HyperTrainedIvEvent, Cancelable() {
|
||||
val context = mutableMapOf(
|
||||
"pokemon" to pokemon.struct,
|
||||
"stat" to StringValue(stat.toString()),
|
||||
"value" to DoubleValue(value)
|
||||
)
|
||||
val functions = moLangFunctionMap(cancelFunc)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired after Hyper Training occurs, this is purely for notification purposes.
|
||||
*/
|
||||
class Post(override val pokemon: Pokemon, override val stat: Stat, val value: Int) : HyperTrainedIvEvent {
|
||||
val context = mutableMapOf(
|
||||
"pokemon" to pokemon.struct,
|
||||
"stat" to StringValue(stat.toString()),
|
||||
"value" to DoubleValue(value)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.fishing
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItemComponents
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.FishingBaitRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
object FishingBaits : JsonDataRegistry<FishingBait>{
|
||||
override val id = cobblemonResource("fishing_baits")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val observable = SimpleObservable<FishingBaits>()
|
||||
override val typeToken: TypeToken<FishingBait> = TypeToken.get(FishingBait::class.java)
|
||||
override val resourcePath = "fishing_baits"
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
|
||||
private val itemMap = mutableMapOf<ResourceLocation, FishingBait>()
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
FishingBaitRegistrySyncPacket(this.itemMap.values.toList()).sendToPlayer(player)
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, FishingBait>) {
|
||||
itemMap.clear()
|
||||
data.forEach { id, bait ->
|
||||
itemMap[bait.item] = bait
|
||||
}
|
||||
}
|
||||
|
||||
fun getFromRodItemStack(stack: ItemStack): FishingBait? {
|
||||
return stack.components.get(CobblemonItemComponents.BAIT)?.bait
|
||||
}
|
||||
|
||||
fun getFromBaitItemStack(stack: ItemStack): FishingBait? {
|
||||
return getFromIdentifier(BuiltInRegistries.ITEM.getKey(stack.item))
|
||||
}
|
||||
|
||||
fun getFromIdentifier(identifier: ResourceLocation): FishingBait? {
|
||||
return itemMap[identifier]
|
||||
}
|
||||
|
||||
fun isFishingBait(stack: ItemStack) = itemMap.containsKey(BuiltInRegistries.ITEM.getKey(stack.item))
|
||||
|
||||
//
|
||||
//
|
||||
// fun getBaitSubcategory(item: ItemStack): String? {
|
||||
// val itemId = Registries.ITEM.getId(item.item)
|
||||
// if (itemId in itemMap.keys) {
|
||||
// return itemMap[itemId]?.subcategory
|
||||
// }
|
||||
// val tag = tagMap.keys.firstOrNull { it.fits(item.item, Registries.ITEM) }
|
||||
// if (tag != null) {
|
||||
// return tagMap[tag]?.subcategory
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
//
|
||||
// fun getBaitSuccessChance(item: ItemStack): Double? {
|
||||
// val itemId = Registries.ITEM.getId(item.item)
|
||||
// if (itemId in itemMap.keys) {
|
||||
// return itemMap[itemId]?.chance
|
||||
// }
|
||||
// val tag = tagMap.keys.firstOrNull { it.fits(item.item, Registries.ITEM) }
|
||||
// if (tag != null) {
|
||||
// return tagMap[tag]?.chance
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
//
|
||||
// fun getBaitEffectValue(item: ItemStack): Double? {
|
||||
// val itemId = Registries.ITEM.getId(item.item)
|
||||
// if (itemId in itemMap.keys) {
|
||||
// return itemMap[itemId]?.value
|
||||
// }
|
||||
// val tag = tagMap.keys.firstOrNull { it.fits(item.item, Registries.ITEM) }
|
||||
// if (tag != null) {
|
||||
// return tagMap[tag]?.value
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
//
|
||||
//
|
||||
// fun getBaitNote(item: ItemStack): String? {
|
||||
// val itemId = Registries.ITEM.getId(item.item)
|
||||
// if (itemId in itemMap.keys) {
|
||||
// return itemMap[itemId]?.note
|
||||
// }
|
||||
// val tag = tagMap.keys.firstOrNull { it.fits(item.item, Registries.ITEM) }
|
||||
// if (tag != null) {
|
||||
// return tagMap[tag]?.note
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
}
|
||||
+16
-23
@@ -8,6 +8,8 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.fishing
|
||||
|
||||
import com.cobblemon.mod.common.api.conditional.ITEM_REGISTRY_LIKE_CODEC
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.fishing.BaitEffectFunctionRegistryEvent
|
||||
import com.cobblemon.mod.common.api.spawning.fishing.FishingSpawnCause
|
||||
@@ -16,18 +18,14 @@ import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import java.util.Optional
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.network.codec.ByteBufCodecs
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
data class FishingBait(
|
||||
val item: ResourceLocation,
|
||||
class SpawnBait(
|
||||
val item: RegistryLikeCondition<Item>,
|
||||
val effects: List<Effect>,
|
||||
) {
|
||||
fun toItemStack(itemRegistry: Registry<Item>) = item.let(itemRegistry::get)?.let { ItemStack(it) } ?: ItemStack.EMPTY
|
||||
|
||||
data class Effect(
|
||||
val type: ResourceLocation,
|
||||
val subcategory: ResourceLocation?,
|
||||
@@ -49,19 +47,14 @@ data class FishingBait(
|
||||
}
|
||||
|
||||
companion object {
|
||||
val CODEC = RecordCodecBuilder.create<FishingBait> { instance ->
|
||||
val CODEC = RecordCodecBuilder.create<SpawnBait> { instance ->
|
||||
instance.group(
|
||||
ResourceLocation.CODEC.fieldOf("item").forGetter { it.item },
|
||||
ITEM_REGISTRY_LIKE_CODEC.fieldOf("item").forGetter { it.item },
|
||||
Effect.CODEC.listOf().fieldOf("effects").forGetter {it.effects}
|
||||
).apply(instance, ::FishingBait)
|
||||
).apply(instance, ::SpawnBait)
|
||||
}
|
||||
|
||||
val STREAM_CODEC = ByteBufCodecs.fromCodec(CODEC)
|
||||
|
||||
val BLANK_BAIT = FishingBait(
|
||||
cobblemonResource("blank"),
|
||||
emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
object Effects {
|
||||
@@ -78,7 +71,7 @@ data class FishingBait(
|
||||
val HIDDEN_ABILITY_CHANCE = cobblemonResource("ha_chance")
|
||||
val POKEMON_CHANCE = cobblemonResource("pokemon_chance")
|
||||
val FRIENDSHIP = cobblemonResource("friendship")
|
||||
val INERT = cobblemonResource("inert")
|
||||
val RARITY_BUCKET = cobblemonResource("rarity_bucket")
|
||||
|
||||
fun registerEffect(type: ResourceLocation, effect: (PokemonEntity, Effect) -> Unit) {
|
||||
EFFECT_FUNCTIONS[type] = effect
|
||||
@@ -89,15 +82,15 @@ data class FishingBait(
|
||||
}
|
||||
|
||||
fun setupEffects() {
|
||||
EFFECT_FUNCTIONS[NATURE] = { entity, effect -> FishingSpawnCause.alterNatureAttempt(entity, effect) }
|
||||
EFFECT_FUNCTIONS[IV] = { entity, effect -> FishingSpawnCause.alterIVAttempt(entity, effect) }
|
||||
EFFECT_FUNCTIONS[SHINY_REROLL] = { entity, effect -> FishingSpawnCause.shinyReroll(entity, effect) }
|
||||
EFFECT_FUNCTIONS[GENDER_CHANCE] = { entity, effect -> FishingSpawnCause.alterGenderAttempt(entity, effect) }
|
||||
EFFECT_FUNCTIONS[LEVEL_RAISE] = { entity, effect -> FishingSpawnCause.alterLevelAttempt(entity, effect) }
|
||||
EFFECT_FUNCTIONS[HIDDEN_ABILITY_CHANCE] = { entity, _ -> FishingSpawnCause.alterHAAttempt(entity) }
|
||||
EFFECT_FUNCTIONS[FRIENDSHIP] = { entity, effect -> FishingSpawnCause.alterFriendshipAttempt(entity, effect) }
|
||||
registerEffect(NATURE) { entity, effect -> FishingSpawnCause.alterNatureAttempt(entity, effect) }
|
||||
registerEffect(IV) { entity, effect -> FishingSpawnCause.alterIVAttempt(entity, effect) }
|
||||
registerEffect(SHINY_REROLL) { entity, effect -> FishingSpawnCause.shinyReroll(entity, effect) }
|
||||
registerEffect(GENDER_CHANCE) { entity, effect -> FishingSpawnCause.alterGenderAttempt(entity, effect) }
|
||||
registerEffect(LEVEL_RAISE) { entity, effect -> FishingSpawnCause.alterLevelAttempt(entity, effect) }
|
||||
registerEffect(HIDDEN_ABILITY_CHANCE) { entity, _ -> FishingSpawnCause.alterHAAttempt(entity) }
|
||||
registerEffect(FRIENDSHIP) { entity, effect -> FishingSpawnCause.alterFriendshipAttempt(entity, effect) }
|
||||
CobblemonEvents.BAIT_EFFECT_REGISTRATION.post(BaitEffectFunctionRegistryEvent()) { event ->
|
||||
EFFECT_FUNCTIONS.putAll(event.functions)
|
||||
event.functions.forEach { (type, function) -> registerEffect(type, function) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.fishing
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItemComponents
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
||||
import com.cobblemon.mod.common.api.conditional.RegistryLikeIdentifierCondition
|
||||
import com.cobblemon.mod.common.api.cooking.Seasonings
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.SpawnBaitRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ItemLikeConditionAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
object SpawnBaitEffects : JsonDataRegistry<SpawnBait> {
|
||||
override val id = cobblemonResource("spawn_bait_effects")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val observable = SimpleObservable<SpawnBaitEffects>()
|
||||
override val typeToken: TypeToken<SpawnBait> = TypeToken.get(SpawnBait::class.java)
|
||||
override val resourcePath = "spawn_bait_effects"
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
|
||||
private val effectsMap = mutableMapOf<ResourceLocation, SpawnBait>()
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
SpawnBaitRegistrySyncPacket(this.effectsMap.toMap()).sendToPlayer(player)
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, SpawnBait>) {
|
||||
effectsMap.clear()
|
||||
data.forEach { id, bait ->
|
||||
effectsMap[id] = bait
|
||||
}
|
||||
}
|
||||
|
||||
fun getEffectsFromRodItemStack(stack: ItemStack): List<SpawnBait.Effect> {
|
||||
return getEffectsFromItemStack(stack.components.get(CobblemonItemComponents.BAIT)?.stack ?: ItemStack.EMPTY)
|
||||
}
|
||||
|
||||
fun getEffectsFromItemStack(stack: ItemStack): List<SpawnBait.Effect> {
|
||||
val componentEffects = stack.get(CobblemonItemComponents.BAIT_EFFECTS)?.effects ?: emptyList()
|
||||
return componentEffects.mapNotNull(::getFromIdentifier).flatMap { it.effects } +
|
||||
getEffectsFromItem(stack.itemHolder)
|
||||
}
|
||||
|
||||
fun getBaitIdentifiersFromItem(holder: Holder<Item>): List<ResourceLocation> {
|
||||
return effectsMap.entries.filter { it.value.item.fits(holder) }.map { it.key }
|
||||
}
|
||||
|
||||
fun getBaitFromItemStack(holder: Holder<Item>): List<SpawnBait> {
|
||||
return effectsMap.values.filter { it.item.fits(holder) }
|
||||
}
|
||||
|
||||
private fun getEffectsFromItem(holder: Holder<Item>): List<SpawnBait.Effect> {
|
||||
return getBaitFromItemStack(holder).flatMap { it.effects }
|
||||
}
|
||||
|
||||
fun getFromIdentifier(identifier: ResourceLocation): SpawnBait? {
|
||||
// Check normal spawn bait registry
|
||||
effectsMap[identifier]?.let { return it }
|
||||
|
||||
// check seasoning spawn bait registry
|
||||
if (identifier.namespace == "seasonings") {
|
||||
val seasoning = com.cobblemon.mod.common.api.cooking.Seasonings.seasonings.find {
|
||||
it.ingredient is RegistryLikeIdentifierCondition &&
|
||||
(it.ingredient as RegistryLikeIdentifierCondition<Item>).identifier.path == identifier.path
|
||||
}
|
||||
|
||||
if (seasoning != null && !seasoning.baitEffects.isNullOrEmpty()) {
|
||||
return SpawnBait(
|
||||
item = seasoning.ingredient,
|
||||
effects = seasoning.baitEffects
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
// if it has bait effects and is not listed as a seasoning then it is a bait
|
||||
fun isFishingBait(stack: ItemStack): Boolean {
|
||||
val holder = stack.itemHolder
|
||||
return effectsMap.values.any { it.item.fits(holder) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.fishing
|
||||
|
||||
import kotlin.math.ceil
|
||||
|
||||
object SpawnBaitUtils {
|
||||
fun mergeEffects(effects: List<SpawnBait.Effect>): List<SpawnBait.Effect> {
|
||||
val grouped = effects.groupBy { Pair(it.type, it.subcategory) }
|
||||
|
||||
return grouped.map { (key, groupEffects) ->
|
||||
val (type, subcategory) = key
|
||||
|
||||
val count = groupEffects.size
|
||||
val totalChance = groupEffects.sumOf { it.chance }
|
||||
val totalValue = groupEffects.sumOf { it.value }
|
||||
|
||||
val multiplier = when (count) {
|
||||
2 -> 0.8
|
||||
3 -> 0.6
|
||||
else -> 1.0
|
||||
}
|
||||
|
||||
val adjustedChance = (totalChance * multiplier).coerceAtMost(1.0)
|
||||
val adjustedValue = ceil(totalValue * multiplier)
|
||||
|
||||
SpawnBait.Effect(type, subcategory, adjustedChance, adjustedValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,6 +215,7 @@ fun drawPosablePortrait(
|
||||
ageInTicks: Float = 0F,
|
||||
headYaw: Float = 0F,
|
||||
headPitch: Float = 0F,
|
||||
doQuirks: Boolean = true,
|
||||
r: Float = 1F,
|
||||
g: Float = 1F,
|
||||
b: Float = 1F,
|
||||
@@ -240,6 +241,7 @@ fun drawPosablePortrait(
|
||||
context.put(RenderContext.SPECIES, identifier)
|
||||
context.put(RenderContext.ASPECTS, state.currentAspects)
|
||||
context.put(RenderContext.POSABLE_STATE, state)
|
||||
context.put(RenderContext.DO_QUIRKS, doQuirks)
|
||||
|
||||
val renderType = RenderType.entityCutout(texture)
|
||||
|
||||
|
||||
+19
-12
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
import com.cobblemon.mod.common.api.callback.MoveSelectCallbacks
|
||||
import com.cobblemon.mod.common.api.callback.PartyMoveSelectCallbacks
|
||||
import com.cobblemon.mod.common.api.moves.Move
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.battles.BagItemActionResponse
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
@@ -82,7 +83,7 @@ interface PokemonAndMoveSelectingItem {
|
||||
val bagItem = bagItem
|
||||
if (!battlePokemon.actor.canFitForcedAction()) {
|
||||
player.sendSystemMessage(battleLang("bagitem.cannot").red())
|
||||
} else if (!bagItem!!.canUse(battle, battlePokemon)) {
|
||||
} else if (!bagItem!!.canUse(stack, battle, battlePokemon)) {
|
||||
player.sendSystemMessage(battleLang("bagitem.invalid").red())
|
||||
} else {
|
||||
battlePokemon.actor.forceChoose(BagItemActionResponse(bagItem, battlePokemon, move.template.name))
|
||||
@@ -92,10 +93,16 @@ interface PokemonAndMoveSelectingItem {
|
||||
}
|
||||
}
|
||||
|
||||
fun canUseOnPokemon(pokemon: Pokemon): Boolean
|
||||
fun canUseOnBattlePokemon(battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(battlePokemon.actor.battle, battlePokemon)
|
||||
fun canUseOnMove(pokemon: Pokemon, move: Move): Boolean = canUseOnMove(move)
|
||||
fun canUseOnMove(move: Move): Boolean
|
||||
fun canUseOnPokemon(stack: ItemStack, pokemon: Pokemon): Boolean {
|
||||
if (stack.`is`(CobblemonItemTags.POKE_FOOD)) {
|
||||
return !pokemon.isFull()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun canUseOnBattlePokemon(stack: ItemStack, battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(stack, battlePokemon.actor.battle, battlePokemon)
|
||||
fun canUseOnMove(stack: ItemStack, pokemon: Pokemon, move: Move): Boolean = canUseOnMove(stack, move)
|
||||
fun canUseOnMove(stack: ItemStack, move: Move): Boolean
|
||||
|
||||
fun interactWithSpecific(player: ServerPlayer, stack: ItemStack, pokemon: Pokemon): InteractionResultHolder<ItemStack>? {
|
||||
|
||||
@@ -106,18 +113,18 @@ interface PokemonAndMoveSelectingItem {
|
||||
MoveSelectCallbacks.create(
|
||||
player = player,
|
||||
moves = pokemon.moveSet.toList(),
|
||||
canSelect = ::canUseOnMove,
|
||||
canSelect = { canUseOnMove(stack, it)},
|
||||
handler = { move -> if (stack.isHeld(player)) applyToPokemon(player, stack, pokemon, move) }
|
||||
)
|
||||
return InteractionResultHolder.success(stack)
|
||||
}
|
||||
|
||||
fun interactWithSpecificBattle(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon): InteractionResultHolder<ItemStack>? {
|
||||
return if (canUseOnBattlePokemon(battlePokemon)) {
|
||||
return if (canUseOnBattlePokemon(stack, battlePokemon)) {
|
||||
MoveSelectCallbacks.create(
|
||||
player = player,
|
||||
moves = battlePokemon.moveSet.getMoves(),
|
||||
canSelect = ::canUseOnMove,
|
||||
canSelect = { canUseOnMove(stack, it) },
|
||||
handler = { applyToBattlePokemon(player, stack, battlePokemon, it) }
|
||||
)
|
||||
InteractionResultHolder.success(stack)
|
||||
@@ -131,8 +138,8 @@ interface PokemonAndMoveSelectingItem {
|
||||
PartyMoveSelectCallbacks.createFromPokemon(
|
||||
player = player,
|
||||
pokemon = player.party().toList(),
|
||||
canSelectPokemon = ::canUseOnPokemon,
|
||||
canSelectMove = ::canUseOnMove,
|
||||
canSelectPokemon = { canUseOnPokemon(stack, it) },
|
||||
canSelectMove = { pokemon, move -> canUseOnMove(stack, pokemon, move) },
|
||||
handler = { pk, mv -> if (stack.isHeld(player)) applyToPokemon(player, stack, pk, mv) }
|
||||
)
|
||||
|
||||
@@ -144,8 +151,8 @@ interface PokemonAndMoveSelectingItem {
|
||||
player = player,
|
||||
pokemon = actor.pokemonList.map { it.effectedPokemon },
|
||||
moves = { pk -> actor.pokemonList.find { it.effectedPokemon == pk }!!.moveSet.getMoves() },
|
||||
canSelectPokemon = { pk -> canUseOnBattlePokemon(actor.pokemonList.find { it.effectedPokemon == pk }!!) },
|
||||
canSelectMove = ::canUseOnMove,
|
||||
canSelectPokemon = { pk -> canUseOnBattlePokemon(stack, actor.pokemonList.find { it.effectedPokemon == pk }!!) },
|
||||
canSelectMove = { pokemon, move -> canUseOnMove(stack, pokemon, move) },
|
||||
handler = { pk, mv -> applyToBattlePokemon(player, stack, actor.pokemonList.find { it.effectedPokemon == pk }!!, mv) }
|
||||
)
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.advancement.CobblemonCriteria
|
||||
import com.cobblemon.mod.common.advancement.criterion.PokemonInteractContext
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
import com.cobblemon.mod.common.api.callback.PartySelectCallbacks
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
import com.cobblemon.mod.common.battles.BagItemActionResponse
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
@@ -92,7 +93,7 @@ interface PokemonSelectingItem {
|
||||
val bagItem = bagItem
|
||||
if (!battlePokemon.actor.canFitForcedAction()) {
|
||||
player.sendSystemMessage(battleLang("bagitem.cannot").red())
|
||||
} else if (!bagItem!!.canUse(battle, battlePokemon)) {
|
||||
} else if (!bagItem!!.canUse(stack, battle, battlePokemon)) {
|
||||
player.sendSystemMessage(battleLang("bagitem.invalid").red())
|
||||
} else {
|
||||
battlePokemon.actor.forceChoose(BagItemActionResponse(bagItem, battlePokemon))
|
||||
@@ -105,11 +106,17 @@ interface PokemonSelectingItem {
|
||||
}
|
||||
}
|
||||
|
||||
fun canUseOnPokemon(pokemon: Pokemon): Boolean
|
||||
fun canUseOnBattlePokemon(battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(battlePokemon.actor.battle, battlePokemon)
|
||||
fun canUseOnPokemon(stack: ItemStack, pokemon: Pokemon): Boolean {
|
||||
if (stack.`is`(CobblemonItemTags.POKE_FOOD)) {
|
||||
return !pokemon.isFull()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun canUseOnBattlePokemon(stack: ItemStack, battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(stack, battlePokemon.actor.battle, battlePokemon)
|
||||
|
||||
fun interactWithSpecificBattle(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon): InteractionResultHolder<ItemStack> {
|
||||
return if (canUseOnBattlePokemon(battlePokemon)) {
|
||||
return if (canUseOnBattlePokemon(stack, battlePokemon)) {
|
||||
applyToBattlePokemon(player, stack, battlePokemon)
|
||||
InteractionResultHolder.success(stack)
|
||||
} else {
|
||||
@@ -127,7 +134,7 @@ interface PokemonSelectingItem {
|
||||
PartySelectCallbacks.createFromPokemon(
|
||||
player = player,
|
||||
pokemon = party,
|
||||
canSelect = ::canUseOnPokemon,
|
||||
canSelect = { pk -> canUseOnPokemon(stack, pk) },
|
||||
handler = { pk ->
|
||||
if (stack.isHeld(player)) {
|
||||
applyToPokemon(player, stack, pk)
|
||||
@@ -136,6 +143,7 @@ interface PokemonSelectingItem {
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
return InteractionResultHolder.success(stack)
|
||||
}
|
||||
|
||||
@@ -143,7 +151,7 @@ interface PokemonSelectingItem {
|
||||
PartySelectCallbacks.createBattleSelect(
|
||||
player = player,
|
||||
pokemon = actor.pokemonList,
|
||||
canSelect = { pk -> canUseOnBattlePokemon(actor.pokemonList.find { it.effectedPokemon == pk.effectedPokemon }!!) },
|
||||
canSelect = { pk -> canUseOnBattlePokemon(stack, actor.pokemonList.find { it.effectedPokemon == pk.effectedPokemon }!!) },
|
||||
handler = { pk -> applyToBattlePokemon(player, stack, actor.pokemonList.find { it.effectedPokemon == pk.effectedPokemon }!!) }
|
||||
)
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.cobblemon.mod.common.CobblemonActivities
|
||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.CobblemonUnlockableWallpapers
|
||||
import com.cobblemon.mod.common.Environment
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.ActorType
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
@@ -32,6 +33,7 @@ import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
|
||||
import com.cobblemon.mod.common.api.moves.animations.NPCProvider
|
||||
import com.cobblemon.mod.common.api.npc.NPCClasses
|
||||
import com.cobblemon.mod.common.api.npc.configuration.interaction.DialogueNPCInteractionConfiguration
|
||||
import com.cobblemon.mod.common.api.npc.configuration.interaction.ScriptNPCInteractionConfiguration
|
||||
import com.cobblemon.mod.common.api.npc.partyproviders.SimplePartyProvider
|
||||
import com.cobblemon.mod.common.api.pokedex.AbstractPokedexManager
|
||||
@@ -44,8 +46,11 @@ import com.cobblemon.mod.common.api.pokedex.SeenPercent
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.scheduling.ClientTaskTracker
|
||||
import com.cobblemon.mod.common.api.scheduling.Schedulable
|
||||
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
|
||||
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
||||
import com.cobblemon.mod.common.api.spawning.context.SpawningContext
|
||||
import com.cobblemon.mod.common.api.spawning.position.SpawnablePosition
|
||||
import com.cobblemon.mod.common.api.storage.PokemonStore
|
||||
import com.cobblemon.mod.common.api.storage.party.NPCPartyStore
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyStore
|
||||
@@ -68,7 +73,9 @@ import com.cobblemon.mod.common.net.messages.client.animation.PlayPosableAnimati
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
||||
import com.cobblemon.mod.common.pokemon.Gender
|
||||
import com.cobblemon.mod.common.pokemon.IVs
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
|
||||
@@ -96,6 +103,7 @@ import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.damagesource.DamageSource
|
||||
import net.minecraft.world.damagesource.DamageTypes
|
||||
@@ -197,7 +205,15 @@ object MoLangFunctions {
|
||||
runtime.environment.variable = params.environment.variable
|
||||
runtime.environment.context = params.environment.context
|
||||
val expression = params.getString(0).asExpressionLike()
|
||||
runtime.resolve(expression)
|
||||
val delayInSeconds = params.getDoubleOrNull(1)?.toFloat() ?: 0.0f
|
||||
if (delayInSeconds > 0.0f) {
|
||||
val tracker = if (Cobblemon.implementation.environment() == Environment.SERVER) ServerTaskTracker else ClientTaskTracker
|
||||
tracker.after(delayInSeconds) {
|
||||
runtime.resolve(expression)
|
||||
}
|
||||
} else {
|
||||
runtime.resolve(expression)
|
||||
}
|
||||
},
|
||||
"system_time_millis" to java.util.function.Function { _ ->
|
||||
DoubleValue(System.currentTimeMillis())
|
||||
@@ -344,6 +360,27 @@ object MoLangFunctions {
|
||||
return@put DoubleValue.ZERO
|
||||
}
|
||||
}
|
||||
map.put("play_sound_on_server") { params ->
|
||||
val sound = params.getString(0).asResource()
|
||||
val soundSource = params.getString(1).uppercase()
|
||||
val x = params.getDouble(2)
|
||||
val y = params.getDouble(3)
|
||||
val z = params.getDouble(4)
|
||||
val player = params.getOrNull<MoValue>(5)?.let {
|
||||
if (it is StringValue) world.getPlayerByUUID(UUID.fromString(it.value))
|
||||
else if (it is ObjectValue<*>) it.obj
|
||||
else null
|
||||
} as? ServerPlayer
|
||||
val volume = params.getDoubleOrNull(6)?.toFloat() ?: 1.0f
|
||||
val pitch = params.getDoubleOrNull(7)?.toFloat() ?: 1.0f
|
||||
|
||||
val packet = UnvalidatedPlaySoundS2CPacket(sound, SoundSource.valueOf(soundSource), x, y, z, volume, pitch)
|
||||
if (player != null) {
|
||||
packet.sendToPlayer(player)
|
||||
} else {
|
||||
packet.sendToPlayersAround(x, y, z, 16.0, world.dimension())
|
||||
}
|
||||
}
|
||||
map.put("get_entities_around") { params ->
|
||||
val x = params.getDouble(0)
|
||||
val y = params.getDouble(1)
|
||||
@@ -404,6 +441,15 @@ object MoLangFunctions {
|
||||
val command = params.getString(0)
|
||||
player.server.commands.performPrefixedCommand(player.createCommandSourceStack(), command)
|
||||
}
|
||||
map.put("play_sound_on_server") { params ->
|
||||
val sound = params.getString(0).asResource()
|
||||
val soundSource = SoundSource.valueOf(params.getString(1).uppercase())
|
||||
val volume = params.getDoubleOrNull(2)?.toFloat() ?: 1.0f
|
||||
val pitch = params.getDoubleOrNull(3)?.toFloat() ?: 1.0f
|
||||
|
||||
val packet = UnvalidatedPlaySoundS2CPacket(sound, soundSource, player.x, player.y, player.z, volume, pitch)
|
||||
packet.sendToPlayer(player)
|
||||
}
|
||||
map.put("is_party_at_full_health") { _ ->
|
||||
DoubleValue(player.party().none(Pokemon::canBeHealed)) }
|
||||
map.put("can_heal_at_healer") { params ->
|
||||
@@ -618,8 +664,9 @@ object MoLangFunctions {
|
||||
map.put("biome") { _ -> entity.level().getBiome(entity.blockPosition()).asBiomeMoLangValue() }
|
||||
map.put("is_passenger") { DoubleValue(entity.isPassenger) }
|
||||
map.put("find_nearby_block") { params ->
|
||||
val type = params.getString(0).asIdentifierDefaultingNamespace(namespace = "minecraft")
|
||||
val isTag = type.path.startsWith("#")
|
||||
val input = params.getString(0)
|
||||
val isTag = input.contains("#")
|
||||
val type = input.replace("#", "").asIdentifierDefaultingNamespace(namespace = "minecraft")
|
||||
val range = params.getDoubleOrNull(1) ?: 10
|
||||
val blockPos = entity.level().getBlockStatesWithPos(AABB.ofSize(entity.position(), range.toDouble(), range.toDouble(), range.toDouble()))
|
||||
.filter { it.first.blockHolder.let { if (isTag) it.`is`(TagKey.create(Registries.BLOCK, type)) else it.`is`(type) } }
|
||||
@@ -675,6 +722,17 @@ object MoLangFunctions {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entity is Schedulable) {
|
||||
map.put("run_molang_after") { params ->
|
||||
val expression = params.getString(0).asExpressionLike()
|
||||
val delayInSeconds = params.getDouble(1).toFloat()
|
||||
val runtime = MoLangRuntime()
|
||||
runtime.environment.cloneFrom(params.environment)
|
||||
entity.after(delayInSeconds) {
|
||||
runtime.resolve(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
// q.entity.spawn_bedrock_particles(effect, locator, [player]) - sends to everyone nearby or just to the player if they're set. Locator is necessary even if unused on non-posables.
|
||||
map.put("spawn_bedrock_particles") { params ->
|
||||
val particle = params.getString(0).asResource()
|
||||
@@ -811,6 +869,17 @@ object MoLangFunctions {
|
||||
npc.hideNameTag = !nameTagVisible
|
||||
return@put DoubleValue.ONE
|
||||
}
|
||||
map.put("unset_interaction") {
|
||||
npc.interaction = null
|
||||
return@put DoubleValue.ONE
|
||||
}
|
||||
map.put("set_dialogue_interaction") { params ->
|
||||
val dialogue = params.getString(0).asIdentifierDefaultingNamespace()
|
||||
npc.interaction = DialogueNPCInteractionConfiguration().also {
|
||||
it.dialogue = dialogue
|
||||
}
|
||||
return@put DoubleValue.ONE
|
||||
}
|
||||
map.put("set_script_interaction") { params ->
|
||||
val script = params.getString(0).asIdentifierDefaultingNamespace()
|
||||
npc.interaction = ScriptNPCInteractionConfiguration().also {
|
||||
@@ -1035,6 +1104,19 @@ object MoLangFunctions {
|
||||
map.put("apply_potential_marks") {
|
||||
return@put DoubleValue(pokemon.applyPotentialMarks())
|
||||
}
|
||||
map.put("hyper_train_iv") { params ->
|
||||
val statId = params.getString(0)
|
||||
val stat = Stats.getStat(statId)
|
||||
val value = params.getIntOrNull(1) ?: IVs.MAX_VALUE
|
||||
|
||||
if (Stats.PERMANENT.contains(stat)) {
|
||||
pokemon.hyperTrainIV(stat, value)
|
||||
return@put DoubleValue.ONE
|
||||
} else {
|
||||
Cobblemon.LOGGER.error("Unknown or non-permanent stat: ${stat.toString()}")
|
||||
return@put DoubleValue.ZERO
|
||||
}
|
||||
}
|
||||
map
|
||||
}
|
||||
)
|
||||
@@ -1045,7 +1127,11 @@ object MoLangFunctions {
|
||||
map.put("in_battle") { DoubleValue(pokemonEntity.isBattling) }
|
||||
map.put("is_moving") { DoubleValue((pokemonEntity.moveControl as? PokemonMoveControl)?.hasWanted() == true) }
|
||||
map.put("is_flying") { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
|
||||
map.put("is_gliding") { DoubleValue(pokemonEntity.useRidingAltPose()) }
|
||||
map.put("is_flying") { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
|
||||
map.put("get_alt_pose") { StringValue(pokemonEntity.getAltPose()) }
|
||||
map.put("is_gliding") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("gliding"))) }
|
||||
map.put("is_sprinting") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("sprinting"))) }
|
||||
map.put("in_air") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("in_air"))) }
|
||||
map.put("is_ridden") { DoubleValue(pokemonEntity.hasControllingPassenger()) }
|
||||
map.put("has_aspect") { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
|
||||
map.put("is_pokemon") { DoubleValue.ONE }
|
||||
@@ -1180,7 +1266,7 @@ object MoLangFunctions {
|
||||
}
|
||||
)
|
||||
|
||||
val spawningContextFunctions = mutableListOf<(SpawningContext) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
|
||||
val spawningContextFunctions = mutableListOf<(SpawnablePosition) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
|
||||
{ spawningContext ->
|
||||
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
|
||||
val worldValue = spawningContext.world.registryAccess().registryOrThrow(Registries.DIMENSION).wrapAsHolder(spawningContext.world).asWorldMoLangValue()
|
||||
@@ -1194,7 +1280,6 @@ object MoLangFunctions {
|
||||
map.put("moon_phase") { _ -> DoubleValue(spawningContext.moonPhase.toDouble()) }
|
||||
map.put("can_see_sky") { _ -> DoubleValue(spawningContext.canSeeSky) }
|
||||
map.put("sky_light") { _ -> DoubleValue(spawningContext.skyLight.toDouble()) }
|
||||
map.put("bucket") { _ -> StringValue(spawningContext.cause.bucket.name) }
|
||||
map.put("player") { _ ->
|
||||
val causeEntity = spawningContext.cause.entity ?: return@put DoubleValue.ZERO
|
||||
if (causeEntity is ServerPlayer) {
|
||||
@@ -1331,6 +1416,8 @@ object MoLangFunctions {
|
||||
map.put("hitbox_height") { DoubleValue(species.hitbox.height) }
|
||||
map.put("hitbox_fixed") { DoubleValue(species.hitbox.fixed) }
|
||||
map.put("catch_rate") { DoubleValue(species.catchRate) }
|
||||
map.put("labels") { return@put species.labels.asArrayValue { StringValue(it) } }
|
||||
map.put("has_label") { params -> DoubleValue(species.labels.contains(params.getString(0))) }
|
||||
map
|
||||
}
|
||||
)
|
||||
@@ -1532,7 +1619,7 @@ object MoLangFunctions {
|
||||
return value
|
||||
}
|
||||
|
||||
fun SpawningContext.asMoLangValue(): ObjectValue<SpawningContext> {
|
||||
fun SpawnablePosition.asMoLangValue(): ObjectValue<SpawnablePosition> {
|
||||
val value = ObjectValue(
|
||||
obj = this,
|
||||
stringify = { it.toString() }
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.moves
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.types.ElementalType
|
||||
import com.cobblemon.mod.common.api.types.ElementalTypes
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
object HiddenPowerUtil {
|
||||
val hiddenPowerTable = arrayOf(
|
||||
ElementalTypes.FIGHTING,
|
||||
ElementalTypes.FLYING,
|
||||
ElementalTypes.POISON,
|
||||
ElementalTypes.GROUND,
|
||||
ElementalTypes.ROCK,
|
||||
ElementalTypes.BUG,
|
||||
ElementalTypes.GHOST,
|
||||
ElementalTypes.STEEL,
|
||||
ElementalTypes.FIRE,
|
||||
ElementalTypes.WATER,
|
||||
ElementalTypes.GRASS,
|
||||
ElementalTypes.ELECTRIC,
|
||||
ElementalTypes.PSYCHIC,
|
||||
ElementalTypes.ICE,
|
||||
ElementalTypes.DRAGON,
|
||||
ElementalTypes.DARK
|
||||
)
|
||||
|
||||
fun getHiddenPowerType(pokemon: Pokemon?): ElementalType {
|
||||
if (pokemon == null) {
|
||||
return ElementalTypes.NORMAL
|
||||
}
|
||||
val ivs = pokemon.ivs
|
||||
val ivArray = arrayOf(
|
||||
ivs[Stats.HP],
|
||||
ivs[Stats.ATTACK],
|
||||
ivs[Stats.DEFENCE],
|
||||
ivs[Stats.SPEED],
|
||||
ivs[Stats.SPECIAL_ATTACK],
|
||||
ivs[Stats.SPECIAL_DEFENCE]
|
||||
).map { it ?: return@getHiddenPowerType ElementalTypes.NORMAL }
|
||||
var tableIndex = 0
|
||||
ivArray.forEachIndexed { index, it ->
|
||||
tableIndex += (it % 2) shl index
|
||||
}
|
||||
tableIndex = tableIndex * 15 / 63
|
||||
return hiddenPowerTable[tableIndex.coerceAtMost(hiddenPowerTable.size - 1)]
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectTimeline
|
||||
import com.cobblemon.mod.common.api.moves.categories.DamageCategories
|
||||
import com.cobblemon.mod.common.api.moves.categories.DamageCategory
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.types.ElementalType
|
||||
import com.cobblemon.mod.common.api.types.ElementalTypes
|
||||
import com.cobblemon.mod.common.battles.MoveTarget
|
||||
@@ -100,24 +99,6 @@ open class MoveTemplate(
|
||||
Moves::getByName,
|
||||
MoveTemplate::name
|
||||
) { id -> "No MoveTemplate for ID $id" }
|
||||
val hiddenPowerTable = arrayOf(
|
||||
ElementalTypes.FIGHTING,
|
||||
ElementalTypes.FLYING,
|
||||
ElementalTypes.POISON,
|
||||
ElementalTypes.GROUND,
|
||||
ElementalTypes.ROCK,
|
||||
ElementalTypes.BUG,
|
||||
ElementalTypes.GHOST,
|
||||
ElementalTypes.STEEL,
|
||||
ElementalTypes.FIRE,
|
||||
ElementalTypes.WATER,
|
||||
ElementalTypes.GRASS,
|
||||
ElementalTypes.ELECTRIC,
|
||||
ElementalTypes.PSYCHIC,
|
||||
ElementalTypes.ICE,
|
||||
ElementalTypes.DRAGON,
|
||||
ElementalTypes.DARK
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,21 +127,7 @@ open class MoveTemplate(
|
||||
return this.elementalType
|
||||
}
|
||||
if (name == "hiddenpower") {
|
||||
val ivs = pokemon.ivs
|
||||
val ivArray = arrayOf(
|
||||
ivs[Stats.HP],
|
||||
ivs[Stats.ATTACK],
|
||||
ivs[Stats.DEFENCE],
|
||||
ivs[Stats.SPEED],
|
||||
ivs[Stats.SPECIAL_ATTACK],
|
||||
ivs[Stats.SPECIAL_DEFENCE]
|
||||
).map { it ?: return@getEffectiveElementalType ElementalTypes.NORMAL }
|
||||
var tableIndex = 0
|
||||
ivArray.forEachIndexed { index, it ->
|
||||
tableIndex += (it % 2) shl index
|
||||
}
|
||||
tableIndex = tableIndex * 15 / 63
|
||||
return hiddenPowerTable[tableIndex.coerceAtMost(hiddenPowerTable.size - 1)]
|
||||
return HiddenPowerUtil.getHiddenPowerType(pokemon)
|
||||
}
|
||||
// TODO: Handle ability suppression: clientactivebattlepokemon needs data about volatiles
|
||||
// TODO: Handle Liquid Voice: need to know what moves have the sound flag
|
||||
|
||||
-1
@@ -16,7 +16,6 @@ import com.cobblemon.mod.common.api.moves.animations.UsersProvider
|
||||
import com.cobblemon.mod.common.api.scheduling.after
|
||||
import com.cobblemon.mod.common.entity.ai.OmniPathNavigation.NavigationContext
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.PokemonNavigation
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
@@ -76,6 +76,8 @@ interface NetworkPacket<T: NetworkPacket<T>> : CustomPacketPayload, Encodable {
|
||||
server.playerList.players.filter { player ->
|
||||
if (exclusionCondition.invoke(player))
|
||||
return@filter false
|
||||
if (player.level().dimension() != worldKey)
|
||||
return@filter false
|
||||
val xDiff = x - player.x
|
||||
val yDiff = y - player.y
|
||||
val zDiff = z - player.z
|
||||
|
||||
Loaded 100 of 3366 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user