mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-26 17:16:25 -04:00
Compare commits
1633
Commits
v1.3.2
...
pokesnap_test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b85132e0b | ||
|
|
9b06f6a31f | ||
|
|
b3696dd45c | ||
|
|
aeda9d94a6 | ||
|
|
e817675abc | ||
|
|
49ebd740b6 | ||
|
|
a96b550618 | ||
|
|
b1431b1be1 | ||
|
|
19400a71f2 | ||
|
|
87661224da | ||
|
|
92dc6fefe0 | ||
|
|
c99b1503cb | ||
|
|
8ede54739b | ||
|
|
921f3796c1 | ||
|
|
225d170ee3 | ||
|
|
5e3479eb8f | ||
|
|
13379eb8d0 | ||
|
|
47f05d0b37 | ||
|
|
5f6bfa03aa | ||
|
|
83ac0388d6 | ||
|
|
454c2b368a | ||
|
|
4395514376 | ||
|
|
a8f7141c14 | ||
|
|
eba32fbf60 | ||
|
|
57a3ad9c9b | ||
|
|
40c2c843a2 | ||
|
|
b20db43afa | ||
|
|
e81c025152 | ||
|
|
39a9c60a84 | ||
|
|
dd3787896b | ||
|
|
80ddbaf50c | ||
|
|
62c9654f97 | ||
|
|
98b5d69d01 | ||
|
|
87f0811c2b | ||
|
|
ec58079b4f | ||
|
|
7c3cf3f498 | ||
|
|
a7c0a911e3 | ||
|
|
fee8634661 | ||
|
|
68a517332f | ||
|
|
b78bdd727f | ||
|
|
610e197236 | ||
|
|
27ee34573d | ||
|
|
e4bd024567 | ||
|
|
e41d94b5dc | ||
|
|
00ae3841db | ||
|
|
b0a54a408f | ||
|
|
a34735891a | ||
|
|
17552017f9 | ||
|
|
d90cd5b9a8 | ||
|
|
33fe1a7c32 | ||
|
|
17096f3bb7 | ||
|
|
81f733e89f | ||
|
|
fac7419225 | ||
|
|
69d174b6a6 | ||
|
|
d66f534b95 | ||
|
|
6f342045f4 | ||
|
|
726aeac836 | ||
|
|
f01c5a5ceb | ||
|
|
5876d83147 | ||
|
|
ae1a55fa98 | ||
|
|
417fefa911 | ||
|
|
e30cc3dce8 | ||
|
|
63f721bc9b | ||
|
|
27248fd17d | ||
|
|
c198aee827 | ||
|
|
a8c6d58499 | ||
|
|
9e748cc9cf | ||
|
|
5890918e04 | ||
|
|
c0567ac11f | ||
|
|
5036e334dc | ||
|
|
9f798cddf5 | ||
|
|
eb2828e0a4 | ||
|
|
53f127fc23 | ||
|
|
c463bb6e06 | ||
|
|
4e9d45d38c | ||
|
|
4e2f7d3bc5 | ||
|
|
8975b099ad | ||
|
|
308380706a | ||
|
|
ef80924526 | ||
|
|
fadf57046d | ||
|
|
13cedaaf73 | ||
|
|
0a0806716b | ||
|
|
af59cb5e58 | ||
|
|
c0f8e37206 | ||
|
|
e64aaf66ab | ||
|
|
a946dfea1f | ||
|
|
f2c459cc06 | ||
|
|
6f12f53e85 | ||
|
|
073ee8e283 | ||
|
|
d3a5ad8efa | ||
|
|
62a2dcc606 | ||
|
|
a7f71eb437 | ||
|
|
b65dab7f30 | ||
|
|
ac76878002 | ||
|
|
fe219e52e6 | ||
|
|
bfd28ec9b0 | ||
|
|
1063441b0e | ||
|
|
4e89f45253 | ||
|
|
56aa5ae8d8 | ||
|
|
156a7a70eb | ||
|
|
3b13b9f246 | ||
|
|
0a8d920285 | ||
|
|
f5418a8088 | ||
|
|
cae097bf2c | ||
|
|
f760003c3a | ||
|
|
38f70c5960 | ||
|
|
81b00d7f85 | ||
|
|
948ceeaa8d | ||
|
|
1eda446897 | ||
|
|
49d03c0336 | ||
|
|
c5d254cca7 | ||
|
|
4f7fda1e96 | ||
|
|
d3e10cb570 | ||
|
|
51d7d2cb04 | ||
|
|
ac53d2da95 | ||
|
|
17e41f5f0b | ||
|
|
4bd70698ce | ||
|
|
23b750d5e9 | ||
|
|
ab2b67c426 | ||
|
|
d68c912ca6 | ||
|
|
c391d1a5e0 | ||
|
|
0af39118eb | ||
|
|
392b69937f | ||
|
|
e32af733f1 | ||
|
|
e1509c9dab | ||
|
|
1cb6baee59 | ||
|
|
9403cb6296 | ||
|
|
fd157fae4f | ||
|
|
9ca472ccaf | ||
|
|
13b7e0d418 | ||
|
|
a6ddc1e4ae | ||
|
|
a5b1b87ec5 | ||
|
|
b3255045fa | ||
|
|
90f3acebac | ||
|
|
0da91fb255 | ||
|
|
ba3b26ac74 | ||
|
|
966761776d | ||
|
|
24f07c58a0 | ||
|
|
a8b5f649a8 | ||
|
|
295c73ae69 | ||
|
|
899bdb38ac | ||
|
|
f30e5bda1e | ||
|
|
76c870b472 | ||
|
|
963448e173 | ||
|
|
48d2fc6e2e | ||
|
|
5868d39431 | ||
|
|
c47b3a21db | ||
|
|
0d12fb1f1c | ||
|
|
78c7188a11 | ||
|
|
ff5f63a998 | ||
|
|
b9a8a9be11 | ||
|
|
2046482252 | ||
|
|
6a737999a9 | ||
|
|
89d37e583b | ||
|
|
e077a5d453 | ||
|
|
e7208ed396 | ||
|
|
27f8bbf029 | ||
|
|
2f97a69b8c | ||
|
|
79d67389ba | ||
|
|
61f2150f2e | ||
|
|
5d63c8fe06 | ||
|
|
0d109a64fd | ||
|
|
5daef700e7 | ||
|
|
21bd1550f0 | ||
|
|
0d4f63ba01 | ||
|
|
946cff21fb | ||
|
|
8a2291cd6e | ||
|
|
304ac0e07a | ||
|
|
3cac1138fb | ||
|
|
b19a11f8ab | ||
|
|
cad64ae24b | ||
|
|
9036909968 | ||
|
|
53b98e8008 | ||
|
|
574fd92827 | ||
|
|
e6d7513c20 | ||
|
|
e36252318a | ||
|
|
5d5dbb9e79 | ||
|
|
4036592c9a | ||
|
|
c0ddbad4f5 | ||
|
|
fa1f485cd2 | ||
|
|
b5aeb0e5f7 | ||
|
|
9c2680783a | ||
|
|
b7ed72241b | ||
|
|
689f9eabc0 | ||
|
|
4fd24be1d3 | ||
|
|
7579203527 | ||
|
|
9e3dd9373c | ||
|
|
c9b9ac7d07 | ||
|
|
dddae893cd | ||
|
|
86508801d3 | ||
|
|
de44411ad2 | ||
|
|
e59aa01345 | ||
|
|
3f3e8b5747 | ||
|
|
bb769fa165 | ||
|
|
163218c0a8 | ||
|
|
e61eadb834 | ||
|
|
29c8bbe9e9 | ||
|
|
7c42390515 | ||
|
|
ff84ca69cd | ||
|
|
dda3c4e981 | ||
|
|
072ad5ff12 | ||
|
|
1570bbf42b | ||
|
|
41cfe79b0e | ||
|
|
dc4e3dc39c | ||
|
|
d100537d41 | ||
|
|
fe218399e2 | ||
|
|
8f4a4a7e45 | ||
|
|
b3757113ac | ||
|
|
3bb17ffc6e | ||
|
|
f37924fb0c | ||
|
|
6e2765902e | ||
|
|
d7c32e4ad8 | ||
|
|
8732094c28 | ||
|
|
38fecf337e | ||
|
|
3c7c640217 | ||
|
|
b7e8cad3bd | ||
|
|
d553332017 | ||
|
|
de04379297 | ||
|
|
10bf9d1abd | ||
|
|
03b0bb9937 | ||
|
|
51a3d686ff | ||
|
|
267c14cdd5 | ||
|
|
c9367f63b4 | ||
|
|
48f8561662 | ||
|
|
951a36f82e | ||
|
|
e9edd7a1e9 | ||
|
|
cb407bb649 | ||
|
|
5e28612d99 | ||
|
|
ea007d21db | ||
|
|
dc1a035dae | ||
|
|
71db46d86b | ||
|
|
a61b71205b | ||
|
|
63b14aa4ba | ||
|
|
fb23e3961c | ||
|
|
bdf9606d61 | ||
|
|
bf5b03398c | ||
|
|
3a824b1971 | ||
|
|
0bbecc5951 | ||
|
|
c60fb253cd | ||
|
|
34240a101a | ||
|
|
c6a4db47f4 | ||
|
|
ac2dbde41e | ||
|
|
b8d19b3c4c | ||
|
|
747aedca27 | ||
|
|
9540bc9394 | ||
|
|
a7fed0d042 | ||
|
|
aedb0755f9 | ||
|
|
23eb10f5ea | ||
|
|
2c134c5e1b | ||
|
|
f7f70f14bc | ||
|
|
d3834b0bb7 | ||
|
|
2033240b83 | ||
|
|
1400505757 | ||
|
|
9da0459793 | ||
|
|
7ac41e2f68 | ||
|
|
e0cdc08cd3 | ||
|
|
438e502a5a | ||
|
|
d7b344cff8 | ||
|
|
249c305474 | ||
|
|
5b6ed359a3 | ||
|
|
d14e16fe5b | ||
|
|
65dd132081 | ||
|
|
54cd0ba700 | ||
|
|
7f8b241695 | ||
|
|
0b824fe4c1 | ||
|
|
46b4bfa7ea | ||
|
|
c9fc2ce95d | ||
|
|
91eff015dc | ||
|
|
a9c8825b3c | ||
|
|
9d64b0f06a | ||
|
|
f5a308e579 | ||
|
|
2b3c2358a5 | ||
|
|
a84a2aac58 | ||
|
|
fe86d644ad | ||
|
|
9eb8d5e832 | ||
|
|
5d2e877176 | ||
|
|
b2b08ac098 | ||
|
|
ae8e4a4f3a | ||
|
|
e5f0911b83 | ||
|
|
e1ae600419 | ||
|
|
34315d9f1d | ||
|
|
773cef8e46 | ||
|
|
282a15b1b2 | ||
|
|
3b17ad4f54 | ||
|
|
04c5b698c2 | ||
|
|
123029199c | ||
|
|
8f70bd5eaf | ||
|
|
24310d5144 | ||
|
|
b4b5d62632 | ||
|
|
d550d775a6 | ||
|
|
e572584dbf | ||
|
|
6ac58cf7c2 | ||
|
|
e8a1e66658 | ||
|
|
9c67d0ad6f | ||
|
|
0747d08a90 | ||
|
|
299ab3d5f7 | ||
|
|
7e0f48ea54 | ||
|
|
49a5090903 | ||
|
|
7e0e55d126 | ||
|
|
f3fa765890 | ||
|
|
a9a91a813a | ||
|
|
579e48f93c | ||
|
|
e8520953f6 | ||
|
|
47deb6504b | ||
|
|
cd0f95169a | ||
|
|
a23b37ee47 | ||
|
|
370d65284d | ||
|
|
e2b2ee9031 | ||
|
|
141b38b81c | ||
|
|
f41c2aa0c1 | ||
|
|
87fffe67f5 | ||
|
|
7a13a5a4d1 | ||
|
|
9efc3f1eef | ||
|
|
8188cabb4f | ||
|
|
b545e01aef | ||
|
|
c34a09430a | ||
|
|
403acf5822 | ||
|
|
d53c17bc8e | ||
|
|
7bc9778ce3 | ||
|
|
57687ffcdb | ||
|
|
d40e2706c0 | ||
|
|
abecc6c74d | ||
|
|
709b933661 | ||
|
|
d426d6e843 | ||
|
|
234acf0787 | ||
|
|
b4b0bed36c | ||
|
|
65f0bfdcd9 | ||
|
|
f598af314a | ||
|
|
cef14e938f | ||
|
|
f53cd87081 | ||
|
|
bfc820808f | ||
|
|
57a34e490d | ||
|
|
e817496f7e | ||
|
|
8aea2d5b74 | ||
|
|
47213c3ae4 | ||
|
|
d70fbe70d2 | ||
|
|
3768d4278e | ||
|
|
6283a0bee0 | ||
|
|
43a24a9c98 | ||
|
|
d8b401aee0 | ||
|
|
f64e919bf2 | ||
|
|
a727c099ae | ||
|
|
e4ae8fe6dd | ||
|
|
c46ab35af0 | ||
|
|
25bfdb3aa2 | ||
|
|
7d5b0c9648 | ||
|
|
2ccf49e65c | ||
|
|
bc12466e09 | ||
|
|
7d03f5f780 | ||
|
|
2eb23f0707 | ||
|
|
cbe7626bdc | ||
|
|
f83b10643c | ||
|
|
40be5a2060 | ||
|
|
2b26576a1c | ||
|
|
48d6f7f707 | ||
|
|
ea6bf1fcd1 | ||
|
|
e0ab5e60d0 | ||
|
|
3d4e941af2 | ||
|
|
6aa359d7cc | ||
|
|
646fc606d6 | ||
|
|
37e9823fe0 | ||
|
|
9cd24e76d2 | ||
|
|
fb52c1badd | ||
|
|
24126e582b | ||
|
|
a08ca9c8eb | ||
|
|
896198eca2 | ||
|
|
38a20c76a1 | ||
|
|
7ac80cb716 | ||
|
|
2a83af5626 | ||
|
|
7cc8fd8201 | ||
|
|
901de0031c | ||
|
|
f762ba7425 | ||
|
|
f5b92c11a0 | ||
|
|
ecc5143ae6 | ||
|
|
c6a7dcde33 | ||
|
|
7821801c83 | ||
|
|
85f8f971da | ||
|
|
2808e52873 | ||
|
|
69f8d4a306 | ||
|
|
e7351af2a8 | ||
|
|
7ad5ee633d | ||
|
|
742c4c8087 | ||
|
|
ae41d4ac58 | ||
|
|
3f4086fc90 | ||
|
|
9e993df788 | ||
|
|
a389c21b25 | ||
|
|
b20be79ce6 | ||
|
|
9b05db6c5f | ||
|
|
f7de61ce71 | ||
|
|
9811390573 | ||
|
|
11e7d193fb | ||
|
|
3e2788b789 | ||
|
|
bda999e1fd | ||
|
|
e249a96749 | ||
|
|
2078108ea7 | ||
|
|
ddb24e9621 | ||
|
|
b07795e547 | ||
|
|
7e63cd9c1d | ||
|
|
8680f2ade0 | ||
|
|
5679d4dc05 | ||
|
|
980c0d4c37 | ||
|
|
50f1abd47e | ||
|
|
a555ac8e6d | ||
|
|
96d2b322a3 | ||
|
|
7bae99468b | ||
|
|
8b99cfe98d | ||
|
|
ac6eb38152 | ||
|
|
1621910428 | ||
|
|
b74037afb6 | ||
|
|
753bfa6936 | ||
|
|
53d575b1c4 | ||
|
|
97e90a87c1 | ||
|
|
a72525cf65 | ||
|
|
07e487e0cd | ||
|
|
bcf3fe1dc6 | ||
|
|
8d5d567153 | ||
|
|
0643bc8d58 | ||
|
|
1c6633bfdc | ||
|
|
f876c5f6c8 | ||
|
|
99744af491 | ||
|
|
9f2a4261f0 | ||
|
|
1b6b0524e8 | ||
|
|
5f740b1c58 | ||
|
|
0cd79c6c8f | ||
|
|
f5e492a6ce | ||
|
|
c8c1677182 | ||
|
|
8431e25c31 | ||
|
|
121f7c6a9a | ||
|
|
37f508793d | ||
|
|
5807e4526e | ||
|
|
63a42edb7f | ||
|
|
c523408fe0 | ||
|
|
7baf8e079d | ||
|
|
88105e070b | ||
|
|
cef0ad7efa | ||
|
|
592ead6674 | ||
|
|
98556c1b24 | ||
|
|
137f080ba9 | ||
|
|
4f3601ab3b | ||
|
|
e523c46594 | ||
|
|
251ebe2a37 | ||
|
|
12191b5d96 | ||
|
|
4da74f0bfb | ||
|
|
b893681af5 | ||
|
|
eb159d0702 | ||
|
|
d47197ab3b | ||
|
|
64a2b9c60f | ||
|
|
b4585cabd4 | ||
|
|
dd15de6e94 | ||
|
|
c5dab7208f | ||
|
|
4a5d53a020 | ||
|
|
cc163b73e1 | ||
|
|
d1682b78c6 | ||
|
|
52827c3be6 | ||
|
|
23e2d56db4 | ||
|
|
3451a70cfd | ||
|
|
3869fc590d | ||
|
|
ba4f4c8137 | ||
|
|
7f372c1f16 | ||
|
|
4624e7cab2 | ||
|
|
967053824b | ||
|
|
95bc331dc9 | ||
|
|
3c3ef6a387 | ||
|
|
309de12a0e | ||
|
|
90b22316cb | ||
|
|
dc1aec75ba | ||
|
|
f60b3f1f4f | ||
|
|
3e118dcca6 | ||
|
|
12aac4f52d | ||
|
|
9b1699b507 | ||
|
|
f0cf94b830 | ||
|
|
ddab45148c | ||
|
|
2a23c77da7 | ||
|
|
97625d2750 | ||
|
|
ef600fda79 | ||
|
|
bd6364deac | ||
|
|
1fbdf1fce1 | ||
|
|
6060013110 | ||
|
|
755cf731f0 | ||
|
|
6246af2979 | ||
|
|
6b27f13396 | ||
|
|
9a4fcb15b2 | ||
|
|
07bb57c009 | ||
|
|
2934e38077 | ||
|
|
d60592b5e4 | ||
|
|
f563f69afd | ||
|
|
354914105e | ||
|
|
b154b6de64 | ||
|
|
66e1f621cf | ||
|
|
7d55d52608 | ||
|
|
63d84df283 | ||
|
|
94400e61f5 | ||
|
|
ce337e8fff | ||
|
|
72b6f46c4b | ||
|
|
547af6dd77 | ||
|
|
70119478a5 | ||
|
|
029e120b2c | ||
|
|
7a305792af | ||
|
|
06ed32e4cb | ||
|
|
ee63bf0eab | ||
|
|
48a4add7aa | ||
|
|
dc8d7e36e0 | ||
|
|
1c1a683f2d | ||
|
|
0ee4f60391 | ||
|
|
4a7893f647 | ||
|
|
76890135ef | ||
|
|
930f95d3b6 | ||
|
|
0c15d14f1a | ||
|
|
a2bb0fb3cd | ||
|
|
a97753c339 | ||
|
|
557dda4c1d | ||
|
|
944fdf7c0c | ||
|
|
10b2aecc12 | ||
|
|
565d38f085 | ||
|
|
ada8bc9403 | ||
|
|
2d3d245b03 | ||
|
|
9adeb60abe | ||
|
|
6c91342954 | ||
|
|
98b84d853c | ||
|
|
83ee5f3c3d | ||
|
|
137088296e | ||
|
|
e748059052 | ||
|
|
d748241727 | ||
|
|
f515a2ef72 | ||
|
|
0c9017d5e2 | ||
|
|
fd12789791 | ||
|
|
638c92ec4c | ||
|
|
bee865931a | ||
|
|
77ee8b1743 | ||
|
|
5eef45b49a | ||
|
|
79f7dd1519 | ||
|
|
919dec6809 | ||
|
|
f00f73491d | ||
|
|
c7cf73812c | ||
|
|
80fbab35dc | ||
|
|
ad039cb949 | ||
|
|
0436b36872 | ||
|
|
9f60ce51c7 | ||
|
|
343e13d1ac | ||
|
|
ca175ab164 | ||
|
|
8a62088fb4 | ||
|
|
7e2bb0ca6a | ||
|
|
ebad166b12 | ||
|
|
92f5fd7cd6 | ||
|
|
507319fa0f | ||
|
|
228347e46f | ||
|
|
3a2c12c652 | ||
|
|
a6945adf5a | ||
|
|
295e68b0d5 | ||
|
|
be983f6115 | ||
|
|
6eeda04b78 | ||
|
|
c03097e627 | ||
|
|
163e17fb3f | ||
|
|
a330f95559 | ||
|
|
25d7c8376e | ||
|
|
bc93bae9ab | ||
|
|
4f9ca14301 | ||
|
|
b9515a2a81 | ||
|
|
6200e3a693 | ||
|
|
290f3e2845 | ||
|
|
516e3c4cd9 | ||
|
|
e419030339 | ||
|
|
7675148d37 | ||
|
|
fe739cd644 | ||
|
|
dd5e9c08aa | ||
|
|
03b29ce468 | ||
|
|
d2668a15b0 | ||
|
|
d9a99ad65b | ||
|
|
0fc9d29884 | ||
|
|
f500ab4a87 | ||
|
|
19a85276af | ||
|
|
70c2404b20 | ||
|
|
27a4b3b6f4 | ||
|
|
5df79f083a | ||
|
|
1501c3689a | ||
|
|
277ec8ffcd | ||
|
|
c7b82adfb0 | ||
|
|
fb56430213 | ||
|
|
083b439049 | ||
|
|
98e495f7e4 | ||
|
|
508e607440 | ||
|
|
ab69588331 | ||
|
|
a8ac109a50 | ||
|
|
1813baaa6f | ||
|
|
5b5171b9bc | ||
|
|
b912e8cbca | ||
|
|
cc2eaf6c1a | ||
|
|
fbe31f3232 | ||
|
|
b530af1ff6 | ||
|
|
a608cbe0fe | ||
|
|
a4ed9393f0 | ||
|
|
f294d4fcef | ||
|
|
6046ca10d0 | ||
|
|
d24371b9e4 | ||
|
|
645d84858e | ||
|
|
04ecd3d976 | ||
|
|
c02fe8a00c | ||
|
|
008e42a267 | ||
|
|
316ab772bf | ||
|
|
bca4b06750 | ||
|
|
dea1d74e40 | ||
|
|
12f1259495 | ||
|
|
cc30f4f207 | ||
|
|
775a2038d0 | ||
|
|
1dc8ae036f | ||
|
|
0011993afb | ||
|
|
1ef22ad52a | ||
|
|
e8030c0180 | ||
|
|
e929f6f02d | ||
|
|
8ec91f7a40 | ||
|
|
41b9411d06 | ||
|
|
9518422f62 | ||
|
|
4c03891f19 | ||
|
|
52a3bf50d0 | ||
|
|
c1657b5772 | ||
|
|
e57c9487ca | ||
|
|
7e583d6319 | ||
|
|
11256c0e3a | ||
|
|
ffb53626eb | ||
|
|
a74671f710 | ||
|
|
04d83251b4 | ||
|
|
bece6dfbb0 | ||
|
|
5e5cb4e388 | ||
|
|
8f9dc451f1 | ||
|
|
ffb1c94c3f | ||
|
|
d9b2f0cef8 | ||
|
|
458fa1732c | ||
|
|
3040eee59c | ||
|
|
23e532a214 | ||
|
|
70f1e5e621 | ||
|
|
10033be4b5 | ||
|
|
914067038a | ||
|
|
bf9f08826b | ||
|
|
da27b80e82 | ||
|
|
e6c9c7798e | ||
|
|
d0b7b956e8 | ||
|
|
0301064ed5 | ||
|
|
b8595f8d59 | ||
|
|
d120c8e031 | ||
|
|
aa91b5b20b | ||
|
|
84dfaa0a77 | ||
|
|
1e8ae04ad5 | ||
|
|
0cfa7bf61d | ||
|
|
9987c0c13f | ||
|
|
99a88e66e7 | ||
|
|
b7a3e276f1 | ||
|
|
0240f925f6 | ||
|
|
d9774272ce | ||
|
|
aa2532df6f | ||
|
|
0c14e5dedc | ||
|
|
62248ff97c | ||
|
|
17343abce2 | ||
|
|
0ff73d0c21 | ||
|
|
77da1f8252 | ||
|
|
18301300aa | ||
|
|
ca044e8390 | ||
|
|
a6b68b4076 | ||
|
|
dbce3252ab | ||
|
|
cc3b09f590 | ||
|
|
8ed2b820f2 | ||
|
|
3b967933ca | ||
|
|
665aad40a8 | ||
|
|
527f429c20 | ||
|
|
85803b11b4 | ||
|
|
6d3f3d1353 | ||
|
|
b70748e1b8 | ||
|
|
c6406ab0ea | ||
|
|
28c750caf9 | ||
|
|
ff2db8fa11 | ||
|
|
42d330e1c0 | ||
|
|
062cee2b9a | ||
|
|
5730d812a0 | ||
|
|
ab22780598 | ||
|
|
1b2e0fb58e | ||
|
|
6616234393 | ||
|
|
cb4ad09a11 | ||
|
|
1d81df91eb | ||
|
|
d962d30074 | ||
|
|
e33420bab7 | ||
|
|
17dcbb25c3 | ||
|
|
1b36c40959 | ||
|
|
5096d9a15a | ||
|
|
24737cf606 | ||
|
|
7bd1c24b57 | ||
|
|
db2cd8501e | ||
|
|
fd6348adbe | ||
|
|
36b1bec04b | ||
|
|
7f14b60efb | ||
|
|
239559cfd3 | ||
|
|
c4b2a1546a | ||
|
|
e3c9c16add | ||
|
|
d17f8f90b8 | ||
|
|
278b36234e | ||
|
|
1598c8209a | ||
|
|
bc9182e37f | ||
|
|
68923dd95f | ||
|
|
1d353bdc5b | ||
|
|
df7109ba45 | ||
|
|
ab3449243f | ||
|
|
deb7ece946 | ||
|
|
d8f9f8926b | ||
|
|
457e7b65c9 | ||
|
|
755d4ea612 | ||
|
|
ad6bcb1572 | ||
|
|
42235a35ee | ||
|
|
a8f6e66ab4 | ||
|
|
d6e51b9c55 | ||
|
|
d2970c10b3 | ||
|
|
f3cb2aab87 | ||
|
|
d9c6522685 | ||
|
|
ca54a0abf0 | ||
|
|
1ad743a126 | ||
|
|
cde5a5b408 | ||
|
|
e6a45fd356 | ||
|
|
c3eb05e5c6 | ||
|
|
a82dee2beb | ||
|
|
8099bfe330 | ||
|
|
9d8803caf2 | ||
|
|
7074a63f95 | ||
|
|
95d6a1c183 | ||
|
|
4fd433b072 | ||
|
|
dc6804bba6 | ||
|
|
3e005e5032 | ||
|
|
08827a742f | ||
|
|
f93e8e221a | ||
|
|
cc7433025f | ||
|
|
aa17482a6e | ||
|
|
7f0f6e7c4d | ||
|
|
16a0cd1fe7 | ||
|
|
2fc9d587d9 | ||
|
|
a6a76052a6 | ||
|
|
abeb005bbb | ||
|
|
6835232aa6 | ||
|
|
78ebc9a9eb | ||
|
|
f5e85971f3 | ||
|
|
1d950d9640 | ||
|
|
3b63f88669 | ||
|
|
e85b2aa138 | ||
|
|
371e1426a3 | ||
|
|
256e09846d | ||
|
|
dd2d441b0c | ||
|
|
4f35e8348d | ||
|
|
36c76b96b3 | ||
|
|
ddc57ecd8d | ||
|
|
202a6a0496 | ||
|
|
fbc639cbf3 | ||
|
|
78faf30b32 | ||
|
|
2fe98577b6 | ||
|
|
39cbb448a6 | ||
|
|
fd10f8efd8 | ||
|
|
9161f61017 | ||
|
|
4244680956 | ||
|
|
92ad81f8d1 | ||
|
|
c1c7106bff | ||
|
|
e36b1b22c4 | ||
|
|
e21d445e14 | ||
|
|
dadeb2670b | ||
|
|
aedca9e969 | ||
|
|
e1ca6bbc94 | ||
|
|
22d66103b6 | ||
|
|
0e2a0af914 | ||
|
|
098ff1f96b | ||
|
|
f93445f081 | ||
|
|
85a962e924 | ||
|
|
f6d0f11c99 | ||
|
|
e74b838fb2 | ||
|
|
7591345181 | ||
|
|
8d157a5ad5 | ||
|
|
d41ef023ff | ||
|
|
8b857881a8 | ||
|
|
995a8c2dc0 | ||
|
|
30b769db13 | ||
|
|
ac7bd33f08 | ||
|
|
4dc7accef9 | ||
|
|
90b8923b98 | ||
|
|
9a7e4d05f0 | ||
|
|
8d981d1b05 | ||
|
|
f5bf60dd37 | ||
|
|
585eb2a946 | ||
|
|
ee38a90aad | ||
|
|
d9fc5f5c90 | ||
|
|
5d9be82e8f | ||
|
|
808a238d2a | ||
|
|
6dc4b6af24 | ||
|
|
69908c1ab5 | ||
|
|
f8cdcde27c | ||
|
|
0a505bec75 | ||
|
|
948d599390 | ||
|
|
f561141315 | ||
|
|
8419b140a7 | ||
|
|
4be1ab3cac | ||
|
|
12824f6f4f | ||
|
|
071278caa2 | ||
|
|
60df079794 | ||
|
|
1924862fcb | ||
|
|
dba3de83fa | ||
|
|
12a29d1289 | ||
|
|
bc85fdb778 | ||
|
|
0d0d659ce5 | ||
|
|
535e0b6f87 | ||
|
|
dd8cb49295 | ||
|
|
2c5968986d | ||
|
|
df30a209a5 | ||
|
|
0fea0966c0 | ||
|
|
727fc969fa | ||
|
|
c17ae13578 | ||
|
|
8e09051bf7 | ||
|
|
4f03643840 | ||
|
|
6cdab8f296 | ||
|
|
fc1bade1d1 | ||
|
|
7b29d31009 | ||
|
|
8820a546db | ||
|
|
fd5132b317 | ||
|
|
c4eb422722 | ||
|
|
d8f4638806 | ||
|
|
544efc80d5 | ||
|
|
43fe97a6fe | ||
|
|
f021faf0d3 | ||
|
|
f92aa1777c | ||
|
|
8d864a3ff8 | ||
|
|
965196da2e | ||
|
|
17a1409619 | ||
|
|
51f92e1635 | ||
|
|
9c3f8c9e8f | ||
|
|
923f40ab68 | ||
|
|
cd7c3a0319 | ||
|
|
8311dd8785 | ||
|
|
f489cd096f | ||
|
|
0a4dc34895 | ||
|
|
b1bc867ef8 | ||
|
|
3f6af25afa | ||
|
|
72c4cc0992 | ||
|
|
b0838e88fd | ||
|
|
925d7ce2dc | ||
|
|
2b562ace12 | ||
|
|
9946c39de0 | ||
|
|
037ba953b7 | ||
|
|
5b7b9342e5 | ||
|
|
c52b99270b | ||
|
|
a4000a6c0f | ||
|
|
a56d24b9dc | ||
|
|
607b59a978 | ||
|
|
b8eb2c708e | ||
|
|
2e67e804a7 | ||
|
|
de58d11f9e | ||
|
|
7bffc44db0 | ||
|
|
1099ce055a | ||
|
|
de5e958bf3 | ||
|
|
ab6494a2f6 | ||
|
|
967fbd2608 | ||
|
|
ede62cc049 | ||
|
|
e6ffd2e16d | ||
|
|
ee92206b43 | ||
|
|
e47dbd7b71 | ||
|
|
8ff0835e4e | ||
|
|
301df2e1d1 | ||
|
|
4c4f79494b | ||
|
|
bcd998d690 | ||
|
|
3548ee1172 | ||
|
|
7ab3c18762 | ||
|
|
e20eb6963f | ||
|
|
0d8589daad | ||
|
|
69fd7f5b99 | ||
|
|
52a6a51d5e | ||
|
|
7583e865ee | ||
|
|
651ed9cbcf | ||
|
|
d45a654433 | ||
|
|
ddb426674f | ||
|
|
6c93a6c1a8 | ||
|
|
a69042d892 | ||
|
|
9007a75d69 | ||
|
|
28d0ae9b75 | ||
|
|
742a6b244f | ||
|
|
bbf9836212 | ||
|
|
0b08044298 | ||
|
|
e53aa10f79 | ||
|
|
1393904bc0 | ||
|
|
4c5fcf5310 | ||
|
|
90d51385b3 | ||
|
|
960454794d | ||
|
|
0648185b38 | ||
|
|
aaf5f4d354 | ||
|
|
f6cbadff61 | ||
|
|
5414cbcc14 | ||
|
|
3104239a9f | ||
|
|
e10e048e2c | ||
|
|
32a360ba0c | ||
|
|
99d190abff | ||
|
|
33aa3043c6 | ||
|
|
efb202070c | ||
|
|
23fdda700c | ||
|
|
4577c36afb | ||
|
|
6d9d5d1533 | ||
|
|
a6cc7b77bb | ||
|
|
67251d3724 | ||
|
|
9fba594ca5 | ||
|
|
967e714c37 | ||
|
|
8fac0e0697 | ||
|
|
cdde54c483 | ||
|
|
59ea3bb3f4 | ||
|
|
cc4456e1e3 | ||
|
|
3ef2eca934 | ||
|
|
36331c733b | ||
|
|
be25dc8999 | ||
|
|
1770b44547 | ||
|
|
e058a4ac86 | ||
|
|
09f4d17e15 | ||
|
|
5d57465a5f | ||
|
|
e1e0635d5d | ||
|
|
2652cfa6fa | ||
|
|
e81eaa5b57 | ||
|
|
a33978d5a5 | ||
|
|
78ff7628a6 | ||
|
|
bfa685a434 | ||
|
|
c9aad028ac | ||
|
|
551b2f9ea6 | ||
|
|
3bc44b3ba3 | ||
|
|
edc5ce5fb4 | ||
|
|
b1b7d3fea2 | ||
|
|
7ee88cefe5 | ||
|
|
2cfa9f8985 | ||
|
|
ea89e64e73 | ||
|
|
dd788d9851 | ||
|
|
7894e1895b | ||
|
|
70ee9617ed | ||
|
|
848cdcfc66 | ||
|
|
dd4c289755 | ||
|
|
57cb10d5ce | ||
|
|
9282f94a85 | ||
|
|
8c7eddccbe | ||
|
|
06be0cc40b | ||
|
|
67fe5d0822 | ||
|
|
eba4162db4 | ||
|
|
5bab095036 | ||
|
|
c394f56548 | ||
|
|
5dcbb271a5 | ||
|
|
e7a5c23204 | ||
|
|
e9d4827a9b | ||
|
|
02898701b9 | ||
|
|
0b8488ab0f | ||
|
|
bd3968c7c5 | ||
|
|
dc270bb64e | ||
|
|
8c6c3a6ca0 | ||
|
|
a5cb807bfa | ||
|
|
afafe35d16 | ||
|
|
99c94a1765 | ||
|
|
f12fd1bb93 | ||
|
|
621280df50 | ||
|
|
68d13abb1d | ||
|
|
897bf4e132 | ||
|
|
5944313fe8 | ||
|
|
aa078c1269 | ||
|
|
5ce0c2a749 | ||
|
|
1665032341 | ||
|
|
6739b2d1ac | ||
|
|
ac05f24646 | ||
|
|
2b3045594b | ||
|
|
86d8fb01ef | ||
|
|
fe9a1c7e99 | ||
|
|
0bb782f314 | ||
|
|
452ff46815 | ||
|
|
ee9fafe4fb | ||
|
|
65a193bb84 | ||
|
|
0a922a91b0 | ||
|
|
98810914fa | ||
|
|
75062f5c16 | ||
|
|
a9735c69cb | ||
|
|
adaf17ee4f | ||
|
|
307196e201 | ||
|
|
4e225afc6e | ||
|
|
bf401d1ff0 | ||
|
|
fb6e65d868 | ||
|
|
9ccff2e547 | ||
|
|
673baa178f | ||
|
|
59242d3020 | ||
|
|
aa04b27500 | ||
|
|
954d6fa156 | ||
|
|
dd2d22b793 | ||
|
|
53156bcfdb | ||
|
|
7fae9ac61f | ||
|
|
e9924a8920 | ||
|
|
d2590b05c5 | ||
|
|
03bfce766d | ||
|
|
fab9eed4e1 | ||
|
|
123ed403ae | ||
|
|
8557096359 | ||
|
|
66592af8ef | ||
|
|
0c763e3715 | ||
|
|
8c5fe15835 | ||
|
|
30dbaa0585 | ||
|
|
480a3894f8 | ||
|
|
d3ffbd654b | ||
|
|
43fcdf3f1b | ||
|
|
b52a0a0ebd | ||
|
|
9c1edea469 | ||
|
|
87d8c17f4f | ||
|
|
75f36825af | ||
|
|
506aafbdf0 | ||
|
|
814bba5273 | ||
|
|
b5475b0e3e | ||
|
|
3ab5a4daf3 | ||
|
|
f7672e66ab | ||
|
|
61d926a23d | ||
|
|
5ab364f0ab | ||
|
|
182f5ce1f9 | ||
|
|
a05bc8887e | ||
|
|
734d2b2414 | ||
|
|
0763a96f34 | ||
|
|
76640c40ae | ||
|
|
2ae4ba68e4 | ||
|
|
750adabba1 | ||
|
|
3404065bf0 | ||
|
|
ba6eec0fad | ||
|
|
ff81bee266 | ||
|
|
6926ae1be1 | ||
|
|
5ce290e792 | ||
|
|
5a7391ff69 | ||
|
|
a914a69051 | ||
|
|
beacc319b9 | ||
|
|
c48b7b980b | ||
|
|
c60a3939a4 | ||
|
|
d553483dcb | ||
|
|
0cd33621b2 | ||
|
|
765421fc5f | ||
|
|
c9f1a61bf5 | ||
|
|
84d58bf2d9 | ||
|
|
4b6cef26bd | ||
|
|
ccbae294f4 | ||
|
|
82f1ce8931 | ||
|
|
474491ebff | ||
|
|
60b36a03d4 | ||
|
|
25bb99b68d | ||
|
|
c0c49cc951 | ||
|
|
fe08a94540 | ||
|
|
c644f610da | ||
|
|
88c38f59b0 | ||
|
|
36f9062f45 | ||
|
|
26a49c8327 | ||
|
|
d8b66e01df | ||
|
|
af14c7d505 | ||
|
|
4148773881 | ||
|
|
6ffdd5c3c7 | ||
|
|
7d253c505a | ||
|
|
827ea20bd7 | ||
|
|
63689e14a0 | ||
|
|
b82c40feb2 | ||
|
|
ed85324b3a | ||
|
|
0ab9b19c4b | ||
|
|
50a33598e8 | ||
|
|
ef81050be9 | ||
|
|
cb95aa2466 | ||
|
|
a4fb1e1e6e | ||
|
|
1c4b146500 | ||
|
|
6fbe1774f8 | ||
|
|
85960ff726 | ||
|
|
df35528a53 | ||
|
|
405f6e91de | ||
|
|
254b4bee80 | ||
|
|
489357ee91 | ||
|
|
600669e1c5 | ||
|
|
d3ff4984fe | ||
|
|
f61a30ab26 | ||
|
|
aa77473288 | ||
|
|
2f837b34fc | ||
|
|
d7ca55597e | ||
|
|
331278d1b3 | ||
|
|
ac072e5a88 | ||
|
|
669a119bf5 | ||
|
|
ca0b098866 | ||
|
|
3fd13dd47c | ||
|
|
3813cdec4b | ||
|
|
f6380a72e3 | ||
|
|
6fe48faff8 | ||
|
|
68b9f09697 | ||
|
|
2080f2f109 | ||
|
|
38bc7e1bde | ||
|
|
6497d770dd | ||
|
|
933ba72d04 | ||
|
|
7f19026c71 | ||
|
|
64e5e9aeb0 | ||
|
|
f6635b5575 | ||
|
|
77fa5f5787 | ||
|
|
12ad46935c | ||
|
|
c3b54fc55b | ||
|
|
46101206f7 | ||
|
|
81150c5ef6 | ||
|
|
10e8d702c2 | ||
|
|
f5ba14ae65 | ||
|
|
2410fa6578 | ||
|
|
32e1623998 | ||
|
|
5ef6c587a8 | ||
|
|
2ba484024c | ||
|
|
687a4aa935 | ||
|
|
5cc297c4af | ||
|
|
31799ad144 | ||
|
|
b60f7ba22e | ||
|
|
ccd4a5237d | ||
|
|
6ad02118a9 | ||
|
|
89bb983925 | ||
|
|
de2dc38778 | ||
|
|
fbcaa7353f | ||
|
|
abf4f97f00 | ||
|
|
a0736e550d | ||
|
|
ea46a2973f | ||
|
|
26a9d8d07f | ||
|
|
71bba4296b | ||
|
|
eb26ffa7ca | ||
|
|
0038f7428b | ||
|
|
1fd1cf32a2 | ||
|
|
57a7dccd37 | ||
|
|
5fa56177fc | ||
|
|
d68d630175 | ||
|
|
662ae77944 | ||
|
|
b219999945 | ||
|
|
467ae236b5 | ||
|
|
4d2c298c00 | ||
|
|
469fb8dd52 | ||
|
|
371f2ac08a | ||
|
|
3d20d7635b | ||
|
|
f67f8007fb | ||
|
|
a1516ecf10 | ||
|
|
6c2ae912d1 | ||
|
|
9a03c17a0c | ||
|
|
1bc2295b70 | ||
|
|
37cd4ff11b | ||
|
|
5f9108400b | ||
|
|
78711ea675 | ||
|
|
0867de8257 | ||
|
|
62720b8d15 | ||
|
|
c80ef7a8c0 | ||
|
|
7bdc302583 | ||
|
|
8de2a12323 | ||
|
|
00f7a859f4 | ||
|
|
280d144dcf | ||
|
|
f2daba8ae8 | ||
|
|
6004c153d3 | ||
|
|
8076287376 | ||
|
|
d54c4ced74 | ||
|
|
4aeedb1751 | ||
|
|
ac96ad3720 | ||
|
|
a06793616d | ||
|
|
97f545bd4e | ||
|
|
a267b63df2 | ||
|
|
ea9d961fd8 | ||
|
|
51396f94b1 | ||
|
|
412dc73d9d | ||
|
|
c605e2d030 | ||
|
|
d5c93b60a9 | ||
|
|
54c591b51f | ||
|
|
620ef585ce | ||
|
|
9601cf49ce | ||
|
|
56088e3a40 | ||
|
|
5b8149ce82 | ||
|
|
7d8c6aef8e | ||
|
|
3c593ea3ed | ||
|
|
2f5b2bc2df | ||
|
|
19a3244102 | ||
|
|
5a7732588d | ||
|
|
25488ae972 | ||
|
|
4bf9733fe6 | ||
|
|
0672aebd61 | ||
|
|
5db7d6380f | ||
|
|
7f90a6ffec | ||
|
|
d45f0e382b | ||
|
|
49987de803 | ||
|
|
fab6d6e82d | ||
|
|
332981a198 | ||
|
|
5c026d7494 | ||
|
|
bb7342cd2d | ||
|
|
90d1797cb4 | ||
|
|
a79c61c5a4 | ||
|
|
3dfe05dccd | ||
|
|
5dab0f060e | ||
|
|
03b17b050a | ||
|
|
2cc44d32fb | ||
|
|
e485484051 | ||
|
|
865ddcd59b | ||
|
|
999070b270 | ||
|
|
00d1590790 | ||
|
|
4be66e4993 | ||
|
|
6cc17a08dc | ||
|
|
04cb83b13e | ||
|
|
d8a5ffa567 | ||
|
|
be2cc7e445 | ||
|
|
07cfd61ebe | ||
|
|
a7fe48ec20 | ||
|
|
1c1cb3e91f | ||
|
|
bfb14ff828 | ||
|
|
60911f3ec7 | ||
|
|
7f1a35fffe | ||
|
|
10f5fd673e | ||
|
|
36fcb12add | ||
|
|
c7ff0c7e39 | ||
|
|
4a1bbd1e6a | ||
|
|
a859ea205b | ||
|
|
6b41168626 | ||
|
|
cb4479a7a1 | ||
|
|
765921d219 | ||
|
|
3f4d2c7f8c | ||
|
|
aa31776bf3 | ||
|
|
2422e60aa1 | ||
|
|
6dbe92e093 | ||
|
|
f75c0aeab4 | ||
|
|
e9265eb0a6 | ||
|
|
07ad7db139 | ||
|
|
952ad6e0d2 | ||
|
|
159ecf5ffa | ||
|
|
12be2c7b7b | ||
|
|
95590a2673 | ||
|
|
0f0e6b0142 | ||
|
|
869f6b1120 | ||
|
|
2a41f431bb | ||
|
|
2cdfac02e6 | ||
|
|
a9127c7021 | ||
|
|
3023de995a | ||
|
|
59c3df6a47 | ||
|
|
63a779cb1e | ||
|
|
7391e3bc69 | ||
|
|
4ab72a6334 | ||
|
|
af357aca51 | ||
|
|
c7d060bb8d | ||
|
|
c3db5c0525 | ||
|
|
04328d2b8a | ||
|
|
27bcdadac6 | ||
|
|
18e1caff39 | ||
|
|
d9af350ab6 | ||
|
|
ca6461499f | ||
|
|
71bee3edd2 | ||
|
|
2c50d5f523 | ||
|
|
721823117a | ||
|
|
e87d6eabab | ||
|
|
fb03f426c6 | ||
|
|
00ed7bb0e8 | ||
|
|
38d81ced56 | ||
|
|
95ecf75a3a | ||
|
|
0afde170f4 | ||
|
|
5a312ee6c6 | ||
|
|
6533da0ed6 | ||
|
|
339ad676ca | ||
|
|
0edc762ff8 | ||
|
|
320a3a11b8 | ||
|
|
f4d177ce8c | ||
|
|
f3598e915e | ||
|
|
3314075f6e | ||
|
|
141296a2d5 | ||
|
|
48147f460b | ||
|
|
2d72fbb82a | ||
|
|
98b72f07b6 | ||
|
|
465fb2bef4 | ||
|
|
d1f96af65f | ||
|
|
990dad0c51 | ||
|
|
2387639cea | ||
|
|
83fdcceaa7 | ||
|
|
8db77bcaea | ||
|
|
6f9b80c3b0 | ||
|
|
67a8230b91 | ||
|
|
0d66e7bc1b | ||
|
|
56f0e0a1e2 | ||
|
|
1e5c48129c | ||
|
|
aed830b1ea | ||
|
|
c30596c89b | ||
|
|
85f4345f5c | ||
|
|
851e0e56dd | ||
|
|
0e92743da5 | ||
|
|
71d0e56c20 | ||
|
|
5b78ba6329 | ||
|
|
1dbe2cc993 | ||
|
|
0245d82250 | ||
|
|
1c942ce83c | ||
|
|
2d3ff73530 | ||
|
|
4d5bc93702 | ||
|
|
b4dc4f4a05 | ||
|
|
cdf41a5b13 | ||
|
|
9651025bef | ||
|
|
54a9412a5c | ||
|
|
4bfeda2031 | ||
|
|
ed136ecabb | ||
|
|
2f0eb7c246 | ||
|
|
ea0c16bf01 | ||
|
|
18d6917e9f | ||
|
|
039c5993f5 | ||
|
|
8394d9f0f0 | ||
|
|
1b791abbe0 | ||
|
|
ed07a915dc | ||
|
|
513221a7dd | ||
|
|
cd5556f2e3 | ||
|
|
db99c7f4b0 | ||
|
|
9dc3b910f4 | ||
|
|
581c9b5844 | ||
|
|
6403ea5a18 | ||
|
|
36772de3e0 | ||
|
|
3ccdb48939 | ||
|
|
058ac88f19 | ||
|
|
089d75cf57 | ||
|
|
9ef45d6324 | ||
|
|
881a957f59 | ||
|
|
23a9399284 | ||
|
|
f67c35541d | ||
|
|
0e0562c1a3 | ||
|
|
40cc7d30b2 | ||
|
|
c2b1d336db | ||
|
|
eca69b4d96 | ||
|
|
c607198de9 | ||
|
|
3ce9bd05a8 | ||
|
|
d209918dde | ||
|
|
c5de65044d | ||
|
|
96fbe3a685 | ||
|
|
d33defea6a | ||
|
|
d16d3eac34 | ||
|
|
99b175f72a | ||
|
|
ae4d16bfcb | ||
|
|
ff039c0d24 | ||
|
|
f4ef41c130 | ||
|
|
e572d22819 | ||
|
|
9c448eca97 | ||
|
|
742caa227d | ||
|
|
b095e87ec9 | ||
|
|
b2c66efa83 | ||
|
|
7274713e50 | ||
|
|
094f943ab5 | ||
|
|
f55198249f | ||
|
|
2fddfe12e6 | ||
|
|
88619f0512 | ||
|
|
695368932d | ||
|
|
71224066a8 | ||
|
|
84926f12eb | ||
|
|
9048c00021 | ||
|
|
ed5cc49b6d | ||
|
|
f348b4e8de | ||
|
|
6acd8167fb | ||
|
|
b131c2fe1f | ||
|
|
d848a2e78c | ||
|
|
2447f61f8c | ||
|
|
950c5b2c82 | ||
|
|
107252b1dd | ||
|
|
9839e48dee | ||
|
|
95f4f96cda | ||
|
|
9ce697bf00 | ||
|
|
72da390ad4 | ||
|
|
5424513e7e | ||
|
|
603336f740 | ||
|
|
83ab81fd37 | ||
|
|
a0ef28effd | ||
|
|
ea20dc7c60 | ||
|
|
4de268fcd8 | ||
|
|
86c415cc55 | ||
|
|
e08066a26c | ||
|
|
eea985d56d | ||
|
|
da473c9951 | ||
|
|
ae33cf7b5c | ||
|
|
d2626b9a0e | ||
|
|
d2f6987ce5 | ||
|
|
af142abd90 | ||
|
|
c072b6525c | ||
|
|
73777a3873 | ||
|
|
ae2ed8e1e6 | ||
|
|
7718bac2e5 | ||
|
|
1dc6f06b94 | ||
|
|
8bb16b8d00 | ||
|
|
8f8fa7efb7 | ||
|
|
6d58b69be6 | ||
|
|
99e501ae3c | ||
|
|
000d210b33 | ||
|
|
124d68a8fe | ||
|
|
0c019b1c71 | ||
|
|
ea41803ccb | ||
|
|
fd5468ff6e | ||
|
|
e1c29b7423 | ||
|
|
a1df69c67a | ||
|
|
2b91acd6ad | ||
|
|
96a6f2adeb | ||
|
|
509e473e4f | ||
|
|
ae825f5e29 | ||
|
|
1d2c1413da | ||
|
|
005945447b | ||
|
|
36de85ccb0 | ||
|
|
b47892892d | ||
|
|
d69ddef3e3 | ||
|
|
9bde52c73e | ||
|
|
469a350497 | ||
|
|
5abc147442 | ||
|
|
390d3b5518 | ||
|
|
ead25288a0 | ||
|
|
030ba82109 | ||
|
|
396aaecdb6 | ||
|
|
b7e752da64 | ||
|
|
c014362025 | ||
|
|
1f86abd8db | ||
|
|
b9cf702042 | ||
|
|
b07b20ef3c | ||
|
|
24692f57f6 | ||
|
|
8e08782cd1 | ||
|
|
dc4ad24004 | ||
|
|
22171add23 | ||
|
|
073901ae7a | ||
|
|
5c092661de | ||
|
|
4eb130e9fd | ||
|
|
33fb5a3ab9 | ||
|
|
7bbbddc580 | ||
|
|
60fb7231c7 | ||
|
|
4ac7060e4d | ||
|
|
5d84ee5ac6 | ||
|
|
048dcf785d | ||
|
|
a244c56c4c | ||
|
|
5f793be70d | ||
|
|
a5e46e900f | ||
|
|
bb9f4b6a9a | ||
|
|
03f6b79f0b | ||
|
|
642fa11cb2 | ||
|
|
22ce696423 | ||
|
|
4bd30be29f | ||
|
|
0b52918d8d | ||
|
|
9b73565e28 | ||
|
|
a1e04e8df2 | ||
|
|
51a542b6a9 | ||
|
|
e88cbc1618 | ||
|
|
2f7084ae15 | ||
|
|
f0e8d80da4 | ||
|
|
a392a087dc | ||
|
|
0081e60cd5 | ||
|
|
3d94cf2c11 | ||
|
|
50588cf372 | ||
|
|
dd8e4ee0a3 | ||
|
|
594d188de7 | ||
|
|
dd8ff8ef36 | ||
|
|
7cf46baa98 | ||
|
|
6c5efcd69b | ||
|
|
9d109a9584 | ||
|
|
fdef9d9837 | ||
|
|
d9cc185052 | ||
|
|
1fdf2b53ff | ||
|
|
5c60f2634d | ||
|
|
b082c3e04d | ||
|
|
424b4dd401 | ||
|
|
1437dbebcf | ||
|
|
cfb49e7f6c | ||
|
|
107baf4d9a | ||
|
|
e739be029a | ||
|
|
bfca02c78f | ||
|
|
007bc4b212 | ||
|
|
bfe1d8bb75 | ||
|
|
d6fc53d42c | ||
|
|
787ce28318 | ||
|
|
b5c10ea372 | ||
|
|
7bc0547c66 | ||
|
|
9c0babf267 | ||
|
|
0b1915946a | ||
|
|
fc78d64f62 | ||
|
|
2140384e9f | ||
|
|
3785313dd2 | ||
|
|
f091c08dd3 | ||
|
|
6e5438040e | ||
|
|
c35213cb3b | ||
|
|
7b2e287b89 | ||
|
|
5b1f32cc57 | ||
|
|
faa8f5aae6 | ||
|
|
7c3ddf6d03 | ||
|
|
80a6a10293 | ||
|
|
65ac3319f3 | ||
|
|
045b9fbc9a | ||
|
|
b97f447169 | ||
|
|
21e505e7ad | ||
|
|
6f30fc3ee3 | ||
|
|
c52822ef3d | ||
|
|
5c349f54d5 | ||
|
|
64b869f365 | ||
|
|
532bf008d3 | ||
|
|
701c727475 | ||
|
|
3df605c50f | ||
|
|
ad97188902 | ||
|
|
237edcc2fa | ||
|
|
51ab2c4fd8 | ||
|
|
c0a482a92a | ||
|
|
829a063fe7 | ||
|
|
f3f2fa11f7 | ||
|
|
298ba53ec2 | ||
|
|
28401e3c95 | ||
|
|
3a0ed1a244 | ||
|
|
b27895a3c2 | ||
|
|
e8647313b7 | ||
|
|
7fdff93a25 | ||
|
|
06335ca854 | ||
|
|
7c5e9c43f2 | ||
|
|
b10c09b740 | ||
|
|
113e423af1 | ||
|
|
f9cdd9d002 | ||
|
|
d2284a8b3b | ||
|
|
ba22800783 | ||
|
|
832f260472 | ||
|
|
671c96856f | ||
|
|
ec625ebc60 | ||
|
|
ece0347973 | ||
|
|
df594f18d4 | ||
|
|
5663d50a1c | ||
|
|
373be37287 | ||
|
|
4cc78ba4c6 | ||
|
|
7071d74196 | ||
|
|
f5f3ad0d58 | ||
|
|
7e1b9b65f1 | ||
|
|
57839da643 | ||
|
|
4a4dd66a65 | ||
|
|
9b29c800b2 | ||
|
|
2aa85c4254 | ||
|
|
d576022219 | ||
|
|
749c12f1ae | ||
|
|
1e4258811c | ||
|
|
7cc5bd6dc8 | ||
|
|
ac8ffc2ca1 | ||
|
|
2df57c3166 | ||
|
|
cfcf97bc88 | ||
|
|
1adf625044 | ||
|
|
a136ca106b | ||
|
|
cbe1a79c2a | ||
|
|
093f953c7f | ||
|
|
dfd4fd252f | ||
|
|
36f70fffb2 | ||
|
|
7170537dcf | ||
|
|
49c578d999 | ||
|
|
e22befbc33 | ||
|
|
ce94877c8b | ||
|
|
baa81cef03 | ||
|
|
7bbb0eac56 | ||
|
|
c0f998eb82 | ||
|
|
69a3ad59cd | ||
|
|
ebe9c7243d | ||
|
|
c42facec8a | ||
|
|
3e28bac830 | ||
|
|
df320ab978 | ||
|
|
1d145f78eb | ||
|
|
e8b23fd0be | ||
|
|
a9e261da03 | ||
|
|
348dd14fc5 | ||
|
|
426962aa6b | ||
|
|
40f377f78e | ||
|
|
39dcae9cb1 | ||
|
|
fd8bdf51f2 | ||
|
|
5eba2230ea | ||
|
|
080a7f76bc | ||
|
|
9a2cfe040c | ||
|
|
47194659fa | ||
|
|
1cdc5aa3c7 | ||
|
|
413dafd681 | ||
|
|
1759249a89 | ||
|
|
6e83f9f7be | ||
|
|
50ac79281a | ||
|
|
4b9071d183 | ||
|
|
76a04a0df9 | ||
|
|
e2506f95a6 | ||
|
|
f3ad759c25 | ||
|
|
0785ce1c71 | ||
|
|
805fe12600 | ||
|
|
26182bdf10 | ||
|
|
14d71200ec | ||
|
|
150e6685ef | ||
|
|
4faf75a763 | ||
|
|
ada2cb77c3 | ||
|
|
50acc65b64 | ||
|
|
59efce5e55 | ||
|
|
0ec23d65b3 | ||
|
|
849ab32c5d | ||
|
|
7d2663b082 | ||
|
|
43c6751039 | ||
|
|
f0fc94d25a | ||
|
|
f710c5ceb5 | ||
|
|
fe81edca50 | ||
|
|
650303de58 | ||
|
|
c76c577b91 | ||
|
|
eb95595af0 | ||
|
|
137d082e1a | ||
|
|
ceb9fd0cf6 | ||
|
|
fce087979a | ||
|
|
939ce328b9 | ||
|
|
d86366a04a | ||
|
|
7234dc0788 | ||
|
|
10ba9c5f87 | ||
|
|
dcca1ec71f | ||
|
|
7847227a57 | ||
|
|
3f1660295e | ||
|
|
9a4ed01c7a | ||
|
|
87f1063d6f | ||
|
|
0951a7d73e | ||
|
|
256fcf3a8b | ||
|
|
7e082f27e0 | ||
|
|
e81b8ca4f2 | ||
|
|
351910a3ef | ||
|
|
e700dcb142 | ||
|
|
2527b0e5d1 | ||
|
|
0fe36a98d7 | ||
|
|
c9ef897a2e | ||
|
|
2cc46406de | ||
|
|
1ef39bf1a3 | ||
|
|
e0bc16a232 | ||
|
|
f46109e080 | ||
|
|
21983061a6 | ||
|
|
87543095f1 | ||
|
|
688b0836a5 | ||
|
|
42d2a5ce89 | ||
|
|
307f5e2c8d | ||
|
|
b1a6b43414 | ||
|
|
8d90e2d190 | ||
|
|
767446c804 | ||
|
|
b6d5762ddd | ||
|
|
dc0ab2e810 | ||
|
|
f50ec2ae5a | ||
|
|
a4d0ddf229 | ||
|
|
b1d84fef55 | ||
|
|
e26f4c33ba | ||
|
|
7b023ab34f | ||
|
|
ded186890d | ||
|
|
4c5b16e502 | ||
|
|
6b95f8b7bf | ||
|
|
4a50293e04 | ||
|
|
9fa829b30a | ||
|
|
0dc6b8321e | ||
|
|
4616e61825 | ||
|
|
63c0b7da37 | ||
|
|
aad041998c | ||
|
|
b0e58975f2 | ||
|
|
cf41dd6fb4 | ||
|
|
a66eb04097 | ||
|
|
960d20599e | ||
|
|
8ea6f13d34 | ||
|
|
34d28c798d | ||
|
|
cb0046f4cc | ||
|
|
b475ead059 | ||
|
|
9557c48cab | ||
|
|
1062507ffb | ||
|
|
b5aef1cccc | ||
|
|
658e6a9da5 | ||
|
|
ff6f18d575 | ||
|
|
f9df1085ec | ||
|
|
997bacefe2 | ||
|
|
5f94707a9e |
+27
-6
@@ -7,12 +7,14 @@ stages:
|
||||
|
||||
#TODO add client reference test process, search for import com.cobblemon.mod.common.client
|
||||
|
||||
build-job:
|
||||
build:
|
||||
stage: build
|
||||
only:
|
||||
- branches@cable-mc/cobblemon
|
||||
script:
|
||||
- export GRADLE_OPTS="-Xmx4G -Xms4G"
|
||||
- chmod +x ./gradlew
|
||||
- ./gradlew build
|
||||
- export GRADLE_OPTS="-Xmx4G -Xms4G"
|
||||
- chmod +x ./gradlew
|
||||
- ./gradlew build
|
||||
cache:
|
||||
key: "$CI_COMMIT_REF_NAME"
|
||||
policy: push
|
||||
@@ -20,9 +22,28 @@ build-job:
|
||||
- forge/build/libs
|
||||
- fabric/build/libs
|
||||
|
||||
# Separate step to deploy the artifacts, save Norry the headache of keeping even more shit around
|
||||
deploy-job:
|
||||
publish:
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- build
|
||||
cache:
|
||||
key: "CI_COMMIT_REF_NAME"
|
||||
policy: pull
|
||||
paths:
|
||||
- forge/build/libs/*.jar
|
||||
- fabric/build/libs/*.jar
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "main"'
|
||||
script:
|
||||
- export GRADLE_OPTS="-Xmx4G -Xms4G"
|
||||
- chmod +x ./gradlew
|
||||
- ./gradlew publish
|
||||
|
||||
# Separate step to deploy the artifacts, save Norry the headache of keeping even more shit around
|
||||
deploy:
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- build
|
||||
when: manual
|
||||
cache:
|
||||
key: "$CI_COMMIT_REF_NAME"
|
||||
|
||||
+487
-6
@@ -1,4 +1,482 @@
|
||||
# Changelog
|
||||
## [1.4.1](#1-4-1)
|
||||
|
||||
### Changes
|
||||
- Slightly lowered the volume of all cries
|
||||
- Pasture blocks will now also connect their bottom left and right sides to walls, iron bars, glass panes and any other modded block that follows the same connection rules.
|
||||
|
||||
### Additions
|
||||
- Cobblemon now has compatibility with [Adorn](https://modrinth.com/mod/adorn) allowing you to craft Apricorn wood furniture.
|
||||
- Berries can now be used in recipes from [Farmer's Delight](https://modrinth.com/mod/farmers-delight) and [Farmer's Delight (Fabric)](https://modrinth.com/mod/farmers-delight-fabric), as well as any other mods using the same berry tags.
|
||||
- The nature of cobblemon will now be displayed italicized when a mint has been applied. Hovering over the nature will display the mint that was applied. This is the intended behaviour, because the original nature and taste of the Cobblemon does not change when a mint is applied.
|
||||
- Giving Pokémon items now plays a sound
|
||||
|
||||
### Fixes
|
||||
- Fixed various stone related blocks not being valid for Big Roots to spread on the Fabric version.
|
||||
- Updated the registration of compostable items to improve compatibility with Fabric forks such as Quilt. Please note this does not mean we officially support Quilt, this change was only done since it was possible by correcting the registration to use the new intended way in the Fabric API.
|
||||
- Fixed Dispensers being unable to shear grown Apricorns.
|
||||
- Fixed Bowl not being given back to player after using Berry Juice
|
||||
- Fixed Moonphases for Clefairy line
|
||||
- Fixed issue where Potions, Super Potions, and Hyper Potions did not work during battle
|
||||
- Fixed the compatibility patch with the Forge version of [Carry On](https://modrinth.com/mod/carry-on) due to a bug on the mod, the Fabric version was unchanged and is still compatible.
|
||||
- Added the ability to place Berries on modded Farmland blocks.
|
||||
- Shouldered Pokémon now hop off when selected in team and r is pressed. This also is in effect in battles leading to shouldered Pokémon jumping of the shoulder of the trainer when it is their turn.
|
||||
- Made more items compostable and changed the process for making items compostable.
|
||||
- Added the ability for Hoppers to fill Brewing Stands with Medicinal Brews and Potions.
|
||||
- Apricorn blocks are now flammable.
|
||||
- The default pose for Pokémon being passengers is now "standing".
|
||||
- Fixed issue where some IVs were changing every player relog.
|
||||
- Fixed cursed battle message
|
||||
- Fixed mistakes in pokemon spawning JSONs
|
||||
- Fixed advancement crash from bad datapack evolution data.
|
||||
|
||||
### Developer
|
||||
- Fixed the `SpawnEvent` not respecting usage of `Cancelable#cancel`.
|
||||
- Added the `EvolutionTestedEvent`, this allows listening and overriding the final result of evolution requirement tests.
|
||||
|
||||
## [1.4.0 - The Friends and Farms Update (October 13th, 2023)](#1-4-0)
|
||||
### Additions
|
||||
- Added pasture blocks, used to let your PC Pokémon roam around an area.
|
||||
- Added nicknaming from the summary menu of a Pokémon (click their name).
|
||||
- Added trading between players. Press R while looking at another player and you'll figure the rest out.
|
||||
- Added mints for changing Pokémon stats. These are most commonly found at high altitudes.
|
||||
- Added [Revival Herbs](https://wiki.cobblemon.com/index.php/Revival_Herb), with pep-up flowers when fully grown, growing in lush caves.
|
||||
- Added [Medicinal Leeks](https://wiki.cobblemon.com/index.php/Medicinal_Leek), growing on the surface of rivers and ponds. It is a potion ingredient and can be cooked as food!.
|
||||
- Added [Big Roots](https://wiki.cobblemon.com/index.php/Big_Root), generating from cave ceiling dirt which sometimes spread as energy roots.
|
||||
- Added [69 Berry Trees](https://wiki.cobblemon.com/index.php/Berry_Tree) and [Berries](https://wiki.cobblemon.com/index.php/Berry). Some are found in village farms, some from planting different berries close to each other.
|
||||
- Added mulches: Mulch Base, Growth Mulch, Surprise Mulch, Coarse Mulch, Humid Mulch, Rich Mulch, Loamy Mulch, Peat Mulch, and Sandy Mulch
|
||||
- Added [Vivichokes](https://wiki.cobblemon.com/index.php/Vivichoke), obtainable from wandering villager trades and some loot chests.
|
||||
- Added medicine brewing using medicinal leeks and berries in brewing stands.
|
||||
- Added Pokémon cries when in battles and being sent out.
|
||||
- Added medicinal items: Berry Juice, Heal Powder, Remedy, Fine Remedy, Superb Remedy, Revive, Max Revive, Potion, Super Potion, Hyper Potion, Max Potion, Full Restore, Full Heal, Antidote, Awakening, Burn Heal, Ice Heal, and Paralyze Heal.
|
||||
- Added battle items: X Attack, X Defence, X Sp.Atk, X Sp.Def, X Speed, Dire Hit, and Guard Spec.
|
||||
- Added EV items: Power Anklet, Power Band, Power Belt, Power Bracelet, Power Lens, Power Weight.
|
||||
- Added food items: Roasted Leek, Leek and Potato Stew, Braised Vivichoke, and Vivichoke Dip
|
||||
- Added evolution items: Auspicious Armor and Malicious Armor, which can be used to evolve Charcadet into Armarouge or Ceruledge respectively.
|
||||
- Added (mostly brewing) recipes for HP Up, Protein, Iron, Calcium, Zinc, Carbos, PP Up, PP Max, and Medicinal Leek to Magenta Dye.
|
||||
- Added held items: Bright Powder, Destiny Knot
|
||||
- Added AI for Nosepass to point towards world spawn when idle. We just think it's neat.
|
||||
- Added shoulder mounting for Mimikyu.
|
||||
- Added flying placeholder animations to Pidgey, Pidgeotto, Pidgeot, Golbat, Crobat, Scyther, Scizor, Zapdos, Moltres, Articuno, Dragonite, Rowlet, Dartrix, and Decidueye.
|
||||
- Added loot to various vanilla chest loot tables (Link Cable in Ancient Cities, Woodland Mansions, End Cities, and Igloos, Vivichoke Seeds in Jungle Temples, Dungeons, and Plains, Savanna, Snowy, and Taiga Villages, and all 7 Apricorn Sprouts in Desert, Plains, Savanna, Snowy, and Taiga Villages, as well as the Bonus Chest, which can also have 5 of the basic Poké Ball types)
|
||||
- Added a `doShinyStarters` gamerule to make it quick and easy to be offered shiny starters.
|
||||
- Added a `doPokemonLoot` gamerule to toggle Pokémon dropping items/exp on death.
|
||||
- Added ability activation announcement when in battle.
|
||||
- Added animations for Wailord and made it BIGGER.
|
||||
- Added Cherry Torterra variant.
|
||||
- Added 2 new face spots for Spinda. The number of unique Spindas increases...
|
||||
- Added Forretress Shulker variant.
|
||||
- Added the `/teststore <player> <store> <properties>` command allowing command block/mcfunction users to query a party, PC or both for Pokémon matching specific properties and returning the match count, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.teststore` if a permission mod is present.
|
||||
- Added the `/querylearnset <player> <slot> <move>` command allowing command block/mcfunction users to query a party slot and check if the Pokémon can learn a specific move returning a 1 if yes otherwise 0, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.querylearnset` if a permission mod is present.
|
||||
- Added the `/testpcslot <player> <slot> <properties>` command allowing command block/mcfunction users to query a pc slot and check if the Pokémon matches specific properties returning a 1 if yes otherwise 0, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.testpcslot` if a permission mod is present.
|
||||
- Added the `/testpartyslot <player> <slot> <properties>` command allowing command block/mcfunction users to query a party slot and check if the Pokémon matches a specific properties returning a 1 if yes otherwise 0, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.testpartyslot` if a permission mod is present.
|
||||
- Added the `/clearparty <player>` command for emptying a player's party.
|
||||
- Added the `/clearpc <player>` command for emptying a player's PC.
|
||||
- Added the `/pokemonrestart <reset_starters>` and the `/pokemonrestartother <player> <reset_starters>` command allowing command block/mcfunction users to reset a players Pokémon data.
|
||||
|
||||
### Pokémon Added
|
||||
#### Gen 2
|
||||
|
||||
- Chikorita
|
||||
- Bayleef
|
||||
- Meganium
|
||||
- Totodile
|
||||
- Croconaw
|
||||
- Feraligatr
|
||||
- Cyndaquil
|
||||
- Quilava
|
||||
- Typhlosion
|
||||
- Spinarak
|
||||
- Ariados
|
||||
- Shuckle
|
||||
- Chinchou
|
||||
- Lanturn
|
||||
- Aipom
|
||||
- Gligar
|
||||
- Hoothoot
|
||||
- Noctowl
|
||||
- Mareep
|
||||
- Flaaffy
|
||||
- Ampharos
|
||||
- Sudowoodo
|
||||
- Snubbull
|
||||
- Granbull
|
||||
- Phanpy
|
||||
- Donphan
|
||||
- Teddiursa
|
||||
- Ursaring
|
||||
|
||||
#### Gen 3
|
||||
|
||||
- Taillow
|
||||
- Swellow
|
||||
- Relicanth
|
||||
- Duskull
|
||||
- Dusclops
|
||||
- Shroomish
|
||||
- Breloom
|
||||
- Cacnea
|
||||
- Cacturne
|
||||
- Poochyena
|
||||
- Mightyena
|
||||
- Wingull
|
||||
- Pelipper
|
||||
- Numel
|
||||
- Camerupt
|
||||
- Clamperl
|
||||
- Huntail
|
||||
- Gorebyss
|
||||
- Surskit
|
||||
- Masquerain
|
||||
- Chimecho
|
||||
- Barboach
|
||||
- Whiscash
|
||||
- Volbeat
|
||||
- Illumise
|
||||
- Zigzagoon
|
||||
- Linoone
|
||||
- Ralts
|
||||
- Kirlia
|
||||
- Gardevoir
|
||||
- Nincada
|
||||
- Ninjask
|
||||
- Shedinja
|
||||
- Beldum
|
||||
- Metang
|
||||
- Metagross
|
||||
|
||||
#### Gen 4
|
||||
|
||||
- Carnivine
|
||||
- Shinx
|
||||
- Luxio
|
||||
- Luxray
|
||||
- Ambipom
|
||||
- Gliscor
|
||||
- Dusknoir
|
||||
- Chingling
|
||||
- Bonsly
|
||||
- Chatot
|
||||
- Combee
|
||||
- Vespiquen
|
||||
- Buizel
|
||||
- Floatzel
|
||||
- Starly
|
||||
- Staravia
|
||||
- Staraptor
|
||||
- Gallade
|
||||
|
||||
#### Gen 5
|
||||
|
||||
- Bouffalant
|
||||
- Roggenrola
|
||||
- Boldore
|
||||
- Gigalith
|
||||
- Venipede
|
||||
- Whirlipede
|
||||
- Scolipede
|
||||
- Yamask
|
||||
- Cofagrigus
|
||||
- Patrat
|
||||
- Watchog
|
||||
- Lillipup
|
||||
- Herdier
|
||||
- Stoutland
|
||||
- Cottonee
|
||||
- Whimsicott
|
||||
- Pidove
|
||||
- Tranquill
|
||||
- Unfezant
|
||||
- Timburr
|
||||
- Gurdurr
|
||||
- Conkeldurr
|
||||
|
||||
#### Gen 6
|
||||
|
||||
- Scatterbug
|
||||
- Spewpa
|
||||
- Vivillon
|
||||
- Skrelp
|
||||
- Dragalge
|
||||
- Bunnelby
|
||||
- Diggersby
|
||||
- Phantump
|
||||
- Trevenant
|
||||
- Fletchling
|
||||
- Fletchinder
|
||||
- Talonflame
|
||||
|
||||
#### Gen 7
|
||||
|
||||
- Wishiwashi
|
||||
- Cutiefly
|
||||
- Ribombee
|
||||
- Stufful
|
||||
- Bewear
|
||||
- Comfey
|
||||
- Alolan Exeggutor
|
||||
- Alolan Raichu
|
||||
- Alolan Meowth
|
||||
- Alolan Persian
|
||||
- Komala
|
||||
- Wimpod
|
||||
- Golisopod
|
||||
- Crabrawler
|
||||
- Crabominable
|
||||
- Mudbray
|
||||
- Mudsdale
|
||||
|
||||
#### Gen 8
|
||||
|
||||
- Arrokuda
|
||||
- Barraskewda
|
||||
- Nickit
|
||||
- Thievul
|
||||
- Falinks
|
||||
- Galarian Farfetch'd
|
||||
- Sirfetch'd
|
||||
- Rookidee
|
||||
- Corvisquire
|
||||
- Corviknight
|
||||
- Galarian Ponyta
|
||||
- Galarian Rapidash
|
||||
- Yamper
|
||||
- Boltund
|
||||
- Galarian Zigzagoon
|
||||
- Galarian Linoone
|
||||
- Obstagoon
|
||||
- Galarian Meowth
|
||||
- Perrserker
|
||||
- Ursaluna
|
||||
|
||||
#### Gen 9
|
||||
|
||||
- Sprigatito
|
||||
- Floragato
|
||||
- Meowscarada
|
||||
- Fuecoco
|
||||
- Crocalor
|
||||
- Skeledirge
|
||||
- Quaxly
|
||||
- Quaxwell
|
||||
- Quaquaval
|
||||
- Flittle
|
||||
- Espathra
|
||||
- Garganacl
|
||||
- Fidough
|
||||
- Dachsbun
|
||||
- Armarouge
|
||||
- Ceruledge
|
||||
- Cetoddle
|
||||
- Cetitan
|
||||
- Shroodle
|
||||
- Grafaiai
|
||||
- Tandemaus
|
||||
- Maushold
|
||||
- Varoom
|
||||
- Revavroom
|
||||
- Squawkabilly
|
||||
- Glimmet
|
||||
- Glimmora
|
||||
- Annihilape
|
||||
- Tinkatink
|
||||
- Tinkatuff
|
||||
- Tinkaton
|
||||
- Maschiff
|
||||
- Mabosstiff
|
||||
- Lechonk
|
||||
- Oinkologne
|
||||
- Paldean Wooper
|
||||
- Clodsire
|
||||
|
||||
### Changes
|
||||
- Removed the existing shoulder effects from Pokémon until we have more balanced versions of them (they're too powerful!)
|
||||
- Updated models and textures of Weedle, Dwebble and Crustle, Spiritomb, Koffing and Weezing, Kadabra and Alakazam, Emolga, Oshawott, Doduo and Dodrio, Dratini and Dragonair and Dragonite, Sneasel and Weavile, Gyarados, Hitmonlee and Hitmonchan, Chesnaught, Spinda, Mamoswine, Steelix, Misdreavus and Mismagius, Buneary and Lopunny, Golduck, Meowth and Persian, Fennekin and Braixen and Delphox, Snivy and Servine and Serperior, Ratatta and Raticate, Nidorina and Nidoqueen, Nidoran Male and Nidoking, Riolu and Lucario, Haunter and Gengar, Mankey and Primeape, Mew and Mewtwo, Arcanine, Magnemite and Magneton and Magnezone, Exeggcute and Exeggutor, Elekid and Electabuzz and Electivire, Pichu and Pikachu and Raichu, Wooper, Drowzee and Hypno, Aerodactyl, Spearow and Fearow, Lickitung and Lickilicky, Pidgey and Pidgeotto and Pidgeot, Scyther and Scizor and Kleavor, Popplio and Brionne and Primarina, Torchic and Combusken and Blaziken, Happiny and Chansey and Blissey.
|
||||
- Updated animations for Steelix, Turtwig and Grotle and Torterra, Ponyta and Rapidash, Piplup and Prinplup and Empoleon, Drowzee and Hypno, Farfetch'd, Exeggcute and Exeggutor, Bidoof, Chimecho, Lickitung and Lickilicky, Popplio and Brionne, Luvdisc, Chimchar and Monferno and Infernape, Sobble and Drizzile and Inteleon, Greninja, Heatmor, Aerodactyl, Ditto, Lotad and Lombre and Ludicolo, Pumpkaboo and Gourgeist.
|
||||
- Updated sprites for EV medicines, the rare candy, and the apricorn door item.
|
||||
- Updated textures for apricorn doors and all the evolution stone ores.
|
||||
- Ponyta and Rapidash now have animated textures; they look insane.
|
||||
- Updated Apricorn Leaves color.
|
||||
- Wild Pokémon now heal if you are defeated by them or flee from them.
|
||||
- Doubled the default time between ambient Pokémon cries (they have cries if you're using a resource pack to add them)
|
||||
- Moved spawn attempts per tick to a config option (ticksBetweenSpawnAttempts)
|
||||
- PCs can now be waterlogged
|
||||
- Starter selection prompt now appears as a tutorial-esque toast instead of plain text
|
||||
- Reorganised the advancements recipes folder
|
||||
- Pokéedit command now supports IVs and EVs.
|
||||
- Reorganised creative categories
|
||||
- Pokémon can now wander into non-solid blocks such as foliage
|
||||
- Thrown Poké Balls now despawn after 30 seconds so that they don't fly forever.
|
||||
- Dive Balls will now have the same motion speed underwater as if they were thrown in the air.
|
||||
- Hardcoded potion shoulder effects have been removed. You can now use any potion vanilla or otherwise with the parameters you'd like, for more information see the [Datapack & Resourcepack Creators](#datapack-&-resourcepack-creators) section.
|
||||
- Clicking categories of the Stat subsection or the party reorder button in the Summary screen will now produce a click sound.
|
||||
- Updated PC Recipe.
|
||||
- Improved Pokémon AI and movement.
|
||||
- Friendship will slowly increase when Pokémon are shoulder-mounted.
|
||||
- Master Balls are now unable to be burned when dropped into fire/lava. They're made from stronger stuff.
|
||||
- Pokémon will appear red when hurt, like regular entities, except when they're fainting.
|
||||
- Pokémon's air meter no longer depletes while battling underwater.
|
||||
- Sleeping partially restores PP of Pokémon
|
||||
- Shoulder mounts now match the shoulder position a bit more accurately when sneaking.
|
||||
- Poison Heal will now cause poisoned Pokémon to heal outside of battle.
|
||||
- Updated Poké Ball, PC, UI, evolution and Healing Machine sounds.
|
||||
|
||||
### Added cries to the following Pokémon:
|
||||
- All starters and their evolutions
|
||||
- Caterpie, Metapod, Butterfree
|
||||
- Weedle, Kakuna, Beedrill
|
||||
- Pidgey, Pidgeotto, Pidgeot
|
||||
- Rattata, Raticate
|
||||
- Spearow, Fearow
|
||||
- Ekans, Arbok
|
||||
- Pichu, Pikachu, Raichu, Alolan Raichu
|
||||
- Cleffa, Clefairy, Clefable
|
||||
- Mankey, Primeape, Annihilape
|
||||
- Ponyta, Rapidash, Galarian Ponyta, Galarian Rapidash
|
||||
- Farfetch'd, Galarian Farfetch'd, Sirfetch'd
|
||||
- Onix, Steelix
|
||||
- Tauros
|
||||
- Ditto
|
||||
- Eevee, Vaporeon, Jolteon, Flareon, Espeon, Umbreon, Leafeon, Glaceon, Sylveon
|
||||
- Hoothoot, Noctowl
|
||||
- Mareep, Flaaffy, Ampharos
|
||||
- Aipom, Ambipom
|
||||
- Wooper, Quagsire, Clodsire
|
||||
- Snubbull, Granbull
|
||||
- Miltank
|
||||
- Poochyena, Mightyena
|
||||
- Taillow, Swellow
|
||||
- Ralts, Kirlia, Gardevoir, Gallade
|
||||
- Shroomish, Breloom
|
||||
- Nincada, Ninjask, Shedinja
|
||||
- Buneary, Lopunny
|
||||
- Chingling
|
||||
- Chatot
|
||||
- Riolu, Lucario
|
||||
- Pidove, Tranquill, Unfezant
|
||||
- Roggenrola, Boldore, Gigalith
|
||||
- Venipede, Whirlipede, Scolipede
|
||||
- Maractus
|
||||
- Dwebble, Crustle
|
||||
- Yamask, Cofagrigus
|
||||
- Bunnelby, Diggersby
|
||||
- Fletchling, Fletchinder, Talonflame
|
||||
- Scatterbug, Spewpa, Vivillon
|
||||
- Honedge, Doublade, Aegislash
|
||||
- Skrelp, Dragalge
|
||||
- Phantump, Trevenant
|
||||
- Pumpkaboo, Gourgeist
|
||||
- Bergmite, Avalugg
|
||||
- Mudbray, Mudsdale
|
||||
- Stufful, Bewear
|
||||
- Mimikyu
|
||||
- Rookidee, Corvisquire, Corviknight
|
||||
- Nickit, Thievul
|
||||
- Wooloo, Dubwool
|
||||
- Yamper, Boltund
|
||||
- Tandemaus
|
||||
- Fidough, Dachsbun
|
||||
- Squawkabilly
|
||||
- Nacli, Naclstack, Garganacl
|
||||
- Charcadet, Armarouge, Ceruledge
|
||||
- Maschiff, Mabosstiff
|
||||
- Shroodle, Grafaiai
|
||||
- Flittle, Espathra
|
||||
- Tinkatink, Tinkatuff, Tinkaton
|
||||
- Varoom, Revavroom
|
||||
- Glimmet, Glimmora
|
||||
- Cetoddle, Cetitan
|
||||
- Tatsugiri
|
||||
|
||||
### Fixes
|
||||
- Fixed spawning moon phase dependent Pokémon only when the moon phase is wrong (that's a funny woopsy)
|
||||
- Fixed large Pokémon spawning partially inside walls where they suffocate.
|
||||
- Fixed custom Pokémon in your party or PC not being removed when the addon is removed, causing major issues.
|
||||
- Fixed messages for entry hazards, screens, weather, damage, healing, Tailwind, Perish Song, Destiny Bond, Shed Skin, Uproar, Forewarn, Disguise, Arena Trap, Yawn, Curse, Clamp, Whirlpool, Liquid Ooze, Miracle Eye, Safeguard, Magic Bounce, Lock On, Focus Energy, Confusion, and more.
|
||||
- Fixed Porygon not evolving with an Upgrade.
|
||||
- Fixed super sized Pumpkaboo not having any moves.
|
||||
- Fixed Infernape look animation.
|
||||
- Fixed Garchomp T-posing while swimming which was very funny.
|
||||
- Fixed a bug that caused sleeping Pokémon to stay asleep. Forever. The years passing them by as they dream of a world without hate...
|
||||
- Fixed a bug that would freeze a battle when a Pokémon gets trapped by an ability, making the trap abilities even scarier and trap-like than they were before.
|
||||
- Fixed the Poké Ball close animation canceling whenever colliding with a block.
|
||||
- Fixed lighting and Pokémon label issues when a Pokémon item frame is nearby.
|
||||
- Fixed Pokémon being able to spawn outside the world border as a tease.
|
||||
- Fixed deepslate water stone ore items looking like deepslate fire stone ores. Huh?
|
||||
- Fixed a bunch of client-side logging errors when Pokémon are shoulder mounted. You didn't notice? Good.
|
||||
- Fixed a crash when wild Pokémon have to struggle under specific circumstances.
|
||||
- Fixed uncolored pixels on Yanma's shiny texture.
|
||||
- Fixed apricorn tree leaves looking gross on the Fast graphics mode.
|
||||
- Fixed hoes not breaking apricorn tree leaves any faster.
|
||||
- Fixed Shiftry's PC model position.
|
||||
- Fixed the /pc command not playing the opening sound.
|
||||
- Fixed different forms of Pokémon not being able to appear as different sizes.
|
||||
- Fixed the Healing Machine soft locking you from using others when removed by non-players.
|
||||
- Fixed animations being sped up when using the Replay Mod.
|
||||
- Fixed particle animations not running when a Pokémon is off-screen.
|
||||
- Fixed Pokémon variants and layers not rendering correctly when shouldered and playing on a dedicated server, existing shoulders affected will need to be retrieved and shouldered again.
|
||||
- Fixed shoulder effects not staying applied through situations that remove potion effects such as drinking milk.
|
||||
- Fixed Shedinja not being able to recover naturally.
|
||||
- Fixed Shedinja evolving to use the consumed Poké Ball and removed the held item to prevent dupes.
|
||||
- Fixed Shedinja healing above 1 HP.
|
||||
- Fixed Shedinja, basically.
|
||||
- Fixed shearing Pokémon dropping 0-2 wool instead of 1-3.
|
||||
- Fixed some alignment issues in the stat hexagon of the summary menu. OCD people rejoice.
|
||||
- Fixed capture calculations not applying ball bonuses entirely correctly.
|
||||
- Fixed battles soft-locking when consecutive Pokémon faint on switch-in.
|
||||
- Fixed timing and color of battle window messages.
|
||||
- Fixed players being able to trade, battle and let out their Pokémon while in spectator mode.
|
||||
- Fixed Galarian Yamask not being able to evolve and by proxy the ``damage_taken`` evolution requirement.
|
||||
- Fixed Bisharp not being able to evolve and by proxy the ``defeat`` evolution requirement.
|
||||
- Fixed White-Striped Basculin not being able to evolve because of a broken ``recoil`` evolution requirement.
|
||||
- Fixed Primeape, Qwilfish and Stantler not being able to evolve because of a broken ``use_move`` evolution requirement.
|
||||
- Fixed Bramblin, Pawmo, and Rellor not being able to evolve because of a broken ``blocks_traveled`` evolution requirement.
|
||||
- Fixed displayName property in spawn files not doing what it's meant to do.
|
||||
- Fixed Pokémon not sleeping in the wild like we wanted them to.
|
||||
|
||||
### Developer
|
||||
- Added SpawnEvent, ThrownPokeballHitEvent, PokemonSentEvent, PokemonRecalledEvent.
|
||||
- Added BattleFledEvent, BattleStartedEvent, BattleFaintedEvent.
|
||||
- Added persistent NBT property inside Pokémon to store quick and simple data.
|
||||
- Species and FormData have had their evolutions, pre-evolution and labels properties exposed. It is still recommended to work using a Pokémon instance when possible.
|
||||
- Added capture check to BattleVictoryEvent.
|
||||
- The various hardcoded potion shoulder effects have been removed, make use of PotionBaseEffect.
|
||||
- Added ContextManager for tracking causes and contexts of conditions created during a battle. See BattleContext for types of conditions that are tracked.
|
||||
- Added MongoDB support for storing Pokémon and Player data. Must be enabled in config, requires MongoDB core and sync drivers (4.10.0+).
|
||||
- CobblemonShowdown updated to version 10.
|
||||
- Generation of a battle can be set in BattleFormat.
|
||||
- Pokémon now have ``teraType``, ``dmaxLevel``, and ``gmaxFactor`` properties. Gimmicks can be used during battle by adding the respective identifiers to ``keyItems`` in PlayerData: ``key_stone``, ``z_ring``, ``dynamax_band``, and ``tera_orb``. Dynamax is only supported in Gen 8 battles. Mega Evolution and Z-Power require custom held items to be added (e.g. an item with the path ``gengarite`` will allow Gengar to Mega Evolve). Currently custom Z-Crystals and Mega Stones are not supported.
|
||||
|
||||
### Datapack & Resourcepack Creators
|
||||
- All potion related shoulder effects have had their IDs changed. They now all share the same type being `potion_effect` and use the vanilla Potion data [parameters](https://minecraft.fandom.com/wiki/Potion#Item_data). For example, here is the converted Pidgey asset:
|
||||
- ```json
|
||||
{
|
||||
"type": "potion_effect",
|
||||
"effect": "minecraft:slow_falling",
|
||||
"amplifier": 0,
|
||||
"ambient": true,
|
||||
"showParticles": false,
|
||||
"showIcon": false
|
||||
}
|
||||
```
|
||||
- Renamed the ``walked_steps`` evolution requirement to ``blocks_traveled``.
|
||||
- Added support for scale in animations.
|
||||
- Added support for jump keyframes (i.e. pre and post keyframes)
|
||||
- Added structure spawning conditions
|
||||
- Added Advancement trigger for defeating Pokémon and collecting varieties of Pokémon.
|
||||
- Added support for "isBattle" and "isTouchingWater" properties on resource pack Pokémon poses. This allows your custom Pokémon to be posed differently when in battle.
|
||||
- Added support for "isVisible" on a transformed part on resource pack Pokémon poses. This allows your custom Pokémon to have bones disappear in specific poses, such as hiding Greninja's throwing star when not in a battle pose.
|
||||
- Added support for battle music. Sounds can be added to the ``battle.pvp.default`` and ``battle.pvw.default`` sound events.
|
||||
- Added 'enabled' optional property on model layers, allowing later variations to disable previously-defined layers. See [this issue](https://gitlab.com/cable-mc/cobblemon/-/issues/335) for how this looks.
|
||||
- Cobblemon items can now all have their own tooltips via resourcepacks. To add a tooltip, add a lang entry like "item.cobblemon.{item_id}.tooltip". If you want to add multiple tooltip lines you can do so with "item.cobblemon.{item_id}.tooltip_1" and upwards.
|
||||
- Item interaction evolutions and held item requirements now support NBT by creating an object JSON containing the key ``item`` for what used to be the existing condition support and a ``nbt`` key for the NBT format, this is the string [format](https://minecraft.fandom.com/wiki/NBT_format) expected in commands. Existing data does not need to be updated.
|
||||
- Fixed faint animations not working properly in add-ons.
|
||||
- Fixed non-existent species in spawn pool files causing random species to spawn.
|
||||
|
||||
### Localization
|
||||
- Added partial translations for Dutch, Polish, Swedish, Hungarian, Czech, Cyprus Greek, and even Esperanto.
|
||||
- Updated translation for French and Canadian French, Simplified Chinese, Japanese, Korean, Spanish and Mexican Spanish, Pirate English, German, Thai, Turkish, Portuguese and Brazilian Portuguese, Ukrainian, and Russian.
|
||||
|
||||
## [1.3.1 (March 31st, 2023)](#1-3-1)
|
||||
|
||||
### Additions
|
||||
@@ -11,7 +489,7 @@
|
||||
- Add lava surface spawn preset.
|
||||
- Added an ``any`` evolution requirement allowing you to define ``possibilities`` of other evolution requirements, for example, this allows you to create an evolution that requires the Pokémon to be shiny or a female.
|
||||
- Added the `/spawnpokemonfrompool [amount]` or `/forcespawn [amount]` command to spawn Pokémon(s) in the surrounding area using the natural spawn rates/pool of that area, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.spawnpokemon` if a permission mod is present. On a successful execution of the command, the amount of Pokémon spawned will be the output.
|
||||
- Added the `/pokebox` and `/pokeboxall` commands to move Pokemon(s) to the PC from a Player's party, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.pokebox` if a permission mod is present. On a successful execution of the command the output will be the number of pokemon moved to the Player's PC.
|
||||
- Added the `/pokebox` and `/pokeboxall` commands to move Pokémon(s) to the PC from a Player's party, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.pokebox` if a permission mod is present. On a successful execution of the command the output will be the number of pokemon moved to the Player's PC.
|
||||
- Added the `/pc` command which opens up the PC UI the same way interacting with the block would, this will be a cheat command in the Minecraft permission system or use the permission `cobblemon.command.pc` if a permission mod is present.
|
||||
|
||||
### Changes
|
||||
@@ -33,6 +511,7 @@
|
||||
- Made Weavile a little bigger.
|
||||
- Changed the recipes for Mystic Water, Miracle Seed, and Charcoal Stick to utilise the evolution stones, as well as Never-Melt Ice having an alternate recipe using the Ice Stone.
|
||||
- Replaced the `Failed to handle` battle messages to `Missing interpretation` to make it more clear that mechanics do work just still pending dedicated messages.
|
||||
- Healing Machine and PC are now mine-able with pickaxes and Apricorn leaves are mine-able using hoes.
|
||||
|
||||
### Fixes
|
||||
- Fixed killing a Dodrio killing your game. Dodrio will never look the same to us.
|
||||
@@ -47,7 +526,7 @@
|
||||
- Fixed console spam when rendering Pokémon model items.
|
||||
- Fixed battle messages for 50+ moves and abilities and items.
|
||||
- Fixed the possible duplicate when capturing Pokémon (probably, this one's hard to reproduce to confirm it's fixed).
|
||||
- Previously duplicated Pokémon are cleaned from PCs and parties on restart.
|
||||
- Previously duplicated Pokémon are cleaned from PCs and parties on restart.
|
||||
- Fixed an issue with some particle effects applying after a Pokémon has died or on top of the wrong Pokémon when using specific mods.
|
||||
- Fixed Pokémon not looking at each other in battle.
|
||||
- Fixed Experience Candy and Experience Share attempting to bring Pokémon above level cap causing crashes.
|
||||
@@ -83,6 +562,8 @@
|
||||
- Fixed instantly fleeing from Pokémon set to be unfleeable.
|
||||
- Fixed Pumpkaboo line forms not working. (Currently sizes aren't visual but check base stats to see which size you have.)
|
||||
- Fixed a bug that caused already interpreted messages for moves to be mistaken as uninterpreted.
|
||||
- Fixed a Pokémon spawner bug that caused Pokémon to not spawn due to dropped item entities.
|
||||
- Fixed a bug that causes Pokémon model items to be invisible.
|
||||
|
||||
### Developer
|
||||
- Add events that are fired just before and after a Pokémon is released (ReleasePokemonEvent.Pre and .Post)
|
||||
@@ -151,7 +632,7 @@
|
||||
- ``generation_9`` Sets the calculator to the generation 9 implementation.
|
||||
- ``cobblemon`` Sets the calculator to the custom Cobblemon implementation. This is the default value.
|
||||
- ``debug`` Sets the calculator to the debug/cheat implementation, every attempt will be a successful critical capture.
|
||||
|
||||
|
||||
### Changes
|
||||
- Pokémon now save to the world by default, meaning the same Pokémon will remain in the world and not disappear after you log out and log back in. They still despawn over time though.
|
||||
- Significantly sped up the Poké Ball shake animation so it takes less time to try to catch Pokémon.
|
||||
@@ -228,7 +709,7 @@
|
||||
- Fixed ambient sound file path for Porygon2.
|
||||
- Fixed forms not being able to unset the secondary type of a Pokémon in the stat JSON.
|
||||
- Fixed moves that haven't carried over from generation 8 onwards having the description they did in the generation 8 games instead of their last valid one.
|
||||
- Fixed shoulder mounted pokemon not returning to party on healer use and on evolution
|
||||
- Fixed shoulder mounted pokemon not returning to party on healer use and on evolution
|
||||
|
||||
### Developer
|
||||
- Reworked CatchRateModifier, as such, existing implementations need to be updated.
|
||||
@@ -240,7 +721,7 @@
|
||||
### Localization
|
||||
- Added complete translations for French, German, Simplified Mandarin, Brazilian Portuguese, and Pirate English.
|
||||
- Added partial translations for Traditional Mandarin, Italian, and Spanish. We'd love more help with this!
|
||||
- Thank you to all of the fantastic volunteer translators for taking the time to help with this!
|
||||
- Thank you to all of the fantastic volunteer translators for taking the time to help with this!
|
||||
|
||||
## [1.2.0 - The Customization Update (January 1st, 2023)](#1-2-0)
|
||||
### Additions
|
||||
@@ -278,7 +759,7 @@
|
||||
- Fixed stat calculations for everything except HP. HP was fine though :).
|
||||
- Fixed a randomized Pokémon spawning in mountains that corrupted the data of whatever party or PC it got into. Yikes.
|
||||
- Fixed a rare crash involving literally random number generation. A random crash involving random numbers.
|
||||
- Fixed all regular Mewtwo having the stats and types of Mega Mewtwo X - same deal with many other Pokémon.
|
||||
- Fixed all regular Mewtwo having the stats and types of Mega Mewtwo X - same deal with many other Pokémon.
|
||||
- Fixed the framing of many Pokémon in GUIs.
|
||||
- Fixed texture glitches with Rattata and Nidoqueen (again!).
|
||||
- Fixed dropped item forms of all Pokéballs and the Healing Machine, and slightly adjusted all other display settings
|
||||
|
||||
@@ -4,14 +4,15 @@ An open-source Pokémon mod for Minecraft Java Edition, written in Kotlin for Fa
|
||||
|
||||
## Getting started
|
||||
|
||||
To set up the development workspace, first clone the project and open the build.gradle with Intellij. There will be
|
||||
errors until you go to File -> Settings -> Build, Execution, Deployment -> Build Tools -> Gradle and change the Gradle JVM
|
||||
to 17. After changing this, click the icon for reloading the project. This will automatically
|
||||
put together all the dependencies and project setup.
|
||||
To set up the development workspace, first clone the project and open the build.gradle with Intellij. Make sure that you clone it to a folder that has no spaces in its path (for example, C:/Development/Cobblemon Stuff/cobblemon/ is bad) since Architectury Plugin seems to dislike it.
|
||||
|
||||
Run `./gradlew genEclipseRuns`, and then in Intellij go to your run configurations, and change whichever you plan on
|
||||
running to use a Java 17 JRE. runClient is as if you booted up in singleplayer, runServer is a server without a client,
|
||||
and runData is for summoning the Eldritch gods or something, idk.
|
||||
After it takes ages to load, you should hopefully have runnable configurations of the project in the top right, such as Minecraft Client (:fabric). If not, try running `./gradlew genEclipseRuns`.
|
||||
|
||||
Troubleshooting:
|
||||
- Try running `./gradlew --refresh-dependencies`
|
||||
- Try File -> Invalidate Caches.
|
||||
- Try deleting the `.idea` folder in the project root (make sure IntelliJ is closed when you try it).
|
||||
- Try completely reclone the thing lmao.
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -19,4 +20,4 @@ If you're interested in contributing to the project, you can simply fork the rep
|
||||
[here](https://gitlab.com/cable-mc/cobblemon/-/issues?scope=all&state=opened&label_name[]=accepted&assignee_id=None).
|
||||
|
||||
If you want a more involved role in the project, involving branches on the main repository instead of forking and involvement
|
||||
in design discussions, add and message Hiroku#4373 on our Discord here: https://discord.gg/AsNpJSST7G.
|
||||
in design discussions, you can either apply in the `application-box` forum of our Discord or add and message Hiroku (`hiroku_dev`) on our Discord here: https://discord.gg/cobblemon.
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
/*
|
||||
*
|
||||
* * 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
val accessWidenerFile = "src/main/resources/cobblemon-common.accesswidener"
|
||||
|
||||
plugins {
|
||||
java
|
||||
`java-library`
|
||||
id("org.cadixdev.licenser")
|
||||
id("dev.architectury.loom")
|
||||
@@ -12,6 +23,9 @@ plugins {
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
//JEI
|
||||
maven("https://maven.blamejared.com/")
|
||||
maven("https://maven.tterrag.com/")
|
||||
}
|
||||
|
||||
license {
|
||||
@@ -38,7 +52,7 @@ loom {
|
||||
|
||||
dependencies {
|
||||
minecraft("net.minecraft:minecraft:${rootProject.property("mc_version")}")
|
||||
mappings("net.fabricmc:yarn:${rootProject.property("yarn_version")}")
|
||||
mappings("net.fabricmc:yarn:${rootProject.property("yarn_version")}:v2")
|
||||
}
|
||||
|
||||
tasks {
|
||||
@@ -54,4 +68,4 @@ tasks {
|
||||
withType<Jar> {
|
||||
from(rootProject.file("LICENSE"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ publishing {
|
||||
maven("https://maven.impactdev.net/repository/development/") {
|
||||
name = "ImpactDev-Public"
|
||||
credentials {
|
||||
username = System.getenv("NEXUS_USER")
|
||||
password = System.getenv("NEXUS_PW")
|
||||
username = System.getenv("COBBLEMON_MAVEN_USER")
|
||||
password = System.getenv("COBBLEMON_MAVEN_PASSWORD")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-4
@@ -1,14 +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/.
|
||||
*
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("cobblemon.base-conventions")
|
||||
id("cobblemon.publish-conventions")
|
||||
}
|
||||
|
||||
architectury {
|
||||
common()
|
||||
common("forge", "fabric")
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven(url = "${rootProject.projectDir}/deps")
|
||||
maven(url = "https://api.modrinth.com/maven")
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
@@ -17,24 +28,33 @@ dependencies {
|
||||
implementation(libs.reflect)
|
||||
|
||||
modImplementation(libs.fabricLoader)
|
||||
modApi(libs.architectury)
|
||||
//Flywheel has no common dep so just pick one and don't use any platform specific code in common
|
||||
// modCompileOnly(libs.flywheelFabric)
|
||||
modApi(libs.molang)
|
||||
compileOnlyApi(libs.jeiApi)
|
||||
modCompileOnly(libs.adornFabric)
|
||||
|
||||
// For Showdown
|
||||
modCompileOnly(libs.graal)
|
||||
|
||||
//shadowCommon group: 'commons-io', name: 'commons-io', version: '2.6'
|
||||
|
||||
// For datastore
|
||||
modCompileOnly(libs.mongoDriverCore)
|
||||
modCompileOnly(libs.mongoDriverSync)
|
||||
|
||||
testRuntimeOnly(libs.junitEngine)
|
||||
testImplementation(libs.junitApi)
|
||||
testImplementation(libs.junitParams)
|
||||
testImplementation(libs.mockito)
|
||||
testImplementation(libs.mockk)
|
||||
|
||||
compileOnly("net.luckperms:api:${rootProject.property("luckperms_version")}")
|
||||
testImplementation(libs.classgraph)
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
setEvents(listOf("failed"))
|
||||
setExceptionFormat("full")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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.access;
|
||||
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
|
||||
public interface SoundManagerDuck {
|
||||
void toggleCategories(SoundCategory... categories);
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.bridges;
|
||||
|
||||
import net.minecraft.structure.processor.StructureProcessor;
|
||||
|
||||
public interface StructureProcessorListBridge {
|
||||
void append(StructureProcessor processor);
|
||||
void clear();
|
||||
}
|
||||
+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.client.render.models.blockbench.pose;
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PoseableEntityModel;
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.Entity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A bone represents a particular joint of a model. Bones are capable of containing child bones identifiable
|
||||
* by a String ideally representing the name of a particular bone.
|
||||
*
|
||||
* This interface is meant to allow projects and sidemods to implement their own rendering logic in reference
|
||||
* to the bones.
|
||||
*
|
||||
* @author Waterpicker
|
||||
* @since 1.4.0
|
||||
*/
|
||||
|
||||
public interface Bone {
|
||||
|
||||
/**
|
||||
* A map of identifiable names to child bones
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
Map<String, Bone> getChildren();
|
||||
|
||||
/**
|
||||
* Renders a particular bone in relation to a particular entity.
|
||||
*
|
||||
* @param context The render context this bone is being drawn for.
|
||||
* @param stack The current [MatrixStack] for the renderer
|
||||
* @param buffer The vertex consumer deployed by the renderer
|
||||
* @param packedLight The light level to be applied to the bone
|
||||
* @param packedOverlay The overlay value to be applied to the bone
|
||||
* @param r A value representing the amount of red coloring that should be applied on the RGB scale
|
||||
* @param g A value representing the amount of green coloring that should be applied on the RGB scale
|
||||
* @param b A value representing the amount of blue coloring that should be applied on the RGB scale
|
||||
* @param a The alpha value to apply to the model based on the RGB scale
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
void render(
|
||||
RenderContext context,
|
||||
MatrixStack stack,
|
||||
VertexConsumer buffer,
|
||||
int packedLight,
|
||||
int packedOverlay,
|
||||
float r,
|
||||
float g,
|
||||
float b,
|
||||
float a
|
||||
);
|
||||
|
||||
/**
|
||||
* Allows for direct transformation of a bone via a given matrix stack
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
void transform(MatrixStack matrixStack);
|
||||
}
|
||||
@@ -1,40 +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 com.cobblemon.mod.common.command.argument.*;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import net.minecraft.command.argument.ArgumentTypes;
|
||||
import net.minecraft.command.argument.serialize.ArgumentSerializer;
|
||||
import net.minecraft.command.argument.serialize.ConstantArgumentSerializer;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
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(ArgumentTypes.class)
|
||||
public class ArgumentTypesMixin {
|
||||
|
||||
@Shadow
|
||||
private static <A extends ArgumentType<?>, T extends ArgumentSerializer.ArgumentTypeProperties<A>> ArgumentSerializer<A, T> register(Registry<ArgumentSerializer<?, ?>> registry, String string, Class<? extends A> clazz, ArgumentSerializer<A, T> argumentSerializer) {
|
||||
throw new AssertionError("Should not be executed.");
|
||||
}
|
||||
|
||||
@Inject(method = "register(Lnet/minecraft/util/registry/Registry;)Lnet/minecraft/command/argument/serialize/ArgumentSerializer;", at = @At("RETURN"))
|
||||
private static void register(Registry<ArgumentSerializer<?, ?>> registry, CallbackInfoReturnable<ArgumentSerializer<?, ?>> ci) {
|
||||
register(registry, "cobblemon:pokemon", PokemonArgumentType.class, ConstantArgumentSerializer.of(PokemonArgumentType.Companion::pokemon));
|
||||
register(registry, "cobblemon:pokemonproperties", PokemonPropertiesArgumentType.class, ConstantArgumentSerializer.of(PokemonPropertiesArgumentType.Companion::properties));
|
||||
register(registry, "cobblemon:spawnbucket", SpawnBucketArgumentType.class, ConstantArgumentSerializer.of(SpawnBucketArgumentType.Companion::spawnBucket));
|
||||
register(registry, "cobblemon:move", MoveArgumentType.class, ConstantArgumentSerializer.of(MoveArgumentType.Companion::move));
|
||||
register(registry, "cobblemon:partyslot", PartySlotArgumentType.class, ConstantArgumentSerializer.of(PartySlotArgumentType.Companion::partySlot));
|
||||
}
|
||||
|
||||
}
|
||||
+2
-1
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.client.render.item.CobblemonBuiltinItemRendererR
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.item.BuiltinModelItemRenderer;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -24,7 +25,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
public class BuiltinModelItemRendererMixin {
|
||||
|
||||
@Inject(method = "render", at = @At("HEAD"), cancellable = true)
|
||||
private void cobblemon$useDynamicItemRenderer(ItemStack stack, ModelTransformation.Mode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo ci) {
|
||||
private void cobblemon$useDynamicItemRenderer(ItemStack stack, ModelTransformationMode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo ci) {
|
||||
CobblemonBuiltinItemRenderer renderer = CobblemonBuiltinItemRendererRegistry.INSTANCE.rendererOf(stack.getItem());
|
||||
if (renderer != null) {
|
||||
renderer.render(stack, mode, matrices, vertexConsumers, light, overlay);
|
||||
|
||||
@@ -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.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.block.PreEmptsExplosion;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.explosion.Explosion;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(value = Explosion.class)
|
||||
public class ExplosionMixin {
|
||||
|
||||
@Redirect(
|
||||
method = "affectWorld",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/World;getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;",
|
||||
ordinal = 0
|
||||
)
|
||||
)
|
||||
public BlockState cobblemon$whenExploded(World world, BlockPos pos) {
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if(blockState.getBlock() instanceof PreEmptsExplosion preExplosionBlock) {
|
||||
preExplosionBlock.whenExploded(world, blockState, pos);
|
||||
}
|
||||
return blockState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.api.pokemon.effect.ShoulderEffectRegistry;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
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(LivingEntity.class)
|
||||
public abstract class LivingEntityMixin {
|
||||
|
||||
@Inject(method = "onStatusEffectRemoved", at = @At(value = "TAIL"))
|
||||
private void cobblemon$onStatusEffectRemoved(StatusEffectInstance effect, CallbackInfo ci) {
|
||||
final LivingEntity entity = (LivingEntity) (Object) this;
|
||||
if (entity instanceof ServerPlayerEntity) {
|
||||
ShoulderEffectRegistry.INSTANCE.onEffectEnd((ServerPlayerEntity) entity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.client.render.models.blockbench.PoseableEntityModel;
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Bone;
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext;
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(ModelPart.class)
|
||||
public abstract class ModelPartMixin implements Bone {
|
||||
@Shadow public abstract void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, float red, float green, float blue, float alpha);
|
||||
|
||||
@Shadow public abstract void rotate(MatrixStack matrixStack);
|
||||
|
||||
@Shadow @Final
|
||||
public Map<String, ModelPart> children;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Bone> getChildren() {
|
||||
return (Map<String, Bone>) (Object) children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderContext context, MatrixStack stack, VertexConsumer buffer, int packedLight, int packedOverlay, float r, float g, float b, float a) {
|
||||
this.render(stack, buffer, packedLight, packedOverlay, r, g, b, a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(MatrixStack matrixStack) {
|
||||
this.rotate(matrixStack);
|
||||
}
|
||||
}
|
||||
@@ -145,7 +145,7 @@ public abstract class PlayerMixin extends LivingEntity {
|
||||
public void onEatFood(World world, ItemStack stack, CallbackInfoReturnable<ItemStack> cir) {
|
||||
if (!getWorld().isClient) {
|
||||
if (stack.getItem() == Items.APPLE && getWorld().random.nextDouble() < Cobblemon.config.getAppleLeftoversChance()) {
|
||||
ItemStack leftovers = new ItemStack(CobblemonItems.LEFTOVERS.get());
|
||||
ItemStack leftovers = new ItemStack(CobblemonItems.LEFTOVERS);
|
||||
ServerPlayerEntity player = Objects.requireNonNull(getServer()).getPlayerManager().getPlayer(uuid);
|
||||
assert player != null;
|
||||
CobblemonEvents.LEFTOVERS_CREATED.postThen(
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.brewing.BrewingRecipes;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.BrewingStandScreenHandler;
|
||||
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;
|
||||
|
||||
@Mixin(BrewingStandScreenHandler.PotionSlot.class)
|
||||
public class PotionSlotMixin {
|
||||
@Inject(
|
||||
method = "matches",
|
||||
at = @At(value = "HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private static void matchesBrewable(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (BrewingRecipes.brewableItems.contains(stack.getItem())) {
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +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 com.cobblemon.mod.common.api.spawning.mixins.CachedOnlyChunkAccessor;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import net.minecraft.server.world.ChunkHolder;
|
||||
import net.minecraft.server.world.ServerChunkManager;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.ChunkManager;
|
||||
import net.minecraft.world.chunk.ChunkStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Mixin(ServerChunkManager.class)
|
||||
public abstract class ServerChunkManagerMixin extends ChunkManager implements CachedOnlyChunkAccessor {
|
||||
@Shadow @Nullable protected abstract ChunkHolder getChunkHolder(long pos);
|
||||
|
||||
@Override
|
||||
public Chunk cobblemon$request(int x, int z, @NotNull ChunkStatus status) {
|
||||
long l = ChunkPos.toLong(x, z);
|
||||
|
||||
ChunkHolder holder = getChunkHolder(l);
|
||||
if (holder != null) {
|
||||
CompletableFuture<Either<Chunk, ChunkHolder.Unloaded>> future = holder.getFutureFor(status);
|
||||
if (future.isDone()) {
|
||||
return future.join().left().orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+5
-10
@@ -8,14 +8,12 @@
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.block.ApricornBlock;
|
||||
import com.cobblemon.mod.common.block.ShearableBlock;
|
||||
import kotlin.Unit;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.dispenser.ShearsDispenserBehavior;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.event.GameEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@@ -24,15 +22,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
@Mixin(ShearsDispenserBehavior.class)
|
||||
public abstract class ShearsDispenserBehaviorMixin {
|
||||
|
||||
// This exists so we can execute our custom interaction only if no one redirected shears interactions to overwrite the vanilla ones.
|
||||
// This exists, so we can execute our custom interaction only if no one redirected shears interactions to overwrite the vanilla ones.
|
||||
@Inject(method = "tryShearBlock", at = @At("HEAD"), cancellable = true)
|
||||
private static void cobblemon$tryApricornHarvest(ServerWorld world, BlockPos pos, CallbackInfoReturnable<Boolean> cir) {
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
if (state.getBlock() instanceof ApricornBlock apricornBlock && state.get(ApricornBlock.Companion.getAGE()) == ApricornBlock.MAX_AGE) {
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_SHEEP_SHEAR, SoundCategory.BLOCKS, 1F, 1F);
|
||||
apricornBlock.harvest(world, state, pos);
|
||||
world.emitGameEvent(null, GameEvent.SHEAR, pos);
|
||||
cir.setReturnValue(true);
|
||||
if (state.getBlock() instanceof ShearableBlock shearableBlock) {
|
||||
cir.setReturnValue(shearableBlock.attemptShear(world, state, pos, () -> Unit.INSTANCE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.access.SoundManagerDuck;
|
||||
import net.minecraft.client.sound.SoundInstance;
|
||||
import net.minecraft.client.sound.SoundManager;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
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(SoundManager.class)
|
||||
public class SoundManagerMixin implements SoundManagerDuck {
|
||||
|
||||
private boolean[] blockedCategories = new boolean[SoundCategory.values().length];
|
||||
|
||||
@Override
|
||||
public void toggleCategories(SoundCategory... categories) {
|
||||
for (SoundCategory category : categories) {
|
||||
int index = category.ordinal();
|
||||
boolean blocked = blockedCategories[index];
|
||||
blockedCategories[index] = !blocked;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "play(Lnet/minecraft/client/sound/SoundInstance;)V", at = @At("HEAD"), cancellable = true)
|
||||
public void play(SoundInstance sound, CallbackInfo cb) {
|
||||
if (blockedCategories[sound.getCategory().ordinal()]) cb.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "play(Lnet/minecraft/client/sound/SoundInstance;I)V", at = @At("HEAD"), cancellable = true)
|
||||
public void play(SoundInstance sound, int delay, CallbackInfo cb) {
|
||||
if (blockedCategories[sound.getCategory().ordinal()]) cb.cancel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.google.common.collect.Multimap;
|
||||
import net.minecraft.client.sound.SoundInstance;
|
||||
import net.minecraft.client.sound.SoundSystem;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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(SoundSystem.class)
|
||||
public abstract class SoundSystemMixin {
|
||||
|
||||
@Shadow
|
||||
private Multimap<SoundCategory, SoundInstance> sounds;
|
||||
|
||||
@Shadow
|
||||
protected abstract void stop(SoundInstance sound);
|
||||
|
||||
@Inject(method = "stopSounds(Lnet/minecraft/util/Identifier;Lnet/minecraft/sound/SoundCategory;)V", at = @At("HEAD"), cancellable = true)
|
||||
public void stopSounds(@Nullable Identifier id, @Nullable SoundCategory category, CallbackInfo cb) {
|
||||
if (id == null && category != null) {
|
||||
sounds.get(category).forEach(this::stop);
|
||||
cb.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.mojang.datafixers.util.Pair;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.structure.pool.StructurePool;
|
||||
import net.minecraft.structure.pool.StructurePoolElement;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(StructurePool.class)
|
||||
public interface StructurePoolAccessor {
|
||||
@Accessor("elementCounts")
|
||||
List<Pair<StructurePoolElement, Integer>> getElementCounts();
|
||||
|
||||
@Mutable
|
||||
@Accessor("elementCounts")
|
||||
void setElementCounts(List<Pair<StructurePoolElement, Integer>> elementCounts);
|
||||
|
||||
@Accessor("elements")
|
||||
ObjectArrayList<StructurePoolElement> getElements();
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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 net.minecraft.registry.Registry;
|
||||
import net.minecraft.structure.PoolStructurePiece;
|
||||
import net.minecraft.structure.StructureTemplateManager;
|
||||
import net.minecraft.structure.pool.*;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.world.HeightLimitView;
|
||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.gen.noise.NoiseConfig;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
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.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Mixin(StructurePoolBasedGenerator.StructurePoolGenerator.class)
|
||||
public abstract class StructurePoolGeneratorMixin {
|
||||
@Final
|
||||
@Mutable
|
||||
@Shadow Deque<StructurePoolBasedGenerator.ShapedPoolStructurePiece> structurePieces;
|
||||
|
||||
Map<String, Integer> generatedStructureGroupCounts;
|
||||
|
||||
private static final Map<String, Integer> structureMaxes;
|
||||
private static final Map<Identifier, Set<String>> structureGroups = new HashMap<>();
|
||||
static {
|
||||
String pokecenter = "pokecenter";
|
||||
String berry = "berry_farm";
|
||||
|
||||
structureGroups.put(CobblemonStructureIDs.PLAINS_POKECENTER, Set.of(pokecenter));
|
||||
structureGroups.put(CobblemonStructureIDs.DESERT_POKECENTER, Set.of(pokecenter));
|
||||
structureGroups.put(CobblemonStructureIDs.SAVANNA_POKECENTER, Set.of(pokecenter));
|
||||
structureGroups.put(CobblemonStructureIDs.SNOWY_POKECENTER, Set.of(pokecenter));
|
||||
structureGroups.put(CobblemonStructureIDs.TAIGA_POKECENTER, Set.of(pokecenter));
|
||||
|
||||
structureGroups.put(CobblemonStructureIDs.SAVANNA_BERRY_SMALL, Set.of(berry));
|
||||
structureGroups.put(CobblemonStructureIDs.SAVANNA_BERRY_LARGE, Set.of(berry));
|
||||
structureGroups.put(CobblemonStructureIDs.PLAINS_BERRY_SMALL, Set.of(berry));
|
||||
structureGroups.put(CobblemonStructureIDs.PLAINS_BERRY_LARGE, Set.of(berry));
|
||||
structureGroups.put(CobblemonStructureIDs.SNOWY_BERRY_SMALL, Set.of(berry));
|
||||
structureGroups.put(CobblemonStructureIDs.SNOWY_BERRY_LARGE, Set.of(berry));
|
||||
structureGroups.put(CobblemonStructureIDs.DESERT_BERRY_SMALL, Set.of(berry));
|
||||
structureGroups.put(CobblemonStructureIDs.DESERT_BERRY_LARGE, Set.of(berry));
|
||||
structureGroups.put(CobblemonStructureIDs.TAIGA_BERRY_SMALL, Set.of(berry));
|
||||
structureGroups.put(CobblemonStructureIDs.TAIGA_BERRY_LARGE, Set.of(berry));
|
||||
|
||||
//Mapped using location string as key
|
||||
Map<String, Integer> aMap = new HashMap<>();
|
||||
aMap.put(pokecenter, 1);
|
||||
aMap.put(berry, 2);
|
||||
|
||||
// aMap.put(CobblemonStructureIDs.PLAINS_LONG_PATH, 3);
|
||||
// aMap.put(CobblemonStructureIDs.DESERT_LONG_PATH, 3);
|
||||
// aMap.put(CobblemonStructureIDs.SAVANNA_LONG_PATH, 3);
|
||||
// aMap.put(CobblemonStructureIDs.SNOWY_LONG_PATH, 3);
|
||||
// aMap.put(CobblemonStructureIDs.TAIGA_LONG_PATH, 3);
|
||||
structureMaxes = Collections.unmodifiableMap(aMap);
|
||||
}
|
||||
|
||||
public Set<String> getGroups(Identifier structureIdentifier) {
|
||||
return structureGroups.getOrDefault(structureIdentifier, Set.of());
|
||||
}
|
||||
|
||||
public boolean hasReachedMaximum(Identifier structureIdentifier) {
|
||||
Set<String> groups = getGroups(structureIdentifier);
|
||||
for (String group : groups) {
|
||||
int count = generatedStructureGroupCounts.getOrDefault(group, 0);
|
||||
if (count >= structureMaxes.getOrDefault(group, Integer.MAX_VALUE)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void incrementStructureCount(Identifier structureIdentifier) {
|
||||
Set<String> groups = getGroups(structureIdentifier);
|
||||
for (String group : groups) {
|
||||
generatedStructureGroupCounts.put(group, generatedStructureGroupCounts.getOrDefault(group, 0) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void onStructurePoolGeneratorCreation(Registry<StructurePool> registry, int maxSize, ChunkGenerator chunkGenerator, StructureTemplateManager structureTemplateManager, List<? super PoolStructurePiece> children, Random random, CallbackInfo ci) {
|
||||
generatedStructureGroupCounts = new HashMap<>();
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "generatePiece", at = @At("STORE"), ordinal = 1)
|
||||
private Iterator<StructurePoolElement> reduceStructurePoolElementIterator(Iterator<StructurePoolElement> iterator) {
|
||||
List<StructurePoolElement> reducedList = new ArrayList<>();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
StructurePoolElement structure = iterator.next();
|
||||
Identifier structurePieceLocationKey = getCobblemonOnlyLocation(structure);
|
||||
if (structurePieceLocationKey == null) {
|
||||
reducedList.add(structure);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hasReachedMaximum(structurePieceLocationKey)) {
|
||||
reducedList.add(structure);
|
||||
}
|
||||
}
|
||||
|
||||
return reducedList.iterator();
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "generatePiece", at = @At("STORE"), ordinal = 1)
|
||||
private PoolStructurePiece injected(PoolStructurePiece poolStructurePiece) {
|
||||
Identifier structureLocationKey = getCobblemonOnlyLocation(poolStructurePiece.getPoolElement());
|
||||
if (structureLocationKey != null) {
|
||||
incrementStructureCount(structureLocationKey);
|
||||
}
|
||||
return poolStructurePiece;
|
||||
}
|
||||
|
||||
// This doesn't SEEM necessary? It appears to work without.
|
||||
@Inject(method = "generatePiece", at = @At("HEAD"))
|
||||
private void beforeGeneratePiece(PoolStructurePiece piece, MutableObject<VoxelShape> pieceShape, int minY, boolean modifyBoundingBox, HeightLimitView world, NoiseConfig noiseConfig, CallbackInfo ci) {
|
||||
// Identifier structureLocationKey = getCobblemonOnlyLocation(piece.getPoolElement());
|
||||
//
|
||||
// if (structureLocationKey != null) {
|
||||
// Integer currentlyGenerated = generatedStructureCounts.get(structureLocationKey);
|
||||
// if (currentlyGenerated == null) currentlyGenerated = 0;
|
||||
// generatedStructureCounts.put(structureLocationKey, currentlyGenerated + 1);
|
||||
// }
|
||||
//
|
||||
// List<StructurePoolBasedGenerator.ShapedPoolStructurePiece> reducedStructurePiecesList = structurePieces.stream().toList();
|
||||
//
|
||||
// for (Identifier maxStructureLocationKey : structureMaxes.keySet()) {
|
||||
// Integer maxAllowed = structureMaxes.get(maxStructureLocationKey);
|
||||
//
|
||||
// Integer currentlyGenerated = generatedStructureCounts.get(maxStructureLocationKey);
|
||||
// if (currentlyGenerated == null) currentlyGenerated = 0;
|
||||
// if (currentlyGenerated < maxAllowed) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// //Already have max so need to remove
|
||||
// reducedStructurePiecesList = reducedStructurePiecesList.stream()
|
||||
// .filter(shapedStructurePiece -> {
|
||||
// Identifier locationKey = getCobblemonOnlyLocation(shapedStructurePiece.piece.getPoolElement());
|
||||
// if (locationKey == null) {
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return !locationKey.equals(maxStructureLocationKey);
|
||||
// })
|
||||
// .collect(Collectors.toList());
|
||||
// }
|
||||
//
|
||||
// structurePieces = new ArrayDeque<>(reducedStructurePiecesList);
|
||||
}
|
||||
|
||||
private static Identifier getCobblemonOnlyLocation(StructurePoolElement structurePoolElement) {
|
||||
Identifier location = getLocationIfAvailable(structurePoolElement);
|
||||
if (location == null) return null;
|
||||
|
||||
if (!location.getNamespace().equals("cobblemon")) return null;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
private static Identifier getLocationIfAvailable(StructurePoolElement structurePoolElement) {
|
||||
if (structurePoolElement instanceof LegacySinglePoolElement legacySinglePoolElement) {
|
||||
if (legacySinglePoolElement.location.left().isEmpty()) return null;
|
||||
|
||||
return legacySinglePoolElement.location.left().get();
|
||||
} else if (structurePoolElement instanceof SinglePoolElement singlePoolElement) {
|
||||
if (singlePoolElement.location.left().isEmpty()) return null;
|
||||
|
||||
return singlePoolElement.location.left().get();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// private List<StructurePoolElement> removeInstanceOfLocationKeyFrom(List<StructurePoolElement> structureList, Integer allowedNumberOfInstances, Identifier locationKey) {
|
||||
// List<StructurePoolElement> reducedList = new ArrayList<>();
|
||||
// int instancesFound = 0;
|
||||
//
|
||||
// for (StructurePoolElement structurePoolElement: structureList) {
|
||||
// Identifier structureKey = getCobblemonOnlyLocation(structurePoolElement);
|
||||
// if (structureKey == null || !structureKey.equals(locationKey)) {
|
||||
// reducedList.add(structurePoolElement);
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (instancesFound >= allowedNumberOfInstances) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// reducedList.add(structurePoolElement);
|
||||
// instancesFound++;
|
||||
// }
|
||||
//
|
||||
// return reducedList;
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.bridges.StructureProcessorListBridge;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.structure.processor.StructureProcessor;
|
||||
import net.minecraft.structure.processor.StructureProcessorList;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(StructureProcessorList.class)
|
||||
public class StructureProcessorListMixin implements StructureProcessorListBridge {
|
||||
|
||||
@Final
|
||||
@Mutable
|
||||
@Shadow
|
||||
private List<StructureProcessor> list;
|
||||
|
||||
@Override
|
||||
public void append(StructureProcessor processor) {
|
||||
List<StructureProcessor> mutable = new ArrayList<>(this.list);
|
||||
mutable.add(processor);
|
||||
this.list = ImmutableList.copyOf(mutable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.list = ImmutableList.of();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+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.sound.MusicTracker;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(MusicTracker.class)
|
||||
public interface MusicTrackerAccessor {
|
||||
@Accessor("timeUntilNextSong")
|
||||
int timeUntilNextSong();
|
||||
|
||||
@Accessor("timeUntilNextSong")
|
||||
void setTimeUntilNextSong(int timeUntilNextSong);
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.entity.effect.StatusEffectInstance;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(StatusEffectInstance.class)
|
||||
public interface StatusEffectInstanceAccessor {
|
||||
|
||||
@Accessor
|
||||
void setAmplifier(int amplifier);
|
||||
|
||||
@Accessor
|
||||
void setShowParticles(boolean showParticles);
|
||||
|
||||
@Accessor
|
||||
void setShowIcon(boolean showIcon);
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.entity;
|
||||
|
||||
import com.cobblemon.mod.common.brewing.BrewingRecipes;
|
||||
import net.minecraft.block.entity.BrewingStandBlockEntity;
|
||||
import net.minecraft.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.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(BrewingStandBlockEntity.class)
|
||||
public abstract class BrewingStandBlockEntityMixin
|
||||
{
|
||||
@Inject(
|
||||
method = "isValid",
|
||||
at = @At(value = "HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$isValid(int slot, ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
|
||||
final BrewingStandBlockEntity entity = (BrewingStandBlockEntity) (Object) this;
|
||||
if (slot < 3)
|
||||
{
|
||||
if (entity.getStack(slot).isEmpty() && BrewingRecipes.brewableItems.contains(stack.getItem()))
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.invoker;
|
||||
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.resource.featuretoggle.FeatureFlag;
|
||||
import net.minecraft.sound.BlockSoundGroup;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mixin(Blocks.class)
|
||||
public interface BlocksInvoker {
|
||||
|
||||
@Invoker("createLogBlock")
|
||||
static PillarBlock createLogBlock(MapColor topMapColor, MapColor sideMapColor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Invoker("createLeavesBlock")
|
||||
static LeavesBlock createLeavesBlock(BlockSoundGroup soundGroup) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Invoker("createWoodenButtonBlock")
|
||||
static ButtonBlock createWoodenButtonBlock(BlockSetType blockSetType, FeatureFlag... requiredFeatures) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Invoker("createFlowerPotBlock")
|
||||
static FlowerPotBlock createFlowerPotBlock(Block flower, FeatureFlag... requiredFeatures) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.invoker;
|
||||
|
||||
import net.minecraft.world.GameRules;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(GameRules.BooleanRule.class)
|
||||
public interface BooleanRuleInvoker {
|
||||
@Invoker("create")
|
||||
static GameRules.Type<GameRules.BooleanRule> cobblemon$create(boolean initialValue) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
+20
@@ -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.invoker;
|
||||
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.entity.Entity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(ClientPlayNetworkHandler.class)
|
||||
public interface ClientPlayNetworkHandlerInvoker {
|
||||
@Invoker
|
||||
void callPlaySpawnSound(Entity entity);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.invoker;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.BlockSetType;
|
||||
import net.minecraft.block.DoorBlock;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(DoorBlock.class)
|
||||
public interface DoorBlockInvoker {
|
||||
@Invoker("<init>")
|
||||
static DoorBlock cobblemon$create(AbstractBlock.Settings settings, BlockSetType blockSetType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -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.invoker;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import net.minecraft.block.FireBlock;
|
||||
import net.minecraft.block.Blocks;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(FireBlock.class)
|
||||
public interface FireBlockInvoker {
|
||||
@Invoker("registerFlammableBlock") void registerNewFlammableBlock(Block block, int burnChance, int spreadChance);
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.invoker;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.BlockSetType;
|
||||
import net.minecraft.block.PressurePlateBlock;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(PressurePlateBlock.class)
|
||||
public interface PressurePlateBlockInvoker {
|
||||
@Invoker("<init>")
|
||||
static PressurePlateBlock cobblemon$create(PressurePlateBlock.ActivationRule type, AbstractBlock.Settings settings, BlockSetType blockSetType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.invoker;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.StairsBlock;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(StairsBlock.class)
|
||||
public interface StairsBlockInvoker {
|
||||
@Invoker("<init>")
|
||||
static StairsBlock cobblemon$create(BlockState baseBlockState, AbstractBlock.Settings settings) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.invoker;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.BlockSetType;
|
||||
import net.minecraft.block.TrapdoorBlock;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(TrapdoorBlock.class)
|
||||
public interface TrapdoorBlockInvoker {
|
||||
@Invoker("<init>")
|
||||
static TrapdoorBlock cobblemon$create(AbstractBlock.Settings settings, BlockSetType blockSetType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import net.minecraft.client.render.item.ItemModels;
|
||||
import net.minecraft.client.render.item.ItemRenderer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||
import net.minecraft.client.util.ModelIdentifier;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
@@ -33,13 +34,12 @@ public abstract class ItemRendererMixin {
|
||||
|
||||
@Shadow @Final private ItemModels models;
|
||||
|
||||
@Shadow public abstract void renderItem(ItemStack stack, ModelTransformation.Mode renderMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model);
|
||||
@Shadow public abstract void renderItem(ItemStack stack, ModelTransformationMode renderMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model);
|
||||
|
||||
@Inject(method = "getModel", at = @At("HEAD"), cancellable = true)
|
||||
private void cobblemon$bakePokeballModel(ItemStack stack, World world, LivingEntity entity, int seed, CallbackInfoReturnable<BakedModel> cir) {
|
||||
if (stack.getItem() instanceof PokeBallItem pokeBallItem) {
|
||||
ModelIdentifier modelIdentifier = new ModelIdentifier(pokeBallItem.getPokeBall().getModel3d());
|
||||
BakedModel model = this.models.getModelManager().getModel(modelIdentifier);
|
||||
BakedModel model = this.models.getModelManager().getModel(new ModelIdentifier(pokeBallItem.getPokeBall().getModel3d(), "inventory"));
|
||||
ClientWorld clientWorld = world instanceof ClientWorld ? (ClientWorld) world : null;
|
||||
BakedModel overriddenModel = model.getOverrides().apply(model, stack, clientWorld, entity, seed);
|
||||
cir.setReturnValue(overriddenModel == null ? this.models.getModelManager().getMissingModel() : overriddenModel);
|
||||
@@ -47,15 +47,14 @@ public abstract class ItemRendererMixin {
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformation$Mode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;)V",
|
||||
method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$determinePokeballModel(ItemStack stack, ModelTransformation.Mode renderMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, CallbackInfo ci) {
|
||||
boolean shouldBe2d = renderMode == ModelTransformation.Mode.GUI || renderMode == ModelTransformation.Mode.FIXED;
|
||||
private void cobblemon$determinePokeballModel(ItemStack stack, ModelTransformationMode renderMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, CallbackInfo ci) {
|
||||
boolean shouldBe2d = renderMode == ModelTransformationMode.GUI || renderMode == ModelTransformationMode.FIXED;
|
||||
if (shouldBe2d && stack.getItem() instanceof PokeBallItem pokeBallItem) {
|
||||
ModelIdentifier modelIdentifier = new ModelIdentifier(pokeBallItem.getPokeBall().getModel2d());
|
||||
BakedModel replacementModel = this.models.getModelManager().getModel(modelIdentifier);
|
||||
BakedModel replacementModel = this.models.getModelManager().getModel(new ModelIdentifier(pokeBallItem.getPokeBall().getModel2d(), "inventory"));
|
||||
if (!model.equals(replacementModel)) {
|
||||
ci.cancel();
|
||||
renderItem(stack, renderMode, leftHanded, matrices, vertexConsumers, light, overlay, replacementModel);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.pokeball;
|
||||
|
||||
import com.cobblemon.mod.common.entity.pokeball.WaterDragModifier;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.projectile.thrown.ThrownEntity;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
|
||||
@Mixin(ThrownEntity.class)
|
||||
public abstract class ThrownEntityMixin extends Entity {
|
||||
|
||||
public ThrownEntityMixin(EntityType<?> type, World world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "tick", at = @At("STORE"), ordinal = 0)
|
||||
private float cobblemon$waterDragModifier(float value) {
|
||||
if (this.isTouchingWater() && this instanceof WaterDragModifier) {
|
||||
return ((WaterDragModifier) this).waterDrag();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.advancement.CobblemonCriteria
|
||||
import com.cobblemon.mod.common.advancement.criterion.EvolvePokemonContext
|
||||
import com.cobblemon.mod.common.api.Priority
|
||||
import com.cobblemon.mod.common.api.SeasonResolver
|
||||
import com.cobblemon.mod.common.api.data.DataProvider
|
||||
@@ -18,12 +19,9 @@ import com.cobblemon.mod.common.api.drop.ItemDropEntry
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.BATTLE_VICTORY
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.DATA_SYNCHRONIZED
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.EVOLUTION_COMPLETE
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.LIVING_DEATH
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.PLAYER_QUIT
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.LEVEL_UP_EVENT
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.POKEMON_CAPTURED
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.SERVER_STARTED
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.SERVER_STOPPED
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.TICK_POST
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.TRADE_COMPLETED
|
||||
import com.cobblemon.mod.common.api.net.serializers.PoseTypeDataSerializer
|
||||
import com.cobblemon.mod.common.api.net.serializers.StringSetDataSerializer
|
||||
import com.cobblemon.mod.common.api.net.serializers.Vec3DataSerializer
|
||||
@@ -43,8 +41,6 @@ import com.cobblemon.mod.common.api.pokemon.stats.EvCalculator
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Generation8EvCalculator
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.StatProvider
|
||||
import com.cobblemon.mod.common.api.properties.CustomPokemonProperty
|
||||
import com.cobblemon.mod.common.api.reactive.Observable.Companion.filter
|
||||
import com.cobblemon.mod.common.api.reactive.Observable.Companion.map
|
||||
import com.cobblemon.mod.common.api.scheduling.ScheduledTaskTracker
|
||||
import com.cobblemon.mod.common.api.spawning.BestSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.CobblemonSpawningProspector
|
||||
@@ -53,21 +49,30 @@ import com.cobblemon.mod.common.api.spawning.prospecting.SpawningProspector
|
||||
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
|
||||
import com.cobblemon.mod.common.api.storage.adapter.flatifle.FileStoreAdapter
|
||||
import com.cobblemon.mod.common.api.storage.adapter.flatifle.JSONStoreAdapter
|
||||
import com.cobblemon.mod.common.api.storage.adapter.flatifle.NBTStoreAdapter
|
||||
import com.cobblemon.mod.common.api.storage.adapter.database.MongoDBStoreAdapter
|
||||
import com.cobblemon.mod.common.api.storage.adapter.flatfile.FileStoreAdapter
|
||||
import com.cobblemon.mod.common.api.storage.adapter.flatfile.JSONStoreAdapter
|
||||
import com.cobblemon.mod.common.api.storage.adapter.flatfile.NBTStoreAdapter
|
||||
import com.cobblemon.mod.common.api.storage.factory.FileBackedPokemonStoreFactory
|
||||
import com.cobblemon.mod.common.api.storage.pc.PCStore
|
||||
import com.cobblemon.mod.common.api.storage.pc.link.PCLinkManager
|
||||
import com.cobblemon.mod.common.api.storage.player.PlayerDataStoreManager
|
||||
import com.cobblemon.mod.common.api.storage.player.factory.JsonPlayerDataStoreFactory
|
||||
import com.cobblemon.mod.common.api.storage.player.factory.MongoPlayerDataStoreFactory
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonEntityTypeTags
|
||||
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.actor.PokemonBattleActor
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.battles.runner.ShowdownService
|
||||
import com.cobblemon.mod.common.command.argument.MoveArgumentType
|
||||
import com.cobblemon.mod.common.command.argument.PartySlotArgumentType
|
||||
import com.cobblemon.mod.common.command.argument.PokemonArgumentType
|
||||
import com.cobblemon.mod.common.command.argument.PokemonPropertiesArgumentType
|
||||
import com.cobblemon.mod.common.command.argument.PokemonStoreArgumentType
|
||||
import com.cobblemon.mod.common.command.argument.SpawnBucketArgumentType
|
||||
import com.cobblemon.mod.common.config.CobblemonConfig
|
||||
import com.cobblemon.mod.common.config.LastChangedVersion
|
||||
import com.cobblemon.mod.common.config.constraint.IntConstraint
|
||||
@@ -77,37 +82,34 @@ import com.cobblemon.mod.common.events.AdvancementHandler
|
||||
import com.cobblemon.mod.common.events.ServerTickHandler
|
||||
import com.cobblemon.mod.common.item.PokeBallItem
|
||||
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
|
||||
import com.cobblemon.mod.common.net.serverhandling.ServerPacketRegistrar
|
||||
import com.cobblemon.mod.common.particle.CobblemonParticles
|
||||
import com.cobblemon.mod.common.permission.LaxPermissionValidator
|
||||
import com.cobblemon.mod.common.platform.events.PlatformEvents
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.pokemon.aspects.GENDER_ASPECT
|
||||
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.*
|
||||
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
|
||||
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||
import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
|
||||
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.UntradeableProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
|
||||
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
|
||||
import com.cobblemon.mod.common.registry.CompletableRegistry
|
||||
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
|
||||
import com.cobblemon.mod.common.trade.TradeManager
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.getServer
|
||||
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.removeAmountIf
|
||||
import com.cobblemon.mod.common.util.server
|
||||
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
|
||||
import com.cobblemon.mod.common.world.feature.CobblemonOrePlacedFeatures
|
||||
import com.cobblemon.mod.common.world.placement.CobblemonPlacementTypes
|
||||
import dev.architectury.event.EventResult
|
||||
import dev.architectury.event.events.common.CommandRegistrationEvent
|
||||
import dev.architectury.event.events.common.InteractionEvent
|
||||
import dev.architectury.event.events.common.PlayerEvent
|
||||
import dev.architectury.hooks.item.tool.AxeItemHooks
|
||||
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
|
||||
@@ -118,17 +120,18 @@ import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
import kotlin.reflect.jvm.javaField
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.command.argument.serialize.ConstantArgumentSerializer
|
||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.item.NameTagItem
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.util.WorldSavePath
|
||||
import net.minecraft.util.registry.RegistryKey
|
||||
import net.minecraft.world.World
|
||||
import org.apache.logging.log4j.LogManager
|
||||
|
||||
object Cobblemon {
|
||||
const val MODID = "cobblemon"
|
||||
const val VERSION = "1.3.1"
|
||||
const val VERSION = "1.4.0"
|
||||
const val CONFIG_PATH = "config/$MODID/main.json"
|
||||
val LOGGER = LogManager.getLogger()
|
||||
|
||||
@@ -158,6 +161,17 @@ object Cobblemon {
|
||||
var seasonResolver: SeasonResolver = TagSeasonResolver
|
||||
|
||||
fun preInitialize(implementation: CobblemonImplementation) {
|
||||
this.implementation = implementation
|
||||
implementation.registerPermissionValidator()
|
||||
implementation.registerSoundEvents()
|
||||
implementation.registerBlocks()
|
||||
implementation.registerItems()
|
||||
implementation.registerEntityTypes()
|
||||
implementation.registerEntityAttributes()
|
||||
implementation.registerBlockEntityTypes()
|
||||
implementation.registerWorldGenFeatures()
|
||||
implementation.registerParticles()
|
||||
|
||||
DropEntry.register("command", CommandDropEntry::class.java)
|
||||
DropEntry.register("item", ItemDropEntry::class.java, isDefault = true)
|
||||
|
||||
@@ -165,18 +179,13 @@ object Cobblemon {
|
||||
CaptureCalculators.registerDefaults()
|
||||
|
||||
this.loadConfig()
|
||||
this.implementation = implementation
|
||||
// CobblemonBlockPredicates.touch()
|
||||
CobblemonOrePlacedFeatures.register()
|
||||
CobblemonPlacedFeatures.register()
|
||||
this.registerArgumentTypes()
|
||||
|
||||
CobblemonCriteria // Init the fields and register the criteria
|
||||
CobblemonEntities.register()
|
||||
CobblemonBlocks.register()
|
||||
CobblemonBlockEntities.register()
|
||||
CobblemonItems.register()
|
||||
ServerPacketRegistrar.registerHandlers()
|
||||
CobblemonSounds.register()
|
||||
CobblemonFeatures.register()
|
||||
CobblemonGameRules.register()
|
||||
CobblemonParticles.register()
|
||||
CobblemonGameRules // Init fields and register
|
||||
|
||||
ShoulderEffectRegistry.register()
|
||||
|
||||
@@ -184,26 +193,28 @@ object Cobblemon {
|
||||
storage.onPlayerDataSync(it)
|
||||
playerData.get(it).sendToPlayer(it)
|
||||
starterHandler.handleJoin(it)
|
||||
ServerSettingsPacket().sendToPlayer(it)
|
||||
ServerSettingsPacket(this.config.preventCompletePartyDeposit, this.config.displayEntityLevelLabel).sendToPlayer(it)
|
||||
}
|
||||
PLAYER_QUIT.subscribe {
|
||||
PCLinkManager.removeLink(it.uuid)
|
||||
BattleRegistry.getBattleByParticipatingPlayer(it)?.stop()
|
||||
PlatformEvents.SERVER_PLAYER_LOGOUT.subscribe {
|
||||
PCLinkManager.removeLink(it.player.uuid)
|
||||
BattleRegistry.getBattleByParticipatingPlayer(it.player)?.stop()
|
||||
storage.onPlayerDisconnect(it.player)
|
||||
playerData.onPlayerDisconnect(it.player)
|
||||
TradeManager.onLogoff(it.player)
|
||||
}
|
||||
LIVING_DEATH.pipe(filter { it is ServerPlayerEntity }, map { it as ServerPlayerEntity }).subscribe {
|
||||
PCLinkManager.removeLink(it.uuid)
|
||||
battleRegistry.getBattleByParticipatingPlayer(it)?.stop()
|
||||
PlatformEvents.PLAYER_DEATH.subscribe {
|
||||
PCLinkManager.removeLink(it.player.uuid)
|
||||
battleRegistry.getBattleByParticipatingPlayer(it.player)?.stop()
|
||||
}
|
||||
|
||||
InteractionEvent.INTERACT_ENTITY.register(InteractionEvent.InteractEntity { player, entity, hand ->
|
||||
if (player.getStackInHand(hand).item is NameTagItem && entity.type.isIn(CobblemonEntityTypeTags.CANNOT_HAVE_NAME_TAG))
|
||||
EventResult.interruptTrue()
|
||||
else
|
||||
EventResult.pass()
|
||||
})
|
||||
InteractionEvent.RIGHT_CLICK_BLOCK.register(InteractionEvent.RightClickBlock { pl, _, pos, _ ->
|
||||
val player = pl as? ServerPlayerEntity ?: return@RightClickBlock EventResult.pass()
|
||||
val block = player.world.getBlockState(pos).block
|
||||
PlatformEvents.RIGHT_CLICK_ENTITY.subscribe { event ->
|
||||
if (event.player.getStackInHand(event.hand).item is NameTagItem && event.entity.type.isIn(CobblemonEntityTypeTags.CANNOT_HAVE_NAME_TAG)) {
|
||||
event.cancel()
|
||||
}
|
||||
}
|
||||
PlatformEvents.RIGHT_CLICK_BLOCK.subscribe { event ->
|
||||
val player = event.player
|
||||
val block = player.world.getBlockState(event.pos).block
|
||||
player.party().forEach { pokemon ->
|
||||
pokemon.evolutions
|
||||
.filterIsInstance<BlockClickEvolution>()
|
||||
@@ -211,12 +222,11 @@ object Cobblemon {
|
||||
evolution.attemptEvolution(pokemon, BlockClickEvolution.BlockInteractionContext(block, player.world))
|
||||
}
|
||||
}
|
||||
return@RightClickBlock EventResult.pass()
|
||||
})
|
||||
}
|
||||
|
||||
PlayerEvent.CHANGE_DIMENSION.register(PlayerEvent.ChangeDimension{ player, _, _ ->
|
||||
player.party().forEach { pokemon -> pokemon.entity?.recallWithAnimation() }
|
||||
})
|
||||
PlatformEvents.CHANGE_DIMENSION.subscribe {
|
||||
it.player.party().forEach { pokemon -> pokemon.entity?.recallWithAnimation() }
|
||||
}
|
||||
|
||||
TrackedDataHandlerRegistry.register(Vec3DataSerializer)
|
||||
TrackedDataHandlerRegistry.register(StringSetDataSerializer)
|
||||
@@ -228,13 +238,6 @@ object Cobblemon {
|
||||
fun initialize() {
|
||||
showdownThread.launch()
|
||||
|
||||
CompletableRegistry.allRegistriesCompleted.thenAccept {
|
||||
LOGGER.info("All registries loaded.")
|
||||
}
|
||||
|
||||
CobblemonPlacementTypes.register()
|
||||
CobblemonOrePlacedFeatures.register()
|
||||
|
||||
// Start up the data provider.
|
||||
CobblemonDataProvider.registerDefaults()
|
||||
|
||||
@@ -251,51 +254,79 @@ object Cobblemon {
|
||||
DataKeys.HAS_BEEN_SHEARED,
|
||||
FlagSpeciesFeatureProvider(keys = listOf(DataKeys.HAS_BEEN_SHEARED), default = false))
|
||||
|
||||
CustomPokemonProperty.register(UntradeableProperty)
|
||||
CustomPokemonProperty.register(UncatchableProperty)
|
||||
CustomPokemonProperty.register(PokemonFlagProperty)
|
||||
CustomPokemonProperty.register(HiddenAbilityPropertyType)
|
||||
|
||||
CommandRegistrationEvent.EVENT.register(CobblemonCommands::register)
|
||||
|
||||
ifDedicatedServer {
|
||||
isDedicatedServer = true
|
||||
TICK_POST.subscribe { ScheduledTaskTracker.update() }
|
||||
CobblemonNetwork.clientHandlersRegistered.complete(Unit)
|
||||
PlatformEvents.SERVER_TICK_POST.subscribe { ScheduledTaskTracker.update() }
|
||||
}
|
||||
|
||||
CobblemonBlocks.completed.thenAccept {
|
||||
AxeItemHooks.addStrippable(CobblemonBlocks.APRICORN_LOG.get(), CobblemonBlocks.STRIPPED_APRICORN_LOG.get())
|
||||
AxeItemHooks.addStrippable(CobblemonBlocks.APRICORN_WOOD.get(), CobblemonBlocks.STRIPPED_APRICORN_WOOD.get())
|
||||
}
|
||||
|
||||
SERVER_STARTED.subscribe { server ->
|
||||
PlatformEvents.SERVER_STARTING.subscribe { event ->
|
||||
val server = event.server
|
||||
playerData = PlayerDataStoreManager().also { it.setup(server) }
|
||||
|
||||
val mongoClient: MongoClient?
|
||||
|
||||
val pokemonStoreRoot = server.getSavePath(WorldSavePath.ROOT).resolve("pokemon").toFile()
|
||||
val storeAdapter = when (config.storageFormat) {
|
||||
"nbt", "json" -> {
|
||||
val jsonFactory = JsonPlayerDataStoreFactory()
|
||||
jsonFactory.setup(server)
|
||||
playerData.setFactory(jsonFactory)
|
||||
|
||||
if (config.storageFormat == "nbt") {
|
||||
NBTStoreAdapter(pokemonStoreRoot.absolutePath, useNestedFolders = true, folderPerClass = true)
|
||||
} else {
|
||||
JSONStoreAdapter(
|
||||
pokemonStoreRoot.absolutePath,
|
||||
useNestedFolders = true,
|
||||
folderPerClass = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
"mongodb" -> {
|
||||
try {
|
||||
Class.forName("com.mongodb.client.MongoClient")
|
||||
|
||||
val mongoClientSettings = MongoClientSettings.builder()
|
||||
.applyConnectionString(ConnectionString(config.mongoDBConnectionString))
|
||||
.build()
|
||||
mongoClient = MongoClients.create(mongoClientSettings)
|
||||
val mongoFactory = MongoPlayerDataStoreFactory(mongoClient, config.mongoDBDatabaseName)
|
||||
playerData.setFactory(mongoFactory)
|
||||
MongoDBStoreAdapter(mongoClient, config.mongoDBDatabaseName)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
LOGGER.error("MongoDB driver not found.")
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
else -> throw IllegalArgumentException("Unsupported storageFormat: ${config.storageFormat}")
|
||||
}
|
||||
.with(ReforgedConversion(server.getSavePath(WorldSavePath.ROOT))) as FileStoreAdapter<*>
|
||||
|
||||
storage.registerFactory(
|
||||
priority = Priority.LOWEST,
|
||||
factory = FileBackedPokemonStoreFactory(
|
||||
adapter = if (config.storageFormat == "nbt") {
|
||||
NBTStoreAdapter(pokemonStoreRoot.absolutePath, useNestedFolders = true, folderPerClass = true)
|
||||
} else {
|
||||
JSONStoreAdapter(pokemonStoreRoot.absolutePath, useNestedFolders = true, folderPerClass = true)
|
||||
}.with(ReforgedConversion(server.getSavePath(WorldSavePath.ROOT))) as FileStoreAdapter<*>,
|
||||
adapter = storeAdapter,
|
||||
createIfMissing = true,
|
||||
pcConstructor = { uuid -> PCStore(uuid).also { it.resize(config.defaultBoxCount) } }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
SERVER_STOPPED.subscribe {
|
||||
PlatformEvents.SERVER_STOPPED.subscribe {
|
||||
storage.unregisterAll()
|
||||
playerData.saveAll()
|
||||
}
|
||||
SERVER_STARTED.subscribe {
|
||||
PlatformEvents.SERVER_STARTED.subscribe {
|
||||
bestSpawner.onServerStarted()
|
||||
battleRegistry.onServerStarted()
|
||||
}
|
||||
TICK_POST.subscribe { ServerTickHandler.onTick(it) }
|
||||
PlatformEvents.SERVER_TICK_POST.subscribe { ServerTickHandler.onTick(it.server) }
|
||||
POKEMON_CAPTURED.subscribe { AdvancementHandler.onCapture(it) }
|
||||
// EGG_HATCH.subscribe { AdvancementHandler.onHatch(it) }
|
||||
BATTLE_VICTORY.subscribe { AdvancementHandler.onWinBattle(it) }
|
||||
@@ -306,18 +337,36 @@ object Cobblemon {
|
||||
// Ensure the config option is enabled and that the result was a ninjask and that shedinja exists
|
||||
if (this.config.ninjaskCreatesShedinja && pokemon.species.resourceIdentifier == ninjaskIdentifier && PokemonSpecies.getByIdentifier(Pokemon.SHEDINJA) != null) {
|
||||
val player = pokemon.getOwnerPlayer() ?: return@subscribe
|
||||
if (player.inventory.containsAny { it.item is PokeBallItem }) {
|
||||
player.inventory.removeAmountIf(1) { it.item is PokeBallItem }
|
||||
if (player.isCreative || player.inventory.containsAny { it.item is PokeBallItem }) {
|
||||
var pokeball = Items.AIR
|
||||
player.inventory.combinedInventory.forEach {
|
||||
it.forEach {
|
||||
itemStack -> if (itemStack.item is PokeBallItem && pokeball == Items.AIR) {
|
||||
pokeball = itemStack.item as PokeBallItem
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!player.isCreative) {
|
||||
player.inventory.removeAmountIf(1) { it.item is PokeBallItem }
|
||||
}
|
||||
if (pokeball == Items.AIR) {
|
||||
pokeball = CobblemonItems.POKE_BALL
|
||||
}
|
||||
val properties = event.evolution.result.copy()
|
||||
properties.species = Pokemon.SHEDINJA.toString()
|
||||
val product = pokemon.clone()
|
||||
product.removeHeldItem()
|
||||
properties.apply(product)
|
||||
product.caughtBall = (pokeball as PokeBallItem).pokeBall
|
||||
pokemon.storeCoordinates.get()?.store?.add(product)
|
||||
CobblemonCriteria.EVOLVE_POKEMON.trigger(player, EvolvePokemonContext(event.pokemon.preEvolution!!.species.resourceIdentifier, product.species.resourceIdentifier, playerData.get(player).advancementData.totalEvolvedCount))
|
||||
}
|
||||
}
|
||||
}
|
||||
LEVEL_UP_EVENT.subscribe { AdvancementHandler.onLevelUp(it) }
|
||||
TRADE_COMPLETED.subscribe { AdvancementHandler.onTradeCompleted(it) }
|
||||
|
||||
PokemonSpecies.observable.subscribe {
|
||||
BagItems.observable.subscribe {
|
||||
LOGGER.info("Starting dummy Showdown battle to force it to pre-load data.")
|
||||
battleRegistry.startBattle(
|
||||
BattleFormat.GEN_9_SINGLES,
|
||||
@@ -329,7 +378,7 @@ object Cobblemon {
|
||||
|
||||
fun getLevel(dimension: RegistryKey<World>): World? {
|
||||
return if (isDedicatedServer) {
|
||||
getServer()?.getWorld(dimension)
|
||||
server()?.getWorld(dimension)
|
||||
} else {
|
||||
val mc = MinecraftClient.getInstance()
|
||||
return mc.server?.getWorld(dimension) ?: mc.world
|
||||
@@ -420,4 +469,14 @@ object Cobblemon {
|
||||
exception.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerArgumentTypes() {
|
||||
this.implementation.registerCommandArgument(cobblemonResource("pokemon"), PokemonArgumentType::class, ConstantArgumentSerializer.of(PokemonArgumentType::pokemon))
|
||||
this.implementation.registerCommandArgument(cobblemonResource("pokemon_properties"), PokemonPropertiesArgumentType::class, ConstantArgumentSerializer.of(PokemonPropertiesArgumentType::properties))
|
||||
this.implementation.registerCommandArgument(cobblemonResource("spawn_bucket"), SpawnBucketArgumentType::class, ConstantArgumentSerializer.of(SpawnBucketArgumentType::spawnBucket))
|
||||
this.implementation.registerCommandArgument(cobblemonResource("move"), MoveArgumentType::class, ConstantArgumentSerializer.of(MoveArgumentType::move))
|
||||
this.implementation.registerCommandArgument(cobblemonResource("party_slot"), PartySlotArgumentType::class, ConstantArgumentSerializer.of(PartySlotArgumentType::partySlot))
|
||||
this.implementation.registerCommandArgument(cobblemonResource("pokemon_store"), PokemonStoreArgumentType::class, ConstantArgumentSerializer.of(PokemonStoreArgumentType::pokemonStore))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,31 +8,28 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.registry.CompletableRegistry
|
||||
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.HealingMachineBlockEntity
|
||||
import com.cobblemon.mod.common.block.entity.PCBlockEntity
|
||||
import dev.architectury.registry.registries.RegistrySupplier
|
||||
import java.util.function.Supplier
|
||||
import com.cobblemon.mod.common.block.entity.PokemonPastureBlockEntity
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import net.minecraft.block.entity.BlockEntityType
|
||||
import net.minecraft.util.registry.Registry
|
||||
import net.minecraft.registry.Registries
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
|
||||
object CobblemonBlockEntities : CompletableRegistry<BlockEntityType<*>>(Registry.BLOCK_ENTITY_TYPE_KEY) {
|
||||
private fun <T : BlockEntityType<*>> register(name: String, blockEntityType: Supplier<T>) : RegistrySupplier<T> {
|
||||
return queue(name, blockEntityType)
|
||||
}
|
||||
object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, RegistryKey<Registry<BlockEntityType<*>>>, BlockEntityType<*>>() {
|
||||
|
||||
override val registry: Registry<BlockEntityType<*>> = Registries.BLOCK_ENTITY_TYPE
|
||||
override val registryKey: RegistryKey<Registry<BlockEntityType<*>>> = RegistryKeys.BLOCK_ENTITY_TYPE
|
||||
|
||||
@JvmField
|
||||
val HEALING_MACHINE = com.cobblemon.mod.common.CobblemonBlockEntities.register("healing_machine") {
|
||||
BlockEntityType.Builder.create(
|
||||
::HealingMachineBlockEntity,
|
||||
CobblemonBlocks.HEALING_MACHINE.get()
|
||||
).build(null)
|
||||
}
|
||||
val HEALING_MACHINE: BlockEntityType<HealingMachineBlockEntity> = this.create("healing_machine", BlockEntityType.Builder.create(::HealingMachineBlockEntity, CobblemonBlocks.HEALING_MACHINE).build(null))
|
||||
@JvmField
|
||||
val PC = com.cobblemon.mod.common.CobblemonBlockEntities.register("pc") {
|
||||
BlockEntityType.Builder.create(
|
||||
::PCBlockEntity,
|
||||
CobblemonBlocks.PC.get()
|
||||
).build(null)
|
||||
}
|
||||
val PC: BlockEntityType<PCBlockEntity> = this.create("pc", BlockEntityType.Builder.create(::PCBlockEntity, CobblemonBlocks.PC).build(null))
|
||||
val BERRY = this.create("berry", BlockEntityType.Builder.create(::BerryBlockEntity, *CobblemonBlocks.berries().values.toTypedArray()).build(null))
|
||||
@JvmField
|
||||
val PASTURE: BlockEntityType<PokemonPastureBlockEntity> = this.create("pasture", BlockEntityType.Builder.create(::PokemonPastureBlockEntity, CobblemonBlocks.PASTURE).build(null))
|
||||
|
||||
}
|
||||
@@ -9,50 +9,61 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.api.apricorn.Apricorn
|
||||
import com.cobblemon.mod.common.registry.CompletableRegistry
|
||||
import com.cobblemon.mod.common.block.ApricornBlock
|
||||
import com.cobblemon.mod.common.block.ApricornSaplingBlock
|
||||
import com.cobblemon.mod.common.block.HealingMachineBlock
|
||||
import com.cobblemon.mod.common.block.PCBlock
|
||||
import dev.architectury.registry.registries.RegistrySupplier
|
||||
import com.cobblemon.mod.common.block.*
|
||||
import com.cobblemon.mod.common.block.MintBlock.MintType
|
||||
import com.cobblemon.mod.common.mixin.invoker.DoorBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.PressurePlateBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.StairsBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.TrapdoorBlockInvoker
|
||||
import com.cobblemon.mod.common.mixin.invoker.*
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.block.BerryBlock
|
||||
import net.minecraft.block.*
|
||||
import net.minecraft.entity.EntityType
|
||||
import net.minecraft.block.piston.PistonBehavior
|
||||
import net.minecraft.entity.effect.StatusEffects
|
||||
import net.minecraft.registry.Registries
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
import net.minecraft.sound.BlockSoundGroup
|
||||
import net.minecraft.util.math.Direction
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.intprovider.UniformIntProvider
|
||||
import net.minecraft.util.registry.Registry
|
||||
import java.util.function.ToIntFunction
|
||||
|
||||
object CobblemonBlocks : CompletableRegistry<Block>(Registry.BLOCK_KEY) {
|
||||
/**
|
||||
* Evolution Ores
|
||||
*/
|
||||
@JvmField
|
||||
val DAWN_STONE_ORE = this.evolutionStoneOre("dawn_stone_ore")
|
||||
@JvmField
|
||||
val DUSK_STONE_ORE = this.evolutionStoneOre("dusk_stone_ore")
|
||||
@JvmField
|
||||
val FIRE_STONE_ORE = this.evolutionStoneOre("fire_stone_ore")
|
||||
@JvmField
|
||||
val ICE_STONE_ORE = this.evolutionStoneOre("ice_stone_ore")
|
||||
@JvmField
|
||||
val LEAF_STONE_ORE = this.evolutionStoneOre("leaf_stone_ore")
|
||||
@JvmField
|
||||
val MOON_STONE_ORE = this.evolutionStoneOre("moon_stone_ore")
|
||||
@JvmField
|
||||
val DRIPSTONE_MOON_STONE_ORE = this.evolutionStoneOre("dripstone_moon_stone_ore")
|
||||
@JvmField
|
||||
val SHINY_STONE_ORE = this.evolutionStoneOre("shiny_stone_ore")
|
||||
@JvmField
|
||||
val SUN_STONE_ORE = this.evolutionStoneOre("sun_stone_ore")
|
||||
@JvmField
|
||||
val THUNDER_STONE_ORE = this.evolutionStoneOre("thunder_stone_ore")
|
||||
@JvmField
|
||||
val WATER_STONE_ORE = this.evolutionStoneOre("water_stone_ore")
|
||||
@Suppress("SameParameterValue", "HasPlatformType", "MemberVisibilityCanBePrivate", "unused")
|
||||
object CobblemonBlocks : PlatformRegistry<Registry<Block>, RegistryKey<Registry<Block>>, Block>() {
|
||||
|
||||
/**
|
||||
* Deepslate separator
|
||||
*/
|
||||
|
||||
|
||||
override val registry: Registry<Block> = Registries.BLOCK
|
||||
override val registryKey: RegistryKey<Registry<Block>> = RegistryKeys.BLOCK
|
||||
|
||||
val APRICORN_BLOCK_SET_TYPE = BlockSetType("apricorn")
|
||||
val APRICORN_WOOD_TYPE = WoodType.register(WoodType("apricorn", APRICORN_BLOCK_SET_TYPE))
|
||||
|
||||
// Evolution Ores
|
||||
@JvmField
|
||||
val DAWN_STONE_ORE = evolutionStoneOre("dawn_stone_ore")
|
||||
@JvmField
|
||||
val DUSK_STONE_ORE = evolutionStoneOre("dusk_stone_ore")
|
||||
@JvmField
|
||||
val FIRE_STONE_ORE = evolutionStoneOre("fire_stone_ore")
|
||||
@JvmField
|
||||
val ICE_STONE_ORE = evolutionStoneOre("ice_stone_ore")
|
||||
@JvmField
|
||||
val LEAF_STONE_ORE = evolutionStoneOre("leaf_stone_ore")
|
||||
@JvmField
|
||||
val MOON_STONE_ORE = evolutionStoneOre("moon_stone_ore")
|
||||
@JvmField
|
||||
val DRIPSTONE_MOON_STONE_ORE = evolutionStoneOre("dripstone_moon_stone_ore")
|
||||
@JvmField
|
||||
val SHINY_STONE_ORE = evolutionStoneOre("shiny_stone_ore")
|
||||
@JvmField
|
||||
val SUN_STONE_ORE = evolutionStoneOre("sun_stone_ore")
|
||||
@JvmField
|
||||
val THUNDER_STONE_ORE = evolutionStoneOre("thunder_stone_ore")
|
||||
@JvmField
|
||||
val WATER_STONE_ORE = evolutionStoneOre("water_stone_ore")
|
||||
|
||||
@JvmField
|
||||
val DEEPSLATE_DAWN_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_dawn_stone_ore")
|
||||
@@ -75,130 +86,287 @@ object CobblemonBlocks : CompletableRegistry<Block>(Registry.BLOCK_KEY) {
|
||||
@JvmField
|
||||
val DEEPSLATE_WATER_STONE_ORE = this.deepslateEvolutionStoneOre("deepslate_water_stone_ore")
|
||||
|
||||
/**
|
||||
* Apricorns
|
||||
*/
|
||||
|
||||
// Apricorns
|
||||
@JvmField
|
||||
val APRICORN_LOG = queue("apricorn_log") {
|
||||
log(
|
||||
MapColor.DIRT_BROWN,
|
||||
MapColor.BROWN
|
||||
)
|
||||
}
|
||||
val APRICORN_LOG = log("apricorn_log", arg2 = MapColor.BROWN)
|
||||
@JvmField
|
||||
val STRIPPED_APRICORN_LOG = queue("stripped_apricorn_log") {
|
||||
log(
|
||||
MapColor.DIRT_BROWN,
|
||||
MapColor.DIRT_BROWN
|
||||
)
|
||||
}
|
||||
val STRIPPED_APRICORN_LOG = log("stripped_apricorn_log")
|
||||
@JvmField
|
||||
val APRICORN_WOOD = queue("apricorn_wood") {
|
||||
log(
|
||||
MapColor.DIRT_BROWN,
|
||||
MapColor.DIRT_BROWN
|
||||
)
|
||||
}
|
||||
val APRICORN_WOOD = log("apricorn_wood")
|
||||
@JvmField
|
||||
val STRIPPED_APRICORN_WOOD = queue("stripped_apricorn_wood") {
|
||||
log(
|
||||
MapColor.DIRT_BROWN,
|
||||
MapColor.DIRT_BROWN
|
||||
)
|
||||
}
|
||||
val STRIPPED_APRICORN_WOOD = log("stripped_apricorn_wood")
|
||||
@JvmField
|
||||
val APRICORN_PLANKS = queue("apricorn_planks") { Block(AbstractBlock.Settings.of(Material.WOOD, MapColor.DIRT_BROWN).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)) }
|
||||
val APRICORN_PLANKS = this.create("apricorn_planks", Block(AbstractBlock.Settings.create().mapColor(MapColor.DIRT_BROWN).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
|
||||
@JvmField
|
||||
val APRICORN_LEAVES = queue("apricorn_leaves") { com.cobblemon.mod.common.CobblemonBlocks.leaves(BlockSoundGroup.GRASS) }
|
||||
val APRICORN_LEAVES = leaves("apricorn_leaves")
|
||||
@JvmField
|
||||
val APRICORN_FENCE = queue("apricorn_fence") { FenceBlock(AbstractBlock.Settings.of(Material.WOOD, APRICORN_PLANKS.get().defaultMapColor).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)) }
|
||||
val APRICORN_FENCE = this.create("apricorn_fence", FenceBlock(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
|
||||
@JvmField
|
||||
val APRICORN_FENCE_GATE = queue("apricorn_fence_gate") { FenceGateBlock(AbstractBlock.Settings.of(Material.WOOD, APRICORN_PLANKS.get().defaultMapColor).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)) }
|
||||
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD), APRICORN_WOOD_TYPE))
|
||||
@JvmField // Note At the time of 1.20.0 we don't need our own BlockSetType for Apricorn wood
|
||||
val APRICORN_BUTTON = this.create("apricorn_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
|
||||
@JvmField
|
||||
val APRICORN_BUTTON = queue("apricorn_button") { WoodenButtonBlock(AbstractBlock.Settings.of(Material.DECORATION).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD)) }
|
||||
@JvmField
|
||||
val APRICORN_PRESSURE_PLATE = queue("apricorn_pressure_plate") { PressurePlateBlock(PressurePlateBlock.ActivationRule.EVERYTHING, AbstractBlock.Settings.of(Material.WOOD, APRICORN_PLANKS.get().defaultMapColor).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD)) }
|
||||
val APRICORN_PRESSURE_PLATE = this.create("apricorn_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(PressurePlateBlock.ActivationRule.EVERYTHING, AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).noCollision().strength(0.5f).sounds(BlockSoundGroup.WOOD), APRICORN_BLOCK_SET_TYPE))
|
||||
// Tag was removed be sure to add it back when implemented
|
||||
// @JvmField
|
||||
// val APRICORN_SIGN = queue("apricorn_sign") { StandingSignBlock(AbstractBlock.Settings.of(Material.WOOD).noCollission().strength(1.0f).sounds(BlockSoundGroup.WOOD), APRICORN_WOOD_TYPE) }
|
||||
//@JvmField
|
||||
// val APRICORN_WALL_SIGN = queue("apricorn_wall_sign") { WallSignBlock(AbstractBlock.Settings.of(Material.WOOD).noCollission().strength(1.0f).sounds(BlockSoundGroup.WOOD).dropsLike(APRICORN_SIGN), APRICORN_WOOD_TYPE) }
|
||||
//val APRICORN_SIGN = queue("apricorn_sign") { StandingSignBlock(AbstractBlock.Settings.of(Material.WOOD).noCollission().strength(1.0f).sounds(BlockSoundGroup.WOOD), APRICORN_WOOD_TYPE) }
|
||||
//val APRICORN_WALL_SIGN = queue("apricorn_wall_sign") { WallSignBlock(AbstractBlock.Settings.of(Material.WOOD).noCollission().strength(1.0f).sounds(BlockSoundGroup.WOOD).dropsLike(APRICORN_SIGN), APRICORN_WOOD_TYPE) }
|
||||
@JvmField
|
||||
val APRICORN_SLAB = queue("apricorn_slab") { SlabBlock(AbstractBlock.Settings.of(Material.WOOD, MapColor.OAK_TAN).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)) }
|
||||
val APRICORN_SLAB = this.create("apricorn_slab", SlabBlock(AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).strength(2.0f, 3.0f).sounds(BlockSoundGroup.WOOD)))
|
||||
@JvmField
|
||||
val APRICORN_STAIRS = queue("apricorn_stairs") { StairsBlock(
|
||||
APRICORN_PLANKS.get().defaultState, AbstractBlock.Settings.copy(
|
||||
APRICORN_PLANKS.get())) }
|
||||
val APRICORN_STAIRS = this.create("apricorn_stairs", StairsBlockInvoker.`cobblemon$create`(APRICORN_PLANKS.defaultState, AbstractBlock.Settings.copy(APRICORN_PLANKS)))
|
||||
@JvmField
|
||||
val APRICORN_DOOR = queue("apricorn_door") { DoorBlock(AbstractBlock.Settings.of(Material.WOOD, APRICORN_PLANKS.get().defaultMapColor).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque()) }
|
||||
val APRICORN_DOOR = this.create("apricorn_door", DoorBlockInvoker.`cobblemon$create`(AbstractBlock.Settings.create().mapColor(APRICORN_PLANKS.defaultMapColor).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque(), APRICORN_BLOCK_SET_TYPE))
|
||||
@JvmField
|
||||
val APRICORN_TRAPDOOR = queue("apricorn_trapdoor") { TrapdoorBlock(AbstractBlock.Settings.of(Material.WOOD, MapColor.OAK_TAN).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque().allowsSpawning { _, _, _, _ -> false }) }
|
||||
val APRICORN_TRAPDOOR = this.create("apricorn_trapdoor", TrapdoorBlockInvoker.`cobblemon$create`(AbstractBlock.Settings.create().mapColor(MapColor.OAK_TAN).strength(3.0F).sounds(BlockSoundGroup.WOOD).nonOpaque().allowsSpawning { _, _, _, _ -> false }, APRICORN_BLOCK_SET_TYPE))
|
||||
|
||||
private val PLANT_PROPERTIES = AbstractBlock.Settings.of(Material.PLANT).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.GRASS)
|
||||
private val PLANT_PROPERTIES = AbstractBlock.Settings.create().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.GRASS).pistonBehavior(PistonBehavior.DESTROY)
|
||||
@JvmField
|
||||
val BLACK_APRICORN_SAPLING = queue("black_apricorn_sapling") { ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.BLACK) }
|
||||
val BLACK_APRICORN_SAPLING = this.create("black_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.BLACK))
|
||||
@JvmField
|
||||
val BLUE_APRICORN_SAPLING = queue("blue_apricorn_sapling") { ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.BLUE) }
|
||||
val BLUE_APRICORN_SAPLING = this.create("blue_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.BLUE))
|
||||
@JvmField
|
||||
val GREEN_APRICORN_SAPLING = queue("green_apricorn_sapling") { ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.GREEN) }
|
||||
val GREEN_APRICORN_SAPLING = this.create("green_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.GREEN))
|
||||
@JvmField
|
||||
val PINK_APRICORN_SAPLING = queue("pink_apricorn_sapling") { ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.PINK) }
|
||||
val PINK_APRICORN_SAPLING = this.create("pink_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.PINK))
|
||||
@JvmField
|
||||
val RED_APRICORN_SAPLING = queue("red_apricorn_sapling") { ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.RED) }
|
||||
val RED_APRICORN_SAPLING = this.create("red_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.RED))
|
||||
@JvmField
|
||||
val WHITE_APRICORN_SAPLING = queue("white_apricorn_sapling") { ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.WHITE) }
|
||||
val WHITE_APRICORN_SAPLING = this.create("white_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.WHITE))
|
||||
@JvmField
|
||||
val YELLOW_APRICORN_SAPLING = queue("yellow_apricorn_sapling") { ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.YELLOW) }
|
||||
val YELLOW_APRICORN_SAPLING = this.create("yellow_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.YELLOW))
|
||||
|
||||
@JvmField
|
||||
val BLACK_APRICORN = registerApricornBlock("black_apricorn", Apricorn.BLACK)
|
||||
val MEDICINAL_LEEK = this.create("medicinal_leek", MedicinalLeekBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DULL_RED).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val BLUE_APRICORN = registerApricornBlock("blue_apricorn", Apricorn.BLUE)
|
||||
val ENERGY_ROOT = this.create("energy_root", EnergyRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DIRT_BROWN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.ROOTS)))
|
||||
@JvmField
|
||||
val GREEN_APRICORN = registerApricornBlock("green_apricorn", Apricorn.GREEN)
|
||||
val BIG_ROOT = this.create("big_root", BigRootBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.ROOTS)))
|
||||
@JvmField
|
||||
val PINK_APRICORN = registerApricornBlock("pink_apricorn", Apricorn.PINK)
|
||||
@JvmField
|
||||
val RED_APRICORN = registerApricornBlock("red_apricorn", Apricorn.RED)
|
||||
@JvmField
|
||||
val WHITE_APRICORN = registerApricornBlock("white_apricorn", Apricorn.WHITE)
|
||||
@JvmField
|
||||
val YELLOW_APRICORN = registerApricornBlock("yellow_apricorn", Apricorn.YELLOW)
|
||||
val REVIVAL_HERB = this.create("revival_herb", RevivalHerbBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).mapColor(MapColor.DARK_GREEN).burnable().noCollision().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
|
||||
@JvmField
|
||||
val HEALING_MACHINE = queue("healing_machine") { HealingMachineBlock(AbstractBlock.Settings.of(Material.METAL, MapColor.IRON_GRAY).sounds(BlockSoundGroup.METAL).strength(2f).nonOpaque().luminance(ToIntFunction { state: BlockState -> if (state.get(HealingMachineBlock.CHARGE_LEVEL) >= HealingMachineBlock.MAX_CHARGE_LEVEL) 7 else 2 })) }
|
||||
val BLACK_APRICORN = apricornBlock("black_apricorn", Apricorn.BLACK)
|
||||
@JvmField
|
||||
val PC = queue("pc") { PCBlock(AbstractBlock.Settings.of(Material.METAL, MapColor.IRON_GRAY).sounds(BlockSoundGroup.METAL).strength(2F).nonOpaque().luminance(ToIntFunction { state: BlockState -> if ((state.get(
|
||||
PCBlock.ON) as Boolean) && (state.get(PCBlock.PART) == PCBlock.PCPart.TOP)) 10 else 0 })) }
|
||||
val BLUE_APRICORN = apricornBlock("blue_apricorn", Apricorn.BLUE)
|
||||
@JvmField
|
||||
val GREEN_APRICORN = apricornBlock("green_apricorn", Apricorn.GREEN)
|
||||
@JvmField
|
||||
val PINK_APRICORN = apricornBlock("pink_apricorn", Apricorn.PINK)
|
||||
@JvmField
|
||||
val RED_APRICORN = apricornBlock("red_apricorn", Apricorn.RED)
|
||||
@JvmField
|
||||
val WHITE_APRICORN = apricornBlock("white_apricorn", Apricorn.WHITE)
|
||||
@JvmField
|
||||
val YELLOW_APRICORN = apricornBlock("yellow_apricorn", Apricorn.YELLOW)
|
||||
|
||||
private fun registerApricornBlock(id: String, apricorn: Apricorn): RegistrySupplier<ApricornBlock> {
|
||||
return queue(id) { ApricornBlock(AbstractBlock.Settings.of(Material.PLANT, apricorn.mapColor()).ticksRandomly().strength(Blocks.OAK_LOG.hardness, Blocks.OAK_LOG.blastResistance).sounds(BlockSoundGroup.WOOD).nonOpaque(), apricorn) }
|
||||
@JvmField
|
||||
val HEALING_MACHINE = create(
|
||||
"healing_machine",
|
||||
HealingMachineBlock(
|
||||
AbstractBlock.Settings.create()
|
||||
.mapColor(MapColor.IRON_GRAY)
|
||||
.sounds(BlockSoundGroup.METAL)
|
||||
.pistonBehavior(PistonBehavior.BLOCK)
|
||||
.strength(2f)
|
||||
.nonOpaque()
|
||||
.luminance { if (it.get(HealingMachineBlock.CHARGE_LEVEL) >= HealingMachineBlock.MAX_CHARGE_LEVEL) 7 else 2 }
|
||||
)
|
||||
)
|
||||
@JvmField
|
||||
val PC = create(
|
||||
"pc",
|
||||
PCBlock(
|
||||
AbstractBlock.Settings.create()
|
||||
.mapColor(MapColor.IRON_GRAY)
|
||||
.sounds(BlockSoundGroup.METAL)
|
||||
.pistonBehavior(PistonBehavior.BLOCK)
|
||||
.strength(2F)
|
||||
.nonOpaque()
|
||||
.luminance { if ((it.get(PCBlock.ON) as Boolean) && (it.get(PCBlock.PART) == PCBlock.PCPart.TOP)) 10 else 0 }
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val RED_MINT = create("red_mint", MintBlock(MintType.RED, AbstractBlock.Settings.create().mapColor(MapColor.RED).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val BLUE_MINT = create("blue_mint", MintBlock(MintType.BLUE, AbstractBlock.Settings.create().mapColor(MapColor.BLUE).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val CYAN_MINT = create("cyan_mint", MintBlock(MintType.CYAN, AbstractBlock.Settings.create().mapColor(MapColor.CYAN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val PINK_MINT = create("pink_mint", MintBlock(MintType.PINK, AbstractBlock.Settings.create().mapColor(MapColor.PINK).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val GREEN_MINT = create("green_mint", MintBlock(MintType.GREEN, AbstractBlock.Settings.create().mapColor(MapColor.GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val WHITE_MINT = create("white_mint", MintBlock(MintType.WHITE, AbstractBlock.Settings.create().mapColor(MapColor.WHITE).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
|
||||
@JvmField
|
||||
val PASTURE = create(
|
||||
"pasture",
|
||||
PastureBlock(
|
||||
AbstractBlock.Settings.create()
|
||||
.mapColor(MapColor.BROWN)
|
||||
.sounds(BlockSoundGroup.WOOD)
|
||||
.strength(2F)
|
||||
.nonOpaque()
|
||||
.pistonBehavior(PistonBehavior.BLOCK)
|
||||
.luminance { if ((it.get(PastureBlock.ON) as Boolean) && (it.get(PastureBlock.PART) == PastureBlock.PasturePart.TOP)) 10 else 0 }
|
||||
)
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val VIVICHOKE_SEEDS = this.create("vivichoke_seeds", VivichokeBlock(AbstractBlock.Settings.create().pistonBehavior(PistonBehavior.DESTROY).burnable().mapColor(MapColor.DARK_GREEN).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP)))
|
||||
@JvmField
|
||||
val PEP_UP_FLOWER = this.create("pep_up_flower", FlowerBlock(StatusEffects.LEVITATION, 10, AbstractBlock.Settings.create().mapColor(MapColor.DARK_GREEN).noCollision().breakInstantly().sounds(BlockSoundGroup.GRASS).offset(AbstractBlock.OffsetType.XZ).pistonBehavior(PistonBehavior.DESTROY)))
|
||||
@JvmField
|
||||
val POTTED_PEP_UP_FLOWER = this.create("potted_pep_up_flower", BlocksInvoker.createFlowerPotBlock(PEP_UP_FLOWER))
|
||||
|
||||
/**
|
||||
* Returns a map of all the blocks that can be stripped with an axe in the format of input - output.
|
||||
*
|
||||
* @return A map of all the blocks that can be stripped with an axe in the format of input - output.
|
||||
*/
|
||||
fun strippedBlocks(): Map<Block, Block> = mapOf(
|
||||
APRICORN_WOOD to STRIPPED_APRICORN_WOOD,
|
||||
APRICORN_LOG to STRIPPED_APRICORN_LOG
|
||||
)
|
||||
|
||||
|
||||
|
||||
private fun apricornBlock(name: String, apricorn: Apricorn): ApricornBlock = this.create(name, ApricornBlock(AbstractBlock.Settings.create().mapColor(apricorn.mapColor()).ticksRandomly().strength(Blocks.OAK_LOG.hardness, Blocks.OAK_LOG.blastResistance).sounds(BlockSoundGroup.WOOD).nonOpaque(), apricorn))
|
||||
|
||||
private val berries = mutableMapOf<Identifier, BerryBlock>()
|
||||
|
||||
val AGUAV_BERRY = this.berryBlock("aguav")
|
||||
val APICOT_BERRY = this.berryBlock("apicot")
|
||||
val ASPEAR_BERRY = this.berryBlock("aspear")
|
||||
val BABIRI_BERRY = this.berryBlock("babiri")
|
||||
val BELUE_BERRY = this.berryBlock("belue")
|
||||
val BLUK_BERRY = this.berryBlock("bluk")
|
||||
val CHARTI_BERRY = this.berryBlock("charti")
|
||||
val CHERI_BERRY = this.berryBlock("cheri")
|
||||
val CHESTO_BERRY = this.berryBlock("chesto")
|
||||
val CHILAN_BERRY = this.berryBlock("chilan")
|
||||
val CHOPLE_BERRY = this.berryBlock("chople")
|
||||
val COBA_BERRY = this.berryBlock("coba")
|
||||
val COLBUR_BERRY = this.berryBlock("colbur")
|
||||
val CORNN_BERRY = this.berryBlock("cornn")
|
||||
val CUSTAP_BERRY = this.berryBlock("custap")
|
||||
val DURIN_BERRY = this.berryBlock("durin")
|
||||
val ENIGMA_BERRY = this.berryBlock("enigma")
|
||||
val FIGY_BERRY = this.berryBlock("figy")
|
||||
val GANLON_BERRY = this.berryBlock("ganlon")
|
||||
val GREPA_BERRY = this.berryBlock("grepa")
|
||||
val HABAN_BERRY = this.berryBlock("haban")
|
||||
val HONDEW_BERRY = this.berryBlock("hondew")
|
||||
val HOPO_BERRY = this.berryBlock("hopo")
|
||||
val IAPAPA_BERRY = this.berryBlock("iapapa")
|
||||
val JABOCA_BERRY = this.berryBlock("jaboca")
|
||||
val KASIB_BERRY = this.berryBlock("kasib")
|
||||
val KEBIA_BERRY = this.berryBlock("kebia")
|
||||
val KEE_BERRY = this.berryBlock("kee")
|
||||
val KELPSY_BERRY = this.berryBlock("kelpsy")
|
||||
val LANSAT_BERRY = this.berryBlock("lansat")
|
||||
val LEPPA_BERRY = this.berryBlock("leppa")
|
||||
val LIECHI_BERRY = this.berryBlock("liechi")
|
||||
val LUM_BERRY = this.berryBlock("lum")
|
||||
val MAGO_BERRY = this.berryBlock("mago")
|
||||
val MAGOST_BERRY = this.berryBlock("magost")
|
||||
val MARANGA_BERRY = this.berryBlock("maranga")
|
||||
val MICLE_BERRY = this.berryBlock("micle")
|
||||
val NANAB_BERRY = this.berryBlock("nanab")
|
||||
val NOMEL_BERRY = this.berryBlock("nomel")
|
||||
val OCCA_BERRY = this.berryBlock("occa")
|
||||
val ORAN_BERRY = this.berryBlock("oran")
|
||||
val PAMTRE_BERRY = this.berryBlock("pamtre")
|
||||
val PASSHO_BERRY = this.berryBlock("passho")
|
||||
val PAYAPA_BERRY = this.berryBlock("payapa")
|
||||
val PECHA_BERRY = this.berryBlock("pecha")
|
||||
val PERSIM_BERRY = this.berryBlock("persim")
|
||||
val PETAYA_BERRY = this.berryBlock("petaya")
|
||||
val PINAP_BERRY = this.berryBlock("pinap")
|
||||
val POMEG_BERRY = this.berryBlock("pomeg")
|
||||
val QUALOT_BERRY = this.berryBlock("qualot")
|
||||
val RABUTA_BERRY = this.berryBlock("rabuta")
|
||||
val RAWST_BERRY = this.berryBlock("rawst")
|
||||
val RAZZ_BERRY = this.berryBlock("razz")
|
||||
val RINDO_BERRY = this.berryBlock("rindo")
|
||||
val ROSELI_BERRY = this.berryBlock("roseli")
|
||||
val ROWAP_BERRY = this.berryBlock("rowap")
|
||||
val SALAC_BERRY = this.berryBlock("salac")
|
||||
val SHUCA_BERRY = this.berryBlock("shuca")
|
||||
val SITRUS_BERRY = this.berryBlock("sitrus")
|
||||
val SPELON_BERRY = this.berryBlock("spelon")
|
||||
val STARF_BERRY = this.berryBlock("starf")
|
||||
val TAMATO_BERRY = this.berryBlock("tamato")
|
||||
val TANGA_BERRY = this.berryBlock("tanga")
|
||||
val TOUGA_BERRY = this.berryBlock("touga")
|
||||
val WACAN_BERRY = this.berryBlock("wacan")
|
||||
val WATMEL_BERRY = this.berryBlock("watmel")
|
||||
val WEPEAR_BERRY = this.berryBlock("wepear")
|
||||
val WIKI_BERRY = this.berryBlock("wiki")
|
||||
val YACHE_BERRY = this.berryBlock("yache")
|
||||
|
||||
init {
|
||||
/**
|
||||
* Makes all blocks in array flammable by adding them to FireBlock's flammableRegistry.
|
||||
* second value is burn chance and third value is spread chance
|
||||
*/
|
||||
arrayOf(
|
||||
Triple(APRICORN_LOG, 5, 5),
|
||||
Triple(STRIPPED_APRICORN_LOG, 5, 5),
|
||||
Triple(APRICORN_WOOD, 5, 5),
|
||||
Triple(STRIPPED_APRICORN_WOOD, 5, 5),
|
||||
Triple(APRICORN_PLANKS, 5, 20),
|
||||
Triple(APRICORN_LEAVES, 30, 60),
|
||||
Triple(APRICORN_FENCE, 5, 20),
|
||||
Triple(APRICORN_FENCE_GATE, 5, 20),
|
||||
Triple(APRICORN_SLAB, 5, 20),
|
||||
Triple(APRICORN_STAIRS, 5, 20)
|
||||
).onEach{ data -> setFlammable(data.first, data.second, data.third) }
|
||||
}
|
||||
|
||||
fun berries() = this.berries.toMap()
|
||||
|
||||
private fun berryBlock(name: String): BerryBlock {
|
||||
val identifier = cobblemonResource("${name}_berry")
|
||||
val block = this.create(identifier.path, BerryBlock(identifier, AbstractBlock.Settings.copy(Blocks.WHEAT).dynamicBounds().sounds(BlockSoundGroup.CROP).strength(0.2F)))
|
||||
this.berries[identifier] = block
|
||||
return block
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for creating logs
|
||||
* copied over from Vanilla
|
||||
* Calls helper method from Vanilla
|
||||
*/
|
||||
private fun log(arg: MapColor, arg2: MapColor): PillarBlock {
|
||||
return PillarBlock(AbstractBlock.Settings.of(Material.WOOD) { arg3: BlockState ->
|
||||
if (arg3.get(PillarBlock.AXIS) === Direction.Axis.Y) arg else arg2
|
||||
}.strength(2.0f).sounds(BlockSoundGroup.WOOD))
|
||||
private fun log(name: String, arg: MapColor = MapColor.DIRT_BROWN, arg2: MapColor = MapColor.DIRT_BROWN): PillarBlock {
|
||||
val block = BlocksInvoker.createLogBlock(arg, arg2)
|
||||
return this.create(name, block)
|
||||
}
|
||||
|
||||
private fun evolutionStoneOre(name: String) = this.queue(name) { OreBlock(AbstractBlock.Settings.copy(Blocks.IRON_ORE), UniformIntProvider.create(1, 2)) }
|
||||
/**
|
||||
* Method uses generic E in order to keep the block as the same return type.
|
||||
* If E is not a block then it will not be set as flammable.
|
||||
* Calls Vanilla implementation of registering a flammable block.
|
||||
* Mixins looks cursed but it is java's fault.
|
||||
*/
|
||||
private fun <E> setFlammable(block: E, burnChance: Int, spreadChance: Int): E {
|
||||
if(block !is Block) return block
|
||||
|
||||
private fun deepslateEvolutionStoneOre(name: String) = this.queue(name) { OreBlock(AbstractBlock.Settings.copy(Blocks.DEEPSLATE_IRON_ORE), UniformIntProvider.create(1, 2)) }
|
||||
var fireBlock: FireBlock = Blocks.FIRE as FireBlock
|
||||
//Cursed Mixin stuff
|
||||
(fireBlock as FireBlockInvoker).registerNewFlammableBlock(block as Block, burnChance, spreadChance)
|
||||
return block
|
||||
}
|
||||
|
||||
private fun evolutionStoneOre(name: String) = this.create(name, ExperienceDroppingBlock(AbstractBlock.Settings.copy(Blocks.IRON_ORE), UniformIntProvider.create(1, 2)))
|
||||
|
||||
private fun deepslateEvolutionStoneOre(name: String) = this.create(name, ExperienceDroppingBlock(AbstractBlock.Settings.copy(Blocks.DEEPSLATE_IRON_ORE), UniformIntProvider.create(1, 2)))
|
||||
|
||||
/**
|
||||
* Helper method for creating leaves
|
||||
* copied over from Vanilla
|
||||
*/
|
||||
private fun leaves(sound: BlockSoundGroup): LeavesBlock {
|
||||
return LeavesBlock(
|
||||
AbstractBlock.Settings.of(Material.LEAVES).strength(0.2f).ticksRandomly().sounds(sound).nonOpaque()
|
||||
.allowsSpawning { _, _, _, type -> type === EntityType.OCELOT || type === EntityType.PARROT }
|
||||
.suffocates { _, _, _ -> false }
|
||||
.blockVision { _, _, _ -> false })
|
||||
private fun leaves(name: String): LeavesBlock {
|
||||
val block = BlocksInvoker.createLeavesBlock(BlockSoundGroup.GRASS)
|
||||
return this.create(name, block)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,21 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import java.util.function.Supplier
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.entity.BlockEntity
|
||||
import net.minecraft.block.entity.BlockEntityType
|
||||
import net.minecraft.client.color.block.BlockColorProvider
|
||||
import net.minecraft.client.color.item.ItemColorProvider
|
||||
import net.minecraft.client.model.TexturedModelData
|
||||
import net.minecraft.client.particle.ParticleFactory
|
||||
import net.minecraft.client.particle.SpriteProvider
|
||||
import net.minecraft.client.render.RenderLayer
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory
|
||||
import net.minecraft.client.render.entity.model.EntityModelLayer
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.particle.ParticleEffect
|
||||
import net.minecraft.particle.ParticleType
|
||||
import net.minecraft.resource.SynchronousResourceReloader
|
||||
|
||||
interface CobblemonClientImplementation {
|
||||
fun registerLayer(modelLayer: EntityModelLayer, supplier: Supplier<TexturedModelData>)
|
||||
@@ -22,4 +31,12 @@ interface CobblemonClientImplementation {
|
||||
type: ParticleType<T>,
|
||||
factory: (SpriteProvider) -> ParticleFactory<T>
|
||||
)
|
||||
|
||||
fun registerBlockRenderType(layer: RenderLayer, vararg blocks: Block)
|
||||
|
||||
fun registerItemColors(provider: ItemColorProvider, vararg items: Item)
|
||||
|
||||
fun registerBlockColors(provider: BlockColorProvider, vararg blocks: Block)
|
||||
|
||||
fun <T : BlockEntity> registerBlockEntityRenderer(type: BlockEntityType<T>, factory: BlockEntityRendererFactory<T>)
|
||||
}
|
||||
@@ -20,6 +20,7 @@ object CobblemonCommands {
|
||||
GivePokemon.register(dispatcher)
|
||||
TakePokemon.register(dispatcher)
|
||||
ChangeScaleAndSize.register(dispatcher)
|
||||
ChangeWalkSpeed.register(dispatcher)
|
||||
TestCommand.register(dispatcher)
|
||||
ReloadShowdownCommand.register(dispatcher)
|
||||
ClickTextCommand.register(dispatcher)
|
||||
@@ -38,5 +39,12 @@ object CobblemonCommands {
|
||||
PcCommand.register(dispatcher)
|
||||
SpawnPokemonFromPool.register(dispatcher)
|
||||
PokeboxCommand.register(dispatcher)
|
||||
TestStoreCommand.register(dispatcher)
|
||||
QueryLearnsetCommand.register(dispatcher)
|
||||
TestPcSlotCommand.register(dispatcher)
|
||||
TestPartySlotCommand.register(dispatcher)
|
||||
ClearPartyCommand.register(dispatcher)
|
||||
ClearPCCommand.register(dispatcher)
|
||||
PokemonRestartCommand.register(dispatcher)
|
||||
}
|
||||
}
|
||||
@@ -1,41 +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
|
||||
|
||||
import net.minecraft.util.registry.RegistryEntry
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeatures
|
||||
import net.minecraft.world.gen.feature.SingleStateFeatureConfig
|
||||
|
||||
object CobblemonConfiguredFeatures {
|
||||
lateinit var BLACK_APRICORN_TREE: RegistryEntry<ConfiguredFeature<SingleStateFeatureConfig, *>>
|
||||
lateinit var BLUE_APRICORN_TREE: RegistryEntry<ConfiguredFeature<SingleStateFeatureConfig, *>>
|
||||
lateinit var GREEN_APRICORN_TREE: RegistryEntry<ConfiguredFeature<SingleStateFeatureConfig, *>>
|
||||
lateinit var PINK_APRICORN_TREE: RegistryEntry<ConfiguredFeature<SingleStateFeatureConfig, *>>
|
||||
lateinit var RED_APRICORN_TREE: RegistryEntry<ConfiguredFeature<SingleStateFeatureConfig, *>>
|
||||
lateinit var WHITE_APRICORN_TREE: RegistryEntry<ConfiguredFeature<SingleStateFeatureConfig, *>>
|
||||
lateinit var YELLOW_APRICORN_TREE: RegistryEntry<ConfiguredFeature<SingleStateFeatureConfig, *>>
|
||||
|
||||
fun register() {
|
||||
BLACK_APRICORN_TREE = ConfiguredFeatures.register("black_apricorn_tree", CobblemonFeatures.APRICORN_TREE_FEATURE.get(), SingleStateFeatureConfig(
|
||||
CobblemonBlocks.BLACK_APRICORN.get().defaultState))
|
||||
BLUE_APRICORN_TREE = ConfiguredFeatures.register("blue_apricorn_tree", CobblemonFeatures.APRICORN_TREE_FEATURE.get(), SingleStateFeatureConfig(
|
||||
CobblemonBlocks.BLUE_APRICORN.get().defaultState))
|
||||
GREEN_APRICORN_TREE = ConfiguredFeatures.register("green_apricorn_tree", CobblemonFeatures.APRICORN_TREE_FEATURE.get(), SingleStateFeatureConfig(
|
||||
CobblemonBlocks.GREEN_APRICORN.get().defaultState))
|
||||
PINK_APRICORN_TREE = ConfiguredFeatures.register("pink_apricorn_tree", CobblemonFeatures.APRICORN_TREE_FEATURE.get(), SingleStateFeatureConfig(
|
||||
CobblemonBlocks.PINK_APRICORN.get().defaultState))
|
||||
RED_APRICORN_TREE = ConfiguredFeatures.register("red_apricorn_tree", CobblemonFeatures.APRICORN_TREE_FEATURE.get(), SingleStateFeatureConfig(
|
||||
CobblemonBlocks.RED_APRICORN.get().defaultState))
|
||||
WHITE_APRICORN_TREE = ConfiguredFeatures.register("white_apricorn_tree", CobblemonFeatures.APRICORN_TREE_FEATURE.get(), SingleStateFeatureConfig(
|
||||
CobblemonBlocks.WHITE_APRICORN.get().defaultState))
|
||||
YELLOW_APRICORN_TREE = ConfiguredFeatures.register("yellow_apricorn_tree", CobblemonFeatures.APRICORN_TREE_FEATURE.get(), SingleStateFeatureConfig(
|
||||
CobblemonBlocks.YELLOW_APRICORN.get().defaultState))
|
||||
}
|
||||
}
|
||||
@@ -8,66 +8,45 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.entity.EntityAttributeEvent
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.entity.data.CobblemonTrackedDataHandlerRegistry
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.registry.CompletableRegistry
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import dev.architectury.registry.level.entity.EntityAttributeRegistry
|
||||
import dev.architectury.registry.registries.RegistrySupplier
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.entity.EntityType
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.entity.SpawnGroup
|
||||
import net.minecraft.entity.attribute.EntityAttributes
|
||||
import net.minecraft.util.registry.Registry
|
||||
import net.minecraft.entity.attribute.DefaultAttributeContainer
|
||||
import net.minecraft.registry.Registries
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
|
||||
object CobblemonEntities : CompletableRegistry<EntityType<*>>(Registry.ENTITY_TYPE_KEY) {
|
||||
object CobblemonEntities : PlatformRegistry<Registry<EntityType<*>>, RegistryKey<Registry<EntityType<*>>>, EntityType<*>>() {
|
||||
|
||||
override fun register() {
|
||||
super.register()
|
||||
CobblemonTrackedDataHandlerRegistry.register()
|
||||
EntityAttributeRegistry.register(
|
||||
{ POKEMON.get() },
|
||||
{
|
||||
LivingEntity.createLivingAttributes()
|
||||
.add(EntityAttributes.GENERIC_FOLLOW_RANGE)
|
||||
.also { CobblemonEvents.ENTITY_ATTRIBUTE.post(EntityAttributeEvent(POKEMON.get(), it)) }
|
||||
}
|
||||
)
|
||||
}
|
||||
private fun <T : Entity> entity(
|
||||
name: String,
|
||||
entityTypeBuilder: EntityType.Builder<T>
|
||||
): RegistrySupplier<EntityType<T>> {
|
||||
return queue(name) { entityTypeBuilder.build(cobblemonResource(name).toString()) }
|
||||
}
|
||||
|
||||
private fun <T : LivingEntity> livingEntity(
|
||||
name: String,
|
||||
entityTypeBuilder: EntityType.Builder<T>
|
||||
): RegistrySupplier<EntityType<T>> {
|
||||
return queue(name) { entityTypeBuilder.build(cobblemonResource("pokemon").toString()) }
|
||||
}
|
||||
|
||||
override val registry: Registry<EntityType<*>> = Registries.ENTITY_TYPE
|
||||
override val registryKey: RegistryKey<Registry<EntityType<*>>> = RegistryKeys.ENTITY_TYPE
|
||||
@JvmField
|
||||
val POKEMON = livingEntity(
|
||||
name = "pokemon",
|
||||
entityTypeBuilder = EntityType.Builder.create<PokemonEntity>(
|
||||
{ _, world -> PokemonEntity(world) },
|
||||
SpawnGroup.CREATURE
|
||||
)
|
||||
val POKEMON_KEY = cobblemonResource("pokemon")
|
||||
@JvmField
|
||||
val POKEMON: EntityType<PokemonEntity> = this.create(
|
||||
POKEMON_KEY.path,
|
||||
EntityType.Builder.create({ _, world -> PokemonEntity(world) }, SpawnGroup.CREATURE)
|
||||
.build(POKEMON_KEY.toString())
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val EMPTY_POKEBALL = entity(
|
||||
name = "empty_pokeball",
|
||||
entityTypeBuilder = EntityType.Builder.create<EmptyPokeBallEntity>(
|
||||
{ _, world -> EmptyPokeBallEntity(PokeBalls.POKE_BALL, world) },
|
||||
SpawnGroup.MISC
|
||||
)
|
||||
val EMPTY_POKEBALL_KEY = cobblemonResource("empty_pokeball")
|
||||
@JvmField
|
||||
val EMPTY_POKEBALL: EntityType<EmptyPokeBallEntity> = this.create(
|
||||
EMPTY_POKEBALL_KEY.path,
|
||||
EntityType.Builder.create({ _, world -> EmptyPokeBallEntity(PokeBalls.POKE_BALL, world) }, SpawnGroup.MISC)
|
||||
.build(EMPTY_POKEBALL_KEY.toString())
|
||||
)
|
||||
|
||||
fun registerAttributes(consumer: (EntityType<out LivingEntity>, DefaultAttributeContainer.Builder) -> Unit) {
|
||||
consumer(POKEMON, PokemonEntity.createAttributes())
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +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
|
||||
|
||||
import com.cobblemon.mod.common.registry.CompletableRegistry
|
||||
import com.cobblemon.mod.common.world.feature.ApricornTreeFeature
|
||||
import dev.architectury.registry.registries.RegistrySupplier
|
||||
import java.util.function.Supplier
|
||||
import net.minecraft.util.registry.Registry
|
||||
import net.minecraft.world.gen.feature.Feature
|
||||
import net.minecraft.world.gen.feature.SingleStateFeatureConfig
|
||||
|
||||
object CobblemonFeatures : CompletableRegistry<Feature<*>>(Registry.FEATURE_KEY) {
|
||||
private fun <T : Feature<*>> register(name: String, feature: Supplier<T>) : RegistrySupplier<T> {
|
||||
return queue(name, feature)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val APRICORN_TREE_FEATURE = register("apricorn_tree_feature") { ApricornTreeFeature(SingleStateFeatureConfig.CODEC) }
|
||||
}
|
||||
@@ -8,12 +8,208 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.mojang.brigadier.arguments.ArgumentType
|
||||
import kotlin.reflect.KClass
|
||||
import net.minecraft.advancement.criterion.Criterion
|
||||
import net.minecraft.block.ComposterBlock
|
||||
import net.minecraft.command.argument.serialize.ArgumentSerializer
|
||||
import net.minecraft.item.ItemConvertible
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.network.listener.ClientPlayPacketListener
|
||||
import net.minecraft.network.packet.Packet
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.tag.TagKey
|
||||
import net.minecraft.resource.ResourceManager
|
||||
import net.minecraft.resource.ResourceReloader
|
||||
import net.minecraft.resource.ResourceType
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.world.GameRules
|
||||
import net.minecraft.world.biome.Biome
|
||||
import net.minecraft.world.gen.GenerationStep
|
||||
import net.minecraft.world.gen.feature.PlacedFeature
|
||||
|
||||
interface CobblemonImplementation {
|
||||
val modAPI: ModAPI
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
val networkManager: NetworkManager
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun environment(): Environment
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
fun isModInstalled(id: String): Boolean
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
fun registerPermissionValidator()
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
fun registerSoundEvents()
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
fun registerItems()
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
fun registerBlocks()
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
fun registerEntityTypes()
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
fun registerEntityAttributes()
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
fun registerBlockEntityTypes()
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
fun registerWorldGenFeatures()
|
||||
|
||||
fun registerParticles()
|
||||
|
||||
/**
|
||||
* Add a feature to the current platform implementation.
|
||||
*
|
||||
* @param feature The [PlacedFeature] being added.
|
||||
* @param step The [GenerationStep.Feature] of this feature.
|
||||
* @param validTag The [TagKey] required by the [Biome] for this feature to generate in, if null all biomes are valid.
|
||||
*/
|
||||
fun addFeatureToWorldGen(feature: RegistryKey<PlacedFeature>, step: GenerationStep.Feature, validTag: TagKey<Biome>?)
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @param A
|
||||
* @param T
|
||||
* @param identifier
|
||||
* @param argumentClass
|
||||
* @param serializer
|
||||
*/
|
||||
fun <A : ArgumentType<*>, T : ArgumentSerializer.ArgumentTypeProperties<A>> registerCommandArgument(identifier: Identifier, argumentClass: KClass<A>, serializer: ArgumentSerializer<A, T>)
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @param T
|
||||
* @param name
|
||||
* @param category
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
fun <T : GameRules.Rule<T>> registerGameRule(name: String, category: GameRules.Category, type: GameRules.Type<T>): GameRules.Key<T>
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @param T
|
||||
* @param criteria
|
||||
* @return
|
||||
*/
|
||||
fun <T : Criterion<*>> registerCriteria(criteria: T): T
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @param identifier
|
||||
* @param reloader
|
||||
* @param type
|
||||
* @param dependencies
|
||||
*/
|
||||
fun registerResourceReloader(identifier: Identifier, reloader: ResourceReloader, type: ResourceType, dependencies: Collection<Identifier>)
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
fun server(): MinecraftServer?
|
||||
|
||||
/**
|
||||
* Handles platform independent reloading of a [JsonDataRegistry].
|
||||
*
|
||||
* @param registry The [JsonDataRegistry] to reload.
|
||||
* @param manager The [ResourceManager] to reload from.
|
||||
*/
|
||||
fun <T> reloadJsonRegistry(registry: JsonDataRegistry<T>, manager: ResourceManager): HashMap<Identifier, T>
|
||||
|
||||
/**
|
||||
* Registers an item to the [ComposterBlock].
|
||||
*
|
||||
* @param item The [ItemConvertible] being registered.
|
||||
* @param chance The chance % of increasing the composter level, 0 to 1 expected.
|
||||
*/
|
||||
fun registerCompostable(item: ItemConvertible, chance: Float)
|
||||
|
||||
/**
|
||||
* Registers a builtin resource pack.
|
||||
*
|
||||
* @param id The unique [Identifier] of this pack.
|
||||
* @param title The title displayed in the resource pack GUI, the description is still a part of the pack metadata.
|
||||
* @param activationBehaviour The [ResourcePackActivationBehaviour] for this pack.
|
||||
*/
|
||||
fun registerBuiltinResourcePack(id: Identifier, title: Text, activationBehaviour: ResourcePackActivationBehaviour)
|
||||
|
||||
}
|
||||
|
||||
enum class ResourcePackActivationBehaviour {
|
||||
|
||||
/**
|
||||
* The resource pack will start disabled.
|
||||
*/
|
||||
NORMAL,
|
||||
|
||||
/**
|
||||
* The resource pack will start enabled.
|
||||
*/
|
||||
DEFAULT_ENABLED,
|
||||
|
||||
/**
|
||||
* The resource pack will always be enabled.
|
||||
* The user can reorder it but cannot remove it.
|
||||
*/
|
||||
ALWAYS_ENABLED;
|
||||
|
||||
}
|
||||
|
||||
enum class ModAPI {
|
||||
@@ -21,12 +217,27 @@ enum class ModAPI {
|
||||
FORGE
|
||||
}
|
||||
|
||||
interface NetworkDelegate {
|
||||
interface NetworkManager {
|
||||
|
||||
fun sendPacketToPlayer(player: ServerPlayerEntity, packet: NetworkPacket)
|
||||
fun sendPacketToServer(packet: NetworkPacket)
|
||||
fun <T : NetworkPacket> buildMessage(
|
||||
packetClass: Class<T>,
|
||||
toServer: Boolean
|
||||
): CobblemonNetwork.PreparedMessage<T>
|
||||
}
|
||||
fun registerClientBound()
|
||||
|
||||
fun registerServerBound()
|
||||
|
||||
fun <T: NetworkPacket<T>> createClientBound(identifier: Identifier, kClass: KClass<T>, encoder: (T, PacketByteBuf) -> Unit, decoder: (PacketByteBuf) -> T, handler: ClientNetworkPacketHandler<T>)
|
||||
|
||||
fun <T: NetworkPacket<T>> createServerBound(identifier: Identifier, kClass: KClass<T>, encoder: (T, PacketByteBuf) -> Unit, decoder: (PacketByteBuf) -> T, handler: ServerNetworkPacketHandler<T>)
|
||||
|
||||
fun sendPacketToPlayer(player: ServerPlayerEntity, packet: NetworkPacket<*>)
|
||||
|
||||
fun sendPacketToServer(packet: NetworkPacket<*>)
|
||||
|
||||
fun <T : NetworkPacket<*>> asVanillaClientBound(packet: T): Packet<ClientPlayPacketListener>
|
||||
|
||||
}
|
||||
|
||||
enum class Environment {
|
||||
|
||||
CLIENT,
|
||||
SERVER
|
||||
|
||||
}
|
||||
|
||||
@@ -8,393 +8,766 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.api.mulch.MulchVariant
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.api.pokemon.helditem.HeldItemProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.Natures
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.block.BerryBlock
|
||||
import com.cobblemon.mod.common.block.MintBlock
|
||||
import com.cobblemon.mod.common.block.MintBlock.MintType
|
||||
import com.cobblemon.mod.common.item.*
|
||||
import com.cobblemon.mod.common.item.interactive.CandyItem
|
||||
import com.cobblemon.mod.common.item.interactive.LinkCableItem
|
||||
import com.cobblemon.mod.common.item.interactive.VitaminItem
|
||||
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.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.interactive.*
|
||||
import com.cobblemon.mod.common.item.interactive.PotionItem
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||
import com.cobblemon.mod.common.registry.CompletableRegistry
|
||||
import dev.architectury.registry.registries.RegistrySupplier
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.ComposterBlock
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.entity.effect.StatusEffectInstance
|
||||
import net.minecraft.entity.effect.StatusEffects
|
||||
import net.minecraft.item.*
|
||||
import net.minecraft.util.registry.Registry
|
||||
import net.minecraft.registry.Registries
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.world.World
|
||||
|
||||
object CobblemonItems : CompletableRegistry<Item>(Registry.ITEM_KEY) {
|
||||
|
||||
init {
|
||||
this.completed.thenRun {
|
||||
val compostChance = ComposterBlock.ITEM_TO_LEVEL_INCREASE_CHANCE.getFloat(Items.OAK_LEAVES)
|
||||
// Should always pass unless Mojang reworks leaves to no longer work in the Composter, in that case we already updated w.o doing anything
|
||||
if (compostChance != ComposterBlock.ITEM_TO_LEVEL_INCREASE_CHANCE.defaultReturnValue()) {
|
||||
ComposterBlock.ITEM_TO_LEVEL_INCREASE_CHANCE[APRICORN_LEAVES.get()] = compostChance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val pokeballs = mutableListOf<RegistrySupplier<PokeBallItem>>()
|
||||
@Suppress("unused")
|
||||
object CobblemonItems : PlatformRegistry<Registry<Item>, RegistryKey<Registry<Item>>, Item>() {
|
||||
override val registry: Registry<Item> = Registries.ITEM
|
||||
override val registryKey: RegistryKey<Registry<Item>> = RegistryKeys.ITEM
|
||||
|
||||
@JvmField
|
||||
val POKE_BALL = pokeballItem(PokeBalls.POKE_BALL)
|
||||
val pokeBalls = mutableListOf<PokeBallItem>()
|
||||
@JvmField
|
||||
val CITRINE_BALL = pokeballItem(PokeBalls.CITRINE_BALL)
|
||||
val POKE_BALL = pokeBallItem(PokeBalls.POKE_BALL)
|
||||
@JvmField
|
||||
val VERDANT_BALL = pokeballItem(PokeBalls.VERDANT_BALL)
|
||||
val CITRINE_BALL = pokeBallItem(PokeBalls.CITRINE_BALL)
|
||||
@JvmField
|
||||
val AZURE_BALL = pokeballItem(PokeBalls.AZURE_BALL)
|
||||
val VERDANT_BALL = pokeBallItem(PokeBalls.VERDANT_BALL)
|
||||
@JvmField
|
||||
val ROSEATE_BALL = pokeballItem(PokeBalls.ROSEATE_BALL)
|
||||
val AZURE_BALL = pokeBallItem(PokeBalls.AZURE_BALL)
|
||||
@JvmField
|
||||
val SLATE_BALL = pokeballItem(PokeBalls.SLATE_BALL)
|
||||
val ROSEATE_BALL = pokeBallItem(PokeBalls.ROSEATE_BALL)
|
||||
@JvmField
|
||||
val PREMIER_BALL = pokeballItem(PokeBalls.PREMIER_BALL)
|
||||
val SLATE_BALL = pokeBallItem(PokeBalls.SLATE_BALL)
|
||||
@JvmField
|
||||
val GREAT_BALL = pokeballItem(PokeBalls.GREAT_BALL)
|
||||
val PREMIER_BALL = pokeBallItem(PokeBalls.PREMIER_BALL)
|
||||
@JvmField
|
||||
val ULTRA_BALL = pokeballItem(PokeBalls.ULTRA_BALL)
|
||||
val GREAT_BALL = pokeBallItem(PokeBalls.GREAT_BALL)
|
||||
@JvmField
|
||||
val SAFARI_BALL = pokeballItem(PokeBalls.SAFARI_BALL)
|
||||
val ULTRA_BALL = pokeBallItem(PokeBalls.ULTRA_BALL)
|
||||
@JvmField
|
||||
val FAST_BALL = pokeballItem(PokeBalls.FAST_BALL)
|
||||
val SAFARI_BALL = pokeBallItem(PokeBalls.SAFARI_BALL)
|
||||
@JvmField
|
||||
val LEVEL_BALL = pokeballItem(PokeBalls.LEVEL_BALL)
|
||||
val FAST_BALL = pokeBallItem(PokeBalls.FAST_BALL)
|
||||
@JvmField
|
||||
val LURE_BALL = pokeballItem(PokeBalls.LURE_BALL)
|
||||
val LEVEL_BALL = pokeBallItem(PokeBalls.LEVEL_BALL)
|
||||
@JvmField
|
||||
val HEAVY_BALL = pokeballItem(PokeBalls.HEAVY_BALL)
|
||||
val LURE_BALL = pokeBallItem(PokeBalls.LURE_BALL)
|
||||
@JvmField
|
||||
val LOVE_BALL = pokeballItem(PokeBalls.LOVE_BALL)
|
||||
val HEAVY_BALL = pokeBallItem(PokeBalls.HEAVY_BALL)
|
||||
@JvmField
|
||||
val FRIEND_BALL = pokeballItem(PokeBalls.FRIEND_BALL)
|
||||
val LOVE_BALL = pokeBallItem(PokeBalls.LOVE_BALL)
|
||||
@JvmField
|
||||
val MOON_BALL = pokeballItem(PokeBalls.MOON_BALL)
|
||||
val FRIEND_BALL = pokeBallItem(PokeBalls.FRIEND_BALL)
|
||||
@JvmField
|
||||
val SPORT_BALL = pokeballItem(PokeBalls.SPORT_BALL)
|
||||
val MOON_BALL = pokeBallItem(PokeBalls.MOON_BALL)
|
||||
@JvmField
|
||||
val PARK_BALL = pokeballItem(PokeBalls.PARK_BALL)
|
||||
val SPORT_BALL = pokeBallItem(PokeBalls.SPORT_BALL)
|
||||
@JvmField
|
||||
val NET_BALL = pokeballItem(PokeBalls.NET_BALL)
|
||||
val PARK_BALL = pokeBallItem(PokeBalls.PARK_BALL)
|
||||
@JvmField
|
||||
val DIVE_BALL = pokeballItem(PokeBalls.DIVE_BALL)
|
||||
val NET_BALL = pokeBallItem(PokeBalls.NET_BALL)
|
||||
@JvmField
|
||||
val NEST_BALL = pokeballItem(PokeBalls.NEST_BALL)
|
||||
val DIVE_BALL = pokeBallItem(PokeBalls.DIVE_BALL)
|
||||
@JvmField
|
||||
val REPEAT_BALL = pokeballItem(PokeBalls.REPEAT_BALL)
|
||||
val NEST_BALL = pokeBallItem(PokeBalls.NEST_BALL)
|
||||
@JvmField
|
||||
val TIMER_BALL = pokeballItem(PokeBalls.TIMER_BALL)
|
||||
val REPEAT_BALL = pokeBallItem(PokeBalls.REPEAT_BALL)
|
||||
@JvmField
|
||||
val LUXURY_BALL = pokeballItem(PokeBalls.LUXURY_BALL)
|
||||
val TIMER_BALL = pokeBallItem(PokeBalls.TIMER_BALL)
|
||||
@JvmField
|
||||
val DUSK_BALL = pokeballItem(PokeBalls.DUSK_BALL)
|
||||
val LUXURY_BALL = pokeBallItem(PokeBalls.LUXURY_BALL)
|
||||
@JvmField
|
||||
val HEAL_BALL = pokeballItem(PokeBalls.HEAL_BALL)
|
||||
val DUSK_BALL = pokeBallItem(PokeBalls.DUSK_BALL)
|
||||
@JvmField
|
||||
val QUICK_BALL = pokeballItem(PokeBalls.QUICK_BALL)
|
||||
val HEAL_BALL = pokeBallItem(PokeBalls.HEAL_BALL)
|
||||
@JvmField
|
||||
val DREAM_BALL = pokeballItem(PokeBalls.DREAM_BALL)
|
||||
val QUICK_BALL = pokeBallItem(PokeBalls.QUICK_BALL)
|
||||
@JvmField
|
||||
val BEAST_BALL = pokeballItem(PokeBalls.BEAST_BALL)
|
||||
val DREAM_BALL = pokeBallItem(PokeBalls.DREAM_BALL)
|
||||
@JvmField
|
||||
val MASTER_BALL = pokeballItem(PokeBalls.MASTER_BALL)
|
||||
val BEAST_BALL = pokeBallItem(PokeBalls.BEAST_BALL)
|
||||
@JvmField
|
||||
val CHERISH_BALL = pokeballItem(PokeBalls.CHERISH_BALL)
|
||||
val MASTER_BALL = pokeBallItem(PokeBalls.MASTER_BALL)
|
||||
@JvmField
|
||||
val CHERISH_BALL = pokeBallItem(PokeBalls.CHERISH_BALL)
|
||||
|
||||
@JvmField
|
||||
val RED_APRICORN = queue("red_apricorn") { ApricornItem(CobblemonBlocks.RED_APRICORN.get()) }
|
||||
@JvmField
|
||||
val YELLOW_APRICORN = queue("yellow_apricorn") { ApricornItem(CobblemonBlocks.YELLOW_APRICORN.get()) }
|
||||
@JvmField
|
||||
val GREEN_APRICORN = queue("green_apricorn") { ApricornItem(CobblemonBlocks.GREEN_APRICORN.get()) }
|
||||
@JvmField
|
||||
val BLUE_APRICORN = queue("blue_apricorn") { ApricornItem(CobblemonBlocks.BLUE_APRICORN.get()) }
|
||||
@JvmField
|
||||
val PINK_APRICORN = queue("pink_apricorn") { ApricornItem(CobblemonBlocks.PINK_APRICORN.get()) }
|
||||
@JvmField
|
||||
val BLACK_APRICORN = queue("black_apricorn") { ApricornItem(CobblemonBlocks.BLACK_APRICORN.get()) }
|
||||
@JvmField
|
||||
val WHITE_APRICORN = queue("white_apricorn") { ApricornItem(CobblemonBlocks.WHITE_APRICORN.get()) }
|
||||
val VIVICHOKE = compostableItem("vivichoke")
|
||||
|
||||
@JvmField
|
||||
val RED_APRICORN_SEED = queue("red_apricorn_seed") { ApricornSeedItem(CobblemonBlocks.RED_APRICORN_SAPLING.get(), ItemGroup.MISC) }
|
||||
@JvmField
|
||||
val YELLOW_APRICORN_SEED = queue("yellow_apricorn_seed") { ApricornSeedItem(CobblemonBlocks.YELLOW_APRICORN_SAPLING.get(), ItemGroup.MISC) }
|
||||
@JvmField
|
||||
val GREEN_APRICORN_SEED = queue("green_apricorn_seed") { ApricornSeedItem(CobblemonBlocks.GREEN_APRICORN_SAPLING.get(), ItemGroup.MISC) }
|
||||
@JvmField
|
||||
val BLUE_APRICORN_SEED = queue("blue_apricorn_seed") { ApricornSeedItem(CobblemonBlocks.BLUE_APRICORN_SAPLING.get(), ItemGroup.MISC) }
|
||||
@JvmField
|
||||
val PINK_APRICORN_SEED = queue("pink_apricorn_seed") { ApricornSeedItem(CobblemonBlocks.PINK_APRICORN_SAPLING.get(), ItemGroup.MISC) }
|
||||
@JvmField
|
||||
val BLACK_APRICORN_SEED = queue("black_apricorn_seed") { ApricornSeedItem(CobblemonBlocks.BLACK_APRICORN_SAPLING.get(), ItemGroup.MISC) }
|
||||
@JvmField
|
||||
val WHITE_APRICORN_SEED = queue("white_apricorn_seed") { ApricornSeedItem(CobblemonBlocks.WHITE_APRICORN_SAPLING.get(), ItemGroup.MISC) }
|
||||
val VIVICHOKE_SEEDS = compostableItem("vivichoke_seeds", VivichokeItem(CobblemonBlocks.VIVICHOKE_SEEDS))
|
||||
|
||||
@JvmField
|
||||
val APRICORN_LOG = queue("apricorn_log") { blockItem(CobblemonBlocks.APRICORN_LOG.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val RED_APRICORN = apricronItem("red", ApricornItem(CobblemonBlocks.RED_APRICORN))
|
||||
@JvmField
|
||||
val STRIPPED_APRICORN_LOG = queue("stripped_apricorn_log") { blockItem(CobblemonBlocks.STRIPPED_APRICORN_LOG.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val YELLOW_APRICORN = apricronItem("yellow", ApricornItem(CobblemonBlocks.YELLOW_APRICORN))
|
||||
@JvmField
|
||||
val APRICORN_WOOD = queue("apricorn_wood") { blockItem(CobblemonBlocks.APRICORN_WOOD.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val GREEN_APRICORN = apricronItem("green", ApricornItem(CobblemonBlocks.GREEN_APRICORN))
|
||||
@JvmField
|
||||
val STRIPPED_APRICORN_WOOD = queue("stripped_apricorn_wood") { blockItem(CobblemonBlocks.STRIPPED_APRICORN_WOOD.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val BLUE_APRICORN = apricronItem("blue", ApricornItem(CobblemonBlocks.BLUE_APRICORN))
|
||||
@JvmField
|
||||
val APRICORN_PLANKS = queue("apricorn_planks") { blockItem(CobblemonBlocks.APRICORN_PLANKS.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val PINK_APRICORN = apricronItem("pink", ApricornItem(CobblemonBlocks.PINK_APRICORN))
|
||||
@JvmField
|
||||
val APRICORN_LEAVES = queue("apricorn_leaves") { blockItem(CobblemonBlocks.APRICORN_LEAVES.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val BLACK_APRICORN = apricronItem("black", ApricornItem(CobblemonBlocks.BLACK_APRICORN))
|
||||
@JvmField
|
||||
val WHITE_APRICORN = apricronItem("white", ApricornItem(CobblemonBlocks.WHITE_APRICORN))
|
||||
|
||||
@JvmField
|
||||
val APRICORN_DOOR = queue("apricorn_door") { blockItem(CobblemonBlocks.APRICORN_DOOR.get(), ItemGroup.REDSTONE) }
|
||||
val RED_APRICORN_SEED = apricronSeedItem("red", ApricornSeedItem(CobblemonBlocks.RED_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val APRICORN_TRAPDOOR = queue("apricorn_trapdoor") { blockItem(CobblemonBlocks.APRICORN_TRAPDOOR.get(), ItemGroup.REDSTONE) }
|
||||
val YELLOW_APRICORN_SEED = apricronSeedItem("yellow", ApricornSeedItem(CobblemonBlocks.YELLOW_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val APRICORN_FENCE = queue("apricorn_fence") { blockItem(CobblemonBlocks.APRICORN_FENCE.get(), ItemGroup.DECORATIONS) }
|
||||
val GREEN_APRICORN_SEED = apricronSeedItem("green", ApricornSeedItem(CobblemonBlocks.GREEN_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val APRICORN_FENCE_GATE = queue("apricorn_fence_gate") { blockItem(CobblemonBlocks.APRICORN_FENCE_GATE.get(), ItemGroup.REDSTONE) }
|
||||
val BLUE_APRICORN_SEED = apricronSeedItem("blue", ApricornSeedItem(CobblemonBlocks.BLUE_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val APRICORN_BUTTON = queue("apricorn_button") { blockItem(CobblemonBlocks.APRICORN_BUTTON.get(), ItemGroup.REDSTONE) }
|
||||
val PINK_APRICORN_SEED = apricronSeedItem("pink", ApricornSeedItem(CobblemonBlocks.PINK_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val APRICORN_PRESSURE_PLATE = queue("apricorn_pressure_plate") { blockItem(CobblemonBlocks.APRICORN_PRESSURE_PLATE.get(), ItemGroup.REDSTONE) }
|
||||
val BLACK_APRICORN_SEED = apricronSeedItem("black", ApricornSeedItem(CobblemonBlocks.BLACK_APRICORN_SAPLING))
|
||||
@JvmField
|
||||
val WHITE_APRICORN_SEED = apricronSeedItem("white", ApricornSeedItem(CobblemonBlocks.WHITE_APRICORN_SAPLING))
|
||||
|
||||
@JvmField
|
||||
val APRICORN_LOG = blockItem("apricorn_log", CobblemonBlocks.APRICORN_LOG)
|
||||
@JvmField
|
||||
val STRIPPED_APRICORN_LOG = blockItem("stripped_apricorn_log", CobblemonBlocks.STRIPPED_APRICORN_LOG)
|
||||
@JvmField
|
||||
val APRICORN_WOOD = blockItem("apricorn_wood", CobblemonBlocks.APRICORN_WOOD)
|
||||
@JvmField
|
||||
val STRIPPED_APRICORN_WOOD = blockItem("stripped_apricorn_wood", CobblemonBlocks.STRIPPED_APRICORN_WOOD)
|
||||
@JvmField
|
||||
val APRICORN_PLANKS = blockItem("apricorn_planks", CobblemonBlocks.APRICORN_PLANKS)
|
||||
@JvmField
|
||||
val APRICORN_LEAVES = compostableBlockItem("apricorn_leaves", CobblemonBlocks.APRICORN_LEAVES)
|
||||
|
||||
@JvmField
|
||||
val APRICORN_DOOR = blockItem("apricorn_door", CobblemonBlocks.APRICORN_DOOR)
|
||||
@JvmField
|
||||
val APRICORN_TRAPDOOR = blockItem("apricorn_trapdoor", CobblemonBlocks.APRICORN_TRAPDOOR)
|
||||
@JvmField
|
||||
val APRICORN_FENCE = blockItem("apricorn_fence", CobblemonBlocks.APRICORN_FENCE)
|
||||
@JvmField
|
||||
val APRICORN_FENCE_GATE = blockItem("apricorn_fence_gate", CobblemonBlocks.APRICORN_FENCE_GATE)
|
||||
@JvmField
|
||||
val APRICORN_BUTTON = blockItem("apricorn_button", CobblemonBlocks.APRICORN_BUTTON)
|
||||
@JvmField
|
||||
val APRICORN_PRESSURE_PLATE = blockItem("apricorn_pressure_plate", CobblemonBlocks.APRICORN_PRESSURE_PLATE)
|
||||
//@JvmField
|
||||
// val APRICORN_SIGN = queue("apricorn_sign", SignItem(Item.Properties().stacksTo(16).tab(CreativeModeTab.TAB_DECORATIONS), CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN))
|
||||
// val APRICORN_SIGN = create("apricorn_sign", SignItem(Item.Properties().stacksTo(16).tab(CreativeModeTab.TAB_DECORATIONS), CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN))
|
||||
@JvmField
|
||||
val APRICORN_SLAB = queue("apricorn_slab") { blockItem(CobblemonBlocks.APRICORN_SLAB.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val APRICORN_SLAB = blockItem("apricorn_slab", CobblemonBlocks.APRICORN_SLAB)
|
||||
@JvmField
|
||||
val APRICORN_STAIRS = queue("apricorn_stairs") { blockItem(CobblemonBlocks.APRICORN_STAIRS.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val APRICORN_STAIRS = blockItem("apricorn_stairs", CobblemonBlocks.APRICORN_STAIRS)
|
||||
|
||||
@JvmField
|
||||
val HEALING_MACHINE = queue("healing_machine") { blockItem(CobblemonBlocks.HEALING_MACHINE.get(), ItemGroup.REDSTONE) }
|
||||
val HEALING_MACHINE = blockItem("healing_machine", CobblemonBlocks.HEALING_MACHINE)
|
||||
@JvmField
|
||||
val PC = queue("pc") { blockItem(CobblemonBlocks.PC.get(), ItemGroup.REDSTONE) }
|
||||
val PC = blockItem("pc", CobblemonBlocks.PC)
|
||||
@JvmField
|
||||
val PASTURE = blockItem("pasture", CobblemonBlocks.PASTURE)
|
||||
|
||||
// Evolution items
|
||||
@JvmField val LINK_CABLE = this.queue("link_cable") { LinkCableItem() }
|
||||
@JvmField val DRAGON_SCALE = this.evolutionItem("dragon_scale")
|
||||
@JvmField val KINGS_ROCK = this.evolutionItem("kings_rock")
|
||||
@JvmField val METAL_COAT = this.evolutionItem("metal_coat")
|
||||
@JvmField val UPGRADE = this.evolutionItem("upgrade")
|
||||
@JvmField val DUBIOUS_DISC = this.evolutionItem("dubious_disc")
|
||||
@JvmField val DEEP_SEA_SCALE = this.evolutionItem("deep_sea_scale")
|
||||
@JvmField val DEEP_SEA_TOOTH = this.evolutionItem("deep_sea_tooth")
|
||||
@JvmField val ELECTIRIZER = this.evolutionItem("electirizer")
|
||||
@JvmField val MAGMARIZER = this.evolutionItem("magmarizer")
|
||||
@JvmField val OVAL_STONE = this.evolutionItem("oval_stone")
|
||||
@JvmField val PROTECTOR = this.evolutionItem("protector")
|
||||
@JvmField val REAPER_CLOTH = this.evolutionItem("reaper_cloth")
|
||||
@JvmField val PRISM_SCALE = this.evolutionItem("prism_scale")
|
||||
@JvmField val SACHET = this.evolutionItem("sachet")
|
||||
@JvmField val WHIPPED_DREAM = this.evolutionItem("whipped_dream")
|
||||
@JvmField val STRAWBERRY_SWEET = this.evolutionItem("strawberry_sweet")
|
||||
@JvmField val LOVE_SWEET = this.evolutionItem("love_sweet")
|
||||
@JvmField val BERRY_SWEET = this.evolutionItem("berry_sweet")
|
||||
@JvmField val CLOVER_SWEET = this.evolutionItem("clover_sweet")
|
||||
@JvmField val FLOWER_SWEET = this.evolutionItem("flower_sweet")
|
||||
@JvmField val STAR_SWEET = this.evolutionItem("star_sweet")
|
||||
@JvmField val RIBBON_SWEET = this.evolutionItem("ribbon_sweet")
|
||||
@JvmField val CHIPPED_POT = this.evolutionItem("chipped_pot")
|
||||
@JvmField val CRACKED_POT = this.evolutionItem("cracked_pot")
|
||||
@JvmField val SWEET_APPLE = this.evolutionItem("sweet_apple")
|
||||
@JvmField val TART_APPLE = this.evolutionItem("tart_apple")
|
||||
@JvmField val GALARICA_CUFF = this.evolutionItem("galarica_cuff")
|
||||
@JvmField val GALARICA_WREATH = this.evolutionItem("galarica_wreath")
|
||||
@JvmField val BLACK_AUGURITE = this.evolutionItem("black_augurite")
|
||||
@JvmField val PEAT_BLOCK = this.evolutionItem("peat_block")
|
||||
@JvmField val RAZOR_CLAW = this.evolutionItem("razor_claw")
|
||||
@JvmField val RAZOR_FANG = this.evolutionItem("razor_fang")
|
||||
// ToDo enable me when malicious armor goes in the game
|
||||
//@JvmField val AUSPICIOUS_ARMOR = this.heldItem("auspicious_armor")
|
||||
@JvmField val LINK_CABLE = create("link_cable", LinkCableItem())
|
||||
@JvmField val DRAGON_SCALE = noSettingsItem("dragon_scale")
|
||||
@JvmField val KINGS_ROCK = noSettingsItem("kings_rock")
|
||||
@JvmField val METAL_COAT = noSettingsItem("metal_coat")
|
||||
@JvmField val UPGRADE = noSettingsItem("upgrade")
|
||||
@JvmField val DUBIOUS_DISC = noSettingsItem("dubious_disc")
|
||||
@JvmField val DEEP_SEA_SCALE = noSettingsItem("deep_sea_scale")
|
||||
@JvmField val DEEP_SEA_TOOTH = noSettingsItem("deep_sea_tooth")
|
||||
@JvmField val ELECTIRIZER = noSettingsItem("electirizer")
|
||||
@JvmField val MAGMARIZER = noSettingsItem("magmarizer")
|
||||
@JvmField val OVAL_STONE = noSettingsItem("oval_stone")
|
||||
@JvmField val PROTECTOR = noSettingsItem("protector")
|
||||
@JvmField val REAPER_CLOTH = noSettingsItem("reaper_cloth")
|
||||
@JvmField val PRISM_SCALE = noSettingsItem("prism_scale")
|
||||
@JvmField val SACHET = noSettingsItem("sachet")
|
||||
@JvmField val WHIPPED_DREAM = noSettingsItem("whipped_dream")
|
||||
@JvmField val STRAWBERRY_SWEET = noSettingsItem("strawberry_sweet")
|
||||
@JvmField val LOVE_SWEET = noSettingsItem("love_sweet")
|
||||
@JvmField val BERRY_SWEET = noSettingsItem("berry_sweet")
|
||||
@JvmField val CLOVER_SWEET = noSettingsItem("clover_sweet")
|
||||
@JvmField val FLOWER_SWEET = noSettingsItem("flower_sweet")
|
||||
@JvmField val STAR_SWEET = noSettingsItem("star_sweet")
|
||||
@JvmField val RIBBON_SWEET = noSettingsItem("ribbon_sweet")
|
||||
@JvmField val CHIPPED_POT = noSettingsItem("chipped_pot")
|
||||
@JvmField val CRACKED_POT = noSettingsItem("cracked_pot")
|
||||
@JvmField val SWEET_APPLE = noSettingsItem("sweet_apple")
|
||||
@JvmField val TART_APPLE = noSettingsItem("tart_apple")
|
||||
@JvmField val GALARICA_CUFF = noSettingsItem("galarica_cuff")
|
||||
@JvmField val GALARICA_WREATH = noSettingsItem("galarica_wreath")
|
||||
@JvmField val BLACK_AUGURITE = noSettingsItem("black_augurite")
|
||||
@JvmField val PEAT_BLOCK = noSettingsItem("peat_block")
|
||||
@JvmField val RAZOR_CLAW = noSettingsItem("razor_claw")
|
||||
@JvmField val RAZOR_FANG = noSettingsItem("razor_fang")
|
||||
@JvmField val AUSPICIOUS_ARMOR = heldItem("auspicious_armor")
|
||||
@JvmField val MALICIOUS_ARMOR = heldItem("malicious_armor")
|
||||
|
||||
private val berries = mutableMapOf<Identifier, BerryItem>()
|
||||
// Plants
|
||||
@JvmField val ORAN_BERRY = berryItem("oran", HealingBerryItem(CobblemonBlocks.ORAN_BERRY) { CobblemonMechanics.berries.oranRestoreAmount })
|
||||
@JvmField val CHERI_BERRY = berryItem("cheri", StatusCuringBerryItem(CobblemonBlocks.CHERI_BERRY, Statuses.PARALYSIS))
|
||||
@JvmField val CHESTO_BERRY = berryItem("chesto", StatusCuringBerryItem(CobblemonBlocks.CHESTO_BERRY, Statuses.SLEEP))
|
||||
@JvmField val PECHA_BERRY = berryItem("pecha", StatusCuringBerryItem(CobblemonBlocks.PECHA_BERRY, Statuses.POISON, Statuses.POISON_BADLY))
|
||||
@JvmField val RAWST_BERRY = berryItem("rawst", StatusCuringBerryItem(CobblemonBlocks.RAWST_BERRY, Statuses.BURN))
|
||||
@JvmField val ASPEAR_BERRY = berryItem("aspear", StatusCuringBerryItem(CobblemonBlocks.ASPEAR_BERRY, Statuses.FROZEN))
|
||||
@JvmField val PERSIM_BERRY = berryItem("persim", VolatileCuringBerryItem(CobblemonBlocks.PERSIM_BERRY, "confusion"))
|
||||
@JvmField val RAZZ_BERRY = berryItem("razz", CobblemonBlocks.RAZZ_BERRY)
|
||||
@JvmField val BLUK_BERRY = berryItem("bluk", CobblemonBlocks.BLUK_BERRY)
|
||||
@JvmField val NANAB_BERRY = berryItem("nanab", CobblemonBlocks.NANAB_BERRY)
|
||||
@JvmField val WEPEAR_BERRY = berryItem("wepear", CobblemonBlocks.WEPEAR_BERRY)
|
||||
@JvmField val PINAP_BERRY = berryItem("pinap", CobblemonBlocks.PINAP_BERRY)
|
||||
@JvmField val OCCA_BERRY = berryItem("occa", CobblemonBlocks.OCCA_BERRY)
|
||||
@JvmField val PASSHO_BERRY = berryItem("passho", CobblemonBlocks.PASSHO_BERRY)
|
||||
@JvmField val WACAN_BERRY = berryItem("wacan", CobblemonBlocks.WACAN_BERRY)
|
||||
@JvmField val RINDO_BERRY = berryItem("rindo", CobblemonBlocks.RINDO_BERRY)
|
||||
@JvmField val YACHE_BERRY = berryItem("yache", CobblemonBlocks.YACHE_BERRY)
|
||||
@JvmField val CHOPLE_BERRY = berryItem("chople", CobblemonBlocks.CHOPLE_BERRY)
|
||||
@JvmField val KEBIA_BERRY = berryItem("kebia", CobblemonBlocks.KEBIA_BERRY)
|
||||
@JvmField val SHUCA_BERRY = berryItem("shuca", CobblemonBlocks.SHUCA_BERRY)
|
||||
@JvmField val COBA_BERRY = berryItem("coba", CobblemonBlocks.COBA_BERRY)
|
||||
@JvmField val PAYAPA_BERRY = berryItem("payapa", CobblemonBlocks.PAYAPA_BERRY)
|
||||
@JvmField val TANGA_BERRY = berryItem("tanga", CobblemonBlocks.TANGA_BERRY)
|
||||
@JvmField val CHARTI_BERRY = berryItem("charti", CobblemonBlocks.CHARTI_BERRY)
|
||||
@JvmField val KASIB_BERRY = berryItem("kasib", CobblemonBlocks.KASIB_BERRY)
|
||||
@JvmField val HABAN_BERRY = berryItem("haban", CobblemonBlocks.HABAN_BERRY)
|
||||
@JvmField val COLBUR_BERRY = berryItem("colbur", CobblemonBlocks.COLBUR_BERRY)
|
||||
@JvmField val BABIRI_BERRY = berryItem("babiri", CobblemonBlocks.BABIRI_BERRY)
|
||||
@JvmField val CHILAN_BERRY = berryItem("chilan", CobblemonBlocks.CHILAN_BERRY)
|
||||
@JvmField val ROSELI_BERRY = berryItem("roseli", CobblemonBlocks.ROSELI_BERRY)
|
||||
@JvmField val LEPPA_BERRY = berryItem("leppa", PPRestoringBerryItem(CobblemonBlocks.LEPPA_BERRY) { CobblemonMechanics.berries.ppRestoreAmount })
|
||||
@JvmField val LUM_BERRY = berryItem("lum", StatusCuringBerryItem(CobblemonBlocks.LUM_BERRY))
|
||||
@JvmField val FIGY_BERRY = berryItem("figy", PortionHealingBerryItem(CobblemonBlocks.FIGY_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
|
||||
@JvmField val WIKI_BERRY = berryItem("wiki", PortionHealingBerryItem(CobblemonBlocks.WIKI_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
|
||||
@JvmField val MAGO_BERRY = berryItem("mago", PortionHealingBerryItem(CobblemonBlocks.MAGO_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
|
||||
@JvmField val AGUAV_BERRY = berryItem("aguav", PortionHealingBerryItem(CobblemonBlocks.AGUAV_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
|
||||
@JvmField val IAPAPA_BERRY = berryItem("iapapa", PortionHealingBerryItem(CobblemonBlocks.IAPAPA_BERRY, true) { CobblemonMechanics.berries.portionHealRatio })
|
||||
@JvmField val SITRUS_BERRY = berryItem("sitrus", HealingBerryItem(CobblemonBlocks.SITRUS_BERRY) { CobblemonMechanics.berries.sitrusHealAmount })
|
||||
@JvmField val TOUGA_BERRY = berryItem("touga", CobblemonBlocks.TOUGA_BERRY)
|
||||
@JvmField val CORNN_BERRY = berryItem("cornn", CobblemonBlocks.CORNN_BERRY)
|
||||
@JvmField val MAGOST_BERRY = berryItem("magost", CobblemonBlocks.MAGOST_BERRY)
|
||||
@JvmField val RABUTA_BERRY = berryItem("rabuta", CobblemonBlocks.RABUTA_BERRY)
|
||||
@JvmField val NOMEL_BERRY = berryItem("nomel", CobblemonBlocks.NOMEL_BERRY)
|
||||
@JvmField val ENIGMA_BERRY = berryItem("enigma", CobblemonBlocks.ENIGMA_BERRY)
|
||||
@JvmField val POMEG_BERRY = berryItem("pomeg", FriendshipRaisingBerryItem(CobblemonBlocks.POMEG_BERRY, Stats.HP))
|
||||
@JvmField val KELPSY_BERRY = berryItem("kelpsy", FriendshipRaisingBerryItem(CobblemonBlocks.KELPSY_BERRY, Stats.ATTACK))
|
||||
@JvmField val QUALOT_BERRY = berryItem("qualot", FriendshipRaisingBerryItem(CobblemonBlocks.QUALOT_BERRY, Stats.DEFENCE))
|
||||
@JvmField val HONDEW_BERRY = berryItem("hondew", FriendshipRaisingBerryItem(CobblemonBlocks.HONDEW_BERRY, Stats.SPECIAL_ATTACK))
|
||||
@JvmField val GREPA_BERRY = berryItem("grepa", FriendshipRaisingBerryItem(CobblemonBlocks.GREPA_BERRY, Stats.SPECIAL_DEFENCE))
|
||||
@JvmField val TAMATO_BERRY = berryItem("tamato", FriendshipRaisingBerryItem(CobblemonBlocks.TAMATO_BERRY, Stats.SPEED))
|
||||
@JvmField val SPELON_BERRY = berryItem("spelon", CobblemonBlocks.SPELON_BERRY)
|
||||
@JvmField val PAMTRE_BERRY = berryItem("pamtre", CobblemonBlocks.PAMTRE_BERRY)
|
||||
@JvmField val WATMEL_BERRY = berryItem("watmel", CobblemonBlocks.WATMEL_BERRY)
|
||||
@JvmField val DURIN_BERRY = berryItem("durin", CobblemonBlocks.DURIN_BERRY)
|
||||
@JvmField val BELUE_BERRY = berryItem("belue", CobblemonBlocks.BELUE_BERRY)
|
||||
@JvmField val KEE_BERRY = berryItem("kee", CobblemonBlocks.KEE_BERRY)
|
||||
@JvmField val MARANGA_BERRY = berryItem("maranga", CobblemonBlocks.MARANGA_BERRY)
|
||||
@JvmField val HOPO_BERRY = berryItem("hopo", PPRestoringBerryItem(CobblemonBlocks.HOPO_BERRY) { CobblemonMechanics.berries.ppRestoreAmount })
|
||||
@JvmField val LIECHI_BERRY = berryItem("liechi", CobblemonBlocks.LIECHI_BERRY)
|
||||
@JvmField val GANLON_BERRY = berryItem("ganlon", CobblemonBlocks.GANLON_BERRY)
|
||||
@JvmField val SALAC_BERRY = berryItem("salac", CobblemonBlocks.SALAC_BERRY)
|
||||
@JvmField val PETAYA_BERRY = berryItem("petaya", CobblemonBlocks.PETAYA_BERRY)
|
||||
@JvmField val APICOT_BERRY = berryItem("apicot", CobblemonBlocks.APICOT_BERRY)
|
||||
@JvmField val LANSAT_BERRY = berryItem("lansat", CobblemonBlocks.LANSAT_BERRY)
|
||||
@JvmField val STARF_BERRY = berryItem("starf", CobblemonBlocks.STARF_BERRY)
|
||||
@JvmField val MICLE_BERRY = berryItem("micle", CobblemonBlocks.MICLE_BERRY)
|
||||
@JvmField val CUSTAP_BERRY = berryItem("custap", CobblemonBlocks.CUSTAP_BERRY)
|
||||
@JvmField val JABOCA_BERRY = berryItem("jaboca", CobblemonBlocks.JABOCA_BERRY)
|
||||
@JvmField val ROWAP_BERRY = berryItem("rowap", CobblemonBlocks.ROWAP_BERRY)
|
||||
|
||||
@JvmField val BERRY_JUICE = this.create("berry_juice", BerryJuiceItem())
|
||||
|
||||
// Medicine
|
||||
@JvmField
|
||||
val RARE_CANDY = queue("rare_candy") { CandyItem { _, pokemon -> pokemon.getExperienceToNextLevel() } }
|
||||
val RARE_CANDY = candyItem("rare_candy") { _, pokemon -> pokemon.getExperienceToNextLevel() }
|
||||
@JvmField
|
||||
val EXPERIENCE_CANDY_XS = queue("exp_candy_xs") { CandyItem { _, _ -> CandyItem.DEFAULT_XS_CANDY_YIELD } }
|
||||
val EXPERIENCE_CANDY_XS = candyItem("exp_candy_xs") { _, _ -> CandyItem.DEFAULT_XS_CANDY_YIELD }
|
||||
@JvmField
|
||||
val EXPERIENCE_CANDY_S = queue("exp_candy_s") { CandyItem { _, _ -> CandyItem.DEFAULT_S_CANDY_YIELD } }
|
||||
val EXPERIENCE_CANDY_S = candyItem("exp_candy_s") { _, _ -> CandyItem.DEFAULT_S_CANDY_YIELD }
|
||||
@JvmField
|
||||
val EXPERIENCE_CANDY_M = queue("exp_candy_m") { CandyItem { _, _ -> CandyItem.DEFAULT_M_CANDY_YIELD } }
|
||||
val EXPERIENCE_CANDY_M = candyItem("exp_candy_m") { _, _ -> CandyItem.DEFAULT_M_CANDY_YIELD }
|
||||
@JvmField
|
||||
val EXPERIENCE_CANDY_L = queue("exp_candy_l") { CandyItem { _, _ -> CandyItem.DEFAULT_L_CANDY_YIELD } }
|
||||
val EXPERIENCE_CANDY_L = candyItem("exp_candy_l") { _, _ -> CandyItem.DEFAULT_L_CANDY_YIELD }
|
||||
@JvmField
|
||||
val EXPERIENCE_CANDY_XL = queue("exp_candy_xl") { CandyItem { _, _ -> CandyItem.DEFAULT_XL_CANDY_YIELD } }
|
||||
val EXPERIENCE_CANDY_XL = candyItem("exp_candy_xl") { _, _ -> CandyItem.DEFAULT_XL_CANDY_YIELD }
|
||||
@JvmField
|
||||
val CALCIUM = queue("calcium") { VitaminItem(Stats.SPECIAL_ATTACK) }
|
||||
val CALCIUM = create("calcium", VitaminItem(Stats.SPECIAL_ATTACK))
|
||||
@JvmField
|
||||
val CARBOS = queue("carbos") { VitaminItem(Stats.SPEED) }
|
||||
val CARBOS = create("carbos", VitaminItem(Stats.SPEED))
|
||||
@JvmField
|
||||
val HP_UP = queue("hp_up") { VitaminItem(Stats.HP) }
|
||||
val HP_UP = create("hp_up", VitaminItem(Stats.HP))
|
||||
@JvmField
|
||||
val IRON = queue("iron") { VitaminItem(Stats.DEFENCE) }
|
||||
val IRON = create("iron", VitaminItem(Stats.DEFENCE))
|
||||
@JvmField
|
||||
val PROTEIN = queue("protein") { VitaminItem(Stats.ATTACK) }
|
||||
val PROTEIN = create("protein", VitaminItem(Stats.ATTACK))
|
||||
@JvmField
|
||||
val ZINC = queue("zinc") { VitaminItem(Stats.SPECIAL_DEFENCE) }
|
||||
val ZINC = create("zinc", VitaminItem(Stats.SPECIAL_DEFENCE))
|
||||
@JvmField
|
||||
val MEDICINAL_LEEK = create("medicinal_leek", MedicinalLeekItem(CobblemonBlocks.MEDICINAL_LEEK, Item.Settings().food(FoodComponent.Builder().snack().hunger(1).saturationModifier(0.2f).build())))
|
||||
@JvmField
|
||||
val ROASTED_LEEK = create("roasted_leek", Item(Item.Settings().food(FoodComponent.Builder().snack().hunger(3).saturationModifier(0.3f).build())))
|
||||
@JvmField
|
||||
val BRAISED_VIVICHOKE = create("braised_vivichoke", Item(Item.Settings().food(FoodComponent.Builder().hunger(6).saturationModifier(0.6f).build())))
|
||||
@JvmField
|
||||
val VIVICHOKE_DIP = create("vivichoke_dip", object : StewItem(Settings().maxCount(1)
|
||||
.food(FoodComponent.Builder()
|
||||
.hunger(10)
|
||||
.saturationModifier(1.2F)
|
||||
.statusEffect(StatusEffectInstance(StatusEffects.ABSORPTION, 900, 0), 1F)
|
||||
.alwaysEdible()
|
||||
.build())) {
|
||||
override fun finishUsing(stack: ItemStack?, world: World?, user: LivingEntity?): ItemStack {
|
||||
user?.clearStatusEffects()
|
||||
return super.finishUsing(stack, world, user)
|
||||
}
|
||||
})
|
||||
@JvmField
|
||||
val ENERGY_ROOT = compostableItem("energy_root", EnergyRootItem(CobblemonBlocks.ENERGY_ROOT, Item.Settings().food(FoodComponent.Builder().hunger(1).snack().saturationModifier(0.2f).build())))
|
||||
@JvmField
|
||||
val REVIVAL_HERB = compostableItem("revival_herb", RevivalHerbItem(CobblemonBlocks.REVIVAL_HERB))
|
||||
@JvmField
|
||||
val PEP_UP_FLOWER = compostableBlockItem("pep_up_flower", CobblemonBlocks.PEP_UP_FLOWER)
|
||||
@JvmField
|
||||
val MEDICINAL_BREW = create("medicinal_brew", Item(Item.Settings()))
|
||||
@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 POTION = create("potion", PotionItem(PotionType.POTION))
|
||||
@JvmField
|
||||
val SUPER_POTION = create("super_potion", PotionItem(PotionType.SUPER_POTION))
|
||||
@JvmField
|
||||
val HYPER_POTION = create("hyper_potion", PotionItem(PotionType.HYPER_POTION))
|
||||
@JvmField
|
||||
val MAX_POTION = create("max_potion", PotionItem(PotionType.MAX_POTION))
|
||||
@JvmField
|
||||
val FULL_RESTORE = create("full_restore", PotionItem(PotionType.FULL_RESTORE))
|
||||
|
||||
@JvmField
|
||||
val HEAL_POWDER = create("heal_powder", HealPowderItem())
|
||||
@JvmField
|
||||
val LEEK_AND_POTATO_STEW = create("leek_and_potato_stew", StewItem(Item.Settings().food(FoodComponent.Builder().hunger(8).saturationModifier(0.6f).build()).maxCount(1)))
|
||||
@JvmField
|
||||
val REVIVE = create("revive", ReviveItem(max = false))
|
||||
@JvmField
|
||||
val MAX_REVIVE = create("max_revive", ReviveItem(max = true))
|
||||
@JvmField
|
||||
val PP_UP = create("pp_up", PPUpItem(1))
|
||||
@JvmField
|
||||
val PP_MAX = create("pp_max", PPUpItem(3))
|
||||
|
||||
@JvmField
|
||||
val RED_MINT_SEEDS = mintSeed("red", MintType.RED.getCropBlock())
|
||||
@JvmField
|
||||
val RED_MINT_LEAF = mintLeaf("red", MintLeafItem(MintType.RED))
|
||||
@JvmField
|
||||
val BLUE_MINT_SEEDS = mintSeed("blue", MintType.BLUE.getCropBlock())
|
||||
@JvmField
|
||||
val BLUE_MINT_LEAF = mintLeaf("blue", MintLeafItem(MintType.BLUE))
|
||||
@JvmField
|
||||
val CYAN_MINT_SEEDS = mintSeed("cyan", MintType.CYAN.getCropBlock())
|
||||
@JvmField
|
||||
val CYAN_MINT_LEAF = mintLeaf("cyan", MintLeafItem(MintType.CYAN))
|
||||
@JvmField
|
||||
val PINK_MINT_SEEDS = mintSeed("pink", MintType.PINK.getCropBlock())
|
||||
@JvmField
|
||||
val PINK_MINT_LEAF = mintLeaf("pink", MintLeafItem(MintType.PINK))
|
||||
@JvmField
|
||||
val GREEN_MINT_SEEDS = mintSeed("green", MintType.GREEN.getCropBlock())
|
||||
@JvmField
|
||||
val GREEN_MINT_LEAF = mintLeaf("green", MintLeafItem(MintType.GREEN))
|
||||
@JvmField
|
||||
val WHITE_MINT_SEEDS = mintSeed("white", MintType.WHITE.getCropBlock())
|
||||
@JvmField
|
||||
val WHITE_MINT_LEAF = mintLeaf("white", MintLeafItem(MintType.WHITE))
|
||||
|
||||
val mints = mutableMapOf<String, MintItem>()
|
||||
|
||||
@JvmField
|
||||
val LONELY_MINT = mintItem("lonely_mint", MintItem(Natures.LONELY))
|
||||
@JvmField
|
||||
val ADAMANT_MINT = mintItem("adamant_mint", MintItem(Natures.ADAMANT))
|
||||
@JvmField
|
||||
val NAUGHTY_MINT = mintItem("naughty_mint", MintItem(Natures.NAUGHTY))
|
||||
@JvmField
|
||||
val BRAVE_MINT = mintItem("brave_mint", MintItem(Natures.BRAVE))
|
||||
@JvmField
|
||||
val BOLD_MINT = mintItem("bold_mint", MintItem(Natures.BOLD))
|
||||
@JvmField
|
||||
val IMPISH_MINT = mintItem("impish_mint", MintItem(Natures.IMPISH))
|
||||
@JvmField
|
||||
val LAX_MINT = mintItem("lax_mint", MintItem(Natures.LAX))
|
||||
@JvmField
|
||||
val RELAXED_MINT = mintItem("relaxed_mint", MintItem(Natures.RELAXED))
|
||||
@JvmField
|
||||
val MODEST_MINT = mintItem("modest_mint", MintItem(Natures.MODEST))
|
||||
@JvmField
|
||||
val MILD_MINT = mintItem("mild_mint", MintItem(Natures.MILD))
|
||||
@JvmField
|
||||
val RASH_MINT = mintItem("rash_mint", MintItem(Natures.RASH))
|
||||
@JvmField
|
||||
val QUIET_MINT = mintItem("quiet_mint", MintItem(Natures.QUIET))
|
||||
@JvmField
|
||||
val CALM_MINT = mintItem("calm_mint", MintItem(Natures.CALM))
|
||||
@JvmField
|
||||
val GENTLE_MINT = mintItem("gentle_mint", MintItem(Natures.GENTLE))
|
||||
@JvmField
|
||||
val CAREFUL_MINT = mintItem("careful_mint", MintItem(Natures.CAREFUL))
|
||||
@JvmField
|
||||
val SASSY_MINT = mintItem("sassy_mint", MintItem(Natures.SASSY))
|
||||
@JvmField
|
||||
val TIMID_MINT = mintItem("timid_mint", MintItem(Natures.TIMID))
|
||||
@JvmField
|
||||
val HASTY_MINT = mintItem("hasty_mint", MintItem(Natures.HASTY))
|
||||
@JvmField
|
||||
val JOLLY_MINT = mintItem("jolly_mint", MintItem(Natures.JOLLY))
|
||||
@JvmField
|
||||
val NAIVE_MINT = mintItem("naive_mint", MintItem(Natures.NAIVE))
|
||||
@JvmField
|
||||
val SERIOUS_MINT = mintItem("serious_mint", MintItem(Natures.SERIOUS))
|
||||
|
||||
@JvmField val X_ACCURACY = create("x_${Stats.ACCURACY.identifier.path}", XStatItem(Stats.ACCURACY))
|
||||
@JvmField val X_ATTACK = create("x_${Stats.ATTACK.identifier.path}", XStatItem(Stats.ATTACK))
|
||||
@JvmField val X_DEFENSE = create("x_${Stats.DEFENCE.identifier.path}", XStatItem(Stats.DEFENCE))
|
||||
@JvmField val X_SP_ATK = create("x_${Stats.SPECIAL_ATTACK.identifier.path}", XStatItem(Stats.SPECIAL_ATTACK))
|
||||
@JvmField val X_SP_DEF = create("x_${Stats.SPECIAL_DEFENCE.identifier.path}", XStatItem(Stats.SPECIAL_DEFENCE))
|
||||
@JvmField val X_SPEED = create("x_${Stats.SPEED.identifier.path}", XStatItem(Stats.SPEED))
|
||||
|
||||
@JvmField val DIRE_HIT = create("dire_hit", DireHitItem())
|
||||
@JvmField val GUARD_SPEC = create("guard_spec", GuardSpecItem())
|
||||
|
||||
@JvmField val BURN_HEAL = create("burn_heal", StatusCureItem("item.cobblemon.burn_heal", Statuses.BURN))
|
||||
@JvmField val PARALYZE_HEAL = create("paralyze_heal", StatusCureItem("item.cobblemon.paralyze_heal", Statuses.PARALYSIS))
|
||||
@JvmField val ICE_HEAL = create("ice_heal", StatusCureItem("item.cobblemon.ice_heal", Statuses.FROZEN))
|
||||
@JvmField val ANTIDOTE = create("antidote", StatusCureItem("item.cobblemon.antidote", Statuses.POISON, Statuses.POISON_BADLY))
|
||||
@JvmField val AWAKENING = create("awakening", StatusCureItem("item.cobblemon.awakening", Statuses.SLEEP))
|
||||
|
||||
@JvmField val FULL_HEAL = create("full_heal", StatusCureItem("item.cobblemon.full_heal"))
|
||||
|
||||
@JvmField val ETHER = create("ether", EtherItem(max = false))
|
||||
@JvmField val MAX_ETHER = create("max_ether", EtherItem(max = true))
|
||||
@JvmField val ELIXIR = create("elixir", ElixirItem(max = false))
|
||||
@JvmField val MAX_ELIXIR = create("max_elixir", ElixirItem(max = true))
|
||||
|
||||
/**
|
||||
* Evolution Ores and Stones
|
||||
*/
|
||||
@JvmField
|
||||
val DAWN_STONE_ORE = queue("dawn_stone_ore") { blockItem(CobblemonBlocks.DAWN_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DAWN_STONE_ORE = blockItem("dawn_stone_ore", CobblemonBlocks.DAWN_STONE_ORE)
|
||||
@JvmField
|
||||
val DUSK_STONE_ORE = queue("dusk_stone_ore") { blockItem(CobblemonBlocks.DUSK_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DUSK_STONE_ORE = blockItem("dusk_stone_ore", CobblemonBlocks.DUSK_STONE_ORE)
|
||||
@JvmField
|
||||
val FIRE_STONE_ORE = queue("fire_stone_ore") { blockItem(CobblemonBlocks.FIRE_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val FIRE_STONE_ORE = blockItem("fire_stone_ore", CobblemonBlocks.FIRE_STONE_ORE)
|
||||
@JvmField
|
||||
val ICE_STONE_ORE = queue("ice_stone_ore") { blockItem(CobblemonBlocks.ICE_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val ICE_STONE_ORE = blockItem("ice_stone_ore", CobblemonBlocks.ICE_STONE_ORE)
|
||||
@JvmField
|
||||
val LEAF_STONE_ORE = queue("leaf_stone_ore") { blockItem(CobblemonBlocks.LEAF_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val LEAF_STONE_ORE = blockItem("leaf_stone_ore", CobblemonBlocks.LEAF_STONE_ORE)
|
||||
@JvmField
|
||||
val MOON_STONE_ORE = queue("moon_stone_ore") { blockItem(CobblemonBlocks.MOON_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val MOON_STONE_ORE = blockItem("moon_stone_ore", CobblemonBlocks.MOON_STONE_ORE)
|
||||
@JvmField
|
||||
val SHINY_STONE_ORE = queue("shiny_stone_ore") { blockItem(CobblemonBlocks.SHINY_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val SHINY_STONE_ORE = blockItem("shiny_stone_ore", CobblemonBlocks.SHINY_STONE_ORE)
|
||||
@JvmField
|
||||
val SUN_STONE_ORE = queue("sun_stone_ore") { blockItem(CobblemonBlocks.SUN_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val SUN_STONE_ORE = blockItem("sun_stone_ore", CobblemonBlocks.SUN_STONE_ORE)
|
||||
@JvmField
|
||||
val THUNDER_STONE_ORE = queue("thunder_stone_ore") { blockItem(CobblemonBlocks.THUNDER_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val THUNDER_STONE_ORE = blockItem("thunder_stone_ore", CobblemonBlocks.THUNDER_STONE_ORE)
|
||||
@JvmField
|
||||
val WATER_STONE_ORE = queue("water_stone_ore") { blockItem(CobblemonBlocks.WATER_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val WATER_STONE_ORE = blockItem("water_stone_ore", CobblemonBlocks.WATER_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_DAWN_STONE_ORE = queue("deepslate_dawn_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_DAWN_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_DAWN_STONE_ORE = blockItem("deepslate_dawn_stone_ore", CobblemonBlocks.DEEPSLATE_DAWN_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_DUSK_STONE_ORE = queue("deepslate_dusk_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_DUSK_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_DUSK_STONE_ORE = blockItem("deepslate_dusk_stone_ore", CobblemonBlocks.DEEPSLATE_DUSK_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_FIRE_STONE_ORE = queue("deepslate_fire_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_FIRE_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_FIRE_STONE_ORE = blockItem("deepslate_fire_stone_ore", CobblemonBlocks.DEEPSLATE_FIRE_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_ICE_STONE_ORE = queue("deepslate_ice_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_ICE_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_ICE_STONE_ORE = blockItem("deepslate_ice_stone_ore", CobblemonBlocks.DEEPSLATE_ICE_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_LEAF_STONE_ORE = queue("deepslate_leaf_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_LEAF_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_LEAF_STONE_ORE = blockItem("deepslate_leaf_stone_ore", CobblemonBlocks.DEEPSLATE_LEAF_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_MOON_STONE_ORE = queue("deepslate_moon_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_MOON_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_MOON_STONE_ORE = blockItem("deepslate_moon_stone_ore", CobblemonBlocks.DEEPSLATE_MOON_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_SHINY_STONE_ORE = queue("deepslate_shiny_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_SHINY_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_SHINY_STONE_ORE = blockItem("deepslate_shiny_stone_ore", CobblemonBlocks.DEEPSLATE_SHINY_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_SUN_STONE_ORE = queue("deepslate_sun_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_SUN_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_SUN_STONE_ORE = blockItem("deepslate_sun_stone_ore", CobblemonBlocks.DEEPSLATE_SUN_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_THUNDER_STONE_ORE = queue("deepslate_thunder_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_THUNDER_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_THUNDER_STONE_ORE = blockItem("deepslate_thunder_stone_ore", CobblemonBlocks.DEEPSLATE_THUNDER_STONE_ORE)
|
||||
@JvmField
|
||||
val DEEPSLATE_WATER_STONE_ORE = queue("deepslate_water_stone_ore") { blockItem(CobblemonBlocks.DEEPSLATE_WATER_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DEEPSLATE_WATER_STONE_ORE = blockItem("deepslate_water_stone_ore", CobblemonBlocks.DEEPSLATE_WATER_STONE_ORE)
|
||||
@JvmField
|
||||
val DRIPSTONE_MOON_STONE_ORE = queue("dripstone_moon_stone_ore") { blockItem(CobblemonBlocks.DRIPSTONE_MOON_STONE_ORE.get(), ItemGroup.BUILDING_BLOCKS) }
|
||||
val DRIPSTONE_MOON_STONE_ORE = blockItem("dripstone_moon_stone_ore", CobblemonBlocks.DRIPSTONE_MOON_STONE_ORE)
|
||||
@JvmField
|
||||
val DAWN_STONE = this.evolutionItem("dawn_stone")
|
||||
val DAWN_STONE = noSettingsItem("dawn_stone")
|
||||
@JvmField
|
||||
val DUSK_STONE = this.evolutionItem("dusk_stone")
|
||||
val DUSK_STONE = noSettingsItem("dusk_stone")
|
||||
@JvmField
|
||||
val FIRE_STONE = this.evolutionItem("fire_stone")
|
||||
val FIRE_STONE = noSettingsItem("fire_stone")
|
||||
@JvmField
|
||||
val ICE_STONE = this.evolutionItem("ice_stone")
|
||||
val ICE_STONE = noSettingsItem("ice_stone")
|
||||
@JvmField
|
||||
val LEAF_STONE = this.evolutionItem("leaf_stone")
|
||||
val LEAF_STONE = noSettingsItem("leaf_stone")
|
||||
@JvmField
|
||||
val MOON_STONE = this.evolutionItem("moon_stone")
|
||||
val MOON_STONE = noSettingsItem("moon_stone")
|
||||
@JvmField
|
||||
val SHINY_STONE = this.evolutionItem("shiny_stone")
|
||||
val SHINY_STONE = noSettingsItem("shiny_stone")
|
||||
@JvmField
|
||||
val SUN_STONE = this.evolutionItem("sun_stone")
|
||||
val SUN_STONE = noSettingsItem("sun_stone")
|
||||
@JvmField
|
||||
val THUNDER_STONE = this.evolutionItem("thunder_stone")
|
||||
val THUNDER_STONE = noSettingsItem("thunder_stone")
|
||||
@JvmField
|
||||
val WATER_STONE = this.evolutionItem("water_stone")
|
||||
val WATER_STONE = noSettingsItem("water_stone")
|
||||
|
||||
// Held Items
|
||||
@JvmField
|
||||
val ASSAULT_VEST = this.heldItem("assault_vest")
|
||||
val ASSAULT_VEST = heldItem("assault_vest")
|
||||
@JvmField
|
||||
val BIG_ROOT = this.heldItem("big_root")
|
||||
val BIG_ROOT = blockItem("big_root", CobblemonBlocks.BIG_ROOT)
|
||||
@JvmField
|
||||
val BLACK_BELT = this.heldItem("black_belt")
|
||||
val BLACK_BELT = heldItem("black_belt")
|
||||
@JvmField
|
||||
val BLACK_GLASSES = this.heldItem("black_glasses")
|
||||
val BLACK_GLASSES = heldItem("black_glasses")
|
||||
@JvmField
|
||||
val BLACK_SLUDGE = this.heldItem("black_sludge")
|
||||
val BLACK_SLUDGE = heldItem("black_sludge")
|
||||
@JvmField
|
||||
val CHARCOAL = this.heldItem("charcoal_stick", remappedName = "charcoal")
|
||||
val CHARCOAL = heldItem("charcoal_stick", remappedName = "charcoal")
|
||||
@JvmField
|
||||
val CHOICE_BAND = this.heldItem("choice_band")
|
||||
val CHOICE_BAND = heldItem("choice_band")
|
||||
@JvmField
|
||||
val CHOICE_SCARF = this.heldItem("choice_scarf")
|
||||
val CHOICE_SCARF = heldItem("choice_scarf")
|
||||
@JvmField
|
||||
val CHOICE_SPECS = this.heldItem("choice_specs")
|
||||
val CHOICE_SPECS = heldItem("choice_specs")
|
||||
@JvmField
|
||||
val DRAGON_FANG = this.heldItem("dragon_fang")
|
||||
val DRAGON_FANG = heldItem("dragon_fang")
|
||||
@JvmField
|
||||
val EXP_SHARE = this.heldItem("exp_share")
|
||||
val EXP_SHARE = heldItem("exp_share")
|
||||
@JvmField
|
||||
val FOCUS_BAND = this.heldItem("focus_band")
|
||||
val FOCUS_BAND = heldItem("focus_band")
|
||||
@JvmField
|
||||
val HARD_STONE = this.heldItem("hard_stone")
|
||||
val HARD_STONE = heldItem("hard_stone")
|
||||
@JvmField
|
||||
val HEAVY_DUTY_BOOTS = this.heldItem("heavy_duty_boots")
|
||||
val HEAVY_DUTY_BOOTS = heldItem("heavy_duty_boots")
|
||||
@JvmField
|
||||
val LEFTOVERS = this.heldItem("leftovers")
|
||||
val LEFTOVERS = heldItem("leftovers")
|
||||
@JvmField
|
||||
val LIGHT_CLAY = this.heldItem("light_clay")
|
||||
val LIGHT_CLAY = heldItem("light_clay")
|
||||
@JvmField
|
||||
val LUCKY_EGG = this.heldItem("lucky_egg")
|
||||
val LUCKY_EGG = heldItem("lucky_egg")
|
||||
@JvmField
|
||||
val MAGNET = this.heldItem("magnet")
|
||||
val MAGNET = heldItem("magnet")
|
||||
@JvmField
|
||||
val MIRACLE_SEED = this.heldItem("miracle_seed")
|
||||
val MIRACLE_SEED = heldItem("miracle_seed")
|
||||
@JvmField
|
||||
val MUSCLE_BAND = this.heldItem("muscle_band")
|
||||
val MUSCLE_BAND = heldItem("muscle_band")
|
||||
@JvmField
|
||||
val MYSTIC_WATER = this.heldItem("mystic_water")
|
||||
val MYSTIC_WATER = heldItem("mystic_water")
|
||||
@JvmField
|
||||
val NEVER_MELT_ICE = this.heldItem("never_melt_ice")
|
||||
val NEVER_MELT_ICE = heldItem("never_melt_ice")
|
||||
@JvmField
|
||||
val POISON_BARB = this.heldItem("poison_barb")
|
||||
val POISON_BARB = heldItem("poison_barb")
|
||||
@JvmField
|
||||
val QUICK_CLAW = this.heldItem("quick_claw")
|
||||
val QUICK_CLAW = heldItem("quick_claw")
|
||||
@JvmField
|
||||
val ROCKY_HELMET = this.heldItem("rocky_helmet")
|
||||
val ROCKY_HELMET = heldItem("rocky_helmet")
|
||||
@JvmField
|
||||
val SAFETY_GOGGLES = this.heldItem("safety_goggles")
|
||||
val SAFETY_GOGGLES = heldItem("safety_goggles")
|
||||
@JvmField
|
||||
val SHARP_BEAK = this.heldItem("sharp_beak")
|
||||
val SHARP_BEAK = heldItem("sharp_beak")
|
||||
@JvmField
|
||||
val SILK_SCARF = this.heldItem("silk_scarf")
|
||||
val SILK_SCARF = heldItem("silk_scarf")
|
||||
@JvmField
|
||||
val SILVER_POWDER = this.heldItem("silver_powder")
|
||||
val SILVER_POWDER = heldItem("silver_powder")
|
||||
@JvmField
|
||||
val SOFT_SAND = this.heldItem("soft_sand")
|
||||
val SOFT_SAND = heldItem("soft_sand")
|
||||
@JvmField
|
||||
val SPELL_TAG = this.heldItem("spell_tag")
|
||||
val SPELL_TAG = heldItem("spell_tag")
|
||||
@JvmField
|
||||
val TWISTED_SPOON = this.heldItem("twisted_spoon")
|
||||
val TWISTED_SPOON = heldItem("twisted_spoon")
|
||||
@JvmField
|
||||
val WISE_GLASSES = this.heldItem("wise_glasses")
|
||||
val WISE_GLASSES = heldItem("wise_glasses")
|
||||
@JvmField
|
||||
val MENTAL_HERB = compostableHeldItem("mental_herb")
|
||||
@JvmField
|
||||
val MIRROR_HERB = compostableHeldItem("mirror_herb")
|
||||
@JvmField
|
||||
val POWER_HERB = compostableHeldItem("power_herb")
|
||||
@JvmField
|
||||
val WHITE_HERB = heldItem("white_herb")
|
||||
@JvmField
|
||||
val BRIGHT_POWDER = heldItem("bright_powder")
|
||||
@JvmField
|
||||
val METAL_POWDER = heldItem("metal_powder")
|
||||
@JvmField
|
||||
val QUICK_POWDER = heldItem("quick_powder")
|
||||
@JvmField
|
||||
val DESTINY_KNOT = heldItem("destiny_knot")
|
||||
@JvmField
|
||||
val EVERSTONE = heldItem("everstone")
|
||||
@JvmField
|
||||
val POWER_ANKLET = heldItem("power_anklet")
|
||||
@JvmField
|
||||
val POWER_BAND = heldItem("power_band")
|
||||
@JvmField
|
||||
val POWER_BELT = heldItem("power_belt")
|
||||
@JvmField
|
||||
val POWER_BRACER = heldItem("power_bracer")
|
||||
@JvmField
|
||||
val POWER_LENS = heldItem("power_lens")
|
||||
@JvmField
|
||||
val POWER_WEIGHT = heldItem("power_weight")
|
||||
|
||||
// Mulch
|
||||
@JvmField
|
||||
val MULCH_BASE = noSettingsItem("mulch_base")
|
||||
@JvmField
|
||||
val COARSE_MULCH = mulchItem("coarse_mulch", MulchVariant.COARSE)
|
||||
@JvmField
|
||||
val GROWTH_MULCH = mulchItem("growth_mulch", MulchVariant.GROWTH)
|
||||
@JvmField
|
||||
val HUMID_MULCH = mulchItem("humid_mulch", MulchVariant.HUMID)
|
||||
@JvmField
|
||||
val LOAMY_MULCH = mulchItem("loamy_mulch", MulchVariant.LOAMY)
|
||||
@JvmField
|
||||
val PEAT_MULCH = mulchItem("peat_mulch", MulchVariant.PEAT)
|
||||
@JvmField
|
||||
val RICH_MULCH = mulchItem("rich_mulch", MulchVariant.RICH)
|
||||
@JvmField
|
||||
val SANDY_MULCH = mulchItem("sandy_mulch", MulchVariant.SANDY)
|
||||
@JvmField
|
||||
val SURPRISE_MULCH = mulchItem("surprise_mulch", MulchVariant.SURPRISE)
|
||||
|
||||
// Misc
|
||||
@JvmField
|
||||
val POKEMON_MODEL = queue("pokemon_model") { PokemonItem() }
|
||||
val POKEMON_MODEL = this.create("pokemon_model", PokemonItem())
|
||||
|
||||
fun pokeballs(): List<RegistrySupplier<PokeBallItem>> = this.pokeballs
|
||||
//Keyitems
|
||||
@JvmField
|
||||
val PHOTODEX = photodexItem("photodex")
|
||||
|
||||
private fun blockItem(block: Block, tab: ItemGroup) : BlockItem {
|
||||
return BlockItem(block, Item.Settings().group(tab))
|
||||
|
||||
private fun blockItem(name: String, block: Block): BlockItem = this.create(name, BlockItem(block, Item.Settings()))
|
||||
|
||||
private fun noSettingsItem(name: String): CobblemonItem = this.create(name, CobblemonItem(Item.Settings()))
|
||||
|
||||
private fun photodexItem(name: String): PhotodexItem = this.create(name, PhotodexItem())
|
||||
|
||||
fun berries() = this.berries.toMap()
|
||||
|
||||
private fun mulchItem(name: String, mulchVariant: MulchVariant): MulchItem = this.create(name, MulchItem(mulchVariant))
|
||||
|
||||
private fun pokeBallItem(pokeBall: PokeBall): PokeBallItem {
|
||||
val item = create(pokeBall.name.path, PokeBallItem(pokeBall))
|
||||
pokeBall.item = item
|
||||
pokeBalls.add(item)
|
||||
return item
|
||||
}
|
||||
|
||||
private fun itemNameBlockItem(block: Block, tab: ItemGroup) : BlockItem {
|
||||
return AliasedBlockItem(block, Item.Settings().group(tab))
|
||||
}
|
||||
private fun candyItem(name: String, calculator: CandyItem.Calculator): CandyItem = this.create(name, CandyItem(calculator))
|
||||
|
||||
private fun evolutionItem(name: String) = queue(name) { CobblemonItem(Item.Settings().group(CobblemonItemGroups.EVOLUTION_ITEM_GROUP)) }
|
||||
|
||||
private fun pokeballItem(pokeBall: PokeBall): RegistrySupplier<PokeBallItem> {
|
||||
val supplier = this.queue(pokeBall.name.path) { PokeBallItem(pokeBall) }
|
||||
pokeBall.itemSupplier = supplier
|
||||
this.pokeballs.add(supplier)
|
||||
return supplier
|
||||
}
|
||||
|
||||
private fun heldItem(name: String, remappedName: String? = null): RegistrySupplier<CobblemonItem> = queue(name) {
|
||||
val item = CobblemonItem(Item.Settings().group(CobblemonItemGroups.HELD_ITEM_GROUP))
|
||||
if (remappedName != null) {
|
||||
CobblemonHeldItemManager.registerRemap(item, remappedName)
|
||||
private fun heldItem(name: String, remappedName: String? = null): CobblemonItem = create(
|
||||
name,
|
||||
CobblemonItem(Item.Settings()).also {
|
||||
if (remappedName != null) {
|
||||
CobblemonHeldItemManager.registerRemap(it, remappedName)
|
||||
}
|
||||
}
|
||||
return@queue item
|
||||
)
|
||||
|
||||
private fun compostable(item: Item, increaseLevelChance: Float) = Cobblemon.implementation.registerCompostable(item, increaseLevelChance)
|
||||
|
||||
private fun berryItem(name: String, berryBlock: BerryBlock): BerryItem {
|
||||
val finalName = "${name}_berry"
|
||||
val item = this.create(finalName, BerryItem(berryBlock))
|
||||
compostable(item, .65f)
|
||||
this.berries[cobblemonResource(finalName)] = item
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
private fun berryItem(name: String, berryItem: BerryItem): BerryItem {
|
||||
val finalName = "${name}_berry"
|
||||
val item = this.create(finalName, berryItem)
|
||||
compostable(item, .65f)
|
||||
this.berries[cobblemonResource(finalName)] = item
|
||||
return item
|
||||
}
|
||||
|
||||
private fun mintItem(name: String, mintItem: MintItem): MintItem {
|
||||
val item = this.create(name, mintItem)
|
||||
mints[item.nature.displayName] = item
|
||||
compostable(item, .65f)
|
||||
return item
|
||||
}
|
||||
|
||||
private fun apricronItem(name: String, apricornItem: ApricornItem): ApricornItem {
|
||||
val finalName = "${name}_apricorn"
|
||||
val item = this.create(finalName, apricornItem)
|
||||
compostable(item, .65f)
|
||||
return item
|
||||
}
|
||||
|
||||
private fun apricronSeedItem(name: String, apricronSeedItem: ApricornSeedItem): ApricornSeedItem {
|
||||
val finalName = "${name}_apricorn_seed"
|
||||
val item = this.create(finalName, apricronSeedItem)
|
||||
compostable(item, .65f)
|
||||
return item
|
||||
}
|
||||
|
||||
private fun mintSeed(name: String, mintBlock: MintBlock): Item {
|
||||
val finalName = "${name}_mint_seeds"
|
||||
val item = this.blockItem(finalName, mintBlock)
|
||||
compostable(item, .65f)
|
||||
return item
|
||||
}
|
||||
|
||||
private fun mintLeaf(name: String, mintLeafItem: MintLeafItem): MintLeafItem {
|
||||
val finalName = "${name}_mint_leaf"
|
||||
val item = this.create(finalName, mintLeafItem)
|
||||
compostable(item, .65f)
|
||||
return item
|
||||
}
|
||||
|
||||
private fun compostableItem(name: String, item: Item? = null, increaseLevelChance: Float = .65f): Item {
|
||||
val createdItem = this.create(name, item ?: Item(Item.Settings()))
|
||||
compostable(createdItem, increaseLevelChance)
|
||||
return createdItem
|
||||
}
|
||||
|
||||
private fun compostableHeldItem(name: String, remappedName: String? = null, increaseLevelChance: Float = .65f): CobblemonItem {
|
||||
val createdItem = heldItem(name, remappedName)
|
||||
compostable(createdItem, increaseLevelChance)
|
||||
return createdItem
|
||||
}
|
||||
|
||||
private fun compostableBlockItem(name: String, block: Block, increaseLevelChance: Float = .65f): Item {
|
||||
val createdItem = this.blockItem(name, block)
|
||||
compostable(createdItem, increaseLevelChance)
|
||||
return createdItem
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.bedrockk.molang.Expression
|
||||
import com.cobblemon.mod.common.api.data.DataRegistry
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.mechanics.BerriesMechanic
|
||||
import com.cobblemon.mod.common.mechanics.PotionsMechanic
|
||||
import com.cobblemon.mod.common.mechanics.RemediesMechanic
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.GsonBuilder
|
||||
import net.minecraft.resource.ResourceManager
|
||||
import net.minecraft.resource.ResourceType
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
object CobblemonMechanics : DataRegistry {
|
||||
override val id: Identifier = cobblemonResource("mechanics")
|
||||
override val type = ResourceType.SERVER_DATA
|
||||
override val observable = SimpleObservable<CobblemonMechanics>()
|
||||
val gson = GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
|
||||
.create()
|
||||
|
||||
var remedies = RemediesMechanic()
|
||||
var berries = BerriesMechanic()
|
||||
var potions = PotionsMechanic()
|
||||
|
||||
override fun sync(player: ServerPlayerEntity) {}
|
||||
override fun reload(manager: ResourceManager) {
|
||||
remedies = loadMechanic(manager, "remedies", RemediesMechanic::class.java)
|
||||
berries = loadMechanic(manager, "berries", BerriesMechanic::class.java)
|
||||
potions = loadMechanic(manager, "potions", PotionsMechanic::class.java)
|
||||
}
|
||||
|
||||
private fun <T> loadMechanic(manager: ResourceManager, name: String, clazz: Class<T>): T {
|
||||
manager.getResourceOrThrow(cobblemonResource("mechanics/$name.json")).inputStream.use {
|
||||
return gson.fromJson(it.reader(), clazz)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,35 +8,73 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattlePersistentStatusPacket
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.net.MessageBuiltEvent
|
||||
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.net.PacketHandler
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleApplyCaptureResponsePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleCaptureEndPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleCaptureShakePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleCaptureStartPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleEndPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleFaintPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleHealthChangePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleInitializePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleQueueRequestPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleSetTeamPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleSwitchPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleUpdateTeamPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.ChallengeNotificationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.*
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.SetClientPlayerDataHandler
|
||||
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.data.DataRegistrySyncPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.data.UnlockReloadPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormParticleHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.InteractPokemonUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.SummaryUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.ClosePastureHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.OpenPastureHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.PokemonPasturedHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.PokemonUnpasturedHandler
|
||||
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
|
||||
import com.cobblemon.mod.common.client.net.settings.ServerSettingsPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.sound.PokemonCryHandler
|
||||
import com.cobblemon.mod.common.client.net.sound.UnvalidatedPlaySoundS2CPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.spawn.SpawnExtraDataEntityHandler
|
||||
import com.cobblemon.mod.common.client.net.starter.StarterUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.RemoveClientPokemonHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.SwapClientPokemonHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.party.InitializePartyHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.party.MoveClientPartyPokemonHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.party.SetPartyPokemonHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.party.SetPartyReferenceHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.pc.ClosePCHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.pc.InitializePCHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.pc.MoveClientPCPokemonHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.pc.OpenPCHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.pc.SetPCBoxPokemonHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.pc.SetPCPokemonHandler
|
||||
import com.cobblemon.mod.common.client.net.toast.ToastPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeAcceptanceChangedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeCancelledHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeCompletedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeOfferExpiredHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeOfferNotificationHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
|
||||
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.data.AbilityRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.BerryRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.MovesRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.PropertiesCompletionRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.SpeciesRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.data.UnlockReloadPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.ClosePasturePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.OpenPasturePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonPasturedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonUnpasturedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.*
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.AddEvolutionPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.ClearEvolutionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.RemoveEvolutionPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.sound.PokemonCryPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokeballPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.starter.OpenStarterUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.starter.SetClientPlayerDataPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.RemoveClientPokemonPacket
|
||||
@@ -51,6 +89,14 @@ import com.cobblemon.mod.common.net.messages.client.storage.pc.MoveClientPCPokem
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.OpenPCPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCBoxPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.toast.ToastPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeAcceptanceChangedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeCancelledPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeCompletedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferExpiredPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferNotificationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeUpdatedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
|
||||
@@ -59,195 +105,308 @@ import com.cobblemon.mod.common.net.messages.server.RequestMoveSwapPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.SelectStarterPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.SendOutPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleSelectActionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectCancelledPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectedPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.party.PartyPokemonSelectedPacket
|
||||
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.pasture.PasturePokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pasture.UnpastureAllPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pasture.UnpasturePokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.interact.InteractPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.evolution.AcceptEvolutionPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.starter.RequestStarterScreenPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.SwapPCPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.ReleasePartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.SwapPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.*
|
||||
import com.cobblemon.mod.common.util.getServer
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonToPartyPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePartyPokemonToPCPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.ReleasePCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.SwapPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.UnlinkPlayerFromPCPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.AcceptTradeRequestPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.CancelTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.ChangeTradeAcceptancePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
|
||||
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectCancelledHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectedHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.party.PartyPokemonSelectedHandler
|
||||
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.evolution.AcceptEvolutionHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pasture.PasturePokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pasture.UnpastureAllPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pasture.UnpasturePokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.interact.InteractPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetNicknameHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.starter.RequestStarterScreenHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.starter.SelectStarterPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.BenchMoveHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.RequestMoveSwapHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.SendOutPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.SwapPCPartyPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.party.MovePartyPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.party.ReleasePCPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.party.SwapPartyPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.pc.MovePCPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.pc.MovePCPokemonToPartyHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.pc.MovePartyPokemonToPCHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.pc.ReleasePartyPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.pc.SwapPCPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.pc.UnlinkPlayerFromPCHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.AcceptTradeRequestHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.CancelTradeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.ChangeTradeAcceptanceHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.OfferTradeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import kotlin.reflect.KClass
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.network.listener.ClientPlayPacketListener
|
||||
import net.minecraft.network.packet.Packet
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
/**
|
||||
* Registers Cobblemon packets. Packet handlers are set up on handling the [MessageBuiltEvent] dispatched from here.
|
||||
* Registers Cobblemon network packets.
|
||||
*
|
||||
* This class also contains short functions for dispatching our packets to a player, all players, or to the entire server.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @author Hiroku, Licious
|
||||
* @since November 27th, 2021
|
||||
*/
|
||||
object CobblemonNetwork {
|
||||
const val PROTOCOL_VERSION = "1"
|
||||
object CobblemonNetwork : NetworkManager {
|
||||
|
||||
var clientHandlersRegistered = CompletableFuture<Unit>()
|
||||
var serverHandlersRegistered = CompletableFuture<Unit>()
|
||||
|
||||
init {
|
||||
clientHandlersRegistered.runAfterBoth(serverHandlersRegistered) { register() }
|
||||
}
|
||||
|
||||
lateinit var networkDelegate: NetworkDelegate
|
||||
|
||||
|
||||
fun ServerPlayerEntity.sendPacket(packet: NetworkPacket) = sendToPlayer(this, packet)
|
||||
fun sendToPlayer(player: ServerPlayerEntity, packet: NetworkPacket) = networkDelegate.sendPacketToPlayer(player, packet)
|
||||
fun sendToServer(packet: NetworkPacket) = networkDelegate.sendPacketToServer(packet)
|
||||
fun sendToAllPlayers(packet: NetworkPacket) = sendToPlayers(getServer()!!.playerManager.playerList, packet)
|
||||
fun sendToPlayers(players: Iterable<ServerPlayerEntity>, packet: NetworkPacket) = players.forEach { sendToPlayer(it, packet) }
|
||||
|
||||
interface PreparedMessage<T : NetworkPacket> {
|
||||
fun registerMessage()
|
||||
fun registerHandler(handler: PacketHandler<T>)
|
||||
}
|
||||
|
||||
interface NetworkContext {
|
||||
val player: ServerPlayerEntity?
|
||||
}
|
||||
|
||||
|
||||
fun register() {
|
||||
// Don't forget to register handlers in either ClientPacketRegistrar or ServerPacketRegistrar!
|
||||
|
||||
/**
|
||||
* Client Packets
|
||||
*/
|
||||
fun ServerPlayerEntity.sendPacket(packet: NetworkPacket<*>) = sendPacketToPlayer(this, packet)
|
||||
fun sendToServer(packet: NetworkPacket<*>) = this.sendPacketToServer(packet)
|
||||
fun sendToAllPlayers(packet: NetworkPacket<*>) = sendPacketToPlayers(server()!!.playerManager.playerList, packet)
|
||||
fun sendPacketToPlayers(players: Iterable<ServerPlayerEntity>, packet: NetworkPacket<*>) = players.forEach { sendPacketToPlayer(it, packet) }
|
||||
|
||||
override fun registerClientBound() {
|
||||
// Pokemon Update Packets
|
||||
buildClientMessage<FriendshipUpdatePacket>()
|
||||
buildClientMessage<MoveSetUpdatePacket>()
|
||||
buildClientMessage<NatureUpdatePacket>()
|
||||
buildClientMessage<ShinyUpdatePacket>()
|
||||
buildClientMessage<SpeciesUpdatePacket>()
|
||||
buildClientMessage<HealthUpdatePacket>()
|
||||
buildClientMessage<ExperienceUpdatePacket>()
|
||||
buildClientMessage<StatusUpdatePacket>()
|
||||
buildClientMessage<CaughtBallUpdatePacket>()
|
||||
buildClientMessage<BenchedMovesUpdatePacket>()
|
||||
buildClientMessage<GenderUpdatePacket>()
|
||||
buildClientMessage<AspectsUpdatePacket>()
|
||||
buildClientMessage<AbilityUpdatePacket>()
|
||||
buildClientMessage<EVsUpdatePacket>()
|
||||
buildClientMessage<IVsUpdatePacket>()
|
||||
buildClientMessage<HeldItemUpdatePacket>()
|
||||
this.createClientBound(FriendshipUpdatePacket.ID, FriendshipUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(MoveSetUpdatePacket.ID, MoveSetUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(NatureUpdatePacket.ID, NatureUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(ShinyUpdatePacket.ID, ShinyUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(SpeciesUpdatePacket.ID, SpeciesUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(NicknameUpdatePacket.ID, NicknameUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(HealthUpdatePacket.ID, HealthUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(ExperienceUpdatePacket.ID, ExperienceUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(StatusUpdatePacket.ID, StatusUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(CaughtBallUpdatePacket.ID, CaughtBallUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(BenchedMovesUpdatePacket.ID, BenchedMovesUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(GenderUpdatePacket.ID, GenderUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(AspectsUpdatePacket.ID, AspectsUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(AbilityUpdatePacket.ID, AbilityUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(EVsUpdatePacket.ID, EVsUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(IVsUpdatePacket.ID, IVsUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(HeldItemUpdatePacket.ID, HeldItemUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(PokemonStateUpdatePacket.ID, PokemonStateUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(TetheringUpdatePacket.ID, TetheringUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(TradeableUpdatePacket.ID, TradeableUpdatePacket::decode, PokemonUpdatePacketHandler())
|
||||
|
||||
// Evolution start
|
||||
buildClientMessage<AddEvolutionPacket>()
|
||||
buildClientMessage<ClearEvolutionsPacket>()
|
||||
buildClientMessage<RemoveEvolutionPacket>()
|
||||
this.createClientBound(AddEvolutionPacket.ID, AddEvolutionPacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(ClearEvolutionsPacket.ID, ClearEvolutionsPacket::decode, PokemonUpdatePacketHandler())
|
||||
this.createClientBound(RemoveEvolutionPacket.ID, RemoveEvolutionPacket::decode, PokemonUpdatePacketHandler())
|
||||
// Evolution End
|
||||
|
||||
buildClientMessage<PokemonStateUpdatePacket>()
|
||||
|
||||
// Storage Packets
|
||||
buildClientMessage<InitializePartyPacket>()
|
||||
buildClientMessage<SetPartyPokemonPacket>()
|
||||
buildClientMessage<MoveClientPartyPokemonPacket>()
|
||||
buildClientMessage<SetPartyReferencePacket>()
|
||||
this.createClientBound(InitializePartyPacket.ID, InitializePartyPacket::decode, InitializePartyHandler)
|
||||
this.createClientBound(SetPartyPokemonPacket.ID, SetPartyPokemonPacket::decode, SetPartyPokemonHandler)
|
||||
this.createClientBound(MoveClientPartyPokemonPacket.ID, MoveClientPartyPokemonPacket::decode, MoveClientPartyPokemonHandler)
|
||||
this.createClientBound(SetPartyReferencePacket.ID, SetPartyReferencePacket::decode, SetPartyReferenceHandler)
|
||||
|
||||
buildClientMessage<InitializePCPacket>()
|
||||
buildClientMessage<MoveClientPCPokemonPacket>()
|
||||
buildClientMessage<SetPCBoxPokemonPacket>()
|
||||
buildClientMessage<SetPCPokemonPacket>()
|
||||
buildClientMessage<OpenPCPacket>()
|
||||
buildClientMessage<ClosePCPacket>()
|
||||
this.createClientBound(InitializePCPacket.ID, InitializePCPacket::decode, InitializePCHandler)
|
||||
this.createClientBound(MoveClientPCPokemonPacket.ID, MoveClientPCPokemonPacket::decode, MoveClientPCPokemonHandler)
|
||||
this.createClientBound(SetPCBoxPokemonPacket.ID, SetPCBoxPokemonPacket::decode, SetPCBoxPokemonHandler)
|
||||
this.createClientBound(SetPCPokemonPacket.ID, SetPCPokemonPacket::decode, SetPCPokemonHandler)
|
||||
this.createClientBound(OpenPCPacket.ID, OpenPCPacket::decode, OpenPCHandler)
|
||||
this.createClientBound(ClosePCPacket.ID, ClosePCPacket::decode, ClosePCHandler)
|
||||
|
||||
buildClientMessage<SwapClientPokemonPacket>()
|
||||
buildClientMessage<RemoveClientPokemonPacket>()
|
||||
this.createClientBound(SwapClientPokemonPacket.ID, SwapClientPokemonPacket::decode, SwapClientPokemonHandler)
|
||||
this.createClientBound(RemoveClientPokemonPacket.ID, RemoveClientPokemonPacket::decode, RemoveClientPokemonHandler)
|
||||
|
||||
// UI Packets
|
||||
buildClientMessage<SummaryUIPacket>()
|
||||
buildClientMessage<InteractPokemonUIPacket>()
|
||||
this.createClientBound(SummaryUIPacket.ID, SummaryUIPacket::decode, SummaryUIPacketHandler)
|
||||
this.createClientBound(InteractPokemonUIPacket.ID, InteractPokemonUIPacket::decode, InteractPokemonUIPacketHandler)
|
||||
|
||||
// Starter packets
|
||||
buildClientMessage<OpenStarterUIPacket>()
|
||||
buildClientMessage<SetClientPlayerDataPacket>()
|
||||
this.createClientBound(OpenStarterUIPacket.ID, OpenStarterUIPacket::decode, StarterUIPacketHandler)
|
||||
this.createClientBound(SetClientPlayerDataPacket.ID, SetClientPlayerDataPacket::decode, SetClientPlayerDataHandler)
|
||||
|
||||
// Battle packets
|
||||
buildClientMessage<BattleEndPacket>()
|
||||
buildClientMessage<BattleInitializePacket>()
|
||||
buildClientMessage<BattleQueueRequestPacket>()
|
||||
buildClientMessage<BattleFaintPacket>()
|
||||
buildClientMessage<BattleMakeChoicePacket>()
|
||||
buildClientMessage<BattleHealthChangePacket>()
|
||||
buildClientMessage<BattleSetTeamPokemonPacket>()
|
||||
buildClientMessage<BattleSwitchPokemonPacket>()
|
||||
buildClientMessage<BattleMessagePacket>()
|
||||
buildClientMessage<BattleCaptureStartPacket>()
|
||||
buildClientMessage<BattleCaptureEndPacket>()
|
||||
buildClientMessage<BattleCaptureShakePacket>()
|
||||
buildClientMessage<BattleApplyCaptureResponsePacket>()
|
||||
buildClientMessage<ChallengeNotificationPacket>()
|
||||
buildClientMessage<BattleUpdateTeamPokemonPacket>()
|
||||
buildClientMessage<BattlePersistentStatusPacket>()
|
||||
this.createClientBound(BattleEndPacket.ID, BattleEndPacket::decode, BattleEndHandler)
|
||||
this.createClientBound(BattleInitializePacket.ID, BattleInitializePacket::decode, BattleInitializeHandler)
|
||||
this.createClientBound(BattleQueueRequestPacket.ID, BattleQueueRequestPacket::decode, BattleQueueRequestHandler)
|
||||
this.createClientBound(BattleFaintPacket.ID, BattleFaintPacket::decode, BattleFaintHandler)
|
||||
this.createClientBound(BattleMakeChoicePacket.ID, BattleMakeChoicePacket::decode, BattleMakeChoiceHandler)
|
||||
this.createClientBound(BattleHealthChangePacket.ID, BattleHealthChangePacket::decode, BattleHealthChangeHandler)
|
||||
this.createClientBound(BattleSetTeamPokemonPacket.ID, BattleSetTeamPokemonPacket::decode, BattleSetTeamPokemonHandler)
|
||||
this.createClientBound(BattleSwitchPokemonPacket.ID, BattleSwitchPokemonPacket::decode, BattleSwitchPokemonHandler)
|
||||
this.createClientBound(BattleMessagePacket.ID, BattleMessagePacket::decode, BattleMessageHandler)
|
||||
this.createClientBound(BattleCaptureStartPacket.ID, BattleCaptureStartPacket::decode, BattleCaptureStartHandler)
|
||||
this.createClientBound(BattleCaptureEndPacket.ID, BattleCaptureEndPacket::decode, BattleCaptureEndHandler)
|
||||
this.createClientBound(BattleCaptureShakePacket.ID, BattleCaptureShakePacket::decode, BattleCaptureShakeHandler)
|
||||
this.createClientBound(BattleApplyPassResponsePacket.ID, BattleApplyPassResponsePacket::decode, BattleApplyPassResponseHandler)
|
||||
this.createClientBound(BattleChallengeNotificationPacket.ID, BattleChallengeNotificationPacket::decode, BattleChallengeNotificationHandler)
|
||||
this.createClientBound(BattleUpdateTeamPokemonPacket.ID, BattleUpdateTeamPokemonPacket::decode, BattleUpdateTeamPokemonHandler)
|
||||
this.createClientBound(BattlePersistentStatusPacket.ID, BattlePersistentStatusPacket::decode, BattlePersistentStatusHandler)
|
||||
this.createClientBound(BattleMadeInvalidChoicePacket.ID, BattleMadeInvalidChoicePacket::decode, BattleMadeInvalidChoiceHandler)
|
||||
this.createClientBound(BattleMusicPacket.ID, BattleMusicPacket::decode, BattleMusicHandler)
|
||||
this.createClientBound(BattleChallengeExpiredPacket.ID, BattleChallengeExpiredPacket::decode, BattleChallengeExpiredHandler)
|
||||
|
||||
|
||||
|
||||
// Settings packets
|
||||
buildClientMessage<ServerSettingsPacket>()
|
||||
this.createClientBound(ServerSettingsPacket.ID, ServerSettingsPacket::decode, ServerSettingsPacketHandler)
|
||||
|
||||
// Data registries
|
||||
buildClientMessage<UnlockReloadPacket>()
|
||||
buildClientMessage<AbilityRegistrySyncPacket>()
|
||||
buildClientMessage<MovesRegistrySyncPacket>()
|
||||
buildClientMessage<SpeciesRegistrySyncPacket>()
|
||||
buildClientMessage<PropertiesCompletionRegistrySyncPacket>()
|
||||
this.createClientBound(AbilityRegistrySyncPacket.ID, AbilityRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(MovesRegistrySyncPacket.ID, MovesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(SpeciesRegistrySyncPacket.ID, SpeciesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(PropertiesCompletionRegistrySyncPacket.ID, PropertiesCompletionRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
this.createClientBound(UnlockReloadPacket.ID, UnlockReloadPacket::decode, UnlockReloadPacketHandler)
|
||||
this.createClientBound(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler())
|
||||
|
||||
// Effects
|
||||
buildClientMessage<SpawnSnowstormParticlePacket>()
|
||||
this.createClientBound(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler)
|
||||
|
||||
// Hax
|
||||
buildClientMessage<UnvalidatedPlaySoundS2CPacket>()
|
||||
this.createClientBound(UnvalidatedPlaySoundS2CPacket.ID, UnvalidatedPlaySoundS2CPacket::decode, UnvalidatedPlaySoundS2CPacketHandler)
|
||||
this.createClientBound(SpawnPokemonPacket.ID, SpawnPokemonPacket::decode, SpawnExtraDataEntityHandler())
|
||||
this.createClientBound(SpawnPokeballPacket.ID, SpawnPokeballPacket::decode, SpawnExtraDataEntityHandler())
|
||||
this.createClientBound(ToastPacket.ID, ToastPacket::decode, ToastPacketHandler)
|
||||
|
||||
/**
|
||||
* Server Packets
|
||||
*/
|
||||
// Trade packets
|
||||
this.createClientBound(TradeAcceptanceChangedPacket.ID, TradeAcceptanceChangedPacket::decode, TradeAcceptanceChangedHandler)
|
||||
this.createClientBound(TradeCancelledPacket.ID, TradeCancelledPacket::decode, TradeCancelledHandler)
|
||||
this.createClientBound(TradeCompletedPacket.ID, TradeCompletedPacket::decode, TradeCompletedHandler)
|
||||
this.createClientBound(TradeUpdatedPacket.ID, TradeUpdatedPacket::decode, TradeUpdatedHandler)
|
||||
this.createClientBound(TradeOfferNotificationPacket.ID, TradeOfferNotificationPacket::decode, TradeOfferNotificationHandler)
|
||||
this.createClientBound(TradeOfferExpiredPacket.ID, TradeOfferExpiredPacket::decode, TradeOfferExpiredHandler)
|
||||
this.createClientBound(TradeStartedPacket.ID, TradeStartedPacket::decode, TradeStartedHandler)
|
||||
|
||||
// Pasture
|
||||
this.createClientBound(OpenPasturePacket.ID, OpenPasturePacket::decode, OpenPastureHandler)
|
||||
this.createClientBound(ClosePasturePacket.ID, ClosePasturePacket::decode, ClosePastureHandler)
|
||||
this.createClientBound(PokemonPasturedPacket.ID, PokemonPasturedPacket::decode, PokemonPasturedHandler)
|
||||
this.createClientBound(PokemonUnpasturedPacket.ID, PokemonUnpasturedPacket::decode, PokemonUnpasturedHandler)
|
||||
|
||||
// Behaviours
|
||||
this.createClientBound(PokemonCryPacket.ID, PokemonCryPacket::decode, PokemonCryHandler)
|
||||
|
||||
// Move select packets
|
||||
this.createClientBound(OpenMoveCallbackPacket.ID, OpenMoveCallbackPacket::decode, OpenMoveCallbackHandler)
|
||||
|
||||
// Party select packets
|
||||
this.createClientBound(OpenPartyCallbackPacket.ID, OpenPartyCallbackPacket::decode, OpenPartyCallbackHandler)
|
||||
|
||||
// Party move select packets
|
||||
this.createClientBound(OpenPartyMoveCallbackPacket.ID, OpenPartyMoveCallbackPacket::decode, OpenPartyMoveCallbackHandler)
|
||||
}
|
||||
|
||||
override fun registerServerBound() {
|
||||
// Pokemon Update Packets
|
||||
// Evolution start
|
||||
buildServerMessage<AcceptEvolutionPacket>()
|
||||
// Evolution End
|
||||
this.createServerBound(SetNicknamePacket.ID, SetNicknamePacket::decode, SetNicknameHandler)
|
||||
|
||||
// Evolution Packets
|
||||
this.createServerBound(AcceptEvolutionPacket.ID, AcceptEvolutionPacket::decode, AcceptEvolutionHandler)
|
||||
|
||||
// Interaction Packets
|
||||
buildServerMessage<InteractPokemonPacket>()
|
||||
this.createServerBound(InteractPokemonPacket.ID, InteractPokemonPacket::decode, InteractPokemonHandler)
|
||||
|
||||
// Storage Packets
|
||||
buildServerMessage<SendOutPokemonPacket>()
|
||||
buildServerMessage<RequestMoveSwapPacket>()
|
||||
buildServerMessage<BenchMovePacket>()
|
||||
buildServerMessage<BattleChallengePacket>()
|
||||
this.createServerBound(SendOutPokemonPacket.ID, SendOutPokemonPacket::decode, SendOutPokemonHandler)
|
||||
this.createServerBound(RequestMoveSwapPacket.ID, RequestMoveSwapPacket::decode, RequestMoveSwapHandler)
|
||||
this.createServerBound(BenchMovePacket.ID, BenchMovePacket::decode, BenchMoveHandler)
|
||||
this.createServerBound(BattleChallengePacket.ID, BattleChallengePacket::decode, ChallengeHandler)
|
||||
|
||||
buildServerMessage<MovePCPokemonToPartyPacket>()
|
||||
buildServerMessage<MovePartyPokemonToPCPacket>()
|
||||
buildServerMessage<ReleasePartyPokemonPacket>()
|
||||
buildServerMessage<ReleasePCPokemonPacket>()
|
||||
buildServerMessage<UnlinkPlayerFromPCPacket>()
|
||||
this.createServerBound(MovePCPokemonToPartyPacket.ID, MovePCPokemonToPartyPacket::decode, MovePCPokemonToPartyHandler)
|
||||
this.createServerBound(MovePartyPokemonToPCPacket.ID, MovePartyPokemonToPCPacket::decode, MovePartyPokemonToPCHandler)
|
||||
this.createServerBound(ReleasePartyPokemonPacket.ID, ReleasePartyPokemonPacket::decode, ReleasePartyPokemonHandler)
|
||||
this.createServerBound(ReleasePCPokemonPacket.ID, ReleasePCPokemonPacket::decode, ReleasePCPokemonHandler)
|
||||
this.createServerBound(UnlinkPlayerFromPCPacket.ID, UnlinkPlayerFromPCPacket::decode, UnlinkPlayerFromPCHandler)
|
||||
|
||||
// Starter packets
|
||||
buildServerMessage<SelectStarterPacket>()
|
||||
buildServerMessage<RequestStarterScreenPacket>()
|
||||
this.createServerBound(SelectStarterPacket.ID, SelectStarterPacket::decode, SelectStarterPacketHandler)
|
||||
this.createServerBound(RequestStarterScreenPacket.ID, RequestStarterScreenPacket::decode, RequestStarterScreenHandler)
|
||||
|
||||
buildServerMessage<SwapPCPokemonPacket>()
|
||||
buildServerMessage<SwapPartyPokemonPacket>()
|
||||
this.createServerBound(SwapPCPokemonPacket.ID, SwapPCPokemonPacket::decode, SwapPCPokemonHandler)
|
||||
this.createServerBound(SwapPartyPokemonPacket.ID, SwapPartyPokemonPacket::decode, SwapPartyPokemonHandler)
|
||||
|
||||
buildServerMessage<MovePCPokemonPacket>()
|
||||
buildServerMessage<MovePartyPokemonPacket>()
|
||||
this.createServerBound(MovePCPokemonPacket.ID, MovePCPokemonPacket::decode, MovePCPokemonHandler)
|
||||
this.createServerBound(MovePartyPokemonPacket.ID, MovePartyPokemonPacket::decode, MovePartyPokemonHandler)
|
||||
|
||||
buildServerMessage<SwapPCPartyPokemonPacket>()
|
||||
this.createServerBound(SwapPCPartyPokemonPacket.ID, SwapPCPartyPokemonPacket::decode, SwapPCPartyPokemonHandler)
|
||||
|
||||
// Battle packets
|
||||
buildServerMessage<BattleSelectActionsPacket>()
|
||||
this.createServerBound(BattleSelectActionsPacket.ID, BattleSelectActionsPacket::decode, BattleSelectActionsHandler)
|
||||
|
||||
// Trade
|
||||
this.createServerBound(AcceptTradeRequestPacket.ID, AcceptTradeRequestPacket::decode, AcceptTradeRequestHandler)
|
||||
this.createServerBound(CancelTradePacket.ID, CancelTradePacket::decode, CancelTradeHandler)
|
||||
this.createServerBound(ChangeTradeAcceptancePacket.ID, ChangeTradeAcceptancePacket::decode, ChangeTradeAcceptanceHandler)
|
||||
this.createServerBound(OfferTradePacket.ID, OfferTradePacket::decode, OfferTradeHandler)
|
||||
this.createServerBound(UpdateTradeOfferPacket.ID, UpdateTradeOfferPacket::decode, UpdateTradeOfferHandler)
|
||||
|
||||
// Pasture
|
||||
this.createServerBound(PasturePokemonPacket.ID, PasturePokemonPacket::decode, PasturePokemonHandler)
|
||||
this.createServerBound(UnpasturePokemonPacket.ID, UnpasturePokemonPacket::decode, UnpasturePokemonHandler)
|
||||
this.createServerBound(UnpastureAllPokemonPacket.ID, UnpastureAllPokemonPacket::decode, UnpastureAllPokemonHandler)
|
||||
|
||||
// Move select packets
|
||||
this.createServerBound(MoveSelectedPacket.ID, MoveSelectedPacket::decode, MoveSelectedHandler)
|
||||
this.createServerBound(MoveSelectCancelledPacket.ID, MoveSelectCancelledPacket::decode, MoveSelectCancelledHandler)
|
||||
|
||||
// Party select packets
|
||||
this.createServerBound(PartyPokemonSelectedPacket.ID, PartyPokemonSelectedPacket::decode, PartyPokemonSelectedHandler)
|
||||
this.createServerBound(PartySelectCancelledPacket.ID, PartySelectCancelledPacket::decode, PartySelectCancelledHandler)
|
||||
|
||||
// Party move select packets
|
||||
this.createServerBound(PartyPokemonMoveSelectedPacket.ID, PartyPokemonMoveSelectedPacket::decode, PartyPokemonMoveSelectedHandler)
|
||||
this.createServerBound(PartyMoveSelectCancelledPacket.ID, PartyMoveSelectCancelledPacket::decode, PartyMoveSelectCancelledHandler)
|
||||
}
|
||||
|
||||
private inline fun <reified P : NetworkPacket> buildClientMessage() =
|
||||
buildMessage<P>(toServer = false)
|
||||
private inline fun <reified P : NetworkPacket> buildServerMessage() =
|
||||
buildMessage<P>(toServer = true)
|
||||
|
||||
private inline fun <reified P : NetworkPacket> buildMessage(toServer: Boolean) {
|
||||
val message = networkDelegate.buildMessage(P::class.java, toServer)
|
||||
// Gives client or server the chance to attach its packet handler
|
||||
CobblemonEvents.MESSAGE_BUILT.post(MessageBuiltEvent(P::class.java, toServer, message))
|
||||
message.registerMessage()
|
||||
private inline fun <reified T : NetworkPacket<T>> createClientBound(identifier: Identifier, noinline decoder: (PacketByteBuf) -> T, handler: ClientNetworkPacketHandler<T>) {
|
||||
Cobblemon.implementation.networkManager.createClientBound(identifier, T::class, { message, buffer -> message.encode(buffer) }, decoder, handler)
|
||||
}
|
||||
|
||||
private inline fun <reified T : NetworkPacket<T>> createServerBound(identifier: Identifier, noinline decoder: (PacketByteBuf) -> T, handler: ServerNetworkPacketHandler<T>) {
|
||||
Cobblemon.implementation.networkManager.createServerBound(identifier, T::class, { message, buffer -> message.encode(buffer) }, decoder, handler)
|
||||
}
|
||||
|
||||
override fun <T : NetworkPacket<T>> createClientBound(
|
||||
identifier: Identifier,
|
||||
kClass: KClass<T>,
|
||||
encoder: (T, PacketByteBuf) -> Unit,
|
||||
decoder: (PacketByteBuf) -> T,
|
||||
handler: ClientNetworkPacketHandler<T>
|
||||
) {
|
||||
Cobblemon.implementation.networkManager.createClientBound(identifier, kClass, encoder, decoder, handler)
|
||||
}
|
||||
|
||||
override fun <T : NetworkPacket<T>> createServerBound(
|
||||
identifier: Identifier,
|
||||
kClass: KClass<T>,
|
||||
encoder: (T, PacketByteBuf) -> Unit,
|
||||
decoder: (PacketByteBuf) -> T,
|
||||
handler: ServerNetworkPacketHandler<T>
|
||||
) {
|
||||
Cobblemon.implementation.networkManager.createServerBound(identifier, kClass, encoder, decoder, handler)
|
||||
}
|
||||
|
||||
override fun sendPacketToPlayer(player: ServerPlayerEntity, packet: NetworkPacket<*>) = Cobblemon.implementation.networkManager.sendPacketToPlayer(player, packet)
|
||||
|
||||
override fun sendPacketToServer(packet: NetworkPacket<*>) = Cobblemon.implementation.networkManager.sendPacketToServer(packet)
|
||||
|
||||
override fun <T : NetworkPacket<*>> asVanillaClientBound(packet: T): Packet<ClientPlayPacketListener> = Cobblemon.implementation.networkManager.asVanillaClientBound(packet)
|
||||
}
|
||||
@@ -1,73 +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
|
||||
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import dev.architectury.registry.level.biome.BiomeModifications
|
||||
import net.minecraft.util.registry.RegistryEntry
|
||||
import net.minecraft.util.registry.RegistryEntryList
|
||||
import net.minecraft.world.gen.GenerationStep
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeatures
|
||||
import net.minecraft.world.gen.feature.Feature
|
||||
import net.minecraft.world.gen.feature.PlacedFeature
|
||||
import net.minecraft.world.gen.feature.PlacedFeatures
|
||||
import net.minecraft.world.gen.feature.SimpleRandomFeatureConfig
|
||||
import net.minecraft.world.gen.feature.VegetationPlacedFeatures
|
||||
import net.minecraft.world.gen.placementmodifier.RarityFilterPlacementModifier
|
||||
|
||||
object CobblemonPlacements {
|
||||
|
||||
lateinit var BLACK_APRICORN_TREE: RegistryEntry<PlacedFeature>
|
||||
lateinit var BLUE_APRICORN_TREE: RegistryEntry<PlacedFeature>
|
||||
lateinit var GREEN_APRICORN_TREE: RegistryEntry<PlacedFeature>
|
||||
lateinit var PINK_APRICORN_TREE: RegistryEntry<PlacedFeature>
|
||||
lateinit var RED_APRICORN_TREE: RegistryEntry<PlacedFeature>
|
||||
lateinit var WHITE_APRICORN_TREE: RegistryEntry<PlacedFeature>
|
||||
lateinit var YELLOW_APRICORN_TREE: RegistryEntry<PlacedFeature>
|
||||
|
||||
lateinit var APRICORN_TREES: RegistryEntry<PlacedFeature>
|
||||
|
||||
fun register() {
|
||||
BLACK_APRICORN_TREE = PlacedFeatures.register(cobblemonResource("black_apricorn_tree").toString(), CobblemonConfiguredFeatures.BLACK_APRICORN_TREE, PlacedFeatures.wouldSurvive(
|
||||
CobblemonBlocks.BLACK_APRICORN_SAPLING.get()))
|
||||
BLUE_APRICORN_TREE = PlacedFeatures.register(cobblemonResource("blue_apricorn_tree").toString(), CobblemonConfiguredFeatures.BLUE_APRICORN_TREE, PlacedFeatures.wouldSurvive(
|
||||
CobblemonBlocks.BLUE_APRICORN_SAPLING.get()))
|
||||
GREEN_APRICORN_TREE = PlacedFeatures.register(cobblemonResource("green_apricorn_tree").toString(), CobblemonConfiguredFeatures.GREEN_APRICORN_TREE, PlacedFeatures.wouldSurvive(
|
||||
CobblemonBlocks.GREEN_APRICORN_SAPLING.get()))
|
||||
PINK_APRICORN_TREE = PlacedFeatures.register(cobblemonResource("pink_apricorn_tree").toString(), CobblemonConfiguredFeatures.PINK_APRICORN_TREE, PlacedFeatures.wouldSurvive(
|
||||
CobblemonBlocks.PINK_APRICORN_SAPLING.get()))
|
||||
RED_APRICORN_TREE = PlacedFeatures.register(cobblemonResource("red_apricorn_tree").toString(), CobblemonConfiguredFeatures.RED_APRICORN_TREE, PlacedFeatures.wouldSurvive(
|
||||
CobblemonBlocks.RED_APRICORN_SAPLING.get()))
|
||||
WHITE_APRICORN_TREE = PlacedFeatures.register(cobblemonResource("white_apricorn_tree").toString(), CobblemonConfiguredFeatures.WHITE_APRICORN_TREE, PlacedFeatures.wouldSurvive(
|
||||
CobblemonBlocks.WHITE_APRICORN_SAPLING.get()))
|
||||
YELLOW_APRICORN_TREE = PlacedFeatures.register(cobblemonResource("yellow_apricorn_tree").toString(), CobblemonConfiguredFeatures.YELLOW_APRICORN_TREE, PlacedFeatures.wouldSurvive(
|
||||
CobblemonBlocks.YELLOW_APRICORN_SAPLING.get()))
|
||||
|
||||
val apricornTreeVariety = ConfiguredFeatures.register(
|
||||
cobblemonResource("apricorn_trees").toString(), Feature.SIMPLE_RANDOM_SELECTOR, SimpleRandomFeatureConfig(
|
||||
RegistryEntryList.of(
|
||||
BLACK_APRICORN_TREE,
|
||||
BLUE_APRICORN_TREE,
|
||||
GREEN_APRICORN_TREE,
|
||||
PINK_APRICORN_TREE,
|
||||
RED_APRICORN_TREE,
|
||||
WHITE_APRICORN_TREE,
|
||||
YELLOW_APRICORN_TREE
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
APRICORN_TREES = PlacedFeatures.register(cobblemonResource("apricorn_trees").toString(), apricornTreeVariety, VegetationPlacedFeatures.modifiers(RarityFilterPlacementModifier.of(8)))
|
||||
|
||||
BiomeModifications.addProperties({ context -> true}, { context, properties ->
|
||||
properties.generationProperties.addFeature(GenerationStep.Feature.VEGETAL_DECORATION, APRICORN_TREES)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,50 +8,86 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.registry.CompletableRegistry
|
||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.registry.Registries
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
import net.minecraft.sound.SoundEvent
|
||||
import net.minecraft.util.registry.Registry
|
||||
|
||||
object CobblemonSounds : CompletableRegistry<SoundEvent>(Registry.SOUND_EVENT_KEY) {
|
||||
private fun queue(name: String) = queue(name) { SoundEvent(cobblemonResource(name)) }
|
||||
object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, RegistryKey<Registry<SoundEvent>>, SoundEvent>() {
|
||||
|
||||
override val registry: Registry<SoundEvent> = Registries.SOUND_EVENT
|
||||
override val registryKey: RegistryKey<Registry<SoundEvent>> = RegistryKeys.SOUND_EVENT
|
||||
|
||||
@JvmField
|
||||
val GUI_CLICK = queue("gui.click")
|
||||
val GUI_CLICK = this.create("gui.click")
|
||||
|
||||
@JvmField
|
||||
val PC_ON = queue("pc.on")
|
||||
val PC_ON = this.create("pc.on")
|
||||
@JvmField
|
||||
val PC_OFF = queue("pc.off")
|
||||
val PC_OFF = this.create("pc.off")
|
||||
@JvmField
|
||||
val PC_GRAB = queue("pc.grab")
|
||||
val PC_GRAB = this.create("pc.grab")
|
||||
@JvmField
|
||||
val PC_DROP = queue("pc.drop")
|
||||
val PC_DROP = this.create("pc.drop")
|
||||
@JvmField
|
||||
val PC_RELEASE = queue("pc.release")
|
||||
val PC_RELEASE = this.create("pc.release")
|
||||
@JvmField
|
||||
val PC_CLICK = this.create("pc.click")
|
||||
|
||||
@JvmField
|
||||
val HEALING_MACHINE_ACTIVE = queue("healing_machine.active")
|
||||
val HEALING_MACHINE_ACTIVE = this.create("healing_machine.active")
|
||||
|
||||
@JvmField
|
||||
val POKE_BALL_CAPTURE_STARTED = queue("poke_ball.capture_started")
|
||||
val POKE_BALL_CAPTURE_STARTED = this.create("poke_ball.capture_started")
|
||||
@JvmField
|
||||
val POKE_BALL_CAPTURE_SUCCEEDED = queue("poke_ball.capture_succeeded")
|
||||
val POKE_BALL_CAPTURE_SUCCEEDED = this.create("poke_ball.capture_succeeded")
|
||||
@JvmField
|
||||
val POKE_BALL_SHAKE = queue("poke_ball.shake")
|
||||
val POKE_BALL_SHAKE = this.create("poke_ball.shake")
|
||||
@JvmField
|
||||
val POKE_BALL_OPEN = queue("poke_ball.open")
|
||||
val POKE_BALL_OPEN = this.create("poke_ball.open")
|
||||
@JvmField
|
||||
val POKE_BALL_HIT = queue("poke_ball.hit")
|
||||
val POKE_BALL_HIT = this.create("poke_ball.hit")
|
||||
@JvmField
|
||||
val POKE_BALL_SEND_OUT = queue("poke_ball.send_out")
|
||||
val POKE_BALL_SEND_OUT = this.create("poke_ball.send_out")
|
||||
@JvmField
|
||||
val POKE_BALL_RECALL = queue("poke_ball.recall")
|
||||
val POKE_BALL_RECALL = this.create("poke_ball.recall")
|
||||
|
||||
@JvmField
|
||||
val ITEM_USE = queue("item.use")
|
||||
val ITEM_USE = this.create("item.use")
|
||||
@JvmField
|
||||
val CAN_EVOLVE = queue("pokemon.can_evolve")
|
||||
val CAN_EVOLVE = this.create("pokemon.can_evolve")
|
||||
@JvmField
|
||||
val EVOLVING = queue("pokemon.evolving")
|
||||
val EVOLVING = this.create("pokemon.evolving")
|
||||
|
||||
@JvmField
|
||||
val PVN_BATTLE = this.create("battle.pvn.default")
|
||||
@JvmField
|
||||
val PVP_BATTLE = this.create("battle.pvp.default")
|
||||
@JvmField
|
||||
val PVW_BATTLE = this.create("battle.pvw.default")
|
||||
|
||||
@JvmField
|
||||
val MEDICINE_HERB_USE = this.create("medicine_herb.use")
|
||||
@JvmField
|
||||
val MEDICINE_LIQUID_USE = this.create("medicine_liquid.use")
|
||||
@JvmField
|
||||
val MEDICINE_PILLS_USE = this.create("medicine_pills.use")
|
||||
@JvmField
|
||||
val MEDICINE_SPRAY_USE = this.create("medicine_spray.use")
|
||||
|
||||
@JvmField
|
||||
val BERRY_HARVEST = this.create("berry.harvest")
|
||||
@JvmField
|
||||
val BERRY_EAT = this.create("berry.eat")
|
||||
|
||||
@JvmField
|
||||
val MULCH_PLACE = this.create("mulch.place")
|
||||
@JvmField
|
||||
val MULCH_REMOVE = this.create("mulch.remove")
|
||||
|
||||
|
||||
private fun create(name: String): SoundEvent = this.create(name, SoundEvent.of(cobblemonResource(name)))
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.registry.Registries
|
||||
import net.minecraft.village.TradeOffers
|
||||
import net.minecraft.village.VillagerData
|
||||
import net.minecraft.village.VillagerProfession
|
||||
|
||||
/**
|
||||
* A generator for various trade offers in the mod.
|
||||
*/
|
||||
object CobblemonTradeOffers {
|
||||
|
||||
/**
|
||||
* Creates a list of all Cobblemon trade offers for every villager profession.
|
||||
*
|
||||
* @return The resulting list.
|
||||
*/
|
||||
fun tradeOffersForAll(): List<VillagerTradeOffer> = Registries.VILLAGER_PROFESSION.map(this::tradeOffersFor).flatten()
|
||||
|
||||
/**
|
||||
* Creates a list of all Cobblemon trade offers for the given [VillagerProfession].
|
||||
*
|
||||
* @param profession The [VillagerProfession] being queried.
|
||||
* @return The resulting list.
|
||||
*/
|
||||
fun tradeOffersFor(profession: VillagerProfession): List<VillagerTradeOffer> = when (profession) {
|
||||
VillagerProfession.FARMER -> listOf(VillagerTradeOffer(VillagerProfession.FARMER, 3, listOf(TradeOffers.SellItemFactory(CobblemonItems.VIVICHOKE_SEEDS, 24, 1, 1, 6))))
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a list of all Cobblemon trade offers for the Wandering trader.
|
||||
*
|
||||
* @return The resulting list.
|
||||
*/
|
||||
fun resolveWanderingTradeOffers(): List<WandererTradeOffer> = listOf(
|
||||
WandererTradeOffer(false, listOf(TradeOffers.SellItemFactory(CobblemonItems.VIVICHOKE_SEEDS, 24, 1, 1, 6)))
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents a trade offer that can be attached to a villager or a wandering trader.
|
||||
*/
|
||||
interface TradeOfferHolder {
|
||||
/**
|
||||
* The list of the possible [TradeOffers.Factory].
|
||||
*/
|
||||
val tradeOffers: List<TradeOffers.Factory>
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a trade offer from a villager.
|
||||
*
|
||||
* @property profession The target profession for this trade.
|
||||
* @property requiredLevel The level required must be a possible level.
|
||||
* @property tradeOffers The list of the possible [TradeOffers.Factory].
|
||||
*
|
||||
* @throws IllegalArgumentException If the [requiredLevel] is not within the bounds of [VillagerData.MIN_LEVEL] & [VillagerData.MAX_LEVEL].
|
||||
*/
|
||||
data class VillagerTradeOffer(
|
||||
val profession: VillagerProfession,
|
||||
val requiredLevel: Int,
|
||||
override val tradeOffers: List<TradeOffers.Factory>
|
||||
) : TradeOfferHolder {
|
||||
|
||||
init {
|
||||
if (this.requiredLevel < VillagerData.MIN_LEVEL || this.requiredLevel > VillagerData.MAX_LEVEL) {
|
||||
throw IllegalArgumentException("${this.requiredLevel} is not a valid level for a villager trade accepted range is ${VillagerData.MIN_LEVEL}-${VillagerData.MAX_LEVEL}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a trade offer from a wandering trader.
|
||||
*
|
||||
* @property isRareTrade If this is rare or common trade.
|
||||
* @property tradeOffers The list of the possible [TradeOffers.Factory].
|
||||
*/
|
||||
data class WandererTradeOffer(
|
||||
val isRareTrade: Boolean,
|
||||
override val tradeOffers: List<TradeOffers.Factory>
|
||||
) : TradeOfferHolder
|
||||
|
||||
}
|
||||
@@ -8,12 +8,10 @@
|
||||
|
||||
package com.cobblemon.mod.common.advancement
|
||||
|
||||
import com.cobblemon.mod.common.advancement.criterion.CaughtPokemonCriterionCondition
|
||||
import com.cobblemon.mod.common.advancement.criterion.PickStarterCriterionCondition
|
||||
import com.cobblemon.mod.common.advancement.criterion.SimpleCountableCriterionCondition
|
||||
import com.cobblemon.mod.common.advancement.criterion.SimpleCriterionTrigger
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.advancement.criterion.*
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.advancement.criterion.Criteria
|
||||
import net.minecraft.advancement.criterion.Criterion
|
||||
|
||||
/**
|
||||
* Contains all the advancement criteria in Cobblemon.
|
||||
@@ -22,40 +20,92 @@ import net.minecraft.advancement.criterion.Criteria
|
||||
* @since October 26th, 2022
|
||||
*/
|
||||
object CobblemonCriteria {
|
||||
val PICK_STARTER = Criteria.register(
|
||||
val PICK_STARTER = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("pick_starter"),
|
||||
PickStarterCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
val CATCH_POKEMON = Criteria.register(
|
||||
val CATCH_POKEMON = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("catch_pokemon"),
|
||||
CaughtPokemonCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
val CATCH_SHINY_POKEMON = Criteria.register(
|
||||
val CATCH_SHINY_POKEMON = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("catch_shiny_pokemon"),
|
||||
SimpleCountableCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
val EGG_HATCH = Criteria.register(
|
||||
val EGG_HATCH = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("eggs_hatched"),
|
||||
SimpleCountableCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
val EVOLVE_POKEMON = Criteria.register(
|
||||
val EVOLVE_POKEMON = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("pokemon_evolved"),
|
||||
SimpleCountableCriterionCondition::class.java
|
||||
EvolvePokemonCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
val WIN_BATTLE = Criteria.register(
|
||||
SimpleCriterionTrigger(
|
||||
val WIN_BATTLE = this.create(
|
||||
BattleCountableCriterionTrigger(
|
||||
cobblemonResource("battles_won"),
|
||||
BattleCountableCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val DEFEAT_POKEMON = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("pokemon_defeated"),
|
||||
SimpleCountableCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val COLLECT_ASPECT = this.create(
|
||||
AspectCriterionTrigger(
|
||||
cobblemonResource("aspects_collected"),
|
||||
AspectCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val POKEMON_INTERACT = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("pokemon_interact"),
|
||||
PokemonInteractCriterion::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val PARTY_CHECK = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("party"),
|
||||
PartyCheckCriterion::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val LEVEL_UP = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("level_up"),
|
||||
LevelUpCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val PASTURE_USE = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("pasture_use"),
|
||||
PickStarterCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
val TRADE_POKEMON = this.create(
|
||||
SimpleCriterionTrigger(
|
||||
cobblemonResource("trade_pokemon"),
|
||||
TradePokemonCriterionCondition::class.java
|
||||
)
|
||||
)
|
||||
|
||||
private fun <T : Criterion<*>> create(criteria: T): T = Cobblemon.implementation.registerCriteria(criteria)
|
||||
|
||||
}
|
||||
+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.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
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("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: ServerPlayerEntity, context: MutableMap<Identifier, MutableSet<String>>): Boolean {
|
||||
val caughtAspects = context.getOrDefault(pokemon, mutableSetOf())
|
||||
return this.aspects.all { it in caughtAspects }
|
||||
}
|
||||
|
||||
}
|
||||
+67
@@ -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.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.util.toJsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
open class BattleCountableCriterionTrigger(identifier: Identifier, criterionClass: Class<BattleCountableCriterionCondition>) : SimpleCriterionTrigger<BattleCountableContext, BattleCountableCriterionCondition>(identifier, criterionClass) {
|
||||
|
||||
}
|
||||
|
||||
class BattleCountableCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<BattleCountableContext>(id, predicate) {
|
||||
|
||||
private var battleTypes = mutableListOf("any")
|
||||
|
||||
override fun fromJson(json: JsonObject) {
|
||||
super.fromJson(json)
|
||||
if(!json.get("battle_types").isJsonNull) {
|
||||
battleTypes.clear()
|
||||
json.get("battle_types").asJsonArray.asList().forEach() {
|
||||
battleTypes.add(it.asString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun toJson(json: JsonObject) {
|
||||
super.toJson(json)
|
||||
json.add("battle_types", battleTypes.toJsonArray())
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: BattleCountableContext): Boolean {
|
||||
var typeCheck = false
|
||||
val advancementData = Cobblemon.playerData.get(player).advancementData
|
||||
if (battleTypes.isEmpty() || battleTypes.contains("any")) {
|
||||
typeCheck = true
|
||||
}
|
||||
if (battleTypes.contains("pvp")) {
|
||||
typeCheck = context.battle.isPvP
|
||||
context.times = advancementData.totalPvPBattleVictoryCount
|
||||
}
|
||||
if (battleTypes.contains("pvw")) {
|
||||
typeCheck = context.battle.isPvW
|
||||
context.times = advancementData.totalPvWBattleVictoryCount
|
||||
}
|
||||
if (battleTypes.contains("pvn")) {
|
||||
typeCheck = context.battle.isPvN
|
||||
context.times = advancementData.totalPvWBattleVictoryCount
|
||||
}
|
||||
if (battleTypes.size > 1) {
|
||||
context.times = advancementData.totalBattleVictoryCount
|
||||
}
|
||||
return context.times >= count && typeCheck
|
||||
}
|
||||
}
|
||||
|
||||
open class BattleCountableContext(times : Int, var battle : PokemonBattle) : CountableContext(times)
|
||||
+3
-3
@@ -9,7 +9,7 @@
|
||||
package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.EntityPredicate.Extended
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
@@ -21,7 +21,7 @@ import net.minecraft.util.Identifier
|
||||
*/
|
||||
open class CountablePokemonTypeContext(times: Int, var type: String) : CountableContext(times)
|
||||
|
||||
class CaughtPokemonCriterionCondition(id: Identifier, entity: Extended) : CountableCriterionCondition<CountablePokemonTypeContext>(id, entity) {
|
||||
class CaughtPokemonCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<CountablePokemonTypeContext>(id, predicate) {
|
||||
var type = "any"
|
||||
override fun toJson(json: JsonObject) {
|
||||
super.toJson(json)
|
||||
@@ -34,6 +34,6 @@ class CaughtPokemonCriterionCondition(id: Identifier, entity: Extended) : Counta
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: CountablePokemonTypeContext): Boolean {
|
||||
return super.matches(player, context) && context.type == type
|
||||
return super.matches(player, context) && (context.type == type || type == "any")
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -9,7 +9,7 @@
|
||||
package com.cobblemon.mod.common.advancement.criterion
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.EntityPredicate.Extended
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
@@ -20,7 +20,7 @@ import net.minecraft.util.Identifier
|
||||
* @author Hiroku
|
||||
* @since November 4th, 2022
|
||||
*/
|
||||
abstract class CountableCriterionCondition<T : CountableContext>(id: Identifier, entity: Extended) : SimpleCriterionCondition<T>(id, entity) {
|
||||
abstract class CountableCriterionCondition<T : CountableContext>(id: Identifier, predicate: LootContextPredicate) : SimpleCriterionCondition<T>(id, predicate) {
|
||||
var count = 0
|
||||
override fun fromJson(json: JsonObject) {
|
||||
count = json.get("count")?.asInt ?: 0
|
||||
@@ -43,7 +43,7 @@ abstract class CountableCriterionCondition<T : CountableContext>(id: Identifier,
|
||||
* @author Hiroku
|
||||
* @since November 4th, 2022
|
||||
*/
|
||||
class SimpleCountableCriterionCondition(id: Identifier, entity: Extended) : CountableCriterionCondition<CountableContext>(id, entity)
|
||||
class SimpleCountableCriterionCondition(id: Identifier, predicate: LootContextPredicate) : CountableCriterionCondition<CountableContext>(id, predicate)
|
||||
fun SimpleCriterionTrigger<CountableContext, SimpleCountableCriterionCondition>.trigger(player: ServerPlayerEntity, times: Int) = trigger(player, CountableContext(times))
|
||||
|
||||
/**
|
||||
|
||||
+38
@@ -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.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
class EvolvePokemonCriterionCondition(id: Identifier, entity: LootContextPredicate) : CountableCriterionCondition<EvolvePokemonContext>(id, entity) {
|
||||
var species = "any"
|
||||
var evolution = "any"
|
||||
override fun toJson(json: JsonObject) {
|
||||
super.toJson(json)
|
||||
json.addProperty("species", species)
|
||||
json.addProperty("evolution", evolution)
|
||||
}
|
||||
|
||||
override fun fromJson(json: JsonObject) {
|
||||
super.fromJson(json)
|
||||
species = json.get("species")?.asString ?: "any"
|
||||
evolution = json.get("evolution")?.asString ?: "any"
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: EvolvePokemonContext): Boolean {
|
||||
return context.times >= count && (context.species == species.asIdentifierDefaultingNamespace() || species == "any") &&
|
||||
(context.evolution == evolution.asIdentifierDefaultingNamespace() || evolution == "any")
|
||||
}
|
||||
}
|
||||
|
||||
open class EvolvePokemonContext(val species : Identifier, val evolution : Identifier, times: Int) : CountableContext(times)
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
class LevelUpCriterionCondition(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<LevelUpContext>(id, entity) {
|
||||
var level = 0
|
||||
var evolved = true
|
||||
override fun toJson(json: JsonObject) {
|
||||
json.addProperty("level", level)
|
||||
json.addProperty("has_evolved", evolved)
|
||||
}
|
||||
|
||||
override fun fromJson(json: JsonObject) {
|
||||
level = json.get("level")?.asInt ?: 0
|
||||
evolved = json.get("has_evolved")?.asBoolean ?: true
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: LevelUpContext): Boolean {
|
||||
val preEvo = context.pokemon.preEvolution == null
|
||||
val hasEvolution = !context.pokemon.evolutions.none()
|
||||
var evolutionCheck = true
|
||||
if (preEvo || hasEvolution) {
|
||||
evolutionCheck = !(preEvo == hasEvolution)
|
||||
}
|
||||
return level == context.level && evolutionCheck == evolved
|
||||
}
|
||||
}
|
||||
|
||||
open class LevelUpContext(var level : Int, var pokemon : Pokemon)
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
class PartyCheckCriterion(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<PartyCheckContext>(id, entity){
|
||||
val party = mutableListOf<Identifier>()
|
||||
override fun toJson(json: JsonObject) {
|
||||
json.add("party", JsonArray(party.size).also {
|
||||
party.forEach { pokemon -> it.add(pokemon.toString()) }
|
||||
})
|
||||
}
|
||||
|
||||
override fun fromJson(json: JsonObject) {
|
||||
party.clear()
|
||||
json.getAsJsonArray("party").forEach { element ->
|
||||
party.add(element.asString.asIdentifierDefaultingNamespace())
|
||||
}
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: PartyCheckContext): Boolean {
|
||||
val playerParty = player.party()
|
||||
val matches = mutableListOf<Identifier>()
|
||||
party.forEach {
|
||||
if (it == "any".asIdentifierDefaultingNamespace()) {
|
||||
matches.add(it)
|
||||
}
|
||||
}
|
||||
val partyCount = playerParty.count()
|
||||
if (matches.containsAll(party) && party.size == partyCount && matches.size == partyCount) return true
|
||||
playerParty.iterator().forEach {
|
||||
if (party.contains(it.species.resourceIdentifier)) {
|
||||
matches.add(it.species.resourceIdentifier)
|
||||
}
|
||||
}
|
||||
return matches.containsAll(party) && matches.size == partyCount
|
||||
}
|
||||
}
|
||||
|
||||
open class PartyCheckContext(val party : PlayerPartyStore)
|
||||
+2
-2
@@ -11,7 +11,7 @@ package com.cobblemon.mod.common.advancement.criterion
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.EntityPredicate.Extended
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
@@ -21,7 +21,7 @@ import net.minecraft.util.Identifier
|
||||
* @author Licious, Hiroku
|
||||
* @since October 26th, 2022
|
||||
*/
|
||||
class PickStarterCriterionCondition(id: Identifier, entity: Extended) : SimpleCriterionCondition<Pokemon>(id, entity) {
|
||||
class PickStarterCriterionCondition(id: Identifier, predicate: LootContextPredicate) : SimpleCriterionCondition<Pokemon>(id, predicate) {
|
||||
var properties = PokemonProperties()
|
||||
override fun toJson(json: JsonObject) {
|
||||
json.addProperty("properties", properties.originalString)
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
open class PokemonInteractContext(var type: Identifier, var item : Identifier)
|
||||
class PokemonInteractCriterion(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<PokemonInteractContext>(id, entity) {
|
||||
var type = "any"
|
||||
var item = "any"
|
||||
override fun toJson(json: JsonObject) {
|
||||
json.addProperty("type", type)
|
||||
json.addProperty("item", item)
|
||||
}
|
||||
|
||||
override fun fromJson(json: JsonObject) {
|
||||
type = json.get("type")?.asString ?: "any"
|
||||
item = json.get("item")?.asString ?: "any"
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: PokemonInteractContext): Boolean {
|
||||
return (context.type == type.asIdentifierDefaultingNamespace() || type == "any") && (context.item == item.asIdentifierDefaultingNamespace() || item == "any")
|
||||
}
|
||||
}
|
||||
+7
-6
@@ -13,7 +13,7 @@ import net.minecraft.advancement.criterion.AbstractCriterion
|
||||
import net.minecraft.advancement.criterion.AbstractCriterionConditions
|
||||
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer
|
||||
import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer
|
||||
import net.minecraft.predicate.entity.EntityPredicate.Extended
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
@@ -31,16 +31,17 @@ open class SimpleCriterionTrigger<T, C : SimpleCriterionCondition<T>>(
|
||||
val criterionClass: Class<C>
|
||||
) : AbstractCriterion<C>() {
|
||||
override fun getId() = _id
|
||||
fun trigger(player: ServerPlayerEntity, context: T) = this.trigger(player) { it.matches(player, context) }
|
||||
override fun conditionsFromJson(
|
||||
obj: JsonObject,
|
||||
playerPredicate: Extended,
|
||||
playerPredicate: LootContextPredicate,
|
||||
predicateDeserializer: AdvancementEntityPredicateDeserializer
|
||||
): C {
|
||||
val instance = criterionClass.getConstructor(Identifier::class.java, Extended::class.java).newInstance(id, playerPredicate)
|
||||
val instance = criterionClass.getConstructor(Identifier::class.java, LootContextPredicate::class.java).newInstance(id, playerPredicate)
|
||||
instance.fromJson(obj)
|
||||
return instance
|
||||
}
|
||||
|
||||
fun trigger(player: ServerPlayerEntity, context: T) = this.trigger(player) { it.matches(player, context) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,8 +53,8 @@ open class SimpleCriterionTrigger<T, C : SimpleCriterionCondition<T>>(
|
||||
*/
|
||||
abstract class SimpleCriterionCondition<T>(
|
||||
id: Identifier,
|
||||
entity: Extended
|
||||
): AbstractCriterionConditions(id, entity) {
|
||||
playerPredicate: LootContextPredicate
|
||||
): AbstractCriterionConditions(id, playerPredicate) {
|
||||
override fun toJson(predicateSerializer: AdvancementEntityPredicateSerializer): JsonObject {
|
||||
val json = super.toJson(predicateSerializer)
|
||||
toJson(json)
|
||||
|
||||
+47
@@ -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.advancement.criterion
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.predicate.entity.LootContextPredicate
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
class TradePokemonCriterionCondition(id: Identifier, entity: LootContextPredicate) : SimpleCriterionCondition<TradePokemonContext>(id, entity) {
|
||||
var traded = "any"
|
||||
var received = "any"
|
||||
var tradedHeldItem = "any"
|
||||
var receivedHeldItem = "any"
|
||||
override fun toJson(json: JsonObject) {
|
||||
json.addProperty("traded", traded)
|
||||
json.addProperty("received", received)
|
||||
json.addProperty("traded_held_item", tradedHeldItem)
|
||||
json.addProperty("received_held_item", receivedHeldItem)
|
||||
}
|
||||
|
||||
override fun fromJson(json: JsonObject) {
|
||||
traded = json.get("traded")?.asString ?: "any"
|
||||
received = json.get("received")?.asString ?: "any"
|
||||
tradedHeldItem = json.get("traded_held_item")?.asString ?: "minecraft:air"
|
||||
receivedHeldItem = json.get("received_held_item")?.asString ?: "minecraft:air"
|
||||
}
|
||||
|
||||
override fun matches(player: ServerPlayerEntity, context: TradePokemonContext): Boolean {
|
||||
val heldItem1 = context.traded.heldItem().item.registryEntry.registryKey().value
|
||||
val heldItem2 = context.received.heldItem().item.registryEntry.registryKey().value
|
||||
return (context.traded.species.resourceIdentifier == traded.asIdentifierDefaultingNamespace() || traded == "any") &&
|
||||
(context.received.species.resourceIdentifier == received.asIdentifierDefaultingNamespace() || received == "any") &&
|
||||
(heldItem1 == tradedHeldItem.asIdentifierDefaultingNamespace() || heldItem1 == "minecraft:air".asIdentifierDefaultingNamespace()) &&
|
||||
(heldItem2 == receivedHeldItem.asIdentifierDefaultingNamespace() || heldItem2 == "minecraft:air".asIdentifierDefaultingNamespace())
|
||||
}
|
||||
}
|
||||
|
||||
open class TradePokemonContext(val traded: Pokemon, val received: Pokemon)
|
||||
@@ -37,7 +37,7 @@ object Abilities : DataRegistry {
|
||||
PotentialAbility.types.add(CommonAbilityType)
|
||||
PotentialAbility.types.add(HiddenAbilityType)
|
||||
this.abilityMap.clear()
|
||||
val abilitiesJson = ShowdownService.get().getAbilityIds()
|
||||
val abilitiesJson = ShowdownService.service.getAbilityIds()
|
||||
for (i in 0 until abilitiesJson.size()) {
|
||||
val id = abilitiesJson[i].asString
|
||||
val ability = AbilityTemplate(id)
|
||||
|
||||
@@ -35,7 +35,7 @@ interface SleepDepth {
|
||||
|
||||
override fun shouldWake(pokemonEntity: PokemonEntity): Boolean {
|
||||
val nearbyPlayers = pokemonEntity.world.getPlayers(TargetPredicate.createNonAttackable(), pokemonEntity, Box.of(pokemonEntity.pos, 16.0, 16.0, 16.0))
|
||||
return nearbyPlayers.none { !it.isSneaking }
|
||||
return nearbyPlayers.any { !it.isSneaking }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ package com.cobblemon.mod.common.api.apricorn
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlocks
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.item.ApricornItem
|
||||
import com.cobblemon.mod.common.block.ApricornBlock
|
||||
import com.cobblemon.mod.common.block.ApricornSaplingBlock
|
||||
import com.cobblemon.mod.common.item.ApricornItem
|
||||
import net.minecraft.block.MapColor
|
||||
import net.minecraft.item.BlockItem
|
||||
|
||||
@@ -33,43 +33,43 @@ enum class Apricorn {
|
||||
YELLOW;
|
||||
|
||||
fun item(): ApricornItem = when(this) {
|
||||
BLACK -> CobblemonItems.BLACK_APRICORN.get()
|
||||
BLUE -> CobblemonItems.BLUE_APRICORN.get()
|
||||
GREEN -> CobblemonItems.GREEN_APRICORN.get()
|
||||
PINK -> CobblemonItems.PINK_APRICORN.get()
|
||||
RED -> CobblemonItems.RED_APRICORN.get()
|
||||
WHITE -> CobblemonItems.WHITE_APRICORN.get()
|
||||
YELLOW -> CobblemonItems.YELLOW_APRICORN.get()
|
||||
BLACK -> CobblemonItems.BLACK_APRICORN
|
||||
BLUE -> CobblemonItems.BLUE_APRICORN
|
||||
GREEN -> CobblemonItems.GREEN_APRICORN
|
||||
PINK -> CobblemonItems.PINK_APRICORN
|
||||
RED -> CobblemonItems.RED_APRICORN
|
||||
WHITE -> CobblemonItems.WHITE_APRICORN
|
||||
YELLOW -> CobblemonItems.YELLOW_APRICORN
|
||||
}
|
||||
|
||||
fun seed(): BlockItem = when(this) {
|
||||
BLACK -> CobblemonItems.BLACK_APRICORN_SEED.get()
|
||||
BLUE -> CobblemonItems.BLUE_APRICORN_SEED.get()
|
||||
GREEN -> CobblemonItems.GREEN_APRICORN_SEED.get()
|
||||
PINK -> CobblemonItems.PINK_APRICORN_SEED.get()
|
||||
RED -> CobblemonItems.RED_APRICORN_SEED.get()
|
||||
WHITE -> CobblemonItems.WHITE_APRICORN_SEED.get()
|
||||
YELLOW -> CobblemonItems.YELLOW_APRICORN_SEED.get()
|
||||
BLACK -> CobblemonItems.BLACK_APRICORN_SEED
|
||||
BLUE -> CobblemonItems.BLUE_APRICORN_SEED
|
||||
GREEN -> CobblemonItems.GREEN_APRICORN_SEED
|
||||
PINK -> CobblemonItems.PINK_APRICORN_SEED
|
||||
RED -> CobblemonItems.RED_APRICORN_SEED
|
||||
WHITE -> CobblemonItems.WHITE_APRICORN_SEED
|
||||
YELLOW -> CobblemonItems.YELLOW_APRICORN_SEED
|
||||
}
|
||||
|
||||
fun block(): ApricornBlock = when(this) {
|
||||
BLACK -> CobblemonBlocks.BLACK_APRICORN.get()
|
||||
BLUE -> CobblemonBlocks.BLUE_APRICORN.get()
|
||||
GREEN -> CobblemonBlocks.GREEN_APRICORN.get()
|
||||
PINK -> CobblemonBlocks.PINK_APRICORN.get()
|
||||
RED -> CobblemonBlocks.RED_APRICORN.get()
|
||||
WHITE -> CobblemonBlocks.WHITE_APRICORN.get()
|
||||
YELLOW -> CobblemonBlocks.YELLOW_APRICORN.get()
|
||||
BLACK -> CobblemonBlocks.BLACK_APRICORN
|
||||
BLUE -> CobblemonBlocks.BLUE_APRICORN
|
||||
GREEN -> CobblemonBlocks.GREEN_APRICORN
|
||||
PINK -> CobblemonBlocks.PINK_APRICORN
|
||||
RED -> CobblemonBlocks.RED_APRICORN
|
||||
WHITE -> CobblemonBlocks.WHITE_APRICORN
|
||||
YELLOW -> CobblemonBlocks.YELLOW_APRICORN
|
||||
}
|
||||
|
||||
fun sapling(): ApricornSaplingBlock = when(this) {
|
||||
BLACK -> CobblemonBlocks.BLACK_APRICORN_SAPLING.get()
|
||||
BLUE -> CobblemonBlocks.BLUE_APRICORN_SAPLING.get()
|
||||
GREEN -> CobblemonBlocks.GREEN_APRICORN_SAPLING.get()
|
||||
PINK -> CobblemonBlocks.PINK_APRICORN_SAPLING.get()
|
||||
RED -> CobblemonBlocks.RED_APRICORN_SAPLING.get()
|
||||
WHITE -> CobblemonBlocks.WHITE_APRICORN_SAPLING.get()
|
||||
YELLOW -> CobblemonBlocks.YELLOW_APRICORN_SAPLING.get()
|
||||
BLACK -> CobblemonBlocks.BLACK_APRICORN_SAPLING
|
||||
BLUE -> CobblemonBlocks.BLUE_APRICORN_SAPLING
|
||||
GREEN -> CobblemonBlocks.GREEN_APRICORN_SAPLING
|
||||
PINK -> CobblemonBlocks.PINK_APRICORN_SAPLING
|
||||
RED -> CobblemonBlocks.RED_APRICORN_SAPLING
|
||||
WHITE -> CobblemonBlocks.WHITE_APRICORN_SAPLING
|
||||
YELLOW -> CobblemonBlocks.YELLOW_APRICORN_SAPLING
|
||||
}
|
||||
|
||||
fun mapColor(): MapColor = when(this) {
|
||||
|
||||
+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.api.battles.interpreter
|
||||
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
|
||||
/**
|
||||
* The context of how a condition was created or changed during a battle.
|
||||
*
|
||||
* @author Segfault Guy
|
||||
* @since April 10th, 2023
|
||||
*/
|
||||
interface BattleContext {
|
||||
|
||||
/** The effect or condition this [BattleContext] represents. */
|
||||
val id: String
|
||||
|
||||
/** The turn this [BattleContext] was created. */
|
||||
val turn: Int
|
||||
|
||||
/** The [BattleContext.Type] tied to this [BattleContext]. */
|
||||
val type: Type
|
||||
|
||||
/** The [BattlePokemon] that directly or indirectly caused this [BattleContext]. */
|
||||
val origin: BattlePokemon?
|
||||
|
||||
/**
|
||||
* The type of [BattleContext].
|
||||
*
|
||||
* @property damaging Whether a context of this type is a source of damage.
|
||||
* @property exclusive Whether only one context of this type can exist.
|
||||
*
|
||||
* @author Segfault Guy
|
||||
* @since April 10th, 2023
|
||||
*/
|
||||
enum class Type(val damaging: Boolean, val exclusive: Boolean) {
|
||||
ITEM(true, true),
|
||||
STATUS(true, false),
|
||||
VOLATILE(true, false),
|
||||
HAZARD(true, false),
|
||||
WEATHER(true, true),
|
||||
ROOM(false, true),
|
||||
SPORT(false, false),
|
||||
TERRAIN(false, true),
|
||||
GRAVITY(false, true),
|
||||
TAILWIND(false, true),
|
||||
SCREEN(false, false),
|
||||
FAINT(false, false),
|
||||
BOOST(false, false),
|
||||
UNBOOST(false, false),
|
||||
MISC(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
data class BasicContext(
|
||||
override val id: String,
|
||||
override val turn: Int,
|
||||
override val type: BattleContext.Type,
|
||||
override val origin: BattlePokemon?
|
||||
) : BattleContext
|
||||
|
||||
data class MissingContext(
|
||||
override val id: String = "error",
|
||||
override val turn: Int = 0,
|
||||
override val type: BattleContext.Type = BattleContext.Type.MISC,
|
||||
override val origin: BattlePokemon? = null
|
||||
) : BattleContext
|
||||
+69
-4
@@ -10,7 +10,11 @@ package com.cobblemon.mod.common.api.battles.interpreter
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
import com.cobblemon.mod.common.api.moves.MoveTemplate
|
||||
import com.cobblemon.mod.common.api.moves.Moves
|
||||
import com.cobblemon.mod.common.battles.ActiveBattlePokemon
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* A class responsible for parsing a raw simulator protocol message received from Showdown.
|
||||
@@ -24,7 +28,6 @@ import com.cobblemon.mod.common.battles.ActiveBattlePokemon
|
||||
* @since December 31st, 2022
|
||||
*/
|
||||
class BattleMessage(rawMessage: String) {
|
||||
|
||||
/**
|
||||
* The ID of the action received in the message.
|
||||
*/
|
||||
@@ -116,6 +119,10 @@ class BattleMessage(rawMessage: String) {
|
||||
return this
|
||||
}
|
||||
|
||||
fun pokemonByUuid(index: Int, battle: PokemonBattle): BattlePokemon? {
|
||||
return this.argumentAt(index)?.let { UUID.fromString(it) }?.let { uuid -> battle.actors.flatMap { it.pokemonList }.find { it.uuid == uuid } }
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries an argument at the given [index] for a 'pnx' that will be parsed into a [BattleActor] and [ActiveBattlePokemon].
|
||||
*
|
||||
@@ -124,10 +131,49 @@ class BattleMessage(rawMessage: String) {
|
||||
* @return A pair of [BattleActor] and [ActiveBattlePokemon] if the argument exists and successfully parses them otherwise null.
|
||||
*/
|
||||
fun actorAndActivePokemon(index: Int, battle: PokemonBattle): Pair<BattleActor, ActiveBattlePokemon>? {
|
||||
val pnx = this.argumentAt(index)?.takeIf { it.length >= 3 }?.substring(0, 3) ?: return null
|
||||
val (pnx, _) = this.pnxAndUuid(index) ?: return null
|
||||
return this.actorAndActivePokemon(pnx, battle)
|
||||
}
|
||||
|
||||
/*
|
||||
Example:
|
||||
|-curestatus|p1: a8e5710e-6835-4387-99d3-331b45f848e6|slp|[msg]
|
||||
|-curestatus|p1: 0686b20d-3019-4167-92e2-786834245743|slp|[msg]
|
||||
// Function used to grab BattlePokemon (As we need to be able to grab non active pokemon to cure their status)
|
||||
// by using playerNumber(actorID) and pokemon uuid(pokemonID)
|
||||
*/
|
||||
fun getBattlePokemon(index: Int, battle: PokemonBattle): BattlePokemon? {
|
||||
val actorAndPokemonID = this.argumentAt(index)?.takeIf { it.length >= 2 }?.split(": ") ?: return null
|
||||
if (actorAndPokemonID.count() < 2) return null
|
||||
val actorID = actorAndPokemonID[0]
|
||||
val pokemonID = actorAndPokemonID[1]
|
||||
return this.getBattlePokemon(actorID, pokemonID, battle)
|
||||
}
|
||||
|
||||
fun getSourceBattlePokemon(battle: PokemonBattle): BattlePokemon? {
|
||||
val sourcePokemonArgument = this.optionalArguments.get("of") ?: return null
|
||||
val actorAndPokemonID = sourcePokemonArgument.takeIf { it.length >= 2 }?.split(": ") ?: return null
|
||||
if (actorAndPokemonID.count() < 2) return null
|
||||
val actorID = actorAndPokemonID[0]
|
||||
val pokemonID = actorAndPokemonID[1]
|
||||
return this.getBattlePokemon(actorID, pokemonID, battle)
|
||||
}
|
||||
|
||||
/**
|
||||
* Deconstructs the Showdown ID of a Pokemon at the given [index] into its 'pnx' and 'uuid' parts.
|
||||
*
|
||||
* @param index The index of the argument containing the Showdown ID of a Pokemon.
|
||||
* @return A 'pnx' String representing position and a 'uuid' String representing the unique Pokemon if parsed correctly, otherwise null.
|
||||
*/
|
||||
fun pnxAndUuid(index: Int): Pair<String, String>? {
|
||||
val argument = this.argumentAt(index)?.takeIf { it.length >= 2 }?.split(":")?.takeIf { it.size == 2 } ?: return null
|
||||
val pnx = argument[0].takeIf { it.matches(PNX_MATCHER) } ?: return null
|
||||
val uuid = argument[1].trim()
|
||||
return pnx to uuid
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to parse an [Effect] from an argument at the given [index].
|
||||
*
|
||||
@@ -150,6 +196,11 @@ class BattleMessage(rawMessage: String) {
|
||||
return Effect.parse(data)
|
||||
}
|
||||
|
||||
fun moveAt(index: Int): MoveTemplate? {
|
||||
val argument = argumentAt(index)?.lowercase()?.replace("[^a-z0-9]".toRegex(), "") ?: return null
|
||||
return Moves.getByName(argument)
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries an optional argument with given [argumentName] for a 'pnx' that will be parsed into a [BattleActor] and [ActiveBattlePokemon].
|
||||
*
|
||||
@@ -158,7 +209,7 @@ class BattleMessage(rawMessage: String) {
|
||||
* @return A pair of [BattleActor] and [ActiveBattlePokemon] if the argument exists and successfully parses them otherwise null.
|
||||
*/
|
||||
fun actorAndActivePokemonFromOptional(battle: PokemonBattle, argumentName: String = "of"): Pair<BattleActor, ActiveBattlePokemon>? {
|
||||
val pnx = this.optionalArgument(argumentName)?.substring(0, 3) ?: return null
|
||||
val pnx = this.optionalArgument(argumentName)?.takeIf { it.length >= 3 }?.substring(0, 3) ?: return null
|
||||
return this.actorAndActivePokemon(pnx, battle)
|
||||
}
|
||||
|
||||
@@ -183,12 +234,26 @@ class BattleMessage(rawMessage: String) {
|
||||
null
|
||||
}
|
||||
|
||||
private fun getBattlePokemon(pnx: String, pokemonID: String, battle: PokemonBattle): BattlePokemon? = try {
|
||||
battle.getBattlePokemon(pnx, pokemonID)
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val SEPARATOR = "|"
|
||||
private const val OPTIONAL_ARG_START = "["
|
||||
private const val OPTIONAL_ARG_END = "]"
|
||||
|
||||
}
|
||||
/**
|
||||
* Pattern to match a Showdown position e.g. p2a, p1b
|
||||
*/
|
||||
val PNX_MATCHER = Regex("p\\d[a-c]")
|
||||
|
||||
/**
|
||||
* Pattern to match a Showdown side position e.g. p2, p1
|
||||
*/
|
||||
val PN_MATCHER = Regex("p\\d")
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,9 @@ interface Effect {
|
||||
*/
|
||||
val rawData: String
|
||||
|
||||
val typelessData: String
|
||||
get() = rawData.substringAfter(type.prefix).trim()
|
||||
|
||||
/**
|
||||
* Represents the type of the [Effect].
|
||||
*
|
||||
@@ -49,6 +52,7 @@ interface Effect {
|
||||
ABILITY("ability:"),
|
||||
ITEM("item:"),
|
||||
MOVE("move:"),
|
||||
BAGITEM("bagitem:"),
|
||||
PURE(""),
|
||||
|
||||
}
|
||||
|
||||
+107
-28
@@ -16,6 +16,8 @@ import com.cobblemon.mod.common.api.battles.model.actor.ActorType
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.EntityBackedBattleActor
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.FleeableBattleActor
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleFledEvent
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.api.text.red
|
||||
@@ -30,15 +32,21 @@ import com.cobblemon.mod.common.battles.dispatch.BattleDispatch
|
||||
import com.cobblemon.mod.common.battles.dispatch.DispatchResult
|
||||
import com.cobblemon.mod.common.battles.dispatch.GO
|
||||
import com.cobblemon.mod.common.battles.dispatch.WaitDispatch
|
||||
import com.cobblemon.mod.common.battles.interpreter.ContextManager
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.battles.runner.ShowdownService
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleEndPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMusicPacket
|
||||
import com.cobblemon.mod.common.pokemon.evolution.progress.DefeatEvolutionProgress
|
||||
import com.cobblemon.mod.common.pokemon.evolution.requirements.DefeatRequirement
|
||||
import com.cobblemon.mod.common.util.battleLang
|
||||
import com.cobblemon.mod.common.util.getPlayer
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.text.Text
|
||||
|
||||
/**
|
||||
@@ -52,7 +60,7 @@ open class PokemonBattle(
|
||||
val side1: BattleSide,
|
||||
val side2: BattleSide
|
||||
) {
|
||||
/** Whether or not logging will be silenced for this battle. */
|
||||
/** Whether logging will be silenced for this battle. */
|
||||
var mute = true
|
||||
|
||||
init {
|
||||
@@ -79,6 +87,7 @@ open class PokemonBattle(
|
||||
val battleId = UUID.randomUUID()
|
||||
|
||||
val showdownMessages = mutableListOf<String>()
|
||||
val battleLog = mutableListOf<String>()
|
||||
var started = false
|
||||
var ended = false
|
||||
// TEMP battle showcase stuff
|
||||
@@ -93,6 +102,10 @@ open class PokemonBattle(
|
||||
|
||||
val captureActions = mutableListOf<BattleCaptureAction>()
|
||||
|
||||
val majorBattleActions = hashMapOf<UUID, BattleMessage>()
|
||||
val minorBattleActions = hashMapOf<UUID, BattleMessage>()
|
||||
val contextManager = ContextManager()
|
||||
|
||||
/** Whether or not there is one side with at least one player, and the other only has wild Pokémon. */
|
||||
val isPvW: Boolean
|
||||
get() {
|
||||
@@ -135,6 +148,11 @@ open class PokemonBattle(
|
||||
return actors.find { actor -> actor.uuid == actorId }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first battle actor whom the given player controls, or null if there is no such actor.
|
||||
*/
|
||||
fun getActor(player: ServerPlayerEntity) = actors.firstOrNull { it.isForPlayer(player) }
|
||||
|
||||
/**
|
||||
* Gets a BattleActor and an [ActiveBattlePokemon] from a pnx key, e.g. p2a
|
||||
*
|
||||
@@ -149,13 +167,25 @@ open class PokemonBattle(
|
||||
return actor to pokemon
|
||||
}
|
||||
|
||||
fun getBattlePokemon(pnx: String, pokemonID: String): BattlePokemon {
|
||||
val actor = actors.find { it.showdownId == pnx.substring(0, 2) }
|
||||
?: throw IllegalStateException("Invalid pnx: $pnx - unknown actor")
|
||||
return actor.pokemonList.find { it.uuid.toString() == pokemonID }
|
||||
?: throw IllegalStateException("Invalid pnx: $pnx - unknown pokemon")
|
||||
}
|
||||
|
||||
fun broadcastChatMessage(component: Text) {
|
||||
spectators.forEach { spectatorId ->
|
||||
spectatorId.getPlayer()?.let {
|
||||
CobblemonNetwork.sendPacketToPlayer(it, BattleMessagePacket(component))
|
||||
}
|
||||
}
|
||||
return actors.forEach { it.sendMessage(component) }
|
||||
}
|
||||
|
||||
fun writeShowdownAction(vararg messages: String) {
|
||||
log(messages.joinToString("\n"))
|
||||
ShowdownService.get().send(battleId, messages.toList().toTypedArray())
|
||||
ShowdownService.service.send(battleId, messages.toList().toTypedArray())
|
||||
}
|
||||
|
||||
fun turn(newTurnNumber: Int) {
|
||||
@@ -179,11 +209,16 @@ open class PokemonBattle(
|
||||
faintedPokemons.forEach { faintedPokemon ->
|
||||
for (opponentPokemon in opponentNonFaintedPokemons) {
|
||||
val facedFainted = opponentPokemon.facedOpponents.contains(faintedPokemon)
|
||||
val defeatProgress = DefeatEvolutionProgress()
|
||||
val pokemon = opponentPokemon.effectedPokemon
|
||||
if (facedFainted && defeatProgress.shouldKeep(pokemon)) {
|
||||
val progress = pokemon.evolutionProxy.current().progressFirstOrCreate({ it is DefeatEvolutionProgress && it.currentProgress().target.matches(faintedPokemon.effectedPokemon) }) { defeatProgress }
|
||||
progress.updateProgress(DefeatEvolutionProgress.Progress(progress.currentProgress().target, progress.currentProgress().amount + 1))
|
||||
if (facedFainted) {
|
||||
pokemon.evolutions.forEach { evolution ->
|
||||
evolution.requirements.filterIsInstance<DefeatRequirement>().forEach { defeatRequirement ->
|
||||
if (defeatRequirement.target.matches(faintedPokemon.effectedPokemon)) {
|
||||
val progress = pokemon.evolutionProxy.current().progressFirstOrCreate({ it is DefeatEvolutionProgress && it.currentProgress().target == defeatRequirement.target }) { DefeatEvolutionProgress() }
|
||||
progress.updateProgress(DefeatEvolutionProgress.Progress(defeatRequirement.target, progress.currentProgress().amount + 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val multiplier = when {
|
||||
// ToDo when Exp. All is implement if enabled && !facedFainted return 2.0, probably should be a configurable value too, this will have priority over the Exp. Share
|
||||
@@ -196,14 +231,26 @@ open class PokemonBattle(
|
||||
if (experience > 0) {
|
||||
opponent.awardExperience(opponentPokemon, experience)
|
||||
}
|
||||
Cobblemon.evYieldCalculator.calculate(opponentPokemon).forEach { (stat, amount) ->
|
||||
Cobblemon.evYieldCalculator.calculate(opponentPokemon, faintedPokemon).forEach { (stat, amount) ->
|
||||
pokemon.evs.add(stat, amount)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Heal Mon if wild
|
||||
actors.filter { it.type == ActorType.WILD }
|
||||
.filterIsInstance<EntityBackedBattleActor<*>>()
|
||||
.mapNotNull { it.entity }
|
||||
.filterIsInstance<PokemonEntity>()
|
||||
.forEach{it.pokemon.heal()}
|
||||
actors.forEach { actor ->
|
||||
actor.pokemonList.forEach { battlePokemon ->
|
||||
battlePokemon.entity?.let { entity -> battlePokemon.postBattleEntityOperation(entity) }
|
||||
}
|
||||
}
|
||||
sendUpdate(BattleEndPacket())
|
||||
sendUpdate(BattleMusicPacket(null))
|
||||
BattleRegistry.closeBattle(this)
|
||||
}
|
||||
|
||||
@@ -216,9 +263,27 @@ open class PokemonBattle(
|
||||
if (!mute) {
|
||||
LOGGER.info(message)
|
||||
}
|
||||
battleLog.add(message)
|
||||
}
|
||||
|
||||
fun sendUpdate(packet: NetworkPacket) {
|
||||
fun saveBattleLog() {
|
||||
val battleLogsDir = File("./battle_logs/")
|
||||
if (!battleLogsDir.exists()) {
|
||||
battleLogsDir.mkdirs()
|
||||
}
|
||||
|
||||
val logFile = File(battleLogsDir, "$battleId.txt")
|
||||
logFile.bufferedWriter().use { out ->
|
||||
battleLog.forEach {
|
||||
out.write(it)
|
||||
out.newLine()
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.info("Saved battle log as $battleId.txt")
|
||||
}
|
||||
|
||||
fun sendUpdate(packet: NetworkPacket<*>) {
|
||||
actors.forEach { it.sendUpdate(packet) }
|
||||
sendSpectatorUpdate(packet)
|
||||
}
|
||||
@@ -231,23 +296,23 @@ open class PokemonBattle(
|
||||
* @param opponentPacket The packet sent to the opposing actors.
|
||||
* @param spectatorsAsAlly If the spectators receive the [allyPacket] or the [opponentPacket], default is false.
|
||||
*/
|
||||
fun sendSidedUpdate(source: BattleActor, allyPacket: NetworkPacket, opponentPacket: NetworkPacket, spectatorsAsAlly: Boolean = false) {
|
||||
fun sendSidedUpdate(source: BattleActor, allyPacket: NetworkPacket<*>, opponentPacket: NetworkPacket<*>, spectatorsAsAlly: Boolean = false) {
|
||||
source.getSide().actors.forEach { it.sendUpdate(allyPacket) }
|
||||
source.getSide().getOppositeSide().actors.forEach { it.sendUpdate(opponentPacket) }
|
||||
sendSpectatorUpdate(if (spectatorsAsAlly) allyPacket else opponentPacket)
|
||||
}
|
||||
|
||||
fun sendToActors(packet: NetworkPacket) {
|
||||
CobblemonNetwork.sendToPlayers(actors.flatMap { it.getPlayerUUIDs().mapNotNull { it.getPlayer() } }, packet)
|
||||
fun sendToActors(packet: NetworkPacket<*>) {
|
||||
CobblemonNetwork.sendPacketToPlayers(actors.flatMap { it.getPlayerUUIDs().mapNotNull { it.getPlayer() } }, packet)
|
||||
}
|
||||
|
||||
fun sendSplitUpdate(privateActor: BattleActor, publicPacket: NetworkPacket, privatePacket: NetworkPacket) {
|
||||
fun sendSplitUpdate(privateActor: BattleActor, publicPacket: NetworkPacket<*>, privatePacket: NetworkPacket<*>) {
|
||||
actors.forEach { it.sendUpdate(if (it == privateActor) privatePacket else publicPacket) }
|
||||
sendSpectatorUpdate(publicPacket)
|
||||
}
|
||||
|
||||
fun sendSpectatorUpdate(packet: NetworkPacket) {
|
||||
CobblemonNetwork.sendToPlayers(spectators.mapNotNull { it.getPlayer() }, packet)
|
||||
fun sendSpectatorUpdate(packet: NetworkPacket<*>) {
|
||||
CobblemonNetwork.sendPacketToPlayers(spectators.mapNotNull { it.getPlayer() }, packet)
|
||||
}
|
||||
|
||||
fun dispatch(dispatcher: () -> DispatchResult) {
|
||||
@@ -288,17 +353,26 @@ open class PokemonBattle(
|
||||
}
|
||||
|
||||
fun tick() {
|
||||
while (dispatchResult.canProceed()) {
|
||||
val dispatch = dispatches.poll() ?: break
|
||||
dispatchResult = dispatch(this)
|
||||
try {
|
||||
while (dispatchResult.canProceed()) {
|
||||
val dispatch = dispatches.poll() ?: break
|
||||
dispatchResult = dispatch(this)
|
||||
}
|
||||
|
||||
if (dispatches.isEmpty()) {
|
||||
afterDispatches.toList().forEach { it() }
|
||||
afterDispatches.clear()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
LOGGER.error("Exception while ticking a battle. Saving battle log.", e)
|
||||
val message = battleLang("crash").red()
|
||||
this.actors.filterIsInstance<PlayerBattleActor>().forEach { it.entity?.sendMessage(message) }
|
||||
this.saveBattleLog()
|
||||
this.stop()
|
||||
return
|
||||
}
|
||||
|
||||
if (dispatches.isEmpty()) {
|
||||
afterDispatches.toList().forEach { it() }
|
||||
afterDispatches.clear()
|
||||
}
|
||||
|
||||
if (started && isPvW && !ended) {
|
||||
if (started && isPvW && !ended && dispatches.isEmpty()) {
|
||||
checkFlee()
|
||||
}
|
||||
}
|
||||
@@ -322,8 +396,14 @@ open class PokemonBattle(
|
||||
nearestPlayerActorDistance != null && nearestPlayerActorDistance < pokemonActor.fleeDistance
|
||||
}
|
||||
}
|
||||
|
||||
if (wildPokemonOutOfRange) {
|
||||
// Heal Wild Pokemon
|
||||
actors.filter { it.type == ActorType.WILD }
|
||||
.filterIsInstance<EntityBackedBattleActor<*>>()
|
||||
.mapNotNull { it.entity }
|
||||
.filterIsInstance<PokemonEntity>()
|
||||
.forEach{it.pokemon.heal()}
|
||||
CobblemonEvents.BATTLE_FLED.post(BattleFledEvent(this, actors.asSequence().filterIsInstance<PlayerBattleActor>().iterator().next()))
|
||||
actors.filterIsInstance<EntityBackedBattleActor<*>>().mapNotNull { it.entity }.forEach { it.sendMessage(battleLang("flee").yellow()) }
|
||||
stop()
|
||||
}
|
||||
@@ -372,5 +452,4 @@ open class PokemonBattle(
|
||||
LOGGER.error("Missing interpretation on '{}' action: \nPublic » {}\nPrivate » {}", publicMessage.id, publicMessage.rawMessage, privateMessage.rawMessage)
|
||||
return Text.literal("Missing interpretation on '${publicMessage.id}' action please report to the developers").red()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+18
-2
@@ -8,9 +8,12 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.battles.model.actor
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon.LOGGER
|
||||
import com.cobblemon.mod.common.api.battles.model.ai.BattleAI
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.battles.PassActionResponse
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.exception.IllegalActionChoiceException
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
|
||||
import java.util.UUID
|
||||
|
||||
@@ -19,11 +22,24 @@ abstract class AIBattleActor(
|
||||
pokemonList: List<BattlePokemon>,
|
||||
val battleAI: BattleAI
|
||||
) : BattleActor(gameId, pokemonList.toMutableList()) {
|
||||
override fun sendUpdate(packet: NetworkPacket) {
|
||||
override fun sendUpdate(packet: NetworkPacket<*>) {
|
||||
super.sendUpdate(packet)
|
||||
|
||||
if (packet is BattleMakeChoicePacket) {
|
||||
setActionResponses(request!!.iterate(this.activePokemon, battleAI::choose) )
|
||||
this.onChoiceRequested()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the AI is requested to make a choice.
|
||||
*/
|
||||
open fun onChoiceRequested() {
|
||||
try {
|
||||
setActionResponses(request!!.iterate(this.activePokemon, battleAI::choose))
|
||||
} catch (exception: IllegalActionChoiceException) {
|
||||
LOGGER.error("AI was unable to choose a move, we're going to need to pass!")
|
||||
exception.printStackTrace()
|
||||
setActionResponses(request!!.iterate(this.activePokemon) { _, _, _ -> PassActionResponse })
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
-12
@@ -11,12 +11,13 @@ package com.cobblemon.mod.common.api.battles.model.actor
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.battles.ActiveBattlePokemon
|
||||
import com.cobblemon.mod.common.battles.BallActionResponse
|
||||
import com.cobblemon.mod.common.battles.ForcePassActionResponse
|
||||
import com.cobblemon.mod.common.battles.ShowdownActionRequest
|
||||
import com.cobblemon.mod.common.battles.ShowdownActionResponse
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.exception.IllegalActionChoiceException
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleApplyPassResponsePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
|
||||
import java.util.UUID
|
||||
@@ -40,11 +41,24 @@ abstract class BattleActor(
|
||||
|
||||
var request: ShowdownActionRequest? = null
|
||||
var responses = mutableListOf<ShowdownActionResponse>()
|
||||
var expectingCaptureActions = 0
|
||||
val expectingPassActions = mutableListOf<ShowdownActionResponse>()
|
||||
var mustChoose = false
|
||||
|
||||
/** For when battles start, it's the number of Pokémon that are still in the process of being sent out (animation wise) */
|
||||
var stillSendingOutCount = 0
|
||||
|
||||
abstract val type: ActorType
|
||||
|
||||
fun canFitForcedAction() = mustChoose && request?.let { request ->
|
||||
val countMovable = (request.active?.count() ?: 0) - request.forceSwitch.count { it }
|
||||
return@let countMovable > expectingPassActions.size && !battle.ended
|
||||
} ?: false
|
||||
|
||||
fun forceChoose(response: ShowdownActionResponse) {
|
||||
expectingPassActions.add(response)
|
||||
sendUpdate(BattleApplyPassResponsePacket())
|
||||
}
|
||||
|
||||
fun getSide() = if (this in battle.side1.actors) battle.side1 else battle.side2
|
||||
open fun getPlayerUUIDs(): Iterable<UUID> = emptyList()
|
||||
|
||||
@@ -60,7 +74,7 @@ abstract class BattleActor(
|
||||
val requestActive = request.active
|
||||
if (requestActive == null || requestActive.isEmpty() || request.wait) {
|
||||
this.request = null
|
||||
expectingCaptureActions = 0
|
||||
expectingPassActions.clear()
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -78,23 +92,24 @@ abstract class BattleActor(
|
||||
|
||||
fun setActionResponses(responses: List<ShowdownActionResponse>) {
|
||||
val request = request ?: return
|
||||
val originalCaptureActions = expectingCaptureActions
|
||||
val originalPassActions = expectingPassActions.toList()
|
||||
responses.forEachIndexed { index, response ->
|
||||
val activeBattlePokemon = activePokemon.let { if (it.size > index) it[index] else return }
|
||||
val showdownMoveSet = request.active?.let { if (it.size > index) it[index] else null }
|
||||
val forceSwitch = request.forceSwitch.let { if (it.size > index) it[index] else false }
|
||||
if (!response.isValid(activeBattlePokemon, showdownMoveSet, forceSwitch)) {
|
||||
expectingCaptureActions = originalCaptureActions
|
||||
expectingPassActions.clear()
|
||||
expectingPassActions.addAll(originalPassActions)
|
||||
throw IllegalActionChoiceException(this, "Invalid action choice for ${activeBattlePokemon.battlePokemon!!.getName().string}: $response")
|
||||
} else if (response is BallActionResponse) {
|
||||
expectingCaptureActions--
|
||||
} else if (response is ForcePassActionResponse) {
|
||||
this.responses.add(expectingPassActions.removeAt(0))
|
||||
} else {
|
||||
this.responses.add(response)
|
||||
}
|
||||
this.responses.add(response)
|
||||
}
|
||||
if (expectingCaptureActions > 0) {
|
||||
if (expectingPassActions.size > 0) {
|
||||
throw IllegalActionChoiceException(this, "Invalid action choice: a capture was expected. Are you hacking me?")
|
||||
}
|
||||
expectingCaptureActions = originalCaptureActions
|
||||
mustChoose = false
|
||||
battle.checkForInputDispatch()
|
||||
}
|
||||
@@ -110,7 +125,7 @@ abstract class BattleActor(
|
||||
}
|
||||
responses.clear()
|
||||
request = null
|
||||
expectingCaptureActions = 0
|
||||
expectingPassActions.clear()
|
||||
battle.writeShowdownAction(">$showdownId ${showdownMessages.joinToString()}")
|
||||
}
|
||||
|
||||
@@ -129,5 +144,5 @@ abstract class BattleActor(
|
||||
sendUpdate(BattleMessagePacket(component))
|
||||
}
|
||||
open fun awardExperience(battlePokemon: BattlePokemon, experience: Int) {}
|
||||
open fun sendUpdate(packet: NetworkPacket) {}
|
||||
open fun sendUpdate(packet: NetworkPacket<*>) {}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.berry.spawncondition.BerrySpawnCondition
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.mulch.MulchVariant
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stat
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Status
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.BerryRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.pokemon.adapters.CobblemonStatTypeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.*
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import java.awt.Color
|
||||
import net.minecraft.predicate.NumberRange
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
import net.minecraft.registry.tag.TagKey
|
||||
import net.minecraft.resource.ResourceType
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.Box
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import net.minecraft.world.biome.Biome
|
||||
|
||||
/**
|
||||
* The data registry for [Berry].
|
||||
*
|
||||
* @author Licious
|
||||
* @since November 28th, 2022
|
||||
*/
|
||||
object Berries : JsonDataRegistry<Berry> {
|
||||
|
||||
override val id: Identifier = cobblemonResource("berries")
|
||||
override val type: ResourceType = ResourceType.SERVER_DATA
|
||||
override val observable = SimpleObservable<Berries>()
|
||||
|
||||
override val gson = GsonBuilder()
|
||||
.disableHtmlEscaping()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(MulchVariant::class.java, MulchVariantAdapter)
|
||||
.registerTypeAdapter(NumberRange.FloatRange::class.java, FloatNumberRangeAdapter)
|
||||
.registerTypeAdapter(Status::class.java, StatusAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(Collection::class.java, Box::class.java).type, BoxCollectionAdapter)
|
||||
.registerTypeAdapter(Box::class.java, BoxAdapter)
|
||||
.registerTypeAdapter(Vec3d::class.java, VerboseVec3dAdapter)
|
||||
.registerTypeAdapter(Identifier::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(GrowthFactor::class.java, CobblemonGrowthFactorAdapter)
|
||||
.registerTypeAdapter(IntRange::class.java, VerboseIntRangeAdapter)
|
||||
.registerTypeAdapter(Color::class.java, LiteralHexColorAdapter)
|
||||
.registerTypeAdapter(Stat::class.java, CobblemonStatTypeAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(TagKey::class.java, Biome::class.java).type, TagKeyAdapter(RegistryKeys.BIOME))
|
||||
.registerTypeAdapter(BerrySpawnCondition::class.java, CobblemonBerrySpawnConditionAdapter)
|
||||
.create()
|
||||
override val typeToken: TypeToken<Berry> = TypeToken.get(Berry::class.java)
|
||||
override val resourcePath = "berries"
|
||||
|
||||
private val berries = hashMapOf<Identifier, Berry>()
|
||||
|
||||
override fun reload(data: Map<Identifier, Berry>) {
|
||||
this.berries.clear()
|
||||
data.forEach { (identifier, berry) ->
|
||||
try {
|
||||
berry.identifier = identifier
|
||||
berry.validate()
|
||||
this.berries[identifier] = berry
|
||||
} catch (e: Exception) {
|
||||
Cobblemon.LOGGER.error("Skipped loading the {} berry", identifier, e)
|
||||
}
|
||||
}
|
||||
Cobblemon.LOGGER.info("Loaded {} berries", this.berries.size)
|
||||
this.observable.emit(this)
|
||||
}
|
||||
|
||||
override fun sync(player: ServerPlayerEntity) {
|
||||
BerryRegistrySyncPacket(this.all()).sendToPlayer(player)
|
||||
}
|
||||
|
||||
fun all() = this.berries.values.toList()
|
||||
|
||||
/**
|
||||
* Gets a berry if loaded.
|
||||
*
|
||||
* @param identifier The identifier of the berry.
|
||||
* @return The [Berry] if loaded otherwise null.
|
||||
*/
|
||||
fun getByIdentifier(identifier: Identifier): Berry? = this.berries[identifier]
|
||||
|
||||
/**
|
||||
* Gets a berry if loaded.
|
||||
*
|
||||
* @param name The path of the identifier of the berry under the [Cobblemon.MODID] namespace.
|
||||
* @return The [Berry] if loaded otherwise null.
|
||||
*/
|
||||
fun getByName(name: String): Berry? = this.getByIdentifier(cobblemonResource(name))
|
||||
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
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.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.berry.BerryYieldCalculationEvent
|
||||
import com.cobblemon.mod.common.api.mulch.MulchVariant
|
||||
import com.cobblemon.mod.common.block.BerryBlock
|
||||
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
|
||||
import com.cobblemon.mod.common.item.BerryItem
|
||||
import com.cobblemon.mod.common.pokemon.Nature
|
||||
import com.cobblemon.mod.common.util.readBox
|
||||
import com.cobblemon.mod.common.util.writeBox
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import java.awt.Color
|
||||
import java.util.EnumSet
|
||||
import kotlin.math.min
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.model.ModelPart
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.registry.tag.TagKey
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.Box
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import net.minecraft.util.shape.VoxelShape
|
||||
import net.minecraft.util.shape.VoxelShapes
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.biome.Biome
|
||||
|
||||
/**
|
||||
* Represents the data behind a berry.
|
||||
*
|
||||
* @property identifier The [Identifier] of this berry.
|
||||
* @property baseYield The [IntRange] possible for the berry tree before [bonusYield] is calculated.
|
||||
* @property preferredBiomeTags The [TagKey]s of the berries preffered biomes. Determines spawning and yield
|
||||
* @property growthTime The [IntRange] possible in minutes for how long the berry tree takes to grow.
|
||||
* @property refreshRate The [IntRange] possible in minutes for how long the berry tree takes to regrow its berries once it has been harvested.
|
||||
* @depreciated @property lifeCycles The [IntRange] possible for the berry to live for between harvests.
|
||||
* @property favoriteMulches The types of mulches that benefit this berries yield
|
||||
* @property growthFactors An array of [GrowthFactor]s that will affect this berry. The client is not aware of these.
|
||||
* @property mutations A map of the partner berry as the key and the value as the resulting mutation with this berry.
|
||||
* @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 tintIndexes Determines tints at specific indexes if any.
|
||||
* @property flowerModelIdentifier The [Identifier] for the model of the berry in flower form.
|
||||
* @property flowerTexture The [Identifier] for the texture of the berry in flower form. This is resolved into a [ModelPart] on the client.
|
||||
* @property fruitModelIdentifier The [Identifier] for the model of the berry in flower form. This is resolved into a [ModelPart] on the client.
|
||||
* @property fruitTexture The [Identifier] for the texture of the berry in flower form.
|
||||
*
|
||||
* @throws IllegalArgumentException if the any yield range argument is not a positive range.
|
||||
*/
|
||||
class Berry(
|
||||
identifier: Identifier,
|
||||
val baseYield: IntRange,
|
||||
val preferredBiomeTags: List<TagKey<Biome>>,
|
||||
val growthTime: IntRange,
|
||||
val refreshRate: IntRange,
|
||||
//val lifeCycles: IntRange,
|
||||
val favoriteMulches: EnumSet<MulchVariant>,
|
||||
val growthFactors: Collection<GrowthFactor>,
|
||||
val spawnConditions: List<BerrySpawnCondition>,
|
||||
var growthPoints: Array<GrowthPoint>,
|
||||
val randomizedGrowthPoints: Boolean = true,
|
||||
val mutations: Map<Identifier, Identifier>,
|
||||
@SerializedName("sproutShape")
|
||||
private val sproutShapeBoxes: Collection<Box>,
|
||||
@SerializedName("matureShape")
|
||||
private val matureShapeBoxes: Collection<Box>,
|
||||
private val flavors: Map<Flavor, Int>,
|
||||
val tintIndexes: Map<Int, Color>,
|
||||
@SerializedName("flowerModel")
|
||||
val flowerModelIdentifier: Identifier,
|
||||
val flowerTexture: Identifier,
|
||||
@SerializedName("fruitModel")
|
||||
val fruitModelIdentifier: Identifier,
|
||||
val fruitTexture: Identifier,
|
||||
val weight: Float
|
||||
) {
|
||||
|
||||
@Transient
|
||||
var identifier: Identifier = identifier
|
||||
internal set
|
||||
|
||||
@Transient
|
||||
private lateinit var shapedFlower: HashMap<Int, VoxelShape>
|
||||
|
||||
@Transient
|
||||
private lateinit var shapedFruit: HashMap<Int, VoxelShape>
|
||||
|
||||
/**
|
||||
* The [VoxelShape] of the tree during the sprouting stages.
|
||||
*/
|
||||
@Transient
|
||||
lateinit var sproutShape: VoxelShape
|
||||
private set
|
||||
|
||||
/**
|
||||
* The [VoxelShape] of the tree during the mature stages.
|
||||
*/
|
||||
@Transient
|
||||
lateinit var matureShape: VoxelShape
|
||||
private set
|
||||
|
||||
init {
|
||||
this.validate()
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the [BerryItem] that uses this berry for data.
|
||||
*
|
||||
* @return The [BerryItem] if existing.
|
||||
*/
|
||||
fun item(): BerryItem? = CobblemonItems.berries()[this.identifier]
|
||||
|
||||
/**
|
||||
* Finds the [BerryBlock] that uses this berry for data.
|
||||
*
|
||||
* @return The [BerryBlock] if existing.
|
||||
*/
|
||||
fun block(): BerryBlock? = CobblemonBlocks.berries()[this.identifier]
|
||||
|
||||
/**
|
||||
* Query the value of a certain flavor.
|
||||
*
|
||||
* @param flavor The [Flavor] being queried.
|
||||
* @return The value if any or 0.
|
||||
*/
|
||||
fun flavor(flavor: Flavor): Int = this.flavors[flavor] ?: 0
|
||||
|
||||
fun dislikedBy(nature: Nature): Boolean {
|
||||
val dislikedFlavor = nature.dislikedFlavor ?: return false
|
||||
return flavor(dislikedFlavor) > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the yield for a berry tree being planted or replanted after a life cycle.
|
||||
* Triggers [BerryYieldCalculationEvent].
|
||||
*
|
||||
* @param world The [World] the tree is present in.
|
||||
* @param state The [BlockState] of the tree.
|
||||
* @param pos The [BlockPos] of the tree.
|
||||
* @param placer The [LivingEntity] tending to the tree, if any.
|
||||
* @return The total berry stack count.
|
||||
*/
|
||||
fun calculateYield(world: World, state: BlockState, pos: BlockPos, placer: LivingEntity? = null): Int {
|
||||
val base = this.baseYield.random()
|
||||
val bonus = this.bonusYield(world, state, pos)
|
||||
var yield = base + bonus.first
|
||||
val treeEntity = world.getBlockEntity(pos) as BerryBlockEntity
|
||||
if (BerryBlock.getMulch(state) == MulchVariant.RICH) {
|
||||
yield = min(yield + 1, maxYield())
|
||||
treeEntity.decrementMulchDuration(world, pos, state)
|
||||
}
|
||||
val event = BerryYieldCalculationEvent(this, world, state, pos, placer, yield, bonus.second)
|
||||
CobblemonEvents.BERRY_YIELD.post(event) { yield = it.yield }
|
||||
return yield
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates and returns the minimum possible yield by summing [baseYield] and [growthFactors] minimum values.
|
||||
*
|
||||
* @return The minimum possible yield.
|
||||
*/
|
||||
fun minYield() = this.baseYield.first + this.growthFactors.sumOf { it.minYield() }
|
||||
|
||||
/**
|
||||
* Calculates and returns the maximum possible yield by summing [baseYield] and [growthFactors] max values.
|
||||
*
|
||||
* @return The maximum possible yield.
|
||||
*/
|
||||
fun maxYield() = this.baseYield.last + this.growthFactors.sumOf { it.maxYield() }
|
||||
|
||||
/**
|
||||
* Checks if this berry can mutate with the given [partner].
|
||||
* For the berry the mutations may produce use [mutationWith].
|
||||
*
|
||||
* @param partner The [Berry] being checked as a possible mutation partner.
|
||||
* @return If a mutation is possible.
|
||||
*/
|
||||
fun canMutateWith(partner: Berry) = this.mutationWith(partner) != null
|
||||
|
||||
/**
|
||||
* Query for the possible mutation with the given [partner].
|
||||
*
|
||||
* @param partner The [Berry] being mutated with.
|
||||
* @return The resulting [Berry] if the mutation is possible.
|
||||
*/
|
||||
fun mutationWith(partner: Berry): Berry? {
|
||||
val berryIdentifier = this.mutations[partner.identifier] ?: return null
|
||||
return Berries.getByIdentifier(berryIdentifier)
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for a possible partner to mutate into the given [resulting].
|
||||
*
|
||||
* @param resulting The [Berry] the mutation should result in.
|
||||
* @return The [Berry] that mutates with this berry into the given [resulting] if possible.
|
||||
*/
|
||||
fun partnerForMutation(resulting: Berry): Berry? {
|
||||
return this.mutations.firstNotNullOfOrNull { (partner, result) ->
|
||||
if (result == resulting.identifier)
|
||||
Berries.getByIdentifier(partner)
|
||||
else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
// A cheat since gson doesn't invoke init block
|
||||
internal fun validate() {
|
||||
if (this.baseYield.first < 0 || this.baseYield.last < 0) {
|
||||
throw IllegalArgumentException("A berry base yield must be a positive range")
|
||||
}
|
||||
if (this.growthTime.first < 0 || this.growthTime.last < 0) {
|
||||
throw IllegalArgumentException("The growth time must be a positive range")
|
||||
}
|
||||
if (this.refreshRate.first < 0 || this.refreshRate.last < 0) {
|
||||
throw IllegalArgumentException("The refresh rate must be a positive range")
|
||||
}
|
||||
/*
|
||||
if (this.lifeCycles.first < 0 || this.lifeCycles.last < 0) {
|
||||
throw IllegalArgumentException("A berry life cycle must be a positive range")
|
||||
}
|
||||
*/
|
||||
this.growthFactors.forEach { it.validateArguments() }
|
||||
val maxYield = this.maxYield()
|
||||
if (this.growthPoints.size < maxYield) {
|
||||
throw IllegalArgumentException("Anchor points must have enough elements for the max possible yield of $maxYield you've provided ${this.growthPoints.size} points")
|
||||
}
|
||||
this.shapedFlower = hashMapOf()
|
||||
this.shapedFruit = hashMapOf()
|
||||
this.sproutShape = this.createAndUniteShapes(this.sproutShapeBoxes)
|
||||
this.matureShape = this.createAndUniteShapes(this.matureShapeBoxes)
|
||||
}
|
||||
|
||||
internal fun encode(buffer: PacketByteBuf) {
|
||||
buffer.writeIdentifier(this.identifier)
|
||||
buffer.writeInt(this.baseYield.first)
|
||||
buffer.writeInt(this.baseYield.last)
|
||||
buffer.writeEnumSet(favoriteMulches, MulchVariant::class.java)
|
||||
//buffer.writeInt(this.lifeCycles.first)
|
||||
//buffer.writeInt(this.lifeCycles.last)
|
||||
buffer.writeInt(this.growthTime.first)
|
||||
buffer.writeInt(this.growthTime.last)
|
||||
buffer.writeInt(this.refreshRate.first)
|
||||
buffer.writeInt(this.refreshRate.last)
|
||||
buffer.writeCollection(this.growthPoints.toList()) { writer, value ->
|
||||
writer.writeDouble(value.position.x)
|
||||
writer.writeDouble(value.position.y)
|
||||
writer.writeDouble(value.position.z)
|
||||
writer.writeDouble(value.rotation.x)
|
||||
writer.writeDouble(value.rotation.y)
|
||||
writer.writeDouble(value.rotation.z)
|
||||
}
|
||||
buffer.writeBoolean(this.randomizedGrowthPoints)
|
||||
buffer.writeMap(this.mutations, { writer, key -> writer.writeIdentifier(key) }, { writer, value -> writer.writeIdentifier(value) })
|
||||
buffer.writeCollection(this.sproutShapeBoxes) { writer, value ->
|
||||
writer.writeBox(value)
|
||||
}
|
||||
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.tintIndexes, { writer, key -> writer.writeInt(key) }, { writer, value -> writer.writeInt(value.rgb) })
|
||||
buffer.writeIdentifier(this.flowerModelIdentifier)
|
||||
buffer.writeIdentifier(this.flowerTexture)
|
||||
buffer.writeIdentifier(this.fruitModelIdentifier)
|
||||
buffer.writeIdentifier(this.fruitTexture)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the bonus yield for the berry tree.
|
||||
*
|
||||
* @param world The [World] the tree is present in.
|
||||
* @param state The [BlockState] of the tree.
|
||||
* @param pos The [BlockPos] of the tree.
|
||||
* @return The bonus yield, the growth factors that passed.
|
||||
*/
|
||||
private fun bonusYield(world: World, state: BlockState, pos: BlockPos): Pair<Int, Collection<GrowthFactor>> {
|
||||
var bonus = 0
|
||||
val passed = arrayListOf<GrowthFactor>()
|
||||
val mulchVariant = BerryBlock.getMulch(state)
|
||||
val hasBiomeMulch = mulchVariant in favoriteMulches
|
||||
this.growthFactors.forEach { factor ->
|
||||
if (factor.isValid(world, state, pos)) {
|
||||
bonus += factor.yield()
|
||||
passed += factor
|
||||
} else if (hasBiomeMulch) {
|
||||
bonus += factor.yield()
|
||||
}
|
||||
}
|
||||
return bonus to passed
|
||||
}
|
||||
|
||||
private fun createAndUniteShapes(boxes: Collection<Box>): VoxelShape {
|
||||
var shape: VoxelShape? = null
|
||||
boxes.forEach { box ->
|
||||
shape = if (shape == null) {
|
||||
Block.createCuboidShape(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)
|
||||
} else {
|
||||
VoxelShapes.union(shape, Block.createCuboidShape(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ))
|
||||
}
|
||||
}
|
||||
return shape ?: VoxelShapes.fullCube()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
internal fun decode(buffer: PacketByteBuf): Berry {
|
||||
val identifier = buffer.readIdentifier()
|
||||
val baseYield = IntRange(buffer.readInt(), buffer.readInt())
|
||||
val favMulchs = buffer.readEnumSet(MulchVariant::class.java)
|
||||
//val lifeCycles = IntRange(buffer.readInt(), buffer.readInt())
|
||||
val growthTime = IntRange(buffer.readInt(), buffer.readInt())
|
||||
val refreshRate = IntRange(buffer.readInt(), buffer.readInt())
|
||||
val growthPoints = buffer.readList { reader ->
|
||||
GrowthPoint(Vec3d(reader.readDouble(), reader.readDouble(), reader.readDouble()), Vec3d(reader.readDouble(), reader.readDouble(), reader.readDouble()))
|
||||
}.toTypedArray()
|
||||
val randomizedGrowthPoints = buffer.readBoolean()
|
||||
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 tintIndexes = buffer.readMap({ reader -> reader.readInt() }, { reader -> Color(reader.readInt()) })
|
||||
val flowerModelIdentifier = buffer.readIdentifier()
|
||||
val flowerTexture = buffer.readIdentifier()
|
||||
val fruitModelIdentifier = buffer.readIdentifier()
|
||||
val fruitTexture = buffer.readIdentifier()
|
||||
return Berry(identifier, baseYield, emptyList(), growthTime, refreshRate, favMulchs, emptySet(), emptyList(), growthPoints, randomizedGrowthPoints, mutations, sproutShapeBoxes, matureShapeBoxes, flavors, tintIndexes, flowerModelIdentifier, flowerTexture, fruitModelIdentifier, fruitTexture, 0F)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.api.berry
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonBlocks
|
||||
import com.cobblemon.mod.common.block.BerryBlock
|
||||
import com.cobblemon.mod.common.world.feature.BerryGroveFeature
|
||||
import com.google.common.cache.CacheBuilder
|
||||
import com.google.common.cache.CacheLoader
|
||||
import com.google.common.cache.LoadingCache
|
||||
import net.minecraft.registry.entry.RegistryEntry
|
||||
import net.minecraft.world.biome.Biome
|
||||
|
||||
object BerryHelper {
|
||||
private val CACHE_LOADER = object : CacheLoader<RegistryEntry<Biome>, List<BerryBlock>>() {
|
||||
override fun load(key: RegistryEntry<Biome>): List<BerryBlock> {
|
||||
return naturalBerries.filter { berryBlock ->
|
||||
val berry = berryBlock.berry()
|
||||
berry?.spawnConditions?.any { it.canSpawn(berry, key) } ?: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val naturalBerries = CobblemonBlocks.berries().values.filter {
|
||||
(it.berry()?.spawnConditions?.size ?: 0) > 0
|
||||
}
|
||||
|
||||
private val validBerryCache: LoadingCache<RegistryEntry<Biome>, List<BerryBlock>> = CacheBuilder.newBuilder()
|
||||
.maximumSize(4)
|
||||
.build(CACHE_LOADER)
|
||||
|
||||
|
||||
fun getBerriesForBiome(biome: RegistryEntry<Biome>): List<BerryBlock> {
|
||||
return validBerryCache.get(biome)
|
||||
}
|
||||
|
||||
fun getNaturallyGeneratingBerries(): List<BerryBlock> {
|
||||
return naturalBerries
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
SPICY,
|
||||
DRY,
|
||||
SWEET,
|
||||
BITTER,
|
||||
SOUR
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.WorldView
|
||||
|
||||
/**
|
||||
* Represents a condition that impacts extra berry yield.
|
||||
*
|
||||
* @author Licious
|
||||
* @since December 2nd, 2022
|
||||
*/
|
||||
interface GrowthFactor {
|
||||
|
||||
/**
|
||||
* Validates the arguments contained in this factor, this is invoked during loading.
|
||||
*
|
||||
* @throws IllegalArgumentException If an argument isn't valid.
|
||||
*/
|
||||
fun validateArguments()
|
||||
|
||||
/**
|
||||
* Checks if this factor should yield a bonus.
|
||||
*
|
||||
* @param world The [WorldView] the berry tree is in.
|
||||
* @param state The [BlockState] of the berry tree.
|
||||
* @param pos The [BlockPos] of the berry tree.
|
||||
* @return If the bonus should activate.
|
||||
*/
|
||||
fun isValid(world: WorldView, state: BlockState, pos: BlockPos): Boolean
|
||||
|
||||
/**
|
||||
* Resolves the amount of bonus berries to grow if [isValid] was true.
|
||||
*
|
||||
* @return The amount of extra berries to grow.
|
||||
*/
|
||||
fun yield(): Int
|
||||
|
||||
/**
|
||||
* Returns the minimum possible yield for this factor.
|
||||
*
|
||||
* @return The minimum possible yield for this factor.
|
||||
*/
|
||||
fun minYield(): Int
|
||||
|
||||
/**
|
||||
* Returns the maximum possible yield for this factor.
|
||||
*
|
||||
* @return The maximum possible yield for this factor.
|
||||
*/
|
||||
fun maxYield(): Int
|
||||
|
||||
}
|
||||
@@ -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.berry
|
||||
|
||||
import net.minecraft.util.math.Vec3d
|
||||
|
||||
/**
|
||||
* Represents a position in a berry tree where a berry will flower then fruit.
|
||||
*
|
||||
* @property position The coordinates of the berry in the tree block.
|
||||
* @property rotation The degree value for the rotation each axis.
|
||||
*
|
||||
* @author Licious
|
||||
* @since December 19th, 2022
|
||||
*/
|
||||
data class GrowthPoint(
|
||||
val position: Vec3d,
|
||||
val rotation: Vec3d
|
||||
)
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.adapter
|
||||
|
||||
import com.cobblemon.mod.common.api.berry.GrowthFactor
|
||||
import com.cobblemon.mod.common.util.adapters.CobblemonGrowthFactorAdapter
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonSerializer
|
||||
import net.minecraft.util.Identifier
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* A type adapter for [GrowthFactor]s.
|
||||
* For the default implementation see [CobblemonGrowthFactorAdapter].
|
||||
*
|
||||
* @author Licious
|
||||
* @since December 2nd, 2022
|
||||
*/
|
||||
interface GrowthFactorAdapter : JsonDeserializer<GrowthFactor>, JsonSerializer<GrowthFactor> {
|
||||
|
||||
/**
|
||||
* Register a [GrowthFactor] to be used by this adapter.
|
||||
*
|
||||
* @param type The [KClass] of the [GrowthFactor].
|
||||
* @param identifier The expected [Identifier] in the parsed JSON.
|
||||
*/
|
||||
fun register(type: KClass<out GrowthFactor>, identifier: Identifier)
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.adapter
|
||||
|
||||
import com.cobblemon.mod.common.api.berry.GrowthFactor
|
||||
import com.cobblemon.mod.common.api.berry.spawncondition.BerrySpawnCondition
|
||||
import com.cobblemon.mod.common.util.adapters.CobblemonBerrySpawnConditionAdapter
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonSerializer
|
||||
import net.minecraft.util.Identifier
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* A type adapter for [GrowthFactor]s.
|
||||
* For the default implementation see [CobblemonBerrySpawnConditionAdapter].
|
||||
*
|
||||
* @author Apion
|
||||
* @since August 14, 2023
|
||||
*/
|
||||
interface SpawnConditionAdapter : JsonDeserializer<BerrySpawnCondition>, JsonSerializer<BerrySpawnCondition> {
|
||||
/**
|
||||
* Register a [BerrySpawnCondition] to be used by this adapter.
|
||||
*
|
||||
* @param type The [KClass] of the [BerrySpawnCondition].
|
||||
* @param identifier The expected [Identifier] in the parsed JSON.
|
||||
*/
|
||||
fun register(type: KClass<out BerrySpawnCondition>, identifier: Identifier)
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.spawncondition
|
||||
|
||||
import com.cobblemon.mod.common.api.berry.Berry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.registry.entry.RegistryEntry
|
||||
import net.minecraft.util.math.random.Random
|
||||
|
||||
import net.minecraft.world.biome.Biome
|
||||
|
||||
class AllBiomeCondition(val minGroveSize: Int, val maxGroveSize: Int) : BerrySpawnCondition{
|
||||
override fun canSpawn(berry: Berry, biome: RegistryEntry<Biome>): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getGroveSize(random: Random): Int {
|
||||
return random.nextBetween(minGroveSize, maxGroveSize)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("all_biome")
|
||||
}
|
||||
}
|
||||
+20
@@ -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.api.berry.spawncondition
|
||||
|
||||
import com.cobblemon.mod.common.api.berry.Berry
|
||||
import net.minecraft.registry.entry.RegistryEntry
|
||||
import net.minecraft.util.math.random.Random
|
||||
import net.minecraft.world.biome.Biome
|
||||
|
||||
interface BerrySpawnCondition {
|
||||
fun getGroveSize(random: Random): Int
|
||||
|
||||
fun canSpawn(berry: Berry, biome: RegistryEntry<Biome>): Boolean
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.spawncondition
|
||||
|
||||
import com.cobblemon.mod.common.api.berry.Berry
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.registry.entry.RegistryEntry
|
||||
import net.minecraft.util.math.random.Random
|
||||
import net.minecraft.world.biome.Biome
|
||||
import kotlin.math.min
|
||||
|
||||
class PreferredBiomeCondition(val minGroveSize: Int, val maxGroveSize: Int) : BerrySpawnCondition{
|
||||
|
||||
override fun getGroveSize(random: Random): Int {
|
||||
return random.nextBetween(minGroveSize, maxGroveSize)
|
||||
}
|
||||
|
||||
override fun canSpawn(berry: Berry, biome: RegistryEntry<Biome>): Boolean {
|
||||
val preferredBiomeTags = berry.preferredBiomeTags
|
||||
return preferredBiomeTags.any {biome.isIn(it)}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("preferred_biome")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.callback
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.moves.Move
|
||||
import com.cobblemon.mod.common.api.moves.MoveTemplate
|
||||
import com.cobblemon.mod.common.api.moves.Moves
|
||||
import com.cobblemon.mod.common.api.text.text
|
||||
import com.cobblemon.mod.common.battles.InBattleMove
|
||||
import com.cobblemon.mod.common.net.IntSize
|
||||
import com.cobblemon.mod.common.net.messages.client.callback.OpenMoveCallbackPacket
|
||||
import com.cobblemon.mod.common.util.readSizedInt
|
||||
import com.cobblemon.mod.common.util.writeSizedInt
|
||||
import java.util.UUID
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.text.Text
|
||||
|
||||
/**
|
||||
* Used for opening move selection screens for players and handling their choice. Currently
|
||||
* only supports up to 4 moves to select from.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since July 1st, 2023
|
||||
*/
|
||||
object MoveSelectCallbacks {
|
||||
val callbacks = mutableMapOf<UUID, MoveSelectCallback>()
|
||||
|
||||
@JvmOverloads
|
||||
fun create(
|
||||
player: ServerPlayerEntity,
|
||||
title: Text = "".text(),
|
||||
possibleMoves: List<MoveSelectDTO>,
|
||||
cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
handler: (ServerPlayerEntity, index: Int, MoveSelectDTO) -> Unit
|
||||
) {
|
||||
val callback = MoveSelectCallback(
|
||||
shownMoves = possibleMoves,
|
||||
cancel = cancel,
|
||||
handler = handler
|
||||
)
|
||||
|
||||
callbacks[player.uuid] = callback
|
||||
|
||||
player.sendPacket(OpenMoveCallbackPacket(callback.uuid, title.copy(), possibleMoves))
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun create(
|
||||
player: ServerPlayerEntity,
|
||||
moves: List<Move>,
|
||||
canSelect: (Move) -> Boolean = { true },
|
||||
cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
handler: (Move) -> Unit
|
||||
) = create(
|
||||
player = player,
|
||||
possibleMoves = moves.map { battleMove -> MoveSelectDTO(battleMove).also { it.enabled = canSelect(battleMove) } },
|
||||
cancel = cancel,
|
||||
handler = { _, index, _ -> handler(moves[index]) }
|
||||
)
|
||||
|
||||
@JvmOverloads
|
||||
fun createBattleSelect(
|
||||
player: ServerPlayerEntity,
|
||||
moves: List<InBattleMove>,
|
||||
canSelect: (InBattleMove) -> Boolean = { true },
|
||||
cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
handler: (InBattleMove) -> Unit
|
||||
) = create(
|
||||
player = player,
|
||||
possibleMoves = moves.map { battleMove -> MoveSelectDTO(battleMove).also { it.enabled = canSelect(battleMove) } },
|
||||
cancel = cancel,
|
||||
handler = { _, index, _ -> handler(moves[index]) }
|
||||
)
|
||||
|
||||
fun handleCancelled(player: ServerPlayerEntity, uuid: UUID) {
|
||||
val callback = callbacks[player.uuid] ?: return
|
||||
if (callback.uuid != uuid) {
|
||||
return
|
||||
}
|
||||
callbacks.remove(player.uuid)
|
||||
callback.cancel(player)
|
||||
}
|
||||
|
||||
fun handleCallback(player: ServerPlayerEntity, uuid: UUID, index: Int) {
|
||||
val callback = callbacks[player.uuid] ?: return
|
||||
callbacks.remove(player.uuid)
|
||||
if (callback.uuid != uuid) {
|
||||
Cobblemon.LOGGER.warn("A move select callback ran but with a mismatching UUID from ${player.gameProfile.name}. Hacking attempts?")
|
||||
} else if (index >= callback.shownMoves.size) {
|
||||
Cobblemon.LOGGER.warn("${player.gameProfile.name} used move select callback with an index that was out of bounds. Hacking attempts? Tried $index, possible size was ${callback.shownMoves.size}")
|
||||
} else if (!callback.shownMoves[index].enabled) {
|
||||
Cobblemon.LOGGER.warn("${player.gameProfile.name} used move select callback with a move that is not enabled. Hacking attempts?")
|
||||
} else {
|
||||
callback.handler(player, index, callback.shownMoves[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MoveSelectCallback(
|
||||
val uuid: UUID = UUID.randomUUID(),
|
||||
val shownMoves: List<MoveSelectDTO>,
|
||||
val cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
val handler: (ServerPlayerEntity, Int, MoveSelectDTO) -> Unit
|
||||
)
|
||||
|
||||
class MoveSelectDTO(val moveTemplate: MoveTemplate, var enabled: Boolean, val pp: Int = -1, val ppMax: Int = -1) {
|
||||
@JvmOverloads
|
||||
constructor(move: Move, enabled: Boolean = true): this(moveTemplate = move.template, enabled = enabled, pp = move.currentPp, ppMax = move.maxPp)
|
||||
@JvmOverloads
|
||||
constructor(move: InBattleMove, enabled: Boolean = true): this(moveTemplate = Moves.getByNameOrDummy(move.move), enabled = enabled, pp = move.pp, ppMax = move.maxpp)
|
||||
constructor(buffer: PacketByteBuf): this(
|
||||
moveTemplate = Moves.getByNameOrDummy(buffer.readString()),
|
||||
enabled = buffer.readBoolean(),
|
||||
pp = buffer.readSizedInt(IntSize.BYTE),
|
||||
ppMax = buffer.readSizedInt(IntSize.BYTE)
|
||||
)
|
||||
|
||||
fun writeToBuffer(buffer: PacketByteBuf) {
|
||||
buffer.writeString(moveTemplate.name)
|
||||
buffer.writeBoolean(enabled)
|
||||
buffer.writeSizedInt(IntSize.BYTE, pp)
|
||||
buffer.writeSizedInt(IntSize.BYTE, ppMax)
|
||||
}
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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.callback
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.moves.Move
|
||||
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyMoveCallbackPacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import java.util.UUID
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.text.MutableText
|
||||
|
||||
/**
|
||||
* Used for opening a party select screen for players which routes to move selection when they choose a Pokémon.
|
||||
* You can do the same sort of thing with combined [MoveSelectCallbacks] and [PartySelectCallbacks] but it isn't
|
||||
* as smooth an experience.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since July 29th, 2023
|
||||
*/
|
||||
object PartyMoveSelectCallbacks {
|
||||
val callbacks = mutableMapOf<UUID, PartyMoveSelectCallback>()
|
||||
|
||||
@JvmOverloads
|
||||
fun create(
|
||||
player: ServerPlayerEntity,
|
||||
partyTitle: MutableText = lang("ui.party"),
|
||||
pokemon: List<Pair<PartySelectPokemonDTO, List<MoveSelectDTO>>>,
|
||||
cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
handler: (ServerPlayerEntity, pokemonIndex: Int, PartySelectPokemonDTO, moveIndex: Int, MoveSelectDTO) -> Unit
|
||||
) {
|
||||
val callback = PartyMoveSelectCallback(
|
||||
pokemon = pokemon,
|
||||
cancel = cancel,
|
||||
handler = handler
|
||||
)
|
||||
callbacks[player.uuid] = callback
|
||||
player.sendPacket(OpenPartyMoveCallbackPacket(callback.uuid, partyTitle, callback.pokemon))
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun createFromPokemon(
|
||||
player: ServerPlayerEntity,
|
||||
partyTitle: MutableText = lang("ui.party"),
|
||||
pokemon: List<Pokemon>,
|
||||
moves: (Pokemon) -> List<Move> = { it.moveSet.getMoves() },
|
||||
canSelectPokemon: (Pokemon) -> Boolean = { true },
|
||||
canSelectMove: (Pokemon, Move) -> Boolean = { _, _ -> true },
|
||||
cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
handler: (Pokemon, Move) -> Unit
|
||||
) {
|
||||
val pokemonList = mutableListOf<Pair<PartySelectPokemonDTO, List<MoveSelectDTO>>>()
|
||||
for (pk in pokemon) {
|
||||
val enabled = canSelectPokemon(pk)
|
||||
val moveList = moves(pk).map { MoveSelectDTO(it, enabled = canSelectMove(pk, it)) }
|
||||
pokemonList.add(PartySelectPokemonDTO(pk, enabled) to moveList)
|
||||
}
|
||||
|
||||
create(
|
||||
player = player,
|
||||
partyTitle = partyTitle,
|
||||
pokemon = pokemonList,
|
||||
cancel = cancel,
|
||||
handler = { _, pkIndex, _, moveIndex, _ ->
|
||||
handler(pokemon[pkIndex], pokemon[pkIndex].moveSet[moveIndex] ?: return@create)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun handleCancelled(player: ServerPlayerEntity, uuid: UUID) {
|
||||
val callback = callbacks[player.uuid] ?: return
|
||||
if (callback.uuid != uuid) {
|
||||
return
|
||||
}
|
||||
callbacks.remove(player.uuid)
|
||||
callback.cancel(player)
|
||||
}
|
||||
|
||||
fun handleCallback(player: ServerPlayerEntity, uuid: UUID, pokemonIndex: Int, moveIndex: Int) {
|
||||
val callback = callbacks[player.uuid] ?: return
|
||||
callbacks.remove(player.uuid)
|
||||
if (callback.uuid != uuid) {
|
||||
return Cobblemon.LOGGER.warn("A party move select callback ran but with a mismatching UUID from ${player.gameProfile.name}. Hacking attempts?")
|
||||
} else if (pokemonIndex >= callback.pokemon.size) {
|
||||
return Cobblemon.LOGGER.warn("${player.gameProfile.name} used party move select callback with a Pokémon index that was out of bounds. Hacking attempts? Tried $pokemonIndex, possible size was ${callback.pokemon.size}")
|
||||
}
|
||||
|
||||
val (pokemon, moves) = callback.pokemon[pokemonIndex]
|
||||
|
||||
if (!pokemon.enabled) {
|
||||
return Cobblemon.LOGGER.warn("${player.gameProfile.name} used party move select callback with a Pokémon that is not enabled. Hacking attempts?")
|
||||
} else if (moveIndex >= moves.size) {
|
||||
return Cobblemon.LOGGER.warn("${player.gameProfile.name} used party move select callback with a move index that was out of bounds. Hacking attempts? Tried $pokemonIndex-$moveIndex, possible size was ${moves.size}")
|
||||
}
|
||||
|
||||
val move = moves[moveIndex]
|
||||
|
||||
if (!move.enabled) {
|
||||
Cobblemon.LOGGER.warn("${player.gameProfile.name} used party move select callback with a move that is not enabled. Hacking attempts?")
|
||||
} else {
|
||||
callback.handler(player, pokemonIndex, pokemon, moveIndex, move)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PartyMoveSelectCallback(
|
||||
val uuid: UUID = UUID.randomUUID(),
|
||||
val pokemon: List<Pair<PartySelectPokemonDTO, List<MoveSelectDTO>>>,
|
||||
val cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
val handler: (ServerPlayerEntity, pokemonIndex: Int, PartySelectPokemonDTO, moveIndex: Int, MoveSelectDTO) -> Unit
|
||||
)
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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.callback
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonPropertyExtractor
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyCallbackPacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import java.util.UUID
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.text.Text
|
||||
|
||||
/**
|
||||
* Used for opening party Pokémon selection screens for players and handling their choice. Currently
|
||||
* only supports up to 6 Pokémon to select from.
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since July 1st, 2023
|
||||
*/
|
||||
object PartySelectCallbacks {
|
||||
val callbacks = mutableMapOf<UUID, PartySelectCallback>()
|
||||
|
||||
@JvmOverloads
|
||||
fun create(
|
||||
player: ServerPlayerEntity,
|
||||
title: Text = lang("ui.party"),
|
||||
pokemon: List<PartySelectPokemonDTO>,
|
||||
cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
handler: (ServerPlayerEntity, index: Int) -> Unit
|
||||
) {
|
||||
val callback = PartySelectCallback(
|
||||
shownPokemon = pokemon,
|
||||
cancel = cancel,
|
||||
handler = handler
|
||||
)
|
||||
|
||||
callbacks[player.uuid] = callback
|
||||
|
||||
player.sendPacket(
|
||||
OpenPartyCallbackPacket(
|
||||
uuid = callback.uuid,
|
||||
title = title.copy(),
|
||||
pokemon = pokemon
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun createBattleSelect(
|
||||
player: ServerPlayerEntity,
|
||||
title: Text = lang("ui.party"),
|
||||
pokemon: List<BattlePokemon>,
|
||||
canSelect: (BattlePokemon) -> Boolean,
|
||||
cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
handler: (BattlePokemon) -> Unit
|
||||
) = create(
|
||||
player = player,
|
||||
title = title,
|
||||
cancel = cancel,
|
||||
pokemon = pokemon.map { pk -> PartySelectPokemonDTO(pk.effectedPokemon).also { it.enabled = canSelect(pk) } }
|
||||
) { _, index -> handler(pokemon[index]) }
|
||||
|
||||
@JvmOverloads
|
||||
fun createFromPokemon(
|
||||
player: ServerPlayerEntity,
|
||||
title: Text = lang("ui.party"),
|
||||
pokemon: List<Pokemon>,
|
||||
canSelect: (Pokemon) -> Boolean,
|
||||
cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
handler: (Pokemon) -> Unit
|
||||
) = create(
|
||||
player = player,
|
||||
title = title,
|
||||
cancel = cancel,
|
||||
pokemon = pokemon.map { pk -> PartySelectPokemonDTO(pk).also { it.enabled = canSelect(pk) } }
|
||||
) { _, index -> handler(pokemon[index]) }
|
||||
|
||||
fun handleCancelled(player: ServerPlayerEntity, uuid: UUID) {
|
||||
val callback = callbacks[player.uuid] ?: return
|
||||
if (callback.uuid != uuid) {
|
||||
return
|
||||
}
|
||||
callbacks.remove(player.uuid)
|
||||
callback.cancel(player)
|
||||
}
|
||||
|
||||
fun handleCallback(player: ServerPlayerEntity, uuid: UUID, index: Int) {
|
||||
val callback = callbacks[player.uuid] ?: return
|
||||
callbacks.remove(player.uuid)
|
||||
if (callback.uuid != uuid) {
|
||||
Cobblemon.LOGGER.warn("A party select callback ran but with a mismatching UUID from ${player.gameProfile.name}. Hacking attempts?")
|
||||
} else if (index >= callback.shownPokemon.size) {
|
||||
Cobblemon.LOGGER.warn("${player.gameProfile.name} used party select callback with an out of bounds index. Hacking attempts? Tried $index, Pokémon list size was ${callback.shownPokemon.size}")
|
||||
} else if (!callback.shownPokemon[index].enabled) {
|
||||
Cobblemon.LOGGER.warn("${player.gameProfile.name} used party select callback with a Pokémon that is not enabled. Hacking attempts?")
|
||||
} else {
|
||||
callback.handler(player, index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PartySelectCallback(
|
||||
val uuid: UUID = UUID.randomUUID(),
|
||||
val shownPokemon: List<PartySelectPokemonDTO>,
|
||||
val cancel: (ServerPlayerEntity) -> Unit = {},
|
||||
val handler: (ServerPlayerEntity, index: Int) -> Unit
|
||||
)
|
||||
|
||||
open class PartySelectPokemonDTO(
|
||||
val pokemonProperties: PokemonProperties,
|
||||
val aspects: Set<String>,
|
||||
val heldItem: ItemStack = ItemStack.EMPTY,
|
||||
var currentHealth: Int,
|
||||
var maxHealth: Int,
|
||||
var enabled: Boolean
|
||||
) {
|
||||
@JvmOverloads
|
||||
constructor(pokemon: Pokemon, enabled: Boolean = true): this(
|
||||
pokemonProperties = pokemon.createPokemonProperties(
|
||||
PokemonPropertyExtractor.SPECIES,
|
||||
PokemonPropertyExtractor.LEVEL,
|
||||
PokemonPropertyExtractor.NICKNAME,
|
||||
PokemonPropertyExtractor.POKEBALL,
|
||||
PokemonPropertyExtractor.STATUS,
|
||||
),
|
||||
aspects = pokemon.aspects,
|
||||
heldItem = pokemon.heldItemNoCopy(),
|
||||
currentHealth = pokemon.currentHealth,
|
||||
maxHealth = pokemon.hp,
|
||||
enabled = enabled
|
||||
)
|
||||
|
||||
constructor(buffer: PacketByteBuf): this(
|
||||
pokemonProperties = PokemonProperties().loadFromNBT(buffer.readNbt() as NbtCompound),
|
||||
aspects = buffer.readList { it.readString() }.toSet(),
|
||||
heldItem = buffer.readItemStack(),
|
||||
currentHealth = buffer.readInt(),
|
||||
maxHealth = buffer.readInt(),
|
||||
enabled = buffer.readBoolean()
|
||||
)
|
||||
|
||||
fun writeToBuffer(buffer: PacketByteBuf) {
|
||||
buffer.writeNbt(pokemonProperties.saveToNBT())
|
||||
buffer.writeCollection(aspects) { _, aspect -> buffer.writeString(aspect) }
|
||||
buffer.writeItemStack(heldItem)
|
||||
buffer.writeInt(currentHealth)
|
||||
buffer.writeInt(maxHealth)
|
||||
buffer.writeBoolean(enabled)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.conditional
|
||||
|
||||
import net.minecraft.util.registry.Registry
|
||||
import net.minecraft.registry.Registry
|
||||
|
||||
/**
|
||||
* A condition which applies to an entry in some [Registry].
|
||||
|
||||
+1
-1
@@ -9,8 +9,8 @@
|
||||
package com.cobblemon.mod.common.api.conditional
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.registry.Registry
|
||||
|
||||
/**
|
||||
* A condition for some registry type which asserts that the entry must have the given [Identifier].
|
||||
|
||||
+8
-8
@@ -9,10 +9,10 @@
|
||||
package com.cobblemon.mod.common.api.conditional
|
||||
|
||||
import com.google.gson.JsonElement
|
||||
import net.minecraft.tag.TagKey
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.tag.TagKey
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.registry.Registry
|
||||
import net.minecraft.util.registry.RegistryKey
|
||||
|
||||
/**
|
||||
* A condition for some registry type that asserts that the entry must be inside the given [TagKey]. This is presented
|
||||
@@ -40,11 +40,11 @@ open class RegistryLikeTagCondition<T>(val tag: TagKey<T>) : RegistryLikeConditi
|
||||
}
|
||||
|
||||
override fun fits(t: T, registry: Registry<T>): Boolean {
|
||||
val registryHasTag = registry.containsTag(tag)
|
||||
if (!registryHasTag) {
|
||||
// LOGGER.warn("No tag in registry: ${tag.id}")
|
||||
return false
|
||||
}
|
||||
// val registryHasTag = registry.containsTag(tag)
|
||||
// if (!registryHasTag) {
|
||||
//// LOGGER.warn("No tag in registry: ${tag.id}")
|
||||
// return false
|
||||
// }
|
||||
|
||||
return registry.getKey(t)
|
||||
.flatMap(registry::getEntry)
|
||||
|
||||
-1
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.api.data
|
||||
import com.cobblemon.mod.common.api.codec.CodecMapped
|
||||
import com.cobblemon.mod.common.api.codec.MappedCodec
|
||||
import com.mojang.serialization.Codec
|
||||
import java.lang.IllegalArgumentException
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,13 +8,9 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.data
|
||||
|
||||
import com.cobblemon.mod.common.util.endsWith
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.ExecutionException
|
||||
import kotlin.io.path.pathString
|
||||
import net.minecraft.resource.ResourceManager
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
@@ -46,20 +42,7 @@ interface JsonDataRegistry<T> : DataRegistry {
|
||||
val resourcePath: String
|
||||
|
||||
override fun reload(manager: ResourceManager) {
|
||||
val data = hashMapOf<Identifier, T>()
|
||||
manager.findResources(this.resourcePath) { path -> path.endsWith(JSON_EXTENSION) }.forEach { (identifier, resource) ->
|
||||
resource.inputStream.use { stream ->
|
||||
stream.bufferedReader().use { reader ->
|
||||
val resolvedIdentifier = Identifier(identifier.namespace, File(identifier.path).nameWithoutExtension)
|
||||
try {
|
||||
data[resolvedIdentifier] = this.gson.fromJson(reader, this.typeToken.type)
|
||||
} catch (exception: Exception) {
|
||||
throw ExecutionException("Error loading JSON for data: $identifier", exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.reload(data)
|
||||
this.reload(Cobblemon.implementation.reloadJsonRegistry(this, manager))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +53,6 @@ interface JsonDataRegistry<T> : DataRegistry {
|
||||
fun reload(data: Map<Identifier, T>)
|
||||
|
||||
companion object {
|
||||
private const val JSON_EXTENSION = ".json"
|
||||
const val JSON_EXTENSION = ".json"
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,11 @@ package com.cobblemon.mod.common.api.drop
|
||||
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.LOOT_DROPPED
|
||||
import com.cobblemon.mod.common.api.events.drops.LootDroppedEvent
|
||||
import kotlin.random.Random
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* A table of drops that can produce a list of [DropEntry]. You can produce a drop list from [getDrops] to
|
||||
|
||||
@@ -19,11 +19,11 @@ import net.minecraft.entity.ItemEntity
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import net.minecraft.util.registry.Registry
|
||||
|
||||
/**
|
||||
* A drop that is an actual item.
|
||||
@@ -41,7 +41,7 @@ class ItemDropEntry : DropEntry {
|
||||
val nbt: NbtCompound? = null
|
||||
|
||||
override fun drop(entity: LivingEntity?, world: ServerWorld, pos: Vec3d, player: ServerPlayerEntity?) {
|
||||
val item = world.registryManager.get(Registry.ITEM_KEY).get(item) ?: return LOGGER.error("Unable to load drop item: $item")
|
||||
val item = world.registryManager.get(RegistryKeys.ITEM).get(item) ?: return LOGGER.error("Unable to load drop item: $item")
|
||||
val stack = ItemStack(item, quantityRange?.random() ?: quantity)
|
||||
val inLava = world.getBlockState(pos.toBlockPos()).block == Blocks.LAVA
|
||||
val dropMethod = (dropMethod ?: Cobblemon.config.defaultDropItemMethod).let {
|
||||
|
||||
@@ -8,53 +8,48 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.events
|
||||
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleFaintedEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleFledEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleStartedPostEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleStartedPreEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleVictoryEvent
|
||||
import com.cobblemon.mod.common.api.events.berry.BerryHarvestEvent
|
||||
import com.cobblemon.mod.common.api.events.berry.BerryMutationOfferEvent
|
||||
import com.cobblemon.mod.common.api.events.berry.BerryMutationResultEvent
|
||||
import com.cobblemon.mod.common.api.events.berry.BerryYieldCalculationEvent
|
||||
import com.cobblemon.mod.common.api.events.drops.LootDroppedEvent
|
||||
import com.cobblemon.mod.common.api.events.entity.EntityAttributeEvent
|
||||
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.SpawnEvent
|
||||
import com.cobblemon.mod.common.api.events.farming.ApricornHarvestEvent
|
||||
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent
|
||||
import com.cobblemon.mod.common.api.events.net.MessageBuiltEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.ExperienceGainedPostEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.ExperienceGainedPreEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.FriendshipUpdatedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.LevelUpEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.PokemonCapturedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.PokemonFaintedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.ShoulderMountEvent
|
||||
import com.cobblemon.mod.common.api.events.pokeball.PokeBallCaptureCalculatedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokeball.PokemonCatchRateEvent
|
||||
import com.cobblemon.mod.common.api.events.pokeball.ThrownPokeballHitEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.*
|
||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionAcceptedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionDisplayEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionTestedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.ExperienceCandyUseEvent
|
||||
import com.cobblemon.mod.common.api.events.starter.StarterChosenEvent
|
||||
import com.cobblemon.mod.common.api.events.storage.ReleasePokemonEvent
|
||||
import com.cobblemon.mod.common.api.events.world.BigRootPropagatedEvent
|
||||
import com.cobblemon.mod.common.api.reactive.CancelableObservable
|
||||
import com.cobblemon.mod.common.api.reactive.EventObservable
|
||||
import com.cobblemon.mod.common.api.reactive.Observable.Companion.filter
|
||||
import com.cobblemon.mod.common.api.reactive.Observable.Companion.map
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.util.asObservable
|
||||
import com.cobblemon.mod.common.util.asServerObservable
|
||||
import com.cobblemon.mod.common.util.asTickObservable
|
||||
import dev.architectury.event.EventResult
|
||||
import dev.architectury.event.events.common.EntityEvent
|
||||
import dev.architectury.event.events.common.EntityEvent.LivingDeath
|
||||
import dev.architectury.event.events.common.LifecycleEvent
|
||||
import dev.architectury.event.events.common.PlayerEvent
|
||||
import dev.architectury.event.events.common.PlayerEvent.PlayerJoin
|
||||
import dev.architectury.event.events.common.PlayerEvent.PlayerQuit
|
||||
import dev.architectury.event.events.common.TickEvent
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
|
||||
@Suppress("unused")
|
||||
object CobblemonEvents {
|
||||
@JvmField
|
||||
val MESSAGE_BUILT = EventObservable<MessageBuiltEvent<*>>()
|
||||
|
||||
@JvmField
|
||||
val DATA_SYNCHRONIZED = SimpleObservable<ServerPlayerEntity>()
|
||||
@JvmField
|
||||
val ENTITY_ATTRIBUTE = EventObservable<EntityAttributeEvent>()
|
||||
@JvmField
|
||||
val SHOULDER_MOUNT = CancelableObservable<ShoulderMountEvent>()
|
||||
@JvmField
|
||||
val FRIENDSHIP_UPDATED = EventObservable<FriendshipUpdatedEvent>()
|
||||
@@ -65,14 +60,42 @@ object CobblemonEvents {
|
||||
@JvmField
|
||||
val EVOLUTION_DISPLAY = EventObservable<EvolutionDisplayEvent>()
|
||||
@JvmField
|
||||
val EVOLUTION_TESTED = EventObservable<EvolutionTestedEvent>()
|
||||
@JvmField
|
||||
val EVOLUTION_COMPLETE = EventObservable<EvolutionCompleteEvent>()
|
||||
@JvmField
|
||||
val POKEMON_NICKNAMED = CancelableObservable<PokemonNicknamedEvent>()
|
||||
|
||||
@JvmField
|
||||
val THROWN_POKEBALL_HIT = CancelableObservable<ThrownPokeballHitEvent>()
|
||||
@JvmField
|
||||
val POKEMON_CATCH_RATE = EventObservable<PokemonCatchRateEvent>()
|
||||
@JvmField
|
||||
val POKE_BALL_CAPTURE_CALCULATED = EventObservable<PokeBallCaptureCalculatedEvent>()
|
||||
@JvmField
|
||||
val POKEMON_CAPTURED = EventObservable<PokemonCapturedEvent>()
|
||||
// @JvmField
|
||||
// val EGG_HATCH = EventObservable<HatchEggEvent>()
|
||||
@JvmField
|
||||
val BATTLE_STARTED_PRE = CancelableObservable<BattleStartedPreEvent>()
|
||||
@JvmField
|
||||
val BATTLE_STARTED_POST = EventObservable<BattleStartedPostEvent>()
|
||||
@JvmField
|
||||
val BATTLE_FLED = EventObservable<BattleFledEvent>()
|
||||
@JvmField
|
||||
val BATTLE_VICTORY = EventObservable<BattleVictoryEvent>()
|
||||
@JvmField
|
||||
val BATTLE_FAINTED = EventObservable<BattleFaintedEvent>()
|
||||
|
||||
@JvmField
|
||||
val POKEMON_SENT_PRE = CancelableObservable<PokemonSentPreEvent>()
|
||||
@JvmField
|
||||
val POKEMON_SENT_POST = EventObservable<PokemonSentPostEvent>()
|
||||
@JvmField
|
||||
val POKEMON_RECALLED = EventObservable<PokemonRecalledEvent>()
|
||||
|
||||
@JvmField
|
||||
val TRADE_COMPLETED = EventObservable<TradeCompletedEvent>()
|
||||
|
||||
@JvmField
|
||||
val LEVEL_UP_EVENT = EventObservable<LevelUpEvent>()
|
||||
@@ -83,6 +106,18 @@ object CobblemonEvents {
|
||||
val POKEMON_ENTITY_LOAD = CancelableObservable<PokemonEntityLoadEvent>()
|
||||
@JvmField
|
||||
val POKEMON_ENTITY_SAVE_TO_WORLD = CancelableObservable<PokemonEntitySaveToWorldEvent>()
|
||||
@JvmField
|
||||
val ENTITY_SPAWN = CancelableObservable<SpawnEvent<*>>()
|
||||
|
||||
@JvmField
|
||||
val POKEMON_ENTITY_SPAWN = ENTITY_SPAWN
|
||||
.pipe(
|
||||
filter { it.entity is PokemonEntity },
|
||||
map {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
it as SpawnEvent<PokemonEntity>
|
||||
}
|
||||
)
|
||||
|
||||
@JvmField
|
||||
val EXPERIENCE_GAINED_EVENT_PRE = CancelableObservable<ExperienceGainedPreEvent>()
|
||||
@@ -105,29 +140,17 @@ object CobblemonEvents {
|
||||
|
||||
@JvmField
|
||||
val APRICORN_HARVESTED = EventObservable<ApricornHarvestEvent>()
|
||||
// Berries
|
||||
@JvmField
|
||||
val BERRY_HARVEST = EventObservable<BerryHarvestEvent>()
|
||||
@JvmField
|
||||
val BERRY_MUTATION_OFFER = EventObservable<BerryMutationOfferEvent>()
|
||||
@JvmField
|
||||
val BERRY_MUTATION_RESULT = EventObservable<BerryMutationResultEvent>()
|
||||
@JvmField
|
||||
val BERRY_YIELD = EventObservable<BerryYieldCalculationEvent>()
|
||||
@JvmField
|
||||
val LEFTOVERS_CREATED = CancelableObservable<LeftoversCreatedEvent>()
|
||||
|
||||
@JvmField
|
||||
val SERVER_STARTING = LifecycleEvent.SERVER_STARTING.asServerObservable()
|
||||
@JvmField
|
||||
val SERVER_STOPPING = LifecycleEvent.SERVER_STOPPING.asServerObservable()
|
||||
|
||||
@JvmField
|
||||
val SERVER_STARTED = LifecycleEvent.SERVER_STARTED.asServerObservable()
|
||||
@JvmField
|
||||
val SERVER_STOPPED = LifecycleEvent.SERVER_STOPPED.asServerObservable()
|
||||
|
||||
@JvmField
|
||||
val TICK_PRE = TickEvent.SERVER_PRE.asTickObservable()
|
||||
@JvmField
|
||||
val TICK_POST = TickEvent.SERVER_POST.asTickObservable()
|
||||
|
||||
@JvmField
|
||||
val PLAYER_JOIN = PlayerEvent.PLAYER_JOIN.asObservable<PlayerJoin, ServerPlayerEntity> { obs -> PlayerJoin { obs.emit(it) } }
|
||||
@JvmField
|
||||
val PLAYER_QUIT = PlayerEvent.PLAYER_QUIT.asObservable<PlayerQuit, ServerPlayerEntity> { obs -> PlayerQuit { obs.emit(it) } }
|
||||
|
||||
@JvmField
|
||||
val LIVING_DEATH = EntityEvent.LIVING_DEATH.asObservable<LivingDeath, LivingEntity> { obs -> LivingDeath { entity, source -> obs.emit(entity); EventResult.pass() } }
|
||||
val BIG_ROOT_PROPAGATED = CancelableObservable<BigRootPropagatedEvent>()
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.battles
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
|
||||
/**
|
||||
* Interface for events involving the Showdown battle engine
|
||||
*
|
||||
* @author Segfault Guy
|
||||
* @since March 25th 2023
|
||||
*/
|
||||
interface BattleEvent {
|
||||
|
||||
/**
|
||||
* The [PokemonBattle] that is the subject of the event.
|
||||
*/
|
||||
val battle: PokemonBattle
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.battles
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.BattleContext
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
|
||||
/**
|
||||
* Event fired when a [BattlePokemon] faints. Exposes the [BattlePokemon] that fainted and the [BattleContext]
|
||||
* of how it fainted.
|
||||
*
|
||||
* @author Segfault Guy
|
||||
* @since April 6th, 2023
|
||||
*/
|
||||
data class BattleFaintedEvent (
|
||||
override val battle: PokemonBattle,
|
||||
val killed: BattlePokemon,
|
||||
val context: BattleContext
|
||||
) : BattleEvent
|
||||
@@ -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.battles
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
|
||||
|
||||
/**
|
||||
* Event fired when a [PokemonBattle] is fled by a [PlayerBattleActor].
|
||||
*
|
||||
* @author Segfault Guy
|
||||
* @since March 25th 2023
|
||||
*/
|
||||
data class BattleFledEvent (
|
||||
|
||||
override val battle: PokemonBattle,
|
||||
val player: PlayerBattleActor
|
||||
|
||||
) : BattleEvent
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.battles
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
import com.cobblemon.mod.common.api.events.Cancelable
|
||||
import com.cobblemon.mod.common.battles.BattleFormat
|
||||
|
||||
/**
|
||||
* Event fired before a [PokemonBattle] is started. Canceling this event prevents the battle from being
|
||||
* created and launched.
|
||||
*
|
||||
* @author Segfault Guy
|
||||
* @since March 26th 2023
|
||||
*/
|
||||
data class BattleStartedPreEvent (
|
||||
|
||||
val participants: Collection<BattleActor>,
|
||||
val format: BattleFormat,
|
||||
val isPvP: Boolean,
|
||||
val isPvN: Boolean,
|
||||
val isPvW: Boolean
|
||||
|
||||
) : Cancelable()
|
||||
|
||||
/**
|
||||
* Event fired after a [PokemonBattle] starts.
|
||||
*
|
||||
* @author Segfault Guy
|
||||
* @since March 26th 2023
|
||||
*/
|
||||
data class BattleStartedPostEvent (
|
||||
|
||||
override val battle: PokemonBattle
|
||||
|
||||
) : BattleEvent
|
||||
+5
-3
@@ -18,6 +18,8 @@ import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
* @since November 3rd, 2022
|
||||
*/
|
||||
data class BattleVictoryEvent (
|
||||
val battle: PokemonBattle,
|
||||
val winners : List<BattleActor>
|
||||
)
|
||||
override val battle: PokemonBattle,
|
||||
val winners : List<BattleActor>,
|
||||
val losers : List<BattleActor>,
|
||||
val wasWildCapture : Boolean
|
||||
) : BattleEvent
|
||||
@@ -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.berry
|
||||
|
||||
import com.cobblemon.mod.common.api.berry.Berry
|
||||
|
||||
/**
|
||||
* The base of all Berry related events.
|
||||
*
|
||||
* @author Licious
|
||||
* @since November 28th, 2022
|
||||
*/
|
||||
interface BerryEvent {
|
||||
|
||||
/**
|
||||
* The [Berry] related to the event trigger
|
||||
*/
|
||||
val berry: Berry
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user