forked from mirrors/cobblemon
Compare commits
770
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f298f7a157 | ||
|
|
7ac54d6d6a | ||
|
|
a9ed3750ad | ||
|
|
24fdae725e | ||
|
|
36169db388 | ||
|
|
1900999a74 | ||
|
|
ab16814cd2 | ||
|
|
9f622fcd74 | ||
|
|
956e2c43b8 | ||
|
|
130f87c9f7 | ||
|
|
22b4e8c75f | ||
|
|
c19a3ca444 | ||
|
|
a006eb5dcc | ||
|
|
ed419e7e53 | ||
|
|
bff2387b4d | ||
|
|
41544efeba | ||
|
|
e6e6c9f7f6 | ||
|
|
22d8e39db3 | ||
|
|
71fc844905 | ||
|
|
bfdf1e9e6c | ||
|
|
c3fccfde09 | ||
|
|
4bb8d43a6e | ||
|
|
fda4b67776 | ||
|
|
f1ee9d45de | ||
|
|
24910778d4 | ||
|
|
363c3e5f0a | ||
|
|
01f7d13e3f | ||
|
|
d85e30f3a6 | ||
|
|
e6f147bd94 | ||
|
|
c66de51e39 | ||
|
|
7d552735f3 | ||
|
|
94c42e7e2c | ||
|
|
ef4690d4fe | ||
|
|
433c0ff345 | ||
|
|
59d42fb328 | ||
|
|
17d6837e34 | ||
|
|
34b4337849 | ||
|
|
392e8663be | ||
|
|
578ff37705 | ||
|
|
77406f91a3 | ||
|
|
9bf526e93e | ||
|
|
29b763ef19 | ||
|
|
938b7a7a94 | ||
|
|
f920639e3f | ||
|
|
8d336fca3e | ||
|
|
ea499a935e | ||
|
|
1dbe5eb944 | ||
|
|
dba0bae810 | ||
|
|
8c04081af5 | ||
|
|
ff27676187 | ||
|
|
d7de4b2463 | ||
|
|
61b767158a | ||
|
|
f2f16cdc9e | ||
|
|
2aec4f972f | ||
|
|
bc8164cf17 | ||
|
|
a09cf1b93d | ||
|
|
b436c42cb1 | ||
|
|
79b83bc8d7 | ||
|
|
a6b5453b34 | ||
|
|
7fcb9e8b4d | ||
|
|
f3740abd39 | ||
|
|
e4decf50ea | ||
|
|
22d33ac5d8 | ||
|
|
f2392db3be | ||
|
|
9fed44328f | ||
|
|
26d0340fb5 | ||
|
|
21f2945dc4 | ||
|
|
16a5316a69 | ||
|
|
1fd5d0ff4b | ||
|
|
378a5ca401 | ||
|
|
d956ca2c3c | ||
|
|
14a079fae1 | ||
|
|
3e9331ec64 | ||
|
|
a7c43701c0 | ||
|
|
34aef306c1 | ||
|
|
b4e99204c8 | ||
|
|
8c09cebc59 | ||
|
|
b5bfe44196 | ||
|
|
38c5fcc23f | ||
|
|
9edfa279be | ||
|
|
2769d5560d | ||
|
|
ed7d2d5d2a | ||
|
|
d839a13b7e | ||
|
|
a23cd170b2 | ||
|
|
3dec294728 | ||
|
|
c67cf2e05d | ||
|
|
3b96beef36 | ||
|
|
dcbac52fd7 | ||
|
|
64dd8336c6 | ||
|
|
2681cdc5ba | ||
|
|
8d265bd820 | ||
|
|
6b43e5d99d | ||
|
|
b430b8a1b4 | ||
|
|
329810407a | ||
|
|
6ca04bb064 | ||
|
|
ebf0144222 | ||
|
|
a71cfaadc8 | ||
|
|
31195dacdb | ||
|
|
4074aa50ce | ||
|
|
107ec7634d | ||
|
|
ed85de34b3 | ||
|
|
6dbf1288a0 | ||
|
|
aee915dc91 | ||
|
|
a1974fbe74 | ||
|
|
145481530d | ||
|
|
b5694b4e13 | ||
|
|
9df4669865 | ||
|
|
92543f9aed | ||
|
|
5d5cb3a240 | ||
|
|
452117c781 | ||
|
|
bc267ec72b | ||
|
|
33a2a0a8e0 | ||
|
|
dac1b3cbf0 | ||
|
|
6d89b737a7 | ||
|
|
53e540472a | ||
|
|
e2804dc83f | ||
|
|
46752a3911 | ||
|
|
82e82cb28e | ||
|
|
052fee56a1 | ||
|
|
15970f2ab0 | ||
|
|
3874867b74 | ||
|
|
ed6485f1d3 | ||
|
|
c7b1036bdf | ||
|
|
8730ff3a3e | ||
|
|
c8bd7c8604 | ||
|
|
b049a39680 | ||
|
|
6503b0806a | ||
|
|
ef0e785855 | ||
|
|
cccd30a284 | ||
|
|
be35e937d9 | ||
|
|
5a73456202 | ||
|
|
089e6c15da | ||
|
|
4f63c40096 | ||
|
|
218d33d78d | ||
|
|
dae5445c3a | ||
|
|
57f9d5b6dc | ||
|
|
fdfa10f5fe | ||
|
|
e12a1df252 | ||
|
|
69e74be5e5 | ||
|
|
8c9ee22547 | ||
|
|
c8074dd825 | ||
|
|
bda5e2ade2 | ||
|
|
0c5118b840 | ||
|
|
0d0eaf2465 | ||
|
|
4eb90400aa | ||
|
|
7387612f0e | ||
|
|
5188318f20 | ||
|
|
627ee5e9b2 | ||
|
|
7f3bd8bec2 | ||
|
|
db70a0f816 | ||
|
|
ab9a66c556 | ||
|
|
f5e1dfe080 | ||
|
|
175aa93284 | ||
|
|
b7926a70ab | ||
|
|
28f2caff58 | ||
|
|
128451785f | ||
|
|
0171ed9747 | ||
|
|
1fb09e27fc | ||
|
|
30a3d6ed83 | ||
|
|
4aa4c229fa | ||
|
|
18cecc68dd | ||
|
|
5036ed0db1 | ||
|
|
3b3150fc72 | ||
|
|
b9fb970ec4 | ||
|
|
761b306590 | ||
|
|
1e7dfce918 | ||
|
|
a453199eae | ||
|
|
f5267c832f | ||
|
|
7f6e0c0377 | ||
|
|
420d42b36d | ||
|
|
a45028d83b | ||
|
|
76ab7e998b | ||
|
|
cbbfa974aa | ||
|
|
9dc6649eb7 | ||
|
|
97ef0dda0a | ||
|
|
76ad22b53d | ||
|
|
a2ddcaebf8 | ||
|
|
71334dc889 | ||
|
|
4d8c4b1d7b | ||
|
|
0701380a36 | ||
|
|
2b03e5660e | ||
|
|
b44a53efce | ||
|
|
5678776938 | ||
|
|
f3985d8250 | ||
|
|
b497c603ca | ||
|
|
b9807773ee | ||
|
|
aba02d7b53 | ||
|
|
0eef30af4a | ||
|
|
3a064c7269 | ||
|
|
1cece70687 | ||
|
|
c2d85df3e0 | ||
|
|
a7c0242575 | ||
|
|
97a7554e79 | ||
|
|
77108ae687 | ||
|
|
413271546f | ||
|
|
75e3c4be7a | ||
|
|
7891347d90 | ||
|
|
0a9b1c5c97 | ||
|
|
89d86aa6e3 | ||
|
|
fd45dacad2 | ||
|
|
a336f0968a | ||
|
|
df852ace9b | ||
|
|
9d6ae6952c | ||
|
|
19c6f98ea4 | ||
|
|
6fc725b6ff | ||
|
|
dbc1674416 | ||
|
|
3e8c0ed14e | ||
|
|
5f8ee45f1e | ||
|
|
5f3e1fb395 | ||
|
|
4befb0a16a | ||
|
|
aab55966a8 | ||
|
|
746c29c6f6 | ||
|
|
0c31f14b15 | ||
|
|
01efc8d9e0 | ||
|
|
e565426291 | ||
|
|
6f115e44e3 | ||
|
|
dd161c2d53 | ||
|
|
50500ab204 | ||
|
|
169c406f03 | ||
|
|
985691958f | ||
|
|
d972b2f998 | ||
|
|
5dc03a71f6 | ||
|
|
6535dd950a | ||
|
|
840d7f50ee | ||
|
|
1d7da21e69 | ||
|
|
c33adf3a8b | ||
|
|
c39eeb69f4 | ||
|
|
32d6811884 | ||
|
|
fa7eb0d98c | ||
|
|
242fa3fed8 | ||
|
|
9364992979 | ||
|
|
488f9b995a | ||
|
|
05f58f86c2 | ||
|
|
3fa3f06a02 | ||
|
|
0a80269670 | ||
|
|
5e2373c656 | ||
|
|
60b95b6fa5 | ||
|
|
77d7bb0fe4 | ||
|
|
bf78e68831 | ||
|
|
49a6dd826a | ||
|
|
b0d80d6c96 | ||
|
|
ca1f008319 | ||
|
|
d22d7cc5b4 | ||
|
|
1ceba8973f | ||
|
|
558daea446 | ||
|
|
6f5a298a5c | ||
|
|
e016d48584 | ||
|
|
9540a4b3eb | ||
|
|
e7234daff6 | ||
|
|
7fbc2b5143 | ||
|
|
9d50dae3d1 | ||
|
|
655a467193 | ||
|
|
cbc6c56c9e | ||
|
|
360de79482 | ||
|
|
8e7ceae7e1 | ||
|
|
92221e0e98 | ||
|
|
27285e3e7f | ||
|
|
04612d58f3 | ||
|
|
ffd5dbb717 | ||
|
|
d7242d2895 | ||
|
|
51c2a418ce | ||
|
|
882a5921e8 | ||
|
|
3a05bd5e2e | ||
|
|
9b58e229d6 | ||
|
|
d357c2cbcb | ||
|
|
5621326c43 | ||
|
|
9fd2b3f1d6 | ||
|
|
439c9647ca | ||
|
|
a89d428699 | ||
|
|
91eda647fa | ||
|
|
c0da612281 | ||
|
|
7dc76fdeb3 | ||
|
|
eb952319e0 | ||
|
|
7e11497c64 | ||
|
|
81978f025b | ||
|
|
8dc3eaafc7 | ||
|
|
c0af1abf9f | ||
|
|
b2d56c339c | ||
|
|
bc49537e16 | ||
|
|
c4c59e6aa5 | ||
|
|
de3cac46fb | ||
|
|
995ad49336 | ||
|
|
1abe38f97b | ||
|
|
ff7fa49baa | ||
|
|
92b2612350 | ||
|
|
ba17f0d35f | ||
|
|
5a628b4c39 | ||
|
|
0b46516ed1 | ||
|
|
715b5d1a08 | ||
|
|
44ca37207f | ||
|
|
cd363e4ef7 | ||
|
|
9d234fa556 | ||
|
|
47e49993ad | ||
|
|
7afdbd2d4b | ||
|
|
38e699aa44 | ||
|
|
2b26e47876 | ||
|
|
2f07f33a71 | ||
|
|
eaec3612aa | ||
|
|
db0c2a0cc2 | ||
|
|
c431cf7b1e | ||
|
|
a5dd0eb924 | ||
|
|
466d91fcbf | ||
|
|
e1a3077780 | ||
|
|
5936ced1d7 | ||
|
|
3d6967d3c7 | ||
|
|
449a8cdb53 | ||
|
|
c91d4a9515 | ||
|
|
793f059f3c | ||
|
|
7200e87886 | ||
|
|
a1dc5c8340 | ||
|
|
4787c1d35b | ||
|
|
2345e7efcc | ||
|
|
d32ed6309c | ||
|
|
72e9481946 | ||
|
|
f3ba7ef121 | ||
|
|
e9aca93f70 | ||
|
|
6f8e3bca29 | ||
|
|
49349848b8 | ||
|
|
bfe1afda4b | ||
|
|
bd54020c9c | ||
|
|
605d44f2c2 | ||
|
|
5c42b441fd | ||
|
|
2211232652 | ||
|
|
4ef8c40a83 | ||
|
|
99ca941c73 | ||
|
|
e5b977ff1a | ||
|
|
0e381ac098 | ||
|
|
ace08a5673 | ||
|
|
de00622235 | ||
|
|
e652b5773d | ||
|
|
ae1f6393b7 | ||
|
|
ddb0ad4dda | ||
|
|
83bc1292ea | ||
|
|
39075b843e | ||
|
|
7db59cc3bd | ||
|
|
98394333da | ||
|
|
5e5f35b306 | ||
|
|
65ef2076eb | ||
|
|
e8f6bbd742 | ||
|
|
653b9be4a3 | ||
|
|
5256bf1267 | ||
|
|
d2a5dfcdc0 | ||
|
|
124eb876de | ||
|
|
a3460a4b8f | ||
|
|
fd74f157a8 | ||
|
|
7b1f50b183 | ||
|
|
2c9705e230 | ||
|
|
b78d05611d | ||
|
|
4574e9ae65 | ||
|
|
4508f47c93 | ||
|
|
683d62f9e0 | ||
|
|
217b1cc561 | ||
|
|
b72f90551e | ||
|
|
30b146a59d | ||
|
|
1e4afe36be | ||
|
|
a76ec37e63 | ||
|
|
c3f397b508 | ||
|
|
d4f5b1c0ca | ||
|
|
ae4680f546 | ||
|
|
b0c14c686c | ||
|
|
4a59c02340 | ||
|
|
9754515ec6 | ||
|
|
f810cdb090 | ||
|
|
af8cfa8b3d | ||
|
|
c9de2b2bf1 | ||
|
|
f3bd112f3e | ||
|
|
2d3bd8c2af | ||
|
|
8a9a59fd3c | ||
|
|
c738f55078 | ||
|
|
885cde045a | ||
|
|
2e39aa7f7f | ||
|
|
c65aaf03eb | ||
|
|
d3e18cb8c0 | ||
|
|
8de519ad3f | ||
|
|
d06c735585 | ||
|
|
c820a01db0 | ||
|
|
bfcaa4bda4 | ||
|
|
7370841e62 | ||
|
|
3c347214a8 | ||
|
|
0d6f6221cb | ||
|
|
77e6070e78 | ||
|
|
46c5849842 | ||
|
|
72bca5b6fc | ||
|
|
94d12f69fe | ||
|
|
1f68bab455 | ||
|
|
390d214976 | ||
|
|
5b40c8bab2 | ||
|
|
7eee9117c0 | ||
|
|
49e1b6ac00 | ||
|
|
d356ad3a3d | ||
|
|
0f38eb5bca | ||
|
|
1d3e54a54a | ||
|
|
4792b14051 | ||
|
|
66d87d68de | ||
|
|
5d60825c7d | ||
|
|
4ca40b59d9 | ||
|
|
a9b6e02a71 | ||
|
|
055eaab819 | ||
|
|
1f467a72a6 | ||
|
|
14ee434e13 | ||
|
|
d317a4488e | ||
|
|
3b78d68ed0 | ||
|
|
2d234931d7 | ||
|
|
ff01cc1551 | ||
|
|
4ae49291ad | ||
|
|
268f219754 | ||
|
|
6d819a0507 | ||
|
|
41e0c1bf2d | ||
|
|
db8b5ab631 | ||
|
|
d7c531d51f | ||
|
|
03f690e450 | ||
|
|
6ffc6b98e5 | ||
|
|
a99865e0c6 | ||
|
|
2c7d5a937f | ||
|
|
37c9c7970a | ||
|
|
a9c1c318dc | ||
|
|
4e74e85976 | ||
|
|
30f9e506b2 | ||
|
|
72b17e3c04 | ||
|
|
ca00521ba8 | ||
|
|
3f289b1deb | ||
|
|
cbd86be78c | ||
|
|
c62e1bcc28 | ||
|
|
6c91bc273e | ||
|
|
76d9fae579 | ||
|
|
76de1f6076 | ||
|
|
b1971f90be | ||
|
|
e702d0088d | ||
|
|
332a0a6e1b | ||
|
|
58bf92eeab | ||
|
|
7787d749c9 | ||
|
|
b075145090 | ||
|
|
afe7fff061 | ||
|
|
6f3abd0986 | ||
|
|
2da2c41011 | ||
|
|
252a223e89 | ||
|
|
dcf8b22592 | ||
|
|
5c1dbfff7b | ||
|
|
e8c9ae1a64 | ||
|
|
b1f9796e21 | ||
|
|
02847c428d | ||
|
|
7552038d48 | ||
|
|
84d6a8b110 | ||
|
|
e9be40848a | ||
|
|
d8dd485d3f | ||
|
|
b27924bd4a | ||
|
|
be61d2d2ad | ||
|
|
647989944e | ||
|
|
e80facfd3b | ||
|
|
43dbc87a1e | ||
|
|
4b4ef77d4e | ||
|
|
cb431c0b5f | ||
|
|
f56960d15b | ||
|
|
41017342c9 | ||
|
|
9b218bb4f7 | ||
|
|
fbe37cf81a | ||
|
|
6ec091dfa5 | ||
|
|
e6a9c8e32e | ||
|
|
ba034be048 | ||
|
|
157fe0435b | ||
|
|
1123d10b05 | ||
|
|
8f7fa9a324 | ||
|
|
7cf60159c4 | ||
|
|
c5add81e90 | ||
|
|
5a6ada47b9 | ||
|
|
f4336c9227 | ||
|
|
123562c672 | ||
|
|
493101850e | ||
|
|
6bba26a848 | ||
|
|
46474f67b8 | ||
|
|
14f0a4643c | ||
|
|
037e667411 | ||
|
|
0a25c286cd | ||
|
|
5561270a60 | ||
|
|
1d499bbce8 | ||
|
|
6e8bf6999c | ||
|
|
5da8977ec0 | ||
|
|
fcb32062d3 | ||
|
|
9e74c7fd18 | ||
|
|
d3d73cc30d | ||
|
|
d9f76677c0 | ||
|
|
151999c2cd | ||
|
|
0460f17c1f | ||
|
|
2c69513d2b | ||
|
|
617efe6a58 | ||
|
|
2734f1d00c | ||
|
|
e66069b270 | ||
|
|
a661575451 | ||
|
|
a23017cd1f | ||
|
|
0df19ce18a | ||
|
|
5a751546ec | ||
|
|
ee9e1cabc1 | ||
|
|
d78b46155f | ||
|
|
1afd61d517 | ||
|
|
97a5083ff5 | ||
|
|
0d31e74790 | ||
|
|
02214196f4 | ||
|
|
aae268cfc5 | ||
|
|
20f37d8799 | ||
|
|
0b825bcda3 | ||
|
|
aba3bd22c7 | ||
|
|
b1fc33f5a1 | ||
|
|
f2033f5e33 | ||
|
|
6c600b7bdb | ||
|
|
e93bfb7f0f | ||
|
|
8976909742 | ||
|
|
30a9c2f53e | ||
|
|
ea60790865 | ||
|
|
f906fac8f3 | ||
|
|
05b324a3cb | ||
|
|
8ce1c7ccf5 | ||
|
|
a37f93241f | ||
|
|
6689663ca9 | ||
|
|
959b81a58f | ||
|
|
62e607b44e | ||
|
|
407bb6b977 | ||
|
|
a9efd327b8 | ||
|
|
64cb4d2ff8 | ||
|
|
54786fa82e | ||
|
|
ecab1b7825 | ||
|
|
75d7106f46 | ||
|
|
6f82c09afa | ||
|
|
778e5e219c | ||
|
|
f4682e0bd2 | ||
|
|
906d487ffc | ||
|
|
817b801bf7 | ||
|
|
e401b11ab9 | ||
|
|
165f70e01d | ||
|
|
fddfbfb4ed | ||
|
|
03e229c511 | ||
|
|
0b08372407 | ||
|
|
6d26b5de20 | ||
|
|
ef179410f9 | ||
|
|
194f6e019a | ||
|
|
1f933827b9 | ||
|
|
28765bb2ce | ||
|
|
136391db04 | ||
|
|
0cc39e71fc | ||
|
|
d65cc08793 | ||
|
|
a1729a0266 | ||
|
|
8505634df3 | ||
|
|
02047c1ec0 | ||
|
|
068fa4b2ef | ||
|
|
bfd266a40e | ||
|
|
6367d4e2aa | ||
|
|
f8a680f381 | ||
|
|
81750e6eb9 | ||
|
|
818cf682bf | ||
|
|
3112a0650f | ||
|
|
747ef94f04 | ||
|
|
dbacada48c | ||
|
|
26db8a40cc | ||
|
|
6e5feda00e | ||
|
|
f04330074b | ||
|
|
80d733d329 | ||
|
|
0099dcf5c5 | ||
|
|
0a30551b7d | ||
|
|
e4ee0227fd | ||
|
|
4ec7168499 | ||
|
|
650647e94b | ||
|
|
a5371f4b5d | ||
|
|
d47e7fb3c4 | ||
|
|
ef983e17fe | ||
|
|
d78975be6e | ||
|
|
19a264870c | ||
|
|
ee1753de67 | ||
|
|
742354b2cb | ||
|
|
e2f6aaa4de | ||
|
|
abc2911059 | ||
|
|
d76caf7093 | ||
|
|
bf859f8435 | ||
|
|
592b4276c8 | ||
|
|
b31c10cc52 | ||
|
|
89e3c7d8b0 | ||
|
|
167b09f24f | ||
|
|
39165266d5 | ||
|
|
7405f2de75 | ||
|
|
762fe87454 | ||
|
|
ebbc81b605 | ||
|
|
12d41aada1 | ||
|
|
61fe9c23ce | ||
|
|
945c9c60a9 | ||
|
|
8413b0392e | ||
|
|
868edcd392 | ||
|
|
a3b2f9b6fc | ||
|
|
12b444bb41 | ||
|
|
0e814fd567 | ||
|
|
7b083aa038 | ||
|
|
4e0a4c84b5 | ||
|
|
2d9b47e645 | ||
|
|
39a2182736 | ||
|
|
5a996abbf3 | ||
|
|
a20def5161 | ||
|
|
030f370290 | ||
|
|
f3ade3cb82 | ||
|
|
315cb6a1ac | ||
|
|
60615d32f5 | ||
|
|
1d27d9cf5b | ||
|
|
2ba760d0f9 | ||
|
|
c31ec3b418 | ||
|
|
d0afab9604 | ||
|
|
4e9f8fe1c0 | ||
|
|
803f93aa73 | ||
|
|
853940d009 | ||
|
|
6ddb746d49 | ||
|
|
2b86b15132 | ||
|
|
5f0f5d0aa5 | ||
|
|
136aab872a | ||
|
|
a1d4702af0 | ||
|
|
b2777c13b8 | ||
|
|
26cb473b9d | ||
|
|
907c639e28 | ||
|
|
80d2eafed7 | ||
|
|
519122e5be | ||
|
|
c211768d5c | ||
|
|
908f318eeb | ||
|
|
0143f93577 | ||
|
|
f8615aeb82 | ||
|
|
b113448a9c | ||
|
|
2930a11c75 | ||
|
|
982de7f5c7 | ||
|
|
bfdb5e9787 | ||
|
|
d5ea945c6b | ||
|
|
5a18d038a2 | ||
|
|
d0389d6c9c | ||
|
|
c9bc6e24fe | ||
|
|
8b4a8e9534 | ||
|
|
5adfd00509 | ||
|
|
4090e038ae | ||
|
|
f3ab282fd1 | ||
|
|
40b97d3c1e | ||
|
|
829b97270d | ||
|
|
61111c8038 | ||
|
|
1f4fbaa177 | ||
|
|
9e8ef7e875 | ||
|
|
190d90a966 | ||
|
|
5a07c82a5d | ||
|
|
9c2e56ee8b | ||
|
|
c83f194dc9 | ||
|
|
b9bcb66d2a | ||
|
|
b72050da1d | ||
|
|
82522ad6ab | ||
|
|
a73cdfbb4f | ||
|
|
d40e2e6103 | ||
|
|
96715770a7 | ||
|
|
770a2e52f6 | ||
|
|
48fa67c2e4 | ||
|
|
9a6217f755 | ||
|
|
f1f035b5f9 | ||
|
|
19aa53effc | ||
|
|
be7cb4583c | ||
|
|
887891f74d | ||
|
|
6629b27f33 | ||
|
|
73b06d2f99 | ||
|
|
d83cd34bf4 | ||
|
|
bee41a90f9 | ||
|
|
79afe9d812 | ||
|
|
9fe55c5692 | ||
|
|
feddce2575 | ||
|
|
4ddc5e3a93 | ||
|
|
f63f1764ab | ||
|
|
7c694e9733 | ||
|
|
21b6977387 | ||
|
|
408735399c | ||
|
|
f6c856d161 | ||
|
|
8173cf13a8 | ||
|
|
7d0becf1bd | ||
|
|
9b4a87ce68 | ||
|
|
464c4d349d | ||
|
|
a35d3131f8 | ||
|
|
9d99d3c331 | ||
|
|
b100516b24 | ||
|
|
8da5396443 | ||
|
|
5d2a727311 | ||
|
|
d7f03215e2 | ||
|
|
d366471e71 | ||
|
|
e5163f154a | ||
|
|
cfc497d8ed | ||
|
|
35f8ab0257 | ||
|
|
e890743c86 | ||
|
|
ffec6e307d | ||
|
|
7c35db7eaa | ||
|
|
9f0c2296bc | ||
|
|
6b0a06c64d | ||
|
|
160186931f | ||
|
|
22c4a14fbe | ||
|
|
241a82764b | ||
|
|
6e4d48bb07 | ||
|
|
7a383f419a | ||
|
|
933b99d349 | ||
|
|
72d78084f6 | ||
|
|
fcee4d2774 | ||
|
|
61c7f3bc13 | ||
|
|
3830637f3c | ||
|
|
45f8049521 | ||
|
|
823774bcfe | ||
|
|
920e5211c0 | ||
|
|
7da61e3d8d | ||
|
|
754b60b15c | ||
|
|
839454bfd6 | ||
|
|
3b6a0667d6 | ||
|
|
f298adaea8 | ||
|
|
641206b811 | ||
|
|
a07a9a75c0 | ||
|
|
d6fdb4c6da | ||
|
|
93a94b4900 | ||
|
|
40363c2ea1 | ||
|
|
6f15d65d90 | ||
|
|
02f9b21cff | ||
|
|
79cf154304 | ||
|
|
c5e036934a | ||
|
|
a650683d45 | ||
|
|
d9938a5cfd | ||
|
|
311dc3dc9c | ||
|
|
fc5d9615fc | ||
|
|
bda1f80ecc | ||
|
|
817796bf40 | ||
|
|
8a48eeab8b | ||
|
|
0061104c0d | ||
|
|
5110a1be17 | ||
|
|
4cbb998106 | ||
|
|
17de3f496c | ||
|
|
b54181e93a | ||
|
|
eaf7edcd94 | ||
|
|
cdf1631e2b | ||
|
|
841f49553e | ||
|
|
57d7d5a1b9 | ||
|
|
b1f2ab2ed7 | ||
|
|
f629d95844 | ||
|
|
30904fbdda | ||
|
|
9a3be6a85a | ||
|
|
88c91d9bdd | ||
|
|
5d2efe3e6b | ||
|
|
e160a42b83 | ||
|
|
d6354d3d94 | ||
|
|
4ddfdd828c | ||
|
|
06b70c6204 | ||
|
|
2dc9d11f79 | ||
|
|
fbb161c511 | ||
|
|
f84bc62d61 | ||
|
|
2e20554d1e | ||
|
|
bb9fcc64ed | ||
|
|
fa68aa44c5 | ||
|
|
2d908468ea | ||
|
|
c9ae148d86 | ||
|
|
f3de9840b5 | ||
|
|
64e3909cea | ||
|
|
735c4b910e | ||
|
|
26a9a1f9e1 | ||
|
|
832ab8db95 | ||
|
|
1d9029ef51 | ||
|
|
a875ba7536 | ||
|
|
93de4785b4 | ||
|
|
765f0e5494 | ||
|
|
4fc232ff31 | ||
|
|
a4d75e9f32 | ||
|
|
a86ae09dc9 | ||
|
|
a5fbafe64d | ||
|
|
1de93b4933 | ||
|
|
f8dfc7c6cc | ||
|
|
accbed9c2b | ||
|
|
8b0e615777 | ||
|
|
746f12c724 | ||
|
|
a11d306a1b | ||
|
|
40d140e84d | ||
|
|
ffdb4842ac | ||
|
|
6baf60d07c | ||
|
|
cb3b7784b0 | ||
|
|
ee4f3b1629 | ||
|
|
518a7daa0e |
+184
-41
@@ -1,52 +1,163 @@
|
||||
# Changelog
|
||||
## [1.6.1 (Release TBD)](#1-6-1)
|
||||
## [1.7.0 (Month xth, 2025)](#1-7-0)
|
||||
|
||||
### Fixes
|
||||
- Fixed Particles sometimes facing the wrong direction (looking at you, Swords Dance)
|
||||
- Fixed PCs always opening at box 2 instead of box 1.
|
||||
|
||||
### Developer
|
||||
- A finished battle now has winners and losers set inside of `PokemonBattle` instead of them always being empty.
|
||||
- Dialogues are correctly removed from memory when they are stopped.
|
||||
- Dialogues with variably-set initial pages now properly start timeout tracking.
|
||||
|
||||
## [1.6.1 (January 26th, 2025)](#1-6-1)
|
||||
|
||||
### Additions
|
||||
- Added crossover paintings from Close Combat: Premonition, Altar, Slumber, and Nomad.
|
||||
- Added Galarica Nuts, used for crafting Galarica Cuffs and Wreaths. Dropped from certain Pokémon. Take a wild guess which.
|
||||
- Added compatibility with Repurposed Structures. (Thank you, TelepathicGrunt!)
|
||||
- Added an evolution method for Karrablast to evolve into Escavalier in singleplayer.
|
||||
- Pokédexes can now be placed in Chiseled Bookshelves.
|
||||
- Added optional box argument to the /pc command.
|
||||
- Pokédex and Dialogue screens now close when the inventory keybind is pressed.
|
||||
- Added config setting `maxPokedexScanningDetectionRange` to control from what distance the player can scan Pokémon using the Pokédex.
|
||||
- Added the `is_standing_on_blocks(depth, blocks...)` MoLang function, which returns whether the specified entity is standing on a specific block or set of blocks. Example usage: `q.is_standing_on_blocks(2, minecraft:sand)`
|
||||
- Added config setting `hideUnimplementedPokemonInThePokedex` which hides unimplemented Pokémon from the Pokédex when set to true.
|
||||
- Added molang particle queries for getting distance to targeted entities.
|
||||
- Added debug renderer for poseable entity locators.
|
||||
- Added `baseScale` property to NPCs.
|
||||
- Added the player to `PokerodReelEvent`.
|
||||
- Pokédex and Dialogue API screens now close when the inventory keybind is pressed.
|
||||
- Added Galarica Nuts, used for crafting Galarica Cuffs and Wreaths. Dropped from certain Pokémon.
|
||||
- Added specific compatibility with Repurposed Structures. (Thank you, TelepathicGrunt!)
|
||||
- Added debug renderer for posable entity locators.
|
||||
- Added crossover paintings from Close Combat, Premonition, Altar, Slumber, and Nomad.
|
||||
- Added optional box argument to the /pc command
|
||||
|
||||
### Changes
|
||||
- Pokémon will now be dynamically revealed to the Pokédex as they're seen instead of revealing entire parties at the end of battle regardless.
|
||||
- Unseen wild Pokémon will update their name from '???' to their real name as soon as a battle starts to reflect the battle UI showing the actual species name.
|
||||
- Pokémon under the illusion effect will reveal their disguise to the Pokédex first and then the base Pokémon once the disguise is broken.
|
||||
- Added more support for a variety of Fabric/NeoForge Convention tags.
|
||||
- Reformatted some tags to be more consistent.
|
||||
- Edited some recipes to utilize tags instead of direct item ids, for greater mod compatibility.
|
||||
- Berries will drop if broken at age 0
|
||||
- Improved Fortune drops on Mint Seeds
|
||||
- New Slowpoke shiny texture.
|
||||
- Updated drops for many Pokémon.
|
||||
- Completely resynced Pokémon move and stat data based on later games. Learnsets have changed considerably to maximise available moves.
|
||||
- Cobblemon save data now saves .old files where applicable as a means to recover from file corruption due to crashes or similar abrupt stops
|
||||
|
||||
### Pokémon Added
|
||||
|
||||
#### Gen 5
|
||||
- Ducklett
|
||||
- Swanna
|
||||
- Shelmet
|
||||
- Accelgor
|
||||
- Karrablast
|
||||
- Escavalier
|
||||
- Rufflet
|
||||
- Braviary
|
||||
- Foongus
|
||||
- Amoonguss
|
||||
|
||||
#### Gen 6
|
||||
- Binacle
|
||||
- Barbaracle
|
||||
|
||||
#### Gen 7
|
||||
- Dewpider
|
||||
- Araquanid
|
||||
- Alolan Geodude
|
||||
- Alolan Graveler
|
||||
- Alolan Golem
|
||||
|
||||
#### Gen 8
|
||||
- Galarian Slowpoke
|
||||
- Galarian Slowbro
|
||||
- Galarian Slowking
|
||||
|
||||
#### Gen 9
|
||||
- Paldean Tauros
|
||||
|
||||
### Added cries to the following Pokémon
|
||||
- All Nidorans
|
||||
- Shellder, Cloyster
|
||||
- Pinsir
|
||||
- Tyrogue, Hitmontop
|
||||
- Spinda
|
||||
|
||||
### Animation updates for the following Pokémon
|
||||
- Primeape
|
||||
- Munchlax
|
||||
- Snorlax
|
||||
- Poliwrath
|
||||
- Goldeen
|
||||
- Seaking
|
||||
- Dondozo
|
||||
- Wobbuffet
|
||||
- Charcadet
|
||||
- Armarouge
|
||||
- Ceruledge
|
||||
- Geodude
|
||||
- Graveler
|
||||
- Golem
|
||||
- Sandile
|
||||
- Krokorok
|
||||
- Krookodile
|
||||
|
||||
### Model updates for the following Pokémon
|
||||
- Slowpoke
|
||||
- Slowbro
|
||||
- Slowking
|
||||
- Eiscue
|
||||
- Tauros
|
||||
- Goldeen
|
||||
- Seaking
|
||||
- Charcadet
|
||||
- Armarouge
|
||||
- Ceruledge
|
||||
- Pinsir
|
||||
- Geodude
|
||||
- Graveler
|
||||
- Golem
|
||||
|
||||
### Cry updates for the following Pokémon
|
||||
- Sceptile
|
||||
|
||||
### Changes
|
||||
- Completely re-synced Pokémon move and stat data based on later games. Learnsets have changed considerably to maximise available moves.
|
||||
- Pokémon will now be dynamically revealed to the Pokédex as they're seen in battle instead of revealing entire parties at the end of battle.
|
||||
- Unseen wild Pokémon will update their name from '???' to their real name as soon as a battle starts to match how the battle UI shows the actual species name.
|
||||
- Pokémon under the illusion effect will reveal their disguise to the Pokédex first and then the base Pokémon once the disguise is broken.
|
||||
- Berries will now drop from berry trees if broken at age 0 so you aren't punished for mistaken planting.
|
||||
- Increased Fortune drops on Mint Seeds.
|
||||
- Updated Slowpoke's shiny texture.
|
||||
- Updated drops for many Pokémon.
|
||||
- Adjusted the evolution sound to match the timing of the particle effect.
|
||||
- Made berry trees shear-able by dispenser blocks. I'm sure nobody will make unholy contraptions with this.
|
||||
- Edited some recipes to utilize tags instead of direct item IDs, for better mod compatibility.
|
||||
- Added more support for a variety of Fabric/NeoForge conventional tags.
|
||||
- Reformatted some tags to be more consistent.
|
||||
|
||||
### Fixes
|
||||
- Fixed Pokédex sometimes crashing when switching forms.
|
||||
- Fixed Pokédex interface not transitioning out when closed.
|
||||
- Fixed texture dimensions for the interact interface.
|
||||
- Fixed crash related to Tom's Simple Storage mod and Fossil Machine.
|
||||
- Fixed texture dimensions for the player and Pokémon interact interface.
|
||||
- Fixed crash related to Tom's Simple Storage mod and the Fossil Machine.
|
||||
- Fixed not being able to retrieve a fossil from the Fossil Machine with an empty hand.
|
||||
- Fixed Pokémon being collidable while being captured by a Poké Ball.
|
||||
- Fixed Pokémon being collidable (collidible? collissionable? kaleidoscopable?) while being captured by a Poké Ball.
|
||||
- Fixed `full_party`, `own_zangoose_seviper`, `use_revive` and `use_candy` Advancement triggers.
|
||||
- Fixed `healing_machine` Advancement by using the correct 1.21 trigger.
|
||||
- Fix Display Cases not dropping items if destroyed through explosions.
|
||||
- Fixed an issue where the first Pokémon in the pastured Pokémon list clipped into the interface.
|
||||
- Fixed all Pokémon facing South on spawn.
|
||||
- Parametric particle motion now works.
|
||||
- Event spawned particles now work.
|
||||
- Particles can now have independent coordinate spaces.
|
||||
- Fixed bait being consumed when not reeling in any Pokémon.
|
||||
- Fixed bait being consumed even when not reeling in any Pokémon.
|
||||
- Fixed Miltank milk magically disappearing out of your bucket.
|
||||
- Fixed Pokémon nicknames migrating from 1.5.2 not being displayed properly.
|
||||
- Fixed capitalization in one of our config fields, but allowing typo'd version to still be valid.
|
||||
- Fixed Poké Rods not working if lure or luck of the sea enchantments get removed by other mods.
|
||||
- Fixed crashes related to Pokémon when they are ready to evolve while holding an enchanted item.
|
||||
- Fixed crashes that sometimes occur when evolving Nincada.
|
||||
- Fixed plants not being compostible on NeoForge.
|
||||
- Fixed capitalization in one of our config options. It was a very important fix. Very important. Old configs are fine.
|
||||
- Fixed Poké Rods not working if Lure or Luck of the Sea enchantments get removed by other mods.
|
||||
- Fixed crashes related to Pokémon when they are ready to evolve while holding an enchanted item. Very specific.
|
||||
- Fixed a crash that sometimes occurred when evolving Nincada.
|
||||
- Fixed Cobblemon plants not being compostable on NeoForge.
|
||||
- Fixed hide UI (F1 key) not hiding the party overlay.
|
||||
- Fixed NPC MoLang command `player_lose_command` not working.
|
||||
- Corrected misaligned tooltips with editboxes in the NPC editor screen.
|
||||
- Fixed misaligned tooltips with edit boxes in the NPC editor screen.
|
||||
- Fixed Pokémon riding two boats when attempting to deploy a platform on water.
|
||||
- Made berry trees be shearable by dispenser blocks.
|
||||
- Fixed the summary screen showing there's experience to reach the next level when at level cap.
|
||||
- Fixed the summary screen showing there's experience to reach the next level when they are at the level cap.
|
||||
- Fixed Pokémon forgetting moves when evolving on specific cases.
|
||||
- Fixed Adorn compatibility, including improvements when using JEI/REI (Apricorn items now show up under the collapsed entries rather than standalone).
|
||||
- Fixed error message appearing on battle log when using Solar Beam with Sunny Day.
|
||||
@@ -54,35 +165,68 @@
|
||||
- Fixed `/pokedex grant all` command not giving male/female/shininess completion for some Pokémon.
|
||||
- Fixed `/pokedex grant only` and `/pokedex remove only` not respecting the form parameter passed.
|
||||
- Fixed variant forms appearing incorrectly in the Pokédex when the normal form had not been unlocked.
|
||||
- Fixed Pokémon occasionally being shot into the sky during battle.
|
||||
- Fixed Pokémon occasionally being shot into the sky during battle. No Pokémon were harmed by this bug, probably.
|
||||
- Fixed NPC editing GUI not updating aspects until a game restart.
|
||||
- Fix some users being unable to open their PC if a Pokémon in said PC had a lot of pp raises beyond normal bounds
|
||||
- Fix some color variants (dubwool, conkeldurr and undyed wooloo) missing in the Pokédex
|
||||
- Fix invalid species or held_items causing Players to not be able to load into their world anymore (commonly happening after removing addons/mods)
|
||||
- Fixed some users being unable to open their PC if a Pokémon in it had a lot of PP raises beyond normal bounds. How did you get those, anyway? Tell me or the Bellossom gets it.
|
||||
- Fixed some color variants (Dubwool, Conkeldurr and Undyed wooloo) being missing in the Pokédex.
|
||||
- Fixed invalid species or held items causing Players to not be able to load into their world anymore (commonly happening after removing addons/mods).
|
||||
- Fixed Wooloo variants not being automatically registered in the owner's Pokédex when dyed.
|
||||
- Fixed Vivichoke Dip and Leek and Potato Stew not returning a bowl upon consumption.
|
||||
- Fixed Fossil Restoration Machine not accepting Hay Bales.
|
||||
- Fixed Potion items so that they no longer apply over double their intended healing value.
|
||||
- Fixed Vivichoke Dip and Leek & Potato Stew not returning a bowl upon consumption.
|
||||
- Fixed Fossil Restoration Tank not accepting Hay Bales as organic material.
|
||||
- Fixed Potion items applying double their intended healing value.
|
||||
- Fixed Fast Ball capture bonuses applying to all Pokémon, making it the Best Ball instead of the Mediocre Edge-Case Ball.
|
||||
- Fixed "learned new move" messages appearing for already-known moves on Pokémon evolutions.
|
||||
- Fixed Pokémon Item Models breaking shadows nearby when being placed in Display Cases or Item Frames.
|
||||
- Fixed berries not giving bonus yields when planted in their preferred biomes. I'm sure we've fixed that 5 times now.
|
||||
- Fixed the NeoForge version not supporting "SodiumDynamicLights".
|
||||
- Fixed players disconnecting from servers if they made changes to certain config options.
|
||||
- Fixed players with shouldered Pokémon not being able to rejoin their 1.5.2 worlds using 1.6.
|
||||
- Fixed `PokemonProperties` utilizing `ability=<some ability>` being treated as a forced ability even when it is a legal ability for the Pokémon.
|
||||
- Fixed type formatting in Pokédex scanner mode when dual types require two lines.
|
||||
- Fixed trading sometimes crashing the game or server.
|
||||
- Fixed Wild shiny sounds not respecting the `shinyNoticeParticlesDistance` config setting.
|
||||
- Fixed Pokémon being able to evolve mid-battle.
|
||||
- Fixed NPC held items being able to be stolen by players. Don't be a thief!
|
||||
- Fixed evolutions that require a held item consuming it as soon as meeting requirements when it should only be consumed upon evolution.
|
||||
- Fixed Pokémon showing only the default form when selecting them as a target in battle.
|
||||
- Fixed a possible error coming out of reeling fishing rods in specific situations.
|
||||
- Fixed incorrect weights being used when Poké Fishing with Luck of the Sea.
|
||||
- Parametric particle motion now works.
|
||||
- Event-spawned particles now work.
|
||||
- Particles can now have independent coordinate spaces.
|
||||
|
||||
### Molang & Datapacks
|
||||
### Developer
|
||||
- Updated the Pokédex data updated events to always include a `Pokemon` instance, and optionally a `DisguiseData` instance.
|
||||
- Updated fields in `SpawnNPCPacket` and `SpawnPokemonPacket` to be visible and mutable.
|
||||
- Updated `UnvalidatedPlaySoundS2CPacket` to be public instead of internal and made its fields mutable.
|
||||
- Added `hideNameTag` field and `HideNPCNameTag` nbt tag to `NPCEntity` to allow hiding the name tag of the NPC.
|
||||
- Added the player to `PokerodReelEvent` so you know who is doing the reeling.
|
||||
|
||||
### MoLang & Datapacks
|
||||
- Added flows for:
|
||||
- `forme_change`: Triggered when a Pokémon changes form in battle.
|
||||
- `mega_evolution`: Triggered when a Pokémon mega evolves in battle. (Note: Third party mods are required for this feature currently)
|
||||
- `zpower_used`: Triggered when a Pokémon uses a Z-Power move in battle. (Note: Third party mods are required for this feature currently)
|
||||
- `terastallization`: Triggered when a Pokémon terastallizes in battle. (Note: Third party mods are required for this feature currently)
|
||||
- `mega_evolution`: Triggered when a Pokémon mega evolves in battle. (Note: Third-party mods are required for this feature currently)
|
||||
- `zpower_used`: Triggered when a Pokémon uses a Z-Power move in battle. (Note: Third-party mods are required for this feature currently)
|
||||
- `terastallization`: Triggered when a Pokémon terastallizes in battle. (Note: Third-party mods are required for this feature currently)
|
||||
- `battle_fainted`: Triggered when a Pokémon faints in battle.
|
||||
- `battle_fled`: Triggered when a Player flees from battle.
|
||||
- `battle_fled`: Triggered when a player flees from battle.
|
||||
- `battle_started_pre`: Triggered when a battle starts. Cancelable!
|
||||
- `battle_started_post`: Triggered when a battle starts.
|
||||
- `apricorn_harvested`: Triggered when an apricorn is harvested.
|
||||
- `apricorn_harvested`: Triggered when an Apricorn is harvested.
|
||||
- `thrown_pokeball_hit`: Triggered when a thrown Pokéball hits a Pokémon.
|
||||
- `level_up`: Triggered when a Pokémon levels up.
|
||||
- `pokemon_fainted`: Triggered when a Pokémon faints.
|
||||
- `pokemon_gained`: Triggered when a Player gains a Pokémon.
|
||||
- Added molang functions:
|
||||
- `pokemon_gained`: Triggered when a player gains a Pokémon.
|
||||
- Added MoLang functions:
|
||||
- For Pokémon:
|
||||
- `pokemon.apply(PokemonProperties)`: Applies the given properties to the Pokémon.
|
||||
- `pokemon.owner`: Returns the owner of the Pokémon or 0.0 if there is no owner or they are not online.
|
||||
- For all entities:
|
||||
- `entity.is_standing_on_blocks(depth, blocks...)`: Returns whether the specified entity is standing on a specific block or set of blocks. Example usage: `q.is_standing_on_blocks(2, minecraft:sand)`
|
||||
- Added NPC field:
|
||||
- `hideNameTag`: Hides the name tag of the NPC.
|
||||
- Added `baseScale` property to NPCs.
|
||||
- Added MoLang particle queries for getting distance to targeted entities.
|
||||
|
||||
## [1.6.0 - The Record Catch Update (December 25th, 2024)](#1-6-0)
|
||||
#### "Now that there's a fishing mechanic, the mod is actually good!"
|
||||
@@ -1985,5 +2129,4 @@ Thank you so much to all of our community translators that bring the mod to the
|
||||
- Added species, ability, and move translations for `ko_ko`, `jp_jp`, `fr_fr`, `es_es`, `it_it`, and `zh_cn`.
|
||||
|
||||
## [1.0.0 (November 12th, 2022)](#1-0-0)
|
||||
- Initial release.
|
||||
|
||||
- Initial release.
|
||||
@@ -1,27 +0,0 @@
|
||||
plugins {
|
||||
id("java-gradle-plugin")
|
||||
kotlin("jvm") version "2.1.0"
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven("https://maven.architectury.dev/")
|
||||
maven("https://maven.fabricmc.net/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("net.neoforged:moddev-gradle:2.0.75")
|
||||
implementation("dev.architectury:at:1.0.1")
|
||||
implementation("net.fabricmc:access-widener:2.1.0")
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
create("cobblemongradle") {
|
||||
id = "com.cobblemon.gradle"
|
||||
implementationClass = "com.cobblemon.gradle.CobblemonGradle"
|
||||
version = "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
create("libs") {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package com.cobblemon.gradle
|
||||
|
||||
import com.cobblemon.gradle.extension.CobblemonGradleExtension
|
||||
import com.cobblemon.gradle.extension.tasks.ConvertAccessWidenersTask
|
||||
import com.cobblemon.gradle.extension.tasks.UnzipAccessWidenersTask
|
||||
import net.neoforged.nfrtgradle.CreateMinecraftArtifacts
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.LibraryElements
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
|
||||
class CobblemonGradle : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
val cobblemonExtension = project.extensions.create(
|
||||
CobblemonGradleExtension.EXTENSION_NAME,
|
||||
CobblemonGradleExtension::class.java
|
||||
)
|
||||
|
||||
//This exists because all of
|
||||
// - com.cobblemon:mod
|
||||
// - com.cobblemon:mod-resources
|
||||
// - com.cobblemon:accesswidener
|
||||
//technically point to the same dependency (the :common project). To pick the proper artifact from that project
|
||||
//we set attributes in that project and check for them here.
|
||||
val accessWideners = project.configurations.register("accessWidener") { configuration ->
|
||||
configuration.isCanBeConsumed = false
|
||||
configuration.isCanBeResolved = true
|
||||
configuration.isCanBeDeclared = true
|
||||
configuration.attributes {
|
||||
it.attribute(
|
||||
LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
|
||||
project.objects.named(LibraryElements::class.java, LibraryElements.OBJECTS)
|
||||
)
|
||||
}
|
||||
}
|
||||
val includeRootResources = project.configurations.register("includeRootResources") { configuration ->
|
||||
configuration.isCanBeConsumed = false
|
||||
configuration.isCanBeResolved = true
|
||||
configuration.isCanBeDeclared = true
|
||||
configuration.attributes {
|
||||
it.attribute(
|
||||
LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
|
||||
project.objects.named(LibraryElements::class.java, LibraryElements.RESOURCES)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val unzipAwTask = project.tasks.register("unzipAccessWideners", UnzipAccessWidenersTask::class.java) {
|
||||
it.accessWidenerZips = accessWideners.get()
|
||||
}
|
||||
|
||||
|
||||
val convertAwTask = project.tasks.register(ConvertAccessWidenersTask.NAME, ConvertAccessWidenersTask::class.java) {
|
||||
it.enabled = cobblemonExtension.convertAccessWideners
|
||||
it.dependsOn(unzipAwTask)
|
||||
it.accessWideners = project.files(unzipAwTask).plus(project.files(cobblemonExtension.additionalAccessWideners))
|
||||
}
|
||||
|
||||
//Add root resources and access wideners to output jar
|
||||
project.tasks.named("processResources", ProcessResources::class.java) { task ->
|
||||
task.dependsOn(includeRootResources)
|
||||
if (cobblemonExtension.convertAccessWideners) {
|
||||
task.dependsOn(convertAwTask)
|
||||
task.from(convertAwTask)
|
||||
}
|
||||
else {
|
||||
task.dependsOn(unzipAwTask)
|
||||
task.from(unzipAwTask)
|
||||
}
|
||||
task.doLast {
|
||||
project.copy {
|
||||
it.from(project.provider {
|
||||
includeRootResources.get().resolve().map { project.zipTree(it) }
|
||||
})
|
||||
it.into(task.destinationDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.tasks.withType(CreateMinecraftArtifacts::class.java) {
|
||||
it.dependsOn(convertAwTask)
|
||||
it.accessTransformers.from(convertAwTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
package com.cobblemon.gradle.extension
|
||||
|
||||
import org.gradle.api.file.FileCollection
|
||||
|
||||
abstract class CobblemonGradleExtension {
|
||||
var additionalAccessWideners: FileCollection? = null
|
||||
var convertAccessWideners = true
|
||||
|
||||
companion object {
|
||||
const val EXTENSION_NAME = "cobblemon"
|
||||
}
|
||||
}
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
package com.cobblemon.gradle.extension.tasks
|
||||
|
||||
import dev.architectury.at.AccessChange
|
||||
import dev.architectury.at.AccessTransform
|
||||
import dev.architectury.at.AccessTransformSet
|
||||
import dev.architectury.at.ModifierChange
|
||||
import dev.architectury.at.io.AccessTransformFormats
|
||||
import net.fabricmc.accesswidener.AccessWidenerReader
|
||||
import net.fabricmc.accesswidener.AccessWidenerVisitor
|
||||
import org.cadixdev.bombe.type.signature.MethodSignature
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.OutputFiles
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.io.Writer
|
||||
import java.nio.file.Files
|
||||
|
||||
abstract class ConvertAccessWidenersTask : DefaultTask() {
|
||||
abstract var accessWideners: FileCollection
|
||||
@InputFiles get
|
||||
|
||||
@Internal
|
||||
val accessTransformerDir = project.layout.buildDirectory.dir("access-transformers")
|
||||
|
||||
@OutputFiles
|
||||
val accessTransformers = project.files ({
|
||||
accessWideners.files.map {
|
||||
accessTransformerDir.get().file(it.name.replace("accesswidener", "accesstransformer.cfg"))
|
||||
}
|
||||
})
|
||||
|
||||
@TaskAction
|
||||
fun convertAccessWideners() {
|
||||
accessWideners.files.forEach { file ->
|
||||
val awFile = Files.newBufferedReader(file.toPath())
|
||||
val result = AccessTransformSet.create();
|
||||
|
||||
AccessWidenerReader(object : AccessWidenerVisitor {
|
||||
override fun visitClass(name: String, access: AccessWidenerReader.AccessType, transitive: Boolean) {
|
||||
result.getOrCreateClass(name).merge(toAt(access));
|
||||
}
|
||||
|
||||
override fun visitMethod(owner: String, name: String, descriptor: String, access: AccessWidenerReader.AccessType, transitive: Boolean) {
|
||||
result.getOrCreateClass(owner).mergeMethod(MethodSignature.of(name, descriptor), toAt(access));
|
||||
}
|
||||
|
||||
override fun visitField(owner: String, name: String, descriptor: String, access: AccessWidenerReader.AccessType, transitive: Boolean) {
|
||||
result.getOrCreateClass(owner).mergeField(name, toAt(access));
|
||||
}
|
||||
}).read(awFile)
|
||||
|
||||
val outputFile = accessTransformerDir.get().file(
|
||||
file.name.replace("accesswidener", "accesstransformer.cfg")
|
||||
)
|
||||
var outputWriter: Writer? = null
|
||||
try {
|
||||
outputWriter = outputFile.asFile.writer()
|
||||
AccessTransformFormats.FML.write(outputWriter, result)
|
||||
}
|
||||
finally {
|
||||
outputWriter?.flush()
|
||||
outputWriter?.close()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun toAt(access: AccessWidenerReader.AccessType): AccessTransform {
|
||||
return when (access) {
|
||||
AccessWidenerReader.AccessType.ACCESSIBLE -> AccessTransform.of(AccessChange.PUBLIC)
|
||||
AccessWidenerReader.AccessType.EXTENDABLE, AccessWidenerReader.AccessType.MUTABLE -> AccessTransform.of(
|
||||
AccessChange.PUBLIC,
|
||||
ModifierChange.REMOVE
|
||||
)
|
||||
}
|
||||
}
|
||||
companion object {
|
||||
const val NAME = "convertAccessWideners"
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
package com.cobblemon.gradle.extension.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.OutputFiles
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
abstract class UnzipAccessWidenersTask : DefaultTask() {
|
||||
abstract var accessWidenerZips: FileCollection
|
||||
@InputFiles get
|
||||
|
||||
@OutputFiles
|
||||
val outputFiles = project.provider {
|
||||
project.files(accessWidenerZips.flatMap { zip ->
|
||||
project.zipTree(zip).files.map { OUTPUT_DIR.get().file(it.name) }
|
||||
})
|
||||
}
|
||||
|
||||
@Internal
|
||||
val OUTPUT_DIR = project.layout.buildDirectory.dir("cobblemon-working/access-wideners")
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
project.copy {
|
||||
it.from(accessWidenerZips.map(project::zipTree))
|
||||
it.into(OUTPUT_DIR)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -1,14 +1,12 @@
|
||||
plugins {
|
||||
//id("cobblemon.root-conventions")
|
||||
id("cobblemon.root-conventions")
|
||||
id ("net.nemerosa.versioning") version "3.1.0"
|
||||
}
|
||||
|
||||
version = "${project.property("mod_version")}+${project.property("mc_version")}"
|
||||
|
||||
val isSnapshot = project.property("snapshot")?.equals("true") ?: false
|
||||
/*
|
||||
val isSnapshot = project.property("snapshot")?.equals("true") == true
|
||||
if (isSnapshot) {
|
||||
val fixedBranchName = versioning.info.branch.substringAfter("/")
|
||||
version = "$version-${fixedBranchName}-${versioning.info.build}"
|
||||
}
|
||||
*/
|
||||
+54
-90
@@ -1,102 +1,68 @@
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import utilities.isSnapshot
|
||||
import utilities.version
|
||||
|
||||
/*
|
||||
*
|
||||
* * 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 {
|
||||
kotlin("jvm") version "2.1.0"
|
||||
id ("net.neoforged.moddev") version "2.0.75"
|
||||
id("net.kyori.blossom") version "2.1.0"
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
id("com.cobblemon.gradle")
|
||||
id("cobblemon.base-conventions")
|
||||
id("cobblemon.publish-conventions")
|
||||
|
||||
id("net.kyori.blossom")
|
||||
id("org.jetbrains.gradle.plugin.idea-ext")
|
||||
id("net.nemerosa.versioning") version "3.1.0"
|
||||
}
|
||||
|
||||
cobblemon {
|
||||
additionalAccessWideners = files(sourceSets.main.get().resources).filter { it.extension == "accesswidener" }
|
||||
}
|
||||
|
||||
val rootResources = configurations.create("rootResources") {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.RESOURCES))
|
||||
}
|
||||
}
|
||||
|
||||
val accessWidenerExport = configurations.create("accessWidenerExport") {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
attributes {
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.OBJECTS))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.processResources {
|
||||
exclude("*.accesswidener")
|
||||
}
|
||||
|
||||
tasks.create<Zip>("zipResources") {
|
||||
dependsOn("processResources")
|
||||
from(tasks.processResources.get().destinationDir)
|
||||
this.archiveBaseName = "mod-resources"
|
||||
}
|
||||
|
||||
tasks.create<Zip>("zipAccessWideners") {
|
||||
from(sourceSets.main.get().resources)
|
||||
include("*.accesswidener")
|
||||
this.archiveBaseName = "mod-accesswideners"
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
archiveBaseName = "mod"
|
||||
manifest {
|
||||
attributes(mapOf("FMLModType" to "GAMELIBRARY"))
|
||||
}
|
||||
exclude {
|
||||
it.file in tasks.processResources.get().outputs.files
|
||||
}
|
||||
}
|
||||
|
||||
tasks.assemble {
|
||||
dependsOn(tasks.named("zipResources"))
|
||||
dependsOn(tasks.named("zipAccessWideners"))
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("rootResources", tasks.getByName<Zip>("zipResources"))
|
||||
add("accessWidenerExport", tasks.getByName("zipAccessWideners"))
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven("https://maven.architectury.dev/")
|
||||
maven("https://maven.fabricmc.net/")
|
||||
}
|
||||
architectury {
|
||||
common("neoforge", "fabric")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://maven.fabricmc.net/")
|
||||
maven("https://maven.blamejared.com/")
|
||||
maven("https://api.modrinth.com/maven")
|
||||
maven(url = "../deps")
|
||||
maven(url = "${rootProject.projectDir}/deps")
|
||||
maven(url = "https://api.modrinth.com/maven")
|
||||
maven(url = "https://maven.neoforged.net/releases")
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.bundles.mongo)
|
||||
compileOnly(libs.bundles.kotlin)
|
||||
compileOnly(libs.molang)
|
||||
compileOnly(libs.graal)
|
||||
compileOnly(libs.jei.api)
|
||||
compileOnly(libs.bundles.fabric.integrations.compileOnly) {
|
||||
implementation(libs.bundles.kotlin)
|
||||
modImplementation(libs.fabric.loader)
|
||||
modApi(libs.molang)
|
||||
|
||||
// Integrations
|
||||
compileOnlyApi(libs.jei.api)
|
||||
modCompileOnly(libs.bundles.fabric.integrations.compileOnly) {
|
||||
isTransitive = false
|
||||
}
|
||||
compileOnly("net.fabricmc:sponge-mixin:0.15.5+mixin.0.8.7")
|
||||
compileOnly("io.github.llamalad7:mixinextras-fabric:0.4.1")
|
||||
// Flywheel has no common dep so just pick one and don't use any platform specific code in common
|
||||
// modCompileOnly(libs.flywheelFabric)
|
||||
|
||||
// Showdown
|
||||
modCompileOnly(libs.graal)
|
||||
|
||||
// Data Storage
|
||||
modCompileOnly(libs.bundles.mongo)
|
||||
|
||||
// Unit Testing
|
||||
testImplementation(libs.bundles.unitTesting)
|
||||
}
|
||||
|
||||
neoForge {
|
||||
neoFormVersion = "1.21.1-20240808.144430"
|
||||
interfaceInjectionData.from("src/main/resources/interfaces.json")
|
||||
validateAccessTransformers = true
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
setEvents(listOf("failed"))
|
||||
setExceptionFormat("full")
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@@ -106,7 +72,7 @@ sourceSets {
|
||||
fun generateLicenseHeader() : String {
|
||||
val builder = StringBuilder()
|
||||
builder.append("/*\n")
|
||||
project.projectDir.parentFile.resolve("HEADER").forEachLine {
|
||||
rootProject.file("HEADER").forEachLine {
|
||||
if(it.isEmpty()) {
|
||||
builder.append(" *").append("\n")
|
||||
} else {
|
||||
@@ -119,14 +85,12 @@ sourceSets {
|
||||
|
||||
property("license", generateLicenseHeader())
|
||||
property("modid", "cobblemon")
|
||||
property("version", project.version as String)
|
||||
property("isSnapshot", "true")
|
||||
/*
|
||||
property("version", project.version())
|
||||
property("isSnapshot", if(rootProject.isSnapshot()) "true" else "false")
|
||||
property("gitCommit", versioning.info.commit)
|
||||
property("branch", versioning.info.branch)
|
||||
System.getProperty("buildNumber")?.let { property("buildNumber", it) }
|
||||
property("timestamp", OffsetDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss")) + " UTC")
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import utilities.isSnapshot
|
||||
import utilities.version
|
||||
|
||||
/*
|
||||
*
|
||||
* * 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")
|
||||
|
||||
id("net.kyori.blossom")
|
||||
id("org.jetbrains.gradle.plugin.idea-ext")
|
||||
id("net.nemerosa.versioning") version "3.1.0"
|
||||
}
|
||||
|
||||
architectury {
|
||||
common("neoforge", "fabric")
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven(url = "${rootProject.projectDir}/deps")
|
||||
maven(url = "https://api.modrinth.com/maven")
|
||||
maven(url = "https://maven.neoforged.net/releases")
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.bundles.kotlin)
|
||||
modImplementation(libs.fabric.loader)
|
||||
modApi(libs.molang)
|
||||
|
||||
// Integrations
|
||||
compileOnlyApi(libs.jei.api)
|
||||
modCompileOnly(libs.bundles.fabric.integrations.compileOnly) {
|
||||
isTransitive = false
|
||||
}
|
||||
// Flywheel has no common dep so just pick one and don't use any platform specific code in common
|
||||
// modCompileOnly(libs.flywheelFabric)
|
||||
|
||||
// Showdown
|
||||
modCompileOnly(libs.graal)
|
||||
|
||||
// Data Storage
|
||||
modCompileOnly(libs.bundles.mongo)
|
||||
|
||||
// Unit Testing
|
||||
testImplementation(libs.bundles.unitTesting)
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
setEvents(listOf("failed"))
|
||||
setExceptionFormat("full")
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
blossom {
|
||||
kotlinSources {
|
||||
fun generateLicenseHeader() : String {
|
||||
val builder = StringBuilder()
|
||||
builder.append("/*\n")
|
||||
rootProject.file("HEADER").forEachLine {
|
||||
if(it.isEmpty()) {
|
||||
builder.append(" *").append("\n")
|
||||
} else {
|
||||
builder.append(" * ").append(it).append("\n")
|
||||
}
|
||||
}
|
||||
|
||||
return builder.append(" */").append("\n").toString()
|
||||
}
|
||||
|
||||
property("license", generateLicenseHeader())
|
||||
property("modid", "cobblemon")
|
||||
property("version", project.version())
|
||||
property("isSnapshot", if(rootProject.isSnapshot()) "true" else "false")
|
||||
property("gitCommit", versioning.info.commit)
|
||||
property("branch", versioning.info.branch)
|
||||
System.getProperty("buildNumber")?.let { property("buildNumber", it) }
|
||||
property("timestamp", OffsetDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss")) + " UTC")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
[versions]
|
||||
# Kotlin
|
||||
kotlin = "2.0.0"
|
||||
|
||||
# Plugins
|
||||
licenser = "0.6.1"
|
||||
shadow = "8.1.1"
|
||||
blossom = "2.1.0"
|
||||
idea-ext = "1.1.7"
|
||||
|
||||
# Loom
|
||||
loom = "1.7-SNAPSHOT"
|
||||
architectury-plugin = "3.4-SNAPSHOT"
|
||||
|
||||
# Common
|
||||
molang = "1.1.18"
|
||||
graal = "22.3.0"
|
||||
icu4j = "71.1"
|
||||
jei-api = "19.8.2.99"
|
||||
|
||||
# Fabric
|
||||
fabric-loader = "0.16.5"
|
||||
fabric-api = "0.104.0+1.21.1"
|
||||
fabric-kotlin = "1.11.0+kotlin.2.0.0"
|
||||
fabric-permissions-api = "0.2-SNAPSHOT"
|
||||
lambDynamicLights = "3.0.1+1.21.1"
|
||||
debugutils-fabric = "1.21-1.0.6-fabric"
|
||||
|
||||
# NeoForge
|
||||
neoforge = "21.1.66"
|
||||
neo-kotlin-for-forge = "5.5.0"
|
||||
debugutils-forge = "1.21-1.0.6-neoforge"
|
||||
|
||||
# Data Storage
|
||||
mongo = "4.10.2"
|
||||
|
||||
# Testing
|
||||
junit = "5.9.0"
|
||||
mockito = "5.2.0"
|
||||
mockk = "1.12.1"
|
||||
classgraph = "4.8.153"
|
||||
|
||||
[libraries]
|
||||
# General Buildscript Plugins
|
||||
kotlin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
|
||||
loom = { group = "dev.architectury", name = "architectury-loom", version.ref = "loom" }
|
||||
architectury = { group = "architectury-plugin", name = "architectury-plugin.gradle.plugin", version.ref = "architectury-plugin" }
|
||||
shadow = { group = "com.github.johnrengelman", name = "shadow", version.ref = "shadow" }
|
||||
blossom = { group = "net.kyori", name = "blossom", version.ref = "blossom" }
|
||||
ideaExt = { group = "org.jetbrains.gradle.plugin.idea-ext", name = "org.jetbrains.gradle.plugin.idea-ext.gradle.plugin", version.ref = "idea-ext"}
|
||||
licenser = { group = "gradle.plugin.org.cadixdev.gradle", name = "licenser", version.ref = "licenser" }
|
||||
|
||||
# Kotlin
|
||||
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" }
|
||||
kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" }
|
||||
|
||||
# Common
|
||||
jei-api = { group = "mezz.jei", name = "jei-1.21-common-api", version.ref = "jei-api"}
|
||||
molang = { group = "local.com.bedrockk", name = "molang", version.ref = "molang" }
|
||||
graal = { group = "org.graalvm.js", name = "js", version.ref = "graal" }
|
||||
icu4j = { group = "com.ibm.icu", name = "icu4j", version.ref = "icu4j" }
|
||||
|
||||
# Fabric
|
||||
fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabric-loader" }
|
||||
fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric-api" }
|
||||
fabric-kotlin = { group = "net.fabricmc", name = "fabric-language-kotlin", version.ref = "fabric-kotlin" }
|
||||
fabric-permissions = { group = "me.lucko", name = "fabric-permissions-api", version.ref = "fabric-permissions-api" }
|
||||
adorn-fabric = { group = "maven.modrinth", name = "adorn", version = "6.0.0-neoforge"}
|
||||
lambDynamicLights = { group = "maven.modrinth", name = "lambdynamiclights", version.ref = "lambDynamicLights"}
|
||||
jei-api-fabric = { group = "mezz.jei", name = "jei-1.21-fabric-api", version.ref = "jei-api" }
|
||||
jei-fabric = { group = "mezz.jei", name = "jei-1.21-fabric", version.ref = "jei-api"}
|
||||
fabric-debugutils = { group = "maven.modrinth", name = "debugutils", version.ref = "debugutils-fabric"}
|
||||
|
||||
# NeoForge
|
||||
neoforge = { group = "net.neoforged", name = "neoforge", version.ref = "neoforge" }
|
||||
neo-kotlin-forge = { group = "thedarkcolour", name = "kotlinforforge-neoforge", version.ref = "neo-kotlin-for-forge" }
|
||||
neoforge-debugutils = { group = "maven.modrinth", name = "debugutils", version.ref = "debugutils-forge"}
|
||||
|
||||
# Data Storage
|
||||
mongo-driver-core = { group = "org.mongodb", name = "mongodb-driver-core", version.ref = "mongo" }
|
||||
mongo-driver-sync = { group = "org.mongodb", name = "mongodb-driver-sync", version.ref = "mongo" }
|
||||
|
||||
# Testing
|
||||
junit = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" }
|
||||
mockito-core = { group = "org.mockito", name = "mockito-core", version.ref = "mockito" }
|
||||
mock-kotlin = { group = "io.mockk", name = "mockk", version.ref = "mockk" }
|
||||
classgraph = { group = "io.github.classgraph", name = "classgraph", version.ref = "classgraph" }
|
||||
|
||||
[bundles]
|
||||
kotlin = [ "kotlin-stdlib", "kotlin-reflect" ]
|
||||
fabric = [ "fabric-kotlin", "fabric-permissions" ]
|
||||
fabric-integrations-compileOnly = [ "adorn-fabric", "lambDynamicLights", "jei-api-fabric" ]
|
||||
fabric-integrations-runtimeOnly = [ "jei-fabric" ]
|
||||
mongo = [ "mongo-driver-core", "mongo-driver-sync" ]
|
||||
unitTesting = [ "junit", "mockito-core", "mock-kotlin", "classgraph" ]
|
||||
@@ -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.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokemon.ai.EntityBehaviour;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.ai.goal.AvoidEntityGoal;
|
||||
import net.minecraft.world.entity.monster.Creeper;
|
||||
import net.minecraft.world.level.Level;
|
||||
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(Creeper.class)
|
||||
public class EntityCreeperMixin extends Mob {
|
||||
|
||||
private EntityCreeperMixin(net.minecraft.world.entity.EntityType<? extends Creeper> entityType, Level world) {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
@Inject(method = "registerGoals", at = @At(value = "TAIL"), cancellable = false)
|
||||
private void cobblemon$initGoals(CallbackInfo callbackInfo) {
|
||||
final Creeper creeper = (Creeper) (Object) this;
|
||||
// Pokemon Entities
|
||||
this.goalSelector.addGoal(
|
||||
3,
|
||||
new AvoidEntityGoal<>(
|
||||
creeper,
|
||||
PokemonEntity.class,
|
||||
6.0f,
|
||||
1.0,
|
||||
1.2,
|
||||
entity -> ((PokemonEntity)entity).getBehaviour().getEntityInteract().getAvoidedByCreeper() && ((PokemonEntity)entity).getBeamMode() != 1
|
||||
)
|
||||
);
|
||||
|
||||
// Players with shoulder mounted Pokemon
|
||||
this.goalSelector.addGoal(
|
||||
3,
|
||||
new AvoidEntityGoal<>(
|
||||
creeper,
|
||||
ServerPlayer.class,
|
||||
6.0f,
|
||||
1.0,
|
||||
1.2,
|
||||
entity -> EntityBehaviour.Companion.hasCreeperFearedShoulderMount((ServerPlayer)entity)
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 net.minecraft.world.entity.monster.Phantom;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(targets = "net/minecraft/world/entity/monster/Phantom$PhantomSweepAttackGoal")
|
||||
public class EntityPhantomMixin {
|
||||
// TODO: Figure out how to access the outer class that wraps SwoopMovementGoal
|
||||
// Need to find the cat mons that are near the phantom
|
||||
|
||||
// @Inject(method = "shouldContinue", at = @At(value = "RETURN"), cancellable = true)
|
||||
// public void cobblemon$shouldContinue(CallbackInfoReturnable<Boolean> ci) {
|
||||
//// var goalSelectorField = PhantomEntity.class.getClasses();// PhantomEntity.class.getFields();// .class.getDeclaredField("goalSelector");
|
||||
//
|
||||
//// goalSelectorField.setAccessible(true);
|
||||
//// GoalSelector goalSelector = (GoalSelector) goalSelectorField.get(mobEntity);
|
||||
//// final SwoopMovementGoal phantom = (SwoopMovementGoal) (Object) this;
|
||||
//// if(ci.getReturnValue() == false) {
|
||||
//// var result = this$0.getWorld().getEntitiesByClass(
|
||||
//// PokemonEntity.class,
|
||||
//// this$0.getBoundingBox().expand(16.0),
|
||||
//// entity -> {
|
||||
//// return ((PokemonEntity) entity).getBehaviour().getEntityInteract().getAvoidedByPhantom();
|
||||
//// }
|
||||
//// ).isEmpty();
|
||||
////
|
||||
//// ci.setReturnValue(result);
|
||||
//// }
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokemon.ai.EntityBehaviour;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.ai.goal.AvoidEntityGoal;
|
||||
import net.minecraft.world.entity.monster.AbstractSkeleton;
|
||||
import net.minecraft.world.level.Level;
|
||||
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(AbstractSkeleton.class)
|
||||
public class EntitySkeletonMixin extends Mob {
|
||||
|
||||
private EntitySkeletonMixin(EntityType<? extends Mob> entityType, Level world) {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
@Inject(method = "registerGoals", at = @At(value = "TAIL"), cancellable = false)
|
||||
private void cobblemon$initGoals(CallbackInfo callbackInfo) {
|
||||
final AbstractSkeleton skeleton = (AbstractSkeleton) (Object) this;
|
||||
// Pokemon Entities
|
||||
this.goalSelector.addGoal(
|
||||
3,
|
||||
new AvoidEntityGoal<>(
|
||||
skeleton,
|
||||
PokemonEntity.class,
|
||||
6.0f,
|
||||
1.0,
|
||||
1.2,
|
||||
entity -> ((PokemonEntity)entity).getBehaviour().getEntityInteract().getAvoidedBySkeleton() && ((PokemonEntity)entity).getBeamMode() != 1
|
||||
)
|
||||
);
|
||||
|
||||
// Players with shoulder mounted Pokemon
|
||||
this.goalSelector.addGoal(
|
||||
3,
|
||||
new AvoidEntityGoal<>(
|
||||
skeleton,
|
||||
ServerPlayer.class,
|
||||
6.0f,
|
||||
1.0,
|
||||
1.2,
|
||||
entity -> EntityBehaviour.Companion.hasSkeletonFearedShoulderMount((ServerPlayer)entity)
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents;
|
||||
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent;
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies;
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyStore;
|
||||
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore;
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.ScannableEntity;
|
||||
@@ -178,10 +179,10 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
|
||||
|
||||
@Override @Nullable
|
||||
public PokedexEntityData resolvePokemonScan() {
|
||||
if(CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityRight())){
|
||||
if (CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityRight())){
|
||||
return getDataFromShoulderPokemon(this.getShoulderEntityRight());
|
||||
}
|
||||
if(CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityLeft())){
|
||||
if (CompoundTagUtilities.isShoulderPokemon(this.getShoulderEntityLeft())){
|
||||
return getDataFromShoulderPokemon(this.getShoulderEntityLeft());
|
||||
}
|
||||
return null;
|
||||
@@ -190,30 +191,34 @@ public abstract class PlayerMixin extends LivingEntity implements ScannableEntit
|
||||
@Nullable @Unique
|
||||
private PokedexEntityData getDataFromShoulderPokemon(CompoundTag shoulderTag) {
|
||||
CompoundTag pokemonTag = shoulderTag.getCompound(DataKeys.POKEMON);
|
||||
if(pokemonTag.isEmpty()) return null;
|
||||
if (pokemonTag.isEmpty()) return null;
|
||||
Species species = PokemonSpecies.INSTANCE.getByIdentifier(ResourceLocation.parse(pokemonTag.getString(DataKeys.POKEMON_SPECIES_IDENTIFIER)));
|
||||
if(species == null) return null;
|
||||
if (species == null) return null;
|
||||
String formId = pokemonTag.getString(DataKeys.POKEMON_FORM_ID);
|
||||
FormData form = species.getStandardForm();
|
||||
List<FormData> formList = species.getForms().stream().filter(it -> it.formOnlyShowdownId().equals(formId)).toList();
|
||||
if(!formList.isEmpty()) form = formList.getFirst();
|
||||
if(form == null) return null;
|
||||
if (!formList.isEmpty()) form = formList.getFirst();
|
||||
if (form == null) return null;
|
||||
String genderString = pokemonTag.getString(DataKeys.POKEMON_GENDER);
|
||||
if(genderString.isEmpty()) return null;
|
||||
if (genderString.isEmpty()) return null;
|
||||
Gender gender = Gender.valueOf(genderString);
|
||||
boolean shiny = pokemonTag.getBoolean(DataKeys.POKEMON_SHINY);
|
||||
int level = pokemonTag.getInt(DataKeys.POKEMON_LEVEL);
|
||||
Set<String> aspects = shoulderTag.getList(DataKeys.SHOULDER_ASPECTS, Tag.TAG_STRING).stream().map(Tag::getAsString).collect(Collectors.toSet());
|
||||
|
||||
return new PokedexEntityData(
|
||||
species,
|
||||
form,
|
||||
gender,
|
||||
aspects,
|
||||
shiny,
|
||||
level,
|
||||
this.getUUID()
|
||||
);
|
||||
Pokemon pokemon = new Pokemon();
|
||||
if (level().isClientSide) {
|
||||
pokemon.setSpecies(species);
|
||||
pokemon.setForm(form);
|
||||
pokemon.setGender(gender);
|
||||
pokemon.setShiny(shiny);
|
||||
pokemon.setLevel(level);
|
||||
pokemon.setForcedAspects(aspects);
|
||||
} else {
|
||||
PlayerPartyStore party = Cobblemon.INSTANCE.getStorage().getParty(this.getUUID(), this.registryAccess());
|
||||
pokemon = party.get(shoulderTag.getUUID(DataKeys.SHOULDER_UUID));
|
||||
}
|
||||
return new PokedexEntityData(pokemon, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.cobblemon.mod.common.api.SeasonResolver
|
||||
import com.cobblemon.mod.common.api.data.DataProvider
|
||||
import com.cobblemon.mod.common.api.drop.CommandDropEntry
|
||||
import com.cobblemon.mod.common.api.drop.DropEntry
|
||||
import com.cobblemon.mod.common.api.drop.EvolutionItemDropEntry
|
||||
import com.cobblemon.mod.common.api.drop.ItemDropEntry
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents.DATA_SYNCHRONIZED
|
||||
@@ -200,6 +201,7 @@ object Cobblemon {
|
||||
|
||||
DropEntry.register("command", CommandDropEntry::class.java)
|
||||
DropEntry.register("item", ItemDropEntry::class.java, isDefault = true)
|
||||
DropEntry.register("evolution", EvolutionItemDropEntry::class.java)
|
||||
|
||||
ExperienceGroups.registerDefaults()
|
||||
CaptureCalculators.registerDefaults()
|
||||
@@ -218,7 +220,7 @@ object Cobblemon {
|
||||
storage.onPlayerDataSync(it)
|
||||
playerDataManager.syncAllToPlayer(it)
|
||||
starterHandler.handleJoin(it)
|
||||
ServerSettingsPacket(this.config.preventCompletePartyDeposit, this.config.displayEntityLevelLabel, this.config.displayEntityNameLabel, this.config.maxPokemonLevel).sendToPlayer(it)
|
||||
ServerSettingsPacket(this.config.preventCompletePartyDeposit, this.config.displayEntityLevelLabel, this.config.displayEntityNameLabel, this.config.maxPokemonLevel, this.config.maxPokemonFriendship, this.config.maxDynamaxLevel).sendToPlayer(it)
|
||||
}
|
||||
PlatformEvents.SERVER_PLAYER_LOGOUT.subscribe {
|
||||
PCLinkManager.removeLink(it.player.uuid)
|
||||
@@ -256,6 +258,8 @@ object Cobblemon {
|
||||
// Lowest priority because this applies after luxury ball bonus as of gen 4
|
||||
CobblemonEvents.FRIENDSHIP_UPDATED.subscribe(Priority.LOWEST) { event ->
|
||||
var increment = (event.newFriendship - event.pokemon.friendship).toFloat()
|
||||
if (increment <= 0) //these affects are only meant to affect positive gains
|
||||
return@subscribe
|
||||
// Our Luxury ball spec is diff from official, but we will still assume these stack
|
||||
if (event.pokemon.heldItemNoCopy().`is`(CobblemonItemTags.IS_FRIENDSHIP_BOOSTER)) {
|
||||
increment += increment * 0.5F
|
||||
|
||||
@@ -15,6 +15,8 @@ object CobblemonActivities {
|
||||
val BATTLING = register(Activity("battling"))
|
||||
val ACTION_EFFECT = register(Activity("action_effect"))
|
||||
val NPC_CHATTING = register(Activity("npc_chatting"))
|
||||
val POKEMON_SLEEPING_ACTIVITY = register(Activity("pokemon_sleeping"))
|
||||
val POKEMON_GROW_CROP = register(Activity("pokemon_grow_crop"))
|
||||
|
||||
fun register(activity: Activity): Activity {
|
||||
activities.add(activity)
|
||||
|
||||
@@ -9,27 +9,35 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.api.ai.BrainPreset
|
||||
import com.cobblemon.mod.common.api.ai.config.BrainConfig
|
||||
import com.cobblemon.mod.common.api.ai.config.task.TaskConfig
|
||||
import com.cobblemon.mod.common.api.data.DataRegistry
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.net.messages.client.data.BrainPresetSyncPacket
|
||||
import com.cobblemon.mod.common.util.adapters.ActivityAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.BrainConfigAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionOrEntityVariableAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.TaskConfigAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.TranslatedTextAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
|
||||
object CobblemonBrainConfigs : JsonDataRegistry<List<BrainConfig>> {
|
||||
object CobblemonBrainConfigs : JsonDataRegistry<BrainPreset> {
|
||||
override val gson: Gson = GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(Activity::class.java, ActivityAdapter)
|
||||
@@ -37,21 +45,27 @@ object CobblemonBrainConfigs : JsonDataRegistry<List<BrainConfig>> {
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(BrainConfig::class.java, BrainConfigAdapter)
|
||||
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
|
||||
.registerTypeAdapter(
|
||||
TypeToken.getParameterized(Either::class.java, Expression::class.java, MoLangConfigVariable::class.java).type,
|
||||
ExpressionOrEntityVariableAdapter
|
||||
)
|
||||
.registerTypeAdapter(Component::class.java, TranslatedTextAdapter)
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.create()
|
||||
|
||||
override val typeToken = TypeToken.getParameterized(List::class.java, BrainConfig::class.java) as TypeToken<List<BrainConfig>>
|
||||
override val typeToken = TypeToken.get(BrainPreset::class.java)
|
||||
override val resourcePath = "brain_presets"
|
||||
override val id: ResourceLocation = cobblemonResource("brain_presets")
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val observable = SimpleObservable<CobblemonBrainConfigs>()
|
||||
|
||||
val presets = mutableMapOf<ResourceLocation, List<BrainConfig>>()
|
||||
val presets = mutableMapOf<ResourceLocation, BrainPreset>()
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
// TODO implement probs ay
|
||||
player.sendPacket(BrainPresetSyncPacket(presets))
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, List<BrainConfig>>) {
|
||||
override fun reload(data: Map<ResourceLocation, BrainPreset>) {
|
||||
presets.clear()
|
||||
presets.putAll(data)
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ object CobblemonCommands {
|
||||
FreezePokemonCommand.register(dispatcher)
|
||||
ApplyPlayerTextureCommand.register(dispatcher)
|
||||
RunMolangScriptCommand.register(dispatcher)
|
||||
BrainEditCommand.register(dispatcher)
|
||||
|
||||
// Possibly lock down registration if and only if under dev environment or running in an environment
|
||||
// with a certain system environment variable set
|
||||
|
||||
@@ -317,6 +317,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
@JvmField val RAZOR_FANG = noSettingsItem("razor_fang")
|
||||
@JvmField val AUSPICIOUS_ARMOR = heldItem("auspicious_armor")
|
||||
@JvmField val MALICIOUS_ARMOR = heldItem("malicious_armor")
|
||||
@JvmField val SHELL_HELMET = heldItem("shell_helmet")
|
||||
|
||||
private val berries = mutableMapOf<ResourceLocation, BerryItem>()
|
||||
// Plants
|
||||
|
||||
@@ -16,14 +16,31 @@ import com.mojang.serialization.codecs.PrimitiveCodec
|
||||
import net.minecraft.core.UUIDUtil
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import java.util.Optional
|
||||
import java.util.UUID
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
object CobblemonMemories {
|
||||
val memories = mutableMapOf<String, MemoryModuleType<*>>()
|
||||
|
||||
/*
|
||||
* When a memory doesn't have a codec provided, it's because it doesn't
|
||||
* get serialized during relogs. This makes sense for things like battles which
|
||||
* do not survive a relog therefore any memory of it should be temporary.
|
||||
*/
|
||||
|
||||
val BATTLING_POKEMON = register("battling_pokemon", ListCodec(UUIDUtil.CODEC, 0, 31))
|
||||
val NPC_BATTLING = register("npc_battling", PrimitiveCodec.BOOL)
|
||||
val DIALOGUES = register<List<ActiveDialogue>>("npc_dialogues")
|
||||
val ACTIVE_ACTION_EFFECT = register<ActionEffectContext>("active_action_effect")
|
||||
val POKEMON_FLYING = register("pokemon_flying", PrimitiveCodec.BOOL)
|
||||
val POKEMON_DROWSY = register("pokemon_drowsy", PrimitiveCodec.BOOL)
|
||||
val POKEMON_SLEEPING = register("pokemon_sleeping", PrimitiveCodec.BOOL)
|
||||
val POKEMON_BATTLE = register<UUID>("pokemon_battle")
|
||||
val REST_PATH_COOLDOWN = register("rest_path_cooldown", PrimitiveCodec.BOOL)
|
||||
val TARGETED_BATTLE_POKEMON = register<UUID>("targeted_battle_pokemon")
|
||||
val NEAREST_VISIBLE_ATTACKER = register<LivingEntity>("nearest_visible_attacker")
|
||||
val NEARBY_GROWABLE_CROPS = register<BlockPos>("nearby_growable_crops")
|
||||
|
||||
fun <U> register(id: String, codec: Codec<U>): MemoryModuleType<U> {
|
||||
val memoryModule = MemoryModuleType(Optional.of(codec))
|
||||
@@ -36,4 +53,4 @@ object CobblemonMemories {
|
||||
memories[id] = memoryModule
|
||||
return memoryModule
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.client.net.OpenBehaviourEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.PlayerInteractOptionsHandler
|
||||
import com.cobblemon.mod.common.client.net.SetClientPlayerDataHandler
|
||||
import com.cobblemon.mod.common.client.net.animation.PlayPosableAnimationHandler
|
||||
@@ -51,8 +52,16 @@ 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.*
|
||||
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.TradeProcessStartedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
|
||||
import com.cobblemon.mod.common.net.PacketRegisterInfo
|
||||
import com.cobblemon.mod.common.net.messages.client.OpenBehaviourEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.SetClientPlayerDataPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.animation.PlayPosableAnimationPacket
|
||||
@@ -93,14 +102,38 @@ import com.cobblemon.mod.common.net.messages.client.storage.party.InitializePart
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.party.MoveClientPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyReferencePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.*
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.ClosePCPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.InitializePCPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.MoveClientPCPokemonPacket
|
||||
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.*
|
||||
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.TradeProcessStartedPacket
|
||||
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.PokedexUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.*
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.*
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengeResponsePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BenchMovePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.RequestMoveSwapPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.RequestPlayerInteractionsPacket
|
||||
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.battle.BattleTeamLeavePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamRequestPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamResponsePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.behaviour.SetEntityBehaviourPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.block.AdjustBlockEntityViewerCountPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectCancelledPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectedPacket
|
||||
@@ -130,9 +163,22 @@ import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePartyPokemonT
|
||||
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.*
|
||||
import com.cobblemon.mod.common.net.serverhandling.*
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.*
|
||||
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.PerformTradePacket
|
||||
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.ChallengeResponseHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.RemoveSpectatorHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamLeaveHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestResponseHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.behaviour.SetEntityBehaviourHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.block.AdjustBlockEntityViewerCountHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectCancelledHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectedHandler
|
||||
@@ -166,7 +212,12 @@ import com.cobblemon.mod.common.net.serverhandling.storage.pc.MovePartyPokemonTo
|
||||
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.*
|
||||
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.PerformTradeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
@@ -304,6 +355,7 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(DexEntrySyncPacket.ID, DexEntrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(FishingBaitRegistrySyncPacket.ID, FishingBaitRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(FlowRegistrySyncPacket.ID, FlowRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(BrainPresetSyncPacket.ID, BrainPresetSyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
|
||||
// Effects
|
||||
list.add(PacketRegisterInfo(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler))
|
||||
@@ -354,6 +406,9 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(CloseNPCEditorPacket.ID, CloseNPCEditorPacket::decode, CloseNPCEditorHandler))
|
||||
list.add(PacketRegisterInfo(OpenNPCEditorPacket.ID, OpenNPCEditorPacket::decode, OpenNPCEditorHandler))
|
||||
|
||||
// Behaviours
|
||||
list.add(PacketRegisterInfo(OpenBehaviourEditorPacket.ID, OpenBehaviourEditorPacket::decode, OpenBehaviourEditorHandler))
|
||||
|
||||
// Pokédex scanning
|
||||
list.add(PacketRegisterInfo(ServerConfirmedRegisterPacket.ID, ServerConfirmedRegisterPacket::decode, ServerConfirmedRegisterHandler))
|
||||
return list
|
||||
@@ -443,6 +498,9 @@ object CobblemonNetwork {
|
||||
// NPC packets
|
||||
list.add(PacketRegisterInfo(SaveNPCPacket.ID, SaveNPCPacket::decode, SaveNPCHandler))
|
||||
|
||||
// Behaviour Packets
|
||||
list.add(PacketRegisterInfo(SetEntityBehaviourPacket.ID, SetEntityBehaviourPacket::decode, SetEntityBehaviourHandler))
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.DefendOwnerSensor
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.DrowsySensor
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.ItemEntitySensor
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.PokemonAdultSensor
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.PokemonGrowableCropSensor
|
||||
import com.cobblemon.mod.common.pokemon.ai.PokemonDisturbancesSensor
|
||||
import com.cobblemon.mod.common.entity.sensor.BattlingPokemonSensor
|
||||
import com.cobblemon.mod.common.entity.sensor.NPCBattlingSensor
|
||||
import java.util.function.Supplier
|
||||
@@ -20,10 +26,22 @@ object CobblemonSensors {
|
||||
|
||||
val NPC_BATTLING = register("npc_battling", ::NPCBattlingSensor)
|
||||
val BATTLING_POKEMON = register("battling_pokemon", ::BattlingPokemonSensor)
|
||||
// val NPC_BATTLING = register("npc_battling", ::NPCBattlingSensor)
|
||||
val POKEMON_DROWSY = register("pokemon_drowsy", ::DrowsySensor)
|
||||
|
||||
val POKEMON_ADULT = register("pokemon_adult_sensor", ::PokemonAdultSensor)
|
||||
|
||||
val POKEMON_DISTURBANCE = register("pokemon_disturbance_sensor", ::PokemonDisturbancesSensor)
|
||||
|
||||
val POKEMON_DEFEND_OWNER = register("pokemon_owner_under_attack", ::DefendOwnerSensor)
|
||||
|
||||
val NEARBY_GROWABLE_CROPS = register("nearby_growable_crops", ::PokemonGrowableCropSensor)
|
||||
|
||||
val ITEM_SENSOR = register("item_sensor", ::ItemEntitySensor)
|
||||
|
||||
fun <E : Entity, U : Sensor<E>> register(id: String, supplier: Supplier<U>): SensorType<U> {
|
||||
val sensor = SensorType(supplier)
|
||||
sensors[id] = sensor
|
||||
return sensor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
package com.cobblemon.mod.common.api.ai
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.config.BrainConfig
|
||||
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
import net.minecraft.world.entity.schedule.Schedule
|
||||
|
||||
class BrainConfigurationContext {
|
||||
var appliedBrainPresets: MutableSet<ResourceLocation> = mutableSetOf()
|
||||
|
||||
var defaultActivity = Activity.IDLE
|
||||
var coreActivities = setOf(Activity.CORE)
|
||||
@@ -27,6 +30,11 @@ class BrainConfigurationContext {
|
||||
fun apply(entity: LivingEntity, brainConfigs: List<BrainConfig>) {
|
||||
val brain = entity.brain
|
||||
|
||||
if (entity is MoLangScriptingEntity) {
|
||||
entity.registerVariables(brainConfigs.flatMap { it.getVariables(entity) })
|
||||
entity.initializeScripting()
|
||||
}
|
||||
|
||||
// Setup the brain config
|
||||
brainConfigs.forEach { it.configure(entity, this) }
|
||||
|
||||
|
||||
@@ -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.ai
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.config.BrainConfig
|
||||
import com.cobblemon.mod.common.util.asTranslated
|
||||
import com.cobblemon.mod.common.util.entityTypeRegistry
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class BrainPreset(
|
||||
val name: Component = "dummy".asTranslated(),
|
||||
val description: Component = "".asTranslated(),
|
||||
val entityType: ResourceLocation? = null,
|
||||
val configurations: List<BrainConfig> = mutableListOf()
|
||||
) {
|
||||
fun canBeApplied(entity: LivingEntity) = entityType?.let { entity.type == entity.level().entityTypeRegistry.get(it) } != false
|
||||
}
|
||||
@@ -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.ai
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.mojang.datafixers.util.Either
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
typealias ExpressionOrEntityVariable = Either<Expression, MoLangConfigVariable>
|
||||
|
||||
fun List<ExpressionOrEntityVariable>.asVariables() = mapNotNull { it.right().getOrNull() }
|
||||
|
||||
|
||||
@@ -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.api.ai
|
||||
|
||||
/**
|
||||
* The medium that an entity might be in which motivates what type of wandering it should do.
|
||||
*
|
||||
* If you've discovered this in main and it's not being used outside of that unused extension function, delete me
|
||||
*
|
||||
* @author Hiroku
|
||||
* @since January 25th, 2025
|
||||
*/
|
||||
enum class PathfindingMedium {
|
||||
LAND,
|
||||
WATER,
|
||||
LAVA,
|
||||
AIR
|
||||
}
|
||||
+7
-11
@@ -8,27 +8,23 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.ai.config.task.TaskConfig
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
|
||||
class AddTasksToActivity : BrainConfig {
|
||||
val activity = Activity.IDLE
|
||||
val condition = "true".asExpressionLike()
|
||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||
val tasksByPriority = mutableMapOf<Int, List<TaskConfig>>()
|
||||
override fun getVariables(entity: LivingEntity) = tasksByPriority.values.flatten().flatMap { it.getVariables(entity) } + listOf(condition).asVariables()
|
||||
|
||||
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
|
||||
val runtime = MoLangRuntime().setup()
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return
|
||||
if (!checkCondition(entity, condition)) return
|
||||
|
||||
val activity = brainConfigurationContext.getOrCreateActivity(activity)
|
||||
tasksByPriority.forEach { (priority, taskConfigs) ->
|
||||
|
||||
+6
-1
@@ -9,8 +9,13 @@
|
||||
package com.cobblemon.mod.common.api.ai.config
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
object DummyBrainConfig : BrainConfig {
|
||||
class AddVariablesConfig : BrainConfig {
|
||||
override fun getVariables(entity: LivingEntity) = mutableListOf<MoLangConfigVariable>()
|
||||
|
||||
// Configuration happens naturally through the override on variables
|
||||
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {}
|
||||
}
|
||||
@@ -8,28 +8,42 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonBrainConfigs
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class ApplyPresets : BrainConfig {
|
||||
val condition = "true".asExpressionLike()
|
||||
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||
val presets = mutableListOf<ResourceLocation>()
|
||||
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
|
||||
val runtime = MoLangRuntime().setup()
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return
|
||||
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
||||
return if (checkCondition(entity, condition)) {
|
||||
presets.flatMap {
|
||||
CobblemonBrainConfigs.presets[it]?.configurations?.flatMap { it.getVariables(entity) } ?: emptyList()
|
||||
} + listOf(condition).asVariables()
|
||||
} else {
|
||||
listOf(condition).asVariables()
|
||||
}
|
||||
}
|
||||
|
||||
val presetConfigs = presets.flatMap { CobblemonBrainConfigs.presets[it] ?: return Cobblemon.LOGGER.warn("Preset $it not found") }
|
||||
presetConfigs.forEach { it.configure(entity, brainConfigurationContext) }
|
||||
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
|
||||
if (!checkCondition(entity, condition)) return
|
||||
|
||||
val presetConfigs = presets.flatMap { CobblemonBrainConfigs.presets[it]?.takeIf { it.canBeApplied(entity) }?.configurations ?: return Cobblemon.LOGGER.warn("Preset $it not found") }
|
||||
// Why not just add the presets to the context directly?
|
||||
// Nested preset application is a thing, and I only want to track the top level presets.
|
||||
// i.e. if a preset applies another preset, I don't want to track the inner preset, since it's redundant if we track the top one.
|
||||
val originalContextPresets = brainConfigurationContext.appliedBrainPresets.toMutableSet()
|
||||
presetConfigs.forEach {
|
||||
it.configure(entity, brainConfigurationContext)
|
||||
}
|
||||
originalContextPresets.addAll(presets)
|
||||
brainConfigurationContext.appliedBrainPresets = originalContextPresets
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,15 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
/**
|
||||
@@ -30,12 +38,21 @@ interface BrainConfig {
|
||||
"add_tasks_to_activity" to AddTasksToActivity::class.java,
|
||||
"apply_presets" to ApplyPresets::class.java,
|
||||
"set_default_activity" to SetDefaultActivity::class.java,
|
||||
"set_core_activities" to SetCoreActivities::class.java
|
||||
"set_core_activities" to SetCoreActivities::class.java,
|
||||
"add_variables" to AddVariablesConfig::class.java,
|
||||
"set_variables" to SetVariablesConfig::class.java,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
fun checkCondition(entity: LivingEntity, expressionOrEntityVariable: ExpressionOrEntityVariable): Boolean {
|
||||
val runtime = MoLangRuntime().setup()
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
return runtime.resolveBoolean(expressionOrEntityVariable.map({ it }, { "q.entity.config.${it.variableName}".asExpression() }))
|
||||
}
|
||||
|
||||
// fun encode(buffer: RegistryFriendlyByteBuf)
|
||||
// fun decode(buffer: RegistryFriendlyByteBuf)
|
||||
fun getVariables(entity: LivingEntity): List<MoLangConfigVariable>
|
||||
fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext)
|
||||
}
|
||||
|
||||
@@ -117,3 +117,49 @@ Example brain preset (`uses_healing_machine.json`):
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### add_variables
|
||||
The `add_variables` type adds some number of MoLang variables to the entity that can be configured in-game or left with defaults.
|
||||
- `variables`: A list of objects, each representing a variable that can be configured.
|
||||
|
||||
Each variable has the following properties:
|
||||
- `variableName`: The name of the variable. This is the name that will be accessible from MoLang scripts.
|
||||
- `defaultValue`: The default value of the variable. This is a MoLang expression that will be used if the variable is not set.
|
||||
- `displayName`: The display name of the variable. This is used in the UI to label the variable. This can be a translation key.
|
||||
- `description`: A description of the variable. This is used in the UI to describe what the variable does. This can be a translation key.
|
||||
- `type`: The type of the variable. This can be `TEXT`, `NUMBER`, or `BOOLEAN`.
|
||||
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"type": "add_variables",
|
||||
"variables": [
|
||||
{
|
||||
"variableName": "can_heal_using_machine",
|
||||
"defaultValue": "false",
|
||||
"displayName": "Can Use Healing Machine",
|
||||
"description": "Whether or not the entity can use a healing machine.",
|
||||
"type": "BOOLEAN"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### set_variables
|
||||
The `set_variables` type sets some values for pre-established variables. This is useful in cases where a preset has defined a variable
|
||||
but it's locked in by a specific entity using that preset. This strongly forces the variable to a specific value. In future this
|
||||
probably should deregister the variable so that the client cannot edit them once they've been forced, as currently that will
|
||||
be possible yet the value will get repeatedly overwritten.
|
||||
|
||||
The values inside the variables map can be MoLang expressions (with `q.entity` as the entity) or simple JSON primitives.
|
||||
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"type": "set_variables",
|
||||
"variables": {
|
||||
"aggressive": true,
|
||||
"attack_range": "10"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -15,8 +15,10 @@ import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.ai.ActivityConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.activityRegistry
|
||||
@@ -33,10 +35,11 @@ import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
class ScriptBrainConfig : BrainConfig {
|
||||
val condition = "true".asExpressionLike()
|
||||
val script = cobblemonResource("dummy")
|
||||
override fun getVariables(entity: LivingEntity) = mutableListOf<MoLangConfigVariable>()
|
||||
|
||||
override fun configure(entity: LivingEntity, context: BrainConfigurationContext) {
|
||||
val runtime = MoLangRuntime().setup()
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!runtime.resolveBoolean(condition)) return
|
||||
|
||||
val struct = createBrainStruct(entity, context)
|
||||
@@ -50,7 +53,7 @@ class ScriptBrainConfig : BrainConfig {
|
||||
|
||||
fun createBrainStruct(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): QueryStruct {
|
||||
return QueryStruct(hashMapOf()).addStandardFunctions()
|
||||
.addFunction("entity") { (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()) }
|
||||
.addFunction("entity") { entity.asMostSpecificMoLangValue() }
|
||||
.addFunction("create_activity") { params ->
|
||||
val name = params.getString(0).asIdentifierDefaultingNamespace()
|
||||
val activity = entity.level().activityRegistry.get(name) ?: return@addFunction run {
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
package com.cobblemon.mod.common.api.ai.config
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
|
||||
class SetCoreActivities : BrainConfig {
|
||||
val activities = mutableListOf<Activity>()
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
|
||||
brainConfigurationContext.coreActivities = activities.toSet()
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
package com.cobblemon.mod.common.api.ai.config
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
|
||||
class SetDefaultActivity : BrainConfig {
|
||||
val activity: Activity = Activity.IDLE
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
|
||||
brainConfigurationContext.defaultActivity = activity
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||
import com.cobblemon.mod.common.util.resolve
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class SetVariablesConfig : BrainConfig {
|
||||
var variableValues = mutableMapOf<String, ExpressionLike>()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
|
||||
override fun configure(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext) {
|
||||
val runtime = MoLangRuntime().setup()
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (entity is MoLangScriptingEntity) {
|
||||
variableValues.forEach { (variableName, valueExpression) ->
|
||||
entity.config.setDirectly(variableName, runtime.resolve(valueExpression))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.ai.config.task.WanderTaskConfig.Companion.WANDER
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.ai.memory.WalkTarget
|
||||
import net.minecraft.world.entity.ai.util.HoverRandomPos
|
||||
|
||||
class AirWanderTaskConfig : SingleTaskConfig {
|
||||
val condition = booleanVariable(WANDER, "air_wanders", true).asExpressible()
|
||||
val wanderChance = numberVariable(WANDER, "air_wander_chance", 1/(20 * 1F)).asExpressible()
|
||||
val horizontalRange = numberVariable(WANDER, "horizontal_wander_range", 20).asExpressible()
|
||||
val verticalRange = numberVariable(WANDER, "vertical_wander_range", 5).asExpressible()
|
||||
val speedMultiplier = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, SharedEntityVariables.WALK_SPEED, 0.35).asExpressible()
|
||||
val minUpwardsMovement: ExpressionOrEntityVariable = Either.left("3.0".asExpression())
|
||||
val minDownwardsMovement: ExpressionOrEntityVariable = Either.left("3.0".asExpression())
|
||||
|
||||
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
||||
return listOf(condition, wanderChance, horizontalRange, verticalRange, speedMultiplier, minUpwardsMovement, minDownwardsMovement).asVariables()
|
||||
}
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
|
||||
return BehaviorBuilder.create {
|
||||
it.group(
|
||||
it.absent(MemoryModuleType.WALK_TARGET),
|
||||
it.registered(MemoryModuleType.LOOK_TARGET)
|
||||
).apply(it) { walkTarget, lookTarget ->
|
||||
Trigger { world, entity, time ->
|
||||
if (entity !is PathfinderMob || entity.isInWater) {
|
||||
return@Trigger false
|
||||
}
|
||||
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
val wanderChance = wanderChance.resolveFloat()
|
||||
if (wanderChance <= 0 || world.random.nextFloat() > wanderChance) return@Trigger false
|
||||
|
||||
val rotVec = entity.getViewVector(0F)
|
||||
val target = HoverRandomPos.getPos(entity, horizontalRange.resolveInt(), verticalRange.resolveInt(), rotVec.x, rotVec.y, 1.5707964f, minUpwardsMovement.resolveInt(), minDownwardsMovement.resolveInt())
|
||||
?: return@Trigger false
|
||||
walkTarget.set(WalkTarget(target, speedMultiplier.resolveFloat(), 3))
|
||||
lookTarget.set(BlockPosTracker(target))
|
||||
return@Trigger true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-5
@@ -8,25 +8,36 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class AllOfTaskConfig : TaskConfig {
|
||||
val condition = "true".asExpressionLike()
|
||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||
val tasks: List<TaskConfig> = emptyList()
|
||||
|
||||
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
||||
return if (checkCondition(entity, condition))
|
||||
tasks.flatMap { it.getVariables(entity) } + listOf(condition).asVariables()
|
||||
else
|
||||
listOf(condition).asVariables()
|
||||
}
|
||||
|
||||
override fun createTasks(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): List<BehaviorControl<in LivingEntity>> {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return emptyList()
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return emptyList()
|
||||
return tasks.flatMap { it.createTasks(entity, brainConfigurationContext) }
|
||||
}
|
||||
}
|
||||
+8
-5
@@ -8,9 +8,10 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.ai.AttackAngryAtTask
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
@@ -19,13 +20,15 @@ import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class AttackAngryAtTaskConfig : SingleTaskConfig {
|
||||
val condition = "true".asExpressionLike()
|
||||
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "should_attack_angry_at", true).asExpressible()
|
||||
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return AttackAngryAtTask.create()
|
||||
}
|
||||
}
|
||||
+9
-5
@@ -8,24 +8,28 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.VillagerCalmDown
|
||||
|
||||
class CalmDownTaskConfig : SingleTaskConfig {
|
||||
var condition = "true".asExpression()
|
||||
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return VillagerCalmDown.create()
|
||||
}
|
||||
}
|
||||
+12
-8
@@ -8,30 +8,34 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.DoNothing
|
||||
|
||||
class DoNothingTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val minDurationTicks = "40".asExpression()
|
||||
val maxDurationTicks = "80".asExpression()
|
||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||
val minDurationTicks: ExpressionOrEntityVariable = Either.left("40".asExpression())
|
||||
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("80".asExpression())
|
||||
override fun getVariables(entity: LivingEntity) = listOf(condition, minDurationTicks, maxDurationTicks).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
return DoNothing(runtime.resolveInt(minDurationTicks), runtime.resolveInt(maxDurationTicks))
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return DoNothing(minDurationTicks.resolveInt(), maxDurationTicks.resolveInt())
|
||||
}
|
||||
}
|
||||
+20
-12
@@ -8,14 +8,14 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.battles.BattleRegistry
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.entity.npc.NPCEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
@@ -24,15 +24,21 @@ import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
|
||||
class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
|
||||
var condition = "true".asExpression()
|
||||
var includePassiveDamage = true
|
||||
var condition = booleanVariable(SharedEntityVariables.BATTLING_CATEGORY, "exit_battle_when_hurt", true).asExpressible()
|
||||
var includePassiveDamage = booleanVariable(SharedEntityVariables.BATTLING_CATEGORY, "exit_battle_from_passive_damage", true).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
includePassiveDamage
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
val includePassiveDamage = includePassiveDamage.resolveBoolean()
|
||||
if (!condition.resolveBoolean()) return null
|
||||
|
||||
if (entity is NPCEntity) {
|
||||
fun cancelNPCBattles(npcEntity: NPCEntity): Boolean {
|
||||
@@ -52,7 +58,7 @@ class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
|
||||
.apply(it) { _, _ -> Trigger { world, entity, _ -> return@Trigger cancelNPCBattles(entity as NPCEntity) } }
|
||||
}
|
||||
}
|
||||
} else { return null }/* else if (entity is PokemonEntity) { TODO uncomment when pokemon have brain :)
|
||||
} else if (entity is PokemonEntity) {
|
||||
fun cancelPokemonBattle(pokemonEntity: PokemonEntity): Boolean {
|
||||
val battle = BattleRegistry.getBattle(pokemonEntity.battleId ?: return false)
|
||||
battle?.end()
|
||||
@@ -61,15 +67,17 @@ class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
|
||||
|
||||
return if (includePassiveDamage) {
|
||||
BehaviorBuilder.create {
|
||||
it.group(it.present(MemoryModuleType.HURT_BY), it.present(CobblemonMemories.POKEMON_BATTLING))
|
||||
it.group(it.present(MemoryModuleType.HURT_BY), it.present(CobblemonMemories.POKEMON_BATTLE))
|
||||
.apply(it) { _, _ -> Trigger { world, entity, _ -> return@Trigger cancelPokemonBattle(entity as PokemonEntity) } }
|
||||
}
|
||||
} else {
|
||||
BehaviorBuilder.create {
|
||||
it.group(it.present(MemoryModuleType.HURT_BY_ENTITY), it.present(CobblemonMemories.POKEMON_BATTLING))
|
||||
it.group(it.present(MemoryModuleType.HURT_BY_ENTITY), it.present(CobblemonMemories.POKEMON_BATTLE))
|
||||
.apply(it) { _, _ -> Trigger { world, entity, _ -> return@Trigger cancelPokemonBattle(entity as PokemonEntity) } }
|
||||
}
|
||||
}
|
||||
}*/
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.FindRestingPlaceTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class FindRestingPlaceTaskConfig : SingleTaskConfig {
|
||||
val horizontalSearchDistance: ExpressionOrEntityVariable = Either.left("16".asExpression())
|
||||
val verticalSearchDistance: ExpressionOrEntityVariable = Either.left("5".asExpression())
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(horizontalSearchDistance, verticalSearchDistance).asVariables()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
return WrapperLivingEntityTask(
|
||||
FindRestingPlaceTask.create(horizontalSearchDistance.resolveInt(), verticalSearchDistance.resolveInt()),
|
||||
PokemonEntity::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
+17
-13
@@ -8,14 +8,12 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.FLEE_DESIRED_DISTANCE
|
||||
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.FLEE_SPEED_MULTIPLIER
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
@@ -24,18 +22,24 @@ import net.minecraft.world.entity.ai.behavior.SetWalkTargetAwayFrom
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
|
||||
class FleeAttackerTaskConfig : SingleTaskConfig {
|
||||
var condition = "true".asExpression()
|
||||
var speedMultiplier = "0.5".asExpression()
|
||||
var desiredDistance = "9".asExpression()
|
||||
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "flee_attacker", true).asExpressible()
|
||||
var speedMultiplier = numberVariable(SharedEntityVariables.FEAR_CATEGORY, FLEE_SPEED_MULTIPLIER, 0.5).asExpressible()
|
||||
var desiredDistance = numberVariable(SharedEntityVariables.FEAR_CATEGORY, FLEE_DESIRED_DISTANCE, 9).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
speedMultiplier,
|
||||
desiredDistance
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition) || entity !is PathfinderMob) return null
|
||||
val speedMultiplier = runtime.resolveFloat(speedMultiplier)
|
||||
val desiredDistance = runtime.resolveInt(desiredDistance)
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean() || entity !is PathfinderMob) return null
|
||||
val speedMultiplier = speedMultiplier.resolveFloat()
|
||||
val desiredDistance = desiredDistance.resolveInt()
|
||||
return WrapperLivingEntityTask(
|
||||
SetWalkTargetAwayFrom.entity(MemoryModuleType.HURT_BY_ENTITY, speedMultiplier, desiredDistance, false),
|
||||
PathfinderMob::class.java
|
||||
|
||||
+14
-13
@@ -8,14 +8,13 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.FLEE_DESIRED_DISTANCE
|
||||
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.FLEE_SPEED_MULTIPLIER
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
@@ -24,18 +23,20 @@ import net.minecraft.world.entity.ai.behavior.SetWalkTargetAwayFrom
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
|
||||
class FleeNearestHostileTaskConfig : SingleTaskConfig {
|
||||
var condition = "true".asExpression()
|
||||
var speedMultiplier = "0.5".asExpression()
|
||||
var desiredDistance = "9".asExpression()
|
||||
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "flee_nearest_hostile", true).asExpressible()
|
||||
var speedMultiplier = numberVariable(SharedEntityVariables.FEAR_CATEGORY, FLEE_SPEED_MULTIPLIER, 0.5).asExpressible()
|
||||
var desiredDistance = numberVariable(SharedEntityVariables.FEAR_CATEGORY, FLEE_DESIRED_DISTANCE, 9).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(condition, speedMultiplier, desiredDistance).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition) || entity !is PathfinderMob) return null
|
||||
val speedMultiplier = runtime.resolveFloat(speedMultiplier)
|
||||
val desiredDistance = runtime.resolveInt(desiredDistance)
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean() || entity !is PathfinderMob) return null
|
||||
val speedMultiplier = speedMultiplier.resolveFloat()
|
||||
val desiredDistance = desiredDistance.resolveInt()
|
||||
return WrapperLivingEntityTask(
|
||||
SetWalkTargetAwayFrom.entity(MemoryModuleType.NEAREST_HOSTILE, speedMultiplier, desiredDistance, false),
|
||||
PathfinderMob::class.java
|
||||
|
||||
+12
-13
@@ -8,32 +8,31 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.ai.FollowWalkTargetTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class FollowWalkTargetTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val minRunTicks: Expression = "150".asExpression()
|
||||
val maxRunTicks: Expression = "250".asExpression()
|
||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||
val minRunTicks: ExpressionOrEntityVariable = Either.left("150".asExpression())
|
||||
val maxRunTicks: ExpressionOrEntityVariable = Either.left("250".asExpression())
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(minRunTicks, maxRunTicks).asVariables()
|
||||
|
||||
override fun createTask(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): BehaviorControl<LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
return WrapperLivingEntityTask(
|
||||
FollowWalkTargetTask(runtime.resolveInt(minRunTicks), runtime.resolveInt(maxRunTicks)),
|
||||
FollowWalkTargetTask(minRunTicks.resolveInt(), maxRunTicks.resolveInt()),
|
||||
PathfinderMob::class.java
|
||||
)
|
||||
}
|
||||
|
||||
+12
-8
@@ -8,26 +8,30 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.ATTACKING_CATEGORY
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.entity.ai.GetAngryAtAttackerTask
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class GetAngryAtAttackerTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
companion object {
|
||||
const val GET_ANGRY_AT_ATTACKER = "get_angry_at_attacker"
|
||||
}
|
||||
|
||||
val condition = booleanVariable(ATTACKING_CATEGORY, GET_ANGRY_AT_ATTACKER, true).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return GetAngryAtAttackerTask.create()
|
||||
}
|
||||
}
|
||||
+24
-19
@@ -8,38 +8,43 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.entity.npc.ai.GoToHealingMachineTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class GoToHealingMachineTaskConfig(
|
||||
val condition: ExpressionLike = "true".asExpressionLike(),
|
||||
val horizontalSearchRange: Expression = "10".asExpression(),
|
||||
val verticalSearchRange: Expression = "5".asExpression(),
|
||||
val speedMultiplier: Expression = "0.35".asExpression(),
|
||||
val completionRange: Expression = "1".asExpression()
|
||||
) : SingleTaskConfig {
|
||||
class GoToHealingMachineTaskConfig : SingleTaskConfig {
|
||||
val condition = booleanVariable(SELF_HEALING, USE_HEALING_MACHINES, true).asExpressible()
|
||||
val horizontalSearchRange: ExpressionOrEntityVariable = Either.left("10".asExpression())
|
||||
val verticalSearchRange: ExpressionOrEntityVariable = Either.left("5".asExpression())
|
||||
val completionRange: ExpressionOrEntityVariable = Either.left("1".asExpression())
|
||||
val walkSpeed = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, SharedEntityVariables.WALK_SPEED, 0.35).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(condition, walkSpeed, horizontalSearchRange, verticalSearchRange, completionRange).asVariables()
|
||||
|
||||
companion object {
|
||||
const val SELF_HEALING = "self_healing"
|
||||
const val USE_HEALING_MACHINES = "use_healing_machines"
|
||||
}
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
|
||||
return GoToHealingMachineTask.create(
|
||||
horizontalSearchRange = horizontalSearchRange,
|
||||
verticalSearchRange = verticalSearchRange,
|
||||
speedMultiplier = speedMultiplier,
|
||||
completionRange = completionRange
|
||||
horizontalSearchRange = horizontalSearchRange.asExpression(),
|
||||
verticalSearchRange = verticalSearchRange.asExpression(),
|
||||
speedMultiplier = walkSpeed.asExpression(),
|
||||
completionRange = completionRange.asExpression()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.GoToSleepTask
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class GoToSleepTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
return WrapperLivingEntityTask(GoToSleepTask.create(), PokemonEntity::class.java)
|
||||
}
|
||||
}
|
||||
+15
-11
@@ -8,29 +8,33 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.ai.config.task.GoToHealingMachineTaskConfig.Companion.SELF_HEALING
|
||||
import com.cobblemon.mod.common.api.ai.config.task.GoToHealingMachineTaskConfig.Companion.USE_HEALING_MACHINES
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.npc.ai.HealUsingHealingMachineTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class HealUsingHealingMachineTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val horizontalUseRange = "3".asExpression()
|
||||
val verticalUseRange = "2".asExpression()
|
||||
val condition = booleanVariable(SELF_HEALING, USE_HEALING_MACHINES, true).asExpressible()
|
||||
val horizontalUseRange: ExpressionOrEntityVariable = Either.left("2".asExpression())
|
||||
val verticalUseRange: ExpressionOrEntityVariable = Either.left("1".asExpression())
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(condition, horizontalUseRange, verticalUseRange).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
return HealUsingHealingMachineTask(horizontalUseRange, verticalUseRange)
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return HealUsingHealingMachineTask(horizontalUseRange.asExpression(), verticalUseRange.asExpression())
|
||||
}
|
||||
}
|
||||
+21
-9
@@ -8,29 +8,41 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.entity.npc.ai.LookAtBattlingPokemonTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class LookAtBattlingPokemonTaskConfig : SingleTaskConfig {
|
||||
val minDurationTicks = "40".asExpression()
|
||||
val maxDurationTicks = "80".asExpression()
|
||||
companion object {
|
||||
const val LOOK_AT_BATTLING_POKEMON = "look_at_battling_pokemon"
|
||||
}
|
||||
|
||||
val condition = booleanVariable(SharedEntityVariables.BATTLING_CATEGORY, LOOK_AT_BATTLING_POKEMON, true).asExpressible()
|
||||
val minDurationTicks: ExpressionOrEntityVariable = Either.left("40".asExpression())
|
||||
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("80".asExpression())
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
minDurationTicks,
|
||||
maxDurationTicks
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!resolveBooleanVariable(LOOK_AT_BATTLING_POKEMON)) return null
|
||||
return LookAtBattlingPokemonTask.create(
|
||||
minDurationTicks = runtime.resolveInt(minDurationTicks),
|
||||
maxDurationTicks = runtime.resolveInt(maxDurationTicks)
|
||||
minDurationTicks = minDurationTicks.resolveInt(),
|
||||
maxDurationTicks = maxDurationTicks.resolveInt()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
+18
-12
@@ -8,29 +8,35 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.SEE_DISTANCE
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget
|
||||
|
||||
class LookAtEntitiesTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val maxDistance = "15".asExpression()
|
||||
companion object {
|
||||
const val LOOK_AT_ENTITIES = "look_at_entities"
|
||||
}
|
||||
|
||||
val condition = booleanVariable(SharedEntityVariables.LOOKING_CATEGORY, LOOK_AT_ENTITIES, true).asExpressible()
|
||||
val maxDistance = numberVariable(SharedEntityVariables.LOOKING_CATEGORY, SEE_DISTANCE, 15).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
maxDistance
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
return SetEntityLookTarget.create(runtime.resolveFloat(maxDistance))
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return SetEntityLookTarget.create(maxDistance.resolveFloat())
|
||||
}
|
||||
}
|
||||
+2
@@ -9,10 +9,12 @@
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.npc.ai.LookAtSpeakerTask
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class LookAtSpeakerTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
|
||||
+17
-13
@@ -8,33 +8,37 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.Mob
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.LookAtTargetSink
|
||||
|
||||
class LookAtTargetTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val minDurationTicks: Expression = "40".asExpression()
|
||||
val maxDurationTicks: Expression = "80".asExpression()
|
||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||
val minDurationTicks: ExpressionOrEntityVariable = Either.left("80".asExpression())
|
||||
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("160".asExpression())
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
minDurationTicks,
|
||||
maxDurationTicks
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
return WrapperLivingEntityTask(LookAtTargetSink(runtime.resolveInt(minDurationTicks), runtime.resolveInt(maxDurationTicks)), Mob::class.java)
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return WrapperLivingEntityTask(LookAtTargetSink(minDurationTicks.resolveInt(), maxDurationTicks.resolveInt()), Mob::class.java)
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.LookAtTargetedBattlePokemonTask
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class LookAtTargetedBattlePokemonTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity> {
|
||||
return WrapperLivingEntityTask(LookAtTargetedBattlePokemonTask.create(), PokemonEntity::class.java)
|
||||
}
|
||||
}
|
||||
+16
-5
@@ -8,18 +8,29 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.LOOKING_CATEGORY
|
||||
import com.cobblemon.mod.common.entity.ai.LookInDirectionTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class LookInDirectionTaskConfig : SingleTaskConfig {
|
||||
var yaw: Expression = "0".asExpression()
|
||||
var pitch: Expression = "0".asExpression()
|
||||
var condition = booleanVariable(LOOKING_CATEGORY, "locked_rotation", true).asExpressible()
|
||||
var yaw = numberVariable(LOOKING_CATEGORY, "locked_yaw", 0F).asExpressible()
|
||||
var pitch = numberVariable(LOOKING_CATEGORY, "locked_pitch", 0F).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
yaw,
|
||||
pitch
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
) = LookInDirectionTask(yaw, pitch)
|
||||
) = LookInDirectionTask(
|
||||
shouldLock = condition.asExpression(),
|
||||
yaw = yaw.asExpression(),
|
||||
pitch = pitch.asExpression()
|
||||
)
|
||||
}
|
||||
+16
-12
@@ -8,32 +8,36 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.npc.ai.MeleeAttackTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class MeleeAttackTaskConfig : SingleTaskConfig {
|
||||
val condition = "true".asExpressionLike()
|
||||
val range = "1.5".asExpression()
|
||||
val cooldownTicks = "30".asExpression()
|
||||
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "attacks_melee", true).asExpressible()
|
||||
val range = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_range", 1.5F).asExpressible()
|
||||
val cooldownTicks = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_cooldown", 30).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
range,
|
||||
cooldownTicks
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
|
||||
return MeleeAttackTask.create(
|
||||
range = range,
|
||||
cooldownTicks = cooldownTicks
|
||||
range = range.asExpression(),
|
||||
cooldownTicks = cooldownTicks.asExpression()
|
||||
)
|
||||
}
|
||||
}
|
||||
+13
-4
@@ -9,19 +9,28 @@
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.ai.MoveToAttackTargetTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class MoveToAttackTargetTaskConfig : SingleTaskConfig {
|
||||
val speedMultiplier = "0.5".asExpression()
|
||||
val closeEnoughDistance = "1".asExpression()
|
||||
val speedMultiplier = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "attacking_movement_speed", 0.5).asExpressible()
|
||||
val closeEnoughDistance: ExpressionOrEntityVariable = Either.left("1".asExpression())
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
speedMultiplier,
|
||||
closeEnoughDistance
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
) = MoveToAttackTargetTask.create(
|
||||
speedMultiplier = speedMultiplier,
|
||||
closeEnoughDistance = closeEnoughDistance
|
||||
speedMultiplier = speedMultiplier.asExpression(),
|
||||
closeEnoughDistance = closeEnoughDistance.asExpression()
|
||||
)
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.ai.FollowWalkTargetTask
|
||||
import com.cobblemon.mod.common.entity.ai.MoveToAttackTargetTask
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.MoveToItemAndEatTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class MoveToItemAndEatTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
|
||||
override fun createTask(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): BehaviorControl<LivingEntity>? {
|
||||
return WrapperLivingEntityTask(
|
||||
MoveToItemAndEatTask(),
|
||||
PokemonEntity::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.MoveToOwnerTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class MoveToOwnerTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||
var completionRange: ExpressionOrEntityVariable = Either.left("4.0".asExpression())
|
||||
var speedMultiplier: ExpressionOrEntityVariable = Either.left("0.4".asExpression())
|
||||
var teleportDistance: ExpressionOrEntityVariable = Either.left("24.0".asExpression())
|
||||
var maxDistance: ExpressionOrEntityVariable = Either.left("14.0".asExpression())
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
completionRange,
|
||||
speedMultiplier,
|
||||
teleportDistance,
|
||||
maxDistance
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
return WrapperLivingEntityTask(
|
||||
MoveToOwnerTask.create(
|
||||
condition = condition.asExpression(),
|
||||
completionRange = completionRange.asExpression(),
|
||||
speedMultiplier = speedMultiplier.asExpression(),
|
||||
teleportDistance = teleportDistance.asExpression(),
|
||||
maxDistance = maxDistance.asExpression()
|
||||
),
|
||||
PokemonEntity::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -11,6 +11,8 @@ package com.cobblemon.mod.common.api.ai.config.task
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
@@ -34,14 +36,16 @@ import net.minecraft.world.entity.ai.behavior.RunOne
|
||||
class OneOfTaskConfig : SingleTaskConfig {
|
||||
class OneOfTaskOption {
|
||||
val weight: Int = 1
|
||||
val task: TaskConfig = SingleTaskConfig { _, _ -> DoNothing(0, 1) }
|
||||
val task: TaskConfig = SingleTaskConfig.nothing()
|
||||
}
|
||||
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val options = mutableListOf<OneOfTaskOption>()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = options.flatMap { it.task.getVariables(entity) }
|
||||
|
||||
override fun createTask(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
return RunOne(options.map { it.task.createTasks(entity, brainConfigurationContext).first() toDF it.weight })
|
||||
}
|
||||
|
||||
+6
-2
@@ -11,6 +11,8 @@ package com.cobblemon.mod.common.api.ai.config.task
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
@@ -34,17 +36,19 @@ import net.minecraft.world.entity.ai.behavior.DoNothing
|
||||
class RandomTaskConfig : TaskConfig {
|
||||
class RandomTaskChoice {
|
||||
val weight = 1.0
|
||||
val task: TaskConfig = SingleTaskConfig { _, _ -> DoNothing(0, 1) }
|
||||
val task: TaskConfig = SingleTaskConfig.nothing()
|
||||
}
|
||||
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val choices = mutableListOf<RandomTaskChoice>()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = choices.flatMap { it.task.getVariables(entity) }
|
||||
|
||||
override fun createTasks(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): List<BehaviorControl<in LivingEntity>> {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!runtime.resolveBoolean(condition)) return emptyList()
|
||||
val task = choices.weightedSelection { it.weight }?.task ?: throw IllegalStateException("No tasks to choose from in random_task config")
|
||||
return task.createTasks(entity, brainConfigurationContext)
|
||||
|
||||
@@ -10,10 +10,10 @@ package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
@@ -31,7 +31,13 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
* @since December 2nd, 2024
|
||||
*/
|
||||
class RunScript : SingleTaskConfig {
|
||||
val script = cobblemonResource("dummy")
|
||||
companion object {
|
||||
const val SCRIPT_CATEGORY = "script"
|
||||
}
|
||||
|
||||
val script = stringVariable(SCRIPT_CATEGORY, "script", "cobblemon:dummy_script").asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(script).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
@@ -41,8 +47,8 @@ class RunScript : SingleTaskConfig {
|
||||
it.registered(MemoryModuleType.LOOK_TARGET) // I think I need to have at least something here?
|
||||
).apply(it) { _ ->
|
||||
Trigger { world, entity, _ ->
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: entity.asMostSpecificMoLangValue())
|
||||
return@Trigger CobblemonScripts.run(script, runtime) == DoubleValue.ONE
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
return@Trigger CobblemonScripts.run(script.resolveString().asIdentifierDefaultingNamespace(), runtime) == DoubleValue.ONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+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.api.ai.config.task
|
||||
|
||||
object SharedEntityVariables {
|
||||
const val MOVEMENT_CATEGORY = "movement"
|
||||
const val FEAR_CATEGORY = "fear"
|
||||
const val ATTACKING_CATEGORY = "attacking"
|
||||
const val BATTLING_CATEGORY = "battling"
|
||||
const val LOOKING_CATEGORY = "looking"
|
||||
|
||||
const val WALK_SPEED = "walk_speed"
|
||||
const val FLEE_SPEED_MULTIPLIER = "flee_speed_multiplier"
|
||||
const val FLEE_DESIRED_DISTANCE = "flee_desired_distance"
|
||||
const val SEE_DISTANCE = "see_distance"
|
||||
}
|
||||
+15
-1
@@ -9,10 +9,24 @@
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.DoNothing
|
||||
|
||||
interface SingleTaskConfig : TaskConfig {
|
||||
companion object {
|
||||
fun nothing() = object : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
return DoNothing(0, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun interface SingleTaskConfig : TaskConfig {
|
||||
override fun createTasks(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
|
||||
+14
-14
@@ -8,31 +8,31 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.ai.StayAfloatTask
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class StayAfloatTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val chance: Expression = "0.01".asExpression()
|
||||
val condition = booleanVariable(SharedEntityVariables.MOVEMENT_CATEGORY, "can_float", true).asExpressible()
|
||||
val chance = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, "float_chance", 0.8F).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
chance
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): BehaviorControl<LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
val chance = runtime.resolveFloat(chance)
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return WrapperLivingEntityTask(
|
||||
StayAfloatTask(chance),
|
||||
StayAfloatTask(chance.resolveFloat()),
|
||||
PathfinderMob::class.java
|
||||
)
|
||||
}
|
||||
|
||||
+8
-8
@@ -8,26 +8,26 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.StopBeingAngryIfTargetDead
|
||||
|
||||
class StopBeingAngryIfAttackerDeadTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "stop_being_angry_if_attacker_dead", true).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return StopBeingAngryIfTargetDead.create()
|
||||
}
|
||||
}
|
||||
+2
@@ -10,11 +10,13 @@ package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
|
||||
class SwitchFromActionEffectTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
|
||||
+2
@@ -10,11 +10,13 @@ package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
|
||||
class SwitchFromChattingTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
|
||||
+2
@@ -9,12 +9,14 @@
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
|
||||
class SwitchFromFightTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
|
||||
+2
@@ -10,12 +10,14 @@ package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
|
||||
class SwitchFromNPCBattleTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
|
||||
+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.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
|
||||
class SwitchFromPokemonBattleTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
return BehaviorBuilder.create {
|
||||
it.group(it.absent(CobblemonMemories.POKEMON_BATTLE)).apply(it) { _ ->
|
||||
Trigger { level, entity, _ ->
|
||||
entity.brain.updateActivityFromSchedule(level.dayTime, level.gameTime)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -11,12 +11,14 @@ package com.cobblemon.mod.common.api.ai.config.task
|
||||
import com.cobblemon.mod.common.CobblemonActivities
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
|
||||
class SwitchToActionEffectTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
|
||||
+2
@@ -11,12 +11,14 @@ package com.cobblemon.mod.common.api.ai.config.task
|
||||
import com.cobblemon.mod.common.CobblemonActivities
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
|
||||
class SwitchToChattingTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
|
||||
+5
-7
@@ -8,11 +8,9 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.Difficulty
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
@@ -22,9 +20,10 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
|
||||
class SwitchToFightTaskConfig : SingleTaskConfig {
|
||||
val condition = "true".asExpressionLike()
|
||||
val activity = Activity.FIGHT
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
@@ -33,8 +32,7 @@ class SwitchToFightTaskConfig : SingleTaskConfig {
|
||||
it.present(MemoryModuleType.ATTACK_TARGET)
|
||||
).apply(it) { _ ->
|
||||
Trigger { world, entity, _ ->
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return@Trigger false
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (entity.commandSenderWorld.getCurrentDifficultyAt(entity.blockPosition()).difficulty == Difficulty.PEACEFUL) return@Trigger false
|
||||
|
||||
entity.brain.setActiveActivityIfPossible(activity)
|
||||
|
||||
+2
@@ -9,11 +9,13 @@
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.npc.ai.SwitchToBattleTask
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class SwitchToNPCBattleTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
|
||||
+21
-9
@@ -9,27 +9,39 @@
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.ai.behavior.Behavior
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
|
||||
class SwitchToPanicWhenHostilesNearbyTaskConfig : SingleTaskConfig {
|
||||
var condition = "true".asExpression()
|
||||
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "panic_when_hostiles_nearby", true).asExpressible()
|
||||
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
) = BehaviorBuilder.create {
|
||||
it.group(it.present(MemoryModuleType.NEAREST_HOSTILE))
|
||||
.apply(it) { nearestHostile ->
|
||||
Trigger { world, entity, _ ->
|
||||
(entity as? PathfinderMob)?.navigation?.stop()
|
||||
entity.brain.setActiveActivityIfPossible(Activity.PANIC)
|
||||
return@Trigger true
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return BehaviorBuilder.create {
|
||||
it.group(it.present(MemoryModuleType.NEAREST_HOSTILE))
|
||||
.apply(it) { nearestHostile ->
|
||||
Trigger { world, entity, _ ->
|
||||
(entity as? PathfinderMob)?.navigation?.stop()
|
||||
entity.brain.setActiveActivityIfPossible(Activity.PANIC)
|
||||
return@Trigger true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-9
@@ -8,11 +8,10 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
@@ -23,16 +22,21 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.schedule.Activity
|
||||
|
||||
class SwitchToPanicWhenHurtTaskConfig : SingleTaskConfig {
|
||||
var condition = "true".asExpression()
|
||||
var includePassiveDamage = false
|
||||
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "panic_when_hurt", true).asExpressible()
|
||||
var includePassiveDamage = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "panic_on_passive_damage", false).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
includePassiveDamage
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
return if (includePassiveDamage) {
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
return if (includePassiveDamage.resolveBoolean()) {
|
||||
BehaviorBuilder.create {
|
||||
it.group(it.present(MemoryModuleType.HURT_BY))
|
||||
.apply(it) { _ ->
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.npc.ai.SwitchToBattleTask
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class SwitchToPokemonBattleTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity> {
|
||||
return SwitchToBattleTask.createForPokemon()
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,18 @@ package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveDouble
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.util.resolveString
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
@@ -23,11 +34,13 @@ import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
* @author Hiroku
|
||||
* @since October 14th, 2024
|
||||
*/
|
||||
fun interface TaskConfig {
|
||||
interface TaskConfig {
|
||||
companion object {
|
||||
val types = mutableMapOf<String, Class<out TaskConfig>>(
|
||||
"one_of" to OneOfTaskConfig::class.java,
|
||||
"wander" to WanderTaskConfig::class.java,
|
||||
"water_wander" to WaterWanderTaskConfig::class.java,
|
||||
"air_wander" to AirWanderTaskConfig::class.java,
|
||||
"look_at_target" to LookAtTargetTaskConfig::class.java,
|
||||
"follow_walk_target" to FollowWalkTargetTaskConfig::class.java,
|
||||
"random" to RandomTaskConfig::class.java,
|
||||
@@ -39,6 +52,9 @@ fun interface TaskConfig {
|
||||
"switch_npc_to_battle" to SwitchToNPCBattleTaskConfig::class.java,
|
||||
"look_at_battling_pokemon" to LookAtBattlingPokemonTaskConfig::class.java,
|
||||
"switch_npc_from_battle" to SwitchFromNPCBattleTaskConfig::class.java,
|
||||
"switch_pokemon_to_battle" to SwitchToPokemonBattleTaskConfig::class.java,
|
||||
"look_at_targeted_battle_pokemon" to LookAtTargetedBattlePokemonTaskConfig::class.java,
|
||||
"switch_pokemon_from_battle" to SwitchFromPokemonBattleTaskConfig::class.java,
|
||||
"go_to_healing_machine" to GoToHealingMachineTaskConfig::class.java,
|
||||
"heal_using_healing_machine" to HealUsingHealingMachineTaskConfig::class.java,
|
||||
"all_of" to AllOfTaskConfig::class.java,
|
||||
@@ -60,6 +76,11 @@ fun interface TaskConfig {
|
||||
"flee_nearest_hostile" to FleeNearestHostileTaskConfig::class.java,
|
||||
"run_script" to RunScript::class.java,
|
||||
"look_in_direction" to LookInDirectionTaskConfig::class.java,
|
||||
"wake_up" to WakeUpTaskConfig::class.java,
|
||||
"go_to_sleep" to GoToSleepTaskConfig::class.java,
|
||||
"find_resting_place" to FindRestingPlaceTaskConfig::class.java,
|
||||
"move_to_owner" to MoveToOwnerTaskConfig::class.java,
|
||||
"move_to_item_and_eat" to MoveToItemAndEatTaskConfig::class.java,
|
||||
)
|
||||
|
||||
val runtime = MoLangRuntime().setup()
|
||||
@@ -68,6 +89,38 @@ fun interface TaskConfig {
|
||||
val runtime: MoLangRuntime
|
||||
get() = Companion.runtime
|
||||
|
||||
fun checkCondition(entity: LivingEntity, expressionOrEntityVariable: ExpressionOrEntityVariable): Boolean {
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
return expressionOrEntityVariable.resolveBoolean()
|
||||
}
|
||||
|
||||
fun ExpressionOrEntityVariable.asExpression() = map({ it }, { "q.entity.config.${it.variableName}".asExpression() })
|
||||
fun ExpressionOrEntityVariable.resolveString() = runtime.resolveString(asExpression())
|
||||
fun ExpressionOrEntityVariable.resolveBoolean() = runtime.resolveBoolean(asExpression())
|
||||
fun ExpressionOrEntityVariable.resolveInt() = runtime.resolveInt(asExpression())
|
||||
fun ExpressionOrEntityVariable.resolveDouble() = runtime.resolveDouble(asExpression())
|
||||
fun ExpressionOrEntityVariable.resolveFloat() = runtime.resolveFloat(asExpression())
|
||||
|
||||
private fun variable(category: String, name: String, type: MoLangConfigVariable.MoLangVariableType, default: String) = MoLangConfigVariable(
|
||||
variableName = name,
|
||||
category = lang("entity.variable.category.$category"),
|
||||
displayName = lang("entity.variable.$name.name"),
|
||||
description = lang("entity.variable.$name.desc"),
|
||||
type = type,
|
||||
defaultValue = default
|
||||
)
|
||||
|
||||
fun stringVariable(category: String, name: String, default: String) = variable(category = category, name = name, type = MoLangConfigVariable.MoLangVariableType.TEXT, default = default)
|
||||
fun numberVariable(category: String, name: String, default: Number) = variable(category = category, name = name, type = MoLangConfigVariable.MoLangVariableType.NUMBER, default = default.toString())
|
||||
fun booleanVariable(category: String, name: String, default: Boolean) = variable(category = category, name = name, type = MoLangConfigVariable.MoLangVariableType.BOOLEAN, default = default.toString())
|
||||
|
||||
fun getVariableExpression(name: String) = "q.entity.config.$name".asExpression()
|
||||
fun resolveStringVariable(name: String) = runtime.resolveString(getVariableExpression(name))
|
||||
fun resolveBooleanVariable(name: String) = runtime.resolveBoolean(getVariableExpression(name))
|
||||
fun resolveNumberVariable(name: String) = runtime.resolveDouble(getVariableExpression(name))
|
||||
|
||||
/** The variables that this task config uses. These are used to declare variables on the entity cleanly. */
|
||||
fun getVariables(entity: LivingEntity): List<MoLangConfigVariable>
|
||||
/** Given the entity in construction, returns a list of tasks. */
|
||||
fun createTasks(entity: LivingEntity, brainConfigurationContext: BrainConfigurationContext): List<BehaviorControl<in LivingEntity>>
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.WakeUpTask
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
|
||||
class WakeUpTaskConfig : SingleTaskConfig {
|
||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
return WrapperLivingEntityTask(WakeUpTask.create(), PokemonEntity::class.java)
|
||||
}
|
||||
}
|
||||
+30
-25
@@ -8,23 +8,16 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.resolveBoolean
|
||||
import com.cobblemon.mod.common.util.resolveDouble
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
|
||||
import net.minecraft.world.entity.ai.behavior.RandomStroll
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
@@ -32,20 +25,31 @@ import net.minecraft.world.entity.ai.memory.WalkTarget
|
||||
import net.minecraft.world.entity.ai.util.LandRandomPos
|
||||
|
||||
class WanderTaskConfig : SingleTaskConfig {
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
val shouldWander: ExpressionLike = "math.random(0, 20 * 8) <= 1".asExpressionLike()
|
||||
val horizontalRange: Expression = "10".asExpression()
|
||||
val verticalRange: Expression = "5".asExpression()
|
||||
val speedMultiplier: Expression = "0.35".asExpression()
|
||||
val completionRange: Expression = "1".asExpression()
|
||||
val lookTargetYOffset: Expression = "1.5".asExpression()
|
||||
companion object {
|
||||
const val WANDER = "wander" // Category
|
||||
}
|
||||
|
||||
val condition = booleanVariable(WANDER, "wanders", true).asExpressible()
|
||||
val wanderChance = numberVariable(WANDER, "wander_chance", 1/(20 * 6F)).asExpressible()
|
||||
val horizontalRange = numberVariable(WANDER, "horizontal_wander_range", 10).asExpressible()
|
||||
val verticalRange = numberVariable(WANDER, "vertical_wander_range", 5).asExpressible()
|
||||
|
||||
val speedMultiplier = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, SharedEntityVariables.WALK_SPEED, 0.35).asExpressible()
|
||||
|
||||
override fun getVariables(entity: LivingEntity) = listOf(
|
||||
condition,
|
||||
wanderChance,
|
||||
horizontalRange,
|
||||
verticalRange,
|
||||
speedMultiplier
|
||||
).asVariables()
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(condition)) return null
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
|
||||
return BehaviorBuilder.create {
|
||||
it.group(
|
||||
@@ -57,12 +61,13 @@ class WanderTaskConfig : SingleTaskConfig {
|
||||
return@Trigger false
|
||||
}
|
||||
|
||||
runtime.withQueryValue("entity", (entity as? PosableEntity)?.struct ?: QueryStruct(hashMapOf()))
|
||||
if (!runtime.resolveBoolean(shouldWander)) return@Trigger false
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
val wanderChance = wanderChance.resolveFloat()
|
||||
if (wanderChance <= 0 || world.random.nextFloat() > wanderChance) return@Trigger false
|
||||
|
||||
val targetVec = LandRandomPos.getPos(entity, runtime.resolveInt(horizontalRange), runtime.resolveInt(verticalRange)) ?: return@Trigger false
|
||||
walkTarget.set(WalkTarget(targetVec, runtime.resolveFloat(speedMultiplier), runtime.resolveInt(completionRange)))
|
||||
lookTarget.set(BlockPosTracker(targetVec.add(0.0, runtime.resolveDouble(lookTargetYOffset), 0.0)))
|
||||
val targetVec = LandRandomPos.getPos(entity, horizontalRange.resolveInt(), verticalRange.resolveInt(), { 0.0 }) ?: return@Trigger false
|
||||
walkTarget.set(WalkTarget(targetVec, speedMultiplier.resolveFloat(), 1))
|
||||
lookTarget.set(BlockPosTracker(targetVec.add(0.0, entity.eyeHeight.toDouble(), 0.0)))
|
||||
return@Trigger true
|
||||
}
|
||||
}
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.BrainConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||
import com.cobblemon.mod.common.api.ai.asVariables
|
||||
import com.cobblemon.mod.common.api.ai.config.task.WanderTaskConfig.Companion.WANDER
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.datafixers.util.Either
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorUtils
|
||||
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.ai.memory.WalkTarget
|
||||
|
||||
class WaterWanderTaskConfig : SingleTaskConfig {
|
||||
val condition = booleanVariable(WANDER, "water_wanders", true).asExpressible()
|
||||
val wanderChance = numberVariable(WANDER, "water_wander_chance", 1/(20 * 3F)).asExpressible()
|
||||
val speedMultiplier = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, SharedEntityVariables.WALK_SPEED, 0.35).asExpressible()
|
||||
val horizontalRange: ExpressionOrEntityVariable = Either.left("10.0".asExpression())
|
||||
val verticalRange: ExpressionOrEntityVariable = Either.left("3.0".asExpression())
|
||||
|
||||
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
||||
return listOf(condition, wanderChance, speedMultiplier).asVariables()
|
||||
}
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
brainConfigurationContext: BrainConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
if (!condition.resolveBoolean()) return null
|
||||
|
||||
return BehaviorBuilder.create {
|
||||
it.group(
|
||||
it.absent(MemoryModuleType.WALK_TARGET),
|
||||
it.registered(MemoryModuleType.LOOK_TARGET)
|
||||
).apply(it) { walkTarget, lookTarget ->
|
||||
Trigger { world, entity, time ->
|
||||
if (entity !is PathfinderMob || !entity.isInWater) {
|
||||
return@Trigger false
|
||||
}
|
||||
|
||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
val wanderChance = wanderChance.resolveFloat()
|
||||
if (wanderChance <= 0 || world.random.nextFloat() > wanderChance) return@Trigger false
|
||||
|
||||
val target = BehaviorUtils.getRandomSwimmablePos(entity, horizontalRange.resolveInt(), verticalRange.resolveInt()) ?: return@Trigger false
|
||||
walkTarget.set(WalkTarget(target, speedMultiplier.resolveFloat(), 1))
|
||||
lookTarget.set(BlockPosTracker(target))
|
||||
return@Trigger true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ class ActiveDialogue(var playerEntity: ServerPlayer, var dialogueReference: Dial
|
||||
)
|
||||
|
||||
dialogueReference.initializationAction.invoke(this)
|
||||
setPage(currentPage)
|
||||
|
||||
if (!completion.isDone) {
|
||||
val packet = DialogueOpenedPacket(this, true)
|
||||
|
||||
@@ -52,6 +52,6 @@ object DialogueManager {
|
||||
fun stopDialogue(playerEntity: ServerPlayer) {
|
||||
val activeDialogue = playerEntity.activeDialogue ?: return
|
||||
DialogueClosedPacket(activeDialogue.dialogueId).sendToPlayer(playerEntity)
|
||||
activeDialogues.remove(activeDialogue.dialogueId)
|
||||
activeDialogues.remove(playerEntity.uuid)
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.drop
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
@@ -40,17 +41,23 @@ interface DropEntry {
|
||||
* to be dropped.
|
||||
*/
|
||||
val percentage: Float
|
||||
|
||||
/**
|
||||
* The drop's quantity when doing selection from the [DropTable]. See the drop table documentation for more on how
|
||||
* this works.
|
||||
*/
|
||||
val quantity: Int
|
||||
|
||||
/**
|
||||
* The maximum number of times the item can be selected drop the [DropTable]. In most cases this will just be 1,
|
||||
* meaning that the item, once picked, cannot be picked again. A larger value will allow the same [DropEntry] from
|
||||
* appearing multiple times in a drop action.
|
||||
*/
|
||||
val maxSelectableTimes: Int
|
||||
|
||||
/** Whether this is considered a possible drop at the moment or not */
|
||||
fun canDrop(pokemon: Pokemon?): Boolean = true
|
||||
|
||||
/** The logic to use to actually drop the thing. */
|
||||
fun drop(entity: LivingEntity?, world: ServerLevel, pos: Vec3, player: ServerPlayer?)
|
||||
}
|
||||
@@ -11,11 +11,13 @@ 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 com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import kotlin.random.Random
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
/**
|
||||
@@ -45,9 +47,11 @@ class DropTable {
|
||||
* Gets a drop list from this table as a list of [DropEntry]. You can specify the range of drop quantity totals
|
||||
* that will be possible, or if you leave it blank it will use [DropTable.amount].
|
||||
*/
|
||||
fun getDrops(amount: IntRange = this.amount): List<DropEntry> {
|
||||
fun getDrops(amount: IntRange = this.amount, pokemon: Pokemon? = null): List<DropEntry> {
|
||||
val chosenAmount = amount.random()
|
||||
val possibleDrops = entries.filter { it.quantity <= chosenAmount }.toMutableList()
|
||||
val possibleDrops = entries.filter {
|
||||
it.quantity <= chosenAmount && it.canDrop(pokemon)
|
||||
}.toMutableList()
|
||||
|
||||
if (possibleDrops.isEmpty()) {
|
||||
return emptyList()
|
||||
@@ -87,11 +91,10 @@ class DropTable {
|
||||
world: ServerLevel,
|
||||
pos: Vec3,
|
||||
player: ServerPlayer?,
|
||||
amount: IntRange = this.amount
|
||||
amount: IntRange = this.amount,
|
||||
pokemon: Pokemon? = null,
|
||||
) {
|
||||
val drops = getDrops(amount).toMutableList()
|
||||
val heldItem = (entity as PokemonEntity).pokemon.heldItemNoCopy()
|
||||
if (!heldItem.isEmpty) entity.spawnAtLocation(heldItem.item)
|
||||
val drops = getDrops(amount, pokemon).toMutableList()
|
||||
LOOT_DROPPED.postThen(
|
||||
event = LootDroppedEvent(this, player, entity, drops),
|
||||
ifSucceeded = { it.drops.forEach { it.drop(entity, world, pos, player) } }
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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.drop
|
||||
|
||||
import com.cobblemon.mod.common.api.pokemon.evolution.requirement.EvolutionRequirement
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
class EvolutionItemDropEntry : ItemDropEntry() {
|
||||
val requirements: MutableSet<EvolutionRequirement> = mutableSetOf()
|
||||
|
||||
override fun canDrop(pokemon: Pokemon?): Boolean = pokemon != null && requirements.all { it.check(pokemon) }
|
||||
}
|
||||
+6
@@ -13,9 +13,13 @@ import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.ActorType
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.EntityBackedBattleActor
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
|
||||
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||
import com.cobblemon.mod.common.entity.npc.NPCBattleActor
|
||||
import com.cobblemon.mod.common.util.asArrayValue
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
/**
|
||||
* Event fired when a battle is won by some number of [BattleActor]s.
|
||||
@@ -40,6 +44,8 @@ data class BattleVictoryEvent (
|
||||
"npc_losers" to losers.filter { it.type == ActorType.NPC }.asArrayValue { it.struct },
|
||||
"wild_pokemon_winners" to winners.filter { it.type == ActorType.WILD }.asArrayValue { it.struct },
|
||||
"wild_pokemon_losers" to losers.filter { it.type == ActorType.WILD }.asArrayValue { it.struct },
|
||||
"scriptable_winners" to winners.filterIsInstance<EntityBackedBattleActor<*>>().mapNotNull { it.entity as? MoLangScriptingEntity }.asArrayValue { (it as LivingEntity).asMostSpecificMoLangValue() },
|
||||
"scriptable_losers" to losers.filterIsInstance<EntityBackedBattleActor<*>>().mapNotNull { it.entity as? MoLangScriptingEntity }.asArrayValue { (it as LivingEntity).asMostSpecificMoLangValue() },
|
||||
"players" to battle.actors.filter { it.type == ActorType.PLAYER }.asArrayValue { it.struct },
|
||||
"npcs" to battle.actors.filter { it.type == ActorType.NPC }.asArrayValue { it.struct },
|
||||
"wild_pokemon" to battle.actors.filter { it.type == ActorType.WILD }.asArrayValue { it.struct }
|
||||
|
||||
+4
-6
@@ -18,19 +18,17 @@ import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
data class PokemonScannedEvent(val player: ServerPlayer, val scannedPokemonEntityData: PokedexEntityData, val scannedEntity: ScannableEntity) {
|
||||
val pokedexEntityData: PokedexEntityData
|
||||
get() = scannedPokemonEntityData
|
||||
|
||||
val isOwned: Boolean
|
||||
get() = scannedPokemonEntityData.ownerUUID == player.uuid
|
||||
get() = scannedPokemonEntityData.pokemon.getOwnerUUID() == player.uuid
|
||||
|
||||
val context = mutableMapOf(
|
||||
"player" to player.asMoLangValue(),
|
||||
"pokemon" to scannedPokemonEntityData.struct,
|
||||
"pokemon" to scannedPokemonEntityData.pokemon.struct,
|
||||
"disguise" to (scannedPokemonEntityData.disguise?.struct ?: DoubleValue.ZERO),
|
||||
"entity" to {
|
||||
when (scannedEntity) {
|
||||
is LivingEntity -> scannedEntity.asMostSpecificMoLangValue()
|
||||
else -> DoubleValue(0.0)
|
||||
else -> DoubleValue.ZERO
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
+9
-2
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.events.pokemon
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
/**
|
||||
@@ -18,5 +19,11 @@ import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
*/
|
||||
data class FriendshipUpdatedEvent(
|
||||
val pokemon: Pokemon,
|
||||
var newFriendship: Int
|
||||
)
|
||||
val newFriendshipInitial: Int
|
||||
)
|
||||
{
|
||||
var newFriendship: Int = newFriendshipInitial
|
||||
set(value) {
|
||||
field = value.coerceIn(0, Cobblemon.config.maxPokemonFriendship)
|
||||
}
|
||||
}
|
||||
+5
-7
@@ -17,16 +17,14 @@ import com.cobblemon.mod.common.api.pokedex.AbstractPokedexManager
|
||||
import com.cobblemon.mod.common.api.pokedex.FormDexRecord
|
||||
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
|
||||
import com.cobblemon.mod.common.pokedex.scanner.PokedexEntityData
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.getPlayer
|
||||
import com.mojang.datafixers.util.Either
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Event that fires when a Pokémon's information is gained or updated in the Pokédex.
|
||||
*/
|
||||
sealed interface PokedexDataChangedEvent {
|
||||
val dataSource: Either<PokedexEntityData, Pokemon>
|
||||
val dataSource: PokedexEntityData
|
||||
val knowledge: PokedexEntryProgress
|
||||
val playerUUID: UUID
|
||||
val record: FormDexRecord
|
||||
@@ -37,22 +35,22 @@ sealed interface PokedexDataChangedEvent {
|
||||
fun getContext(): MutableMap<String, MoValue> {
|
||||
return mutableMapOf(
|
||||
"player" to (playerUUID.getPlayer()?.asMoLangValue() ?: DoubleValue.ZERO),
|
||||
"pokemon" to dataSource.map({ DoubleValue.ZERO }, { it.struct }),
|
||||
"data" to dataSource.map({ it.struct }, { DoubleValue.ZERO }),
|
||||
"pokemon" to dataSource.pokemon.struct,
|
||||
"disguise" to (dataSource.disguise?.struct ?: DoubleValue.ZERO),
|
||||
"knowledge" to StringValue(knowledge.name.lowercase()),
|
||||
"pokedex" to pokedexManager.struct
|
||||
)
|
||||
}
|
||||
|
||||
class Pre(
|
||||
override val dataSource: Either<PokedexEntityData, Pokemon>,
|
||||
override val dataSource: PokedexEntityData,
|
||||
override val knowledge: PokedexEntryProgress,
|
||||
override val playerUUID: UUID,
|
||||
override val record: FormDexRecord
|
||||
) : PokedexDataChangedEvent, Cancelable()
|
||||
|
||||
class Post(
|
||||
override val dataSource: Either<PokedexEntityData, Pokemon>,
|
||||
override val dataSource: PokedexEntityData,
|
||||
override val knowledge: PokedexEntryProgress,
|
||||
override val playerUUID: UUID,
|
||||
override val record: FormDexRecord
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.interaction
|
||||
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonSerializer
|
||||
import kotlin.reflect.KClass
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
/**
|
||||
* A type adapter for [EntityInteraction]s.
|
||||
* For the default implementation with Pokémon entities see [CobblemonPokemonEntityInteractionTypeAdapter].
|
||||
*
|
||||
* @param T The type of [EntityInteraction].
|
||||
*
|
||||
* @author Licious
|
||||
* @since November 30th, 2022
|
||||
*/
|
||||
interface EntityInteractionTypeAdapter<T : EntityInteraction<*>> : JsonDeserializer<T>, JsonSerializer<T> {
|
||||
|
||||
fun registerInteraction(identifier: ResourceLocation, type: KClass<out T>)
|
||||
|
||||
}
|
||||
@@ -90,11 +90,13 @@ import net.minecraft.world.entity.EntityType
|
||||
import net.minecraft.world.entity.LightningBolt
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.TamableAnimal
|
||||
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.ai.memory.MemoryStatus
|
||||
import net.minecraft.world.entity.ai.memory.WalkTarget
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.level.ClipContext
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.Level.ExplosionInteraction
|
||||
import net.minecraft.world.level.biome.Biome
|
||||
@@ -419,6 +421,38 @@ object MoLangFunctions {
|
||||
val source = DamageSource(entity.level().registryAccess().registryOrThrow(Registries.DAMAGE_TYPE).getHolder(DamageTypes.GENERIC).get())
|
||||
entity.hurt(source, amount.toFloat())
|
||||
}
|
||||
map.put("distance_to_owner") {
|
||||
if (entity !is TamableAnimal) {
|
||||
return@put DoubleValue.ZERO
|
||||
}
|
||||
val owner = entity.owner ?: return@put DoubleValue.ZERO
|
||||
return@put DoubleValue(entity.distanceTo(owner))
|
||||
}
|
||||
map.put("owner") {
|
||||
if (entity !is TamableAnimal) {
|
||||
return@put DoubleValue.ZERO
|
||||
}
|
||||
val owner = entity.owner
|
||||
return@put owner?.asMostSpecificMoLangValue() ?: DoubleValue.ZERO
|
||||
}
|
||||
map.put("can_see") { params ->
|
||||
val target = params.get<MoValue>(0)
|
||||
val range = params.getDoubleOrNull(1) ?: 32.0
|
||||
if (target is ObjectValue<*>) {
|
||||
val targetEntity = target.obj as? LivingEntity ?: return@put DoubleValue.ZERO
|
||||
val vector = targetEntity.eyePosition.subtract(entity.eyePosition).normalize()
|
||||
val trace = entity.traceEntityCollision(
|
||||
maxDistance = range.toFloat(),
|
||||
stepDistance = 0.1F,
|
||||
direction = vector,
|
||||
entityClass = targetEntity.javaClass,
|
||||
collideBlock = ClipContext.Fluid.NONE
|
||||
)
|
||||
return@put DoubleValue(targetEntity in (trace?.entities ?: emptyList()))
|
||||
} else {
|
||||
return@put DoubleValue.ZERO
|
||||
}
|
||||
}
|
||||
map.put("walk_to") { params ->
|
||||
val x = params.getDouble(0)
|
||||
val y = params.getDouble(1)
|
||||
@@ -698,6 +732,8 @@ object MoLangFunctions {
|
||||
map.put("max_hp") { DoubleValue(pokemon.maxHealth.toDouble()) }
|
||||
map.put("current_hp") { DoubleValue(pokemon.currentHealth.toDouble()) }
|
||||
map.put("friendship") { DoubleValue(pokemon.friendship.toDouble()) }
|
||||
map.put("behaviour") { pokemon.form.behaviour.struct }
|
||||
map.put("behavior") { pokemon.form.behaviour.struct } // Inferior
|
||||
map.put("evs") {
|
||||
val struct = QueryStruct(hashMapOf())
|
||||
for (stat in Stats.PERMANENT) {
|
||||
@@ -714,6 +750,7 @@ object MoLangFunctions {
|
||||
}
|
||||
map.put("is_wild") { DoubleValue(pokemon.entity?.let { it.ownerUUID == null } == true) }
|
||||
map.put("is_shiny") { DoubleValue(pokemon.shiny) }
|
||||
map.put("is_in_party") { DoubleValue(pokemon.storeCoordinates.get()?.store is PartyStore) }
|
||||
map.put("species") { pokemon.species.struct }
|
||||
map.put("form") { StringValue(pokemon.form.name) }
|
||||
map.put("weight") { DoubleValue(pokemon.species.weight.toDouble()) }
|
||||
@@ -997,7 +1034,6 @@ object MoLangFunctions {
|
||||
map.put("hitbox_height") { DoubleValue(species.hitbox.height) }
|
||||
map.put("hitbox_fixed") { DoubleValue(species.hitbox.fixed) }
|
||||
map.put("catch_rate") { DoubleValue(species.catchRate) }
|
||||
|
||||
map
|
||||
}
|
||||
)
|
||||
@@ -1093,7 +1129,7 @@ object MoLangFunctions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Different functions exist depending on
|
||||
* Different functions exist depending on the entity type, this tries to make the struct that's most specific to the type.
|
||||
*/
|
||||
fun LivingEntity.asMostSpecificMoLangValue(): ObjectValue<out LivingEntity> {
|
||||
return when (this) {
|
||||
@@ -1162,6 +1198,7 @@ object MoLangFunctions {
|
||||
.flatMap { it.invoke(pokemonEntity).entries }
|
||||
.associate { it.key to it.value }
|
||||
functions.putAll(addedFunctions)
|
||||
pokemonEntity.registerFunctionsForScripting(this)
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,15 @@ class BenchedMoves : Iterable<BenchedMove> {
|
||||
}
|
||||
}
|
||||
|
||||
fun add(benchedMove: BenchedMove) = doThenEmit { benchedMoves.add(benchedMove) }
|
||||
fun add(benchedMove: BenchedMove): Boolean {
|
||||
if (any { it.moveTemplate == benchedMove.moveTemplate }) {
|
||||
return false
|
||||
}
|
||||
|
||||
doThenEmit { benchedMoves.add(benchedMove) }
|
||||
return true
|
||||
}
|
||||
|
||||
fun addAll(benchedMoves: Iterable<BenchedMove>) = doThenEmit { this.benchedMoves.addAll(benchedMoves) }
|
||||
fun clear() = doThenEmit { benchedMoves.clear() }
|
||||
fun remove(benchedMove: BenchedMove) = doThenEmit { benchedMoves.remove(benchedMove) }
|
||||
|
||||
@@ -134,18 +134,21 @@ class MoveSet : Iterable<Move> {
|
||||
return json
|
||||
}
|
||||
|
||||
fun add(move: Move) {
|
||||
fun add(move: Move): Boolean {
|
||||
if (any { it.template == move.template }) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
for (i in 0 until MOVE_COUNT) {
|
||||
if (moves[i] == null) {
|
||||
moves[i] = move
|
||||
move.observable.subscribe { this.update() }
|
||||
update()
|
||||
return
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun update() {
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.bedrockk.molang.runtime.value.MoValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.api.ai.config.BrainConfig
|
||||
import com.cobblemon.mod.common.api.npc.configuration.NPCBattleConfiguration
|
||||
import com.cobblemon.mod.common.api.npc.configuration.NPCConfigVariable
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
|
||||
import com.cobblemon.mod.common.api.npc.variation.NPCVariationProvider
|
||||
import com.cobblemon.mod.common.api.npc.variation.RandomNPCVariationProvider
|
||||
@@ -45,7 +45,7 @@ class NPCClass {
|
||||
var interaction: NPCInteractConfiguration? = null
|
||||
var canDespawn = true
|
||||
var variations: MutableMap<String, NPCVariationProvider> = mutableMapOf()
|
||||
var config: MutableList<NPCConfigVariable> = mutableListOf()
|
||||
var config: MutableList<MoLangConfigVariable> = mutableListOf()
|
||||
var variables = mutableMapOf<String, MoValue>() // Questionable whether this should be here.
|
||||
var party: NPCPartyProvider? = null
|
||||
var skill: Int = 0
|
||||
@@ -57,6 +57,7 @@ class NPCClass {
|
||||
var isInvulnerable = false
|
||||
var isLeashable = true
|
||||
var allowProjectileHits = true
|
||||
var hideNameTag = false
|
||||
|
||||
// If you're adding stuff here, add it to NPCPreset and NPCClassAdapter too
|
||||
|
||||
@@ -80,6 +81,7 @@ class NPCClass {
|
||||
}
|
||||
buffer.writeCollection(config) { _, v ->
|
||||
buffer.writeString(v.variableName)
|
||||
buffer.writeText(v.category)
|
||||
buffer.writeText(v.displayName)
|
||||
buffer.writeText(v.description)
|
||||
buffer.writeEnumConstant(v.type)
|
||||
@@ -97,6 +99,7 @@ class NPCClass {
|
||||
buffer.writeBoolean(isInvulnerable)
|
||||
buffer.writeBoolean(isLeashable)
|
||||
buffer.writeBoolean(allowProjectileHits)
|
||||
buffer.writeBoolean(hideNameTag)
|
||||
}
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
@@ -125,11 +128,12 @@ class NPCClass {
|
||||
}
|
||||
config = buffer.readList {
|
||||
val variableName = buffer.readString()
|
||||
val category = buffer.readText()
|
||||
val displayName = buffer.readText()
|
||||
val description = buffer.readText()
|
||||
val type = buffer.readEnumConstant(NPCConfigVariable.NPCVariableType::class.java)
|
||||
val type = buffer.readEnumConstant(MoLangConfigVariable.MoLangVariableType::class.java)
|
||||
val defaultValue = buffer.readString()
|
||||
NPCConfigVariable(variableName, displayName, description, type, defaultValue)
|
||||
MoLangConfigVariable(variableName, category, displayName, description, type, defaultValue)
|
||||
}.toMutableList()
|
||||
skill = buffer.readInt()
|
||||
autoHealParty = buffer.readBoolean()
|
||||
@@ -148,5 +152,6 @@ class NPCClass {
|
||||
isInvulnerable = buffer.readBoolean()
|
||||
isLeashable = buffer.readBoolean()
|
||||
allowProjectileHits = buffer.readBoolean()
|
||||
hideNameTag = buffer.readBoolean()
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ import com.cobblemon.mod.common.api.drop.DropEntry
|
||||
import com.cobblemon.mod.common.api.drop.ItemDropMethod
|
||||
import com.cobblemon.mod.common.api.entity.EntityDimensionsAdapter
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.npc.NPCClasses.getByIdentifier
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
|
||||
import com.cobblemon.mod.common.api.npc.variation.NPCVariationProvider
|
||||
import com.cobblemon.mod.common.api.npc.variation.WeightedAspect
|
||||
@@ -74,6 +76,10 @@ object NPCClasses : JsonDataRegistry<NPCClass> {
|
||||
.registerTypeAdapter(WeightedAspect::class.java, WeightedAspectAdapter)
|
||||
.registerTypeAdapter(BrainConfig::class.java, BrainConfigAdapter)
|
||||
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
|
||||
.registerTypeAdapter(
|
||||
TypeToken.getParameterized(Either::class.java, Expression::class.java, MoLangConfigVariable::class.java).type,
|
||||
ExpressionOrEntityVariableAdapter
|
||||
)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
|
||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
|
||||
@@ -90,14 +96,6 @@ object NPCClasses : JsonDataRegistry<NPCClass> {
|
||||
val classes: Collection<NPCClass>
|
||||
get() = this.npcClassesByIdentifier.values
|
||||
|
||||
init {
|
||||
// NPC additions would be useful
|
||||
// SpeciesAdditions.observable.subscribe {
|
||||
// this.species.forEach(Species::initialize)
|
||||
// this.species.forEach(Species::resolveEvolutionMoves)
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an NPC class by the pathname of their [ResourceLocation].
|
||||
* This method exists for the convenience of finding Cobble default NPC classes.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
package com.cobblemon.mod.common.api.npc
|
||||
|
||||
import com.cobblemon.mod.common.api.ai.config.BrainConfig
|
||||
import com.cobblemon.mod.common.api.npc.configuration.NPCConfigVariable
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.api.npc.configuration.NPCInteractConfiguration
|
||||
import com.cobblemon.mod.common.api.npc.variation.NPCVariationProvider
|
||||
import net.minecraft.network.chat.Component
|
||||
@@ -21,7 +21,7 @@ class NPCPreset {
|
||||
var resourceIdentifier: ResourceLocation? = null
|
||||
var aspects: Set<String>? = null
|
||||
var variations: Map<String, NPCVariationProvider>? = null
|
||||
var config: List<NPCConfigVariable>? = null
|
||||
var config: List<MoLangConfigVariable>? = null
|
||||
var party: NPCPartyProvider? = null
|
||||
var canDespawn: Boolean? = null
|
||||
var interaction: NPCInteractConfiguration? = null
|
||||
@@ -37,6 +37,7 @@ class NPCPreset {
|
||||
var isInvulnerable: Boolean? = null
|
||||
var isLeashable: Boolean? = null
|
||||
var allowProjectileHits: Boolean? = null
|
||||
var hideNameTag: Boolean? = null
|
||||
|
||||
fun applyTo(npcClass: NPCClass) {
|
||||
resourceIdentifier?.let { npcClass.resourceIdentifier = it }
|
||||
@@ -63,5 +64,6 @@ class NPCPreset {
|
||||
isInvulnerable?.let { npcClass.isInvulnerable = it }
|
||||
isLeashable?.let { npcClass.isLeashable = it }
|
||||
allowProjectileHits?.let { npcClass.allowProjectileHits = it }
|
||||
hideNameTag?.let { npcClass.hideNameTag = it }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user