mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-27 04:26:27 -04:00
Compare commits
422
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35b2b33eb4 | ||
|
|
9900fbf3d6 | ||
|
|
1e8d012371 | ||
|
|
82ef84d82b | ||
|
|
c0154cd82d | ||
|
|
1c9c833a49 | ||
|
|
0bc5bb5caa | ||
|
|
3330941a2c | ||
|
|
901e3e09e1 | ||
|
|
79ea082d7e | ||
|
|
3d78929ff0 | ||
|
|
5d94b03f7a | ||
|
|
587305eb52 | ||
|
|
e363ce5e0e | ||
|
|
e49b704200 | ||
|
|
ec8b35860c | ||
|
|
74c49bf2da | ||
|
|
c03e7d9ed3 | ||
|
|
b54f2442c9 | ||
|
|
62c0545ea7 | ||
|
|
f821abd7e5 | ||
|
|
2652e53e0c | ||
|
|
08ac7d478d | ||
|
|
4f51016ca9 | ||
|
|
ef8b4fd3cd | ||
|
|
f55972c190 | ||
|
|
2dbf304ebe | ||
|
|
1c5feab9c9 | ||
|
|
1c720793c4 | ||
|
|
6a170f8ce8 | ||
|
|
b4aba94f89 | ||
|
|
9832730f5c | ||
|
|
ffdaec3e15 | ||
|
|
d481f887a8 | ||
|
|
df3aec6222 | ||
|
|
b423fb1c46 | ||
|
|
8ae26a268a | ||
|
|
39b522abcc | ||
|
|
9bcfcef4fd | ||
|
|
60ac2d8058 | ||
|
|
9366d28141 | ||
|
|
75b48196b7 | ||
|
|
5180e2b501 | ||
|
|
bb407b1d65 | ||
|
|
8b308e5595 | ||
|
|
148526e5e8 | ||
|
|
f319efcf12 | ||
|
|
5055e3926c | ||
|
|
3d92de18b8 | ||
|
|
ab9851fd12 | ||
|
|
a9df6bc709 | ||
|
|
3681813976 | ||
|
|
333d234dbe | ||
|
|
ee42825dc3 | ||
|
|
0d9a4f9392 | ||
|
|
5e90c05fdd | ||
|
|
9a0648d956 | ||
|
|
91187ce952 | ||
|
|
686bc62996 | ||
|
|
5925247ace | ||
|
|
c6a4bec3f3 | ||
|
|
7e582090f8 | ||
|
|
55eef6ea69 | ||
|
|
f65cb9538c | ||
|
|
8dbce8fefe | ||
|
|
4eb39566fa | ||
|
|
b33536e872 | ||
|
|
5957ddae58 | ||
|
|
fcb798161e | ||
|
|
357ac35802 | ||
|
|
25c6fb6d31 | ||
|
|
7fd9b678f1 | ||
|
|
169e06a26f | ||
|
|
ecfc71bfd1 | ||
|
|
f2919aa75d | ||
|
|
336b076eee | ||
|
|
7a970b4bc1 | ||
|
|
1947450d77 | ||
|
|
de94721703 | ||
|
|
c6e217dda7 | ||
|
|
49f4a254d1 | ||
|
|
b0886449bb | ||
|
|
aca61300d6 | ||
|
|
5667ddf6a2 | ||
|
|
702ce3b8f8 | ||
|
|
096136b48e | ||
|
|
25bcd1dec2 | ||
|
|
a9432fc1de | ||
|
|
7ec7152ec3 | ||
|
|
0ac7f664f1 | ||
|
|
4550cf31ed | ||
|
|
4d783b2d15 | ||
|
|
d034469ebb | ||
|
|
4f8a44c95b | ||
|
|
52b17ca39e | ||
|
|
c0fc28d61d | ||
|
|
3701ae7dac | ||
|
|
b4cc95b3bf | ||
|
|
eb83d11952 | ||
|
|
dc2ffa7899 | ||
|
|
a80689609c | ||
|
|
42c2eab418 | ||
|
|
7c1c0dd3c8 | ||
|
|
320f5f7090 | ||
|
|
beed7a322c | ||
|
|
b58e9c6de5 | ||
|
|
3e7ae9750c | ||
|
|
85f80c530e | ||
|
|
1ab5f13704 | ||
|
|
782f0b8a5a | ||
|
|
9dbd27b23c | ||
|
|
2faf669ace | ||
|
|
1c38433dda | ||
|
|
d9d3583cb1 | ||
|
|
dd7edee941 | ||
|
|
616d16e11f | ||
|
|
77a648cebd | ||
|
|
adaa852b59 | ||
|
|
c17c48caec | ||
|
|
f6a833a5fd | ||
|
|
ab3d26dee6 | ||
|
|
37e526614f | ||
|
|
0f3c6d07c8 | ||
|
|
3be4ae8fa6 | ||
|
|
d9b027dd66 | ||
|
|
612b75d3e5 | ||
|
|
bbfe6bd143 | ||
|
|
219fcc369f | ||
|
|
e28eb0e3da | ||
|
|
b3160795fe | ||
|
|
aa68ef640d | ||
|
|
562418e324 | ||
|
|
47a6d450cf | ||
|
|
14e4abca27 | ||
|
|
108716eb84 | ||
|
|
8c6ef80cf5 | ||
|
|
2d61cb5979 | ||
|
|
5b8dc82ef2 | ||
|
|
1d3bc137ad | ||
|
|
35e6caf6f2 | ||
|
|
cd827eccbf | ||
|
|
3e89e2b9ad | ||
|
|
f0c0bb2521 | ||
|
|
82c2ce22c1 | ||
|
|
d14a269b29 | ||
|
|
a726408482 | ||
|
|
7e8b972c70 | ||
|
|
016db10de7 | ||
|
|
15e76629cb | ||
|
|
10c0c188b3 | ||
|
|
fd9d3a3028 | ||
|
|
61d01d3731 | ||
|
|
ba5529e401 | ||
|
|
e0a4a72f9c | ||
|
|
59c922dee0 | ||
|
|
e5dda3e975 | ||
|
|
7d75993562 | ||
|
|
54c64d3dfe | ||
|
|
ddf1396abb | ||
|
|
e3b2220813 | ||
|
|
f982a94ebb | ||
|
|
1c97760188 | ||
|
|
c6d33e6cec | ||
|
|
8e6e1cc3f2 | ||
|
|
ea9654af61 | ||
|
|
b8ccaf9f89 | ||
|
|
dac42f1971 | ||
|
|
09152c7e97 | ||
|
|
f9cddd02a9 | ||
|
|
4920244767 | ||
|
|
9b20a55b69 | ||
|
|
9f1be5feaa | ||
|
|
8ea8968a04 | ||
|
|
efd4f3c623 | ||
|
|
4a06c57a1b | ||
|
|
2ab3d396d2 | ||
|
|
297fa6f9b0 | ||
|
|
455b6bde43 | ||
|
|
b3f32404cb | ||
|
|
8b4326a82d | ||
|
|
fb45d110bc | ||
|
|
a51ccb1a86 | ||
|
|
e3cfb7199d | ||
|
|
3bb61dd649 | ||
|
|
b55d4d576d | ||
|
|
99d818d11e | ||
|
|
48b546fad4 | ||
|
|
2ee04e3b1c | ||
|
|
fbef8ff0dc | ||
|
|
c25a8ca8b5 | ||
|
|
248cc4c5bc | ||
|
|
1bbebfd3ae | ||
|
|
5b5a0afc45 | ||
|
|
d07729abfc | ||
|
|
945c34ccd6 | ||
|
|
01d2350993 | ||
|
|
93b7c421cb | ||
|
|
192542a362 | ||
|
|
8af45c01d8 | ||
|
|
96d508d548 | ||
|
|
a51db63d86 | ||
|
|
f906079a25 | ||
|
|
efd77e1337 | ||
|
|
acc4f341b6 | ||
|
|
567372ef51 | ||
|
|
53b712f8a2 | ||
|
|
d787aabe4e | ||
|
|
327c8b47d1 | ||
|
|
448b02cef9 | ||
|
|
1c669d3eae | ||
|
|
14d6b55989 | ||
|
|
c3d023a56b | ||
|
|
8382e9d904 | ||
|
|
2cf907bec1 | ||
|
|
d167d4c2f2 | ||
|
|
61181f3f1c | ||
|
|
156d193fc8 | ||
|
|
b5b22e2c23 | ||
|
|
e47275236a | ||
|
|
eb96be2eff | ||
|
|
f620f84222 | ||
|
|
2c79a66298 | ||
|
|
27ce289de0 | ||
|
|
bc4076f734 | ||
|
|
b2b5a8f715 | ||
|
|
46764b9fab | ||
|
|
d212cc0ad1 | ||
|
|
600e07fe08 | ||
|
|
4a3f3b0d3f | ||
|
|
bc423515fb | ||
|
|
13e8e39d43 | ||
|
|
8dd6446b6a | ||
|
|
8fc9b46ce7 | ||
|
|
832d315501 | ||
|
|
d4da62adb5 | ||
|
|
f7f6e9d2ee | ||
|
|
8a375d5e81 | ||
|
|
0bb860c9ab | ||
|
|
7616008cd3 | ||
|
|
cf36db419d | ||
|
|
f634d7fae0 | ||
|
|
dddb3b3d48 | ||
|
|
2468f8a8e6 | ||
|
|
c6ce359736 | ||
|
|
e99ba8cd1d | ||
|
|
3f35ca5bd2 | ||
|
|
e053d2864e | ||
|
|
e098426a6d | ||
|
|
069f483552 | ||
|
|
9a8c7dc8bf | ||
|
|
82ba0334a7 | ||
|
|
bfed3ad52f | ||
|
|
149a59ffbf | ||
|
|
a7dd139c14 | ||
|
|
3866e888de | ||
|
|
5089ea5027 | ||
|
|
840762c00d | ||
|
|
b38c44321e | ||
|
|
1ba7ed425e | ||
|
|
9645a1dd17 | ||
|
|
232d871bef | ||
|
|
ce0b5b77bd | ||
|
|
a4f2472431 | ||
|
|
aaae400f0a | ||
|
|
ba42daa83e | ||
|
|
85577259a6 | ||
|
|
5271e09d8d | ||
|
|
c6cb98cabd | ||
|
|
95f56fc1f8 | ||
|
|
a328c54dda | ||
|
|
12db01b7b2 | ||
|
|
93515777b8 | ||
|
|
16e327bd27 | ||
|
|
0edb9ad115 | ||
|
|
8189e5d819 | ||
|
|
72234e6260 | ||
|
|
48e341aca6 | ||
|
|
f2aed673ee | ||
|
|
51d214d45e | ||
|
|
a4619e761b | ||
|
|
fa67e21a76 | ||
|
|
62cccd204a | ||
|
|
ec9c1a0db3 | ||
|
|
d2bbf12598 | ||
|
|
e58ffb9a00 | ||
|
|
0281dd2e94 | ||
|
|
4060472a23 | ||
|
|
58ec5f38ed | ||
|
|
38938b99ac | ||
|
|
ba204b1473 | ||
|
|
fd2de073d9 | ||
|
|
ecec45fb7f | ||
|
|
9889307981 | ||
|
|
9a18dcadd4 | ||
|
|
7e6864764f | ||
|
|
8468d81286 | ||
|
|
e6636bb6af | ||
|
|
78706548ab | ||
|
|
a5184be524 | ||
|
|
da6455fd33 | ||
|
|
7e544346dd | ||
|
|
4812a33169 | ||
|
|
0fbd003cba | ||
|
|
074073a933 | ||
|
|
f82712e6b4 | ||
|
|
5745ff547c | ||
|
|
8f5617c986 | ||
|
|
02f69779a1 | ||
|
|
a2bfc55e96 | ||
|
|
1f9c632883 | ||
|
|
7fecdb1126 | ||
|
|
f88ec39ec7 | ||
|
|
f8b4b2fc2a | ||
|
|
271aef9821 | ||
|
|
ce9970ca1a | ||
|
|
bf47299b2f | ||
|
|
e56b399c59 | ||
|
|
39098134e8 | ||
|
|
0f505ea3f8 | ||
|
|
478859d0ed | ||
|
|
cf95f62185 | ||
|
|
6ba2fc5b65 | ||
|
|
c25724967a | ||
|
|
067e9d42e7 | ||
|
|
0063c8c8af | ||
|
|
ebdffb44e8 | ||
|
|
6cc609fdfc | ||
|
|
864a4f5c09 | ||
|
|
d2f365504b | ||
|
|
0319ac9a87 | ||
|
|
a5aea7a75f | ||
|
|
48f4790a36 | ||
|
|
024ec427da | ||
|
|
935ea3ad53 | ||
|
|
f270e479e6 | ||
|
|
ce5d3e75a0 | ||
|
|
f7a5bcbd4d | ||
|
|
75b7ca4786 | ||
|
|
dfee92bc1c | ||
|
|
0fd4bd443e | ||
|
|
e26eceeb2a | ||
|
|
51be1364d3 | ||
|
|
27706a766e | ||
|
|
79a4fbcb48 | ||
|
|
53fdce17f8 | ||
|
|
b03e29c5a9 | ||
|
|
3bdf89570a | ||
|
|
0c15a05986 | ||
|
|
bd69670cd2 | ||
|
|
a89f07856a | ||
|
|
8d0fc13e11 | ||
|
|
9fc77832e6 | ||
|
|
fbd928eeaf | ||
|
|
8d0beca2f6 | ||
|
|
94c159b42b | ||
|
|
9350960457 | ||
|
|
1b3daa2740 | ||
|
|
784f06b9f0 | ||
|
|
6cfe3fd39d | ||
|
|
338cb819af | ||
|
|
1a75d4b2e8 | ||
|
|
5c4c7b2995 | ||
|
|
39e3ca9da8 | ||
|
|
e40164f8cf | ||
|
|
c087cab84a | ||
|
|
bbdc732bd4 | ||
|
|
e9bdd6be11 | ||
|
|
2330aa9512 | ||
|
|
76ec04055a | ||
|
|
7472d3fd0f | ||
|
|
73c842391e | ||
|
|
ce28b96fc8 | ||
|
|
f0b2f71f17 | ||
|
|
e5187f0d0a | ||
|
|
4610870a1d | ||
|
|
5658c12a7d | ||
|
|
c2e6723c3a | ||
|
|
2a31ebf292 | ||
|
|
77f76edfcf | ||
|
|
9684f39c65 | ||
|
|
011995390b | ||
|
|
a2500b7b2d | ||
|
|
811674adb9 | ||
|
|
6ca671c877 | ||
|
|
080ba93d57 | ||
|
|
96d3e39211 | ||
|
|
79c02d386b | ||
|
|
38c0c13121 | ||
|
|
157e211f06 | ||
|
|
e4654cf24d | ||
|
|
3c80a61011 | ||
|
|
e6c54575ee | ||
|
|
e29087c805 | ||
|
|
e850253d88 | ||
|
|
bbb692f521 | ||
|
|
da1d67bbe6 | ||
|
|
792834f219 | ||
|
|
94b31cd658 | ||
|
|
19364f39c6 | ||
|
|
2fc8f6b9df | ||
|
|
9089ff3bbb | ||
|
|
90f581051c | ||
|
|
061bdcc478 | ||
|
|
6811394f71 | ||
|
|
1235a70323 | ||
|
|
d94952347f | ||
|
|
7fe6141640 | ||
|
|
4b1653ca6c | ||
|
|
7265ab57b9 | ||
|
|
27e3a95b06 | ||
|
|
38de3c6267 | ||
|
|
376e5ac906 | ||
|
|
b225283dcc | ||
|
|
b90f852a71 | ||
|
|
fdf7a9703a | ||
|
|
bb41f28342 | ||
|
|
c5ee7ebe7a | ||
|
|
f6ae10e1d9 | ||
|
|
b2070b53fb | ||
|
|
7fb873dc2c | ||
|
|
641f529de3 | ||
|
|
db9fb4fefa |
+31
-508
@@ -1,518 +1,41 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
## [1.8.0 (MONTH Xth, 2026)](#1-8-0)
|
## [1.8.1 (September 13th, 2026)](#1-8-1)
|
||||||
|
|
||||||
### Additions
|
|
||||||
- Added config options to award experience to fainted Pokémon for opponents they helped defeat (`awardExperienceToFaintedPokemon`) and to still award experience for defeated enemies even after battle loss/forfeit (`awardExperienceOnBattleLoss`)
|
|
||||||
- Party Overlay Exp Gained Animation will now display the amount of EXP the Pokémon gained
|
|
||||||
- Added a toast to notify players of how they can scroll through their party. Did you know you can hold R and scroll instead of using arrow keys??!
|
|
||||||
- Added a new layer property that makes a layer scroll in a direction. "scrolling": {"speedU": 0.1, "speedV": 0.1}
|
|
||||||
- Added missing crops to Botany Pots integration
|
|
||||||
- Added a way to obtain Porygon by inserting the Upgrade or Dubious Disc into a data monitor
|
|
||||||
- Added a new `cobblemon:structure`, which is a feature without any restrictions allowing the Builders to place certain structures in much more specific manner.
|
|
||||||
- Added Configs for Infinite Use TMs and Unlocking all TMs
|
|
||||||
- Added Type Gem blocks
|
|
||||||
- Added Type Gem Clusters
|
|
||||||
- Added TMs
|
|
||||||
- Added TM Machine
|
|
||||||
- Added Deepslate Core Block
|
|
||||||
- Added /givetm Command
|
|
||||||
- Added advancement triggers for learning TMs: `cobblemon:has_learn_specific_tm` (per-TM), `cobblemon:has_learn_all_tm` (all TMs learned), and `cobblemon:tms_learned` (count-based), backed by a new `totalTMLearnedCount` on player advancement data.
|
|
||||||
- Added `cobblemon:catch_alpha_pokemon` advancement trigger and `totalAlphaCaptureCount` tracking for capturing Alpha Pokémon.
|
|
||||||
- Added Move Dex to Pokédex
|
|
||||||
- Added the Habitat Block, a spawner block for servers and adventure maps that controls spawning in an area.
|
|
||||||
- Added Disk Rack for storing disks and being an audio sequencer for Noteblocks
|
|
||||||
- Added intrinsic scaling to all Pokémon (+-5%). Some rendering cases, such as shoulder mounting, revert to 1.0 scaling to preserve animation accuracy.
|
|
||||||
- Added scaling to "baby" Pokémon (smaller (-20%) at level 1 → normally sized at level 10)
|
|
||||||
- Added conditional seats for riding. Seats can be gated by molang such as "is_alpha".
|
|
||||||
- Added Alpha Pokémon
|
|
||||||
- Added alpha scaling (alphas are larger than their normal counterparts)
|
|
||||||
- Alphas will always lead herds and will spawn in herds
|
|
||||||
- Alphas spawn with two random TM moves from their learnset
|
|
||||||
- Alpha Pokémon will always defend themselves from players that attack them
|
|
||||||
- Added alpha level matching and stat boost (based on level)
|
|
||||||
- Added pitch-down and reverb to alpha cries
|
|
||||||
- Added alpha Pokémon bait effect
|
|
||||||
- Added alpha eye rendering including eye overlay, bloom, eye trail, and particles.
|
|
||||||
- Added cobweb block slowness immunity for spider Pokémon
|
|
||||||
- Added 49 new habitat structures. 34 as typical Minecraft structures and 15 as structures that get placed as biome features to allow for more natural placement in generation. Structures placed as biome features will not be able to be located with the `/locate structure` command.
|
|
||||||
- Vanilla village house template pools have been adjusted to account for the new abandoned village structure habitat. Weights have changed within the JSON file for every piece to ensure too many habitats don't generate in a single village.
|
|
||||||
- Added 10 new ruin structures.
|
|
||||||
- rooted_arch_ruins & crumbling_arch_ruins have been transferred over to biome features, allowing for better placement in generation.
|
|
||||||
- All ruin structures that did not generate with a gimmighoul/gilded chest before will now generate with one.
|
|
||||||
- All ruin structures gilded chest loot tables have been updated to include a guaranteed TM not learned naturally by any Pokémon through their level-up moveset. Each ruin gets its own specific TM, so you can now go hunting ruins to complete your move dex!
|
|
||||||
- All fossil structures have been transferred over to biome features, allowing for better placement in generation.
|
|
||||||
- The prehistoric_underwater_fissure & prehistoric_submerged_impact fossil structures now use the biome tag `#cobblemon:is_temperate_ocean`.
|
|
||||||
- Gimmighoul towers now generate at ground level rather than sinking one block into the ground.
|
|
||||||
- A new shipwreck cove structure called the "magma_shipwreck_cove" has been added.
|
|
||||||
- Shipwreck coves now generate slightly more frequently.
|
|
||||||
- Added equipment loot tables for shipwreck cove enemies.
|
|
||||||
- Maps from abandoned fishing boats leading to shipwreck coves now will skip explored chunks, allowing the player to find more shipwreck coves easier.
|
|
||||||
- The lush shipwreck cove's phantom mob spawner has been replaced with breezes.
|
|
||||||
- The lush shipwreck cove structure itself has been slightly cleaned up to be less noisy with the blocks it is built out of.
|
|
||||||
- All shipwreck coves' spawners have been adjusted to give compatible mobs enchanted iron or diamond armour and weapons while in its ominous state. The armour given to the mobs will also use the automaton trim. We upped the difficulty because it was too easy now that your Pokémon can fight for you.
|
|
||||||
- One TM of the elemental hyper beams has been added as guaranteed loot to the main treasure chest in every shipwreck cove. (Magma cove gets blast burn, lush cove gets frenzy plant, and submerged cove gets hydro cannon)
|
|
||||||
- Added 7 new advancements
|
|
||||||
- Pressing the inventory key now closes the Pokémon interact wheel GUI
|
|
||||||
- Pokémon cries now play when clicking Pokémon in the summary screen.
|
|
||||||
- Pressing the Summary key while either the starter selection or summary screen are open now closes those screens
|
|
||||||
- Ice type Pokémon are now immune to Packed Snow
|
|
||||||
- Held item visibility can now be controlled by the held_item_visible command argument.
|
|
||||||
|
|
||||||
### New rideable Pokémon
|
|
||||||
- Crobat
|
|
||||||
- Skarmory
|
|
||||||
- Milotic
|
|
||||||
- Archeops
|
|
||||||
- Goodra
|
|
||||||
- Goodra (Hisuian Form)
|
|
||||||
- Drampa
|
|
||||||
- Duraludon
|
|
||||||
- Archaludon
|
|
||||||
|
|
||||||
### Pokémon Added
|
|
||||||
#### Generation 3
|
|
||||||
- Wurmple
|
|
||||||
- Silcoon
|
|
||||||
- Beautifly
|
|
||||||
- Cascoon
|
|
||||||
- Dustox
|
|
||||||
- Skitty
|
|
||||||
- Delcatty
|
|
||||||
- Seviper
|
|
||||||
- Zangoose
|
|
||||||
|
|
||||||
#### Generation 4
|
|
||||||
- Cherubi
|
|
||||||
- Cherrim
|
|
||||||
- Stunky
|
|
||||||
- Skuntank
|
|
||||||
|
|
||||||
#### Generation 5
|
|
||||||
- Audino
|
|
||||||
- Pawniard
|
|
||||||
- Bisharp
|
|
||||||
|
|
||||||
#### Generation 6
|
|
||||||
- Pancham (+ Cosmetic with Black Glasses)
|
|
||||||
- Pangoro (+ Cosmetic with Black Glasses)
|
|
||||||
|
|
||||||
#### Generation 7
|
|
||||||
- Rockruff
|
|
||||||
- Lycanroc
|
|
||||||
|
|
||||||
#### Generation 8
|
|
||||||
- Rolycoly
|
|
||||||
- Carkol
|
|
||||||
- Coalossal
|
|
||||||
- Runerigus
|
|
||||||
- Snom
|
|
||||||
- Frosmoth
|
|
||||||
- Indeedee
|
|
||||||
- Duraludon
|
|
||||||
- Applin
|
|
||||||
- Flapple
|
|
||||||
- Appletun
|
|
||||||
|
|
||||||
#### Generation 9
|
|
||||||
|
|
||||||
- Nymble
|
|
||||||
- Lokix
|
|
||||||
- Kingambit
|
|
||||||
- Dipplin
|
|
||||||
- Archaludon
|
|
||||||
- Hydrapple
|
|
||||||
|
|
||||||
#### Regional Forms
|
|
||||||
- Sandshrew (Alolan Form)
|
|
||||||
- Sandslash (Alolan Form)
|
|
||||||
- Yamask (Galarian Form)
|
|
||||||
- Avalugg (Hisuian Form)
|
|
||||||
|
|
||||||
### Model updates for the following Pokémon
|
|
||||||
|
|
||||||
- Sandshrew
|
|
||||||
- Sandslash
|
|
||||||
- Nidoking
|
|
||||||
- Zubat
|
|
||||||
- Golbat
|
|
||||||
- Crobat
|
|
||||||
- Ditto
|
|
||||||
- Porygon
|
|
||||||
- Porygon2
|
|
||||||
- Porygon-Z
|
|
||||||
- Skarmory
|
|
||||||
- Smoochum
|
|
||||||
- Jynx
|
|
||||||
- Popplio
|
|
||||||
- Brionne
|
|
||||||
- Primarina
|
|
||||||
- Fletchling
|
|
||||||
- Fletchinder
|
|
||||||
- Talonflame
|
|
||||||
- Sableye
|
|
||||||
- Mawile
|
|
||||||
- Goomy
|
|
||||||
- Sliggoo
|
|
||||||
- Goodra
|
|
||||||
- Nacli
|
|
||||||
- Naclstack
|
|
||||||
- Garganacl
|
|
||||||
- Bidoof
|
|
||||||
- Cranidos
|
|
||||||
- Chatot
|
|
||||||
- Yamask
|
|
||||||
- Cofagrigus
|
|
||||||
- Tyranitar
|
|
||||||
- Turtonator
|
|
||||||
- Golett
|
|
||||||
- Corsola
|
|
||||||
- Arbok (New Patterns: Angry, Cartoon, Clown, Comedic, Crow, Grin, Ink, Modern, Rain, Scribble, Silence, Sloth, Suspicious, Will)
|
|
||||||
- ... and Substitute
|
|
||||||
|
|
||||||
#### Model changes to the regional bias resource pack:
|
|
||||||
|
|
||||||
- Added Mime Jr. (Galar Bias)
|
|
||||||
- Added Bergmite (Hisui Bias)
|
|
||||||
- Changed models for every existing regional bias
|
|
||||||
|
|
||||||
### Animation updates for the following Pokémon
|
### Animation updates for the following Pokémon
|
||||||
|
- Flapple, Appletun, Dipplin, Hydrapple (placeholder animations only).
|
||||||
- Kakuna
|
|
||||||
- Grimer
|
|
||||||
- Nidoran♀ (+ New shoulder mount)
|
|
||||||
- Nidorina
|
|
||||||
- Nidoran♂ (+ New shoulder mount)
|
|
||||||
- Sandshrew
|
|
||||||
- Diglett
|
|
||||||
- Dugtrio
|
|
||||||
- Graveler
|
|
||||||
- Happiny
|
|
||||||
- Chansey
|
|
||||||
- Blissey
|
|
||||||
- Poliwhirl
|
|
||||||
- Poliwrath
|
|
||||||
- Zubat
|
|
||||||
- Vulpix
|
|
||||||
- Drowzee
|
|
||||||
- Hypno
|
|
||||||
- Noctowl
|
|
||||||
- Skarmory
|
|
||||||
- Skitty
|
|
||||||
- Flygon
|
|
||||||
- Shellos
|
|
||||||
- Riolu
|
|
||||||
- Lucario
|
|
||||||
- Purrloin
|
|
||||||
- Liepard
|
|
||||||
- Joltik
|
|
||||||
- Galvantula
|
|
||||||
- Nidoking
|
|
||||||
- Fletchling
|
|
||||||
- Fletchinder
|
|
||||||
- Talonflame
|
|
||||||
- Archeops
|
|
||||||
- Drampa
|
|
||||||
- Sewaddle
|
|
||||||
- Swadloon
|
|
||||||
- Leavanny
|
|
||||||
- Goomy
|
|
||||||
- Sliggoo
|
|
||||||
- Goodra
|
|
||||||
- Shedinja
|
|
||||||
- Skwovet
|
|
||||||
- Greedent
|
|
||||||
- Bidoof
|
|
||||||
- Cranidos
|
|
||||||
- Chatot
|
|
||||||
- Yamask
|
|
||||||
- Cofagrigus
|
|
||||||
- Luvdisc
|
|
||||||
- Staryu
|
|
||||||
- Starmie
|
|
||||||
- Togetic
|
|
||||||
- Rellor
|
|
||||||
- Rabsca
|
|
||||||
- Yungoos
|
|
||||||
- Gumshoos
|
|
||||||
- Cottonee
|
|
||||||
- Whimsicott
|
|
||||||
- Corsola
|
|
||||||
|
|
||||||
#### Added sounds to the following moves
|
|
||||||
|
|
||||||
- Absorb
|
|
||||||
- Aurora Beam
|
|
||||||
- Double Team
|
|
||||||
- Draco Meteor
|
|
||||||
- Fire Punch
|
|
||||||
- Fire Spin
|
|
||||||
- Flame Charge
|
|
||||||
- Flame Wheel
|
|
||||||
- Giga Drain
|
|
||||||
- Ice Punch
|
|
||||||
- Leech Life
|
|
||||||
- Magical Leaf
|
|
||||||
- Mega Drain
|
|
||||||
- Minimize
|
|
||||||
- Poison Gas
|
|
||||||
- Rock Throw
|
|
||||||
- Scary Face
|
|
||||||
- Seed bomb
|
|
||||||
- Smokescreen
|
|
||||||
- String Shot
|
|
||||||
- Tail Whip
|
|
||||||
|
|
||||||
### Changes
|
|
||||||
- Stat increase and decrease particles have been changed, with the addition of alpha boost particles.
|
|
||||||
- Dragonite's mailbag cosmetic can now also be obtained with a chest in the cosmetic slot
|
|
||||||
- Adjusted Croagunk's walkspeed
|
|
||||||
- Adjusted Aerodactyl's walkspeed
|
|
||||||
- Sharp Beak can now be crafted
|
|
||||||
- Metal Alloy can now be crafted
|
|
||||||
- Ability Capsules can now be brewed
|
|
||||||
- Using an Ability Capsule will now return an Empty Bottle
|
|
||||||
- The following items can now be obtained by brushing the following Pokémon:
|
|
||||||
- Pink Wool - Wigglytuff
|
|
||||||
- White Wool - Swablu, Altaria
|
|
||||||
- Shed Shell - Ekans, Arbok, Dratini, Dragonair, Dunsparce, Treecko, Grovyle, Sceptile, Seviper, Scraggy, Scrafty, Helioptile, Heliolisk, Salandit, Salazzle, Sobble, Drizzile, Inteleon, Silicoblra, Sandaconda, Toxel, Toxtricity, Orthworm, Dudunsparce
|
|
||||||
- Phantom Membrane - Dreepy, Drakloak, Dragapult
|
|
||||||
- The following items can now be obtained by evolving the following Pokémon into any of their evolutions:
|
|
||||||
- Turtle Scute - Squirtle, Wartortle, Turtwig, Grotle, Tirtouga, Chewtle
|
|
||||||
- Shed Shell - Metapod, Kakuna, Ekans, Paras, Venonat, Krabby, Scyther, Kabuto, Dratini, Dragonair, Ledyba, Spinarak, Yanma, Pineco, Dunsparce, GLigar, Pupitar, Treecko, Grovyle, Silcoon, Cascoon, Surskit, Nincada, Trapinch, Vibrava, Corphish, Anorith, Bagon, Shelgon, Kricketot, Burmy, Combee, Skorupi, Swadloon, Whirlipede, Dwebble, Scraggy, Karrablast, Joltik, Larvesta, Spewpa, Clauncher, Helioptile, Charjabug, Crabrawler, Cutiefly, Dewpider, Salandit, Wimpod, Poipole, Sobble, Drizzile, Dottler, Silicobra, Toxel, Sizzlipede, Snom, Tarountula, Nymble, Rellor
|
|
||||||
- Saccharine Leaves now drop Tart, Sweet, or Syrupy Apples, depending on their honey coating stage, instead of vanilla Apples
|
|
||||||
- Fixed the height of the Tumblestone Bud items when held in hand, placed on head, viewed in a GUI, and placed in an Item Frame
|
|
||||||
- Refactored all advancements, removing several deemed unnecessary. Due to this refactor, all previously obtained advancements will be reset besides the root (for picking a starter Pokémon). We are sorry for the inconvience, but it makes the tab cleaner and simplifies future advancements.
|
|
||||||
- Restructured Botany Pots integration folder structure
|
|
||||||
- Decrease the default pastured mon wander radius to 32.
|
|
||||||
- Factor in the weight of Pokémon when calculating pushing forces between hitboxes.
|
|
||||||
- Remade the Starter Selection Screen with new assets
|
|
||||||
- Refactored berry trees to be less impactful on TPS (more performant)
|
|
||||||
- Changed the bait effects of the following items: (Vanilla) Sweet & Glow Berries, Golden & Enchanted Golden Apples (Cobblemon) Custap, Eggant, Hopo & Micle Berries, Sweet Hearts
|
|
||||||
- Wild Pokémon now reliably have at least one offensive move if they can have offensive moves at that level.
|
|
||||||
- Data Monitor can accept Disks (TMs, Music Disks, Upgrade, Dubious Disk, etc.) to change what's being displayed on the screen
|
|
||||||
- Rider positioning is now client-driven (Remove poseOffsets and offset per seat/pose) in favour of sending real-time passenger position.
|
|
||||||
- Cleaned up seat data. Removed all now unused fields from seats in all species files. Also made locator seat names explicit in the species files (however, this doesn't break the legacy format)
|
|
||||||
- Marks can now provide aspects.
|
|
||||||
- Added new shiny and Alpha chance configs
|
|
||||||
- Apricorns now make a new sound when harvested
|
|
||||||
- Lowered the volume of harvesting berries
|
|
||||||
- Added alternate versions of the basic PC Wallpapers based on the original design of Cobblemon's PC, before public release
|
|
||||||
- Improved compatibility with various mods
|
|
||||||
- Farmer's Delight's cutting board can now be used to strip Apricorn and Saccharine's logs, or salvage their planks from various blocks. It can also separate their boats from chests
|
|
||||||
- Farmer's Delight's cutting board can be used to get two white dye from Pep-Up Flowers and two magenta dye from Medicinal Leeks
|
|
||||||
- Farmer's Delight's cutting board can separate Tumblestone Blocks back into Tumblestones
|
|
||||||
- Farmer's Delight's cutting board can salvage Type Gems from their Gem Blocks
|
|
||||||
- Farmer's Delight's Onions, Tomatoes, and Cabbages can be used to cook Open-Faced Sandwiches. Nature's Spirit's Olives also can be used
|
|
||||||
- Farmer's Delight's cutting board can be used on Hearty Grains to obtain rice and straw, similarly to Farmer's Delight's Rice Panicles
|
|
||||||
- Farmer's Delight's Apple Pies and Apple Ciders can now be made using Applin Apples, alongside the Vanilla counterpart
|
|
||||||
- Amendments allows for cooking Leek and Potato Stew in a Cauldron
|
|
||||||
- Any mods that utilise Moonlight's Soft Fluid system can store Leek and Potato Stew, Medicinal Brew, Antidote, Awakening, Burn Heal, Ice Heal, Paralyze Heal, Full Heal, Potion, Super Potion, Hyper Potion, Max Potion, Full Restore, Ability Capsules, Moomoo Milk, and Berry Juice in liquid form (such as Suplementaries' Jar or Goblet, or Cauldrons while using Amendments)
|
|
||||||
- Supplementaries' Hourglass can now use Bright Powder, Quick Powder, Metal Powder, Heal Powder, Silver Powder, and Remedy
|
|
||||||
- Berry Trees are now compatible with the Planter properly
|
|
||||||
- Saccharine Way Signs (added by Supplementaries automagically) now use a premade texture to prevent odd visual issues
|
|
||||||
- Supplementaries' Jar can now store various Cobblemon cookies, candies, and similar items
|
|
||||||
- Some of Supplementaries' items have been added to the `#cobblemon:held/container_held_items` item tag, including sacks, safes, and lunch baskets
|
|
||||||
- Experience Nuggets can be used in place of Sculk for making the EXP Candies if using Create
|
|
||||||
- Rage Candy Bar has a Create Mixing recipe
|
|
||||||
- All Cobblemon ores can now be crushed in Create's Crushing Wheels
|
|
||||||
- All Gem and Tumblestone Clusters can be crushed for automatic, low return, gems
|
|
||||||
- Hearty Grains can be milled like Farmer's Delight Rice Panicles if both Farmer's Delight and Create are installed
|
|
||||||
- Big Roots and Revival Herbs can be milled to their respective powders
|
|
||||||
- Pep-Up Flowers, Medicinal Leeks, and all 70 berries can be milled in Create's Millstone for additional dye drops
|
|
||||||
- Auspicious Armour and Upgrades can be Haunted using Create's crafting systems
|
|
||||||
- Applin Apples can be used to make Honeyed Apples in Create
|
|
||||||
- Golden Apples can now be crafted using the Applin Apples
|
|
||||||
- Prismarine Crystals and Amethyst Shards can now be used to craft Pokedexes
|
|
||||||
- Updated Pokédex Screens item tag to support tagged variants of Redstone and Glowstone Dust
|
|
||||||
- Sounds for interacting with various Cobblemon blocks now play from the centre of the block, rather than the corner
|
|
||||||
- The `/pc` command no longer plays PC activation sounds
|
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Fixed Blitzle's base scale being `1` rather than the intended `0.8`
|
- Fixed a potential world generation stall caused by Type Gem clusters.
|
||||||
- Fixed Magnezone's emissive layer for the shiny having the wrong name, thus displaying wrongly
|
- Fixed Pokémon on shoulders not animating if they are visibly holding a held item.
|
||||||
- Fixed Litleo not blinking
|
- Fixed NPCs getting their own TM progress file.
|
||||||
- Fixed Omanyte and Omastar incorrectly using water animations on land.
|
- Fixed odd NeoForge crash due to a dependency being outdated. It will now correctly flag the dependency for being outdated.
|
||||||
- Fixed Pokédex layout for genderless variations
|
- Fixed the TM Machine refusing move selections that the `unlockAllMoveDexMovesByDefault` config had made visible, leaving the move slot blank and the craft button unresponsive.
|
||||||
- Fixed odd stacking behaviour with the poke_bait item.
|
- Fixed the Beast Ball not applying its 0.1× penalty to Pokémon that are not Ultra Beasts.
|
||||||
- Fixed a compatibility issue with World Game Rules which caused some log spam in specific cases.
|
- Fixed the Moon Ball reading the world's total elapsed time instead of the time of day, so its bonus applied during the day instead.
|
||||||
- Fixed improper validation of Pokémon when performing a trade.
|
- Fixed the Love Ball never awarding its 2.5× opposite gender bonus, and matching species by display name instead of identifier.
|
||||||
- Fixed an issue where particle like beam can disappear when you don't see the beginning of the beam, or you look away
|
- Fixed the Timer Ball being weaker than a regular Poké Ball on early turns and only reaching 4× on turn 14 instead of turn 10.
|
||||||
- Fixed Bedrock particle materials (alpha/opaque/blend/add) sharing one render batch, which caused incorrect culling on mixed batches; each material now batches and draws with its own blend and cull state, and the alpha material renders as a true cutout
|
- Fixed the Luxury Ball only doubling Friendship gains of 1, leaving level up and berry gains unaffected.
|
||||||
- Fixed an occasional crash on retrieving revived fossils
|
- Fixed Rufflet, Braviary, and Hisuian Braviary flooding logs with errors about missing sound events.
|
||||||
- Fixed brushing not working on Neoforge
|
- Fixed Pokémon property typos in Pangoro and Dedenne herd spawn files.
|
||||||
- Fixed braking not working for submarines (whoops).
|
- Fixed unintentional watermelon cosmetic for Hisuian Electrode.
|
||||||
- Fixed strafing not having the same friction as forward movement (funny whoops).
|
- Fixed Blastoise having an unintentional passenger seat.
|
||||||
- Fixed submarine's surface-water animations not playing when supposed to.
|
- Fixed form typo in Rockruff-Dusk spawn, preventing it from being able to spawn.
|
||||||
- Fixed submarine camera freaking out when looking up or down on the surface.
|
- Fixed the `stat_compare` and `stat_equal` evolution requirements crashing the game when given `special_attack` or `special_defence`, and made them treat any non-permanent stat as a failed requirement instead of crashing.
|
||||||
- Fixed pastured mons despawning and running away.
|
- Fixed Rowap and Jacoba berries not correctly altering Pokémon sizes when used as bait.
|
||||||
- Fixed Apricorn trees crashing when other mods bonemeal it
|
- Fixed Ampharos' eyes not emitting particles.
|
||||||
- Fixed the issue that caused Hover Behaviour rides without a ground style to be rendered useless upon touching the ground on a server.
|
- Fixed Alolan Raticate's cry not playing.
|
||||||
- Removed the "inAir" penalty for block destruction speed when on a hover mount.
|
- Fixed several incorrect light-based spawning conditions for ghosts and bugs.
|
||||||
- Fixed horizontal and vertical collisions with hover mounts so they no longer accumulate or retain momentum
|
- Removed unused, placeholder habitat pools.
|
||||||
- Fixed NeoForge brewing stand unexpectedly crashing users when shift clicking items within its menu
|
- Fixed Mantyke, Mantine, and Quaxly getting stuck in a recoil 'expression' during battles due to having an expression assigned as a recoil animation.
|
||||||
- Fixed NPCs switching Pokémon very often during battles
|
- Fixed Lucario's aura particles not emitting.
|
||||||
- Fixed Campfire pot causing crashes under certain circumstances
|
- Fixed Lycanroc's head movement.
|
||||||
- Fixed Type Gems not being consumed upon use
|
- Added head movement to Archaludon.
|
||||||
- Fixed Ancient Pokéball's to their respective modifiers
|
- Fixed Duraludon line not having their sleep animations.
|
||||||
- Fixed a Server warning when recalling Pokémon
|
- Fixed Diglett line not having their faint animations.
|
||||||
- Fixed sliding particles incorrectly handling block collision
|
- Fixed Kingambit moving its legs while walking.
|
||||||
- Fixed Full Heal not curing status conditions in battle
|
|
||||||
- Fixed a rare issue with battles locking up when you are forced to switch, with the switch menu appearing instantly.
|
|
||||||
- Fixed the combined effects of Pledge moves having broken Showdown message handling and localisation
|
|
||||||
- Fixed rare Pokémon being far too likely to spawn multiple times in a single spawn cycle. The dev told me that the exact bug is too complicated to explain.
|
|
||||||
- Resolved the niche issue where Structures would spawn in an incorrect location, creating very funky world gen.
|
|
||||||
- Fixed Galarian Ponyta missing its cry.
|
|
||||||
- Fixed various log warnings caused by redundant files and sound events.
|
|
||||||
- Traded Pokémon will now retain the original friendship level when traded back to its OT
|
|
||||||
- Clusters now display correctly on maps
|
|
||||||
- Fixed removing mulch from berry trees with a shovel not working.
|
|
||||||
- Fixed collecting honey from Saccharine Leaf blocks deleting Honey Bottles when the inventory was full
|
|
||||||
- Fixed Stripped Saccharine Wood recipe being missing
|
|
||||||
- Fixed CancelableSoundInstance causing lag by attempting to create sounds every tick when out of range of hearing
|
|
||||||
- Fixed Stat Reducing Aprijuice not being possible to apply on a max out Pokémon, and the possibility of going into negatives
|
|
||||||
- Fixed Exploit where you could take out the bait or drop your Pokérod with bait to avoid consuming bait, now the bobber will just disappear if you do so
|
|
||||||
- Fixed Apricorn and Saccharine boats incorrectly using chest boat models
|
|
||||||
- Fixed wild and trainer battle AI refusing to select moves with the `adjacentAlly` target type, even when it's their only option
|
|
||||||
- Fixed gilded chests being more accessible than intended
|
|
||||||
- Fixed fished up Pokémon not being added as "seen" to the Pokedex
|
|
||||||
- Fixed surprised Gimmighoul encounters not being added as "seen" to the Pokedex
|
|
||||||
- Fixed a crash involving berry trees that have been world edited.
|
|
||||||
- Fixed visual desync in multiplayer for players mounting Pokémon outside other players' loaded chunks
|
|
||||||
- Fixed Pokémon entities leveled by rare candy not getting stronger as Minecraft entities unless recalled.
|
|
||||||
- Fixed a freeze during game load that occurred when multiple mods tried to load Cobblemon API classes at the same time.
|
|
||||||
- Fixed random tick crashes from berry trees
|
|
||||||
- Lowered the volume of Blitzle and Zebstrika's cry
|
|
||||||
- Regional Foods will now prioritise being eaten instead of used for healing Pokémon, shift clicking will use it as healing
|
|
||||||
- Resolved Z-Fighting on Pokédex Models
|
|
||||||
- Restored Ninjask's ability to do barrel rolls
|
|
||||||
- Fixed Raichu (male) and Alolan Raichu (both genders) not displaying the correct Partner Cap when Pewter Crunchies are in the cosmetic slot.
|
|
||||||
- Fixed a crash caused by adding enchanted items to the Resurrection Machine
|
|
||||||
- Fixed a crash that could occur when starting a PvN battle with only fainted Pokémon.
|
|
||||||
- Fixed the Remember Riding Camera config not being respected when dismounting and resolved the incompatibility with the Auto Third Person mod
|
|
||||||
- Fixed Full Heal block not dropping Full Heals
|
|
||||||
- Fixed status cure items not returning an empty bottle when used
|
|
||||||
- Fixed Panpour consuming its held item when evolving with a Water Stone
|
|
||||||
- Fixed Smoked Tail Curry returning a Wooden Bowl when consumed despite it not being included in the recipe
|
|
||||||
- Fixed `/giveallpokemon` not respecting the min and max parameters
|
|
||||||
- Fixed the choose starter toast not disappearing when capturing a Pokémon instead of opening the starter selection screen
|
|
||||||
- Fixed an issue where certain Sinister Tea seasonings were only applying as instant effects and would not apply over time
|
|
||||||
- Long config option labels now scroll instead of overflowing
|
|
||||||
|
|
||||||
### Developer
|
|
||||||
- Added `PokeSnackSpawnerFactory` which allows influence registration on PokeSnack encounters
|
|
||||||
- Added `FishingSpawnerFactory` which allows influence registration on fishing encounters
|
|
||||||
- Added `BattleFleeAttemptEvent` fired from `PokemonBattle.checkFleeAttempt`, allowing developers to intercept and control flee attempts
|
|
||||||
- Tweaked the spawning selector interface to take a bucket function rather than a bucket directly.
|
|
||||||
- Added a new `cobblemon:height_range` processor type to allow developers to restrict structure-spawning ranges.
|
|
||||||
- Separated all the functions of MoLangFunctions.kt into their own files.
|
|
||||||
- Spawn buckets and their base weights are now provided by the spawner, with different base weights for world, fishing, snack, and habitat spawn buckets.
|
|
||||||
- Removed "SpawnBucket" class in favour of just storing maps of bucket names to weights.
|
|
||||||
- Fixed nicknames not being applied to Pokémon spawned from `spawn_pool_world` files.
|
|
||||||
- Added support for `profilePokedexScale`, `profilePokedexTranslation`, `profileSummaryScale`, and `profileSummaryTranslation` in poser files for finer control over profile displays.
|
|
||||||
- Fixed riding camera offsets defined on Pokémon forms not being applied
|
|
||||||
|
|
||||||
### Molang & Datapacks
|
|
||||||
- Added `moveset_builders` datapack folder for different styles of movesets.
|
|
||||||
- Added `party_pools` datapack folder for defining groups of Pokémon for complex NPC party definitions.
|
|
||||||
- Added `party_compositions` datapack folder for arranging parties on NPCs that rely on party pools.
|
|
||||||
- Added `composed_pool` NPC party provider type which combines a party pool with a party composition to create more complex NPC parties.
|
|
||||||
- Added basic chatter NPC Behaviour
|
|
||||||
- Added `q.item.is_enchanted()`
|
|
||||||
- Added `q.item.has_enchantment(minecraft:sharpness, 3)`
|
|
||||||
- Added `has_chosen_starter` & `get_starter_uuid` as available Molang functions
|
|
||||||
- Added `has_tm_move_unlocked`, `unlock_tm_move`, & `lock_tm_move` as available Molang functions for Players
|
|
||||||
- Added `marks`, `has_mark`, & `remove_marks` as available Molang functions for Pokémon
|
|
||||||
- Added Data Component support for species drops, eg `"components": {"minecraft:custom_model_data": 123}`
|
|
||||||
- Added the new `sortOrder` field to mark entries, (defaults to 0 if not specified) which controls the order in which marks are rendered on the HUD, with higher numbers being rendered on top of lower numbers
|
|
||||||
- Added optional `order` field to starter categories. It will allow explicitly sorting categories in the starter selection screen
|
|
||||||
- SpeciesAdditions append vs override now matches wiki documentation
|
|
||||||
- Added `weighted_choice` as a new feature type. It requires setting weights for each choice and allows developers to simplify the process of assigning random aspect choice based on marble chance
|
|
||||||
- Added `q.world.spawn_loot_table_items(loot_table_id, x, y, z)` which spawns the items from the loot table at the position. (Use type: "minecraft:chest" for the loot table.)
|
|
||||||
- Added `q.pokemon.entity` to access the entity of Pokémon.
|
|
||||||
- Flamethrower and Seismic Toss had their action effect JSON cleaned up
|
|
||||||
- Ride sounds can now be set as exclusive to passengers
|
|
||||||
- Ride sounds no longer play when submerged unless specified with a new setting
|
|
||||||
- NPC Trainers can now call a `command` animation when issuing a command in battle.
|
|
||||||
- Added a q.failed function to move action effects.
|
|
||||||
- Herd spawned Pokémon have their levels controlled differently. The `levelRange` property now acts as a clamp instead of a filter, with a new `herdLevelRange` property to do the filter behaviour.
|
|
||||||
- `q.sound` now accepts three parameters (sound event, volume and pitch) instead of just the sound event and pitch.
|
|
||||||
|
|
||||||
### Particles
|
|
||||||
|
|
||||||
#### New Move Animations
|
|
||||||
- Blizzard
|
|
||||||
- Disarming Voice
|
|
||||||
- Draco Meteor
|
|
||||||
- Dragon Breath
|
|
||||||
- Dragon Rage
|
|
||||||
- Drain Punch
|
|
||||||
- Fairy Wind
|
|
||||||
- Fire Fang
|
|
||||||
- Gust
|
|
||||||
- Horn Drill
|
|
||||||
- Hydro Pump
|
|
||||||
- Ice Fang
|
|
||||||
- Leafage
|
|
||||||
- Leaf Storm
|
|
||||||
- Light Screen
|
|
||||||
- Night Shade
|
|
||||||
- Play Rough
|
|
||||||
- Pyro Ball
|
|
||||||
- Reflect
|
|
||||||
- Rock Slide
|
|
||||||
- Sonic Boom
|
|
||||||
- Sucker Punch
|
|
||||||
- Supersonic
|
|
||||||
- Thunder Fang
|
|
||||||
|
|
||||||
#### Tweaks and Fixes (Moves)
|
|
||||||
|
|
||||||
- Confusion
|
|
||||||
- Dragon Claw
|
|
||||||
- Eruption
|
|
||||||
- Fire Punch
|
|
||||||
- Flame Burst
|
|
||||||
- Flame Charge
|
|
||||||
- Flamethrower
|
|
||||||
- Frost Breath
|
|
||||||
- Hypnosis
|
|
||||||
- Ice Punch
|
|
||||||
- Icy Wind
|
|
||||||
- Mud Sport
|
|
||||||
- Poison Fang
|
|
||||||
- Protect
|
|
||||||
- Psychic
|
|
||||||
- Quick Attack
|
|
||||||
- Rage Powder
|
|
||||||
- Razor Leaf
|
|
||||||
- Sand Attack
|
|
||||||
- Scratch
|
|
||||||
- Shadow Claw
|
|
||||||
- Sing
|
|
||||||
- Spore
|
|
||||||
- String Shot
|
|
||||||
- Tackle
|
|
||||||
- Tail Whip
|
|
||||||
- Thunder
|
|
||||||
- Thunder Punch
|
|
||||||
- Thunder Wave
|
|
||||||
- Water Gun
|
|
||||||
- Water Pulse
|
|
||||||
- Water Sport
|
|
||||||
|
|
||||||
#### Miscellaneous Particles
|
|
||||||
|
|
||||||
+ Added Wild Might particles for Alpha Pokémon
|
|
||||||
+ Updated stat increase and decrease particles
|
|
||||||
|
|
||||||
### Localization
|
### Localization
|
||||||
- Updated translations for:
|
- Updated translations for:
|
||||||
- Japanese
|
|
||||||
- German
|
|
||||||
- Spanish
|
|
||||||
- Ecuadorian Spanish
|
|
||||||
- Portuguese
|
|
||||||
- Brazilian Portuguese
|
- Brazilian Portuguese
|
||||||
- Simplified Chinese
|
- Simplified Chinese
|
||||||
- Traditional Chinese
|
- Japanese
|
||||||
- Korean
|
|
||||||
@@ -0,0 +1,529 @@
|
|||||||
|
# Changelog
|
||||||
|
## [1.8.0 - Make Your Move Update (September 6th, 2026)](#1-8-0)
|
||||||
|
#### I think the red eyes mean they're friendly!
|
||||||
|
|
||||||
|
### Additions
|
||||||
|
- Added Alpha Pokémon
|
||||||
|
- Alpha Pokémon are bigger, stronger, and more aggressive than regular Pokémon.
|
||||||
|
- They are also scarier.
|
||||||
|
- They always know a TM move and will adapt to be stronger than your party.
|
||||||
|
- Alphas will always lead herds and spawn in herds.
|
||||||
|
- Added alpha Pokémon attraction bait effect to Hopo Berries.
|
||||||
|
- Added intrinsic scaling to all Pokémon (anywhere from 5% smaller to 5% bigger than normal). Some cases, such as shoulder mounting, will not scale so that the shoulder animations don't look silly.
|
||||||
|
- Added scaling to "baby" Pokémon (10% smaller at level 1 → normally sized at level 10).
|
||||||
|
- Added TMs.
|
||||||
|
- Added TM Machine. TMs are made from elemental type gems, and their recipes are unlocked by having Pokémon that know the move.
|
||||||
|
- Added config options for making TMs infinite-use and instant unlocking of all TM recipes.
|
||||||
|
- Added Type Gem blocks as well as crystal clusters and deepslate core blocks that are used for growing elemental type gems.
|
||||||
|
- Added a new Starter Selection menu that looks way better.
|
||||||
|
- Added a "Move Dex" to the Pokédex to help identify what moves a Pokémon can learn and what Pokémon can get a move.
|
||||||
|
- Added the Habitat Block, a spawner block for servers and adventure maps that controls spawning in an area.
|
||||||
|
- Added 49 new habitat structures. In these habitats you will find rarer Pokémon and sometimes different Pokémon will appear on different days.
|
||||||
|
- Added a toast to notify players of how they can scroll through their party. Did you know you can hold R and scroll instead of using arrow keys? It's true!!!
|
||||||
|
- Added a way to obtain Porygon by inserting an Upgrade or Dubious Disc into a data monitor.
|
||||||
|
- Added Disk Rack for storing disks and being an audio sequencer for Noteblocks. What does that have to do with Pokémon? How about you mind your own business!
|
||||||
|
- Added missing crops to Botany Pots integration.
|
||||||
|
- Added conditional seats for riding. Seats can be gated by Molang such as "is_alpha".
|
||||||
|
- Added 10 new ruin structures.
|
||||||
|
- Added a new shipwreck cove structure called the Magma Shipwreck Cove.
|
||||||
|
- Added 7 new advancements.
|
||||||
|
- Pokémon cries now play when clicking Pokémon in the summary screen.
|
||||||
|
- Held item visibility can now be controlled by the `held_item_visible` command argument.
|
||||||
|
- Added config option to disable Pokémon spawning on a per-world basis.
|
||||||
|
- Added config options to award experience to fainted Pokémon for opponents they helped defeat (`awardExperienceToFaintedPokemon`) and to still award experience for defeated enemies even after battle loss/forfeit (`awardExperienceOnBattleLoss`).
|
||||||
|
- Added `/givetm` command.
|
||||||
|
- Added advancement triggers for learning TMs: `cobblemon:has_learn_specific_tm` (per-TM), `cobblemon:has_learn_all_tm` (all TMs learned), and `cobblemon:tms_learned` (count-based), backed by a new `totalTMLearnedCount` on player advancement data.
|
||||||
|
- Added `cobblemon:catch_alpha_pokemon` advancement trigger and `totalAlphaCaptureCount` stat for captured Alpha Pokémon.
|
||||||
|
|
||||||
|
### New rideable Pokémon
|
||||||
|
- Crobat
|
||||||
|
- Skarmory
|
||||||
|
- Milotic
|
||||||
|
- Archeops
|
||||||
|
- Goodra
|
||||||
|
- Goodra (Hisuian Form)
|
||||||
|
- Drampa
|
||||||
|
- Duraludon
|
||||||
|
- Archaludon
|
||||||
|
|
||||||
|
### Pokémon Added
|
||||||
|
#### Generation 3
|
||||||
|
- Wurmple
|
||||||
|
- Silcoon
|
||||||
|
- Beautifly
|
||||||
|
- Cascoon
|
||||||
|
- Dustox
|
||||||
|
- Skitty
|
||||||
|
- Delcatty
|
||||||
|
- Seviper
|
||||||
|
- Zangoose
|
||||||
|
|
||||||
|
#### Generation 4
|
||||||
|
- Cherubi
|
||||||
|
- Cherrim
|
||||||
|
- Stunky
|
||||||
|
- Skuntank
|
||||||
|
|
||||||
|
#### Generation 5
|
||||||
|
- Audino
|
||||||
|
- Pawniard
|
||||||
|
- Bisharp
|
||||||
|
|
||||||
|
#### Generation 6
|
||||||
|
- Pancham (+ Cosmetic with Black Glasses)
|
||||||
|
- Pangoro (+ Cosmetic with Black Glasses)
|
||||||
|
|
||||||
|
#### Generation 7
|
||||||
|
- Rockruff
|
||||||
|
- Lycanroc
|
||||||
|
|
||||||
|
#### Generation 8
|
||||||
|
- Rolycoly
|
||||||
|
- Carkol
|
||||||
|
- Coalossal
|
||||||
|
- Runerigus
|
||||||
|
- Snom
|
||||||
|
- Frosmoth
|
||||||
|
- Indeedee
|
||||||
|
- Duraludon
|
||||||
|
- Applin
|
||||||
|
- Flapple
|
||||||
|
- Appletun
|
||||||
|
|
||||||
|
#### Generation 9
|
||||||
|
|
||||||
|
- Nymble
|
||||||
|
- Lokix
|
||||||
|
- Kingambit
|
||||||
|
- Dipplin
|
||||||
|
- Archaludon
|
||||||
|
- Hydrapple
|
||||||
|
|
||||||
|
#### Regional Forms
|
||||||
|
- Sandshrew (Alolan Form)
|
||||||
|
- Sandslash (Alolan Form)
|
||||||
|
- Yamask (Galarian Form)
|
||||||
|
- Avalugg (Hisuian Form)
|
||||||
|
|
||||||
|
### Model updates for the following Pokémon
|
||||||
|
|
||||||
|
- Sandshrew
|
||||||
|
- Sandslash
|
||||||
|
- Nidoking
|
||||||
|
- Zubat
|
||||||
|
- Golbat
|
||||||
|
- Crobat
|
||||||
|
- Ditto
|
||||||
|
- Porygon
|
||||||
|
- Porygon2
|
||||||
|
- Porygon-Z
|
||||||
|
- Skarmory
|
||||||
|
- Smoochum
|
||||||
|
- Jynx
|
||||||
|
- Popplio
|
||||||
|
- Brionne
|
||||||
|
- Primarina
|
||||||
|
- Fletchling
|
||||||
|
- Fletchinder
|
||||||
|
- Talonflame
|
||||||
|
- Sableye
|
||||||
|
- Mawile
|
||||||
|
- Goomy
|
||||||
|
- Sliggoo
|
||||||
|
- Goodra
|
||||||
|
- Nacli
|
||||||
|
- Naclstack
|
||||||
|
- Garganacl
|
||||||
|
- Bidoof
|
||||||
|
- Cranidos
|
||||||
|
- Chatot
|
||||||
|
- Yamask
|
||||||
|
- Cofagrigus
|
||||||
|
- Tyranitar
|
||||||
|
- Turtonator
|
||||||
|
- Golett
|
||||||
|
- Corsola
|
||||||
|
- Arbok (New Patterns: Angry, Cartoon, Clown, Comedic, Crow, Grin, Ink, Modern, Rain, Scribble, Silence, Sloth, Suspicious, Will)
|
||||||
|
- ... and Substitute
|
||||||
|
|
||||||
|
#### Model changes to the regional bias resource pack:
|
||||||
|
- Added Mime Jr. (Galar Bias)
|
||||||
|
- Added Bergmite (Hisui Bias)
|
||||||
|
- Changed models for every existing regional bias
|
||||||
|
|
||||||
|
### Animation updates for the following Pokémon
|
||||||
|
|
||||||
|
- Kakuna
|
||||||
|
- Grimer
|
||||||
|
- Nidoran♀ (+ New shoulder mount)
|
||||||
|
- Nidorina
|
||||||
|
- Nidoran♂ (+ New shoulder mount)
|
||||||
|
- Sandshrew
|
||||||
|
- Diglett
|
||||||
|
- Dugtrio
|
||||||
|
- Graveler
|
||||||
|
- Happiny
|
||||||
|
- Chansey
|
||||||
|
- Blissey
|
||||||
|
- Poliwhirl
|
||||||
|
- Poliwrath
|
||||||
|
- Zubat
|
||||||
|
- Vulpix
|
||||||
|
- Drowzee
|
||||||
|
- Hypno
|
||||||
|
- Noctowl
|
||||||
|
- Skarmory
|
||||||
|
- Skitty
|
||||||
|
- Flygon
|
||||||
|
- Shellos
|
||||||
|
- Riolu
|
||||||
|
- Lucario
|
||||||
|
- Purrloin
|
||||||
|
- Liepard
|
||||||
|
- Joltik
|
||||||
|
- Galvantula
|
||||||
|
- Nidoking
|
||||||
|
- Fletchling
|
||||||
|
- Fletchinder
|
||||||
|
- Talonflame
|
||||||
|
- Archeops
|
||||||
|
- Drampa
|
||||||
|
- Sewaddle
|
||||||
|
- Swadloon
|
||||||
|
- Leavanny
|
||||||
|
- Goomy
|
||||||
|
- Sliggoo
|
||||||
|
- Goodra
|
||||||
|
- Shedinja
|
||||||
|
- Skwovet
|
||||||
|
- Greedent
|
||||||
|
- Bidoof
|
||||||
|
- Cranidos
|
||||||
|
- Chatot
|
||||||
|
- Yamask
|
||||||
|
- Cofagrigus
|
||||||
|
- Luvdisc
|
||||||
|
- Staryu
|
||||||
|
- Starmie
|
||||||
|
- Togetic
|
||||||
|
- Rellor
|
||||||
|
- Rabsca
|
||||||
|
- Yungoos
|
||||||
|
- Gumshoos
|
||||||
|
- Cottonee
|
||||||
|
- Whimsicott
|
||||||
|
- Corsola
|
||||||
|
|
||||||
|
#### Added sounds to the following moves
|
||||||
|
|
||||||
|
- Absorb
|
||||||
|
- Aurora Beam
|
||||||
|
- Double Team
|
||||||
|
- Draco Meteor
|
||||||
|
- Fire Punch
|
||||||
|
- Fire Spin
|
||||||
|
- Flame Charge
|
||||||
|
- Flame Wheel
|
||||||
|
- Giga Drain
|
||||||
|
- Ice Punch
|
||||||
|
- Leech Life
|
||||||
|
- Magical Leaf
|
||||||
|
- Mega Drain
|
||||||
|
- Minimize
|
||||||
|
- Poison Gas
|
||||||
|
- Rock Throw
|
||||||
|
- Scary Face
|
||||||
|
- Seed bomb
|
||||||
|
- Smokescreen
|
||||||
|
- String Shot
|
||||||
|
- Tail Whip
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Removed the penalty for block destruction speed when on a hover mount, making them better for digging.
|
||||||
|
- Golden Apples can now be crafted using the Applin Apples.
|
||||||
|
- Prismarine Crystals and Amethyst Shards can now be used to craft Pokedexes.
|
||||||
|
- Updated Pokédex Screens item tag to support tagged variants of Redstone and Glowstone Dust.
|
||||||
|
- Sharp Beak can now be crafted using bones and Flying Gems.
|
||||||
|
- Metal Alloy can now be crafted using iron and Thunder Stones.
|
||||||
|
- Ability Capsules can now be brewed from Medicinal Brew and Dragon Breath.
|
||||||
|
- Using an Ability Capsule will now return an Empty Bottle.
|
||||||
|
- Decreased the default pastured wander radius to 32 blocks.
|
||||||
|
- Added alternate versions of the basic PC Wallpapers based on the original design of Cobblemon's PC, before public release.
|
||||||
|
- Rooted Arch Ruins, Crumbling Arch Ruins, and all fossil structures have been improved so that they generate more naturally in terrain.
|
||||||
|
- Gimmighoul towers now generate at ground-level rather than sinking one block into the ground.
|
||||||
|
- All ruin structures that did not generate with a gimmighoul/gilded chest before will now generate with one.
|
||||||
|
- All ruin structures gilded chest loot tables have been updated to include a guaranteed TM not learned naturally by any Pokémon through their level-up moveset. Each ruin gets its own specific TM, so you can now go hunting ruins to complete your move dex!
|
||||||
|
- The Prehistoric Underwater Fissure and Prehistoric Submerged Impact fossil structures now use the biome tag `#cobblemon:is_temperate_ocean`.
|
||||||
|
- The lush shipwreck cove's phantom mob spawner has been replaced with breezes.
|
||||||
|
- Shipwreck coves now generate slightly more frequently.
|
||||||
|
- Added equipment loot tables for shipwreck cove enemies.
|
||||||
|
- Maps from abandoned fishing boats leading to shipwreck coves now will skip explored chunks, allowing the player to find more shipwreck coves more easily.
|
||||||
|
- All shipwreck coves' spawners have been adjusted to give compatible mobs enchanted iron or diamond armour and weapons while in its ominous state. The armour given to the mobs will also use the automaton trim. We upped the difficulty because it was too easy now that your Pokémon can fight for you.
|
||||||
|
- One TM of the elemental hyper beams has been added as guaranteed loot to the main treasure chest in every shipwreck cove. (Magma Cove gets Blast Burn, Lush Cove gets Frenzy Plant, and Submerged Cove gets Hydro Cannon.)
|
||||||
|
- The following items can now be obtained by brushing the following Pokémon:
|
||||||
|
- Pink Wool - Wigglytuff
|
||||||
|
- White Wool - Swablu, Altaria
|
||||||
|
- Shed Shell - Ekans, Arbok, Dratini, Dragonair, Dunsparce, Treecko, Grovyle, Sceptile, Seviper, Scraggy, Scrafty, Helioptile, Heliolisk, Salandit, Salazzle, Sobble, Drizzile, Inteleon, Silicoblra, Sandaconda, Toxel, Toxtricity, Orthworm, Dudunsparce
|
||||||
|
- Phantom Membrane - Dreepy, Drakloak, Dragapult
|
||||||
|
- The following items can now be obtained by evolving the following Pokémon into any of their evolutions:
|
||||||
|
- Turtle Scute - Squirtle, Wartortle, Turtwig, Grotle, Tirtouga, Chewtle
|
||||||
|
- Shed Shell - Metapod, Kakuna, Ekans, Paras, Venonat, Krabby, Scyther, Kabuto, Dratini, Dragonair, Ledyba, Spinarak, Yanma, Pineco, Dunsparce, GLigar, Pupitar, Treecko, Grovyle, Silcoon, Cascoon, Surskit, Nincada, Trapinch, Vibrava, Corphish, Anorith, Bagon, Shelgon, Kricketot, Burmy, Combee, Skorupi, Swadloon, Whirlipede, Dwebble, Scraggy, Karrablast, Joltik, Larvesta, Spewpa, Clauncher, Helioptile, Charjabug, Crabrawler, Cutiefly, Dewpider, Salandit, Wimpod, Poipole, Sobble, Drizzile, Dottler, Silicobra, Toxel, Sizzlipede, Snom, Tarountula, Nymble, Rellor
|
||||||
|
- Saccharine Leaves now drop Tart, Sweet, or Syrupy Apples, depending on their honey coating stage, instead of vanilla Apples.
|
||||||
|
- Fixed the height of the Tumblestone Bud items when held in hand, placed on head, viewed in a GUI, and placed in an Item Frame.
|
||||||
|
- Refactored all advancements, removing several deemed unnecessary. Due to this cleanup, all previously obtained advancements will be reset besides the root (for picking a starter Pokémon). This sucks, and we're sorry. We had to do this eventually so better now than later.
|
||||||
|
- Forces between colliding hitboxes now factors in the weight of Pokémon.
|
||||||
|
- Improved berry tree performance on singleplayer and servers.
|
||||||
|
- Updated stat increase and decrease particle effects with the addition of alpha boost particles.
|
||||||
|
- Improved the performance of pasture blocks on singleplayer and servers.
|
||||||
|
- Changed the bait effects of the following items: (Vanilla) Sweet & Glow Berries, Golden & Enchanted Golden Apples (Cobblemon) Custap, Eggant, Hopo & Micle Berries, Sweet Hearts.
|
||||||
|
- Wild Pokémon now reliably have at least one offensive move if they can have offensive moves at that level. No more free lunches with Pokémon that can't even hurt you.
|
||||||
|
- Data Monitor can accept Disks (TMs, Music Disks, Upgrade, Dubious Disk, etc.) to change what's being displayed on the screen.
|
||||||
|
- The party overlay's experience-gained animation now displays the amount of EXP the Pokémon gained.
|
||||||
|
- Pressing the inventory key now closes the Pokémon interact wheel GUI.
|
||||||
|
- Updated the sound for harvesting Apricorns.
|
||||||
|
- Lowered the volume of harvesting berries.
|
||||||
|
- Improved compatibility with various mods
|
||||||
|
- Farmer's Delight's cutting board can now be used to strip Apricorn and Saccharine's logs, or salvage their planks from various blocks. It can also separate their boats from chests.
|
||||||
|
- Farmer's Delight's cutting board can be used to get two white dye from Pep-Up Flowers and two magenta dye from Medicinal Leeks.
|
||||||
|
- Farmer's Delight's cutting board can separate Tumblestone Blocks back into Tumblestones.
|
||||||
|
- Farmer's Delight's cutting board can salvage Type Gems from their Gem Blocks.
|
||||||
|
- Farmer's Delight's Onions, Tomatoes, and Cabbages can be used to cook Open-Faced Sandwiches. Nature's Spirit's Olives also can be used.
|
||||||
|
- Farmer's Delight's cutting board can be used on Hearty Grains to obtain rice and straw, similarly to Farmer's Delight's Rice Panicles.
|
||||||
|
- Farmer's Delight's Apple Pies and Apple Ciders can now be made using Applin Apples, alongside the Vanilla counterpart.
|
||||||
|
- Amendments allows for cooking Leek and Potato Stew in a Cauldron.
|
||||||
|
- Any mods that utilise Moonlight's Soft Fluid system can store Leek and Potato Stew, Medicinal Brew, Antidote, Awakening, Burn Heal, Ice Heal, Paralyze Heal, Full Heal, Potion, Super Potion, Hyper Potion, Max Potion, Full Restore, Ability Capsules, Moomoo Milk, and Berry Juice in liquid form (such as Suplementaries' Jar or Goblet, or Cauldrons while using Amendments).
|
||||||
|
- Supplementaries' Hourglass can now use Bright Powder, Quick Powder, Metal Powder, Heal Powder, Silver Powder, and Remedy.
|
||||||
|
- Berry Trees are now compatible with the Planter properly
|
||||||
|
- Saccharine Way Signs (added by Supplementaries automagically) now use a premade texture to prevent odd visual issues.
|
||||||
|
- Supplementaries' Jar can now store various Cobblemon cookies, candies, and similar items.
|
||||||
|
- Some of Supplementaries' items have been added to the `#cobblemon:held/container_held_items` item tag, including sacks, safes, and lunch baskets.
|
||||||
|
- Experience Nuggets can be used in place of Sculk for making the EXP Candies if using Create.
|
||||||
|
- Rage Candy Bar has a Create Mixing recipe.
|
||||||
|
- All Cobblemon ores can now be crushed in Create's Crushing Wheels. All Gem and Tumblestone Clusters can be crushed for automatic, low return, gems.
|
||||||
|
- Hearty Grains can be milled like Farmer's Delight Rice Panicles if both Farmer's Delight and Create are installed.
|
||||||
|
- Big Roots and Revival Herbs can be milled to their respective powders.
|
||||||
|
- Pep-Up Flowers, Medicinal Leeks, and all 70 berries can be milled in Create's Millstone for additional dye drops.
|
||||||
|
- Auspicious Armour and Upgrades can be Haunted using Create's crafting systems.
|
||||||
|
- Applin Apples can be used to make Honeyed Apples in Create.
|
||||||
|
- Sounds for interacting with various Cobblemon blocks now play from the centre of the block, rather than the corner. You probably didn't notice.
|
||||||
|
- Dragonite's mailbag cosmetic can now also be obtained with a chest in the cosmetic slot.
|
||||||
|
- Adjusted the walk speed for Croagunk and Aerodactyl.
|
||||||
|
- The `/pc` command no longer plays PC activation sounds
|
||||||
|
- Pressing the Summary key while either the starter selection or summary screen are open now closes those screens.
|
||||||
|
- Ice type Pokémon are now immune to Packed Snow.
|
||||||
|
- Added cobweb block slowness immunity for spider Pokémon
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fixed rare Pokémon being far too likely to spawn multiple times in a single spawn cycle. The dev told me that the exact bug is too complicated to explain.
|
||||||
|
- Fixed Omanyte and Omastar incorrectly using water animations on land.
|
||||||
|
- Fixed Pokédex layout for genderless variations.
|
||||||
|
- Fixed odd stacking behaviour with Poké Baits.
|
||||||
|
- Fixed a compatibility issue with World Game Rules which caused some log spam in specific cases.
|
||||||
|
- Fixed improper validation of Pokémon when performing a trade.
|
||||||
|
- Fixed an issue where particles like beams can disappear when you don't see the beginning of the beam, or you look away.
|
||||||
|
- Fixed Bedrock particle materials sometimes being incorrectly invisible from some sides.
|
||||||
|
- Fixed an occasional crash on retrieving revived fossils.
|
||||||
|
- Fixed brushing not working on Neoforge. Again.
|
||||||
|
- Fixed braking not working for submarine-style mounts (whoops).
|
||||||
|
- Fixed strafing not having the same friction as forward movement (funny whoops).
|
||||||
|
- Fixed submarine-style mounts' surface-water animations not playing when supposed to.
|
||||||
|
- Fixed submarine-style mounts' camera freaking out when looking up or down on the surface.
|
||||||
|
- Fixed pastured Pokémon despawning and running away.
|
||||||
|
- Fixed Apricorn trees crashing when other mods bonemeal them.
|
||||||
|
- Fixed the issue that caused hover-style mounts without a ground style to be rendered useless upon touching the ground on a server.
|
||||||
|
- Fixed horizontal and vertical collisions with hover-style mounts so they no longer accumulate or retain momentum.
|
||||||
|
- Fixed NeoForge brewing stand unexpectedly crashing users when shift clicking items within its menu. Well, I suppose all crashes are unexpected. You know what I mean.
|
||||||
|
- Fixed NPCs switching Pokémon very often during battles.
|
||||||
|
- Fixed Campfire Pot causing crashes under certain circumstances.
|
||||||
|
- Fixed Type Gems not being consumed upon use in battles.
|
||||||
|
- Fixed several Ancient Pokéball's not using the correct capture multiplier.
|
||||||
|
- Fixed a server warning that could occur when recalling Pokémon.
|
||||||
|
- Fixed sliding particles incorrectly handling block collision.
|
||||||
|
- Fixed Full Heal not curing status conditions in battle. Literally it's one job.
|
||||||
|
- Fixed a rare issue with battles locking up when you are forced to switch, with the switch menu appearing instantly.
|
||||||
|
- Fixed the combined effects of Pledge moves having broken Showdown message handling and localisation.
|
||||||
|
- Fixed a very niche issue where structures would spawn in an incorrect location, creating very funky world gen.
|
||||||
|
- Fixed Galarian Ponyta missing its cry.
|
||||||
|
- Fixed various log warnings caused by redundant files and sound events.
|
||||||
|
- Traded Pokémon will now retain the original friendship level when traded back to its OT.
|
||||||
|
- Tumblestone Clusters now display correctly on maps.
|
||||||
|
- Fixed removing mulch from berry trees with a shovel not working. That was meant to be a thing.
|
||||||
|
- Fixed collecting honey from Saccharine Leaf blocks deleting Honey Bottles when the inventory was full.
|
||||||
|
- Fixed Stripped Saccharine Wood recipe being... not there.
|
||||||
|
- Fixed some performance issues with a kind of sound event causing lag by attempting to create sounds every tick when out of range of hearing.
|
||||||
|
- Fixed stat-reducing Aprijuice not being possible to apply on a maxed out Pokémon. Also fixed the possibility of going into negatives.
|
||||||
|
- Fixed exploit where you could take out the bait or drop your Pokérod with bait to avoid consuming bait, now the bobber will just disappear if you do so.
|
||||||
|
- Fixed Apricorn and Saccharine boats incorrectly using chest boat models.
|
||||||
|
- Fixed wild and trainer battle AI refusing to select moves with the `adjacentAlly` target type, even when it's their only option.
|
||||||
|
- Fixed gilded chests being more accessible than intended.
|
||||||
|
- Fixed fished up Pokémon not being added as "seen" to the Pokédex.
|
||||||
|
- Fixed surprised Gimmighoul encounters not being added as "seen" to the Pokédex.
|
||||||
|
- Fixed a crash involving berry trees that have been world edited.
|
||||||
|
- Fixed visual desync in multiplayer for players mounting Pokémon outside other players' loaded chunks.
|
||||||
|
- Fixed Pokémon entities leveled by rare candy not getting stronger as Minecraft entities unless recalled.
|
||||||
|
- Fixed a freeze during game load that occurred when multiple mods tried to load Cobblemon API classes at the same time.
|
||||||
|
- Lowered the volume of Blitzle and Zebstrika's cry (shut up!).
|
||||||
|
- Regional Foods will now prioritise being eaten instead of used for healing Pokémon - shift clicking will use it as healing.
|
||||||
|
- Resolved z-fighting (texture flickering) on Pokédex Models.
|
||||||
|
- Restored Ninjask's ability to do barrel rolls.
|
||||||
|
- Fixed Raichu (male) and Alolan Raichu (both genders) not displaying the correct Partner Cap when Pewter Crunchies are in the cosmetic slot.
|
||||||
|
- Fixed a crash caused by adding enchanted items to the Resurrection Machine.
|
||||||
|
- Fixed a crash that could occur when starting a PvN battle with only fainted Pokémon.
|
||||||
|
- Fixed the Remember Riding Camera config not being respected when dismounting and resolved the incompatibility with the Auto Third Person mod.
|
||||||
|
- Fixed Full Heal block not dropping Full Heals. Lmao.
|
||||||
|
- Fixed status cure items not returning an empty bottle when used.
|
||||||
|
- Fixed Panpour consuming its held item when evolving with a Water Stone.
|
||||||
|
- Fixed Smoked Tail Curry returning a Wooden Bowl when consumed despite it not being included in the recipe. Free bowls!
|
||||||
|
- Fixed `/giveallpokemon` not respecting the min and max arguments.
|
||||||
|
- Fixed the choose starter toast not disappearing when capturing a Pokémon instead of opening the starter selection screen.
|
||||||
|
- Fixed an issue where certain Sinister Tea seasonings were only applying as instant effects and would not apply over time.
|
||||||
|
- Long config option labels now scroll instead of overflowing in the configuration menu.
|
||||||
|
- Fixed some z-fighting and clipping on Dewott and Hisui-Bias Dewott.
|
||||||
|
- Eggant Berries can now be composted properly on NeoForge.
|
||||||
|
- Composting chances are now the same on NeoForge as on Fabric.
|
||||||
|
- Fixed problem where furnaces which had smelted Revival Herbs into Heal Powder in older versions would glitch out on trying to get the experience out of the block.
|
||||||
|
- Fixed the Battle AI not recognizing Surging Strikes as a multistrike move.
|
||||||
|
- Fixed Tentacool not using its swim animation when on water surface.
|
||||||
|
- Fixed Eevee using its left shoulder pose when in battle.
|
||||||
|
- Fixed Magikarp and Gyarados Jump Pattern resourcepacks replacing shiny textures of addons targeting Magikarp or Gyarados.
|
||||||
|
- Fixed Combee's pollinated texture overwriting the shiny and female textures.
|
||||||
|
- Fixed a colour mistake with Dracovish's shiny.
|
||||||
|
- Fixed Togedemaru's back spikes z-fighting.
|
||||||
|
- Fixed Sliggoo (+ Hisuian) evolving in the Nether and End where it can't actually rain.
|
||||||
|
- Corrected the scales, hitbox sizes, and eye heights for Ariados, Cetoddle, Durant, Galvantula, Klink, Lanturn, Lumineon, Mantine, Mantyke, Mudbray, Numel, Staravia, and Torkoal.
|
||||||
|
- Fixed Torkoal's walk speed not matching its animation. He will no longer move faster than Bunnelby and Buneary. This tortoise would've won.
|
||||||
|
- Fixed Lanturn T-posing due to missing ground walk and sleep animations.
|
||||||
|
- Fixed Oshawott and Dewott using their sleep animation in unintended scenarios.
|
||||||
|
- Fixed Dudunsparce and Maushold always having the same form instead of having the 1 in 100 chance of being different.
|
||||||
|
- Fixed bird mounts rapidly switching between their flying and gliding animations when flying at low speed.
|
||||||
|
- Fixed some battles being startable with fainted Pokémon in the initial sendout.
|
||||||
|
- Fixed random gender selection for forms with strict gender divides (such as Meowstic and Oinkologne) never choosing female (that's sexist).
|
||||||
|
- Fixed the "Press R to battle" prompt not disappearing after you finish your first battle, at least until you relogged.
|
||||||
|
- Fixed the composter block being listed as "composer" in the cosmetic items species feature
|
||||||
|
- Fixed Castform's forms being tagged as introduced in generation 4 instead of 3.
|
||||||
|
- Fixed Blitzle's base scale being `1` rather than the intended `0.8`.
|
||||||
|
- Fixed Magnezone's emissive layer for the shiny having the wrong name, thus displaying wrongly.
|
||||||
|
- Fixed Litleo not blinking.
|
||||||
|
|
||||||
|
### Developer
|
||||||
|
- Added `PokeSnackSpawnerFactory` which allows influence registration on PokeSnack encounters.
|
||||||
|
- Added `FishingSpawnerFactory` which allows influence registration on fishing encounters.
|
||||||
|
- Added `BattleFleeAttemptEvent` fired from `PokemonBattle.checkFleeAttempt`, allowing developers to intercept and control flee attempts.
|
||||||
|
- Tweaked the spawning selector interface to take a bucket function rather than a bucket directly.
|
||||||
|
- Added a new `cobblemon:height_range` processor type to allow developers to restrict structure-spawning ranges.
|
||||||
|
- Separated all the functions of MoLangFunctions.kt into their own files.
|
||||||
|
- Spawn buckets and their base weights are now provided by the spawner, with different base weights for world, fishing, snack, and habitat spawn buckets.
|
||||||
|
- Removed "SpawnBucket" class in favour of just storing maps of bucket names to weights.
|
||||||
|
- Fixed nicknames not being applied to Pokémon spawned from `spawn_pool_world` files.
|
||||||
|
- Added support for `profilePokedexScale`, `profilePokedexTranslation`, `profileSummaryScale`, and `profileSummaryTranslation` in poser files for finer control over profile displays.
|
||||||
|
- Fixed riding camera offsets defined on Pokémon forms not being applied.
|
||||||
|
- Marks can now provide aspects.
|
||||||
|
|
||||||
|
### Molang & Datapacks
|
||||||
|
- Added `moveset_builders` datapack folder for different styles of movesets.
|
||||||
|
- Added `party_pools` datapack folder for defining groups of Pokémon for complex NPC party definitions.
|
||||||
|
- Added `party_compositions` datapack folder for arranging parties on NPCs that rely on party pools.
|
||||||
|
- Added `composed_pool` NPC party provider type which combines a party pool with a party composition to create more complex NPC parties.
|
||||||
|
- Added basic chatter NPC Behaviour.
|
||||||
|
- Added `q.item.is_enchanted()`.
|
||||||
|
- Added `q.item.has_enchantment(minecraft:sharpness, 3)`.
|
||||||
|
- Added `has_chosen_starter` and `get_starter_uuid` as available Molang functions.
|
||||||
|
- Added `has_tm_move_unlocked`, `unlock_tm_move`, and `lock_tm_move` as available Molang functions for Players.
|
||||||
|
- Added `marks`, `has_mark`, and `remove_marks` as available Molang functions for Pokémon.
|
||||||
|
- Added Data Component support for species drops, eg `"components": {"minecraft:custom_model_data": 123}`
|
||||||
|
- Added the new `sortOrder` field to mark entries, (defaults to 0 if not specified) which controls the order in which marks are rendered on the HUD, with higher numbers being rendered on top of lower numbers.
|
||||||
|
- Added optional `order` field to starter categories. It will allow explicitly sorting categories in the starter selection screen.
|
||||||
|
- SpeciesAdditions append vs override now matches the wiki documentation.
|
||||||
|
- Added `weighted_choice` as a new feature type. It requires setting weights for each choice and allows developers to simplify the process of assigning random aspect choice based on marble chance.
|
||||||
|
- Added `q.world.spawn_loot_table_items(loot_table_id, x, y, z)` which spawns the items from the loot table at the position. Use type: `minecraft:chest` for the loot table.
|
||||||
|
- Added `q.pokemon.entity` to access the entity of Pokémon.
|
||||||
|
- Flamethrower and Seismic Toss had their action effect JSON cleaned up.
|
||||||
|
- Ride sounds can now be set as exclusive to passengers.
|
||||||
|
- Ride sounds no longer play when submerged unless specified with a new setting.
|
||||||
|
- NPC Trainers can now call a `command` animation when issuing a command in battle.
|
||||||
|
- Added a q.failed function to move action effects.
|
||||||
|
- Herd spawned Pokémon have their levels controlled differently. The `levelRange` property now acts as a pre-offset clamp instead of a filter, with a new `herdLevelRange` property to do the filter behaviour.
|
||||||
|
- `q.sound` now accepts three parameters (sound event, volume, and pitch) instead of just the sound event and pitch.
|
||||||
|
- Added a new layer property that makes a layer scroll in a direction. "scrolling": {"speedU": 0.1, "speedV": 0.1}
|
||||||
|
- Cleaned up seat data. Removed all now unused fields from seats in all species files. Also made locator seat names explicit in the species files (however, this doesn't break the legacy format)
|
||||||
|
|
||||||
|
### Particles
|
||||||
|
|
||||||
|
#### New Move Animations
|
||||||
|
- Blizzard
|
||||||
|
- Disarming Voice
|
||||||
|
- Draco Meteor
|
||||||
|
- Dragon Breath
|
||||||
|
- Dragon Rage
|
||||||
|
- Drain Punch
|
||||||
|
- Fairy Wind
|
||||||
|
- Fire Fang
|
||||||
|
- Gust
|
||||||
|
- Horn Drill
|
||||||
|
- Hydro Pump
|
||||||
|
- Ice Fang
|
||||||
|
- Leafage
|
||||||
|
- Leaf Storm
|
||||||
|
- Light Screen
|
||||||
|
- Night Shade
|
||||||
|
- Play Rough
|
||||||
|
- Pyro Ball
|
||||||
|
- Reflect
|
||||||
|
- Rock Slide
|
||||||
|
- Sonic Boom
|
||||||
|
- Sucker Punch
|
||||||
|
- Supersonic
|
||||||
|
- Thunder Fang
|
||||||
|
|
||||||
|
#### Tweaks and Fixes (Moves)
|
||||||
|
|
||||||
|
- Confusion
|
||||||
|
- Dragon Claw
|
||||||
|
- Eruption
|
||||||
|
- Fire Punch
|
||||||
|
- Flame Burst
|
||||||
|
- Flame Charge
|
||||||
|
- Flamethrower
|
||||||
|
- Frost Breath
|
||||||
|
- Hypnosis
|
||||||
|
- Ice Punch
|
||||||
|
- Icy Wind
|
||||||
|
- Mud Sport
|
||||||
|
- Poison Fang
|
||||||
|
- Protect
|
||||||
|
- Psychic
|
||||||
|
- Quick Attack
|
||||||
|
- Rage Powder
|
||||||
|
- Razor Leaf
|
||||||
|
- Sand Attack
|
||||||
|
- Scratch
|
||||||
|
- Shadow Claw
|
||||||
|
- Sing
|
||||||
|
- Spore
|
||||||
|
- String Shot
|
||||||
|
- Tackle
|
||||||
|
- Tail Whip
|
||||||
|
- Thunder
|
||||||
|
- Thunder Punch
|
||||||
|
- Thunder Wave
|
||||||
|
- Water Gun
|
||||||
|
- Water Pulse
|
||||||
|
- Water Sport
|
||||||
|
|
||||||
|
#### Miscellaneous Particles
|
||||||
|
|
||||||
|
- Added Wild Might particles for Alpha Pokémon.
|
||||||
|
- Updated stat increase and decrease particles.
|
||||||
|
|
||||||
|
### Localization
|
||||||
|
- Updated translations for:
|
||||||
|
- Japanese
|
||||||
|
- German
|
||||||
|
- Spanish
|
||||||
|
- Ecuadorian Spanish
|
||||||
|
- Portuguese
|
||||||
|
- Brazilian Portuguese
|
||||||
|
- Simplified Chinese
|
||||||
|
- Traditional Chinese
|
||||||
|
- Korean
|
||||||
|
- Russian
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
import utilities.isSnapshot
|
|
||||||
import utilities.version
|
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
import java.time.ZoneOffset
|
import java.time.ZoneOffset
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
import utilities.isSnapshot
|
||||||
|
import utilities.version
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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.duck;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duck that facilitates getting a level key for a given level.
|
||||||
|
*
|
||||||
|
* @author dualspiral
|
||||||
|
* @since August 30th, 2026
|
||||||
|
*/
|
||||||
|
public interface MinecraftServerDuck {
|
||||||
|
Optional<ResourceKey<Level>> cobblemon$getLevelKey(Level level);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.duck;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duck that facilitates getting a level key that we store on the level.
|
||||||
|
*
|
||||||
|
* @author dualspiral
|
||||||
|
* @since August 30th, 2026
|
||||||
|
*/
|
||||||
|
public interface ServerLevelDuck {
|
||||||
|
ResourceLocation cobblemon$getLevelResourceLocation();
|
||||||
|
}
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2023 Cobblemon Contributors
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.cobblemon.mod.common.mixin;
|
|
||||||
|
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Mixin(ClientPacketListener.class)
|
|
||||||
public class ClientPacketListenerMixin {
|
|
||||||
|
|
||||||
@Shadow private ClientLevel level;
|
|
||||||
|
|
||||||
@Inject(method = "handleSetEntityPassengersPacket", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/entity/Entity;hasIndirectPassenger(Lnet/minecraft/world/entity/Entity;)Z", shift = At.Shift.BEFORE), cancellable = true)
|
|
||||||
private void cobblemon$handlePokemonPassengers(ClientboundSetPassengersPacket packet, CallbackInfo ci) {
|
|
||||||
Entity entity = this.level.getEntity(packet.getVehicle());
|
|
||||||
if (entity instanceof PokemonEntity pokemon) {
|
|
||||||
var passengers = new ArrayList<Entity>();
|
|
||||||
for (int passenger : packet.getPassengers()) {
|
|
||||||
passengers.add(this.level.getEntity(passenger));
|
|
||||||
}
|
|
||||||
pokemon.getOccupiedSeats().values().stream()
|
|
||||||
.filter(x -> !passengers.contains(x))
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.forEach(Entity::stopRiding);
|
|
||||||
|
|
||||||
// Mount passengers not yet in the map
|
|
||||||
var currentPassengers = new ArrayList<>(pokemon.getOccupiedSeats().values());
|
|
||||||
passengers.stream()
|
|
||||||
.filter(x -> !currentPassengers.contains(x))
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.forEach(x -> x.startRiding(pokemon, true));
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2023 Cobblemon Contributors
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.cobblemon.mod.common.mixin;
|
|
||||||
|
|
||||||
import com.cobblemon.mod.common.mixin.accessor.SinglePoolElementAccessor;
|
|
||||||
import com.cobblemon.mod.common.world.structureprocessors.HeightRangeStructureProcessor;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Holder;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
|
||||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
|
||||||
import net.minecraft.world.level.levelgen.structure.pools.*;
|
|
||||||
import net.minecraft.world.level.levelgen.structure.pools.alias.PoolAliasLookup;
|
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
|
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor;
|
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Mixin(JigsawPlacement.class)
|
|
||||||
public class JigsawPlacementMixin {
|
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "addPieces(Lnet/minecraft/world/level/levelgen/structure/Structure$GenerationContext;Lnet/minecraft/core/Holder;Ljava/util/Optional;ILnet/minecraft/core/BlockPos;ZLjava/util/Optional;ILnet/minecraft/world/level/levelgen/structure/pools/alias/PoolAliasLookup;Lnet/minecraft/world/level/levelgen/structure/pools/DimensionPadding;Lnet/minecraft/world/level/levelgen/structure/templatesystem/LiquidSettings;)Ljava/util/Optional;",
|
|
||||||
at = @At("RETURN"),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
private static void onAddPieces(
|
|
||||||
Structure.GenerationContext context,
|
|
||||||
Holder<StructureTemplatePool> startPool,
|
|
||||||
Optional<ResourceLocation> startJigsawName,
|
|
||||||
int maxDepth,
|
|
||||||
BlockPos pos,
|
|
||||||
boolean useExpansionHack,
|
|
||||||
Optional<Heightmap.Types> projectStartToHeightmap,
|
|
||||||
int maxDistanceFromCenter,
|
|
||||||
PoolAliasLookup aliasLookup,
|
|
||||||
DimensionPadding dimensionPadding,
|
|
||||||
LiquidSettings liquidSettings,
|
|
||||||
CallbackInfoReturnable<Optional<Structure.GenerationStub>> cir
|
|
||||||
) {
|
|
||||||
Optional<Structure.GenerationStub> result = cir.getReturnValue();
|
|
||||||
if (result.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BlockPos spawnPos = result.get().position();
|
|
||||||
boolean canPlace = cobblemon$canAnyStartElementPlace(context, startPool, spawnPos);
|
|
||||||
|
|
||||||
if (canPlace) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cir.setReturnValue(Optional.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private static boolean cobblemon$canAnyStartElementPlace(
|
|
||||||
Structure.GenerationContext generationContext,
|
|
||||||
Holder<StructureTemplatePool> startPool,
|
|
||||||
BlockPos startPos
|
|
||||||
) {
|
|
||||||
for (StructurePoolElement element : startPool.value().templates) {
|
|
||||||
Optional<HeightRangeStructureProcessor> heightRangeProcessor = cobblemon$getHeightRangeProcessor(element);
|
|
||||||
|
|
||||||
if (heightRangeProcessor.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
HeightRangeStructureProcessor processor = heightRangeProcessor.get();
|
|
||||||
boolean valid = processor.isValidPlacement(
|
|
||||||
generationContext.chunkGenerator(),
|
|
||||||
generationContext.heightAccessor(),
|
|
||||||
generationContext.randomState(),
|
|
||||||
startPos
|
|
||||||
);
|
|
||||||
|
|
||||||
if (valid) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private static Optional<HeightRangeStructureProcessor> cobblemon$getHeightRangeProcessor(StructurePoolElement element) {
|
|
||||||
if (!(element instanceof SinglePoolElement)) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
StructureProcessorList processorList = ((SinglePoolElementAccessor) element).getProcessors().value();
|
|
||||||
for (StructureProcessor processor : processorList.list()) {
|
|
||||||
if (processor instanceof HeightRangeStructureProcessor heightRangeStructureProcessor) {
|
|
||||||
return Optional.of(heightRangeStructureProcessor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.mixin;
|
package com.cobblemon.mod.common.mixin;
|
||||||
|
|
||||||
import com.cobblemon.mod.common.CobblemonNetwork;
|
|
||||||
import com.cobblemon.mod.common.OrientationControllable;
|
import com.cobblemon.mod.common.OrientationControllable;
|
||||||
import com.cobblemon.mod.common.api.orientation.OrientationController;
|
import com.cobblemon.mod.common.api.orientation.OrientationController;
|
||||||
import com.cobblemon.mod.common.api.pokemon.effect.ShoulderEffectRegistry;
|
import com.cobblemon.mod.common.api.pokemon.effect.ShoulderEffectRegistry;
|
||||||
@@ -18,7 +17,6 @@ import com.cobblemon.mod.common.api.riding.behaviour.types.liquid.SubmarineBehav
|
|||||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate;
|
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate;
|
||||||
import com.cobblemon.mod.common.client.render.MatrixWrapper;
|
import com.cobblemon.mod.common.client.render.MatrixWrapper;
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||||
import com.cobblemon.mod.common.net.messages.server.orientation.ServerboundUpdateOrientationPacket;
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.mixin;
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.duck.MinecraftServerDuck;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Mixin(MinecraftServer.class)
|
||||||
|
public class MinecraftServerMixin implements MinecraftServerDuck {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private Map<ResourceKey<Level>, ServerLevel> levels;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<ResourceKey<Level>> cobblemon$getLevelKey(final Level level) {
|
||||||
|
return this.levels.entrySet()
|
||||||
|
.stream()
|
||||||
|
// Reference equality is intended here, the level we're handed is the same one as in the
|
||||||
|
// map so we don't need to check value semantics.
|
||||||
|
.filter(entry -> entry.getValue() == level)
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@@ -114,15 +115,13 @@ public abstract class ServerEntityMixin {
|
|||||||
if (currentPassengers.equals(cobblemon$lastSeatPassengers)) return;
|
if (currentPassengers.equals(cobblemon$lastSeatPassengers)) return;
|
||||||
cobblemon$lastSeatPassengers = List.copyOf(currentPassengers);
|
cobblemon$lastSeatPassengers = List.copyOf(currentPassengers);
|
||||||
|
|
||||||
|
var assignments = new LinkedHashMap<String, Integer>();
|
||||||
pokemon.getOccupiedSeats().forEach((seat, passenger) -> {
|
pokemon.getOccupiedSeats().forEach((seat, passenger) -> {
|
||||||
if (seat.getLocator() == null) return;
|
if (seat.getLocator() == null) return;
|
||||||
if (passenger == null) return;
|
if (passenger == null) return;
|
||||||
cobblemon$broadcast(new ClientboundSeatAssignmentPacket(
|
assignments.put(seat.getLocator(), passenger.getId());
|
||||||
passenger.getId(),
|
|
||||||
pokemon.getId(),
|
|
||||||
seat.getLocator()
|
|
||||||
));
|
|
||||||
});
|
});
|
||||||
|
cobblemon$broadcast(new ClientboundSeatAssignmentPacket(pokemon.getId(), assignments));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cobblemon$broadcast(NetworkPacket<?> packet) {
|
private void cobblemon$broadcast(NetworkPacket<?> packet) {
|
||||||
|
|||||||
@@ -8,22 +8,69 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.mixin;
|
package com.cobblemon.mod.common.mixin;
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.duck.MinecraftServerDuck;
|
||||||
|
import com.cobblemon.mod.common.duck.ServerLevelDuck;
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.level.storage.WritableLevelData;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
|
||||||
@Mixin(ServerLevel.class)
|
@Mixin(ServerLevel.class)
|
||||||
public abstract class ServerLevelMixin {
|
public abstract class ServerLevelMixin extends Level implements ServerLevelDuck {
|
||||||
|
|
||||||
|
// Ignored by Mixin, fulfils Java contract
|
||||||
|
protected ServerLevelMixin(
|
||||||
|
WritableLevelData levelData,
|
||||||
|
ResourceKey<Level> dimension,
|
||||||
|
RegistryAccess registryAccess,
|
||||||
|
Holder<DimensionType> dimensionTypeRegistration,
|
||||||
|
Supplier<ProfilerFiller> profiler,
|
||||||
|
boolean isClientSide,
|
||||||
|
boolean isDebug,
|
||||||
|
long biomeZoomSeed,
|
||||||
|
int maxChainedNeighborUpdates
|
||||||
|
) {
|
||||||
|
super(levelData, dimension, registryAccess, dimensionTypeRegistration, profiler, isClientSide, isDebug, biomeZoomSeed, maxChainedNeighborUpdates);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract MinecraftServer shadow$getServer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached to speed up level world key checks every tick.
|
||||||
|
*/
|
||||||
|
private ResourceLocation cobblemon$levelResourceLocation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation cobblemon$getLevelResourceLocation() {
|
||||||
|
if (this.cobblemon$levelResourceLocation == null) {
|
||||||
|
this.cobblemon$levelResourceLocation = ((MinecraftServerDuck) this.shadow$getServer())
|
||||||
|
.cobblemon$getLevelKey(this)
|
||||||
|
.map(ResourceKey::location)
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
return this.cobblemon$levelResourceLocation;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "findLightningRod", at = @At(value = "RETURN"), cancellable = true)
|
@Inject(method = "findLightningRod", at = @At(value = "RETURN"), cancellable = true)
|
||||||
private void cobblemon$findLightningRod(BlockPos blockPos, CallbackInfoReturnable<Optional<BlockPos>> ci) {
|
private void cobblemon$findLightningRod(BlockPos blockPos, CallbackInfoReturnable<Optional<BlockPos>> ci) {
|
||||||
|
|||||||
@@ -15,15 +15,18 @@ import com.cobblemon.mod.common.api.riding.RidingStyle;
|
|||||||
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner;
|
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner;
|
||||||
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory;
|
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory;
|
||||||
import com.cobblemon.mod.common.api.stats.CobblemonStats;
|
import com.cobblemon.mod.common.api.stats.CobblemonStats;
|
||||||
|
import com.cobblemon.mod.common.duck.ServerLevelDuck;
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
|
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
|
||||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
@@ -33,9 +36,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
|
|
||||||
@Mixin(ServerPlayer.class)
|
@Mixin(ServerPlayer.class)
|
||||||
public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
|
public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public abstract ServerLevel serverLevel();
|
public abstract ServerLevel serverLevel();
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
public MinecraftServer server;
|
||||||
@Unique
|
@Unique
|
||||||
public PlayerSpawner cobblemon$spawner;
|
public PlayerSpawner cobblemon$spawner;
|
||||||
|
|
||||||
@@ -55,12 +62,9 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
|
|||||||
|
|
||||||
@Inject(method = "tick", at = @At("TAIL"))
|
@Inject(method = "tick", at = @At("TAIL"))
|
||||||
private void cobblemon$tickSpawner(CallbackInfo ci) {
|
private void cobblemon$tickSpawner(CallbackInfo ci) {
|
||||||
if (!Cobblemon.config.getEnableSpawning()) {
|
if (cobblemon$canSpawn()) {
|
||||||
return;
|
getPlayerSpawner().tick();
|
||||||
} else if (!serverLevel().getGameRules().getBoolean(CobblemonGameRules.DO_POKEMON_SPAWNING)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
getPlayerSpawner().tick();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "rideTick", at = @At("HEAD"))
|
@Inject(method = "rideTick", at = @At("HEAD"))
|
||||||
@@ -121,4 +125,21 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
|
|||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether we should spawn Cobblemon entities here.
|
||||||
|
*
|
||||||
|
* @return true if we can spawn cobblemon in the current level,
|
||||||
|
* false otherwise
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("resource")
|
||||||
|
@Unique
|
||||||
|
private boolean cobblemon$canSpawn() {
|
||||||
|
return Cobblemon.config.getEnableSpawning() &&
|
||||||
|
this.serverLevel().getGameRules().getBoolean(CobblemonGameRules.DO_POKEMON_SPAWNING) &&
|
||||||
|
// intentionally last as this is a more expensive check, even with all the caching
|
||||||
|
!Cobblemon.config.getWorldSpawningBlocklist().contains(
|
||||||
|
((ServerLevelDuck) this.serverLevel()).cobblemon$getLevelResourceLocation()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* 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.mixin.accessor.SinglePoolElementAccessor;
|
||||||
|
import com.cobblemon.mod.common.world.structureprocessors.HeightRangeStructureProcessor;
|
||||||
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.level.levelgen.RandomState;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.PoolElementStructurePiece;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.StructurePiece;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
@Mixin(Structure.class)
|
||||||
|
public abstract class StructureMixin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discards a structure start when any of its pieces carries a {@link HeightRangeStructureProcessor}
|
||||||
|
* whose range the piece does not fit in.
|
||||||
|
* Crab Note: We have to make this has to happen here rather than in the processor itself. Terrain adaptation and {@code /locate}
|
||||||
|
* both read the start, so by the time processors run the terrain has already been generated and the
|
||||||
|
* structure is already on the map which previously were left behdind when we were trying to make some structures not generate via processor. Now
|
||||||
|
* Returning {@link StructureStart#INVALID_START} keeps the start from ever existing, which makes sure that weird generation isn't left behind.
|
||||||
|
*/
|
||||||
|
@Inject(
|
||||||
|
method = "generate",
|
||||||
|
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/structure/StructureStart;isValid()Z"),
|
||||||
|
cancellable = true
|
||||||
|
)
|
||||||
|
private void cobblemon$rejectStartsOutsideHeightRange(
|
||||||
|
RegistryAccess registryAccess, ChunkGenerator chunkGenerator, BiomeSource biomeSource,
|
||||||
|
RandomState randomState, StructureTemplateManager structureTemplateManager, long seed,
|
||||||
|
ChunkPos chunkPos, int references, LevelHeightAccessor heightAccessor,
|
||||||
|
Predicate<Holder<Biome>> validBiome,
|
||||||
|
CallbackInfoReturnable<StructureStart> cir,
|
||||||
|
@Local StructureStart structureStart
|
||||||
|
) {
|
||||||
|
for (StructurePiece piece : structureStart.getPieces()) {
|
||||||
|
if (!(piece instanceof PoolElementStructurePiece poolPiece)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<HeightRangeStructureProcessor> heightRangeProcessor = cobblemon$getHeightRangeProcessor(poolPiece.getElement());
|
||||||
|
if (heightRangeProcessor.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean valid = heightRangeProcessor.get().isValidPlacement(
|
||||||
|
chunkGenerator,
|
||||||
|
heightAccessor,
|
||||||
|
randomState,
|
||||||
|
piece.getBoundingBox()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
cir.setReturnValue(StructureStart.INVALID_START);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static Optional<HeightRangeStructureProcessor> cobblemon$getHeightRangeProcessor(StructurePoolElement element) {
|
||||||
|
if (!(element instanceof SinglePoolElement)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
StructureProcessorList processorList = ((SinglePoolElementAccessor) element).getProcessors().value();
|
||||||
|
for (StructureProcessor processor : processorList.list()) {
|
||||||
|
if (processor instanceof HeightRangeStructureProcessor heightRangeStructureProcessor) {
|
||||||
|
return Optional.of(heightRangeStructureProcessor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
-2
@@ -10,9 +10,7 @@ package com.cobblemon.mod.common.mixin.accessor;
|
|||||||
|
|
||||||
import net.minecraft.client.gui.components.StateSwitchingButton;
|
import net.minecraft.client.gui.components.StateSwitchingButton;
|
||||||
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
|
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
@Mixin(RecipeBookComponent.class)
|
@Mixin(RecipeBookComponent.class)
|
||||||
|
|||||||
+1
-2
@@ -15,11 +15,9 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
|||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
import com.llamalad7.mixinextras.sugar.Local;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.NonNullList;
|
import net.minecraft.core.NonNullList;
|
||||||
import net.minecraft.world.Containers;
|
import net.minecraft.world.Containers;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
|
||||||
import net.minecraft.world.item.alchemy.PotionBrewing;
|
import net.minecraft.world.item.alchemy.PotionBrewing;
|
||||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||||
import net.minecraft.world.item.crafting.RecipeManager;
|
import net.minecraft.world.item.crafting.RecipeManager;
|
||||||
@@ -34,6 +32,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Mixin(BrewingStandBlockEntity.class)
|
@Mixin(BrewingStandBlockEntity.class)
|
||||||
public class BrewingStandBlockEntityMixin {
|
public class BrewingStandBlockEntityMixin {
|
||||||
|
|
||||||
|
|||||||
@@ -9,17 +9,11 @@
|
|||||||
package com.cobblemon.mod.common.mixin.brewing;
|
package com.cobblemon.mod.common.mixin.brewing;
|
||||||
|
|
||||||
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
|
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
|
||||||
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.inventory.BrewingStandMenu;
|
import net.minecraft.world.inventory.BrewingStandMenu;
|
||||||
import net.minecraft.world.inventory.ContainerData;
|
import net.minecraft.world.inventory.ContainerData;
|
||||||
import net.minecraft.world.inventory.Slot;
|
import net.minecraft.world.inventory.Slot;
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
|
|||||||
import net.minecraft.world.inventory.BrewingStandMenu;
|
import net.minecraft.world.inventory.BrewingStandMenu;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.crafting.RecipeManager;
|
import net.minecraft.world.item.crafting.RecipeManager;
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import net.minecraft.client.Camera;
|
|||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ package com.cobblemon.mod.common.mixin.client;
|
|||||||
|
|
||||||
import com.cobblemon.mod.common.CobblemonRecipeCategories;
|
import com.cobblemon.mod.common.CobblemonRecipeCategories;
|
||||||
import com.cobblemon.mod.common.item.crafting.CookingPotBookCategory;
|
import com.cobblemon.mod.common.item.crafting.CookingPotBookCategory;
|
||||||
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe;
|
|
||||||
import com.cobblemon.mod.common.item.crafting.CookingPotRecipeBase;
|
import com.cobblemon.mod.common.item.crafting.CookingPotRecipeBase;
|
||||||
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
//This is a yucky hack but better than what we were doing before
|
// There appears to be a data driven way to do this now, however I am not sure how it works since there is no wiki or anything so yolo
|
||||||
@Mixin(BlockVariantSets.class)
|
@Mixin(BlockVariantSets.class)
|
||||||
public abstract class AdornRegisterInvoker {
|
public abstract class AdornRegisterInvoker {
|
||||||
@Final
|
@Final
|
||||||
|
|||||||
@@ -97,10 +97,10 @@ import com.cobblemon.mod.common.pokemon.Pokemon
|
|||||||
import com.cobblemon.mod.common.pokemon.aspects.ALPHA_ASPECT
|
import com.cobblemon.mod.common.pokemon.aspects.ALPHA_ASPECT
|
||||||
import com.cobblemon.mod.common.pokemon.aspects.CHARACTERISTIC_RAINBOW_ASPECT
|
import com.cobblemon.mod.common.pokemon.aspects.CHARACTERISTIC_RAINBOW_ASPECT
|
||||||
import com.cobblemon.mod.common.pokemon.aspects.COSMETIC_SLOT_ASPECT
|
import com.cobblemon.mod.common.pokemon.aspects.COSMETIC_SLOT_ASPECT
|
||||||
|
import com.cobblemon.mod.common.pokemon.aspects.FORM_ASPECTS
|
||||||
import com.cobblemon.mod.common.pokemon.aspects.GENDER_ASPECT
|
import com.cobblemon.mod.common.pokemon.aspects.GENDER_ASPECT
|
||||||
import com.cobblemon.mod.common.pokemon.aspects.MARK_ASPECT
|
import com.cobblemon.mod.common.pokemon.aspects.MARK_ASPECT
|
||||||
import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
|
import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
|
||||||
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
|
|
||||||
import com.cobblemon.mod.common.pokemon.feature.SlowpokeTailRegrowthSpeciesFeature
|
import com.cobblemon.mod.common.pokemon.feature.SlowpokeTailRegrowthSpeciesFeature
|
||||||
import com.cobblemon.mod.common.pokemon.feature.SlowpokeTailRegrowthSpeciesFeatureProvider
|
import com.cobblemon.mod.common.pokemon.feature.SlowpokeTailRegrowthSpeciesFeatureProvider
|
||||||
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
|
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
|
||||||
@@ -115,6 +115,7 @@ import com.cobblemon.mod.common.pokemon.properties.NoAIProperty
|
|||||||
import com.cobblemon.mod.common.pokemon.properties.UnaspectPropertyType
|
import com.cobblemon.mod.common.pokemon.properties.UnaspectPropertyType
|
||||||
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
|
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
|
||||||
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
|
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.triggers.BlockClickTrigger
|
||||||
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
|
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
|
||||||
import com.cobblemon.mod.common.util.*
|
import com.cobblemon.mod.common.util.*
|
||||||
import com.cobblemon.mod.common.world.feature.CobblemonPlacedFeatures
|
import com.cobblemon.mod.common.world.feature.CobblemonPlacedFeatures
|
||||||
@@ -273,13 +274,8 @@ object Cobblemon {
|
|||||||
PlatformEvents.RIGHT_CLICK_BLOCK.subscribe { event ->
|
PlatformEvents.RIGHT_CLICK_BLOCK.subscribe { event ->
|
||||||
val player = event.player
|
val player = event.player
|
||||||
val block = player.level().getBlockState(event.pos).block
|
val block = player.level().getBlockState(event.pos).block
|
||||||
player.party().forEach { pokemon ->
|
val context = BlockClickTrigger.Context(block, player.level())
|
||||||
pokemon.lockedEvolutions
|
player.party().forEach { pokemon -> pokemon.triggerTransformations<BlockClickTrigger>(context) }
|
||||||
.filterIsInstance<BlockClickEvolution>()
|
|
||||||
.forEach { evolution ->
|
|
||||||
evolution.attemptEvolution(pokemon, BlockClickEvolution.BlockInteractionContext(block, player.level()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformEvents.CHANGE_DIMENSION.subscribe {
|
PlatformEvents.CHANGE_DIMENSION.subscribe {
|
||||||
@@ -323,6 +319,7 @@ object Cobblemon {
|
|||||||
|
|
||||||
SHINY_ASPECT.register()
|
SHINY_ASPECT.register()
|
||||||
GENDER_ASPECT.register()
|
GENDER_ASPECT.register()
|
||||||
|
FORM_ASPECTS.register()
|
||||||
COSMETIC_SLOT_ASPECT.register()
|
COSMETIC_SLOT_ASPECT.register()
|
||||||
CHARACTERISTIC_RAINBOW_ASPECT.register()
|
CHARACTERISTIC_RAINBOW_ASPECT.register()
|
||||||
ALPHA_ASPECT.register()
|
ALPHA_ASPECT.register()
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
package com.cobblemon.mod.common
|
package com.cobblemon.mod.common
|
||||||
|
|
||||||
import com.bedrockk.molang.Expression
|
import com.bedrockk.molang.Expression
|
||||||
|
import com.cobblemon.mod.common.CobblemonBehaviours.autoPokemonBehaviours
|
||||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||||
import com.cobblemon.mod.common.api.ai.CobblemonBehaviour
|
import com.cobblemon.mod.common.api.ai.CobblemonBehaviour
|
||||||
import com.cobblemon.mod.common.api.ai.config.BehaviourConfig
|
import com.cobblemon.mod.common.api.ai.config.BehaviourConfig
|
||||||
@@ -19,16 +20,7 @@ import com.cobblemon.mod.common.api.molang.ExpressionLike
|
|||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||||
import com.cobblemon.mod.common.net.messages.client.data.BehaviourSyncPacket
|
import com.cobblemon.mod.common.net.messages.client.data.BehaviourSyncPacket
|
||||||
import com.cobblemon.mod.common.util.adapters.ActivityAdapter
|
import com.cobblemon.mod.common.util.adapters.*
|
||||||
import com.cobblemon.mod.common.util.adapters.BehaviourConfigAdapter
|
|
||||||
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
|
|
||||||
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
|
|
||||||
import com.cobblemon.mod.common.util.adapters.ExpressionOrEntityVariableAdapter
|
|
||||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
|
||||||
import com.cobblemon.mod.common.util.adapters.MemoryModuleTypeAdapter
|
|
||||||
import com.cobblemon.mod.common.util.adapters.SensorTypeAdapter
|
|
||||||
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.cobblemon.mod.common.util.cobblemonResource
|
||||||
import com.cobblemon.mod.common.util.endsWith
|
import com.cobblemon.mod.common.util.endsWith
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ object CobblemonCommands {
|
|||||||
HeldItemCommand.register(dispatcher, registry)
|
HeldItemCommand.register(dispatcher, registry)
|
||||||
PcCommand.register(dispatcher)
|
PcCommand.register(dispatcher)
|
||||||
SpawnPokemonFromPool.register(dispatcher)
|
SpawnPokemonFromPool.register(dispatcher)
|
||||||
|
SpawnMeteorCommand.register(dispatcher)
|
||||||
|
SetMegaBondCommand.register(dispatcher)
|
||||||
PokeboxCommand.register(dispatcher)
|
PokeboxCommand.register(dispatcher)
|
||||||
PokedexCommand.register(dispatcher)
|
PokedexCommand.register(dispatcher)
|
||||||
TestStoreCommand.register(dispatcher)
|
TestStoreCommand.register(dispatcher)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import com.cobblemon.mod.common.entity.generic.GenericBedrockEntity
|
|||||||
import com.cobblemon.mod.common.entity.npc.NPCEntity
|
import com.cobblemon.mod.common.entity.npc.NPCEntity
|
||||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||||
|
import com.cobblemon.mod.common.entity.projectile.FallingStarEntity
|
||||||
import com.cobblemon.mod.common.platform.PlatformRegistry
|
import com.cobblemon.mod.common.platform.PlatformRegistry
|
||||||
import com.cobblemon.mod.common.util.cobblemonResource
|
import com.cobblemon.mod.common.util.cobblemonResource
|
||||||
import net.minecraft.core.Registry
|
import net.minecraft.core.Registry
|
||||||
@@ -95,6 +96,15 @@ object CobblemonEntities : PlatformRegistry<Registry<EntityType<*>>, ResourceKey
|
|||||||
EntityType.Builder.of({ _, world -> NPCEntity(world) }, MobCategory.CREATURE).build("$NPC_KEY")
|
EntityType.Builder.of({ _, world -> NPCEntity(world) }, MobCategory.CREATURE).build("$NPC_KEY")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val FALLING_STAR_KEY = cobblemonResource("falling_star")
|
||||||
|
@JvmField
|
||||||
|
val FALLING_STAR: EntityType<FallingStarEntity> = create(
|
||||||
|
FALLING_STAR_KEY.path,
|
||||||
|
EntityType.Builder.of(::FallingStarEntity, MobCategory.MISC).sized(0.5F, 0.5F).clientTrackingRange(8)
|
||||||
|
.build(FALLING_STAR_KEY.toString())
|
||||||
|
)
|
||||||
|
|
||||||
fun registerAttributes(consumer: (EntityType<out LivingEntity>, AttributeSupplier.Builder) -> Unit) {
|
fun registerAttributes(consumer: (EntityType<out LivingEntity>, AttributeSupplier.Builder) -> Unit) {
|
||||||
consumer(POKEMON, PokemonEntity.createAttributes())
|
consumer(POKEMON, PokemonEntity.createAttributes())
|
||||||
consumer(NPC, NPCEntity.createAttributes())
|
consumer(NPC, NPCEntity.createAttributes())
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import net.minecraft.server.level.ServerPlayer
|
|||||||
import net.minecraft.server.packs.PackType
|
import net.minecraft.server.packs.PackType
|
||||||
import net.minecraft.server.packs.resources.PreparableReloadListener
|
import net.minecraft.server.packs.resources.PreparableReloadListener
|
||||||
import net.minecraft.tags.TagKey
|
import net.minecraft.tags.TagKey
|
||||||
import net.minecraft.world.inventory.MenuType
|
|
||||||
import net.minecraft.world.level.GameRules
|
import net.minecraft.world.level.GameRules
|
||||||
import net.minecraft.world.level.ItemLike
|
import net.minecraft.world.level.ItemLike
|
||||||
import net.minecraft.world.level.biome.Biome
|
import net.minecraft.world.level.biome.Biome
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>
|
|||||||
.networkSynchronized(HeldItemEffectComponent.PACKET_CODEC)
|
.networkSynchronized(HeldItemEffectComponent.PACKET_CODEC)
|
||||||
.build())
|
.build())
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val MEGA_BOND: DataComponentType<MegaBondComponent> = create("mega_bond", DataComponentType.builder<MegaBondComponent>()
|
||||||
|
.persistent(MegaBondComponent.CODEC)
|
||||||
|
.networkSynchronized(MegaBondComponent.PACKET_CODEC)
|
||||||
|
.build())
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val BAIT: DataComponentType<RodBaitComponent> = create("bait", DataComponentType.builder<RodBaitComponent>()
|
val BAIT: DataComponentType<RodBaitComponent> = create("bait", DataComponentType.builder<RodBaitComponent>()
|
||||||
.persistent(RodBaitComponent.CODEC)
|
.persistent(RodBaitComponent.CODEC)
|
||||||
|
|||||||
@@ -914,6 +914,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
val THUNDER_STONE = noSettingsItem("thunder_stone")
|
val THUNDER_STONE = noSettingsItem("thunder_stone")
|
||||||
@JvmField
|
@JvmField
|
||||||
val WATER_STONE = noSettingsItem("water_stone")
|
val WATER_STONE = noSettingsItem("water_stone")
|
||||||
|
@JvmField
|
||||||
|
val MEGA_SHARD = noSettingsItem("mega_shard")
|
||||||
|
@JvmField
|
||||||
|
val DORMANT_MEGA_STONE = heldItem("dormant_mega_stone")
|
||||||
|
|
||||||
val wearables = mutableListOf<WearableItem>()
|
val wearables = mutableListOf<WearableItem>()
|
||||||
//Wearable items (these items should have a corresponding 3D model)
|
//Wearable items (these items should have a corresponding 3D model)
|
||||||
@@ -932,14 +936,34 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val ABILITY_SHIELD = heldItem("ability_shield")
|
val ABILITY_SHIELD = heldItem("ability_shield")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val ABOMASITE = heldItem("abomasite")
|
||||||
|
@JvmField
|
||||||
|
val ABSOLITE = heldItem("absolite")
|
||||||
|
@JvmField
|
||||||
val ABSORB_BULB = heldItem("absorb_bulb")
|
val ABSORB_BULB = heldItem("absorb_bulb")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val AERODACTYLITE = heldItem("aerodactylite")
|
||||||
|
@JvmField
|
||||||
|
val AGGRONITE = heldItem("aggronite")
|
||||||
|
@JvmField
|
||||||
val AIR_BALLOON = heldItem("air_balloon")
|
val AIR_BALLOON = heldItem("air_balloon")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val ALAKAZITE = heldItem("alakazite")
|
||||||
|
@JvmField
|
||||||
|
val ALTARIANITE = heldItem("altarianite")
|
||||||
|
@JvmField
|
||||||
|
val AMPHAROSITE = heldItem("ampharosite")
|
||||||
|
@JvmField
|
||||||
val ASSAULT_VEST = heldItem("assault_vest")
|
val ASSAULT_VEST = heldItem("assault_vest")
|
||||||
@JvmField
|
@JvmField
|
||||||
val BIG_ROOT = compostableBlockItem("big_root", CobblemonBlocks.BIG_ROOT, 0.30f)
|
val BIG_ROOT = compostableBlockItem("big_root", CobblemonBlocks.BIG_ROOT, 0.30f)
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val AUDINITE = heldItem("audinite")
|
||||||
|
@JvmField
|
||||||
|
val BANETTITE = heldItem("banettite")
|
||||||
|
@JvmField
|
||||||
|
val BEEDRILLITE = heldItem("beedrillite")
|
||||||
|
@JvmField
|
||||||
val BINDING_BAND = heldItem("binding_band")
|
val BINDING_BAND = heldItem("binding_band")
|
||||||
@JvmField
|
@JvmField
|
||||||
val BLACK_BELT = heldItem("black_belt")
|
val BLACK_BELT = heldItem("black_belt")
|
||||||
@@ -948,10 +972,20 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val BLUNDER_POLICY = itemNameBlockItem("blunder_policy", CobblemonBlocks.BLUNDER_POLICY)
|
val BLUNDER_POLICY = itemNameBlockItem("blunder_policy", CobblemonBlocks.BLUNDER_POLICY)
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val BLASTOISINITE = heldItem("blastoisinite")
|
||||||
|
@JvmField
|
||||||
|
val BLAZIKENITE = heldItem("blazikenite")
|
||||||
|
@JvmField
|
||||||
|
val CAMERUPTITE = heldItem("cameruptite")
|
||||||
|
@JvmField
|
||||||
val CELL_BATTERY = heldItem("cell_battery")
|
val CELL_BATTERY = heldItem("cell_battery")
|
||||||
@JvmField
|
@JvmField
|
||||||
val CHARCOAL = heldItem("charcoal_stick", remappedName = "charcoal")
|
val CHARCOAL = heldItem("charcoal_stick", remappedName = "charcoal")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val CHARIZARDITE_X = heldItem("charizardite_x")
|
||||||
|
@JvmField
|
||||||
|
val CHARIZARDITE_Y = heldItem("charizardite_y")
|
||||||
|
@JvmField
|
||||||
val CHOICE_SCARF = heldItem("choice_scarf")
|
val CHOICE_SCARF = heldItem("choice_scarf")
|
||||||
@JvmField
|
@JvmField
|
||||||
val CLEANSE_TAG = itemNameBlockItem("cleanse_tag", CobblemonBlocks.CLEANSE_TAG)
|
val CLEANSE_TAG = itemNameBlockItem("cleanse_tag", CobblemonBlocks.CLEANSE_TAG)
|
||||||
@@ -962,6 +996,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val DESTINY_KNOT = heldItem("destiny_knot")
|
val DESTINY_KNOT = heldItem("destiny_knot")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val DIANCITE = heldItem("diancite")
|
||||||
|
@JvmField
|
||||||
val DRAGON_FANG = heldItem("dragon_fang")
|
val DRAGON_FANG = heldItem("dragon_fang")
|
||||||
@JvmField
|
@JvmField
|
||||||
val EJECT_BUTTON = heldItem("eject_button")
|
val EJECT_BUTTON = heldItem("eject_button")
|
||||||
@@ -984,20 +1020,42 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val FOCUS_SASH = heldItem("focus_sash")
|
val FOCUS_SASH = heldItem("focus_sash")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val GALLADITE = heldItem("galladite")
|
||||||
|
@JvmField
|
||||||
|
val GARCHOMPITE = heldItem("garchompite")
|
||||||
|
@JvmField
|
||||||
|
val GARDEVOIRITE = heldItem("gardevoirite")
|
||||||
|
@JvmField
|
||||||
|
val GENGARITE = heldItem("gengarite")
|
||||||
|
@JvmField
|
||||||
|
val GLALITITE = heldItem("glalitite")
|
||||||
|
@JvmField
|
||||||
val GRASSY_SEED = heldItem("grassy_seed")
|
val GRASSY_SEED = heldItem("grassy_seed")
|
||||||
@JvmField
|
@JvmField
|
||||||
val GRIP_CLAW = heldItem("grip_claw")
|
val GRIP_CLAW = heldItem("grip_claw")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val GYARADOSITE = heldItem("gyaradosite")
|
||||||
|
@JvmField
|
||||||
val HARD_STONE = heldItem("hard_stone")
|
val HARD_STONE = heldItem("hard_stone")
|
||||||
@JvmField
|
@JvmField
|
||||||
val HEAVY_DUTY_BOOTS = heldItem("heavy_duty_boots")
|
val HEAVY_DUTY_BOOTS = heldItem("heavy_duty_boots")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val HERACRONITE = heldItem("heracronite")
|
||||||
|
@JvmField
|
||||||
|
val HOUNDOOMINITE = heldItem("houndoominite")
|
||||||
|
@JvmField
|
||||||
val IRON_BALL = heldItem("iron_ball")
|
val IRON_BALL = heldItem("iron_ball")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val KANGASKHANITE = heldItem("kangaskhanite")
|
||||||
|
@JvmField
|
||||||
val LAGGING_TAIL = heldItem("lagging_tail")
|
val LAGGING_TAIL = heldItem("lagging_tail")
|
||||||
@JvmField
|
@JvmField
|
||||||
val LEFTOVERS = compostableHeldItem("leftovers", null, 0.50f)
|
val LEFTOVERS = compostableHeldItem("leftovers", null, 0.50f)
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val LATIASITE = heldItem("latiasite")
|
||||||
|
@JvmField
|
||||||
|
val LATIOSITE = heldItem("latiosite")
|
||||||
|
@JvmField
|
||||||
val LIFE_ORB = heldItem("life_orb")
|
val LIFE_ORB = heldItem("life_orb")
|
||||||
@JvmField
|
@JvmField
|
||||||
val LIGHT_BALL = heldItem("light_ball")
|
val LIGHT_BALL = heldItem("light_ball")
|
||||||
@@ -1006,20 +1064,40 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val LOADED_DICE = heldItem("loaded_dice")
|
val LOADED_DICE = heldItem("loaded_dice")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val LOPUNNITE = heldItem("lopunnite")
|
||||||
|
@JvmField
|
||||||
|
val LUCARIONITE = heldItem("lucarionite")
|
||||||
|
@JvmField
|
||||||
val LUCKY_EGG = heldItem("lucky_egg")
|
val LUCKY_EGG = heldItem("lucky_egg")
|
||||||
@JvmField
|
@JvmField
|
||||||
val LUMINOUS_MOSS = heldItem("luminous_moss")
|
val LUMINOUS_MOSS = heldItem("luminous_moss")
|
||||||
@JvmField
|
@JvmField
|
||||||
val MAGNET = heldItem("magnet")
|
val MAGNET = heldItem("magnet")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val MANECTITE = heldItem("manectite")
|
||||||
|
@JvmField
|
||||||
|
val MAWILITE = heldItem("mawilite")
|
||||||
|
@JvmField
|
||||||
|
val MEDICHAMITE = heldItem("medichamite")
|
||||||
|
@JvmField
|
||||||
|
val METAGROSSITE = heldItem("metagrossite")
|
||||||
|
@JvmField
|
||||||
val METRONOME = heldItem("metronome")
|
val METRONOME = heldItem("metronome")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val MEWTWONITE_X = heldItem("mewtwonite_x")
|
||||||
|
@JvmField
|
||||||
|
val MEWTWONITE_Y = heldItem("mewtwonite_y")
|
||||||
|
@JvmField
|
||||||
val MIRACLE_SEED = heldItem("miracle_seed")
|
val MIRACLE_SEED = heldItem("miracle_seed")
|
||||||
@JvmField
|
@JvmField
|
||||||
val MYSTIC_WATER = heldItem("mystic_water")
|
val MYSTIC_WATER = heldItem("mystic_water")
|
||||||
@JvmField
|
@JvmField
|
||||||
val NEVER_MELT_ICE = heldItem("never_melt_ice")
|
val NEVER_MELT_ICE = heldItem("never_melt_ice")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val PIDGEOTITE = heldItem("pidgeotite")
|
||||||
|
@JvmField
|
||||||
|
val PINSIRITE = heldItem("pinsirite")
|
||||||
|
@JvmField
|
||||||
val POISON_BARB = heldItem("poison_barb")
|
val POISON_BARB = heldItem("poison_barb")
|
||||||
@JvmField
|
@JvmField
|
||||||
val POWER_ANKLET = heldItem("power_anklet")
|
val POWER_ANKLET = heldItem("power_anklet")
|
||||||
@@ -1048,10 +1126,20 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val ROOM_SERVICE = heldItem("room_service")
|
val ROOM_SERVICE = heldItem("room_service")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val SABLENITE = heldItem("sablenite")
|
||||||
|
@JvmField
|
||||||
|
val SALAMENCITE = heldItem("salamencite")
|
||||||
|
@JvmField
|
||||||
|
val SCEPTILITE = heldItem("sceptilite")
|
||||||
|
@JvmField
|
||||||
|
val SCIZORITE = heldItem("scizorite")
|
||||||
|
@JvmField
|
||||||
val SCOPE_LENS = heldItem("scope_lens")
|
val SCOPE_LENS = heldItem("scope_lens")
|
||||||
@JvmField
|
@JvmField
|
||||||
val SHARP_BEAK = heldItem("sharp_beak")
|
val SHARP_BEAK = heldItem("sharp_beak")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val SHARPEDONITE = heldItem("sharpedonite")
|
||||||
|
@JvmField
|
||||||
val SHED_SHELL = heldItem("shed_shell")
|
val SHED_SHELL = heldItem("shed_shell")
|
||||||
@JvmField
|
@JvmField
|
||||||
val SHELL_BELL = heldItem("shell_bell")
|
val SHELL_BELL = heldItem("shell_bell")
|
||||||
@@ -1060,6 +1148,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val SILVER_POWDER = heldItem("silver_powder")
|
val SILVER_POWDER = heldItem("silver_powder")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val SLOWBRONITE = heldItem("slowbronite")
|
||||||
|
@JvmField
|
||||||
val SOFT_SAND = heldItem("soft_sand")
|
val SOFT_SAND = heldItem("soft_sand")
|
||||||
@JvmField
|
@JvmField
|
||||||
val SPELL_TAG = itemNameBlockItem("spell_tag", CobblemonBlocks.SPELL_TAG)
|
val SPELL_TAG = itemNameBlockItem("spell_tag", CobblemonBlocks.SPELL_TAG)
|
||||||
@@ -1068,8 +1158,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val SOOTHE_BELL = heldItem("soothe_bell")
|
val SOOTHE_BELL = heldItem("soothe_bell")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val STEELIXITE = heldItem("steelixite")
|
||||||
|
@JvmField
|
||||||
val STICKY_BARB = heldItem("sticky_barb")
|
val STICKY_BARB = heldItem("sticky_barb")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val SWAMPERTITE = heldItem("swampertite")
|
||||||
|
@JvmField
|
||||||
val TERRAIN_EXTENDER = heldItem("terrain_extender")
|
val TERRAIN_EXTENDER = heldItem("terrain_extender")
|
||||||
@JvmField
|
@JvmField
|
||||||
val THROAT_SPRAY = heldItem("throat_spray")
|
val THROAT_SPRAY = heldItem("throat_spray")
|
||||||
@@ -1078,10 +1172,14 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val TWISTED_SPOON = heldItem("twisted_spoon")
|
val TWISTED_SPOON = heldItem("twisted_spoon")
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val TYRANITARITE = heldItem("tyranitarite")
|
||||||
|
@JvmField
|
||||||
val UTILITY_UMBRELLA = heldItem("utility_umbrella")
|
val UTILITY_UMBRELLA = heldItem("utility_umbrella")
|
||||||
@JvmField
|
@JvmField
|
||||||
val WEAKNESS_POLICY = itemNameBlockItem("weakness_policy", CobblemonBlocks.WEAKNESS_POLICY)
|
val WEAKNESS_POLICY = itemNameBlockItem("weakness_policy", CobblemonBlocks.WEAKNESS_POLICY)
|
||||||
@JvmField
|
@JvmField
|
||||||
|
val VENUSAURITE = heldItem("venusaurite")
|
||||||
|
@JvmField
|
||||||
val WIDE_LENS = heldItem("wide_lens")
|
val WIDE_LENS = heldItem("wide_lens")
|
||||||
@JvmField
|
@JvmField
|
||||||
val ZOOM_LENS = heldItem("zoom_lens")
|
val ZOOM_LENS = heldItem("zoom_lens")
|
||||||
@@ -1756,4 +1854,4 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
private fun foodItem(nutrition: Int, saturationModifier: Float): Item {
|
private fun foodItem(nutrition: Int, saturationModifier: Float): Item {
|
||||||
return CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
|
return CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,12 +15,12 @@ import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
|||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
import com.mojang.serialization.codecs.ListCodec
|
import com.mojang.serialization.codecs.ListCodec
|
||||||
import com.mojang.serialization.codecs.PrimitiveCodec
|
import com.mojang.serialization.codecs.PrimitiveCodec
|
||||||
|
import java.util.Optional
|
||||||
|
import java.util.UUID
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.GlobalPos
|
|
||||||
import net.minecraft.core.UUIDUtil
|
import net.minecraft.core.UUIDUtil
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object CobblemonMemories {
|
object CobblemonMemories {
|
||||||
val memories = mutableMapOf<String, MemoryModuleType<*>>()
|
val memories = mutableMapOf<String, MemoryModuleType<*>>()
|
||||||
|
|||||||
@@ -107,10 +107,14 @@ import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.Add
|
|||||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.ClearEvolutionsPacket
|
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.ClearEvolutionsPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.ClientboundSeatAssignmentPacket
|
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.ClientboundSeatAssignmentPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.RemoveEvolutionPacket
|
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.RemoveEvolutionPacket
|
||||||
|
import com.cobblemon.mod.common.net.messages.client.pokemon.update.form.AddFormPacket
|
||||||
|
import com.cobblemon.mod.common.net.messages.client.pokemon.update.form.ClearFormsPacket
|
||||||
|
import com.cobblemon.mod.common.net.messages.client.pokemon.update.form.RemoveFormPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.settings.OpenCobblemonConfigScreenPacket
|
import com.cobblemon.mod.common.net.messages.client.settings.OpenCobblemonConfigScreenPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
|
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnGenericBedrockPacket
|
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnGenericBedrockPacket
|
||||||
|
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnFallingStarPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnNPCPacket
|
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnNPCPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokeballPacket
|
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokeballPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokemonPacket
|
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokemonPacket
|
||||||
@@ -194,6 +198,8 @@ import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetItemHidden
|
|||||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetMarkingsPacket
|
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetMarkingsPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePacket
|
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.evolution.AcceptEvolutionPacket
|
import com.cobblemon.mod.common.net.messages.server.pokemon.update.evolution.AcceptEvolutionPacket
|
||||||
|
import com.cobblemon.mod.common.net.messages.server.pokemon.update.form.AcceptFormPacket
|
||||||
|
import com.cobblemon.mod.common.net.messages.server.pokemon.update.form.RevertFormPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.riding.DismountPokemonPacket
|
import com.cobblemon.mod.common.net.messages.server.riding.DismountPokemonPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateDriverInputPacket
|
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateDriverInputPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdatePassengerPositionPacket
|
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdatePassengerPositionPacket
|
||||||
@@ -211,9 +217,11 @@ import com.cobblemon.mod.common.net.messages.server.trade.ChangeTradeAcceptanceP
|
|||||||
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
|
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.PerformTradePacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
|
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
|
||||||
|
import com.cobblemon.mod.common.net.serverhandling.AcceptFormHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
|
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.ChallengeResponseHandler
|
import com.cobblemon.mod.common.net.serverhandling.ChallengeResponseHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
|
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
|
||||||
|
import com.cobblemon.mod.common.net.serverhandling.RevertFormHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
|
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.RemoveSpectatorHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
|
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
|
||||||
@@ -457,6 +465,7 @@ object CobblemonNetwork {
|
|||||||
list.add(PacketRegisterInfo(SpawnPokemonPacket.ID, SpawnPokemonPacket::decode, SpawnExtraDataEntityHandler()))
|
list.add(PacketRegisterInfo(SpawnPokemonPacket.ID, SpawnPokemonPacket::decode, SpawnExtraDataEntityHandler()))
|
||||||
list.add(PacketRegisterInfo(SpawnPokeballPacket.ID, SpawnPokeballPacket::decode, SpawnExtraDataEntityHandler()))
|
list.add(PacketRegisterInfo(SpawnPokeballPacket.ID, SpawnPokeballPacket::decode, SpawnExtraDataEntityHandler()))
|
||||||
list.add(PacketRegisterInfo(SpawnGenericBedrockPacket.ID, SpawnGenericBedrockPacket::decode, SpawnExtraDataEntityHandler()))
|
list.add(PacketRegisterInfo(SpawnGenericBedrockPacket.ID, SpawnGenericBedrockPacket::decode, SpawnExtraDataEntityHandler()))
|
||||||
|
list.add(PacketRegisterInfo(SpawnFallingStarPacket.ID, SpawnFallingStarPacket::decode, SpawnExtraDataEntityHandler()))
|
||||||
list.add(PacketRegisterInfo(SpawnNPCPacket.ID, SpawnNPCPacket::decode, SpawnExtraDataEntityHandler()))
|
list.add(PacketRegisterInfo(SpawnNPCPacket.ID, SpawnNPCPacket::decode, SpawnExtraDataEntityHandler()))
|
||||||
list.add(PacketRegisterInfo(ToastPacket.ID, ToastPacket::decode, ToastPacketHandler))
|
list.add(PacketRegisterInfo(ToastPacket.ID, ToastPacket::decode, ToastPacketHandler))
|
||||||
|
|
||||||
@@ -506,6 +515,11 @@ object CobblemonNetwork {
|
|||||||
// Pokédex scanning
|
// Pokédex scanning
|
||||||
list.add(PacketRegisterInfo(ServerConfirmedRegisterPacket.ID, ServerConfirmedRegisterPacket::decode, ServerConfirmedRegisterHandler))
|
list.add(PacketRegisterInfo(ServerConfirmedRegisterPacket.ID, ServerConfirmedRegisterPacket::decode, ServerConfirmedRegisterHandler))
|
||||||
|
|
||||||
|
// Form packets
|
||||||
|
list.add(PacketRegisterInfo(AddFormPacket.ID, AddFormPacket::decode, PokemonUpdatePacketHandler()))
|
||||||
|
list.add(PacketRegisterInfo(ClearFormsPacket.ID, ClearFormsPacket::decode, PokemonUpdatePacketHandler()))
|
||||||
|
list.add(PacketRegisterInfo(RemoveFormPacket.ID, RemoveFormPacket::decode, PokemonUpdatePacketHandler()))
|
||||||
|
|
||||||
// Riding
|
// Riding
|
||||||
list.add(PacketRegisterInfo(ClientboundUpdateRidingStatePacket.ID, ClientboundUpdateRidingStatePacket::decode, ClientboundUpdateRidingStateHandler))
|
list.add(PacketRegisterInfo(ClientboundUpdateRidingStatePacket.ID, ClientboundUpdateRidingStatePacket::decode, ClientboundUpdateRidingStateHandler))
|
||||||
list.add(PacketRegisterInfo(ClientboundUpdateDriverInputPacket.ID, ClientboundUpdateDriverInputPacket::decode, ClientboundUpdateDriverInputHandler))
|
list.add(PacketRegisterInfo(ClientboundUpdateDriverInputPacket.ID, ClientboundUpdateDriverInputPacket::decode, ClientboundUpdateDriverInputHandler))
|
||||||
@@ -621,6 +635,10 @@ object CobblemonNetwork {
|
|||||||
// NPC packets
|
// NPC packets
|
||||||
list.add(PacketRegisterInfo(SaveNPCPacket.ID, SaveNPCPacket::decode, SaveNPCHandler))
|
list.add(PacketRegisterInfo(SaveNPCPacket.ID, SaveNPCPacket::decode, SaveNPCHandler))
|
||||||
|
|
||||||
|
// Form Packets
|
||||||
|
list.add(PacketRegisterInfo(AcceptFormPacket.ID, AcceptFormPacket::decode, AcceptFormHandler))
|
||||||
|
list.add(PacketRegisterInfo(RevertFormPacket.ID, RevertFormPacket::decode, RevertFormHandler))
|
||||||
|
|
||||||
// Riding packet(s)
|
// Riding packet(s)
|
||||||
list.add(PacketRegisterInfo(ServerboundUpdateOrientationPacket.ID, ServerboundUpdateOrientationPacket::decode, ServerboundUpdateOrientationHandler))
|
list.add(PacketRegisterInfo(ServerboundUpdateOrientationPacket.ID, ServerboundUpdateOrientationPacket::decode, ServerboundUpdateOrientationHandler))
|
||||||
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatePacket.ID, ServerboundUpdateRidingStatePacket::decode, ServerboundUpdateRidingStateHandler))
|
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatePacket.ID, ServerboundUpdateRidingStatePacket::decode, ServerboundUpdateRidingStateHandler))
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
package com.cobblemon.mod.common
|
package com.cobblemon.mod.common
|
||||||
|
|
||||||
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.*
|
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.*
|
||||||
import com.cobblemon.mod.common.pokemon.ai.PokemonDisturbancesSensor
|
|
||||||
import com.cobblemon.mod.common.entity.sensor.BattlingPokemonSensor
|
import com.cobblemon.mod.common.entity.sensor.BattlingPokemonSensor
|
||||||
import com.cobblemon.mod.common.entity.sensor.NPCBattlingSensor
|
import com.cobblemon.mod.common.entity.sensor.NPCBattlingSensor
|
||||||
|
import com.cobblemon.mod.common.pokemon.ai.PokemonDisturbancesSensor
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
import net.minecraft.world.entity.Entity
|
import net.minecraft.world.entity.Entity
|
||||||
import net.minecraft.world.entity.ai.sensing.Sensor
|
import net.minecraft.world.entity.ai.sensing.Sensor
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common
|
package com.cobblemon.mod.common
|
||||||
|
|
||||||
|
import java.util.Optional
|
||||||
import net.minecraft.core.registries.BuiltInRegistries
|
import net.minecraft.core.registries.BuiltInRegistries
|
||||||
import net.minecraft.util.RandomSource
|
import net.minecraft.util.RandomSource
|
||||||
import net.minecraft.world.entity.Entity
|
import net.minecraft.world.entity.Entity
|
||||||
@@ -18,7 +19,6 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import net.minecraft.world.item.Items
|
import net.minecraft.world.item.Items
|
||||||
import net.minecraft.world.item.trading.ItemCost
|
import net.minecraft.world.item.trading.ItemCost
|
||||||
import net.minecraft.world.item.trading.MerchantOffer
|
import net.minecraft.world.item.trading.MerchantOffer
|
||||||
import java.util.Optional
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generator for various trade offers in the mod.
|
* A generator for various trade offers in the mod.
|
||||||
|
|||||||
+1
-1
@@ -11,10 +11,10 @@ package com.cobblemon.mod.common.advancement.criterion
|
|||||||
import com.cobblemon.mod.common.util.cobblemonResource
|
import com.cobblemon.mod.common.util.cobblemonResource
|
||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||||
|
import java.util.Optional
|
||||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import java.util.Optional
|
|
||||||
|
|
||||||
class AspectCriterion(
|
class AspectCriterion(
|
||||||
playerCtx: Optional<ContextAwarePredicate>,
|
playerCtx: Optional<ContextAwarePredicate>,
|
||||||
|
|||||||
+1
-1
@@ -14,8 +14,8 @@ import com.mojang.serialization.codecs.RecordCodecBuilder
|
|||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||||
import net.minecraft.advancements.critereon.EntityPredicate
|
import net.minecraft.advancements.critereon.EntityPredicate
|
||||||
import net.minecraft.server.level.ServerPlayer
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
|
||||||
class CastPokeRodContext(val baitId: ResourceLocation)
|
class CastPokeRodContext(val baitId: ResourceLocation)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -10,10 +10,10 @@ package com.cobblemon.mod.common.advancement.criterion
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||||
|
import java.util.Optional
|
||||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||||
import net.minecraft.advancements.critereon.EntityPredicate
|
import net.minecraft.advancements.critereon.EntityPredicate
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import java.util.Optional
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A context that is used when you require a [CountableContext] along with some type string.
|
* A context that is used when you require a [CountableContext] along with some type string.
|
||||||
|
|||||||
+1
-1
@@ -14,8 +14,8 @@ import com.mojang.serialization.codecs.RecordCodecBuilder
|
|||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||||
import net.minecraft.advancements.critereon.EntityPredicate
|
import net.minecraft.advancements.critereon.EntityPredicate
|
||||||
import net.minecraft.server.level.ServerPlayer
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
|
||||||
class ReelInPokemonContext(val species : ResourceLocation, val baitId: ResourceLocation)
|
class ReelInPokemonContext(val species : ResourceLocation, val baitId: ResourceLocation)
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
package com.cobblemon.mod.common.api.abilities
|
package com.cobblemon.mod.common.api.abilities
|
||||||
|
|
||||||
import com.cobblemon.mod.common.api.Priority
|
import com.cobblemon.mod.common.api.Priority
|
||||||
|
import com.cobblemon.mod.common.api.data.ShowdownIdentifiable
|
||||||
import com.cobblemon.mod.common.util.codec.CodecUtils
|
import com.cobblemon.mod.common.util.codec.CodecUtils
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
@@ -25,7 +26,7 @@ class AbilityTemplate(
|
|||||||
var builder: (AbilityTemplate, forced: Boolean, priority: Priority) -> Ability = { template, forced, priority -> Ability(template, forced, priority) },
|
var builder: (AbilityTemplate, forced: Boolean, priority: Priority) -> Ability = { template, forced, priority -> Ability(template, forced, priority) },
|
||||||
val displayName: String = "cobblemon.ability.$name",
|
val displayName: String = "cobblemon.ability.$name",
|
||||||
val description: String = "cobblemon.ability.$name.desc"
|
val description: String = "cobblemon.ability.$name.desc"
|
||||||
) {
|
) : ShowdownIdentifiable {
|
||||||
/**
|
/**
|
||||||
* Returns the Ability or if applicable the extension connected to this template
|
* Returns the Ability or if applicable the extension connected to this template
|
||||||
*/
|
*/
|
||||||
@@ -45,6 +46,8 @@ class AbilityTemplate(
|
|||||||
*/
|
*/
|
||||||
fun create(json: JsonObject) = create().loadFromJSON(json)
|
fun create(json: JsonObject) = create().loadFromJSON(json)
|
||||||
|
|
||||||
|
override fun showdownId(): String = ShowdownIdentifiable.REGEX.replace(this.name.lowercase(), "")
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|||||||
-1
@@ -18,7 +18,6 @@ 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.asMostSpecificMoLangValue
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||||
import com.cobblemon.mod.common.api.molang.ObjectValue
|
import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||||
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
|
||||||
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||||
import com.cobblemon.mod.common.util.activityRegistry
|
import com.cobblemon.mod.common.util.activityRegistry
|
||||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import com.cobblemon.mod.common.api.ai.config.BehaviourConfig
|
|||||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
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.asMostSpecificMoLangValue
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||||
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
|
||||||
import com.cobblemon.mod.common.util.asTranslated
|
import com.cobblemon.mod.common.util.asTranslated
|
||||||
import com.cobblemon.mod.common.util.resolve
|
import com.cobblemon.mod.common.util.resolve
|
||||||
import com.cobblemon.mod.common.util.withQueryValue
|
import com.cobblemon.mod.common.util.withQueryValue
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import com.cobblemon.mod.common.util.getBooleanOrNull
|
|||||||
import com.cobblemon.mod.common.util.getDoubleOrNull
|
import com.cobblemon.mod.common.util.getDoubleOrNull
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to maintain some settings around how the entity should wander this tick. The idea is you
|
* Used to maintain some settings around how the entity should wander this tick. The idea is you
|
||||||
|
|||||||
@@ -8,16 +8,12 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config
|
package com.cobblemon.mod.common.api.ai.config
|
||||||
|
|
||||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
|
||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
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.api.npc.configuration.MoLangConfigVariable
|
||||||
import com.cobblemon.mod.common.util.asExpression
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
import com.cobblemon.mod.common.util.cobblemonResource
|
import com.cobblemon.mod.common.util.cobblemonResource
|
||||||
import com.cobblemon.mod.common.util.resolveBoolean
|
import com.cobblemon.mod.common.util.resolveBoolean
|
||||||
import com.cobblemon.mod.common.util.withQueryValue
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
|
||||||
|
|||||||
@@ -11,13 +11,8 @@ package com.cobblemon.mod.common.api.ai.config.task
|
|||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||||
import com.cobblemon.mod.common.api.ai.asVariables
|
import com.cobblemon.mod.common.api.ai.asVariables
|
||||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
|
||||||
import com.cobblemon.mod.common.util.asExpression
|
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.weightedSelection
|
import com.cobblemon.mod.common.util.weightedSelection
|
||||||
import com.cobblemon.mod.common.util.withQueryValue
|
|
||||||
import com.mojang.datafixers.util.Either
|
import com.mojang.datafixers.util.Either
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
|
|||||||
-2
@@ -8,12 +8,10 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
|
||||||
import com.cobblemon.mod.common.CobblemonMemories
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask.Companion.wrapped
|
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask.Companion.wrapped
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
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.api.npc.configuration.MoLangConfigVariable
|
||||||
import com.cobblemon.mod.common.util.mainThreadRuntime
|
import com.cobblemon.mod.common.util.mainThreadRuntime
|
||||||
import com.cobblemon.mod.common.util.resolveBoolean
|
import com.cobblemon.mod.common.util.resolveBoolean
|
||||||
|
|||||||
-2
@@ -10,8 +10,6 @@ package com.cobblemon.mod.common.api.ai.config.task
|
|||||||
|
|
||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.ai.asVariables
|
import com.cobblemon.mod.common.api.ai.asVariables
|
||||||
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.LivingEntity
|
||||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
import net.minecraft.world.entity.ai.behavior.StopBeingAngryIfTargetDead
|
import net.minecraft.world.entity.ai.behavior.StopBeingAngryIfTargetDead
|
||||||
|
|||||||
-2
@@ -9,9 +9,7 @@
|
|||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
|
||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
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.Difficulty
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||||
|
|||||||
-1
@@ -15,7 +15,6 @@ import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
|||||||
import com.cobblemon.mod.common.entity.npc.ai.SwitchToBattleTask
|
import com.cobblemon.mod.common.entity.npc.ai.SwitchToBattleTask
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
|
||||||
|
|
||||||
class SwitchToNPCBattleTaskConfig : SingleTaskConfig {
|
class SwitchToNPCBattleTaskConfig : SingleTaskConfig {
|
||||||
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
|
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
|
||||||
|
|||||||
-2
@@ -10,8 +10,6 @@ package com.cobblemon.mod.common.api.ai.config.task
|
|||||||
|
|
||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.ai.asVariables
|
import com.cobblemon.mod.common.api.ai.asVariables
|
||||||
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.LivingEntity
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
|
|||||||
-2
@@ -10,8 +10,6 @@ package com.cobblemon.mod.common.api.ai.config.task
|
|||||||
|
|
||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.ai.asVariables
|
import com.cobblemon.mod.common.api.ai.asVariables
|
||||||
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.LivingEntity
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
|
|||||||
-1
@@ -25,7 +25,6 @@ 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.BehaviorBuilder
|
||||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
import net.minecraft.world.entity.ai.memory.MemoryStatus
|
|
||||||
import net.minecraft.world.entity.ai.sensing.SensorType
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-1
@@ -22,6 +22,7 @@ import com.cobblemon.mod.common.util.mainThreadRuntime
|
|||||||
import com.cobblemon.mod.common.util.resolveFloat
|
import com.cobblemon.mod.common.util.resolveFloat
|
||||||
import com.cobblemon.mod.common.util.withQueryValue
|
import com.cobblemon.mod.common.util.withQueryValue
|
||||||
import com.mojang.datafixers.util.Either
|
import com.mojang.datafixers.util.Either
|
||||||
|
import kotlin.math.ceil
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.world.entity.PathfinderMob
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
@@ -34,7 +35,6 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
|||||||
import net.minecraft.world.level.material.Fluids
|
import net.minecraft.world.level.material.Fluids
|
||||||
import net.minecraft.world.level.pathfinder.PathType
|
import net.minecraft.world.level.pathfinder.PathType
|
||||||
import net.minecraft.world.phys.Vec3
|
import net.minecraft.world.phys.Vec3
|
||||||
import kotlin.math.ceil
|
|
||||||
|
|
||||||
class WaterWanderTaskConfig : SingleTaskConfig {
|
class WaterWanderTaskConfig : SingleTaskConfig {
|
||||||
val condition = booleanVariable(WANDER, "water_wanders", true).asExpressible()
|
val condition = booleanVariable(WANDER, "water_wanders", true).asExpressible()
|
||||||
|
|||||||
+13
-12
@@ -54,9 +54,9 @@ import com.cobblemon.mod.common.net.messages.client.battle.BattleEndPacket
|
|||||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
|
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
|
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleQueueRequestPacket
|
import com.cobblemon.mod.common.net.messages.client.battle.BattleQueueRequestPacket
|
||||||
import com.cobblemon.mod.common.pokemon.evolution.progress.DefeatEvolutionProgress
|
import com.cobblemon.mod.common.pokemon.transformation.progress.DefeatTransformationProgress
|
||||||
import com.cobblemon.mod.common.pokemon.evolution.progress.LastBattleCriticalHitsEvolutionProgress
|
import com.cobblemon.mod.common.pokemon.transformation.progress.LastBattleCriticalHitsTransformationProgress
|
||||||
import com.cobblemon.mod.common.pokemon.requirements.DefeatRequirement
|
import com.cobblemon.mod.common.pokemon.transformation.requirements.DefeatRequirement
|
||||||
import com.cobblemon.mod.common.util.battleLang
|
import com.cobblemon.mod.common.util.battleLang
|
||||||
import com.cobblemon.mod.common.util.getPlayer
|
import com.cobblemon.mod.common.util.getPlayer
|
||||||
import com.cobblemon.mod.common.util.giveOrDropItemStack
|
import com.cobblemon.mod.common.util.giveOrDropItemStack
|
||||||
@@ -97,8 +97,8 @@ open class PokemonBattle(
|
|||||||
this.actors.forEach { actor ->
|
this.actors.forEach { actor ->
|
||||||
actor.battle = this
|
actor.battle = this
|
||||||
actor.pokemonList.forEach { battlePokemon ->
|
actor.pokemonList.forEach { battlePokemon ->
|
||||||
battlePokemon.effectedPokemon.evolutionProxy.current().progress()
|
battlePokemon.effectedPokemon.requirementProgress
|
||||||
.filterIsInstance<LastBattleCriticalHitsEvolutionProgress>()
|
.filterIsInstance<LastBattleCriticalHitsTransformationProgress>()
|
||||||
.forEach { it.reset() }
|
.forEach { it.reset() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ open class PokemonBattle(
|
|||||||
set(value) { field = value.coerceAtMost(Int.MAX_VALUE) } // go outside
|
set(value) { field = value.coerceAtMost(Int.MAX_VALUE) } // go outside
|
||||||
|
|
||||||
/** The current duration of the battle in seconds. */
|
/** The current duration of the battle in seconds. */
|
||||||
val time: Int get() = ticks % 20
|
val time: Int get() = ticks / 20
|
||||||
|
|
||||||
var dispatchResult = GO
|
var dispatchResult = GO
|
||||||
val dispatches = ConcurrentLinkedDeque<BattleDispatch>()
|
val dispatches = ConcurrentLinkedDeque<BattleDispatch>()
|
||||||
@@ -271,12 +271,13 @@ open class PokemonBattle(
|
|||||||
val facedFainted = opponentPokemon.facedOpponents.contains(faintedPokemon)
|
val facedFainted = opponentPokemon.facedOpponents.contains(faintedPokemon)
|
||||||
val pokemon = opponentPokemon.effectedPokemon
|
val pokemon = opponentPokemon.effectedPokemon
|
||||||
if (facedFainted) {
|
if (facedFainted) {
|
||||||
pokemon.lockedEvolutions.forEach { evolution ->
|
if (pokemon.hasMatchingRequirement<DefeatRequirement>({ it.target.matches(faintedPokemon.effectedPokemon) })) {
|
||||||
evolution.requirements.filterIsInstance<DefeatRequirement>().forEach { defeatRequirement ->
|
val requiredPokemonProperties = pokemon.getRelevantRequirements<DefeatRequirement> { it.target.matches(faintedPokemon.effectedPokemon) }
|
||||||
if (defeatRequirement.target.matches(faintedPokemon.effectedPokemon)) {
|
.map { it.target }
|
||||||
val progress = pokemon.evolutionProxy.current().progressFirstOrCreate({ it is DefeatEvolutionProgress && it.currentProgress().target == defeatRequirement.target }) { DefeatEvolutionProgress() }
|
.distinctBy { it.asString() }
|
||||||
progress.updateProgress(DefeatEvolutionProgress.Progress(defeatRequirement.target, progress.currentProgress().amount + 1))
|
for (props in requiredPokemonProperties) {
|
||||||
}
|
val progress = pokemon.progressFirstOrCreate({ it is DefeatTransformationProgress && it.currentProgress().target.asString().equals(props.asString(), ignoreCase = true) }, ::DefeatTransformationProgress)
|
||||||
|
progress.updateProgress(DefeatTransformationProgress.Progress(props.copy(), progress.currentProgress().amount + 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -22,9 +22,9 @@ import com.cobblemon.mod.common.item.battle.BagItem
|
|||||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleApplyPassResponsePacket
|
import com.cobblemon.mod.common.net.messages.client.battle.BattleApplyPassResponsePacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
|
import com.cobblemon.mod.common.net.messages.client.battle.BattleMakeChoicePacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
|
import com.cobblemon.mod.common.net.messages.client.battle.BattleMessagePacket
|
||||||
|
import java.util.UUID
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.network.chat.MutableComponent
|
import net.minecraft.network.chat.MutableComponent
|
||||||
import java.util.UUID
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
|
||||||
abstract class BattleActor(
|
abstract class BattleActor(
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.cobblemon.mod.common.util.adapters.*
|
|||||||
import com.cobblemon.mod.common.util.cobblemonResource
|
import com.cobblemon.mod.common.util.cobblemonResource
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
|
import java.awt.Color
|
||||||
import net.minecraft.advancements.critereon.MinMaxBounds
|
import net.minecraft.advancements.critereon.MinMaxBounds
|
||||||
import net.minecraft.core.registries.Registries
|
import net.minecraft.core.registries.Registries
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
@@ -30,7 +31,6 @@ import net.minecraft.tags.TagKey
|
|||||||
import net.minecraft.world.level.biome.Biome
|
import net.minecraft.world.level.biome.Biome
|
||||||
import net.minecraft.world.phys.AABB
|
import net.minecraft.world.phys.AABB
|
||||||
import net.minecraft.world.phys.Vec3
|
import net.minecraft.world.phys.Vec3
|
||||||
import java.awt.Color
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data registry for [Berry].
|
* The data registry for [Berry].
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ import com.cobblemon.mod.common.util.writeBox
|
|||||||
import com.cobblemon.mod.common.util.writeEnumConstant
|
import com.cobblemon.mod.common.util.writeEnumConstant
|
||||||
import com.cobblemon.mod.common.util.writeIdentifier
|
import com.cobblemon.mod.common.util.writeIdentifier
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import java.util.EnumSet
|
import java.util.EnumSet
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.tags.TagKey
|
import net.minecraft.tags.TagKey
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.drop
|
package com.cobblemon.mod.common.api.drop
|
||||||
|
|
||||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
import com.cobblemon.mod.common.api.pokemon.transformation.requirement.TransformationRequirement
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
|
||||||
class EvolutionItemDropEntry : ItemDropEntry() {
|
class EvolutionItemDropEntry : ItemDropEntry() {
|
||||||
val requirements: MutableSet<Requirement> = mutableSetOf()
|
val requirements: MutableSet<TransformationRequirement> = mutableSetOf()
|
||||||
|
|
||||||
override fun canDrop(pokemon: Pokemon?): Boolean = pokemon != null && requirements.all { it.check(pokemon) }
|
override fun canDrop(pokemon: Pokemon?): Boolean = pokemon != null && requirements.all { it.check(pokemon) }
|
||||||
}
|
}
|
||||||
@@ -48,6 +48,10 @@ import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionAcceptedEv
|
|||||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEvent
|
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEvent
|
||||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionDisplayEvent
|
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionDisplayEvent
|
||||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionTestedEvent
|
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionTestedEvent
|
||||||
|
import com.cobblemon.mod.common.api.events.pokemon.form.FormAcceptedEvent
|
||||||
|
import com.cobblemon.mod.common.api.events.pokemon.form.FormCompleteEvent
|
||||||
|
import com.cobblemon.mod.common.api.events.pokemon.form.FormDisplayEvent
|
||||||
|
import com.cobblemon.mod.common.api.events.pokemon.form.FormTestedEvent
|
||||||
import com.cobblemon.mod.common.api.events.pokemon.healing.PokemonHealedEvent
|
import com.cobblemon.mod.common.api.events.pokemon.healing.PokemonHealedEvent
|
||||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.ExperienceCandyUseEvent
|
import com.cobblemon.mod.common.api.events.pokemon.interaction.ExperienceCandyUseEvent
|
||||||
import com.cobblemon.mod.common.api.events.pokemon.interaction.PokemonInteractionGUICreationEvent
|
import com.cobblemon.mod.common.api.events.pokemon.interaction.PokemonInteractionGUICreationEvent
|
||||||
@@ -103,6 +107,18 @@ object CobblemonEvents {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val EVOLUTION_COMPLETE = EventObservable<EvolutionCompleteEvent>()
|
val EVOLUTION_COMPLETE = EventObservable<EvolutionCompleteEvent>()
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val FORM_ACCEPTED = CancelableObservable<FormAcceptedEvent>()
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val FORM_DISPLAY = EventObservable<FormDisplayEvent>()
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val FORM_TESTED = EventObservable<FormTestedEvent>()
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val FORM_COMPLETE = EventObservable<FormCompleteEvent>()
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val POKEMON_NICKNAMED = CancelableObservable<PokemonNicknamedEvent>()
|
val POKEMON_NICKNAMED = CancelableObservable<PokemonNicknamedEvent>()
|
||||||
|
|
||||||
|
|||||||
-2
@@ -15,9 +15,7 @@ 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.BattleActor
|
||||||
import com.cobblemon.mod.common.api.battles.model.actor.EntityBackedBattleActor
|
import com.cobblemon.mod.common.api.battles.model.actor.EntityBackedBattleActor
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
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.MoLangScriptingEntity
|
||||||
import com.cobblemon.mod.common.entity.npc.NPCBattleActor
|
|
||||||
import com.cobblemon.mod.common.util.asArrayValue
|
import com.cobblemon.mod.common.util.asArrayValue
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -21,7 +21,8 @@ import com.cobblemon.mod.common.pokemon.Pokemon
|
|||||||
*/
|
*/
|
||||||
data class FriendshipUpdatedEvent(
|
data class FriendshipUpdatedEvent(
|
||||||
val pokemon: Pokemon,
|
val pokemon: Pokemon,
|
||||||
val newFriendshipInitial: Int
|
val newFriendshipInitial: Int,
|
||||||
|
val earned: Boolean = false
|
||||||
) {
|
) {
|
||||||
var newFriendship: Int = newFriendshipInitial
|
var newFriendship: Int = newFriendshipInitial
|
||||||
set(value) {
|
set(value) {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import com.bedrockk.molang.runtime.value.DoubleValue
|
|||||||
import com.cobblemon.mod.common.api.events.Cancelable
|
import com.cobblemon.mod.common.api.events.Cancelable
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
import com.cobblemon.mod.common.trade.TradeParticipant
|
import com.cobblemon.mod.common.trade.TradeParticipant
|
||||||
import com.cobblemon.mod.common.util.getPlayer
|
import com.cobblemon.mod.common.util.getPlayer
|
||||||
|
|||||||
+1
-1
@@ -12,8 +12,8 @@ import com.bedrockk.molang.runtime.value.MoValue
|
|||||||
import com.cobblemon.mod.common.api.events.Cancelable
|
import com.cobblemon.mod.common.api.events.Cancelable
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.evolution.Evolution
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired when an evolution is accepted.
|
* Fired when an evolution is accepted.
|
||||||
|
|||||||
+1
-1
@@ -10,8 +10,8 @@ package com.cobblemon.mod.common.api.events.pokemon.evolution
|
|||||||
|
|
||||||
import com.bedrockk.molang.runtime.value.MoValue
|
import com.bedrockk.molang.runtime.value.MoValue
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.evolution.Evolution
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired after an evolution finishes.
|
* Fired after an evolution finishes.
|
||||||
|
|||||||
+2
-2
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.events.pokemon.evolution
|
package com.cobblemon.mod.common.api.events.pokemon.evolution
|
||||||
|
|
||||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
import com.cobblemon.mod.common.pokemon.transformation.evolution.Evolution
|
||||||
import com.cobblemon.mod.common.api.pokemon.evolution.EvolutionDisplay
|
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.evolution.EvolutionDisplay
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired before an evolution is sent to clients.
|
* Fired before an evolution is sent to clients.
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.events.pokemon.evolution
|
package com.cobblemon.mod.common.api.events.pokemon.evolution
|
||||||
|
|
||||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
import com.cobblemon.mod.common.pokemon.transformation.evolution.Evolution
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-1
@@ -12,8 +12,8 @@ import com.bedrockk.molang.runtime.value.DoubleValue
|
|||||||
import com.bedrockk.molang.runtime.value.MoValue
|
import com.bedrockk.molang.runtime.value.MoValue
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.evolution.Evolution
|
||||||
import com.cobblemon.mod.common.util.getBoolean
|
import com.cobblemon.mod.common.util.getBoolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.api.events.pokemon.form
|
||||||
|
|
||||||
|
import com.bedrockk.molang.runtime.value.StringValue
|
||||||
|
import com.cobblemon.mod.common.api.events.Cancelable
|
||||||
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||||
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.form.TemporaryForm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when a temporary form change is accepted.
|
||||||
|
* Cancelling will not notify users nor remove the form from the pending list.
|
||||||
|
*
|
||||||
|
* @param pokemon The [Pokemon] about to change form.
|
||||||
|
* @param form The [TemporaryForm] being used.
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since June 3rd, 2026
|
||||||
|
*/
|
||||||
|
data class FormAcceptedEvent(
|
||||||
|
override val pokemon: Pokemon,
|
||||||
|
override val form: TemporaryForm
|
||||||
|
) : Cancelable(), FormEvent {
|
||||||
|
val context = mutableMapOf(
|
||||||
|
"pokemon" to pokemon.struct,
|
||||||
|
"form" to StringValue(form.formOnlyShowdownId())
|
||||||
|
)
|
||||||
|
|
||||||
|
val functions = moLangFunctionMap(cancelFunc)
|
||||||
|
}
|
||||||
+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.events.pokemon.form
|
||||||
|
|
||||||
|
import com.bedrockk.molang.runtime.value.StringValue
|
||||||
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.form.TemporaryForm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after a temporary form change finishes.
|
||||||
|
*
|
||||||
|
* @param pokemon The [Pokemon] resulting from the form change.
|
||||||
|
* @param form The [TemporaryForm] that was used.
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since June 3rd, 2026
|
||||||
|
*/
|
||||||
|
data class FormCompleteEvent(
|
||||||
|
/** The [Pokemon] that did the form change. */
|
||||||
|
override val pokemon: Pokemon,
|
||||||
|
/** The [TemporaryForm] that was used. */
|
||||||
|
override val form: TemporaryForm
|
||||||
|
) : FormEvent {
|
||||||
|
val context = mutableMapOf(
|
||||||
|
"pokemon" to pokemon.struct,
|
||||||
|
"form" to StringValue(form.formOnlyShowdownId())
|
||||||
|
)
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.api.events.pokemon.form
|
||||||
|
|
||||||
|
import com.bedrockk.molang.runtime.value.StringValue
|
||||||
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.form.FormDisplay
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.form.TemporaryForm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired before a form is sent to clients. For modifications on the actual output when they accept it modify
|
||||||
|
* the [display] directly.
|
||||||
|
*
|
||||||
|
* @param pokemon The [Pokemon] that will change form if this proposition is accepted.
|
||||||
|
* @param display The current [FormDisplay] the client will see.
|
||||||
|
* @param form The [TemporaryForm] being used.
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since June 3rd, 2026
|
||||||
|
*/
|
||||||
|
data class FormDisplayEvent(
|
||||||
|
override val pokemon: Pokemon,
|
||||||
|
var display: FormDisplay,
|
||||||
|
override val form: TemporaryForm
|
||||||
|
) : FormEvent {
|
||||||
|
val context = mutableMapOf(
|
||||||
|
"pokemon" to pokemon.struct,
|
||||||
|
"display" to display.struct,
|
||||||
|
"form" to StringValue(form.formOnlyShowdownId())
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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.events.pokemon.form
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.form.TemporaryForm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The root of the various [TemporaryForm]-related events.
|
||||||
|
*/
|
||||||
|
interface FormEvent {
|
||||||
|
/** The Pokémon impacted in this event.*/
|
||||||
|
val pokemon: Pokemon
|
||||||
|
/*** The form triggering this event.*/
|
||||||
|
val form: TemporaryForm
|
||||||
|
}
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.api.events.pokemon.form
|
||||||
|
|
||||||
|
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||||
|
import com.bedrockk.molang.runtime.value.StringValue
|
||||||
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||||
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.form.TemporaryForm
|
||||||
|
import com.cobblemon.mod.common.util.getBoolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event fired when [TemporaryForm.test] has been performed.
|
||||||
|
* The final state [result] will be the return value of the test function.
|
||||||
|
*
|
||||||
|
* @property pokemon The [Pokemon] being tested against.
|
||||||
|
* @property form The [TemporaryForm] instance performing the test.
|
||||||
|
* @property originalResult The base result from the Cobblemon implementation.
|
||||||
|
* @property result The final value returned by [TemporaryForm.test].
|
||||||
|
*/
|
||||||
|
data class FormTestedEvent(
|
||||||
|
override val pokemon: Pokemon,
|
||||||
|
override val form: TemporaryForm,
|
||||||
|
val originalResult: Boolean,
|
||||||
|
) : FormEvent {
|
||||||
|
var result: Boolean = originalResult
|
||||||
|
|
||||||
|
val context = mutableMapOf(
|
||||||
|
"pokemon" to pokemon.struct,
|
||||||
|
"form" to StringValue(form.formOnlyShowdownId()),
|
||||||
|
"original_result" to DoubleValue(originalResult),
|
||||||
|
)
|
||||||
|
|
||||||
|
val functions = moLangFunctionMap(
|
||||||
|
"result" to { DoubleValue(result) },
|
||||||
|
"set_result" to {
|
||||||
|
result = it.getBoolean(0)
|
||||||
|
DoubleValue.ONE
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
-1
@@ -15,7 +15,6 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
|||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
import com.cobblemon.mod.common.util.getPlayer
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
-1
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.events.storage
|
package com.cobblemon.mod.common.api.events.storage
|
||||||
|
|
||||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
|
||||||
import com.bedrockk.molang.runtime.value.StringValue
|
import com.bedrockk.molang.runtime.value.StringValue
|
||||||
import com.cobblemon.mod.common.api.events.Cancelable
|
import com.cobblemon.mod.common.api.events.Cancelable
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||||
|
|||||||
-2
@@ -16,9 +16,7 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
|||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
|
||||||
import com.cobblemon.mod.common.api.storage.PokemonStore
|
import com.cobblemon.mod.common.api.storage.PokemonStore
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
import com.cobblemon.mod.common.util.getPlayer
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base of the events around the release of Pokémon from pc or party.
|
* The base of the events around the release of Pokémon from pc or party.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
|||||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||||
import com.cobblemon.mod.common.net.messages.client.data.FossilRegistrySyncPacket
|
import com.cobblemon.mod.common.net.messages.client.data.FossilRegistrySyncPacket
|
||||||
import com.cobblemon.mod.common.pokemon.evolution.adapters.LegacyItemConditionWrapperAdapter
|
import com.cobblemon.mod.common.pokemon.transformation.adapters.LegacyItemConditionWrapperAdapter
|
||||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||||
import com.cobblemon.mod.common.util.adapters.ItemLikeConditionAdapter
|
import com.cobblemon.mod.common.util.adapters.ItemLikeConditionAdapter
|
||||||
import com.cobblemon.mod.common.util.adapters.pokemonPropertiesShortAdapter
|
import com.cobblemon.mod.common.util.adapters.pokemonPropertiesShortAdapter
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class HabitatSpawn {
|
|||||||
/** The maximum light level that the Pokémon can spawn in. */
|
/** The maximum light level that the Pokémon can spawn in. */
|
||||||
var maxLight: Int? = null
|
var maxLight: Int? = null
|
||||||
|
|
||||||
open fun writeToNBT(nbt: CompoundTag) {
|
fun writeToNBT(nbt: CompoundTag) {
|
||||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_SPECIES, species.resourceIdentifier.toString())
|
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_SPECIES, species.resourceIdentifier.toString())
|
||||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_POSITION_TYPE, spawnablePositionType)
|
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_POSITION_TYPE, spawnablePositionType)
|
||||||
nbt.putFloat(DataKeys.HABITAT_POOL_SPAWN_WEIGHT, weight)
|
nbt.putFloat(DataKeys.HABITAT_POOL_SPAWN_WEIGHT, weight)
|
||||||
@@ -78,7 +78,7 @@ class HabitatSpawn {
|
|||||||
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_BUCKET, bucket)
|
nbt.putString(DataKeys.HABITAT_POOL_SPAWN_BUCKET, bucket)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun readFromNBT(nbt: CompoundTag) {
|
fun readFromNBT(nbt: CompoundTag) {
|
||||||
species = PokemonSpecies.getByIdentifier(nbt.getString(DataKeys.HABITAT_POOL_SPAWN_SPECIES).asIdentifierDefaultingNamespace())!!
|
species = PokemonSpecies.getByIdentifier(nbt.getString(DataKeys.HABITAT_POOL_SPAWN_SPECIES).asIdentifierDefaultingNamespace())!!
|
||||||
spawnablePositionType = nbt.getString(DataKeys.HABITAT_POOL_SPAWN_POSITION_TYPE)
|
spawnablePositionType = nbt.getString(DataKeys.HABITAT_POOL_SPAWN_POSITION_TYPE)
|
||||||
weight = nbt.getFloat(DataKeys.HABITAT_POOL_SPAWN_WEIGHT)
|
weight = nbt.getFloat(DataKeys.HABITAT_POOL_SPAWN_WEIGHT)
|
||||||
@@ -91,7 +91,7 @@ class HabitatSpawn {
|
|||||||
bucket = if (nbt.contains(DataKeys.HABITAT_POOL_SPAWN_BUCKET)) nbt.getString(DataKeys.HABITAT_POOL_SPAWN_BUCKET) else "common"
|
bucket = if (nbt.contains(DataKeys.HABITAT_POOL_SPAWN_BUCKET)) nbt.getString(DataKeys.HABITAT_POOL_SPAWN_BUCKET) else "common"
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun encode(buffer: RegistryFriendlyByteBuf) {
|
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||||
buffer.writeResourceLocation(species.resourceIdentifier)
|
buffer.writeResourceLocation(species.resourceIdentifier)
|
||||||
buffer.writeUtf(spawnablePositionType)
|
buffer.writeUtf(spawnablePositionType)
|
||||||
buffer.writeFloat(weight)
|
buffer.writeFloat(weight)
|
||||||
@@ -104,7 +104,7 @@ class HabitatSpawn {
|
|||||||
buffer.writeUtf(bucket)
|
buffer.writeUtf(bucket)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun decode(buffer: RegistryFriendlyByteBuf) {
|
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||||
species = PokemonSpecies.getByIdentifier(buffer.readResourceLocation())!!
|
species = PokemonSpecies.getByIdentifier(buffer.readResourceLocation())!!
|
||||||
spawnablePositionType = buffer.readUtf()
|
spawnablePositionType = buffer.readUtf()
|
||||||
weight = buffer.readFloat()
|
weight = buffer.readFloat()
|
||||||
@@ -118,7 +118,7 @@ class HabitatSpawn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Creates the [PokemonSpawnDetail] that will be used in the spawner. This is done per habitat block. */
|
/** Creates the [PokemonSpawnDetail] that will be used in the spawner. This is done per habitat block. */
|
||||||
open fun createSpawnDetail(habitatBlockEntity: HabitatBlockEntity): PokemonSpawnDetail? {
|
fun createSpawnDetail(habitatBlockEntity: HabitatBlockEntity): PokemonSpawnDetail? {
|
||||||
val spawnDetail = PokemonSpawnDetail()
|
val spawnDetail = PokemonSpawnDetail()
|
||||||
|
|
||||||
// If the habitat block specifies a level range, it restricts how and if this spawn exists
|
// If the habitat block specifies a level range, it restricts how and if this spawn exists
|
||||||
|
|||||||
+5
-5
@@ -13,13 +13,13 @@ import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
|
|||||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
import com.cobblemon.mod.common.api.pokemon.transformation.requirement.TransformationRequirement
|
||||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||||
import com.cobblemon.mod.common.net.messages.client.data.PokemonInteractionsSyncPacket
|
import com.cobblemon.mod.common.net.messages.client.data.PokemonInteractionsSyncPacket
|
||||||
import com.cobblemon.mod.common.pokemon.adapters.CobblemonRequirementAdapter
|
import com.cobblemon.mod.common.pokemon.transformation.adapters.CobblemonRequirementAdapter
|
||||||
import com.cobblemon.mod.common.pokemon.evolution.adapters.LegacyItemConditionWrapperAdapter
|
import com.cobblemon.mod.common.pokemon.transformation.adapters.LegacyItemConditionWrapperAdapter
|
||||||
import com.cobblemon.mod.common.pokemon.requirements.PokemonPropertiesRequirement
|
import com.cobblemon.mod.common.pokemon.transformation.requirements.PokemonPropertiesRequirement
|
||||||
import com.cobblemon.mod.common.util.adapters.*
|
import com.cobblemon.mod.common.util.adapters.*
|
||||||
import com.cobblemon.mod.common.util.cobblemonResource
|
import com.cobblemon.mod.common.util.cobblemonResource
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
@@ -46,7 +46,7 @@ object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
|
|||||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||||
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
|
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
|
||||||
.registerTypeAdapter(ItemPredicate::class.java, LegacyItemConditionWrapperAdapter)
|
.registerTypeAdapter(ItemPredicate::class.java, LegacyItemConditionWrapperAdapter)
|
||||||
.registerTypeAdapter(Requirement::class.java, CobblemonRequirementAdapter)
|
.registerTypeAdapter(TransformationRequirement::class.java, CobblemonRequirementAdapter)
|
||||||
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
|
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
|
||||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||||
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
|
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
|
||||||
|
|||||||
+10
-5
@@ -12,11 +12,16 @@ import com.bedrockk.molang.runtime.MoLangRuntime
|
|||||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
import com.cobblemon.mod.common.api.pokemon.transformation.requirement.TransformationRequirement
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||||
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
||||||
import com.cobblemon.mod.common.pokemon.adapters.CobblemonRequirementAdapter
|
import com.cobblemon.mod.common.pokemon.transformation.adapters.CobblemonRequirementAdapter
|
||||||
import com.cobblemon.mod.common.util.*
|
import com.cobblemon.mod.common.util.asExpressionLike
|
||||||
|
import com.cobblemon.mod.common.util.giveOrDropItemStack
|
||||||
|
import com.cobblemon.mod.common.util.readExpressionLike
|
||||||
|
import com.cobblemon.mod.common.util.withPlayerValue
|
||||||
|
import com.cobblemon.mod.common.util.withQueryValue
|
||||||
|
import com.cobblemon.mod.common.util.writeExpressionLike
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
import net.minecraft.core.registries.Registries
|
import net.minecraft.core.registries.Registries
|
||||||
import net.minecraft.network.FriendlyByteBuf
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
@@ -29,7 +34,7 @@ import net.minecraft.world.entity.item.ItemEntity
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
|
|
||||||
data class PokemonInteractionSet(
|
data class PokemonInteractionSet(
|
||||||
val requirements: List<Requirement> = listOf(),
|
val requirements: List<TransformationRequirement> = listOf(),
|
||||||
val interactions: List<PokemonInteraction> = listOf(),
|
val interactions: List<PokemonInteraction> = listOf(),
|
||||||
) {
|
) {
|
||||||
fun encode(buffer: FriendlyByteBuf) {
|
fun encode(buffer: FriendlyByteBuf) {
|
||||||
@@ -51,7 +56,7 @@ data class PokemonInteractionSet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class PokemonInteraction(
|
data class PokemonInteraction(
|
||||||
val requirements: List<Requirement> = listOf(),
|
val requirements: List<TransformationRequirement> = listOf(),
|
||||||
val effects: List<InteractionEffect> = listOf(),
|
val effects: List<InteractionEffect> = listOf(),
|
||||||
val cooldown: ExpressionLike = "0".asExpressionLike()
|
val cooldown: ExpressionLike = "0".asExpressionLike()
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ abstract class RequestManager<T : ServerPlayerActionRequest> {
|
|||||||
?: this.getInboundRequest(receiver.uuid, requestID)
|
?: this.getInboundRequest(receiver.uuid, requestID)
|
||||||
|
|
||||||
/** Determines whether [player] can receive a [T]. */
|
/** Determines whether [player] can receive a [T]. */
|
||||||
open fun isBusy(player: ServerPlayer): Boolean = player.isInBattle() || player.isTrading() || player.party().find { it.entity?.isBusy == true } != null
|
open fun isBusy(player: ServerPlayer): Boolean = player.isBusy() || player.isPartyBusy()
|
||||||
|
|
||||||
/** Determines if the [target] is a valid interaction request target. */
|
/** Determines if the [target] is a valid interaction request target. */
|
||||||
abstract fun isValidInteraction(player: ServerPlayer, target: ServerPlayer): Boolean
|
abstract fun isValidInteraction(player: ServerPlayer, target: ServerPlayer): Boolean
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
package com.cobblemon.mod.common.api.item
|
package com.cobblemon.mod.common.api.item
|
||||||
|
|
||||||
import com.cobblemon.mod.common.api.data.DataRegistry
|
import com.cobblemon.mod.common.api.data.DataRegistry
|
||||||
|
import com.cobblemon.mod.common.api.data.ShowdownIdentifiable
|
||||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||||
import com.cobblemon.mod.common.battles.runner.ShowdownService
|
import com.cobblemon.mod.common.battles.runner.ShowdownService
|
||||||
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
|
||||||
@@ -29,9 +30,11 @@ object HeldItems : DataRegistry {
|
|||||||
// val heldItems = PrioritizedList<BagItemLike>()
|
// val heldItems = PrioritizedList<BagItemLike>()
|
||||||
internal val heldItemsScripts = mutableMapOf<String, String>() // showdown item ID to JavaScript
|
internal val heldItemsScripts = mutableMapOf<String, String>() // showdown item ID to JavaScript
|
||||||
val showdownItems = hashSetOf<String>()
|
val showdownItems = hashSetOf<String>()
|
||||||
|
val megaStones = hashMapOf<String, String>()
|
||||||
|
|
||||||
override fun reload(manager: ResourceManager) {
|
override fun reload(manager: ResourceManager) {
|
||||||
heldItemsScripts.clear()
|
heldItemsScripts.clear()
|
||||||
|
megaStones.clear()
|
||||||
ShowdownService.service.resetRegistryData("heldItem")
|
ShowdownService.service.resetRegistryData("heldItem")
|
||||||
manager.listResources("held_items") { it.path.endsWith(".js") }.forEach { (identifier, resource) ->
|
manager.listResources("held_items") { it.path.endsWith(".js") }.forEach { (identifier, resource) ->
|
||||||
resource.open().use { stream ->
|
resource.open().use { stream ->
|
||||||
@@ -48,6 +51,9 @@ object HeldItems : DataRegistry {
|
|||||||
for (i in 0 until itemsJson.size()) {
|
for (i in 0 until itemsJson.size()) {
|
||||||
val jsItem = itemsJson[i].asJsonObject
|
val jsItem = itemsJson[i].asJsonObject
|
||||||
showdownItems += jsItem.get("id").asString
|
showdownItems += jsItem.get("id").asString
|
||||||
|
if (jsItem.has("megaEvolves")) {
|
||||||
|
megaStones[jsItem.get("id").asString] = ShowdownIdentifiable.REGEX.replace(jsItem.get("megaEvolves").asString.lowercase(), "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CobblemonHeldItemManager.load()
|
CobblemonHeldItemManager.load()
|
||||||
|
|||||||
@@ -21,34 +21,9 @@ import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
|
|||||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||||
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
|
||||||
import com.cobblemon.mod.common.api.drop.DropEntry
|
import com.cobblemon.mod.common.api.drop.DropEntry
|
||||||
import com.cobblemon.mod.common.api.molang.function.BattleActorMoLangFunctions
|
import com.cobblemon.mod.common.api.molang.function.*
|
||||||
import com.cobblemon.mod.common.api.molang.function.BattleMessageMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.BattleMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.BiomeMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.BlockMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.DimensionTypeMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.DropEntryMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.EntityMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.EvolutionMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.GeneralMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.ItemStackMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.LivingEntityMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.NPCMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.PCMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.PartyMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.PlayerMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.PokedexMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.PokemonEntityMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.PokemonMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.PokemonPropertiesMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.PokemonStoreMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.ServerMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.SpawnablePositionMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.SpeciesMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.molang.function.WorldMoLangFunctions
|
|
||||||
import com.cobblemon.mod.common.api.pokedex.AbstractPokedexManager
|
import com.cobblemon.mod.common.api.pokedex.AbstractPokedexManager
|
||||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
|
||||||
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
||||||
import com.cobblemon.mod.common.api.spawning.position.SpawnablePosition
|
import com.cobblemon.mod.common.api.spawning.position.SpawnablePosition
|
||||||
import com.cobblemon.mod.common.api.storage.PokemonStore
|
import com.cobblemon.mod.common.api.storage.PokemonStore
|
||||||
@@ -58,8 +33,10 @@ import com.cobblemon.mod.common.entity.npc.NPCEntity
|
|||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
import com.cobblemon.mod.common.pokemon.Species
|
import com.cobblemon.mod.common.pokemon.Species
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.evolution.Evolution
|
||||||
import com.cobblemon.mod.common.util.effectiveName
|
import com.cobblemon.mod.common.util.effectiveName
|
||||||
import com.mojang.datafixers.util.Either
|
import com.mojang.datafixers.util.Either
|
||||||
|
import java.util.function.Function
|
||||||
import net.minecraft.core.Holder
|
import net.minecraft.core.Holder
|
||||||
import net.minecraft.core.Registry
|
import net.minecraft.core.Registry
|
||||||
import net.minecraft.core.RegistryAccess
|
import net.minecraft.core.RegistryAccess
|
||||||
@@ -83,14 +60,7 @@ import net.minecraft.world.level.Level
|
|||||||
import net.minecraft.world.level.biome.Biome
|
import net.minecraft.world.level.biome.Biome
|
||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.dimension.DimensionType
|
import net.minecraft.world.level.dimension.DimensionType
|
||||||
import net.minecraft.world.level.levelgen.Heightmap
|
|
||||||
import net.minecraft.world.level.pathfinder.PathType
|
|
||||||
import net.minecraft.world.level.storage.loot.LootParams
|
|
||||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
|
|
||||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
|
||||||
import net.minecraft.world.phys.AABB
|
|
||||||
import net.minecraft.world.phys.Vec3
|
import net.minecraft.world.phys.Vec3
|
||||||
import java.util.function.Function
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds a bunch of useful MoLang trickery that can be used or extended in API
|
* Holds a bunch of useful MoLang trickery that can be used or extended in API
|
||||||
@@ -99,25 +69,31 @@ import java.util.function.Function
|
|||||||
* @since October 2nd, 2023
|
* @since October 2nd, 2023
|
||||||
*/
|
*/
|
||||||
object MoLangFunctions {
|
object MoLangFunctions {
|
||||||
fun ItemStack.asMoLangValue(registryAccess: RegistryAccess) = ObjectValue(this)
|
fun ItemStack.asMoLangValue(registryAccess: RegistryAccess) =
|
||||||
.addStandardFunctions()
|
ObjectValue(this)
|
||||||
.addFunctions(ItemStackMoLangFunctions.attach(Pair(this, registryAccess)))
|
.addStandardFunctions()
|
||||||
|
.addFunctions(ItemStackMoLangFunctions.attach(Pair(this, registryAccess)))
|
||||||
|
|
||||||
fun Holder<Biome>.asBiomeMoLangValue() = asMoLangValue(Registries.BIOME)
|
fun Holder<Biome>.asBiomeMoLangValue() =
|
||||||
.addFunctions(BiomeMoLangFunctions.attach(this))
|
asMoLangValue(Registries.BIOME)
|
||||||
|
.addFunctions(BiomeMoLangFunctions.attach(this))
|
||||||
|
|
||||||
fun Holder<Level>.asWorldMoLangValue() = asMoLangValue(Registries.DIMENSION)
|
fun Holder<Level>.asWorldMoLangValue() =
|
||||||
.addFunctions(WorldMoLangFunctions.attach(this))
|
asMoLangValue(Registries.DIMENSION)
|
||||||
|
.addFunctions(WorldMoLangFunctions.attach(this))
|
||||||
|
|
||||||
fun Holder<Block>.asBlockMoLangValue() = asMoLangValue(Registries.BLOCK)
|
fun Holder<Block>.asBlockMoLangValue() =
|
||||||
.addFunctions(BlockMoLangFunctions.attach(this))
|
asMoLangValue(Registries.BLOCK)
|
||||||
|
.addFunctions(BlockMoLangFunctions.attach(this))
|
||||||
|
|
||||||
fun MinecraftServer.asMoLangValue() = ObjectValue(this)
|
fun MinecraftServer.asMoLangValue() =
|
||||||
.addStandardFunctions()
|
ObjectValue(this)
|
||||||
.addFunctions(ServerMoLangFunctions.attach(this))
|
.addStandardFunctions()
|
||||||
|
.addFunctions(ServerMoLangFunctions.attach(this))
|
||||||
|
|
||||||
fun Holder<DimensionType>.asDimensionTypeMoLangValue() = asMoLangValue(Registries.DIMENSION_TYPE)
|
fun Holder<DimensionType>.asDimensionTypeMoLangValue() =
|
||||||
.addFunctions(DimensionTypeMoLangFunctions.attach(this))
|
asMoLangValue(Registries.DIMENSION_TYPE)
|
||||||
|
.addFunctions(DimensionTypeMoLangFunctions.attach(this))
|
||||||
|
|
||||||
fun Player.asMoLangValue(): ObjectValue<Player> {
|
fun Player.asMoLangValue(): ObjectValue<Player> {
|
||||||
if (this is ServerPlayer && uuid in Cobblemon.serverPlayerStructs) {
|
if (this is ServerPlayer && uuid in Cobblemon.serverPlayerStructs) {
|
||||||
@@ -129,10 +105,11 @@ object MoLangFunctions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.effectiveName().string }
|
obj = this,
|
||||||
)
|
stringify = { it.effectiveName().string },
|
||||||
|
)
|
||||||
|
|
||||||
value.addFunctions(EntityMoLangFunctions.attach(this))
|
value.addFunctions(EntityMoLangFunctions.attach(this))
|
||||||
value.addFunctions(LivingEntityMoLangFunctions.attach(this))
|
value.addFunctions(LivingEntityMoLangFunctions.attach(this))
|
||||||
@@ -153,57 +130,63 @@ object MoLangFunctions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PartyStore.asMoLangValue(): ObjectValue<PartyStore> {
|
fun PartyStore.asMoLangValue(): ObjectValue<PartyStore> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.toString() }
|
obj = this,
|
||||||
)
|
stringify = { it.toString() },
|
||||||
|
)
|
||||||
value.addFunctions(PokemonStoreMoLangFunctions.attach(this))
|
value.addFunctions(PokemonStoreMoLangFunctions.attach(this))
|
||||||
value.addFunctions(PartyMoLangFunctions.attach(this))
|
value.addFunctions(PartyMoLangFunctions.attach(this))
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DropEntry.asMoLangValue(): ObjectValue<DropEntry> {
|
fun DropEntry.asMoLangValue(): ObjectValue<DropEntry> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.toString() }
|
obj = this,
|
||||||
)
|
stringify = { it.toString() },
|
||||||
|
)
|
||||||
value.addFunctions(DropEntryMoLangFunctions.attach(this))
|
value.addFunctions(DropEntryMoLangFunctions.attach(this))
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PokemonProperties.asMoLangValue(): ObjectValue<PokemonProperties> {
|
fun PokemonProperties.asMoLangValue(): ObjectValue<PokemonProperties> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.asString() }
|
obj = this,
|
||||||
)
|
stringify = { it.asString() },
|
||||||
|
)
|
||||||
value.addFunctions(PokemonPropertiesMoLangFunctions.attach(this))
|
value.addFunctions(PokemonPropertiesMoLangFunctions.attach(this))
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Evolution.asMoLangValue(): ObjectValue<Evolution> {
|
fun Evolution.asMoLangValue(): ObjectValue<Evolution> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.toString() }
|
obj = this,
|
||||||
)
|
stringify = { it.toString() },
|
||||||
|
)
|
||||||
value.addFunctions(EvolutionMoLangFunctions.attach(this))
|
value.addFunctions(EvolutionMoLangFunctions.attach(this))
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PCStore.asMoLangValue(): ObjectValue<PCStore> {
|
fun PCStore.asMoLangValue(): ObjectValue<PCStore> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.toString() }
|
obj = this,
|
||||||
)
|
stringify = { it.toString() },
|
||||||
|
)
|
||||||
value.addFunctions(PokemonStoreMoLangFunctions.attach(this))
|
value.addFunctions(PokemonStoreMoLangFunctions.attach(this))
|
||||||
value.addFunctions(PCMoLangFunctions.attach(this))
|
value.addFunctions(PCMoLangFunctions.attach(this))
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NPCEntity.asMoLangValue(): ObjectValue<NPCEntity> {
|
fun NPCEntity.asMoLangValue(): ObjectValue<NPCEntity> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.name.string }
|
obj = this,
|
||||||
)
|
stringify = { it.name.string },
|
||||||
|
)
|
||||||
value.addFunctions(EntityMoLangFunctions.attach(this))
|
value.addFunctions(EntityMoLangFunctions.attach(this))
|
||||||
value.addFunctions(LivingEntityMoLangFunctions.attach(this))
|
value.addFunctions(LivingEntityMoLangFunctions.attach(this))
|
||||||
value.addFunctions(NPCMoLangFunctions.attach(this))
|
value.addFunctions(NPCMoLangFunctions.attach(this))
|
||||||
@@ -211,10 +194,11 @@ object MoLangFunctions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PokemonEntity.asMoLangValue(): ObjectValue<PokemonEntity> {
|
fun PokemonEntity.asMoLangValue(): ObjectValue<PokemonEntity> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.pokemon.uuid.toString() }
|
obj = this,
|
||||||
)
|
stringify = { it.pokemon.uuid.toString() },
|
||||||
|
)
|
||||||
|
|
||||||
value.addFunctions(EntityMoLangFunctions.attach(this))
|
value.addFunctions(EntityMoLangFunctions.attach(this))
|
||||||
value.addFunctions(LivingEntityMoLangFunctions.attach(this))
|
value.addFunctions(LivingEntityMoLangFunctions.attach(this))
|
||||||
@@ -225,36 +209,40 @@ object MoLangFunctions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PokemonBattle.asMoLangValue(): ObjectValue<PokemonBattle> {
|
fun PokemonBattle.asMoLangValue(): ObjectValue<PokemonBattle> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.battleId.toString() }
|
obj = this,
|
||||||
)
|
stringify = { it.battleId.toString() },
|
||||||
|
)
|
||||||
value.addFunctions(BattleMoLangFunctions.attach(this))
|
value.addFunctions(BattleMoLangFunctions.attach(this))
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun BattleActor.asMoLangValue(): ObjectValue<BattleActor> {
|
fun BattleActor.asMoLangValue(): ObjectValue<BattleActor> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.toString() }
|
obj = this,
|
||||||
)
|
stringify = { it.toString() },
|
||||||
|
)
|
||||||
value.addFunctions(BattleActorMoLangFunctions.attach(this))
|
value.addFunctions(BattleActorMoLangFunctions.attach(this))
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun SpawnablePosition.asMoLangValue(): ObjectValue<SpawnablePosition> {
|
fun SpawnablePosition.asMoLangValue(): ObjectValue<SpawnablePosition> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.toString() }
|
obj = this,
|
||||||
)
|
stringify = { it.toString() },
|
||||||
|
)
|
||||||
value.addFunctions(SpawnablePositionMoLangFunctions.attach(this))
|
value.addFunctions(SpawnablePositionMoLangFunctions.attach(this))
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Vec3.asMoLangValue(): ObjectValue<Vec3> {
|
fun Vec3.asMoLangValue(): ObjectValue<Vec3> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this
|
ObjectValue(
|
||||||
)
|
obj = this,
|
||||||
|
)
|
||||||
value.addFunction("x") { this.x }
|
value.addFunction("x") { this.x }
|
||||||
value.addFunction("y") { this.y }
|
value.addFunction("y") { this.y }
|
||||||
value.addFunction("z") { this.z }
|
value.addFunction("z") { this.z }
|
||||||
@@ -265,45 +253,66 @@ object MoLangFunctions {
|
|||||||
/**
|
/**
|
||||||
* Different functions exist depending on the entity type, this tries to make the struct that's most specific to the type.
|
* Different functions exist depending on the entity type, this tries to make the struct that's most specific to the type.
|
||||||
*/
|
*/
|
||||||
fun Entity.asMostSpecificMoLangValue(): ObjectValue<out Entity> {
|
fun Entity.asMostSpecificMoLangValue(): ObjectValue<out Entity> =
|
||||||
return when (this) {
|
when (this) {
|
||||||
is Player -> asMoLangValue()
|
is Player -> {
|
||||||
is PokemonEntity -> struct
|
asMoLangValue()
|
||||||
is NPCEntity -> struct
|
|
||||||
is ItemEntity -> ObjectValue(this).also { item ->
|
|
||||||
item.addStandardFunctions()
|
|
||||||
item.addFunctions(EntityMoLangFunctions.attach(this))
|
|
||||||
item.addFunctions(ItemStackMoLangFunctions.attach(Pair(this.item, this.registryAccess())))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> ObjectValue(this).also { objectValue ->
|
is PokemonEntity -> {
|
||||||
objectValue.addStandardFunctions()
|
struct
|
||||||
objectValue.addFunctions(EntityMoLangFunctions.attach(this))
|
}
|
||||||
if (this is LivingEntity) {
|
|
||||||
objectValue.addFunctions(LivingEntityMoLangFunctions.attach(this))
|
is NPCEntity -> {
|
||||||
|
struct
|
||||||
|
}
|
||||||
|
|
||||||
|
is ItemEntity -> {
|
||||||
|
ObjectValue(this).also { item ->
|
||||||
|
item.addStandardFunctions()
|
||||||
|
item.addFunctions(EntityMoLangFunctions.attach(this))
|
||||||
|
item.addFunctions(ItemStackMoLangFunctions.attach(Pair(this.item, this.registryAccess())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
ObjectValue(this).also { objectValue ->
|
||||||
|
objectValue.addStandardFunctions()
|
||||||
|
objectValue.addFunctions(EntityMoLangFunctions.attach(this))
|
||||||
|
if (this is LivingEntity) {
|
||||||
|
objectValue.addFunctions(LivingEntityMoLangFunctions.attach(this))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> Holder<T>.asMoLangValue(key: ResourceKey<Registry<T>>): ObjectValue<Holder<T>> {
|
fun <T> Holder<T>.asMoLangValue(key: ResourceKey<Registry<T>>): ObjectValue<Holder<T>> {
|
||||||
val value = ObjectValue(
|
val value =
|
||||||
obj = this,
|
ObjectValue(
|
||||||
stringify = { it.unwrapKey().get().location().toString() }
|
obj = this,
|
||||||
)
|
stringify = {
|
||||||
value.functions["is_in"] = Function put@{ params: MoParams ->
|
it
|
||||||
val tag = TagKey.create(key, ResourceLocation.parse(params.getString(0).replace("#", "")))
|
.unwrapKey()
|
||||||
return@put DoubleValue(if (value.obj.`is`(tag)) 1.0 else 0.0)
|
.get()
|
||||||
}
|
.location()
|
||||||
value.functions["is_of"] = Function put@{ params: MoParams ->
|
.toString()
|
||||||
val identifier = ResourceLocation.parse(params.getString(0))
|
},
|
||||||
return@put DoubleValue(if (value.obj.`is`(identifier)) 1.0 else 0.0)
|
)
|
||||||
}
|
value.functions["is_in"] =
|
||||||
|
Function put@{ params: MoParams ->
|
||||||
|
val tag = TagKey.create(key, ResourceLocation.parse(params.getString(0).replace("#", "")))
|
||||||
|
return@put DoubleValue(if (value.obj.`is`(tag)) 1.0 else 0.0)
|
||||||
|
}
|
||||||
|
value.functions["is_of"] =
|
||||||
|
Function put@{ params: MoParams ->
|
||||||
|
val identifier = ResourceLocation.parse(params.getString(0))
|
||||||
|
return@put DoubleValue(if (value.obj.`is`(identifier)) 1.0 else 0.0)
|
||||||
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun QueryStruct.addStandardFunctions(): QueryStruct {
|
fun QueryStruct.addStandardFunctions(): QueryStruct {
|
||||||
addFunctions(GeneralMoLangFunctions.holder)
|
addFunctions(GeneralMoLangFunctions.functions)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,23 +379,17 @@ object MoLangFunctions {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun moLangFunctionMap(
|
fun moLangFunctionMap(vararg functions: Pair<String, (MoParams) -> MoValue>): Map<String, (MoParams) -> MoValue> = functions.toMap()
|
||||||
vararg functions: Pair<String, (MoParams) -> MoValue>
|
|
||||||
): Map<String, (MoParams) -> MoValue> {
|
|
||||||
return functions.toMap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun queryStructOf(
|
fun queryStructOf(vararg functions: Pair<String, (MoParams) -> MoValue>): QueryStruct =
|
||||||
vararg functions: Pair<String, (MoParams) -> MoValue>
|
QueryStruct(
|
||||||
): QueryStruct {
|
|
||||||
return QueryStruct(
|
|
||||||
hashMapOf<String, Function<MoParams, Any>>(
|
hashMapOf<String, Function<MoParams, Any>>(
|
||||||
*functions.map { (name, func) ->
|
*functions
|
||||||
name to Function<MoParams, Any> { params -> func(params) }
|
.map { (name, func) ->
|
||||||
}.toTypedArray()
|
name to Function<MoParams, Any> { params -> func(params) }
|
||||||
)
|
}.toTypedArray(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
fun MoLangRuntime.setup(): MoLangRuntime {
|
fun MoLangRuntime.setup(): MoLangRuntime {
|
||||||
environment.query.addStandardFunctions()
|
environment.query.addStandardFunctions()
|
||||||
@@ -395,8 +398,14 @@ object MoLangFunctions {
|
|||||||
|
|
||||||
fun writeMoValueToNBT(value: MoValue): Tag? {
|
fun writeMoValueToNBT(value: MoValue): Tag? {
|
||||||
return when (value) {
|
return when (value) {
|
||||||
is DoubleValue -> DoubleTag.valueOf(value.value)
|
is DoubleValue -> {
|
||||||
is StringValue -> StringTag.valueOf(value.value)
|
DoubleTag.valueOf(value.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
is StringValue -> {
|
||||||
|
StringTag.valueOf(value.value)
|
||||||
|
}
|
||||||
|
|
||||||
is ArrayStruct -> {
|
is ArrayStruct -> {
|
||||||
val list = value.map.values
|
val list = value.map.values
|
||||||
val nbtList = ListTag()
|
val nbtList = ListTag()
|
||||||
@@ -413,14 +422,22 @@ object MoLangFunctions {
|
|||||||
nbt
|
nbt
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
else -> {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun readMoValueFromNBT(nbt: Tag): MoValue {
|
fun readMoValueFromNBT(nbt: Tag): MoValue =
|
||||||
return when (nbt) {
|
when (nbt) {
|
||||||
is DoubleTag -> DoubleValue(nbt.asDouble)
|
is DoubleTag -> {
|
||||||
is StringTag -> StringValue(nbt.asString)
|
DoubleValue(nbt.asDouble)
|
||||||
|
}
|
||||||
|
|
||||||
|
is StringTag -> {
|
||||||
|
StringValue(nbt.asString)
|
||||||
|
}
|
||||||
|
|
||||||
is ListTag -> {
|
is ListTag -> {
|
||||||
val array = ArrayStruct(hashMapOf())
|
val array = ArrayStruct(hashMapOf())
|
||||||
var index = 0
|
var index = 0
|
||||||
@@ -441,11 +458,12 @@ object MoLangFunctions {
|
|||||||
variable
|
variable
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> VariableStruct()
|
else -> {
|
||||||
|
VariableStruct()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this one is unused. Should we move it to [MoLangFunctions] object?
|
// TODO: this one is unused. Should we move it to [MoLangFunctions] object?
|
||||||
fun Either<ResourceLocation, ExpressionLike>.runScript(runtime: MoLangRuntime) =
|
fun Either<ResourceLocation, ExpressionLike>.runScript(runtime: MoLangRuntime) =
|
||||||
map({ CobblemonScripts.run(it, runtime) }, { it.resolve(runtime) })
|
map({ CobblemonScripts.run(it, runtime) }, { it.resolve(runtime) })
|
||||||
|
|||||||
+9
-10
@@ -17,30 +17,29 @@ import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
|
|||||||
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
|
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
|
||||||
import com.cobblemon.mod.common.entity.npc.NPCBattleActor
|
import com.cobblemon.mod.common.entity.npc.NPCBattleActor
|
||||||
|
|
||||||
|
|
||||||
object BattleActorMoLangFunctions : AbstractMoLangFunctionHolder<BattleActor>() {
|
object BattleActorMoLangFunctions : AbstractMoLangFunctionHolder<BattleActor>() {
|
||||||
override fun BattleActor.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun BattleActor.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val actor = this
|
val actor = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>(
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
"is_npc" to { DoubleValue(actor.type == ActorType.NPC) },
|
|
||||||
"is_player" to { DoubleValue(actor.type == ActorType.PLAYER) },
|
functions["is_npc"] = { DoubleValue(actor.type == ActorType.NPC) }
|
||||||
"is_wild" to { DoubleValue(actor.type == ActorType.WILD) }
|
functions["is_player"] = { DoubleValue(actor.type == ActorType.PLAYER) }
|
||||||
)
|
functions["is_wild"] = { DoubleValue(actor.type == ActorType.WILD) }
|
||||||
|
|
||||||
when (actor) {
|
when (actor) {
|
||||||
is NPCBattleActor -> {
|
is NPCBattleActor -> {
|
||||||
map["npc"] = { actor.entity.struct }
|
functions["npc"] = { actor.entity.struct }
|
||||||
}
|
}
|
||||||
|
|
||||||
is PlayerBattleActor -> {
|
is PlayerBattleActor -> {
|
||||||
map["player"] = { actor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
|
functions["player"] = { actor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
|
||||||
}
|
}
|
||||||
|
|
||||||
is PokemonBattleActor -> {
|
is PokemonBattleActor -> {
|
||||||
map["pokemon"] = { actor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
|
functions["pokemon"] = { actor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return map
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-12
@@ -16,17 +16,19 @@ import com.cobblemon.mod.common.util.getStringOrNull
|
|||||||
object BattleMessageMoLangFunctions : AbstractMoLangFunctionHolder<BattleMessage>() {
|
object BattleMessageMoLangFunctions : AbstractMoLangFunctionHolder<BattleMessage>() {
|
||||||
override fun BattleMessage.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun BattleMessage.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val battleMessage = this
|
val battleMessage = this
|
||||||
return mutableMapOf(
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
"has_argument_at" to { params ->
|
|
||||||
val index = params.getInt(0)
|
functions["has_argument_at"] = { params ->
|
||||||
val value = params.getStringOrNull(1) ?: ""
|
val index = params.getInt(0)
|
||||||
DoubleValue(value == battleMessage.argumentAt(index))
|
val value = params.getStringOrNull(1) ?: ""
|
||||||
},
|
DoubleValue(value == battleMessage.argumentAt(index))
|
||||||
"has_argument" to { params ->
|
}
|
||||||
val argumentName = params.getString(0)
|
functions["has_argument"] = { params ->
|
||||||
val value = params.getStringOrNull(1) ?: ""
|
val argumentName = params.getString(0)
|
||||||
DoubleValue(value == battleMessage.optionalArgument(argumentName))
|
val value = params.getStringOrNull(1) ?: ""
|
||||||
}
|
DoubleValue(value == battleMessage.optionalArgument(argumentName))
|
||||||
)
|
}
|
||||||
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-16
@@ -13,25 +13,27 @@ import com.bedrockk.molang.runtime.value.DoubleValue
|
|||||||
import com.bedrockk.molang.runtime.value.StringValue
|
import com.bedrockk.molang.runtime.value.StringValue
|
||||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||||
import com.cobblemon.mod.common.util.asArrayValue
|
import com.cobblemon.mod.common.util.asArrayValue
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
|
|
||||||
object BattleMoLangFunctions : AbstractMoLangFunctionHolder<PokemonBattle>() {
|
object BattleMoLangFunctions : AbstractMoLangFunctionHolder<PokemonBattle>() {
|
||||||
override fun PokemonBattle.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun PokemonBattle.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val battle = this
|
val battle = this
|
||||||
return mutableMapOf(
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
"environment" to { battle.runtime.environment },
|
|
||||||
"battle_id" to { StringValue(battle.battleId.toString()) },
|
functions["environment"] = { battle.runtime.environment }
|
||||||
"battle_type" to { StringValue(battle.format.toString()) },
|
functions["battle_id"] = { StringValue(battle.battleId.toString()) }
|
||||||
"is_pvn" to { DoubleValue(battle.isPvN) },
|
functions["battle_type"] = { StringValue(battle.format.toString()) }
|
||||||
"is_pvp" to { DoubleValue(battle.isPvP) },
|
functions["is_pvn"] = { DoubleValue(battle.isPvN) }
|
||||||
"is_pvw" to { DoubleValue(battle.isPvW) },
|
functions["is_pvp"] = { DoubleValue(battle.isPvP) }
|
||||||
"stop" to { battle.stop() },
|
functions["is_pvw"] = { DoubleValue(battle.isPvW) }
|
||||||
"actors" to { battle.actors.toList().asArrayValue { it.struct } },
|
functions["stop"] = { battle.stop() }
|
||||||
"get_actor" to getActor@{ params ->
|
functions["actors"] = { battle.actors.toList().asArrayValue { it.struct } }
|
||||||
val uuid = UUID.fromString(params.getString(0))
|
functions["get_actor"] = getActor@{ params ->
|
||||||
val actor = battle.actors.find { it.uuid == uuid } ?: return@getActor DoubleValue.ZERO
|
val uuid = UUID.fromString(params.getString(0))
|
||||||
actor.struct
|
val actor = battle.actors.find { it.uuid == uuid } ?: return@getActor DoubleValue.ZERO
|
||||||
}
|
actor.struct
|
||||||
)
|
}
|
||||||
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -12,8 +12,11 @@ import com.bedrockk.molang.runtime.MoParams
|
|||||||
import net.minecraft.core.Holder
|
import net.minecraft.core.Holder
|
||||||
import net.minecraft.world.level.biome.Biome
|
import net.minecraft.world.level.biome.Biome
|
||||||
|
|
||||||
object BiomeMoLangFunctions: AbstractMoLangFunctionHolder<Holder<Biome>>() {
|
object BiomeMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Biome>>() {
|
||||||
override fun Holder<Biome>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun Holder<Biome>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
return mutableMapOf()
|
val biome = this
|
||||||
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -12,8 +12,11 @@ import com.bedrockk.molang.runtime.MoParams
|
|||||||
import net.minecraft.core.Holder
|
import net.minecraft.core.Holder
|
||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
|
|
||||||
object BlockMoLangFunctions: AbstractMoLangFunctionHolder<Holder<Block>>() {
|
object BlockMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Block>>() {
|
||||||
override fun Holder<Block>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun Holder<Block>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
return mutableMapOf()
|
val block = this
|
||||||
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -14,6 +14,9 @@ import net.minecraft.world.level.dimension.DimensionType
|
|||||||
|
|
||||||
object DimensionTypeMoLangFunctions : AbstractMoLangFunctionHolder<Holder<DimensionType>>() {
|
object DimensionTypeMoLangFunctions : AbstractMoLangFunctionHolder<Holder<DimensionType>>() {
|
||||||
override fun Holder<DimensionType>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun Holder<DimensionType>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
return mutableMapOf()
|
val dimension = this
|
||||||
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-6
@@ -18,15 +18,16 @@ import com.cobblemon.mod.common.util.getOrNull
|
|||||||
object DropEntryMoLangFunctions : AbstractMoLangFunctionHolder<DropEntry>() {
|
object DropEntryMoLangFunctions : AbstractMoLangFunctionHolder<DropEntry>() {
|
||||||
override fun DropEntry.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun DropEntry.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val drop = this
|
val drop = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
|
|
||||||
map["percentage"] = { DoubleValue(drop.percentage.toDouble()) }
|
functions["percentage"] = { DoubleValue(drop.percentage.toDouble()) }
|
||||||
map["quantity"] = { DoubleValue(drop.quantity.toDouble()) }
|
functions["quantity"] = { DoubleValue(drop.quantity.toDouble()) }
|
||||||
map["max_selectable_times"] = { DoubleValue(drop.maxSelectableTimes.toDouble()) }
|
functions["max_selectable_times"] = { DoubleValue(drop.maxSelectableTimes.toDouble()) }
|
||||||
map["can_drop"] = { params ->
|
functions["can_drop"] = { params ->
|
||||||
val pokemon = params.getOrNull<ObjectValue<Pokemon>>(0)?.obj
|
val pokemon = params.getOrNull<ObjectValue<Pokemon>>(0)?.obj
|
||||||
DoubleValue(if (drop.canDrop(pokemon)) 1.0 else 0.0)
|
DoubleValue(if (drop.canDrop(pokemon)) 1.0 else 0.0)
|
||||||
}
|
}
|
||||||
return map
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+265
-223
@@ -56,258 +56,300 @@ import kotlin.math.sqrt
|
|||||||
|
|
||||||
object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
||||||
override fun Entity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun Entity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val thisEntity = this
|
val entity = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>(
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
"uuid" to { StringValue(thisEntity.uuid.toString()) },
|
|
||||||
"name" to { _ -> StringValue(thisEntity.effectiveName().string) },
|
functions["uuid"] = { StringValue(entity.uuid.toString()) }
|
||||||
"yaw" to { _ -> DoubleValue(thisEntity.yRot.toDouble()) },
|
functions["name"] = { StringValue(entity.effectiveName().string) }
|
||||||
"pitch" to { _ -> DoubleValue(thisEntity.xRot.toDouble()) },
|
functions["yaw"] = { DoubleValue(entity.yRot.toDouble()) }
|
||||||
"x" to { _ -> DoubleValue(thisEntity.x) },
|
functions["pitch"] = { DoubleValue(entity.xRot.toDouble()) }
|
||||||
"y" to { _ -> DoubleValue(thisEntity.y) },
|
functions["x"] = { DoubleValue(entity.x) }
|
||||||
"z" to { _ -> DoubleValue(thisEntity.z) },
|
functions["y"] = { DoubleValue(entity.y) }
|
||||||
"velocity_x" to { _ -> DoubleValue(thisEntity.deltaMovement.x) },
|
functions["z"] = { DoubleValue(entity.z) }
|
||||||
"velocity_y" to { _ -> DoubleValue(thisEntity.deltaMovement.y) },
|
functions["velocity_x"] = { DoubleValue(entity.deltaMovement.x) }
|
||||||
"velocity_z" to { _ -> DoubleValue(thisEntity.deltaMovement.z) },
|
functions["velocity_y"] = { DoubleValue(entity.deltaMovement.y) }
|
||||||
"width" to { DoubleValue(thisEntity.boundingBox.xsize) },
|
functions["velocity_z"] = { DoubleValue(entity.deltaMovement.z) }
|
||||||
"height" to { DoubleValue(thisEntity.boundingBox.ysize) },
|
functions["width"] = { DoubleValue(entity.boundingBox.xsize) }
|
||||||
"this_size" to { DoubleValue(thisEntity.boundingBox.run { if (xsize > ysize) xsize else ysize }) },
|
functions["height"] = { DoubleValue(entity.boundingBox.ysize) }
|
||||||
"this_width" to { DoubleValue(thisEntity.boundingBox.xsize) },
|
functions["this_size"] = { DoubleValue(entity.boundingBox.run { if (xsize > ysize) xsize else ysize }) }
|
||||||
"this_height" to { DoubleValue(thisEntity.boundingBox.ysize) },
|
functions["this_width"] = { DoubleValue(entity.boundingBox.xsize) }
|
||||||
"id_modulo" to { params -> DoubleValue(thisEntity.uuid.hashCode() % params.getDouble(0)) },
|
functions["this_height"] = { DoubleValue(entity.boundingBox.ysize) }
|
||||||
"horizontal_velocity" to { _ -> DoubleValue(thisEntity.deltaMovement.horizontalDistance()) },
|
functions["id_modulo"] = { params -> DoubleValue(entity.uuid.hashCode() % params.getDouble(0)) }
|
||||||
"vertical_velocity" to { DoubleValue(thisEntity.deltaMovement.y) },
|
functions["horizontal_velocity"] = { DoubleValue(entity.deltaMovement.horizontalDistance()) }
|
||||||
"is_on_ground" to { _ -> DoubleValue(thisEntity.onGround()) },
|
functions["vertical_velocity"] = { DoubleValue(entity.deltaMovement.y) }
|
||||||
"world" to { _ -> thisEntity.level().worldRegistry.wrapAsHolder(thisEntity.level()).asWorldMoLangValue() },
|
functions["is_on_ground"] = { DoubleValue(entity.onGround()) }
|
||||||
"biome" to { _ -> thisEntity.level().getBiome(thisEntity.blockPosition()).asBiomeMoLangValue() },
|
functions["world"] = {
|
||||||
"is_passenger" to { DoubleValue(thisEntity.isPassenger) },
|
entity
|
||||||
"discard" to { thisEntity.discard() },
|
.level()
|
||||||
"is_sneaking" to { _ -> DoubleValue(thisEntity.isShiftKeyDown) },
|
.worldRegistry
|
||||||
"is_sprinting" to { _ -> DoubleValue(thisEntity.isSprinting) },
|
.wrapAsHolder(entity.level())
|
||||||
"is_in_water" to { _ -> DoubleValue(thisEntity.isUnderWater) },
|
.asWorldMoLangValue()
|
||||||
"is_in_rain" to { _ -> DoubleValue(thisEntity.isInWaterOrRain && !thisEntity.isInWater) },
|
}
|
||||||
"is_touching_water_or_rain" to { _ -> DoubleValue(thisEntity.isInWaterRainOrBubble) },
|
functions["biome"] = { entity.level().getBiome(entity.blockPosition()).asBiomeMoLangValue() }
|
||||||
"is_touching_water" to { _ -> DoubleValue(thisEntity.isInWater) },
|
functions["is_passenger"] = { DoubleValue(entity.isPassenger) }
|
||||||
"is_underwater" to { DoubleValue(thisEntity.getIsSubmerged()) },
|
functions["discard"] = { entity.discard() }
|
||||||
"is_in_lava" to { _ -> DoubleValue(thisEntity.isInLava) },
|
functions["is_sneaking"] = { DoubleValue(entity.isShiftKeyDown) }
|
||||||
"is_on_fire" to { _ -> DoubleValue(thisEntity.isOnFire) },
|
functions["is_sprinting"] = { DoubleValue(entity.isSprinting) }
|
||||||
"is_invisible" to { _ -> DoubleValue(thisEntity.isInvisible) },
|
functions["is_in_water"] = { DoubleValue(entity.isUnderWater) }
|
||||||
"is_riding" to { _ -> DoubleValue(thisEntity.isPassenger) },
|
functions["is_in_rain"] = { DoubleValue(entity.isInWaterOrRain && !entity.isInWater) }
|
||||||
"set_name" to { params ->
|
functions["is_touching_water_or_rain"] = { DoubleValue(entity.isInWaterRainOrBubble) }
|
||||||
val name = params.getString(0)
|
functions["is_touching_water"] = { DoubleValue(entity.isInWater) }
|
||||||
thisEntity.customName = name.text()
|
functions["is_underwater"] = { DoubleValue(entity.getIsSubmerged()) }
|
||||||
DoubleValue.ONE
|
functions["is_in_lava"] = { DoubleValue(entity.isInLava) }
|
||||||
},
|
functions["is_on_fire"] = { DoubleValue(entity.isOnFire) }
|
||||||
"damage" to { params ->
|
functions["is_invisible"] = { DoubleValue(entity.isInvisible) }
|
||||||
val amount = params.getDouble(0)
|
functions["is_riding"] = { DoubleValue(entity.isPassenger) }
|
||||||
val source = DamageSource(
|
functions["set_name"] = { params ->
|
||||||
thisEntity.level().registryAccess().registryOrThrow(Registries.DAMAGE_TYPE)
|
val name = params.getString(0)
|
||||||
.getHolder(DamageTypes.GENERIC).get()
|
entity.customName = name.text()
|
||||||
|
DoubleValue.ONE
|
||||||
|
}
|
||||||
|
functions["damage"] = { params ->
|
||||||
|
val amount = params.getDouble(0)
|
||||||
|
val source =
|
||||||
|
DamageSource(
|
||||||
|
entity
|
||||||
|
.level()
|
||||||
|
.registryAccess()
|
||||||
|
.registryOrThrow(Registries.DAMAGE_TYPE)
|
||||||
|
.getHolder(DamageTypes.GENERIC)
|
||||||
|
.get(),
|
||||||
)
|
)
|
||||||
thisEntity.hurt(source, amount.toFloat())
|
entity.hurt(source, amount.toFloat())
|
||||||
},
|
}
|
||||||
"distance_to_owner" to distanceToOwner@{
|
functions["distance_to_owner"] = distanceToOwner@{
|
||||||
if (thisEntity !is TamableAnimal) {
|
if (entity !is TamableAnimal) {
|
||||||
return@distanceToOwner DoubleValue.ZERO
|
return@distanceToOwner DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
val owner = thisEntity.owner ?: return@distanceToOwner DoubleValue.ZERO
|
val owner = entity.owner ?: return@distanceToOwner DoubleValue.ZERO
|
||||||
DoubleValue(thisEntity.distanceTo(owner))
|
DoubleValue(entity.distanceTo(owner))
|
||||||
},
|
}
|
||||||
"owner" to owner@{
|
functions["owner"] = owner@{
|
||||||
if (thisEntity !is TamableAnimal) return@owner DoubleValue.ZERO
|
if (entity !is TamableAnimal) return@owner DoubleValue.ZERO
|
||||||
val owner = thisEntity.owner
|
val owner = entity.owner
|
||||||
owner?.asMostSpecificMoLangValue() ?: DoubleValue.ZERO
|
owner?.asMostSpecificMoLangValue() ?: DoubleValue.ZERO
|
||||||
},
|
}
|
||||||
"delta_movement" to {
|
functions["delta_movement"] = {
|
||||||
listOf(thisEntity.deltaMovement.x, thisEntity.deltaMovement.y, thisEntity.deltaMovement.z)
|
listOf(entity.deltaMovement.x, entity.deltaMovement.y, entity.deltaMovement.z)
|
||||||
.asArrayValue(::DoubleValue)
|
.asArrayValue(::DoubleValue)
|
||||||
},
|
}
|
||||||
"tags" to {
|
functions["tags"] = {
|
||||||
val tags = thisEntity.tags
|
val tags = entity.tags
|
||||||
val array = ArrayStruct(hashMapOf())
|
val array = ArrayStruct(hashMapOf())
|
||||||
tags.forEachIndexed { index, tag -> array.setDirectly("$index", StringValue(tag)) }
|
tags.forEachIndexed { index, tag -> array.setDirectly("$index", StringValue(tag)) }
|
||||||
array
|
array
|
||||||
},
|
}
|
||||||
"add_tag" to { params ->
|
functions["add_tag"] = { params ->
|
||||||
val tag = params.getString(0)
|
val tag = params.getString(0)
|
||||||
thisEntity.addTag(tag)
|
entity.addTag(tag)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
},
|
}
|
||||||
"remove_tag" to { params ->
|
functions["remove_tag"] = { params ->
|
||||||
val tag = params.getString(0)
|
val tag = params.getString(0)
|
||||||
thisEntity.removeTag(tag)
|
entity.removeTag(tag)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
},
|
}
|
||||||
"has_tag" to { params ->
|
functions["has_tag"] = { params ->
|
||||||
val tag = params.getString(0)
|
val tag = params.getString(0)
|
||||||
DoubleValue(thisEntity.tags.contains(tag))
|
DoubleValue(entity.tags.contains(tag))
|
||||||
},
|
}
|
||||||
"distance_to_pos" to { params ->
|
functions["distance_to_pos"] = { params ->
|
||||||
val x = params.getDouble(0)
|
val x = params.getDouble(0)
|
||||||
val y = params.getDouble(1)
|
val y = params.getDouble(1)
|
||||||
val z = params.getDouble(2)
|
val z = params.getDouble(2)
|
||||||
DoubleValue(sqrt(thisEntity.distanceToSqr(Vec3(x, y, z))))
|
DoubleValue(sqrt(entity.distanceToSqr(Vec3(x, y, z))))
|
||||||
},
|
}
|
||||||
"type" to { _ ->
|
functions["type"] = {
|
||||||
thisEntity.registryAccess().registry(Registries.ENTITY_TYPE).get().getKey(thisEntity.type)?.toString()?.let {
|
entity
|
||||||
|
.registryAccess()
|
||||||
|
.registry(Registries.ENTITY_TYPE)
|
||||||
|
.get()
|
||||||
|
.getKey(entity.type)
|
||||||
|
?.toString()
|
||||||
|
?.let {
|
||||||
StringValue(it)
|
StringValue(it)
|
||||||
} ?: DoubleValue.ZERO
|
} ?: DoubleValue.ZERO
|
||||||
},
|
}
|
||||||
"find_nearby_block" to findNearbyBlock@{ params ->
|
functions["find_nearby_block"] = findNearbyBlock@{ params ->
|
||||||
val input = params.getString(0)
|
val input = params.getString(0)
|
||||||
val isTag = input.contains("#")
|
val isTag = input.contains("#")
|
||||||
val type = input.replace("#", "").asIdentifierDefaultingNamespace(namespace = "minecraft")
|
val type = input.replace("#", "").asIdentifierDefaultingNamespace(namespace = "minecraft")
|
||||||
val range = params.getDoubleOrNull(1) ?: 10
|
val range = params.getDoubleOrNull(1) ?: 10
|
||||||
val blockPos = thisEntity.level().getBlockStatesWithPos(
|
val blockPos =
|
||||||
AABB.ofSize(
|
entity
|
||||||
thisEntity.position(),
|
.level()
|
||||||
range.toDouble(),
|
.getBlockStatesWithPos(
|
||||||
range.toDouble(),
|
AABB.ofSize(
|
||||||
range.toDouble()
|
entity.position(),
|
||||||
)
|
range.toDouble(),
|
||||||
)
|
range.toDouble(),
|
||||||
.filter { blockPosPair ->
|
range.toDouble(),
|
||||||
|
),
|
||||||
|
).filter { blockPosPair ->
|
||||||
blockPosPair.first.blockHolder.let {
|
blockPosPair.first.blockHolder.let {
|
||||||
if (isTag) it.`is`(
|
if (isTag) {
|
||||||
TagKey.create(
|
it.`is`(
|
||||||
Registries.BLOCK,
|
TagKey.create(
|
||||||
type
|
Registries.BLOCK,
|
||||||
|
type,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
) else it.`is`(type)
|
} else {
|
||||||
|
it.`is`(type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}.minByOrNull { it.second.distSqr(entity.blockPosition()) }
|
||||||
.minByOrNull { it.second.distSqr(thisEntity.blockPosition()) }
|
|
||||||
?.second
|
?.second
|
||||||
if (blockPos != null) {
|
if (blockPos != null) {
|
||||||
return@findNearbyBlock ArrayStruct(
|
return@findNearbyBlock ArrayStruct(
|
||||||
mapOf(
|
mapOf(
|
||||||
"0" to DoubleValue(blockPos.x),
|
"0" to DoubleValue(blockPos.x),
|
||||||
"1" to DoubleValue(blockPos.y),
|
"1" to DoubleValue(blockPos.y),
|
||||||
"2" to DoubleValue(blockPos.z)
|
"2" to DoubleValue(blockPos.z),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return@findNearbyBlock DoubleValue.ZERO
|
return@findNearbyBlock DoubleValue.ZERO
|
||||||
},
|
}
|
||||||
"get_nearby_entities" to { params ->
|
functions["get_nearby_entities"] = { params ->
|
||||||
val distance = params.getDouble(0)
|
val distance = params.getDouble(0)
|
||||||
val entities =
|
val entities =
|
||||||
thisEntity.level().getEntities(thisEntity, AABB.ofSize(thisEntity.position(), distance, distance, distance))
|
entity
|
||||||
|
.level()
|
||||||
|
.getEntities(entity, AABB.ofSize(entity.position(), distance, distance, distance))
|
||||||
|
|
||||||
entities
|
entities
|
||||||
.filterIsInstance<Entity>()
|
.filterIsInstance<Entity>()
|
||||||
.map { it.asMostSpecificMoLangValue() }
|
.map { it.asMostSpecificMoLangValue() }
|
||||||
.asArrayValue()
|
.asArrayValue()
|
||||||
},
|
}
|
||||||
"is_standing_on_blocks" to { params ->
|
functions["is_standing_on_blocks"] = { params ->
|
||||||
val depth = params.getDouble(0).toInt()
|
val depth = params.getDouble(0).toInt()
|
||||||
val blockStrings: MutableSet<String> = mutableSetOf()
|
val blockStrings: MutableSet<String> = mutableSetOf()
|
||||||
for (blockIndex in 1..<params.params.size) {
|
for (blockIndex in 1..<params.params.size) {
|
||||||
blockStrings.add(params.getString(blockIndex))
|
blockStrings.add(params.getString(blockIndex))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thisEntity.isStandingOn(blockStrings, depth)) DoubleValue.ONE else DoubleValue.ZERO
|
if (entity.isStandingOn(blockStrings, depth)) DoubleValue.ONE else DoubleValue.ZERO
|
||||||
},
|
}
|
||||||
|
|
||||||
// q.entity.spawn_bedrock_particles(effect, locator, [player])
|
// q.entity.spawn_bedrock_particles(effect, locator, [player])
|
||||||
// sends to everyone nearby or just to the player if they're set.
|
// sends to everyone nearby or just to the player if they're set.
|
||||||
// Locator is necessary even if unused on non-posables.
|
// Locator is necessary even if unused on non-posables.
|
||||||
"spawn_bedrock_particles" to { params ->
|
functions["spawn_bedrock_particles"] = { params ->
|
||||||
val particle = params.getString(0).asResource()
|
val particle = params.getString(0).asResource()
|
||||||
val locator = params.getString(1)
|
val locator = params.getString(1)
|
||||||
val player = params.getOrNull<MoValue>(2)?.let {
|
val player =
|
||||||
|
params.getOrNull<MoValue>(2)?.let {
|
||||||
when (it) {
|
when (it) {
|
||||||
is StringValue -> thisEntity.level().getPlayerByUUID(UUID.fromString(it.value))
|
is StringValue -> entity.level().getPlayerByUUID(UUID.fromString(it.value))
|
||||||
is ObjectValue<*> -> it.obj
|
is ObjectValue<*> -> it.obj
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
} as? ServerPlayer
|
} as? ServerPlayer
|
||||||
|
|
||||||
val packet = SpawnSnowstormEntityParticlePacket(particle, thisEntity.id, listOf(locator))
|
val packet = SpawnSnowstormEntityParticlePacket(particle, entity.id, listOf(locator))
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
packet.sendToPlayersAround(thisEntity.x, thisEntity.y, thisEntity.z, 64.0, thisEntity.level().dimension())
|
packet.sendToPlayersAround(
|
||||||
} else {
|
entity.x,
|
||||||
packet.sendToPlayer(player)
|
entity.y,
|
||||||
}
|
entity.z,
|
||||||
},
|
64.0,
|
||||||
"make_intangible" to { params ->
|
entity.level().dimension(),
|
||||||
val intangible = params.getBooleanOrNull(0) ?: true
|
)
|
||||||
thisEntity.noPhysics = intangible
|
} else {
|
||||||
DoubleValue.ONE
|
packet.sendToPlayer(player)
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
functions["make_intangible"] = { params ->
|
||||||
|
val intangible = params.getBooleanOrNull(0) ?: true
|
||||||
|
entity.noPhysics = intangible
|
||||||
|
DoubleValue.ONE
|
||||||
|
}
|
||||||
|
|
||||||
|
when (entity) {
|
||||||
if (thisEntity is PosableEntity) {
|
is PosableEntity -> {
|
||||||
map["play_animation"] = playAnimation@{ params ->
|
functions["play_animation"] = playAnimation@{ params ->
|
||||||
val animation = params.getString(0)
|
val animation = params.getString(0)
|
||||||
val packet = PlayPosableAnimationPacket(thisEntity.id, setOf(animation), emptyList())
|
val packet = PlayPosableAnimationPacket(entity.id, setOf(animation), emptyList())
|
||||||
val target = params.getStringOrNull(1)
|
val target = params.getStringOrNull(1)
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
val targetPlayer = if (target.asUUID != null) {
|
val targetPlayer =
|
||||||
thisEntity.level().getPlayerByUUID(target.asUUID!!) as ServerPlayer
|
if (target.asUUID != null) {
|
||||||
} else if (thisEntity.level() is ServerLevel) {
|
entity.level().getPlayerByUUID(target.asUUID!!) as ServerPlayer
|
||||||
thisEntity.level().server!!.playerList.getPlayerByName(target)
|
} else if (entity.level() is ServerLevel) {
|
||||||
|
entity
|
||||||
|
.level()
|
||||||
|
.server!!
|
||||||
|
.playerList
|
||||||
|
.getPlayerByName(target)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
if (targetPlayer != null) {
|
||||||
|
packet.sendToPlayer(targetPlayer)
|
||||||
|
return@playAnimation DoubleValue.ONE
|
||||||
|
} else {
|
||||||
|
return@playAnimation DoubleValue.ZERO
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
null
|
packet.sendToPlayersAround(
|
||||||
}
|
entity.x,
|
||||||
if (targetPlayer != null) {
|
entity.y,
|
||||||
packet.sendToPlayer(targetPlayer)
|
entity.z,
|
||||||
|
64.0,
|
||||||
|
entity.level().dimension(),
|
||||||
|
)
|
||||||
return@playAnimation DoubleValue.ONE
|
return@playAnimation DoubleValue.ONE
|
||||||
} else {
|
|
||||||
return@playAnimation DoubleValue.ZERO
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
packet.sendToPlayersAround(thisEntity.x, thisEntity.y, thisEntity.z, 64.0, thisEntity.level().dimension())
|
|
||||||
return@playAnimation DoubleValue.ONE
|
functions["face"] = { params ->
|
||||||
|
ObjectValue(ReferenceDialogueFaceProvider(entity.id, params.getBooleanOrNull(0) != false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map["face"] = { params ->
|
is Schedulable -> {
|
||||||
ObjectValue(ReferenceDialogueFaceProvider(thisEntity.id, params.getBooleanOrNull(0) != false))
|
functions["run_molang_after"] = { params ->
|
||||||
|
val expression = params.getString(0).asExpressionLike()
|
||||||
|
val delayInSeconds = params.getDouble(1).toFloat()
|
||||||
|
val runtime = MoLangRuntime()
|
||||||
|
runtime.environment.cloneFrom(params.environment)
|
||||||
|
entity.after(delayInSeconds) {
|
||||||
|
runtime.resolve(expression)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (thisEntity is Schedulable) {
|
is MoLangScriptingEntity -> {
|
||||||
map["run_molang_after"] = { params ->
|
functions["add_callback"] = { params ->
|
||||||
val expression = params.getString(0).asExpressionLike()
|
val type = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val delayInSeconds = params.getDouble(1).toFloat()
|
val callback = params.getString(1).asIdentifierDefaultingNamespace()
|
||||||
val runtime = MoLangRuntime()
|
val allowDuplicates = params.getBooleanOrNull(2) ?: false
|
||||||
runtime.environment.cloneFrom(params.environment)
|
entity.callbacks.addCallback(type, callback, allowDuplicates)
|
||||||
thisEntity.after(delayInSeconds) {
|
}
|
||||||
runtime.resolve(expression)
|
functions["remove_callback"] = { params ->
|
||||||
|
val type = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
|
val callback = params.getString(1).asIdentifierDefaultingNamespace()
|
||||||
|
entity.callbacks.removeCallback(type, callback)
|
||||||
|
}
|
||||||
|
functions["has_callback"] = { params ->
|
||||||
|
val type = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
|
val callback = params.getString(1).asIdentifierDefaultingNamespace()
|
||||||
|
DoubleValue(callback in (entity.callbacks[type] ?: emptySet()))
|
||||||
|
}
|
||||||
|
functions["clear_callbacks"] = { params ->
|
||||||
|
val type = params.getStringOrNull(0)?.asIdentifierDefaultingNamespace()
|
||||||
|
if (type != null) {
|
||||||
|
entity.callbacks[type]?.clear()
|
||||||
|
} else {
|
||||||
|
entity.callbacks.clear()
|
||||||
|
}
|
||||||
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thisEntity is MoLangScriptingEntity) {
|
return functions
|
||||||
map["add_callback"] = { params ->
|
|
||||||
val type = params.getString(0).asIdentifierDefaultingNamespace()
|
|
||||||
val callback = params.getString(1).asIdentifierDefaultingNamespace()
|
|
||||||
val allowDuplicates = params.getBooleanOrNull(2) ?: false
|
|
||||||
thisEntity.callbacks.addCallback(type, callback, allowDuplicates)
|
|
||||||
}
|
|
||||||
map["remove_callback"] = { params ->
|
|
||||||
val type = params.getString(0).asIdentifierDefaultingNamespace()
|
|
||||||
val callback = params.getString(1).asIdentifierDefaultingNamespace()
|
|
||||||
thisEntity.callbacks.removeCallback(type, callback)
|
|
||||||
}
|
|
||||||
map["has_callback"] = { params ->
|
|
||||||
val type = params.getString(0).asIdentifierDefaultingNamespace()
|
|
||||||
val callback = params.getString(1).asIdentifierDefaultingNamespace()
|
|
||||||
DoubleValue(callback in (thisEntity.callbacks[type] ?: emptySet()))
|
|
||||||
}
|
|
||||||
map["clear_callbacks"] = { params ->
|
|
||||||
val type = params.getStringOrNull(0)?.asIdentifierDefaultingNamespace()
|
|
||||||
if (type != null) {
|
|
||||||
thisEntity.callbacks[type]?.clear()
|
|
||||||
} else {
|
|
||||||
thisEntity.callbacks.clear()
|
|
||||||
}
|
|
||||||
DoubleValue.ONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return map
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-20
@@ -11,34 +11,37 @@ package com.cobblemon.mod.common.api.molang.function
|
|||||||
import com.bedrockk.molang.runtime.MoParams
|
import com.bedrockk.molang.runtime.MoParams
|
||||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||||
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
|
import com.cobblemon.mod.common.api.pokemon.transformation.Transformation
|
||||||
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
|
import com.cobblemon.mod.common.pokemon.transformation.evolution.Evolution
|
||||||
import com.cobblemon.mod.common.pokemon.evolution.variants.LevelUpEvolution
|
import com.cobblemon.mod.common.pokemon.transformation.triggers.ItemInteractionTrigger
|
||||||
import com.cobblemon.mod.common.pokemon.evolution.variants.TradeEvolution
|
import com.cobblemon.mod.common.pokemon.transformation.triggers.LevelUpTrigger
|
||||||
|
import com.cobblemon.mod.common.pokemon.transformation.triggers.TradeTrigger
|
||||||
|
|
||||||
object EvolutionMoLangFunctions : AbstractMoLangFunctionHolder<Evolution>() {
|
object EvolutionMoLangFunctions : AbstractMoLangFunctionHolder<Transformation>() {
|
||||||
override fun Evolution.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun Transformation.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val evolution = this
|
val evolution = this
|
||||||
val map = hashMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
|
|
||||||
map["result"] = { evolution.result.asMoLangValue() }
|
functions["reevaluate"] = { DoubleValue(evolution.reevaluate) }
|
||||||
map["is_optional"] = { DoubleValue(evolution.optional) }
|
functions["is_optional"] = { DoubleValue(evolution.optional) }
|
||||||
map["consumes_held_item"] = { DoubleValue(evolution.consumeHeldItem) }
|
|
||||||
|
|
||||||
when (evolution) {
|
if (evolution is Evolution) {
|
||||||
is LevelUpEvolution -> {
|
functions["result"] = { evolution.result.asMoLangValue() }
|
||||||
map["is_level_up"] = { DoubleValue.ONE }
|
when (evolution.trigger) {
|
||||||
}
|
is LevelUpTrigger -> {
|
||||||
|
functions["is_level_up"] = { DoubleValue.ONE }
|
||||||
|
}
|
||||||
|
|
||||||
is TradeEvolution -> {
|
is TradeTrigger -> {
|
||||||
map["is_trade"] = { DoubleValue.ONE }
|
functions["is_trade"] = { DoubleValue.ONE }
|
||||||
}
|
}
|
||||||
|
|
||||||
is ItemInteractionEvolution -> {
|
is ItemInteractionTrigger -> {
|
||||||
map["is_item"] = { DoubleValue.ONE }
|
functions["is_item"] = { DoubleValue.ONE }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return map
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+104
-103
@@ -42,101 +42,99 @@ import net.minecraft.world.item.ItemStack
|
|||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
|
|
||||||
object GeneralMoLangFunctions {
|
object GeneralMoLangFunctions {
|
||||||
val holder: HashMap<String, (MoParams) -> Any> = hashMapOf(
|
val functions: MutableMap<String, (MoParams) -> Any> = mutableMapOf()
|
||||||
"print" to { params ->
|
|
||||||
|
init {
|
||||||
|
functions["print"] = { params ->
|
||||||
val message = params.get<MoValue>(0).asString()
|
val message = params.get<MoValue>(0).asString()
|
||||||
LOGGER.info(message)
|
LOGGER.info(message)
|
||||||
},
|
}
|
||||||
"delete_variable" to deleteVar@{ params ->
|
functions["delete_variable"] = { params ->
|
||||||
val struct = params.get<VariableStruct>(0)
|
val struct = params.get<VariableStruct>(0)
|
||||||
val variable = params.getString(1)
|
val variable = params.getString(1)
|
||||||
struct.map.remove(variable)
|
struct.map.remove(variable)
|
||||||
return@deleteVar DoubleValue.ONE
|
|
||||||
},
|
|
||||||
"delete_variables" to { params ->
|
|
||||||
val struct = params.get<VariableStruct>(0)
|
|
||||||
struct.map.clear()
|
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
},
|
}
|
||||||
"get_variable" to { params ->
|
functions["get_variable"] = { params ->
|
||||||
val struct = params.get<VariableStruct>(0)
|
val struct = params.get<VariableStruct>(0)
|
||||||
val variable = params.getString(1)
|
val variable = params.getString(1)
|
||||||
struct.map[variable] ?: DoubleValue.ZERO
|
struct.map[variable] ?: DoubleValue.ZERO
|
||||||
},
|
}
|
||||||
"set_variable" to { params ->
|
functions["set_variable"] = { params ->
|
||||||
val struct = params.get<VariableStruct>(0)
|
val struct = params.get<VariableStruct>(0)
|
||||||
val variable = params.getString(1)
|
val variable = params.getString(1)
|
||||||
val value = params.get<MoValue>(2)
|
val value = params.get<MoValue>(2)
|
||||||
struct.map[variable] = value
|
struct.map[variable] = value
|
||||||
value
|
value
|
||||||
},
|
}
|
||||||
"set_query" to { params ->
|
functions["set_query"] = { params ->
|
||||||
val variable = params.getString(0)
|
val variable = params.getString(0)
|
||||||
val value = params.get<MoValue>(1)
|
val value = params.get<MoValue>(1)
|
||||||
params.environment.query.addFunction(variable) { value }
|
params.environment.query.addFunction(variable) { value }
|
||||||
value
|
value
|
||||||
},
|
}
|
||||||
"replace" to { params ->
|
functions["replace"] = { params ->
|
||||||
val text = params.getString(0)
|
val text = params.getString(0)
|
||||||
val search = params.getString(1)
|
val search = params.getString(1)
|
||||||
val replace = params.getString(2)
|
val replace = params.getString(2)
|
||||||
StringValue(text.replace(search, replace))
|
StringValue(text.replace(search, replace))
|
||||||
},
|
}
|
||||||
"is_included" to { params ->
|
functions["is_included"] = { params ->
|
||||||
val text = params.getString(0)
|
val text = params.getString(0)
|
||||||
val search = params.getString(1)
|
val search = params.getString(1)
|
||||||
DoubleValue(text.contains(search))
|
DoubleValue(text.contains(search))
|
||||||
},
|
}
|
||||||
"to_lower" to { params ->
|
functions["to_lower"] = { params ->
|
||||||
StringValue(params.getString(0).lowercase())
|
StringValue(params.getString(0).lowercase())
|
||||||
},
|
}
|
||||||
"to_upper" to { params ->
|
functions["to_upper"] = { params ->
|
||||||
StringValue(params.getString(0).uppercase())
|
StringValue(params.getString(0).uppercase())
|
||||||
},
|
}
|
||||||
"string_length" to { params ->
|
functions["string_length"] = { params ->
|
||||||
DoubleValue(params.getString(0).length)
|
DoubleValue(params.getString(0).length)
|
||||||
},
|
}
|
||||||
"split_string" to { params ->
|
functions["split_string"] = { params ->
|
||||||
val text = params.getString(0)
|
val text = params.getString(0)
|
||||||
val delimiter = params.getString(1)
|
val delimiter = params.getString(1)
|
||||||
val parts = text.split(delimiter).map { StringValue(it) }
|
val parts = text.split(delimiter).map { StringValue(it) }
|
||||||
val struct = ArrayStruct(hashMapOf())
|
val struct = ArrayStruct(hashMapOf())
|
||||||
parts.forEachIndexed { index, moValue -> struct.setDirectly("$index", moValue) }
|
parts.forEachIndexed { index, moValue -> struct.setDirectly("$index", moValue) }
|
||||||
struct
|
struct
|
||||||
},
|
}
|
||||||
"is_blank" to { params ->
|
functions["is_blank"] = { params ->
|
||||||
val arg = params.get<MoValue>(0)
|
val arg = params.get<MoValue>(0)
|
||||||
DoubleValue((arg is StringValue && (arg.value.isBlank() || arg.value.toDoubleOrNull() == 0.0)) || (arg is DoubleValue && arg.value == 0.0))
|
DoubleValue(
|
||||||
},
|
(arg is StringValue && (arg.value.isBlank() || arg.value.toDoubleOrNull() == 0.0)) ||
|
||||||
"run_command" to { params ->
|
(arg is DoubleValue && arg.value == 0.0),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
functions["run_command"] = { params ->
|
||||||
val command = params.getString(0)
|
val command = params.getString(0)
|
||||||
try {
|
try {
|
||||||
server()!!.commands.performPrefixedCommand(server()!!.createCommandSourceStack(), command)
|
server()!!.commands.performPrefixedCommand(server()!!.createCommandSourceStack(), command)
|
||||||
} catch (_: NullPointerException) {
|
} catch (_: NullPointerException) {
|
||||||
DoubleValue.ZERO
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"is_int" to { params -> DoubleValue(params.get<MoValue>(0).asString().isInt()) },
|
functions["is_int"] = { params -> DoubleValue(params.get<MoValue>(0).asString().isInt()) }
|
||||||
"is_number" to { params ->
|
functions["is_number"] = { params ->
|
||||||
DoubleValue(
|
DoubleValue(
|
||||||
params.get<MoValue>(0).asString().toDoubleOrNull() != null
|
params.get<MoValue>(0).asString().toDoubleOrNull() != null,
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
"to_number" to { params ->
|
functions["to_number"] = { params ->
|
||||||
DoubleValue(
|
DoubleValue(
|
||||||
params.get<MoValue>(0).asString().toDoubleOrNull() ?: 0.0
|
params.get<MoValue>(0).asString().toDoubleOrNull() ?: 0.0,
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
"to_int" to { params ->
|
functions["to_int"] = { params ->
|
||||||
DoubleValue(
|
DoubleValue(
|
||||||
params.get<MoValue>(0).asString().toIntOrNull() ?: 0
|
params.get<MoValue>(0).asString().toIntOrNull() ?: 0,
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
"to_string" to { params -> StringValue(params.get<MoValue>(0).asString()) },
|
functions["to_string"] = { params -> StringValue(params.get<MoValue>(0).asString()) }
|
||||||
"do_effect_walks" to { _ ->
|
functions["do_effect_walks"] = { DoubleValue(Cobblemon.config.walkingInBattleAnimations) }
|
||||||
DoubleValue(Cobblemon.config.walkingInBattleAnimations)
|
functions["random"] = { params ->
|
||||||
},
|
|
||||||
"random" to { params ->
|
|
||||||
val options = mutableListOf<MoValue>()
|
val options = mutableListOf<MoValue>()
|
||||||
var index = 0
|
var index = 0
|
||||||
while (params.contains(index)) {
|
while (params.contains(index)) {
|
||||||
@@ -144,35 +142,35 @@ object GeneralMoLangFunctions {
|
|||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
options.random() // Can throw an exception if they specified no args. They'd be idiots though.
|
options.random() // Can throw an exception if they specified no args. They'd be idiots though.
|
||||||
},
|
}
|
||||||
"curve" to { params ->
|
functions["curve"] = { params ->
|
||||||
val curveName = params.getString(0)
|
val curveName = params.getString(0)
|
||||||
val curve =
|
val curve =
|
||||||
WaveFunctions.functions[curveName] ?: throw IllegalArgumentException("Unknown curve: $curveName")
|
WaveFunctions.functions[curveName] ?: throw IllegalArgumentException("Unknown curve: $curveName")
|
||||||
ObjectValue(curve)
|
ObjectValue(curve)
|
||||||
},
|
}
|
||||||
"array" to { params ->
|
functions["array"] = { params ->
|
||||||
val values = params.params
|
val values = params.params
|
||||||
val array = ArrayStruct(hashMapOf())
|
val array = ArrayStruct(hashMapOf())
|
||||||
values.forEachIndexed { index, moValue -> array.setDirectly("$index", moValue) }
|
values.forEachIndexed { index, moValue -> array.setDirectly("$index", moValue) }
|
||||||
array
|
array
|
||||||
},
|
}
|
||||||
"length" to { params ->
|
functions["length"] = { params ->
|
||||||
val array = (params.getOrNull<MoValue>(0) as? VariableStruct)
|
val array = (params.getOrNull<MoValue>(0) as? VariableStruct)
|
||||||
if (array == null) {
|
if (array == null) {
|
||||||
DoubleValue.ZERO
|
DoubleValue.ZERO
|
||||||
} else {
|
} else {
|
||||||
DoubleValue(array.map.size.toDouble())
|
DoubleValue(array.map.size.toDouble())
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"append" to { params ->
|
functions["append"] = { params ->
|
||||||
val array = params.get<ArrayStruct>(0)
|
val array = params.get<ArrayStruct>(0)
|
||||||
val value = params.get<MoValue>(1)
|
val value = params.get<MoValue>(1)
|
||||||
val nextIndex = array.map.size
|
val nextIndex = array.map.size
|
||||||
array.setDirectly("$nextIndex", value)
|
array.setDirectly("$nextIndex", value)
|
||||||
array
|
array
|
||||||
},
|
}
|
||||||
"insert" to { params ->
|
functions["insert"] = { params ->
|
||||||
val array = params.get<ArrayStruct>(0)
|
val array = params.get<ArrayStruct>(0)
|
||||||
val index = params.getInt(1)
|
val index = params.getInt(1)
|
||||||
val value = params.get<MoValue>(2)
|
val value = params.get<MoValue>(2)
|
||||||
@@ -187,36 +185,40 @@ object GeneralMoLangFunctions {
|
|||||||
}
|
}
|
||||||
array.map[index.toString()] = value
|
array.map[index.toString()] = value
|
||||||
array
|
array
|
||||||
},
|
}
|
||||||
"delete" to { params ->
|
functions["delete"] = { params ->
|
||||||
val array = params.get<ArrayStruct>(0)
|
val array = params.get<ArrayStruct>(0)
|
||||||
val index = params.getInt(1)
|
val index = params.getInt(1)
|
||||||
if (index in 0 until array.map.size) {
|
if (index in 0 until array.map.size) {
|
||||||
array.map.remove(index.toString())
|
array.map.remove(index.toString())
|
||||||
// Re-index the array to keep keys sequential in numerical order
|
// Re-index the array to keep keys sequential in numerical order
|
||||||
val newMap = hashMapOf<String, MoValue>()
|
val newMap = hashMapOf<String, MoValue>()
|
||||||
array.map.keys.mapNotNull { it.toIntOrNull() }
|
array.map.keys
|
||||||
|
.mapNotNull { it.toIntOrNull() }
|
||||||
.sorted()
|
.sorted()
|
||||||
.forEachIndexed { i, k -> newMap[i.toString()] = array.map[k.toString()]!! }
|
.forEachIndexed { i, k -> newMap[i.toString()] = array.map[k.toString()]!! }
|
||||||
array.map.clear()
|
array.map.clear()
|
||||||
array.map.putAll(newMap)
|
array.map.putAll(newMap)
|
||||||
}
|
}
|
||||||
array
|
array
|
||||||
},
|
}
|
||||||
"run_script" to { params ->
|
functions["run_script"] = { params ->
|
||||||
val runtime = MoLangRuntime()
|
val runtime = MoLangRuntime()
|
||||||
runtime.environment.query = params.environment.query
|
runtime.environment.query = params.environment.query
|
||||||
runtime.environment.variable = params.environment.variable
|
runtime.environment.variable = params.environment.variable
|
||||||
val args = params.params.subList(1, params.params.size)
|
val args = params.params.subList(1, params.params.size)
|
||||||
runtime.environment.context = ContextStruct(
|
runtime.environment.context =
|
||||||
(params.environment.context?.map
|
ContextStruct(
|
||||||
?: emptyMap()) + args.mapIndexed { index, value -> "arg_${index + 1}" to value }.toMap()
|
(
|
||||||
)
|
params.environment.context?.map
|
||||||
|
?: emptyMap()
|
||||||
|
) + args.mapIndexed { index, value -> "arg_${index + 1}" to value }.toMap(),
|
||||||
|
)
|
||||||
val script = params.getString(0).asIdentifierDefaultingNamespace()
|
val script = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
// store the args in the
|
// store the args in the
|
||||||
CobblemonScripts.run(script, runtime) ?: DoubleValue.ZERO
|
CobblemonScripts.run(script, runtime) ?: DoubleValue.ZERO
|
||||||
},
|
}
|
||||||
"run_molang" to { params ->
|
functions["run_molang"] = { params ->
|
||||||
val runtime = MoLangRuntime()
|
val runtime = MoLangRuntime()
|
||||||
runtime.environment.query = params.environment.query
|
runtime.environment.query = params.environment.query
|
||||||
runtime.environment.variable = params.environment.variable
|
runtime.environment.variable = params.environment.variable
|
||||||
@@ -224,17 +226,16 @@ object GeneralMoLangFunctions {
|
|||||||
val expression = params.getString(0).asExpressionLike()
|
val expression = params.getString(0).asExpressionLike()
|
||||||
val delayInSeconds = params.getDoubleOrNull(1)?.toFloat() ?: 0.0f
|
val delayInSeconds = params.getDoubleOrNull(1)?.toFloat() ?: 0.0f
|
||||||
|
|
||||||
fun evaluate(): MoValue {
|
fun evaluate(): MoValue =
|
||||||
return try {
|
try {
|
||||||
runtime.resolve(expression)
|
runtime.resolve(expression)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
LOGGER.warn(
|
LOGGER.warn(
|
||||||
"Failed to evaluate MoLang expression${if (delayInSeconds > 0.0f) " (delayed)" else ""}: $expression",
|
"Failed to evaluate MoLang expression${if (delayInSeconds > 0.0f) " (delayed)" else ""}: $expression",
|
||||||
ex
|
ex,
|
||||||
)
|
)
|
||||||
DoubleValue.ZERO
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (delayInSeconds > 0.0f) {
|
if (delayInSeconds > 0.0f) {
|
||||||
val tracker =
|
val tracker =
|
||||||
@@ -246,55 +247,55 @@ object GeneralMoLangFunctions {
|
|||||||
} else {
|
} else {
|
||||||
evaluate()
|
evaluate()
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"system_time_millis" to { _ ->
|
functions["system_time_millis"] = { DoubleValue(System.currentTimeMillis()) }
|
||||||
DoubleValue(System.currentTimeMillis())
|
|
||||||
},
|
|
||||||
// the rest of the world use dd/MM/yyyy grow up america (this comment was generated by copilot)
|
// the rest of the world use dd/MM/yyyy grow up america (this comment was generated by copilot)
|
||||||
"date_local_time" to { _ ->
|
functions["date_local_time"] = {
|
||||||
val time = System.currentTimeMillis()
|
val time = System.currentTimeMillis()
|
||||||
val date = java.util.Date(time)
|
val date = java.util.Date(time)
|
||||||
val formatted = java.text.SimpleDateFormat("dd/MM/yyyy").format(date)
|
val formatted = java.text.SimpleDateFormat("dd/MM/yyyy").format(date)
|
||||||
StringValue(formatted)
|
StringValue(formatted)
|
||||||
},
|
}
|
||||||
"date_of" to { params ->
|
functions["date_of"] = { params ->
|
||||||
val time = params.getDouble(0).toLong()
|
val time = params.getDouble(0).toLong()
|
||||||
val date = java.util.Date(time)
|
val date = java.util.Date(time)
|
||||||
val formatted = java.text.SimpleDateFormat("dd/MM/yyyy").format(date)
|
val formatted = java.text.SimpleDateFormat("dd/MM/yyyy").format(date)
|
||||||
StringValue(formatted)
|
StringValue(formatted)
|
||||||
},
|
}
|
||||||
"date_is_after" to { params ->
|
functions["date_is_after"] = { params ->
|
||||||
val dateA = params.getString(0)
|
val dateA = params.getString(0)
|
||||||
val dateB = params.getString(1)
|
val dateB = params.getString(1)
|
||||||
val format = java.text.SimpleDateFormat("dd/MM/yyyy")
|
val format = java.text.SimpleDateFormat("dd/MM/yyyy")
|
||||||
val a = try {
|
val a =
|
||||||
format.parse(dateA)
|
try {
|
||||||
} catch (_: ParseException) {
|
format.parse(dateA)
|
||||||
throw RuntimeException("Cannot parse date ${dateA}, expected it to be in dd/MM/yyyy format, other provided")
|
} catch (_: ParseException) {
|
||||||
}
|
throw RuntimeException("Cannot parse date $dateA, expected it to be in dd/MM/yyyy format, other provided")
|
||||||
val b = try {
|
}
|
||||||
format.parse(dateB)
|
val b =
|
||||||
} catch (_: ParseException) {
|
try {
|
||||||
throw RuntimeException("Cannot parse date ${dateB}, expected it to be in dd/MM/yyyy format, other provided")
|
format.parse(dateB)
|
||||||
}
|
} catch (_: ParseException) {
|
||||||
|
throw RuntimeException("Cannot parse date $dateB, expected it to be in dd/MM/yyyy format, other provided")
|
||||||
|
}
|
||||||
DoubleValue(a.after(b))
|
DoubleValue(a.after(b))
|
||||||
},
|
}
|
||||||
"get_move_from_id" to { params ->
|
functions["get_move_from_id"] = { params ->
|
||||||
val moveId = params.getString(0)
|
val moveId = params.getString(0)
|
||||||
val moveTemplate = Moves.getByName(moveId)
|
val moveTemplate = Moves.getByName(moveId)
|
||||||
moveTemplate?.struct ?: DoubleValue.ZERO
|
moveTemplate?.struct ?: DoubleValue.ZERO
|
||||||
},
|
}
|
||||||
"create_simple_party_provider" to { _ ->
|
functions["create_simple_party_provider"] = {
|
||||||
val partyProvider = SimplePartyProvider()
|
val partyProvider = SimplePartyProvider()
|
||||||
partyProvider.struct
|
partyProvider.struct
|
||||||
},
|
}
|
||||||
"create_pickup_item" to { params ->
|
functions["create_pickup_item"] = { params ->
|
||||||
val item = params.getOrNull<MoValue>(0)?.asString()?.let(ObtainableItemCondition::parseFromString)
|
val item = params.getOrNull<MoValue>(0)?.asString()?.let(ObtainableItemCondition::parseFromString)
|
||||||
val pickupPriority = params.getIntOrNull(1) ?: 0
|
val pickupPriority = params.getIntOrNull(1) ?: 0
|
||||||
val pickupItem = ObtainableItem(item = item, pickupPriority = pickupPriority)
|
val pickupItem = ObtainableItem(item = item, pickupPriority = pickupPriority)
|
||||||
pickupItem.struct
|
pickupItem.struct
|
||||||
},
|
}
|
||||||
"create_itemstack" to { params ->
|
functions["create_itemstack"] = { params ->
|
||||||
val itemId = params.getString(0).asIdentifierDefaultingNamespace()
|
val itemId = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
try {
|
try {
|
||||||
val item = BuiltInRegistries.ITEM.get(itemId)
|
val item = BuiltInRegistries.ITEM.get(itemId)
|
||||||
@@ -305,7 +306,7 @@ object GeneralMoLangFunctions {
|
|||||||
LOGGER.error("Cannot create item stack from identifier: $itemId, item with that ID does not exist. Possible typo?")
|
LOGGER.error("Cannot create item stack from identifier: $itemId, item with that ID does not exist. Possible typo?")
|
||||||
DoubleValue.ZERO
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"file" to { MoLangLoadedFilesCache.struct }
|
functions["file"] = { MoLangLoadedFilesCache.struct }
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-21
@@ -26,43 +26,44 @@ object ItemStackMoLangFunctions : AbstractMoLangFunctionHolder<Pair<ItemStack, R
|
|||||||
val registryAccess = this.second
|
val registryAccess = this.second
|
||||||
val itemRegistry = registryAccess.registryOrThrow(Registries.ITEM)
|
val itemRegistry = registryAccess.registryOrThrow(Registries.ITEM)
|
||||||
val holder = itemRegistry.wrapAsHolder(stack.item)
|
val holder = itemRegistry.wrapAsHolder(stack.item)
|
||||||
|
val functions = mutableMapOf<String, (MoParams) -> Any>()
|
||||||
|
|
||||||
val map = hashMapOf<String, (MoParams) -> Any>()
|
functions["item"] = { holder.asMoLangValue(Registries.ITEM) }
|
||||||
map["item"] = { _ -> holder.asMoLangValue(Registries.ITEM) }
|
functions["count"] = { DoubleValue(stack.count.toDouble()) }
|
||||||
map["count"] = { _ -> DoubleValue(stack.count.toDouble()) }
|
functions["damage_value"] = { DoubleValue(stack.damageValue) }
|
||||||
map["damage_value"] = { _ -> DoubleValue(stack.damageValue) }
|
functions["max_damage"] = { DoubleValue(stack.maxDamage) }
|
||||||
map["max_damage"] = { _ -> DoubleValue(stack.maxDamage) }
|
functions["is_empty"] = { DoubleValue(stack.isEmpty) }
|
||||||
map["is_empty"] = { _ -> DoubleValue(stack.isEmpty) }
|
functions["shrink"] = { params -> stack.shrink(params.getInt(0)) }
|
||||||
map["shrink"] = { params -> stack.shrink(params.getInt(0)) }
|
functions["grow"] = { params -> stack.grow(params.getInt(0)) }
|
||||||
map["grow"] = { params -> stack.grow(params.getInt(0)) }
|
functions["is_of"] = { params ->
|
||||||
map["is_of"] = { params ->
|
|
||||||
DoubleValue(
|
DoubleValue(
|
||||||
holder.`is`(
|
holder.`is`(
|
||||||
params.getString(0).asIdentifierDefaultingNamespace()
|
params.getString(0).asIdentifierDefaultingNamespace(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
map["is_in"] = { params ->
|
functions["is_in"] = { params ->
|
||||||
DoubleValue(
|
DoubleValue(
|
||||||
holder.`is`(
|
holder.`is`(
|
||||||
TagKey.create(
|
TagKey.create(
|
||||||
Registries.ITEM,
|
Registries.ITEM,
|
||||||
params.getString(0).replace("#", "").asIdentifierDefaultingNamespace()
|
params.getString(0).replace("#", "").asIdentifierDefaultingNamespace(),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
map["is_food"] = { _ -> DoubleValue(stack.has(DataComponents.FOOD)) }
|
functions["is_food"] = { DoubleValue(stack.has(DataComponents.FOOD)) }
|
||||||
map["is_enchanted"] = { _ -> DoubleValue(stack.hasFoil()) }
|
functions["is_enchanted"] = { DoubleValue(stack.hasFoil()) }
|
||||||
map["has_enchantment"] = put@{ params ->
|
functions["has_enchantment"] = hasEnchantment@{ params ->
|
||||||
val enchantmentId = params.getString(0).asIdentifierDefaultingNamespace()
|
val enchantmentId = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val minLevel = params.getIntOrNull(1) ?: 1
|
val minLevel = params.getIntOrNull(1) ?: 1
|
||||||
val enchantmentRegistry = registryAccess.registryOrThrow(Registries.ENCHANTMENT)
|
val enchantmentRegistry = registryAccess.registryOrThrow(Registries.ENCHANTMENT)
|
||||||
val holder =
|
val holder =
|
||||||
enchantmentRegistry.getHolder(enchantmentId).orElse(null) ?: return@put DoubleValue.ZERO
|
enchantmentRegistry.getHolder(enchantmentId).orElse(null) ?: return@hasEnchantment DoubleValue.ZERO
|
||||||
val level = EnchantmentHelper.getItemEnchantmentLevel(holder, stack)
|
val level = EnchantmentHelper.getItemEnchantmentLevel(holder, stack)
|
||||||
return@put DoubleValue(level >= minLevel)
|
DoubleValue(level >= minLevel)
|
||||||
}
|
}
|
||||||
return map
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+154
-137
@@ -53,26 +53,27 @@ import java.util.*
|
|||||||
object LivingEntityMoLangFunctions : AbstractMoLangFunctionHolder<LivingEntity>() {
|
object LivingEntityMoLangFunctions : AbstractMoLangFunctionHolder<LivingEntity>() {
|
||||||
override fun LivingEntity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun LivingEntity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val entity = this
|
val entity = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
map["is_player"] = { _ -> DoubleValue(entity is Player) }
|
|
||||||
map["is_npc"] = { _ -> DoubleValue(entity is NPCEntity) }
|
functions["is_player"] = { DoubleValue(entity is Player) }
|
||||||
map["is_mob"] = { _ -> DoubleValue(entity is Mob) }
|
functions["is_npc"] = { DoubleValue(entity is NPCEntity) }
|
||||||
map["is_pokemon"] = { _ -> DoubleValue(entity is PokemonEntity) }
|
functions["is_mob"] = { DoubleValue(entity is Mob) }
|
||||||
map["is_animal"] = { _ -> DoubleValue(entity is Animal) }
|
functions["is_pokemon"] = { DoubleValue(entity is PokemonEntity) }
|
||||||
map["is_tamable"] = { _ -> DoubleValue(entity is TamableAnimal) }
|
functions["is_animal"] = { DoubleValue(entity is Animal) }
|
||||||
map["is_tamed"] = { _ -> DoubleValue(entity is TamableAnimal && entity.isTame) }
|
functions["is_tamable"] = { DoubleValue(entity is TamableAnimal) }
|
||||||
map["is_hostile"] = { _ -> DoubleValue(entity is Monster) }
|
functions["is_tamed"] = { DoubleValue(entity is TamableAnimal && entity.isTame) }
|
||||||
map["is_baby"] = { _ -> DoubleValue(entity.isBaby) }
|
functions["is_hostile"] = { DoubleValue(entity is Monster) }
|
||||||
map["is_adult"] = { _ -> DoubleValue(!entity.isBaby) }
|
functions["is_baby"] = { DoubleValue(entity.isBaby) }
|
||||||
map["remove_effect"] = put@{ params ->
|
functions["is_adult"] = { DoubleValue(!entity.isBaby) }
|
||||||
|
functions["remove_effect"] = removeEffect@{ params ->
|
||||||
val effectId = params.getString(0).asIdentifierDefaultingNamespace()
|
val effectId = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val effectHolder = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null)
|
val effectHolder = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null)
|
||||||
if (effectHolder != null) {
|
if (effectHolder != null) {
|
||||||
entity.removeEffect(effectHolder)
|
entity.removeEffect(effectHolder)
|
||||||
return@put DoubleValue.ONE
|
return@removeEffect DoubleValue.ONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["add_effect"] = put@{ params ->
|
functions["add_effect"] = addEffect@{ params ->
|
||||||
val effectId = params.getString(0).asIdentifierDefaultingNamespace()
|
val effectId = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val duration = params.getInt(1)
|
val duration = params.getInt(1)
|
||||||
val amplifier = params.getIntOrNull(2) ?: 0
|
val amplifier = params.getIntOrNull(2) ?: 0
|
||||||
@@ -81,36 +82,37 @@ object LivingEntityMoLangFunctions : AbstractMoLangFunctionHolder<LivingEntity>(
|
|||||||
val effectHolder = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null)
|
val effectHolder = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null)
|
||||||
if (effectHolder != null) {
|
if (effectHolder != null) {
|
||||||
entity.addEffect(MobEffectInstance(effectHolder, duration, amplifier, ambient, visible))
|
entity.addEffect(MobEffectInstance(effectHolder, duration, amplifier, ambient, visible))
|
||||||
return@put DoubleValue.ONE
|
return@addEffect DoubleValue.ONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["has_effect"] = put@{ params ->
|
functions["has_effect"] = { params ->
|
||||||
val effectId = params.getString(0).asIdentifierDefaultingNamespace()
|
val effectId = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val effectHolder = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null)
|
val effectHolder = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null)
|
||||||
return@put DoubleValue(if (effectHolder != null) entity.hasEffect(effectHolder) else false)
|
DoubleValue(effectHolder != null && entity.hasEffect(effectHolder))
|
||||||
}
|
}
|
||||||
map["heal"] = { params ->
|
functions["heal"] = { params ->
|
||||||
val amount = params.getDouble(0)
|
val amount = params.getDouble(0)
|
||||||
entity.heal(amount.toFloat())
|
entity.heal(amount.toFloat())
|
||||||
}
|
}
|
||||||
map["is_looking_at"] = put@{ params ->
|
functions["is_looking_at"] = isLookingAt@{ params ->
|
||||||
val targetEntity = params.get<MoValue>(0)
|
val targetEntity = params.get<MoValue>(0)
|
||||||
val maxDistance = params.getDoubleOrNull(1)?.toFloat() ?: 2.0F
|
val maxDistance = params.getDoubleOrNull(1)?.toFloat() ?: 2.0F
|
||||||
|
|
||||||
val entity = if (targetEntity is ObjectValue<*> && targetEntity.obj is Entity) {
|
val entity =
|
||||||
targetEntity.obj as Entity
|
if (targetEntity is ObjectValue<*> && targetEntity.obj is Entity) {
|
||||||
} else {
|
targetEntity.obj as Entity
|
||||||
return@put DoubleValue.ZERO
|
} else {
|
||||||
}
|
return@isLookingAt DoubleValue.ZERO
|
||||||
|
}
|
||||||
|
|
||||||
return@put DoubleValue(entity.isLookingAt(entity, maxDistance))
|
DoubleValue(entity.isLookingAt(entity, maxDistance))
|
||||||
}
|
}
|
||||||
map["is_living_entity"] = { DoubleValue.ONE }
|
functions["is_living_entity"] = { DoubleValue.ONE }
|
||||||
map["is_flying"] = { _ -> DoubleValue(entity.isFallFlying) }
|
functions["is_flying"] = { DoubleValue(entity.isFallFlying) }
|
||||||
map["is_sleeping"] = { _ -> DoubleValue(entity.isSleeping) }
|
functions["is_sleeping"] = { DoubleValue(entity.isSleeping) }
|
||||||
map["health"] = { _ -> DoubleValue(entity.health) }
|
functions["health"] = { DoubleValue(entity.health) }
|
||||||
map["max_health"] = { _ -> DoubleValue(entity.maxHealth) }
|
functions["max_health"] = { DoubleValue(entity.maxHealth) }
|
||||||
map["look_at_position"] = { params ->
|
functions["look_at_position"] = { params ->
|
||||||
val x = params.getDouble(0)
|
val x = params.getDouble(0)
|
||||||
val y = params.getDouble(1)
|
val y = params.getDouble(1)
|
||||||
val z = params.getDouble(2)
|
val z = params.getDouble(2)
|
||||||
@@ -120,159 +122,174 @@ object LivingEntityMoLangFunctions : AbstractMoLangFunctionHolder<LivingEntity>(
|
|||||||
brain.setMemoryWithExpiry(
|
brain.setMemoryWithExpiry(
|
||||||
MemoryModuleType.LOOK_TARGET,
|
MemoryModuleType.LOOK_TARGET,
|
||||||
CobblemonBlockPosTracker(Vec3(x, y, z), flags.toSet()),
|
CobblemonBlockPosTracker(Vec3(x, y, z), flags.toSet()),
|
||||||
duration.toLong()
|
duration.toLong(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
map["get_wander_control_memory"] = put@{
|
functions["get_wander_control_memory"] = {
|
||||||
val value = entity.brain.getMemorySafely(CobblemonMemories.WANDER_CONTROL).orElse(null)
|
val value =
|
||||||
?: CobblemonWanderControl()
|
entity.brain.getMemorySafely(CobblemonMemories.WANDER_CONTROL).orElse(null)
|
||||||
|
?: CobblemonWanderControl()
|
||||||
if (
|
if (
|
||||||
!entity.brain.checkMemory(CobblemonMemories.WANDER_CONTROL, MemoryStatus.VALUE_PRESENT)
|
!entity.brain.checkMemory(CobblemonMemories.WANDER_CONTROL, MemoryStatus.VALUE_PRESENT) &&
|
||||||
&& entity.brain.checkMemory(CobblemonMemories.WANDER_CONTROL, MemoryStatus.REGISTERED)
|
entity.brain.checkMemory(CobblemonMemories.WANDER_CONTROL, MemoryStatus.REGISTERED)
|
||||||
) {
|
) {
|
||||||
entity.brain.setMemory(CobblemonMemories.WANDER_CONTROL, value)
|
entity.brain.setMemory(CobblemonMemories.WANDER_CONTROL, value)
|
||||||
}
|
}
|
||||||
return@put value.struct
|
value.struct
|
||||||
}
|
}
|
||||||
map["get_position_memory"] = put@{ params ->
|
functions["get_position_memory"] = getPosMemory@{ params ->
|
||||||
val id = params.getString(0).asIdentifierDefaultingNamespace()
|
val id = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val memoryType = BuiltInRegistries.MEMORY_MODULE_TYPE.get(id)
|
val memoryType = BuiltInRegistries.MEMORY_MODULE_TYPE.get(id)
|
||||||
if (entity.brain.checkMemory(memoryType, MemoryStatus.VALUE_PRESENT)) {
|
if (entity.brain.checkMemory(memoryType, MemoryStatus.VALUE_PRESENT)) {
|
||||||
return@put when (val memory = entity.brain.getMemory(memoryType).get()) {
|
return@getPosMemory when (val memory = entity.brain.getMemory(memoryType).get()) {
|
||||||
is Vec3i -> VariableStruct(
|
is Vec3i -> {
|
||||||
mapOf(
|
VariableStruct(
|
||||||
"x" to DoubleValue(memory.x),
|
mapOf(
|
||||||
"y" to DoubleValue(memory.y),
|
"x" to DoubleValue(memory.x),
|
||||||
"z" to DoubleValue(memory.z)
|
"y" to DoubleValue(memory.y),
|
||||||
|
"z" to DoubleValue(memory.z),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
|
|
||||||
is Position -> VariableStruct(
|
is Position -> {
|
||||||
mapOf(
|
VariableStruct(
|
||||||
"x" to DoubleValue(memory.x()),
|
mapOf(
|
||||||
"y" to DoubleValue(memory.y()),
|
"x" to DoubleValue(memory.x()),
|
||||||
"z" to DoubleValue(memory.z())
|
"y" to DoubleValue(memory.y()),
|
||||||
|
"z" to DoubleValue(memory.z()),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
|
|
||||||
else -> DoubleValue.ZERO
|
else -> {
|
||||||
|
DoubleValue.ZERO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
map["set_uuid_memory"] = put@{ params ->
|
functions["set_uuid_memory"] = setUuidMemory@{ params ->
|
||||||
val memory = params.getString(0).asIdentifierDefaultingNamespace()
|
val memory =
|
||||||
.let(BuiltInRegistries.MEMORY_MODULE_TYPE::get) as MemoryModuleType<UUID>
|
params
|
||||||
val uuid = params.getString(1).asUUID ?: return@put DoubleValue.ZERO
|
.getString(0)
|
||||||
|
.asIdentifierDefaultingNamespace()
|
||||||
|
.let(BuiltInRegistries.MEMORY_MODULE_TYPE::get) as MemoryModuleType<UUID>
|
||||||
|
val uuid = params.getString(1).asUUID ?: return@setUuidMemory DoubleValue.ZERO
|
||||||
val expiry = params.getIntOrNull(2) ?: -1
|
val expiry = params.getIntOrNull(2) ?: -1
|
||||||
if (expiry != -1) {
|
if (expiry != -1) {
|
||||||
entity.brain.setMemoryWithExpiry(memory, uuid, expiry.toLong())
|
entity.brain.setMemoryWithExpiry(memory, uuid, expiry.toLong())
|
||||||
} else {
|
} else {
|
||||||
entity.brain.setMemory(memory, uuid)
|
entity.brain.setMemory(memory, uuid)
|
||||||
}
|
}
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["erase_memory"] = put@{ params ->
|
functions["erase_memory"] = { params ->
|
||||||
val memories = params.params.map { it.asString().asIdentifierDefaultingNamespace() }
|
val memories =
|
||||||
.map(BuiltInRegistries.MEMORY_MODULE_TYPE::get)
|
params.params
|
||||||
|
.map { it.asString().asIdentifierDefaultingNamespace() }
|
||||||
|
.map(BuiltInRegistries.MEMORY_MODULE_TYPE::get)
|
||||||
memories.forEach { entity.brain.eraseMemory(it) }
|
memories.forEach { entity.brain.eraseMemory(it) }
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["has_memory_value"] = put@{ params ->
|
functions["has_memory_value"] = hasMemoryValue@{ params ->
|
||||||
for (param in params.params) {
|
for (param in params.params) {
|
||||||
if (!entity.hasMemoryFromString(param.asString())) {
|
if (!entity.hasMemoryFromString(param.asString())) {
|
||||||
return@put DoubleValue.ZERO
|
return@hasMemoryValue DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["lacks_memory_value"] = put@{ params ->
|
functions["lacks_memory_value"] = lacksMemoryValue@{ params ->
|
||||||
for (param in params.params) {
|
for (param in params.params) {
|
||||||
if (entity.hasMemoryFromString(param.asString())) {
|
if (entity.hasMemoryFromString(param.asString())) {
|
||||||
return@put DoubleValue.ZERO
|
return@lacksMemoryValue DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["is_doing_activity"] = put@{ params ->
|
functions["is_doing_activity"] = isDoingActivity@{ params ->
|
||||||
for (param in params.params) {
|
for (param in params.params) {
|
||||||
if (entity.isDoingActivityFromString(param.asString())) {
|
if (entity.isDoingActivityFromString(param.asString())) {
|
||||||
return@put DoubleValue.ONE
|
return@isDoingActivity DoubleValue.ONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@put DoubleValue.ZERO
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
map["can_see"] = put@{ params ->
|
functions["can_see"] = canSee@{ params ->
|
||||||
val target = params.get<MoValue>(0)
|
val target = params.get<MoValue>(0)
|
||||||
val range = params.getDoubleOrNull(1) ?: 32.0
|
val range = params.getDoubleOrNull(1) ?: 32.0
|
||||||
if (target is ObjectValue<*>) {
|
if (target is ObjectValue<*>) {
|
||||||
val targetEntity = target.obj as? LivingEntity ?: return@put DoubleValue.ZERO
|
val targetEntity = target.obj as? LivingEntity ?: return@canSee DoubleValue.ZERO
|
||||||
val vector = targetEntity.eyePosition.subtract(entity.eyePosition).normalize()
|
val vector = targetEntity.eyePosition.subtract(entity.eyePosition).normalize()
|
||||||
val trace = entity.traceEntityCollision(
|
val trace =
|
||||||
maxDistance = range.toFloat(),
|
entity.traceEntityCollision(
|
||||||
stepDistance = 0.1F,
|
maxDistance = range.toFloat(),
|
||||||
direction = vector,
|
stepDistance = 0.1F,
|
||||||
entityClass = targetEntity.javaClass,
|
direction = vector,
|
||||||
collideBlock = ClipContext.Fluid.NONE
|
entityClass = targetEntity.javaClass,
|
||||||
)
|
collideBlock = ClipContext.Fluid.NONE,
|
||||||
return@put DoubleValue(targetEntity in (trace?.entities ?: emptyList()))
|
)
|
||||||
} else {
|
return@canSee DoubleValue(targetEntity in (trace?.entities ?: emptyList()))
|
||||||
return@put DoubleValue.ZERO
|
}
|
||||||
|
DoubleValue.ZERO
|
||||||
|
}
|
||||||
|
|
||||||
|
when (entity) {
|
||||||
|
is PathfinderMob -> {
|
||||||
|
functions["walk_to"] = { params ->
|
||||||
|
val x = params.getDouble(0)
|
||||||
|
val y = params.getDouble(1)
|
||||||
|
val z = params.getDouble(2)
|
||||||
|
val speedMultiplier = params.getDoubleOrNull(3) ?: 0.35
|
||||||
|
|
||||||
|
if (entity.brain.checkMemory(MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED)) {
|
||||||
|
entity.brain.setMemory(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
WalkTarget(Vec3(x, y, z), speedMultiplier.toFloat(), 1),
|
||||||
|
)
|
||||||
|
entity.brain.setMemory(
|
||||||
|
MemoryModuleType.LOOK_TARGET,
|
||||||
|
BlockPosTracker(Vec3(x, y + entity.eyeHeight, z)),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
entity.navigation.moveTo(x, y, z, speedMultiplier)
|
||||||
|
entity.lookControl.setLookAt(Vec3(x, y + entity.eyeHeight, z))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
functions["has_walk_target"] = {
|
||||||
|
DoubleValue(entity.brain.getMemorySafely(MemoryModuleType.WALK_TARGET).isPresent || entity.isPathFinding)
|
||||||
|
}
|
||||||
|
|
||||||
|
functions["set_can_float"] = { params ->
|
||||||
|
val canFloat = params.getBooleanOrNull(0) != false
|
||||||
|
entity.navigation.setCanFloat(canFloat)
|
||||||
|
DoubleValue.ONE
|
||||||
|
}
|
||||||
|
|
||||||
|
functions["get_pathfinding_malus"] = getPfMalus@{ params ->
|
||||||
|
val type = PathType.entries.find { it.name == params.getString(0).uppercase() }
|
||||||
|
if (type != null) {
|
||||||
|
return@getPfMalus DoubleValue(entity.getPathfindingMalus(type))
|
||||||
|
}
|
||||||
|
Cobblemon.LOGGER.error("Cannot get pathfinding type, unknown value: ${params.getString(0)}")
|
||||||
|
DoubleValue.ZERO
|
||||||
|
}
|
||||||
|
functions["set_pathfinding_malus"] = setPfMalus@{ params ->
|
||||||
|
val type = PathType.entries.find { it.name == params.getString(0).uppercase() }
|
||||||
|
val malus = params.getDouble(1).toFloat()
|
||||||
|
if (type != null) {
|
||||||
|
entity.setPathfindingMalus(type, malus)
|
||||||
|
return@setPfMalus DoubleValue.ONE
|
||||||
|
}
|
||||||
|
Cobblemon.LOGGER.error("Cannot set pathfinding type, unknown value: ${params.getString(0)}")
|
||||||
|
DoubleValue.ZERO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity is PathfinderMob) {
|
return functions
|
||||||
map["walk_to"] = { params ->
|
|
||||||
val x = params.getDouble(0)
|
|
||||||
val y = params.getDouble(1)
|
|
||||||
val z = params.getDouble(2)
|
|
||||||
val speedMultiplier = params.getDoubleOrNull(3) ?: 0.35
|
|
||||||
|
|
||||||
if (entity.brain.checkMemory(MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED)) {
|
|
||||||
entity.brain.setMemory(
|
|
||||||
MemoryModuleType.WALK_TARGET,
|
|
||||||
WalkTarget(Vec3(x, y, z), speedMultiplier.toFloat(), 1)
|
|
||||||
)
|
|
||||||
entity.brain.setMemory(
|
|
||||||
MemoryModuleType.LOOK_TARGET,
|
|
||||||
BlockPosTracker(Vec3(x, y + entity.eyeHeight, z))
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
entity.navigation.moveTo(x, y, z, speedMultiplier)
|
|
||||||
entity.lookControl.setLookAt(Vec3(x, y + entity.eyeHeight, z))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
map["has_walk_target"] = { _ ->
|
|
||||||
DoubleValue(entity.brain.getMemorySafely(MemoryModuleType.WALK_TARGET).isPresent || entity.isPathFinding)
|
|
||||||
}
|
|
||||||
|
|
||||||
map["set_can_float"] = { params ->
|
|
||||||
val canFloat = params.getBooleanOrNull(0) != false
|
|
||||||
entity.navigation.setCanFloat(canFloat)
|
|
||||||
DoubleValue.ONE
|
|
||||||
}
|
|
||||||
|
|
||||||
map["get_pathfinding_malus"] = put@{ params ->
|
|
||||||
val type = PathType.entries.find { it.name == params.getString(0).uppercase() }
|
|
||||||
if (type != null) {
|
|
||||||
return@put DoubleValue(entity.getPathfindingMalus(type))
|
|
||||||
}
|
|
||||||
Cobblemon.LOGGER.error("Unknown pathfinding type: ${params.getString(0)}")
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
|
||||||
map["set_pathfinding_malus"] = put@{ params ->
|
|
||||||
val type = PathType.entries.find { it.name == params.getString(0).uppercase() }
|
|
||||||
val malus = params.getDouble(1).toFloat()
|
|
||||||
if (type != null) {
|
|
||||||
entity.setPathfindingMalus(type, malus)
|
|
||||||
return@put DoubleValue.ONE
|
|
||||||
}
|
|
||||||
Cobblemon.LOGGER.error("Unknown pathfinding type: ${params.getString(0)}")
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+108
-98
@@ -50,18 +50,23 @@ import kotlin.collections.any
|
|||||||
object NPCMoLangFunctions : AbstractMoLangFunctionHolder<NPCEntity>() {
|
object NPCMoLangFunctions : AbstractMoLangFunctionHolder<NPCEntity>() {
|
||||||
override fun NPCEntity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun NPCEntity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val npc = this
|
val npc = this
|
||||||
val map = hashMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
map["class"] = { StringValue(npc.npc.id.toString()) }
|
|
||||||
map["name"] = { StringValue(npc.name.string) }
|
functions["class"] = { StringValue(npc.npc.id.toString()) }
|
||||||
map["level"] = { DoubleValue(npc.level) }
|
functions["name"] = { StringValue(npc.name.string) }
|
||||||
map["has_aspect"] = { params -> DoubleValue(npc.aspects.contains(params.getString(0))) }
|
functions["level"] = { DoubleValue(npc.level) }
|
||||||
map["in_battle"] = { DoubleValue(npc.isInBattle()) }
|
functions["has_aspect"] = { params -> DoubleValue(npc.aspects.contains(params.getString(0))) }
|
||||||
map["battles"] = {
|
functions["in_battle"] = { DoubleValue(npc.isInBattle()) }
|
||||||
ArrayStruct(npc.battleIds.mapNotNull { BattleRegistry.getBattle(it)?.struct }
|
functions["battles"] = {
|
||||||
.mapIndexed { index, value -> "$index" to value }.toMap())
|
ArrayStruct(
|
||||||
|
npc.battleIds
|
||||||
|
.mapNotNull { BattleRegistry.getBattle(it)?.struct }
|
||||||
|
.mapIndexed { index, value -> "$index" to value }
|
||||||
|
.toMap(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
map["stop_battles"] = { _ -> npc.battleIds.forEach { BattleRegistry.getBattle(it)?.stop() } }
|
functions["stop_battles"] = { npc.battleIds.forEach { BattleRegistry.getBattle(it)?.stop() } }
|
||||||
map["run_script_on_client"] = { params ->
|
functions["run_script_on_client"] = { params ->
|
||||||
val world = npc.level()
|
val world = npc.level()
|
||||||
if (world is ServerLevel) {
|
if (world is ServerLevel) {
|
||||||
val script = params.getString(0)
|
val script = params.getString(0)
|
||||||
@@ -70,141 +75,142 @@ object NPCMoLangFunctions : AbstractMoLangFunctionHolder<NPCEntity>() {
|
|||||||
}
|
}
|
||||||
Unit
|
Unit
|
||||||
}
|
}
|
||||||
map["run_script"] = { params ->
|
functions["run_script"] = { params ->
|
||||||
val script = params.getString(0).asIdentifierDefaultingNamespace()
|
val script = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val runtime = MoLangRuntime()
|
val runtime = MoLangRuntime()
|
||||||
runtime.environment.cloneFrom(params.environment)
|
runtime.environment.cloneFrom(params.environment)
|
||||||
CobblemonScripts.run(script, runtime) ?: DoubleValue(0)
|
CobblemonScripts.run(script, runtime) ?: DoubleValue(0)
|
||||||
}
|
}
|
||||||
map["set_movable"] = put@{ params ->
|
functions["set_movable"] = { params ->
|
||||||
val movable = params.getBooleanOrNull(0) != false
|
val movable = params.getBooleanOrNull(0) != false
|
||||||
npc.isMovable = movable
|
npc.isMovable = movable
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_invulnerable"] = put@{ params ->
|
functions["set_invulnerable"] = { params ->
|
||||||
val invulnerable = params.getBooleanOrNull(0) != false
|
val invulnerable = params.getBooleanOrNull(0) != false
|
||||||
npc.isInvulnerable = invulnerable
|
npc.isInvulnerable = invulnerable
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_leashable"] = put@{ params ->
|
functions["set_leashable"] = { params ->
|
||||||
val leashable = params.getBooleanOrNull(0) != false
|
val leashable = params.getBooleanOrNull(0) != false
|
||||||
npc.isLeashable = leashable
|
npc.isLeashable = leashable
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_allow_projectile_hits"] = put@{ params ->
|
functions["set_allow_projectile_hits"] = { params ->
|
||||||
val allowProjectileHits = params.getBooleanOrNull(0) != false
|
val allowProjectileHits = params.getBooleanOrNull(0) != false
|
||||||
npc.allowProjectileHits = allowProjectileHits
|
npc.allowProjectileHits = allowProjectileHits
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_name_tag_visible"] = put@{ params ->
|
functions["set_name_tag_visible"] = { params ->
|
||||||
val nameTagVisible = params.getBooleanOrNull(0) != false
|
val nameTagVisible = params.getBooleanOrNull(0) != false
|
||||||
npc.hideNameTag = !nameTagVisible
|
npc.hideNameTag = !nameTagVisible
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["unset_interaction"] = put@{
|
functions["unset_interaction"] = {
|
||||||
npc.interaction = null
|
npc.interaction = null
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_dialogue_interaction"] = put@{ params ->
|
functions["set_dialogue_interaction"] = { params ->
|
||||||
val dialogue = params.getString(0).asIdentifierDefaultingNamespace()
|
val dialogue = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
npc.interaction = DialogueNPCInteractionConfiguration().also {
|
npc.interaction =
|
||||||
it.dialogue = dialogue
|
DialogueNPCInteractionConfiguration().also {
|
||||||
}
|
it.dialogue = dialogue
|
||||||
return@put DoubleValue.ONE
|
}
|
||||||
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_script_interaction"] = put@{ params ->
|
functions["set_script_interaction"] = { params ->
|
||||||
val script = params.getString(0).asIdentifierDefaultingNamespace()
|
val script = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
npc.interaction = ScriptNPCInteractionConfiguration().also {
|
npc.interaction =
|
||||||
it.script = script
|
ScriptNPCInteractionConfiguration().also {
|
||||||
}
|
it.script = script
|
||||||
return@put DoubleValue.ONE
|
}
|
||||||
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_player_texture"] = put@{ params ->
|
functions["set_player_texture"] = setPlayerTexture@{ params ->
|
||||||
val username = params.getString(0)
|
val username = params.getString(0)
|
||||||
// Re-applying it would be unnecessarily laggy.
|
// Re-applying it would be unnecessarily laggy.
|
||||||
if (username == npc.data.map["player_texture_username"]?.asString()) {
|
if (username == npc.data.map["player_texture_username"]?.asString()) {
|
||||||
return@put DoubleValue.ZERO
|
return@setPlayerTexture DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
npc.loadTextureFromGameProfileName(username)
|
npc.loadTextureFromGameProfileName(username)
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["unset_player_texture"] = put@{
|
functions["unset_player_texture"] = {
|
||||||
npc.unloadTexture()
|
npc.unloadTexture()
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_resource_identifier"] = put@{ params ->
|
functions["set_resource_identifier"] = { params ->
|
||||||
val identifier = params.getStringOrNull(0)?.asIdentifierDefaultingNamespace()
|
val identifier = params.getStringOrNull(0)?.asIdentifierDefaultingNamespace()
|
||||||
npc.forcedResourceIdentifier = identifier
|
npc.forcedResourceIdentifier = identifier
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["unset_resource_identifier"] = put@{
|
functions["unset_resource_identifier"] = {
|
||||||
npc.forcedResourceIdentifier = null
|
npc.forcedResourceIdentifier = null
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_class"] = put@{ params ->
|
functions["set_class"] = setClass@{ params ->
|
||||||
val identifier = params.getString(0).asIdentifierDefaultingNamespace()
|
val identifier = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val npcClass = NPCClasses.getByIdentifier(identifier)
|
val npcClass = NPCClasses.getByIdentifier(identifier)
|
||||||
if (npcClass != null) {
|
if (npcClass != null) {
|
||||||
npc.npc = npcClass
|
npc.npc = npcClass
|
||||||
return@put DoubleValue.ONE
|
return@setClass DoubleValue.ONE
|
||||||
} else {
|
|
||||||
Cobblemon.LOGGER.error("Unknown NPC class: $identifier")
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
}
|
||||||
|
Cobblemon.LOGGER.error("Unknown NPC class: $identifier")
|
||||||
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
map["set_render_scale"] = put@{ params ->
|
functions["set_render_scale"] = { params ->
|
||||||
val scale = params.getDouble(0)
|
val scale = params.getDouble(0)
|
||||||
npc.renderScale = scale.toFloat()
|
npc.renderScale = scale.toFloat()
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["render_scale"] = { _ -> DoubleValue(npc.renderScale) }
|
functions["render_scale"] = { DoubleValue(npc.renderScale) }
|
||||||
map["set_hitbox_scale"] = put@{ params ->
|
functions["set_hitbox_scale"] = { params ->
|
||||||
val scale = params.getDouble(0).toFloat()
|
val scale = params.getDouble(0).toFloat()
|
||||||
npc.hitboxScale = scale
|
npc.hitboxScale = scale
|
||||||
npc.refreshDimensions()
|
npc.refreshDimensions()
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["hitbox_scale"] = { _ -> DoubleValue(npc.hitboxScale) }
|
functions["hitbox_scale"] = { DoubleValue(npc.hitboxScale) }
|
||||||
map["set_hitbox"] = put@{ params ->
|
functions["set_hitbox"] = setHitbox@{ params ->
|
||||||
if (params.params.isEmpty()) {
|
if (params.params.isEmpty()) {
|
||||||
npc.hitbox = null
|
npc.hitbox = null
|
||||||
return@put DoubleValue.ONE
|
return@setHitbox DoubleValue.ONE
|
||||||
}
|
}
|
||||||
val width = params.getDouble(0).toFloat()
|
val width = params.getDouble(0).toFloat()
|
||||||
val height = params.getDouble(1).toFloat()
|
val height = params.getDouble(1).toFloat()
|
||||||
val eyeHeight = params.getDoubleOrNull(2)?.toFloat() ?: (height * 0.85F)
|
val eyeHeight = params.getDoubleOrNull(2)?.toFloat() ?: (height * 0.85F)
|
||||||
npc.hitbox = EntityDimensions.scalable(width, height).withEyeHeight(eyeHeight)
|
npc.hitbox = EntityDimensions.scalable(width, height).withEyeHeight(eyeHeight)
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["unset_hitbox"] = put@{
|
functions["unset_hitbox"] = {
|
||||||
npc.hitbox = null
|
npc.hitbox = null
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["aspects"] = put@{
|
functions["aspects"] = {
|
||||||
val aspects = npc.aspects
|
val aspects = npc.aspects
|
||||||
return@put aspects.asArrayValue { StringValue(it) }
|
aspects.asArrayValue { StringValue(it) }
|
||||||
}
|
}
|
||||||
map["add_aspect"] = put@{ params ->
|
functions["add_aspect"] = { params ->
|
||||||
val aspects = params.params.map { it.asString() }
|
val aspects = params.params.map { it.asString() }
|
||||||
npc.appliedAspects.addAll(aspects)
|
npc.appliedAspects.addAll(aspects)
|
||||||
npc.updateAspects()
|
npc.updateAspects()
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["remove_aspect"] = put@{ params ->
|
functions["remove_aspect"] = { params ->
|
||||||
val aspects = params.params.map { it.asString() }
|
val aspects = params.params.map { it.asString() }
|
||||||
npc.appliedAspects.removeAll(aspects.toSet())
|
npc.appliedAspects.removeAll(aspects.toSet())
|
||||||
npc.updateAspects()
|
npc.updateAspects()
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["party"] = put@{
|
functions["party"] = party@{
|
||||||
val party = npc.party ?: return@put DoubleValue.ZERO
|
val party = npc.party ?: return@party DoubleValue.ZERO
|
||||||
return@put party.asMoLangValue()
|
party.asMoLangValue()
|
||||||
}
|
}
|
||||||
map["create_npc_party"] = put@{
|
functions["create_npc_party"] = {
|
||||||
val party = NPCPartyStore(npc)
|
val party = NPCPartyStore(npc)
|
||||||
return@put party.asMoLangValue()
|
party.asMoLangValue()
|
||||||
}
|
}
|
||||||
map["set_npc_party"] = { params ->
|
functions["set_npc_party"] = { params ->
|
||||||
val party = params.get<MoValue>(0)
|
val party = params.get<MoValue>(0)
|
||||||
if (party is ObjectValue<*>) {
|
if (party is ObjectValue<*>) {
|
||||||
npc.party = party.obj as NPCPartyStore
|
npc.party = party.obj as NPCPartyStore
|
||||||
@@ -213,18 +219,19 @@ object NPCMoLangFunctions : AbstractMoLangFunctionHolder<NPCEntity>() {
|
|||||||
}
|
}
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["run_action_effect"] = put@{ params ->
|
functions["run_action_effect"] = runActionEffect@{ params ->
|
||||||
val runtime = MoLangRuntime().setup()
|
val runtime = MoLangRuntime().setup()
|
||||||
runtime.environment.cloneFrom(params.environment)
|
runtime.environment.cloneFrom(params.environment)
|
||||||
runtime.withNPCValue(value = npc)
|
runtime.withNPCValue(value = npc)
|
||||||
val actionEffect = ActionEffects.actionEffects[params.getString(0).asIdentifierDefaultingNamespace()]
|
val actionEffect = ActionEffects.actionEffects[params.getString(0).asIdentifierDefaultingNamespace()]
|
||||||
if (actionEffect != null) {
|
if (actionEffect != null) {
|
||||||
val context = ActionEffectContext(
|
val context =
|
||||||
actionEffect = actionEffect,
|
ActionEffectContext(
|
||||||
providers = mutableListOf(NPCProvider(npc)),
|
actionEffect = actionEffect,
|
||||||
runtime = runtime,
|
providers = mutableListOf(NPCProvider(npc)),
|
||||||
level = npc.level()
|
runtime = runtime,
|
||||||
)
|
level = npc.level(),
|
||||||
|
)
|
||||||
npc.actionEffect = context
|
npc.actionEffect = context
|
||||||
npc.brain.setMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT, context)
|
npc.brain.setMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT, context)
|
||||||
npc.brain.setActiveActivityIfPossible(CobblemonActivities.ACTION_EFFECT)
|
npc.brain.setActiveActivityIfPossible(CobblemonActivities.ACTION_EFFECT)
|
||||||
@@ -236,37 +243,40 @@ object NPCMoLangFunctions : AbstractMoLangFunctionHolder<NPCEntity>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return@put DoubleValue.ONE
|
return@runActionEffect DoubleValue.ONE
|
||||||
}
|
}
|
||||||
return@put DoubleValue.ZERO
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
map["put_pokemon_in_healer"] = put@{ params ->
|
functions["put_pokemon_in_healer"] = putPokeInHealer@{ params ->
|
||||||
val healer = npc.level()
|
val healer =
|
||||||
.getBlockEntity(params.get<ArrayStruct>(0).asBlockPos(), CobblemonBlockEntities.HEALING_MACHINE)
|
npc
|
||||||
.orElse(null) ?: return@put DoubleValue.ZERO
|
.level()
|
||||||
val party = npc.party ?: return@put DoubleValue.ZERO
|
.getBlockEntity(params.get<ArrayStruct>(0).asBlockPos(), CobblemonBlockEntities.HEALING_MACHINE)
|
||||||
|
.orElse(null) ?: return@putPokeInHealer DoubleValue.ZERO
|
||||||
|
val party = npc.party ?: return@putPokeInHealer DoubleValue.ZERO
|
||||||
if (healer.canHeal(party)) {
|
if (healer.canHeal(party)) {
|
||||||
healer.activate(npc.uuid, party)
|
healer.activate(npc.uuid, party)
|
||||||
return@put DoubleValue.ONE
|
return@putPokeInHealer DoubleValue.ONE
|
||||||
} else {
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
}
|
||||||
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
map["look_at_position"] = { params ->
|
functions["look_at_position"] = { params ->
|
||||||
val pos = Vec3(params.getDouble(0), params.getDouble(1), params.getDouble(2))
|
val pos = Vec3(params.getDouble(0), params.getDouble(1), params.getDouble(2))
|
||||||
npc.lookAt(EntityAnchorArgument.Anchor.EYES, pos)
|
npc.lookAt(EntityAnchorArgument.Anchor.EYES, pos)
|
||||||
}
|
}
|
||||||
map["environment"] = { _ -> npc.runtime.environment }
|
functions["environment"] = { npc.runtime.environment }
|
||||||
map["party"] = { npc.party?.struct ?: DoubleValue.ZERO }
|
functions["party"] = { npc.party?.struct ?: DoubleValue.ZERO }
|
||||||
map["has_party"] = { DoubleValue(npc.party != null) }
|
functions["has_party"] = { DoubleValue(npc.party != null) }
|
||||||
map["is_npc"] = { DoubleValue.ONE }
|
functions["is_npc"] = { DoubleValue.ONE }
|
||||||
map["can_battle"] =
|
functions["can_battle"] = {
|
||||||
{ DoubleValue(npc.party?.any { it.currentHealth > 0 } == true || npc.npc.party?.isStatic == false) }
|
DoubleValue(npc.party?.any { it.currentHealth > 0 } == true || npc.npc.party?.isStatic == false)
|
||||||
map["set_battle_theme"] = put@{ params ->
|
}
|
||||||
|
functions["set_battle_theme"] = { params ->
|
||||||
val soundId = params.getString(0).asResource()
|
val soundId = params.getString(0).asResource()
|
||||||
npc.npc.battleTheme = soundId
|
npc.npc.battleTheme = soundId
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
return map
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -23,40 +23,40 @@ import com.cobblemon.mod.common.util.getBooleanOrNull
|
|||||||
object PCMoLangFunctions : AbstractMoLangFunctionHolder<PCStore>() {
|
object PCMoLangFunctions : AbstractMoLangFunctionHolder<PCStore>() {
|
||||||
override fun PCStore.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun PCStore.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val pc = this
|
val pc = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
|
|
||||||
map["get_pokemon"] = getPokemon@{ params ->
|
functions["get_pokemon"] = getPokemon@{ params ->
|
||||||
val box = params.getInt(0)
|
val box = params.getInt(0)
|
||||||
val slot = params.getInt(1)
|
val slot = params.getInt(1)
|
||||||
val pokemon = pc[PCPosition(box, slot)] ?: return@getPokemon DoubleValue.ZERO
|
val pokemon = pc[PCPosition(box, slot)] ?: return@getPokemon DoubleValue.ZERO
|
||||||
return@getPokemon pokemon.struct
|
pokemon.struct
|
||||||
}
|
}
|
||||||
map["set_pokemon"] = { params ->
|
functions["set_pokemon"] = { params ->
|
||||||
val box = params.getInt(0)
|
val box = params.getInt(0)
|
||||||
val slot = params.getInt(1)
|
val slot = params.getInt(1)
|
||||||
val pokemon = params.get<ObjectValue<Pokemon>>(2).obj
|
val pokemon = params.get<ObjectValue<Pokemon>>(2).obj
|
||||||
pc[PCPosition(box, slot)] = pokemon
|
pc[PCPosition(box, slot)] = pokemon
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["resize"] = { params ->
|
functions["resize"] = { params ->
|
||||||
val newSize = params.getInt(0)
|
val newSize = params.getInt(0)
|
||||||
val lockNewSize = params.getBooleanOrNull(1) == true
|
val lockNewSize = params.getBooleanOrNull(1) == true
|
||||||
pc.resize(newSize, lockNewSize)
|
pc.resize(newSize, lockNewSize)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["get_box_count"] = { DoubleValue(pc.boxes.size.toDouble()) }
|
functions["get_box_count"] = { DoubleValue(pc.boxes.size.toDouble()) }
|
||||||
map["has_unlocked_wallpaper"] = { params ->
|
functions["has_unlocked_wallpaper"] = { params ->
|
||||||
val wallpaper = params.getString(0).asIdentifierDefaultingNamespace()
|
val wallpaper = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
DoubleValue(pc.unlockedWallpapers.contains(wallpaper))
|
DoubleValue(pc.unlockedWallpapers.contains(wallpaper))
|
||||||
}
|
}
|
||||||
map["get_unlocked_wallpapers"] = { pc.unlockedWallpapers.asArrayValue { StringValue(it.toString()) } }
|
functions["get_unlocked_wallpapers"] = { pc.unlockedWallpapers.asArrayValue { StringValue(it.toString()) } }
|
||||||
map["unlock_wallpaper"] = unlockWallpaper@{
|
functions["unlock_wallpaper"] = unlockWallpaper@{
|
||||||
val wallpaper = it.getString(0).asIdentifierDefaultingNamespace()
|
val wallpaper = it.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val playSound = it.getBooleanOrNull(1) != false
|
val playSound = it.getBooleanOrNull(1) != false
|
||||||
CobblemonUnlockableWallpapers.unlockableWallpapers[wallpaper] ?: return@unlockWallpaper DoubleValue.ZERO
|
CobblemonUnlockableWallpapers.unlockableWallpapers[wallpaper] ?: return@unlockWallpaper DoubleValue.ZERO
|
||||||
return@unlockWallpaper DoubleValue(pc.unlockWallpaper(wallpaper, playSound))
|
DoubleValue(pc.unlockWallpaper(wallpaper, playSound))
|
||||||
}
|
}
|
||||||
|
|
||||||
return map
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-5
@@ -14,21 +14,23 @@ import com.cobblemon.mod.common.api.molang.ObjectValue
|
|||||||
import com.cobblemon.mod.common.api.storage.party.PartyStore
|
import com.cobblemon.mod.common.api.storage.party.PartyStore
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
|
||||||
object PartyMoLangFunctions: AbstractMoLangFunctionHolder<PartyStore>() {
|
object PartyMoLangFunctions : AbstractMoLangFunctionHolder<PartyStore>() {
|
||||||
override fun PartyStore.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun PartyStore.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val party = this
|
val party = this
|
||||||
val map = hashMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
map["get_pokemon"] = getPokemon@{ params ->
|
|
||||||
|
functions["get_pokemon"] = getPokemon@{ params ->
|
||||||
val index = params.getInt(0)
|
val index = params.getInt(0)
|
||||||
val pokemon = party.get(index) ?: return@getPokemon DoubleValue.ZERO
|
val pokemon = party.get(index) ?: return@getPokemon DoubleValue.ZERO
|
||||||
pokemon.struct
|
pokemon.struct
|
||||||
}
|
}
|
||||||
map["set_pokemon"] = { params ->
|
functions["set_pokemon"] = { params ->
|
||||||
val index = params.getInt(0)
|
val index = params.getInt(0)
|
||||||
val pokemon = params.get<ObjectValue<Pokemon>>(1).obj
|
val pokemon = params.get<ObjectValue<Pokemon>>(1).obj
|
||||||
party.set(index, pokemon)
|
party.set(index, pokemon)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
return map
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+300
-266
@@ -17,12 +17,12 @@ import com.bedrockk.molang.runtime.value.MoValue
|
|||||||
import com.bedrockk.molang.runtime.value.StringValue
|
import com.bedrockk.molang.runtime.value.StringValue
|
||||||
import com.cobblemon.mod.common.Cobblemon
|
import com.cobblemon.mod.common.Cobblemon
|
||||||
import com.cobblemon.mod.common.CobblemonBlockEntities
|
import com.cobblemon.mod.common.CobblemonBlockEntities
|
||||||
import com.cobblemon.mod.common.api.moves.Moves
|
|
||||||
import com.cobblemon.mod.common.api.tms.TechnicalMachines
|
|
||||||
import com.cobblemon.mod.common.api.dialogue.PlayerDialogueFaceProvider
|
import com.cobblemon.mod.common.api.dialogue.PlayerDialogueFaceProvider
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||||
import com.cobblemon.mod.common.api.molang.ObjectValue
|
import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||||
|
import com.cobblemon.mod.common.api.moves.Moves
|
||||||
import com.cobblemon.mod.common.api.text.text
|
import com.cobblemon.mod.common.api.text.text
|
||||||
|
import com.cobblemon.mod.common.api.tms.TechnicalMachines
|
||||||
import com.cobblemon.mod.common.battles.BattleBuilder
|
import com.cobblemon.mod.common.battles.BattleBuilder
|
||||||
import com.cobblemon.mod.common.battles.BattleFormat
|
import com.cobblemon.mod.common.battles.BattleFormat
|
||||||
import com.cobblemon.mod.common.entity.npc.NPCEntity
|
import com.cobblemon.mod.common.entity.npc.NPCEntity
|
||||||
@@ -52,355 +52,389 @@ import net.minecraft.core.registries.Registries
|
|||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.sounds.SoundSource
|
import net.minecraft.sounds.SoundSource
|
||||||
|
import net.minecraft.stats.Stats
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.GameType
|
import net.minecraft.world.level.GameType
|
||||||
import kotlin.collections.iterator
|
|
||||||
|
|
||||||
object PlayerMoLangFunctions : AbstractMoLangFunctionHolder<Player>() {
|
object PlayerMoLangFunctions : AbstractMoLangFunctionHolder<Player>() {
|
||||||
override fun Player.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun Player.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val player = this
|
val player = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
map["username"] = { _ -> StringValue(player.gameProfile.name) }
|
|
||||||
map["uuid"] = { _ -> StringValue(player.gameProfile.id.toString()) }
|
functions["username"] = { StringValue(player.gameProfile.name) }
|
||||||
map["main_held_item"] = { _ -> player.mainHandItem.asMoLangValue(player.registryAccess()) }
|
functions["uuid"] = { StringValue(player.gameProfile.id.toString()) }
|
||||||
map["off_held_item"] = { _ -> player.offhandItem.asMoLangValue(player.registryAccess()) }
|
functions["main_held_item"] = { player.mainHandItem.asMoLangValue(player.registryAccess()) }
|
||||||
map["inventory"] = put@{ _ ->
|
functions["off_held_item"] = { player.offhandItem.asMoLangValue(player.registryAccess()) }
|
||||||
|
functions["inventory"] = {
|
||||||
val inventory = player.inventory
|
val inventory = player.inventory
|
||||||
val items = ArrayStruct(hashMapOf())
|
val items = ArrayStruct(hashMapOf())
|
||||||
for (i in 0 until inventory.containerSize) {
|
for (i in 0 until inventory.containerSize) {
|
||||||
items.setDirectly("$i", inventory.getItem(i).asMoLangValue(player.registryAccess()))
|
items.setDirectly("$i", inventory.getItem(i).asMoLangValue(player.registryAccess()))
|
||||||
}
|
}
|
||||||
return@put items
|
items
|
||||||
}
|
}
|
||||||
map["has_inventory_space"] = put@{ _ ->
|
functions["has_inventory_space"] = {
|
||||||
val inventory = player.inventory
|
val inventory = player.inventory
|
||||||
return@put if (inventory.getFreeSlot() != -1) DoubleValue.ONE else DoubleValue.ZERO
|
if (inventory.freeSlot != -1) DoubleValue.ONE else DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
map["set_inventory_slot"] = put@{ params ->
|
functions["set_inventory_slot"] = setInvSlot@{ params ->
|
||||||
val slot = params.getInt(0)
|
val slot = params.getInt(0)
|
||||||
val inventory = player.inventory
|
val inventory = player.inventory
|
||||||
if (slot !in 0 until inventory.containerSize) return@put DoubleValue.ZERO
|
if (slot !in 0 until inventory.containerSize) return@setInvSlot DoubleValue.ZERO
|
||||||
|
|
||||||
val value = params.getOrNull<MoValue>(1) ?: return@put DoubleValue.ZERO
|
val value = params.getOrNull<MoValue>(1) ?: return@setInvSlot DoubleValue.ZERO
|
||||||
|
|
||||||
val stack: ItemStack? = when (value) {
|
val stack: ItemStack? =
|
||||||
is ObjectValue<*> -> value.obj as? ItemStack
|
when (value) {
|
||||||
is StringValue -> {
|
is ObjectValue<*> -> {
|
||||||
val id = ResourceLocation.parse(value.value)
|
value.obj as? ItemStack
|
||||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(id)
|
}
|
||||||
?: return@put DoubleValue.ZERO
|
|
||||||
ItemStack(item)
|
is StringValue -> {
|
||||||
|
val id = ResourceLocation.parse(value.value)
|
||||||
|
val item =
|
||||||
|
player.registryAccess().registryOrThrow(Registries.ITEM).get(id)
|
||||||
|
?: return@setInvSlot DoubleValue.ZERO
|
||||||
|
ItemStack(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
if (stack == null) return@setInvSlot DoubleValue.ZERO
|
||||||
}
|
|
||||||
|
|
||||||
if (stack == null) return@put DoubleValue.ZERO
|
|
||||||
|
|
||||||
inventory.setItem(slot, stack)
|
inventory.setItem(slot, stack)
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["give_item"] = put@{ params ->
|
functions["give_item"] = giveItem@{ params ->
|
||||||
val inventory = player.inventory
|
val inventory = player.inventory
|
||||||
val freeSlot = inventory.getFreeSlot()
|
val freeSlot = inventory.freeSlot
|
||||||
val value = params.getOrNull<MoValue>(0) ?: return@put DoubleValue.ZERO
|
val value = params.getOrNull<MoValue>(0) ?: return@giveItem DoubleValue.ZERO
|
||||||
val dropIfFull = params.getBooleanOrNull(1) ?: false
|
val dropIfFull = params.getBooleanOrNull(1) ?: false
|
||||||
|
|
||||||
val stack: ItemStack? = when (value) {
|
val stack: ItemStack? =
|
||||||
is ObjectValue<*> -> value.obj as? ItemStack
|
when (value) {
|
||||||
is StringValue -> {
|
is ObjectValue<*> -> {
|
||||||
val id = ResourceLocation.parse(value.value)
|
value.obj as? ItemStack
|
||||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(id)
|
}
|
||||||
?: return@put DoubleValue.ZERO
|
|
||||||
ItemStack(item)
|
is StringValue -> {
|
||||||
|
val id = ResourceLocation.parse(value.value)
|
||||||
|
val item =
|
||||||
|
player.registryAccess().registryOrThrow(Registries.ITEM).get(id)
|
||||||
|
?: return@giveItem DoubleValue.ZERO
|
||||||
|
ItemStack(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
if (stack == null) return@giveItem DoubleValue.ZERO
|
||||||
}
|
|
||||||
|
|
||||||
if (stack == null) return@put DoubleValue.ZERO
|
|
||||||
|
|
||||||
if (freeSlot == -1) {
|
if (freeSlot == -1) {
|
||||||
if (dropIfFull) {
|
if (dropIfFull) {
|
||||||
player.drop(stack, false)
|
player.drop(stack, false)
|
||||||
return@put DoubleValue.ONE
|
return@giveItem DoubleValue.ONE
|
||||||
} else {
|
} else {
|
||||||
return@put DoubleValue.ZERO
|
return@giveItem DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inventory.setItem(freeSlot, stack)
|
inventory.setItem(freeSlot, stack)
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["face"] = { params ->
|
functions["face"] = { params ->
|
||||||
ObjectValue(
|
ObjectValue(
|
||||||
PlayerDialogueFaceProvider(
|
PlayerDialogueFaceProvider(
|
||||||
player.uuid,
|
player.uuid,
|
||||||
params.getBooleanOrNull(0) != false
|
params.getBooleanOrNull(0) != false,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
map["swing_hand"] = { _ -> player.swing(player.usedItemHand) }
|
functions["swing_hand"] = { player.swing(player.usedItemHand) }
|
||||||
map["food_level"] = { _ -> DoubleValue(player.foodData.foodLevel) }
|
functions["food_level"] = { DoubleValue(player.foodData.foodLevel) }
|
||||||
map["saturation_level"] = { _ -> DoubleValue(player.foodData.saturationLevel) }
|
functions["saturation_level"] = { DoubleValue(player.foodData.saturationLevel) }
|
||||||
map["tell"] = { params ->
|
functions["tell"] = { params ->
|
||||||
val message = params.getString(0).text()
|
val message = params.getString(0).text()
|
||||||
val overlay = params.getBooleanOrNull(1) == true
|
val overlay = params.getBooleanOrNull(1) == true
|
||||||
player.displayClientMessage(message, overlay)
|
player.displayClientMessage(message, overlay)
|
||||||
}
|
}
|
||||||
map["teleport"] = { params ->
|
functions["teleport"] = { params ->
|
||||||
val x = params.getDouble(0)
|
val x = params.getDouble(0)
|
||||||
val y = params.getDouble(1)
|
val y = params.getDouble(1)
|
||||||
val z = params.getDouble(2)
|
val z = params.getDouble(2)
|
||||||
val playParticleOptionss = params.getBooleanOrNull(3) ?: false
|
val playParticleOptions = params.getBooleanOrNull(3) ?: false
|
||||||
player.randomTeleport(x, y, z, playParticleOptionss)
|
player.randomTeleport(x, y, z, playParticleOptions)
|
||||||
}
|
}
|
||||||
map["heal"] = { params ->
|
functions["heal"] = { params ->
|
||||||
val amount = params.getDoubleOrNull(0) ?: player.maxHealth
|
val amount = params.getDoubleOrNull(0) ?: player.maxHealth
|
||||||
player.heal(amount.toFloat())
|
player.heal(amount.toFloat())
|
||||||
}
|
}
|
||||||
map["environment"] = {
|
functions["environment"] = {
|
||||||
val environment = MoLangEnvironment()
|
val environment = MoLangEnvironment()
|
||||||
environment.query = player.asMoLangValue()
|
environment.query = player.asMoLangValue()
|
||||||
environment
|
environment
|
||||||
}
|
}
|
||||||
map["is_player"] = { DoubleValue.ONE }
|
functions["is_player"] = { DoubleValue.ONE }
|
||||||
map["riding_pokemon"] = put@{
|
functions["riding_pokemon"] = ridingPokemon@{
|
||||||
val vehicle = player.vehicle
|
val vehicle = player.vehicle
|
||||||
if (vehicle is PokemonEntity) {
|
if (vehicle is PokemonEntity) {
|
||||||
return@put vehicle.struct
|
return@ridingPokemon vehicle.struct
|
||||||
} else {
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
}
|
||||||
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
if (player is ServerPlayer) {
|
|
||||||
map["seen_credits"] = { _ ->
|
when (player) {
|
||||||
DoubleValue(player.seenCredits)
|
is ServerPlayer -> {
|
||||||
}
|
functions["seen_credits"] = { DoubleValue(player.seenCredits) }
|
||||||
map["is_in_dialogue"] = { _ ->
|
functions["is_in_dialogue"] = { DoubleValue(player.isInDialogue) }
|
||||||
DoubleValue(player.isInDialogue)
|
functions["active_dialogue"] = activeDialogue@{
|
||||||
}
|
if (player.isInDialogue) {
|
||||||
map["active_dialogue"] = put@{ _ ->
|
return@activeDialogue player.activeDialogue?.toMoLangStruct() ?: DoubleValue.ZERO
|
||||||
if (player.isInDialogue) {
|
}
|
||||||
return@put player.activeDialogue?.toMoLangStruct() ?: DoubleValue.ZERO
|
|
||||||
} else {
|
|
||||||
DoubleValue.ZERO
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
functions["is_spectator"] = { DoubleValue(player.isSpectator) }
|
||||||
map["is_spectator"] = { DoubleValue(player.isSpectator) }
|
functions["is_creative"] = { DoubleValue(player.isCreative) }
|
||||||
map["is_creative"] = { DoubleValue(player.isCreative) }
|
functions["is_survival"] = { DoubleValue(player.gameMode.isSurvival) }
|
||||||
map["is_survival"] = { DoubleValue(player.gameMode.isSurvival) }
|
functions["is_adventure"] = { DoubleValue(player.gameMode.gameModeForPlayer == GameType.ADVENTURE) }
|
||||||
map["is_adventure"] = { DoubleValue(player.gameMode.gameModeForPlayer == GameType.ADVENTURE) }
|
functions["run_command"] = { params ->
|
||||||
map["run_command"] = { params ->
|
val command = params.getString(0)
|
||||||
val command = params.getString(0)
|
player.server.commands.performPrefixedCommand(player.createCommandSourceStack(), command)
|
||||||
player.server.commands.performPrefixedCommand(player.createCommandSourceStack(), command)
|
}
|
||||||
}
|
functions["set_battle_theme"] = { params ->
|
||||||
map["set_battle_theme"] = put@{ params ->
|
val soundId = params.getString(0).asResource()
|
||||||
val soundId = params.getString(0).asResource()
|
Cobblemon.playerDataManager.getGenericData(player).battleTheme = soundId
|
||||||
Cobblemon.playerDataManager.getGenericData(player).battleTheme = soundId
|
DoubleValue.ONE
|
||||||
return@put DoubleValue.ONE
|
}
|
||||||
}
|
functions["battle_music"] = battleMusic@{ params ->
|
||||||
map["battle_music"] = put@{ params ->
|
val soundId = params.getString(0).asResource()
|
||||||
val soundId = params.getString(0).asResource()
|
val volume = params.getDoubleOrNull(1)?.toFloat() ?: 1.0f
|
||||||
val volume = params.getDoubleOrNull(1)?.toFloat() ?: 1.0f
|
val pitch = params.getDoubleOrNull(2)?.toFloat() ?: 1.0f
|
||||||
val pitch = params.getDoubleOrNull(2)?.toFloat() ?: 1.0f
|
val restart = params.getBooleanOrNull(3) ?: true
|
||||||
val restart = params.getBooleanOrNull(3) ?: true
|
|
||||||
|
|
||||||
if (soundId != null) {
|
if (soundId != null) {
|
||||||
val packet = BattleMusicPacket(soundId, volume, pitch, restart)
|
val packet = BattleMusicPacket(soundId, volume, pitch, restart)
|
||||||
|
packet.sendToPlayer(player)
|
||||||
|
return@battleMusic DoubleValue.ONE
|
||||||
|
}
|
||||||
|
DoubleValue.ZERO
|
||||||
|
}
|
||||||
|
functions["stop_battle_music"] = {
|
||||||
|
val packet = BattleMusicPacket(null)
|
||||||
packet.sendToPlayer(player)
|
packet.sendToPlayer(player)
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
} else {
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
}
|
||||||
}
|
functions["play_sound_on_server"] = { params ->
|
||||||
map["stop_battle_music"] = put@{ _ ->
|
val sound = params.getString(0).asResource()
|
||||||
val packet = BattleMusicPacket(null)
|
val soundSource = SoundSource.valueOf(params.getString(1).uppercase())
|
||||||
packet.sendToPlayer(player)
|
val volume = params.getDoubleOrNull(2)?.toFloat() ?: 1.0f
|
||||||
return@put DoubleValue.ONE
|
val pitch = params.getDoubleOrNull(3)?.toFloat() ?: 1.0f
|
||||||
}
|
|
||||||
map["play_sound_on_server"] = { params ->
|
|
||||||
val sound = params.getString(0).asResource()
|
|
||||||
val soundSource = SoundSource.valueOf(params.getString(1).uppercase())
|
|
||||||
val volume = params.getDoubleOrNull(2)?.toFloat() ?: 1.0f
|
|
||||||
val pitch = params.getDoubleOrNull(3)?.toFloat() ?: 1.0f
|
|
||||||
|
|
||||||
val packet =
|
val packet =
|
||||||
UnvalidatedPlaySoundS2CPacket(sound, soundSource, player.x, player.y, player.z, volume, pitch)
|
UnvalidatedPlaySoundS2CPacket(
|
||||||
packet.sendToPlayer(player)
|
sound,
|
||||||
}
|
soundSource,
|
||||||
map["is_party_at_full_health"] = { _ ->
|
player.x,
|
||||||
DoubleValue(player.party().none(Pokemon::canBeHealed))
|
player.y,
|
||||||
}
|
player.z,
|
||||||
map["can_heal_at_healer"] = put@{ params ->
|
volume,
|
||||||
val pos = params.get<ArrayStruct>(0).asBlockPos()
|
pitch,
|
||||||
val healer = player.level().getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null)
|
)
|
||||||
?: return@put DoubleValue.ZERO
|
|
||||||
val party = player.party()
|
packet.sendToPlayer(player)
|
||||||
return@put DoubleValue(healer.canHeal(party))
|
|
||||||
}
|
|
||||||
map["put_pokemon_in_healer"] = put@{ params ->
|
|
||||||
val healer = player.level()
|
|
||||||
.getBlockEntity(params.get<ArrayStruct>(0).asBlockPos(), CobblemonBlockEntities.HEALING_MACHINE)
|
|
||||||
.orElse(null) ?: return@put DoubleValue.ZERO
|
|
||||||
val party = player.party()
|
|
||||||
if (healer.canHeal(party)) {
|
|
||||||
healer.activate(player.uuid, party)
|
|
||||||
return@put DoubleValue.ONE
|
|
||||||
} else {
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
}
|
||||||
}
|
functions["is_party_at_full_health"] = { DoubleValue(player.party().none(Pokemon::canBeHealed)) }
|
||||||
map["party"] = { player.party().struct }
|
functions["can_heal_at_healer"] = canHealAtHealer@{ params ->
|
||||||
map["pc"] = { player.pc().struct }
|
val pos = params.get<ArrayStruct>(0).asBlockPos()
|
||||||
map["has_permission"] = { params ->
|
val healer =
|
||||||
DoubleValue(
|
player.level().getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null)
|
||||||
Cobblemon.permissionValidator.hasPermission(
|
?: return@canHealAtHealer DoubleValue.ZERO
|
||||||
player,
|
val party = player.party()
|
||||||
params.getString(0),
|
DoubleValue(healer.canHeal(party))
|
||||||
params.getIntOrNull(1) ?: 4
|
}
|
||||||
|
functions["put_pokemon_in_healer"] = putPokemonAtHealer@{ params ->
|
||||||
|
val healer =
|
||||||
|
player
|
||||||
|
.level()
|
||||||
|
.getBlockEntity(
|
||||||
|
params.get<ArrayStruct>(0).asBlockPos(),
|
||||||
|
CobblemonBlockEntities.HEALING_MACHINE,
|
||||||
|
).orElse(null) ?: return@putPokemonAtHealer DoubleValue.ZERO
|
||||||
|
val party = player.party()
|
||||||
|
if (healer.canHeal(party)) {
|
||||||
|
healer.activate(player.uuid, party)
|
||||||
|
return@putPokemonAtHealer DoubleValue.ONE
|
||||||
|
}
|
||||||
|
DoubleValue.ZERO
|
||||||
|
}
|
||||||
|
functions["party"] = { player.party().struct }
|
||||||
|
functions["pc"] = { player.pc().struct }
|
||||||
|
functions["has_permission"] = { params ->
|
||||||
|
DoubleValue(
|
||||||
|
Cobblemon.permissionValidator.hasPermission(
|
||||||
|
player,
|
||||||
|
params.getString(0),
|
||||||
|
params.getIntOrNull(1) ?: 4,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
functions["data"] = { params -> Cobblemon.molangData.load(player.uuid, params.getStringOrNull(0)) }
|
||||||
map["data"] = { params -> Cobblemon.molangData.load(player.uuid, params.getStringOrNull(0)) }
|
functions["save_data"] = { params -> Cobblemon.molangData.save(player.uuid, params.getStringOrNull(0)) }
|
||||||
map["save_data"] = { params -> Cobblemon.molangData.save(player.uuid, params.getStringOrNull(0)) }
|
functions["in_battle"] = { DoubleValue(player.isInBattle()) }
|
||||||
map["in_battle"] = { DoubleValue(player.isInBattle()) }
|
functions["battle"] = { player.getBattleState()?.first?.struct ?: DoubleValue.ZERO }
|
||||||
map["battle"] = { player.getBattleState()?.first?.struct ?: DoubleValue.ZERO }
|
functions["get_npc_data"] = getNpcData@{ params ->
|
||||||
map["get_npc_data"] = put@{ params ->
|
val npcId =
|
||||||
val npcId = ((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
|
((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
|
||||||
?: params.getString(0)
|
?: params.getString(0)
|
||||||
val data = Cobblemon.molangData.load(player.uuid, params.getStringOrNull(1))
|
val data = Cobblemon.molangData.load(player.uuid, params.getStringOrNull(1))
|
||||||
if (data.map.containsKey(npcId)) {
|
if (data.map.containsKey(npcId)) {
|
||||||
return@put data.map[npcId]!!
|
return@getNpcData data.map[npcId]!!
|
||||||
} else {
|
}
|
||||||
|
|
||||||
val vars = VariableStruct()
|
val vars = VariableStruct()
|
||||||
data.map[npcId] = vars
|
data.map[npcId] = vars
|
||||||
return@put vars
|
vars
|
||||||
}
|
}
|
||||||
}
|
functions["get_npc_variable"] = getNpcVariable@{ params ->
|
||||||
map["get_npc_variable"] = put@{ params ->
|
val npcId =
|
||||||
val npcId = ((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
|
((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
|
||||||
?: params.getString(0)
|
?: params.getString(0)
|
||||||
val variable = params.getString(1)
|
val variable = params.getString(1)
|
||||||
val data = Cobblemon.molangData.load(player.uuid, params.getStringOrNull(2))
|
val data = Cobblemon.molangData.load(player.uuid, params.getStringOrNull(2))
|
||||||
if (data.map.containsKey(npcId)) {
|
if (data.map.containsKey(npcId)) {
|
||||||
return@put (data.map[npcId] as VariableStruct).map[variable] ?: DoubleValue.ZERO
|
return@getNpcVariable (data.map[npcId] as VariableStruct).map[variable] ?: DoubleValue.ZERO
|
||||||
} else {
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
map["set_npc_variable"] = put@{ params ->
|
|
||||||
val npcId = ((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
|
|
||||||
?: params.getString(0)
|
|
||||||
val variable = params.getString(1)
|
|
||||||
val value = params.get<MoValue>(2)
|
|
||||||
val saveAfterwards = params.getBooleanOrNull(3) != false
|
|
||||||
val path = params.getStringOrNull(4)
|
|
||||||
val data = Cobblemon.molangData.load(player.uuid, path)
|
|
||||||
val npcData = data.map.getOrPut(npcId) { VariableStruct() } as VariableStruct
|
|
||||||
npcData.map[variable] = value
|
|
||||||
if (saveAfterwards) {
|
|
||||||
Cobblemon.molangData.save(player.uuid, path)
|
|
||||||
}
|
|
||||||
return@put DoubleValue.ONE
|
|
||||||
}
|
|
||||||
map["pokedex"] = { player.pokedex().struct }
|
|
||||||
map["has_advancement"] = put@{ params ->
|
|
||||||
val requiredAdvancement = ResourceLocation.parse(params.getString(0))
|
|
||||||
for (entry in player.advancements.progress) {
|
|
||||||
if (entry.key.id == requiredAdvancement && entry.value.isDone) {
|
|
||||||
return@put DoubleValue.ONE
|
|
||||||
}
|
}
|
||||||
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
return@put DoubleValue.ZERO
|
functions["set_npc_variable"] = { params ->
|
||||||
}
|
val npcId =
|
||||||
map["has_tm_move_unlocked"] = put@{ params ->
|
((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
|
||||||
val move = Moves.getByName(params.getString(0)) ?: return@put DoubleValue.ZERO
|
?: params.getString(0)
|
||||||
val tm = TechnicalMachines.moveToTM[move] ?: return@put DoubleValue.ZERO
|
val variable = params.getString(1)
|
||||||
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
|
val value = params.get<MoValue>(2)
|
||||||
}
|
val saveAfterwards = params.getBooleanOrNull(3) != false
|
||||||
map["unlock_tm_move"] = put@{ params ->
|
val path = params.getStringOrNull(4)
|
||||||
val move = Moves.getByName(params.getString(0)) ?: return@put DoubleValue.ZERO
|
val data = Cobblemon.molangData.load(player.uuid, path)
|
||||||
val tm = TechnicalMachines.moveToTM[move] ?: return@put DoubleValue.ZERO
|
val npcData = data.map.getOrPut(npcId) { VariableStruct() } as VariableStruct
|
||||||
player.tmList().syncTMFromMove(move)
|
npcData.map[variable] = value
|
||||||
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
|
if (saveAfterwards) {
|
||||||
}
|
Cobblemon.molangData.save(player.uuid, path)
|
||||||
map["lock_tm_move"] = put@{ params ->
|
|
||||||
val move = Moves.getByName(params.getString(0)) ?: return@put DoubleValue.ZERO
|
|
||||||
val tm = TechnicalMachines.moveToTM[move] ?: return@put DoubleValue.ZERO
|
|
||||||
player.tmList().syncTMLockFromMove(move)
|
|
||||||
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 0.0 else 1.0)
|
|
||||||
}
|
|
||||||
map["start_battle"] = put@{ params ->
|
|
||||||
val opponentValue = params.get<MoValue>(0)
|
|
||||||
val opponent = if (opponentValue is ObjectValue<*>) {
|
|
||||||
opponentValue.obj as ServerPlayer
|
|
||||||
} else {
|
|
||||||
val paramString = opponentValue.asString()
|
|
||||||
val playerUUID = paramString.asUUID
|
|
||||||
if (playerUUID != null) {
|
|
||||||
server()?.playerList?.getPlayer(playerUUID) ?: return@put DoubleValue.ZERO
|
|
||||||
} else {
|
|
||||||
server()?.playerList?.getPlayerByName(paramString) ?: return@put DoubleValue.ZERO
|
|
||||||
}
|
}
|
||||||
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
val format = params.getStringOrNull(1)
|
functions["pokedex"] = { player.pokedex().struct }
|
||||||
?.let(BattleFormat::fromFormatIdentifier)
|
functions["has_advancement"] = hasAdvancement@{ params ->
|
||||||
?: BattleFormat.GEN_9_SINGLES
|
val requiredAdvancement = ResourceLocation.parse(params.getString(0))
|
||||||
|
player.advancements.progress.forEach { (holder, progress) ->
|
||||||
|
if (holder.id == requiredAdvancement && progress.isDone) {
|
||||||
|
return@hasAdvancement DoubleValue.ONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DoubleValue.ZERO
|
||||||
|
}
|
||||||
|
functions["has_tm_move_unlocked"] = hasTmMoveUnlocked@{ params ->
|
||||||
|
val move = Moves.getByName(params.getString(0)) ?: return@hasTmMoveUnlocked DoubleValue.ZERO
|
||||||
|
val tm = TechnicalMachines.moveToTM[move] ?: return@hasTmMoveUnlocked DoubleValue.ZERO
|
||||||
|
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
|
||||||
|
}
|
||||||
|
functions["unlock_tm_move"] = unlockTmMove@{ params ->
|
||||||
|
val move = Moves.getByName(params.getString(0)) ?: return@unlockTmMove DoubleValue.ZERO
|
||||||
|
val tm = TechnicalMachines.moveToTM[move] ?: return@unlockTmMove DoubleValue.ZERO
|
||||||
|
player.tmList().syncTMFromMove(move)
|
||||||
|
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
|
||||||
|
}
|
||||||
|
functions["lock_tm_move"] = lockTmMove@{ params ->
|
||||||
|
val move = Moves.getByName(params.getString(0)) ?: return@lockTmMove DoubleValue.ZERO
|
||||||
|
val tm = TechnicalMachines.moveToTM[move] ?: return@lockTmMove DoubleValue.ZERO
|
||||||
|
player.tmList().syncTMLockFromMove(move)
|
||||||
|
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 0.0 else 1.0)
|
||||||
|
}
|
||||||
|
functions["start_battle"] = startBattle@{ params ->
|
||||||
|
val opponentValue = params.get<MoValue>(0)
|
||||||
|
val opponent =
|
||||||
|
if (opponentValue is ObjectValue<*>) {
|
||||||
|
opponentValue.obj as ServerPlayer
|
||||||
|
} else {
|
||||||
|
val paramString = opponentValue.asString()
|
||||||
|
val playerUUID = paramString.asUUID
|
||||||
|
if (playerUUID != null) {
|
||||||
|
server()?.playerList?.getPlayer(playerUUID) ?: return@startBattle DoubleValue.ZERO
|
||||||
|
} else {
|
||||||
|
server()?.playerList?.getPlayerByName(paramString)
|
||||||
|
?: return@startBattle DoubleValue.ZERO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val format =
|
||||||
|
params
|
||||||
|
.getStringOrNull(1)
|
||||||
|
?.let(BattleFormat::fromFormatIdentifier)
|
||||||
|
?: BattleFormat.GEN_9_SINGLES
|
||||||
|
|
||||||
val setLevel = params.getIntOrNull(2) ?: -1
|
val setLevel = params.getIntOrNull(2) ?: -1
|
||||||
format.adjustLevel = setLevel
|
format.adjustLevel = setLevel
|
||||||
|
|
||||||
val rules = params.getStringOrNull(5)
|
val rules =
|
||||||
?.split(",")
|
params
|
||||||
?.toSet()
|
.getStringOrNull(5)
|
||||||
?: emptySet()
|
?.split(",")
|
||||||
|
?.toSet()
|
||||||
|
?: emptySet()
|
||||||
|
|
||||||
val modifiedBattleFormat = BattleFormat.setBattleRules(
|
val modifiedBattleFormat =
|
||||||
battleFormat = format,
|
BattleFormat.setBattleRules(
|
||||||
rules = rules
|
battleFormat = format,
|
||||||
)
|
rules = rules,
|
||||||
|
)
|
||||||
|
|
||||||
val cloneParties = (setLevel != -1) || (params.getBooleanOrNull(3) ?: false)
|
val cloneParties = (setLevel != -1) || (params.getBooleanOrNull(3) ?: false)
|
||||||
val healFirst = params.getBooleanOrNull(4) ?: false
|
val healFirst = params.getBooleanOrNull(4) ?: false
|
||||||
|
|
||||||
val battleStartResult = BattleBuilder.pvp1v1(
|
val battleStartResult =
|
||||||
player1 = player,
|
BattleBuilder.pvp1v1(
|
||||||
player2 = opponent,
|
player1 = player,
|
||||||
battleFormat = modifiedBattleFormat,
|
player2 = opponent,
|
||||||
cloneParties = cloneParties,
|
battleFormat = modifiedBattleFormat,
|
||||||
healFirst = healFirst
|
cloneParties = cloneParties,
|
||||||
)
|
healFirst = healFirst,
|
||||||
var returnValue: MoValue = DoubleValue.ZERO
|
)
|
||||||
battleStartResult.ifSuccessful { returnValue = it.struct }
|
var returnValue: MoValue = DoubleValue.ZERO
|
||||||
return@put returnValue
|
battleStartResult.ifSuccessful { returnValue = it.struct }
|
||||||
|
returnValue
|
||||||
|
}
|
||||||
|
functions["get_custom_stat"] = getCustomStat@{ params ->
|
||||||
|
val statName = params.getString(0)
|
||||||
|
|
||||||
|
val resourceLocation = ResourceLocation.tryParse(statName) ?: return@getCustomStat DoubleValue.ZERO
|
||||||
|
val statResourceLocation =
|
||||||
|
BuiltInRegistries.CUSTOM_STAT.get(resourceLocation) ?: return@getCustomStat DoubleValue.ZERO
|
||||||
|
|
||||||
|
val exists = Stats.CUSTOM.contains(statResourceLocation)
|
||||||
|
if (!exists) return@getCustomStat DoubleValue.ZERO
|
||||||
|
|
||||||
|
val stat = Stats.CUSTOM.get(statResourceLocation)
|
||||||
|
val value = player.stats.getValue(stat)
|
||||||
|
|
||||||
|
DoubleValue(value)
|
||||||
|
}
|
||||||
|
functions["get_starter_uuid"] = {
|
||||||
|
Cobblemon.playerDataManager.getGenericData(player).starterUUID?.let {
|
||||||
|
StringValue(
|
||||||
|
it.toString(),
|
||||||
|
)
|
||||||
|
} ?: DoubleValue.ZERO
|
||||||
|
}
|
||||||
|
functions["has_chosen_starter"] = {
|
||||||
|
DoubleValue(Cobblemon.playerDataManager.getGenericData(player).starterSelected)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
map["get_custom_stat"] = put@{ params ->
|
|
||||||
val statName = params.getString(0)
|
|
||||||
|
|
||||||
val resourceLocation = ResourceLocation.tryParse(statName) ?: return@put DoubleValue.ZERO
|
|
||||||
val statResourceLocation =
|
|
||||||
BuiltInRegistries.CUSTOM_STAT.get(resourceLocation) ?: return@put DoubleValue.ZERO
|
|
||||||
|
|
||||||
val exists = net.minecraft.stats.Stats.CUSTOM.contains(statResourceLocation)
|
|
||||||
if (!exists) return@put DoubleValue.ZERO
|
|
||||||
|
|
||||||
val stat = net.minecraft.stats.Stats.CUSTOM.get(statResourceLocation)
|
|
||||||
val value = player.stats.getValue(stat)
|
|
||||||
|
|
||||||
DoubleValue(value)
|
|
||||||
}
|
|
||||||
map["get_starter_uuid"] = { _ ->
|
|
||||||
Cobblemon.playerDataManager.getGenericData(player).starterUUID?.let {
|
|
||||||
StringValue(
|
|
||||||
it.toString()
|
|
||||||
)
|
|
||||||
} ?: DoubleValue.ZERO
|
|
||||||
}
|
|
||||||
map["has_chosen_starter"] = { _ -> DoubleValue(Cobblemon.playerDataManager.getGenericData(player).starterSelected) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return map
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-37
@@ -27,57 +27,69 @@ import com.cobblemon.mod.common.util.getStringOrNull
|
|||||||
object PokedexMoLangFunctions : AbstractMoLangFunctionHolder<AbstractPokedexManager>() {
|
object PokedexMoLangFunctions : AbstractMoLangFunctionHolder<AbstractPokedexManager>() {
|
||||||
override fun AbstractPokedexManager.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun AbstractPokedexManager.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val pokedex = this
|
val pokedex = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
map["get_species_record"] = { params ->
|
|
||||||
|
functions["get_species_record"] = { params ->
|
||||||
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
|
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
pokedex.speciesRecords[speciesId]?.struct ?: QueryStruct(hashMapOf())
|
pokedex.speciesRecords[speciesId]?.struct ?: QueryStruct(hashMapOf())
|
||||||
}
|
}
|
||||||
|
|
||||||
map["has_seen"] = put@{ params ->
|
functions["has_seen"] = hasSeen@{ params ->
|
||||||
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
|
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val formName = params.getStringOrNull(1)
|
val formName =
|
||||||
|
params.getStringOrNull(1)
|
||||||
|
?: return@hasSeen DoubleValue(
|
||||||
|
pokedex.getHighestKnowledgeForSpecies(speciesId).ordinal >= PokedexEntryProgress.SEEN.ordinal,
|
||||||
|
)
|
||||||
|
|
||||||
if (formName == null) {
|
DoubleValue(
|
||||||
return@put DoubleValue(pokedex.getHighestKnowledgeForSpecies(speciesId).ordinal >= PokedexEntryProgress.SEEN.ordinal)
|
(
|
||||||
} else {
|
pokedex
|
||||||
return@put DoubleValue(
|
.getSpeciesRecord(speciesId)
|
||||||
(pokedex.getSpeciesRecord(speciesId)?.getFormRecord(formName)?.knowledge?.ordinal
|
?.getFormRecord(formName)
|
||||||
?: 0) >= PokedexEntryProgress.SEEN.ordinal
|
?.knowledge
|
||||||
)
|
?.ordinal
|
||||||
}
|
?: 0
|
||||||
|
) >= PokedexEntryProgress.SEEN.ordinal,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
map["has_caught"] = put@{ params ->
|
functions["has_caught"] = hasCaught@{ params ->
|
||||||
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
|
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val formName = params.getStringOrNull(1)
|
val formName =
|
||||||
if (formName == null) {
|
params.getStringOrNull(1) ?: return@hasCaught DoubleValue(
|
||||||
return@put DoubleValue(pokedex.getHighestKnowledgeForSpecies(speciesId) == PokedexEntryProgress.OWNED)
|
pokedex.getHighestKnowledgeForSpecies(
|
||||||
} else {
|
speciesId,
|
||||||
return@put DoubleValue(
|
) == PokedexEntryProgress.OWNED,
|
||||||
pokedex.getSpeciesRecord(speciesId)
|
|
||||||
?.getFormRecord(formName)?.knowledge == PokedexEntryProgress.OWNED
|
|
||||||
)
|
)
|
||||||
}
|
DoubleValue(
|
||||||
|
pokedex
|
||||||
|
.getSpeciesRecord(speciesId)
|
||||||
|
?.getFormRecord(formName)
|
||||||
|
?.knowledge == PokedexEntryProgress.OWNED,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
map["caught_count"] = { DoubleValue(pokedex.getGlobalCalculatedValue(CaughtCount)) }
|
functions["caught_count"] = { DoubleValue(pokedex.getGlobalCalculatedValue(CaughtCount)) }
|
||||||
map["seen_count"] = { DoubleValue(pokedex.getGlobalCalculatedValue(SeenCount)) }
|
functions["seen_count"] = { DoubleValue(pokedex.getGlobalCalculatedValue(SeenCount)) }
|
||||||
map["caught_percent"] = { DoubleValue(pokedex.getGlobalCalculatedValue(CaughtPercent)) }
|
functions["caught_percent"] = { DoubleValue(pokedex.getGlobalCalculatedValue(CaughtPercent)) }
|
||||||
map["seen_percent"] = { DoubleValue(pokedex.getGlobalCalculatedValue(SeenPercent)) }
|
functions["seen_percent"] = { DoubleValue(pokedex.getGlobalCalculatedValue(SeenPercent)) }
|
||||||
|
|
||||||
if (pokedex is PokedexManager) {
|
when (pokedex) {
|
||||||
map["player_id"] = { StringValue(pokedex.uuid.toString()) }
|
is PokedexManager -> {
|
||||||
map["see"] = put@{ params ->
|
functions["player_id"] = { StringValue(pokedex.uuid.toString()) }
|
||||||
val pokemon = params.get<ObjectValue<Pokemon>>(0).obj
|
functions["see"] = { params ->
|
||||||
pokedex.encounter(pokemon)
|
val pokemon = params.get<ObjectValue<Pokemon>>(0).obj
|
||||||
return@put DoubleValue.ONE
|
pokedex.encounter(pokemon)
|
||||||
}
|
DoubleValue.ONE
|
||||||
map["catch"] = put@{ params ->
|
}
|
||||||
val pokemon = params.get<ObjectValue<Pokemon>>(0).obj
|
functions["catch"] = { params ->
|
||||||
pokedex.obtain(pokemon)
|
val pokemon = params.get<ObjectValue<Pokemon>>(0).obj
|
||||||
return@put DoubleValue.ONE
|
pokedex.obtain(pokemon)
|
||||||
|
DoubleValue.ONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return map
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-40
@@ -32,100 +32,113 @@ import com.cobblemon.mod.common.util.withQueryValue
|
|||||||
object PokemonEntityMoLangFunctions : AbstractMoLangFunctionHolder<PokemonEntity>() {
|
object PokemonEntityMoLangFunctions : AbstractMoLangFunctionHolder<PokemonEntity>() {
|
||||||
override fun PokemonEntity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun PokemonEntity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val pokemonEntity = this
|
val pokemonEntity = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
map["is_busy"] = { DoubleValue(pokemonEntity.isBusy) }
|
|
||||||
map["in_battle"] = { DoubleValue(pokemonEntity.isBattling) }
|
functions["is_busy"] = { DoubleValue(pokemonEntity.isBusy) }
|
||||||
map["is_moving"] = { DoubleValue((pokemonEntity.moveControl as? PokemonMoveControl)?.hasWanted() == true) }
|
functions["in_battle"] = { DoubleValue(pokemonEntity.isBattling) }
|
||||||
map["is_flying"] = { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
|
functions["is_moving"] =
|
||||||
map["get_riding_state"] = { params ->
|
{ DoubleValue((pokemonEntity.moveControl as? PokemonMoveControl)?.hasWanted() == true) }
|
||||||
|
functions["is_flying"] = { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
|
||||||
|
functions["get_riding_state"] = { params ->
|
||||||
val name = params.getStringOrNull(0)
|
val name = params.getStringOrNull(0)
|
||||||
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
||||||
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
||||||
return@ifRidingAvailableSupply moValue.functions[name]?.apply(MoParams.EMPTY) as? MoValue ?: moValue
|
return@ifRidingAvailableSupply moValue.functions[name]?.apply(MoParams.EMPTY) as? MoValue ?: moValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["is_gliding"] = {
|
functions["is_gliding"] = {
|
||||||
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
||||||
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
||||||
return@ifRidingAvailableSupply moValue.functions["gliding"]?.apply(MoParams.EMPTY) as? MoValue
|
return@ifRidingAvailableSupply moValue.functions["gliding"]?.apply(MoParams.EMPTY) as? MoValue
|
||||||
?: DoubleValue.ZERO
|
?: DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["is_sprinting"] = {
|
functions["is_sprinting"] = {
|
||||||
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
||||||
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
||||||
return@ifRidingAvailableSupply moValue.functions["sprinting"]?.apply(MoParams.EMPTY) as? MoValue
|
return@ifRidingAvailableSupply moValue.functions["sprinting"]?.apply(MoParams.EMPTY) as? MoValue
|
||||||
?: DoubleValue.ZERO
|
?: DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["is_drifting"] = {
|
functions["is_drifting"] = {
|
||||||
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
||||||
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
||||||
return@ifRidingAvailableSupply moValue.functions["drifting"]?.apply(MoParams.EMPTY) as? MoValue
|
return@ifRidingAvailableSupply moValue.functions["drifting"]?.apply(MoParams.EMPTY) as? MoValue
|
||||||
?: DoubleValue.ZERO
|
?: DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["is_powered_drifting"] = {
|
functions["is_powered_drifting"] = {
|
||||||
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
||||||
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
||||||
return@ifRidingAvailableSupply moValue.functions["powered_drifting"]?.apply(MoParams.EMPTY) as? MoValue
|
return@ifRidingAvailableSupply moValue.functions["powered_drifting"]?.apply(MoParams.EMPTY) as? MoValue
|
||||||
?: DoubleValue.ZERO
|
?: DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["in_air"] = {
|
functions["in_air"] = {
|
||||||
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
|
||||||
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
|
||||||
return@ifRidingAvailableSupply moValue.functions["in_air"]?.apply(MoParams.EMPTY) as? MoValue
|
return@ifRidingAvailableSupply moValue.functions["in_air"]?.apply(MoParams.EMPTY) as? MoValue
|
||||||
?: DoubleValue.ZERO
|
?: DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["is_wild"] = { DoubleValue(pokemonEntity.ownerUUID == null) }
|
functions["is_wild"] = { DoubleValue(pokemonEntity.ownerUUID == null) }
|
||||||
map["is_in_party"] = { DoubleValue(pokemonEntity.pokemon.storeCoordinates.get()?.store is PartyStore) }
|
functions["is_in_party"] = {
|
||||||
map["is_ridden"] = { DoubleValue(pokemonEntity.hasControllingPassenger()) }
|
DoubleValue(
|
||||||
map["has_aspect"] = { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
|
pokemonEntity.pokemon.storeCoordinates
|
||||||
map["is_pokemon"] = { DoubleValue.ONE }
|
.get()
|
||||||
map["is_holding_item"] = {
|
?.store is PartyStore,
|
||||||
DoubleValue(!pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).let {
|
)
|
||||||
it.isEmpty || it.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS) || it.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
map["riding_style"] = {
|
functions["is_ridden"] = { DoubleValue(pokemonEntity.hasControllingPassenger()) }
|
||||||
StringValue(pokemonEntity.ifRidingAvailableSupply("") { behaviour, settings, state ->
|
functions["has_aspect"] = { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
|
||||||
behaviour.getRidingStyle(settings, state).name
|
functions["is_pokemon"] = { DoubleValue.ONE }
|
||||||
})
|
functions["is_holding_item"] = {
|
||||||
|
DoubleValue(
|
||||||
|
!pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).let {
|
||||||
|
it.isEmpty || it.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS) || it.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
map["is_wearing_hat"] = {
|
functions["riding_style"] = {
|
||||||
|
StringValue(
|
||||||
|
pokemonEntity.ifRidingAvailableSupply("") { behaviour, settings, state ->
|
||||||
|
behaviour.getRidingStyle(settings, state).name
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
functions["is_wearing_hat"] = {
|
||||||
DoubleValue(
|
DoubleValue(
|
||||||
pokemonEntity.entityData
|
pokemonEntity.entityData
|
||||||
.get(PokemonEntity.SHOWN_HELD_ITEM)
|
.get(PokemonEntity.SHOWN_HELD_ITEM)
|
||||||
.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS)
|
.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
map["is_wearing_face"] = {
|
functions["is_wearing_face"] = {
|
||||||
DoubleValue(
|
DoubleValue(
|
||||||
pokemonEntity.entityData
|
pokemonEntity.entityData
|
||||||
.get(PokemonEntity.SHOWN_HELD_ITEM)
|
.get(PokemonEntity.SHOWN_HELD_ITEM)
|
||||||
.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
|
.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
map["is_pastured"] = {
|
functions["is_pastured"] = {
|
||||||
DoubleValue((pokemonEntity.tethering != null))
|
DoubleValue((pokemonEntity.tethering != null))
|
||||||
}
|
}
|
||||||
map["pasture_conflict_enabled"] = {
|
functions["pasture_conflict_enabled"] = {
|
||||||
DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.PASTURE_CONFLICT))
|
DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.PASTURE_CONFLICT))
|
||||||
}
|
}
|
||||||
map["run_action_effect"] = runActionEffect@{ params ->
|
functions["run_action_effect"] = runActionEffect@{ params ->
|
||||||
val runtime = MoLangRuntime().setup()
|
val runtime = MoLangRuntime().setup()
|
||||||
runtime.environment.cloneFrom(params.environment)
|
runtime.environment.cloneFrom(params.environment)
|
||||||
runtime.withQueryValue("entity", pokemonEntity.struct)
|
runtime.withQueryValue("entity", pokemonEntity.struct)
|
||||||
val actionEffect = ActionEffects.actionEffects[params.getString(0).asIdentifierDefaultingNamespace()]
|
val actionEffect = ActionEffects.actionEffects[params.getString(0).asIdentifierDefaultingNamespace()]
|
||||||
if (actionEffect != null) {
|
if (actionEffect != null) {
|
||||||
val context = ActionEffectContext(
|
val context =
|
||||||
actionEffect = actionEffect,
|
ActionEffectContext(
|
||||||
providers = mutableListOf(TargetsProvider(pokemonEntity)),
|
actionEffect = actionEffect,
|
||||||
runtime = runtime,
|
providers = mutableListOf(TargetsProvider(pokemonEntity)),
|
||||||
level = pokemonEntity.level()
|
runtime = runtime,
|
||||||
)
|
level = pokemonEntity.level(),
|
||||||
|
)
|
||||||
// This was taken from NPC run_action_effect but this variable isn't used, so I just commented it out.
|
// This was taken from NPC run_action_effect but this variable isn't used, so I just commented it out.
|
||||||
// pokemonEntity.actionEffect = context
|
// pokemonEntity.actionEffect = context
|
||||||
pokemonEntity.brain.setMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT, context)
|
pokemonEntity.brain.setMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT, context)
|
||||||
@@ -135,14 +148,16 @@ object PokemonEntityMoLangFunctions : AbstractMoLangFunctionHolder<PokemonEntity
|
|||||||
pokemonEntity.brain.getMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT).orElse(null)
|
pokemonEntity.brain.getMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT).orElse(null)
|
||||||
if (pokemonActionEffect == context && pokemonEntity.brain.isActive(CobblemonActivities.ACTION_EFFECT)) {
|
if (pokemonActionEffect == context && pokemonEntity.brain.isActive(CobblemonActivities.ACTION_EFFECT)) {
|
||||||
pokemonEntity.brain.eraseMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT)
|
pokemonEntity.brain.eraseMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT)
|
||||||
//pokemonEntity.actionEffect = null
|
// pokemonEntity.actionEffect = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return@runActionEffect DoubleValue.ONE
|
return@runActionEffect DoubleValue.ONE
|
||||||
}
|
}
|
||||||
return@runActionEffect DoubleValue.ZERO
|
|
||||||
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
return map
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+129
-128
@@ -33,218 +33,214 @@ import com.cobblemon.mod.common.util.getDoubleOrNull
|
|||||||
import com.cobblemon.mod.common.util.getIntOrNull
|
import com.cobblemon.mod.common.util.getIntOrNull
|
||||||
import com.cobblemon.mod.common.util.server
|
import com.cobblemon.mod.common.util.server
|
||||||
import com.cobblemon.mod.common.util.toProperties
|
import com.cobblemon.mod.common.util.toProperties
|
||||||
import kotlin.random.Random
|
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
||||||
override fun Pokemon.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun Pokemon.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val pokemon = this
|
val pokemon = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
map["id"] = { StringValue(pokemon.uuid.toString()) }
|
|
||||||
map["nickname"] = { StringValue(pokemon.nickname.toString()) }
|
functions["id"] = { StringValue(pokemon.uuid.toString()) }
|
||||||
map["level"] = { DoubleValue(pokemon.level.toDouble()) }
|
functions["nickname"] = { StringValue(pokemon.nickname.toString()) }
|
||||||
map["max_hp"] = { DoubleValue(pokemon.maxHealth.toDouble()) }
|
functions["level"] = { DoubleValue(pokemon.level.toDouble()) }
|
||||||
map["current_hp"] = { DoubleValue(pokemon.currentHealth.toDouble()) }
|
functions["max_hp"] = { DoubleValue(pokemon.maxHealth.toDouble()) }
|
||||||
map["friendship"] = { DoubleValue(pokemon.friendship.toDouble()) }
|
functions["current_hp"] = { DoubleValue(pokemon.currentHealth.toDouble()) }
|
||||||
map["max_fullness"] = { DoubleValue(pokemon.getMaxFullness().toDouble()) }
|
functions["friendship"] = { DoubleValue(pokemon.friendship.toDouble()) }
|
||||||
map["fullness"] = { DoubleValue(pokemon.currentFullness.toDouble()) }
|
functions["max_fullness"] = { DoubleValue(pokemon.getMaxFullness().toDouble()) }
|
||||||
map["lose_fullness"] = { params ->
|
functions["fullness"] = { DoubleValue(pokemon.currentFullness.toDouble()) }
|
||||||
|
functions["lose_fullness"] = { params ->
|
||||||
val amount = params.getDouble(0)
|
val amount = params.getDouble(0)
|
||||||
pokemon.loseFullness(amount.toInt())
|
pokemon.loseFullness(amount.toInt())
|
||||||
}
|
}
|
||||||
map["feed_pokemon"] = { params ->
|
functions["feed_pokemon"] = { params ->
|
||||||
val amount = params.getDouble(0)
|
val amount = params.getDouble(0)
|
||||||
val playSound = params.getBooleanOrNull(1) ?: true
|
val playSound = params.getBooleanOrNull(1) ?: true
|
||||||
pokemon.feedPokemon(amount.toInt(), playSound)
|
pokemon.feedPokemon(amount.toInt(), playSound)
|
||||||
}
|
}
|
||||||
map["behaviour"] = { pokemon.form.behaviour.struct }
|
functions["behaviour"] = { pokemon.form.behaviour.struct }
|
||||||
map["behavior"] = { pokemon.form.behaviour.struct } // Inferior
|
functions["behavior"] = { pokemon.form.behaviour.struct } // Inferior
|
||||||
map["pokeball"] = { StringValue(pokemon.caughtBall.toString()) }
|
functions["pokeball"] = { StringValue(pokemon.caughtBall.toString()) }
|
||||||
map["ability"] = { StringValue(pokemon.ability.name) }
|
functions["ability"] = { StringValue(pokemon.ability.name) }
|
||||||
map["has_learned"] = put@{ params ->
|
functions["has_learned"] = hasLearned@{ params ->
|
||||||
val moveName = params.getString(0)
|
val moveName = params.getString(0)
|
||||||
val move = pokemon.allAccessibleMoves.find { it.name == moveName }
|
val move = pokemon.allAccessibleMoves.find { it.name == moveName }
|
||||||
if (move != null) {
|
if (move != null) return@hasLearned DoubleValue.ONE
|
||||||
return@put DoubleValue.ONE
|
DoubleValue.ZERO
|
||||||
} else {
|
|
||||||
return@put DoubleValue.ZERO
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
map["moveset"] = {
|
functions["moveset"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for ((index, move) in pokemon.moveSet.withIndex()) {
|
for ((index, move) in pokemon.moveSet.withIndex()) {
|
||||||
struct.addFunction(index.toString()) { move.struct }
|
struct.addFunction(index.toString()) { move.struct }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["evs"] = {
|
functions["evs"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for (stat in Stats.PERMANENT) {
|
for (stat in Stats.PERMANENT) {
|
||||||
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.evs.getOrDefault(stat).toDouble()) }
|
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.evs.getOrDefault(stat).toDouble()) }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["ivs"] = {
|
functions["ivs"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for (stat in Stats.PERMANENT) {
|
for (stat in Stats.PERMANENT) {
|
||||||
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.ivs.getOrDefault(stat).toDouble()) }
|
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.ivs.getOrDefault(stat).toDouble()) }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["hyper_trained_ivs"] = {
|
functions["hyper_trained_ivs"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for (stat in Stats.PERMANENT) {
|
for (stat in Stats.PERMANENT) {
|
||||||
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.ivs.hyperTrainedIVs[stat] ?: -1.0) }
|
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.ivs.hyperTrainedIVs[stat] ?: -1.0) }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["ride_boosts"] = {
|
functions["ride_boosts"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for (stat in RidingStat.entries) {
|
for (stat in RidingStat.entries) {
|
||||||
struct.addFunction(stat.name.lowercase()) { DoubleValue(pokemon.getRideBoost(stat)) }
|
struct.addFunction(stat.name.lowercase()) { DoubleValue(pokemon.getRideBoost(stat)) }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["natdex_number"] = {
|
functions["natdex_number"] = {
|
||||||
DoubleValue(pokemon.species.nationalPokedexNumber.toDouble())
|
DoubleValue(pokemon.species.nationalPokedexNumber.toDouble())
|
||||||
}
|
}
|
||||||
map["types"] = {
|
functions["types"] = {
|
||||||
pokemon.form.types.map { it.showdownId }.asArrayValue(::StringValue)
|
pokemon.form.types
|
||||||
|
.map { it.showdownId }
|
||||||
|
.asArrayValue(::StringValue)
|
||||||
}
|
}
|
||||||
map["gender_ratio"] = {
|
functions["gender_ratio"] = {
|
||||||
DoubleValue(pokemon.form.maleRatio.toDouble())
|
DoubleValue(pokemon.form.maleRatio.toDouble())
|
||||||
}
|
}
|
||||||
map["ev_yield"] = {
|
functions["ev_yield"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for (stat in Stats.PERMANENT) {
|
for (stat in Stats.PERMANENT) {
|
||||||
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.form.evYield[stat]?.toDouble()) }
|
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.form.evYield[stat]?.toDouble()) }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["base_stats"] = {
|
functions["base_stats"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for (stat in Stats.PERMANENT) {
|
for (stat in Stats.PERMANENT) {
|
||||||
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.form.baseStats[stat]?.toDouble()) }
|
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.form.baseStats[stat]?.toDouble()) }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["catch_rate"] = {
|
functions["catch_rate"] = {
|
||||||
DoubleValue(pokemon.form.catchRate.toDouble())
|
DoubleValue(pokemon.form.catchRate.toDouble())
|
||||||
}
|
}
|
||||||
map["base_experience_yield"] = {
|
functions["base_experience_yield"] = {
|
||||||
DoubleValue(pokemon.form.baseExperienceYield.toDouble())
|
DoubleValue(pokemon.form.baseExperienceYield.toDouble())
|
||||||
}
|
}
|
||||||
map["drops"] = {
|
functions["drops"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for ((index, drop) in pokemon.form.drops.entries.withIndex()) {
|
for ((index, drop) in pokemon.form.drops.entries
|
||||||
|
.withIndex()) {
|
||||||
struct.addFunction(index.toString()) { drop }
|
struct.addFunction(index.toString()) { drop }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["tm_learnset"] = {
|
functions["tm_learnset"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for ((index, move) in pokemon.form.moves.tmMoves.withIndex()) {
|
for ((index, move) in pokemon.form.moves.tmMoves
|
||||||
|
.withIndex()) {
|
||||||
struct.addFunction(index.toString()) { move.struct }
|
struct.addFunction(index.toString()) { move.struct }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["egg_learnset"] = {
|
functions["egg_learnset"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for ((index, move) in pokemon.form.moves.eggMoves.withIndex()) {
|
for ((index, move) in pokemon.form.moves.eggMoves
|
||||||
|
.withIndex()) {
|
||||||
struct.addFunction(index.toString()) { move.struct }
|
struct.addFunction(index.toString()) { move.struct }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["tutor_learnset"] = {
|
functions["tutor_learnset"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for ((index, move) in pokemon.form.moves.tutorMoves.withIndex()) {
|
for ((index, move) in pokemon.form.moves.tutorMoves
|
||||||
|
.withIndex()) {
|
||||||
struct.addFunction(index.toString()) { move.struct }
|
struct.addFunction(index.toString()) { move.struct }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["level_learnset"] = {
|
functions["level_learnset"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for ((index, move) in pokemon.form.moves.levelUpMoves) {
|
for ((index, move) in pokemon.form.moves.levelUpMoves) {
|
||||||
struct.addFunction(index.toString()) { move }
|
struct.addFunction(index.toString()) { move }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["ability_pool"] = {
|
functions["ability_pool"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for ((index, ability) in pokemon.form.abilities.withIndex()) {
|
for ((index, ability) in pokemon.form.abilities.withIndex()) {
|
||||||
struct.addFunction(index.toString()) { StringValue(ability.toString()) }
|
struct.addFunction(index.toString()) { StringValue(ability.toString()) }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["egg_groups"] = {
|
functions["egg_groups"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for ((index, group) in pokemon.form.eggGroups.withIndex()) {
|
for ((index, group) in pokemon.form.eggGroups.withIndex()) {
|
||||||
struct.addFunction(index.toString()) { StringValue(group.toString()) }
|
struct.addFunction(index.toString()) { StringValue(group.toString()) }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["egg_cycles"] = {
|
functions["egg_cycles"] = {
|
||||||
DoubleValue(pokemon.species.eggCycles.toDouble())
|
DoubleValue(pokemon.species.eggCycles.toDouble())
|
||||||
}
|
}
|
||||||
map["labels"] = {
|
functions["labels"] = {
|
||||||
val struct = QueryStruct(hashMapOf())
|
val struct = QueryStruct(hashMapOf())
|
||||||
for ((index, label) in pokemon.form.labels.withIndex()) {
|
for ((index, label) in pokemon.form.labels.withIndex()) {
|
||||||
struct.addFunction(index.toString()) { StringValue(label) }
|
struct.addFunction(index.toString()) { StringValue(label) }
|
||||||
}
|
}
|
||||||
struct
|
struct
|
||||||
}
|
}
|
||||||
map["aspects"] = {
|
functions["aspects"] = {
|
||||||
val aspects = pokemon.aspects
|
val aspects = pokemon.aspects
|
||||||
aspects.asArrayValue { StringValue(it) }
|
aspects.asArrayValue { StringValue(it) }
|
||||||
}
|
}
|
||||||
map["form_aspects"] = {
|
functions["form_aspects"] = {
|
||||||
val aspects = pokemon.form.aspects
|
val aspects = pokemon.form.aspects
|
||||||
aspects.asArrayValue { StringValue(it) }
|
aspects.asArrayValue { StringValue(it) }
|
||||||
}
|
}
|
||||||
map["form_name"] = {
|
functions["form_name"] = {
|
||||||
StringValue(pokemon.form.name)
|
StringValue(pokemon.form.name)
|
||||||
}
|
}
|
||||||
// Yes, this is the lazy call for a single hardcoded pre-evolution.
|
// Yes, this is the lazy call for a single hardcoded pre-evolution.
|
||||||
// Lol. Lmao, even.
|
// Lol. Lmao, even.
|
||||||
// TO-DO: Subscribe to [PokemonSpecies.observable].
|
// TO-DO: Subscribe to [PokemonSpecies.observable].
|
||||||
// Gito: surely this is just a typo, right? not touching the function name just in case
|
functions["pre_evolution"] = { pokemon.species.preEvolution ?: DoubleValue.ZERO }
|
||||||
map["prevolution"] = preEvolution@{
|
functions["nature"] = { StringValue(pokemon.nature.toString()) }
|
||||||
val preEvolution = pokemon.species.preEvolution ?: return@preEvolution DoubleValue.ZERO
|
functions["is_wild"] = { DoubleValue(pokemon.entity?.let { it.ownerUUID == null } == true) }
|
||||||
return@preEvolution preEvolution
|
functions["is_shiny"] = { DoubleValue(pokemon.shiny) }
|
||||||
}
|
functions["is_in_party"] = { DoubleValue(pokemon.storeCoordinates.get()?.store is PartyStore) }
|
||||||
map["nature"] = { StringValue(pokemon.nature.toString()) }
|
functions["species"] = { pokemon.species.struct }
|
||||||
map["is_wild"] = { DoubleValue(pokemon.entity?.let { it.ownerUUID == null } == true) }
|
functions["form"] = { StringValue(pokemon.form.name) }
|
||||||
map["is_shiny"] = { DoubleValue(pokemon.shiny) }
|
functions["weight"] = { DoubleValue(pokemon.species.weight.toDouble()) }
|
||||||
map["is_in_party"] = { DoubleValue(pokemon.storeCoordinates.get()?.store is PartyStore) }
|
functions["matches"] = { params -> DoubleValue(params.getString(0).toProperties().matches(pokemon)) }
|
||||||
map["species"] = { pokemon.species.struct }
|
functions["apply"] = { params ->
|
||||||
map["form"] = { StringValue(pokemon.form.name) }
|
|
||||||
map["weight"] = { DoubleValue(pokemon.species.weight.toDouble()) }
|
|
||||||
map["matches"] = { params -> DoubleValue(params.getString(0).toProperties().matches(pokemon)) }
|
|
||||||
map["apply"] = { params ->
|
|
||||||
params.getString(0).toProperties().apply(pokemon)
|
params.getString(0).toProperties().apply(pokemon)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["owner"] = { pokemon.getOwnerPlayer()?.asMoLangValue() ?: DoubleValue.ZERO }
|
functions["owner"] = { pokemon.getOwnerPlayer()?.asMoLangValue() ?: DoubleValue.ZERO }
|
||||||
map["held_item"] = { pokemon.heldItem().asMoLangValue(server()!!.registryAccess()) }
|
functions["held_item"] = { pokemon.heldItem().asMoLangValue(server()!!.registryAccess()) }
|
||||||
map["remove_held_item"] = { _ ->
|
functions["remove_held_item"] = { pokemon.removeHeldItem() }
|
||||||
pokemon.removeHeldItem()
|
functions["add_aspects"] = { params ->
|
||||||
}
|
|
||||||
map["add_aspects"] = { params ->
|
|
||||||
for (aspect in params.params) pokemon.forcedAspects += aspect.asString()
|
for (aspect in params.params) pokemon.forcedAspects += aspect.asString()
|
||||||
pokemon.updateAspects()
|
pokemon.updateAspects()
|
||||||
}
|
}
|
||||||
map["remove_aspects"] = { params ->
|
functions["remove_aspects"] = { params ->
|
||||||
for (aspect in params.params) pokemon.forcedAspects -= aspect.asString()
|
for (aspect in params.params) pokemon.forcedAspects -= aspect.asString()
|
||||||
pokemon.updateAspects()
|
pokemon.updateAspects()
|
||||||
}
|
}
|
||||||
map["cosmetic_item"] = {
|
functions["cosmetic_item"] = {
|
||||||
pokemon.cosmeticItem().asMoLangValue(server()!!.registryAccess())
|
pokemon.cosmeticItem().asMoLangValue(server()!!.registryAccess())
|
||||||
}
|
}
|
||||||
map["remove_cosmetic_item"] = { _ ->
|
functions["remove_cosmetic_item"] = { pokemon.removeCosmeticItem() }
|
||||||
pokemon.removeCosmeticItem()
|
functions["marks"] = { pokemon.marks.asArrayValue { StringValue(it.identifier.toString()) } }
|
||||||
}
|
functions["has_mark"] = { params ->
|
||||||
map["marks"] = { _ -> pokemon.marks.asArrayValue { StringValue(it.identifier.toString()) } }
|
|
||||||
map["has_mark"] = { params ->
|
|
||||||
var hasMark = false
|
var hasMark = false
|
||||||
val identifier = params.getString(0).asIdentifierDefaultingNamespace()
|
val identifier = params.getString(0).asIdentifierDefaultingNamespace()
|
||||||
val mark = Marks.getByIdentifier(identifier)
|
val mark = Marks.getByIdentifier(identifier)
|
||||||
@@ -254,7 +250,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
|||||||
|
|
||||||
DoubleValue(hasMark)
|
DoubleValue(hasMark)
|
||||||
}
|
}
|
||||||
map["remove_marks"] = { params ->
|
functions["remove_marks"] = { params ->
|
||||||
var removedMark = false
|
var removedMark = false
|
||||||
for (param in params.params) {
|
for (param in params.params) {
|
||||||
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
||||||
@@ -267,7 +263,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
|||||||
|
|
||||||
DoubleValue(removedMark)
|
DoubleValue(removedMark)
|
||||||
}
|
}
|
||||||
map["add_marks"] = { params ->
|
functions["add_marks"] = { params ->
|
||||||
var appliedMark = false
|
var appliedMark = false
|
||||||
for (param in params.params) {
|
for (param in params.params) {
|
||||||
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
||||||
@@ -280,7 +276,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
|||||||
|
|
||||||
DoubleValue(appliedMark)
|
DoubleValue(appliedMark)
|
||||||
}
|
}
|
||||||
map["add_marks_with_chance"] = { params ->
|
functions["add_marks_with_chance"] = { params ->
|
||||||
var appliedMark = false
|
var appliedMark = false
|
||||||
for (param in params.params) {
|
for (param in params.params) {
|
||||||
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
||||||
@@ -298,17 +294,15 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
|||||||
|
|
||||||
DoubleValue(appliedMark)
|
DoubleValue(appliedMark)
|
||||||
}
|
}
|
||||||
map["add_potential_marks"] = { params ->
|
functions["add_potential_marks"] = { params ->
|
||||||
for (param in params.params) {
|
for (param in params.params) {
|
||||||
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
||||||
val mark = Marks.getByIdentifier(identifier)
|
val mark = Marks.getByIdentifier(identifier)
|
||||||
if (mark != null) pokemon.addPotentialMark(mark)
|
if (mark != null) pokemon.addPotentialMark(mark)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["apply_potential_marks"] = put@{
|
functions["apply_potential_marks"] = { DoubleValue(pokemon.applyPotentialMarks()) }
|
||||||
return@put DoubleValue(pokemon.applyPotentialMarks())
|
functions["hyper_train_iv"] = hyperTrainIv@{ params ->
|
||||||
}
|
|
||||||
map["hyper_train_iv"] = hyperTrainIv@{ params ->
|
|
||||||
val statId = params.getString(0)
|
val statId = params.getString(0)
|
||||||
val stat = Stats.getStat(statId)
|
val stat = Stats.getStat(statId)
|
||||||
val value = params.getIntOrNull(1) ?: IVs.MAX_VALUE
|
val value = params.getIntOrNull(1) ?: IVs.MAX_VALUE
|
||||||
@@ -321,12 +315,12 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
|||||||
return@hyperTrainIv DoubleValue.ZERO
|
return@hyperTrainIv DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["add_exp"] = { params ->
|
functions["add_exp"] = { params ->
|
||||||
val exp = params.getDouble(0).toInt()
|
val exp = params.getDouble(0).toInt()
|
||||||
pokemon.addExperience(SidemodExperienceSource("molang"), exp)
|
pokemon.addExperience(SidemodExperienceSource("molang"), exp)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["set_iv"] = setIv@{ params ->
|
functions["set_iv"] = setIv@{ params ->
|
||||||
val statId = params.getString(0)
|
val statId = params.getString(0)
|
||||||
val stat = Stats.getStat(statId)
|
val stat = Stats.getStat(statId)
|
||||||
val value = params.getIntOrNull(1)?.coerceIn(0, IVs.MAX_VALUE) ?: IVs.MAX_VALUE
|
val value = params.getIntOrNull(1)?.coerceIn(0, IVs.MAX_VALUE) ?: IVs.MAX_VALUE
|
||||||
@@ -338,7 +332,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
|||||||
return@setIv DoubleValue.ZERO
|
return@setIv DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["set_ev"] = setEv@{ params ->
|
functions["set_ev"] = setEv@{ params ->
|
||||||
val statId = params.getString(0)
|
val statId = params.getString(0)
|
||||||
val stat = Stats.getStat(statId)
|
val stat = Stats.getStat(statId)
|
||||||
val value = (params.getIntOrNull(1) ?: 0).coerceIn(0, 255)
|
val value = (params.getIntOrNull(1) ?: 0).coerceIn(0, 255)
|
||||||
@@ -350,49 +344,54 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
|||||||
return@setEv DoubleValue.ZERO
|
return@setEv DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map["set_ride_boost"] = setRideBoost@{ params ->
|
functions["set_ride_boost"] = setRideBoost@{ params ->
|
||||||
val statName = params.getString(0).uppercase()
|
val statName = params.getString(0).uppercase()
|
||||||
val stat = RidingStat.entries.find { it.name.equals(statName, ignoreCase = true) }
|
val stat =
|
||||||
?: return@setRideBoost DoubleValue.ZERO
|
RidingStat.entries.find { it.name.equals(statName, ignoreCase = true) }
|
||||||
|
?: return@setRideBoost DoubleValue.ZERO
|
||||||
val value = params.getDoubleOrNull(1)?.toFloat() ?: return@setRideBoost DoubleValue.ZERO
|
val value = params.getDoubleOrNull(1)?.toFloat() ?: return@setRideBoost DoubleValue.ZERO
|
||||||
|
|
||||||
pokemon.setRideBoost(stat, value)
|
pokemon.setRideBoost(stat, value)
|
||||||
return@setRideBoost DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["add_ride_boost"] = addRideBoost@{ params ->
|
functions["add_ride_boost"] = addRideBoost@{ params ->
|
||||||
val statName = params.getString(0).uppercase()
|
val statName = params.getString(0).uppercase()
|
||||||
val stat = RidingStat.entries.find { it.name.equals(statName, ignoreCase = true) }
|
val stat =
|
||||||
?: return@addRideBoost DoubleValue.ZERO
|
RidingStat.entries.find { it.name.equals(statName, ignoreCase = true) }
|
||||||
|
?: return@addRideBoost DoubleValue.ZERO
|
||||||
val value = params.getDoubleOrNull(1)?.toFloat() ?: return@addRideBoost DoubleValue.ZERO
|
val value = params.getDoubleOrNull(1)?.toFloat() ?: return@addRideBoost DoubleValue.ZERO
|
||||||
|
|
||||||
return@addRideBoost DoubleValue(if (pokemon.addRideBoost(stat, value)) 1.0 else 0.0)
|
DoubleValue(if (pokemon.addRideBoost(stat, value)) 1.0 else 0.0)
|
||||||
}
|
}
|
||||||
map["initialize_moveset"] = put@{ params ->
|
functions["initialize_moveset"] = initializeMoveset@{ params ->
|
||||||
val param = params.get<MoValue>(0) ?: StringValue(pokemon.form.defaultWildMovesetBuilder.toString())
|
val param = params.get<MoValue>(0) ?: StringValue(pokemon.form.defaultWildMovesetBuilder.toString())
|
||||||
if (param is DoubleValue) {
|
if (param is DoubleValue) {
|
||||||
pokemon.initializeMoveset(param == DoubleValue.ONE)
|
pokemon.initializeMoveset(param == DoubleValue.ONE)
|
||||||
} else {
|
} else {
|
||||||
val movesetBuilderId = ResourceLocation.parse(param.asString())
|
val movesetBuilderId = ResourceLocation.parse(param.asString())
|
||||||
val movesetBuilder = CobblemonMovesetBuilders.movesetBuilders[movesetBuilderId]
|
val movesetBuilder =
|
||||||
?: run {
|
CobblemonMovesetBuilders.movesetBuilders[movesetBuilderId]
|
||||||
Cobblemon.LOGGER.error("Tried initializing moveset from moveset builder ${param.asString()} but it does not exist.")
|
?: run {
|
||||||
return@put DoubleValue.ZERO
|
Cobblemon.LOGGER.error(
|
||||||
}
|
"Tried initializing moveset from moveset builder ${param.asString()} but it does not exist.",
|
||||||
|
)
|
||||||
|
return@initializeMoveset DoubleValue.ZERO
|
||||||
|
}
|
||||||
pokemon.initializeMovesetFrom(movesetBuilder)
|
pokemon.initializeMovesetFrom(movesetBuilder)
|
||||||
}
|
}
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["validate_moveset"] = { params ->
|
functions["validate_moveset"] = { params ->
|
||||||
val includeLegacy = params.getBooleanOrNull(0) ?: true
|
val includeLegacy = params.getBooleanOrNull(0) ?: true
|
||||||
pokemon.validateMoveset(includeLegacy)
|
pokemon.validateMoveset(includeLegacy)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["teach_learnable_moves"] = { params ->
|
functions["teach_learnable_moves"] = { params ->
|
||||||
val includeLegacy = params.getBooleanOrNull(0) ?: true
|
val includeLegacy = params.getBooleanOrNull(0) ?: true
|
||||||
pokemon.teachLearnableMoves(includeLegacy)
|
pokemon.teachLearnableMoves(includeLegacy)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["teach_move"] = teachMove@{ params ->
|
functions["teach_move"] = teachMove@{ params ->
|
||||||
val moveName = params.getString(0)
|
val moveName = params.getString(0)
|
||||||
val moveTemplate = Moves.getByName(moveName) ?: return@teachMove DoubleValue.ZERO
|
val moveTemplate = Moves.getByName(moveName) ?: return@teachMove DoubleValue.ZERO
|
||||||
val bypass = params.getBooleanOrNull(1) ?: false
|
val bypass = params.getBooleanOrNull(1) ?: false
|
||||||
@@ -402,8 +401,9 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
|||||||
return@teachMove DoubleValue.ZERO
|
return@teachMove DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
|
|
||||||
val alreadyKnows = pokemon.moveSet.getMoves().any { it.template == moveTemplate } ||
|
val alreadyKnows =
|
||||||
pokemon.benchedMoves.any { it.moveTemplate == moveTemplate }
|
pokemon.moveSet.getMoves().any { it.template == moveTemplate } ||
|
||||||
|
pokemon.benchedMoves.any { it.moveTemplate == moveTemplate }
|
||||||
if (alreadyKnows) {
|
if (alreadyKnows) {
|
||||||
return@teachMove DoubleValue.ZERO
|
return@teachMove DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
@@ -416,42 +416,43 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
|||||||
|
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["can_learn_move"] = canLearnMove@{ params ->
|
functions["can_learn_move"] = canLearnMove@{ params ->
|
||||||
val moveName = params.getString(0)
|
val moveName = params.getString(0)
|
||||||
val moveTemplate = Moves.getByName(moveName) ?: return@canLearnMove DoubleValue.ZERO
|
val moveTemplate = Moves.getByName(moveName) ?: return@canLearnMove DoubleValue.ZERO
|
||||||
val includeLegacy = params.getBooleanOrNull(1) ?: true
|
val includeLegacy = params.getBooleanOrNull(1) ?: true
|
||||||
|
|
||||||
val canLearn = if (includeLegacy) {
|
val canLearn =
|
||||||
LearnsetQuery.ANY.canLearn(moveTemplate, pokemon.form.moves)
|
if (includeLegacy) {
|
||||||
} else {
|
LearnsetQuery.ANY.canLearn(moveTemplate, pokemon.form.moves)
|
||||||
LearnsetQuery.LEGAL.canLearn(moveTemplate, pokemon.form.moves)
|
} else {
|
||||||
}
|
LearnsetQuery.LEGAL.canLearn(moveTemplate, pokemon.form.moves)
|
||||||
return@canLearnMove DoubleValue(if (canLearn) 1.0 else 0.0)
|
}
|
||||||
|
|
||||||
|
DoubleValue(if (canLearn) 1.0 else 0.0)
|
||||||
}
|
}
|
||||||
map["unlearn_move"] = unlearnMove@{ params ->
|
functions["unlearn_move"] = unlearnMove@{ params ->
|
||||||
val moveName = params.getString(0)
|
val moveName = params.getString(0)
|
||||||
val moveTemplate = Moves.getByName(moveName)
|
val moveTemplate = Moves.getByName(moveName)
|
||||||
if (moveTemplate != null) {
|
if (moveTemplate != null) {
|
||||||
pokemon.unlearnMove(moveTemplate)
|
pokemon.unlearnMove(moveTemplate)
|
||||||
return@unlearnMove DoubleValue.ONE
|
return@unlearnMove DoubleValue.ONE
|
||||||
} else {
|
|
||||||
return@unlearnMove DoubleValue.ZERO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
map["can_evolve"] = { _ ->
|
functions["can_evolve"] = { DoubleValue(pokemon.evolutions.any()) }
|
||||||
DoubleValue(pokemon.evolutions.any())
|
functions["force_evolve"] = forceEvolve@{ params ->
|
||||||
}
|
|
||||||
map["force_evolve"] = forceEvolve@{ params ->
|
|
||||||
val idx = params.getInt(0)
|
val idx = params.getInt(0)
|
||||||
val evolution = if (idx >= 0) pokemon.evolutions.elementAtOrNull(idx) else return@forceEvolve DoubleValue.ZERO
|
val evolution =
|
||||||
evolution?.forceEvolve(pokemon)
|
if (idx >= 0) pokemon.evolutions.elementAtOrNull(idx) else return@forceEvolve DoubleValue.ZERO
|
||||||
|
evolution?.perform(pokemon)
|
||||||
StringValue(evolution.toString())
|
StringValue(evolution.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
map["entity"] = { pokemon.entity?.asMoLangValue() ?: DoubleValue.ZERO }
|
functions["entity"] = { pokemon.entity?.asMoLangValue() ?: DoubleValue.ZERO }
|
||||||
map["is_alpha"] = { DoubleValue(pokemon.isAlpha) }
|
functions["is_alpha"] = { DoubleValue(pokemon.isAlpha) }
|
||||||
map["size_category"] = { _ -> StringValue(pokemon.getSizeCategory().name) }
|
functions["size_category"] = { StringValue(pokemon.getSizeCategory().name) }
|
||||||
|
|
||||||
return map
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-22
@@ -20,52 +20,50 @@ import com.cobblemon.mod.common.util.getStringOrNull
|
|||||||
object PokemonPropertiesMoLangFunctions : AbstractMoLangFunctionHolder<PokemonProperties>() {
|
object PokemonPropertiesMoLangFunctions : AbstractMoLangFunctionHolder<PokemonProperties>() {
|
||||||
override fun PokemonProperties.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun PokemonProperties.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val props = this
|
val props = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
|
|
||||||
map["level"] = { DoubleValue(props.level?.toDouble() ?: 0) }
|
functions["level"] = { DoubleValue(props.level?.toDouble() ?: 0) }
|
||||||
map["set_level"] = { params ->
|
functions["set_level"] = { params ->
|
||||||
props.level = params.getIntOrNull(0)
|
props.level = params.getIntOrNull(0)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["shiny"] = { DoubleValue(props.shiny) }
|
functions["shiny"] = { DoubleValue(props.shiny) }
|
||||||
map["set_shiny"] = { params ->
|
functions["set_shiny"] = { params ->
|
||||||
props.shiny = params.getBooleanOrNull(0)
|
props.shiny = params.getBooleanOrNull(0)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["species"] = { props.species?.let { StringValue(it) } ?: DoubleValue.ZERO }
|
functions["species"] = { props.species?.let { StringValue(it) } ?: DoubleValue.ZERO }
|
||||||
map["set_species"] = { params ->
|
functions["set_species"] = { params ->
|
||||||
props.species = params.getStringOrNull(0)
|
props.species = params.getStringOrNull(0)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["gender"] = { props.gender?.let { StringValue(it.name) } ?: DoubleValue.ZERO }
|
functions["gender"] = { props.gender?.let { StringValue(it.name) } ?: DoubleValue.ZERO }
|
||||||
map["set_gender"] = { params ->
|
functions["set_gender"] = { params ->
|
||||||
props.gender = params.getStringOrNull(0)?.let { Gender.valueOf(it) }
|
props.gender = params.getStringOrNull(0)?.let { Gender.valueOf(it) }
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["form"] = { props.form?.let { StringValue(it) } ?: DoubleValue.ZERO }
|
functions["form"] = { props.form?.let { StringValue(it) } ?: DoubleValue.ZERO }
|
||||||
map["ivs"] = ivs@{
|
functions["ivs"] = ivs@{
|
||||||
val ivs = props.ivs ?: return@ivs DoubleValue.ZERO
|
val ivs = props.ivs ?: return@ivs DoubleValue.ZERO
|
||||||
|
|
||||||
return@ivs ivs.struct
|
ivs.struct
|
||||||
}
|
}
|
||||||
map["evs"] = evs@{
|
functions["evs"] = evs@{
|
||||||
val evs = props.evs ?: return@evs DoubleValue.ZERO
|
val evs = props.evs ?: return@evs DoubleValue.ZERO
|
||||||
|
|
||||||
return@evs evs.struct
|
evs.struct
|
||||||
}
|
}
|
||||||
map["friendship"] = { DoubleValue(props.friendship?.toDouble() ?: DoubleValue.ZERO) }
|
functions["friendship"] = { DoubleValue(props.friendship?.toDouble() ?: DoubleValue.ZERO) }
|
||||||
map["set_friendship"] = { params ->
|
functions["set_friendship"] = { params ->
|
||||||
props.friendship = params.getIntOrNull(0)
|
props.friendship = params.getIntOrNull(0)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["create"] = {
|
functions["create"] = { (props.create()).struct }
|
||||||
val pokemon = props.create()
|
functions["to_string"] = { params ->
|
||||||
pokemon.struct
|
|
||||||
}
|
|
||||||
map["to_string"] = { params ->
|
|
||||||
val separator = params.getStringOrNull(0) ?: " "
|
val separator = params.getStringOrNull(0) ?: " "
|
||||||
StringValue(props.asString(separator = separator))
|
StringValue(props.asString(separator = separator))
|
||||||
}
|
}
|
||||||
return map
|
|
||||||
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-27
@@ -22,83 +22,84 @@ import com.cobblemon.mod.common.util.asUUID
|
|||||||
import com.cobblemon.mod.common.util.getPlayer
|
import com.cobblemon.mod.common.util.getPlayer
|
||||||
import com.cobblemon.mod.common.util.toProperties
|
import com.cobblemon.mod.common.util.toProperties
|
||||||
|
|
||||||
object PokemonStoreMoLangFunctions: AbstractMoLangFunctionHolder<PokemonStore<*>>() {
|
object PokemonStoreMoLangFunctions : AbstractMoLangFunctionHolder<PokemonStore<*>>() {
|
||||||
override fun PokemonStore<*>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun PokemonStore<*>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val store = this
|
val store = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
map["uuid"] = { StringValue(store.uuid.toString()) }
|
|
||||||
map["add"] = { params ->
|
functions["uuid"] = { StringValue(store.uuid.toString()) }
|
||||||
|
functions["add"] = { params ->
|
||||||
val pokemon = params.get<ObjectValue<Pokemon>>(0)
|
val pokemon = params.get<ObjectValue<Pokemon>>(0)
|
||||||
DoubleValue(store.add(pokemon.obj))
|
DoubleValue(store.add(pokemon.obj))
|
||||||
}
|
}
|
||||||
map["add_by_properties"] = { params ->
|
functions["add_by_properties"] = { params ->
|
||||||
val props = params.getString(0).toProperties()
|
val props = params.getString(0).toProperties()
|
||||||
val player = (store as? PlayerPartyStore)?.playerUUID?.getPlayer() // Only really know for sure when it's a player party store
|
val player =
|
||||||
|
(store as? PlayerPartyStore)?.playerUUID?.getPlayer() // Only really know for sure when it's a player party store
|
||||||
val pokemon = props.create(player = player)
|
val pokemon = props.create(player = player)
|
||||||
DoubleValue(store.add(pokemon))
|
DoubleValue(store.add(pokemon))
|
||||||
}
|
}
|
||||||
map["find_by_properties"] = { params ->
|
functions["find_by_properties"] = { params ->
|
||||||
val props = params.getString(0).toProperties()
|
val props = params.getString(0).toProperties()
|
||||||
val pokemon = store.find { props.matches(it) }
|
val pokemon = store.find { props.matches(it) }
|
||||||
pokemon?.asStruct() ?: DoubleValue.ZERO
|
pokemon?.asStruct() ?: DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
map["find_all_by_properties"] = { params ->
|
functions["find_all_by_properties"] = { params ->
|
||||||
val props = params.getString(0).toProperties()
|
val props = params.getString(0).toProperties()
|
||||||
val pokemon = store.filter { props.matches(it) }
|
val pokemon = store.filter { props.matches(it) }
|
||||||
ArrayStruct(pokemon.mapIndexed { index, value -> "$index" to value.asStruct() }.toMap())
|
ArrayStruct(pokemon.mapIndexed { index, value -> "$index" to value.asStruct() }.toMap())
|
||||||
}
|
}
|
||||||
map["find_by_id"] = { params ->
|
functions["find_by_id"] = { params ->
|
||||||
val id = params.getString(0).asUUID
|
val id = params.getString(0).asUUID
|
||||||
val pokemon = store.find { it.uuid == id }
|
val pokemon = store.find { it.uuid == id }
|
||||||
pokemon?.asStruct() ?: DoubleValue.ZERO
|
pokemon?.asStruct() ?: DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
map["remove_by_id"] = removeById@{ params ->
|
functions["remove_by_id"] = removeById@{ params ->
|
||||||
val id = params.getString(0).asUUID
|
val id = params.getString(0).asUUID
|
||||||
val pokemon = store.find { it.uuid == id } ?: return@removeById DoubleValue.ZERO
|
val pokemon = store.find { it.uuid == id } ?: return@removeById DoubleValue.ZERO
|
||||||
return@removeById DoubleValue(store.remove(pokemon))
|
DoubleValue(store.remove(pokemon))
|
||||||
}
|
}
|
||||||
map["average_level"] = averageLevel@{ _ ->
|
functions["average_level"] = averageLevel@{
|
||||||
var numberOfPokemon = 0
|
var numberOfPokemon = 0
|
||||||
var totalLevel = 0
|
var totalLevel = 0
|
||||||
for (pokemon in store) {
|
for (pokemon in store) {
|
||||||
totalLevel += pokemon.level
|
totalLevel += pokemon.level
|
||||||
numberOfPokemon++
|
numberOfPokemon++
|
||||||
}
|
}
|
||||||
if (numberOfPokemon == 0) {
|
|
||||||
return@averageLevel DoubleValue.ZERO
|
if (numberOfPokemon == 0) return@averageLevel DoubleValue.ZERO
|
||||||
}
|
|
||||||
return@averageLevel DoubleValue(totalLevel.toDouble() / numberOfPokemon)
|
DoubleValue(totalLevel.toDouble() / numberOfPokemon)
|
||||||
}
|
}
|
||||||
map["count"] = { _ -> DoubleValue(store.count()) }
|
functions["count"] = { DoubleValue(store.count()) }
|
||||||
map["count_by_properties"] = { params ->
|
functions["count_by_properties"] = { params ->
|
||||||
val props = params.getString(0).toProperties()
|
val props = params.getString(0).toProperties()
|
||||||
DoubleValue(store.count { props.matches(it) })
|
DoubleValue(store.count { props.matches(it) })
|
||||||
}
|
}
|
||||||
map["highest_level"] = {
|
functions["highest_level"] = {
|
||||||
val highest = store.maxOfOrNull { it.level } ?: 0
|
val highest = store.maxOfOrNull { it.level } ?: 0
|
||||||
DoubleValue(highest)
|
DoubleValue(highest)
|
||||||
}
|
}
|
||||||
map["lowest_level"] = {
|
functions["lowest_level"] = {
|
||||||
val lowest = store.minOfOrNull { it.level } ?: 0
|
val lowest = store.minOfOrNull { it.level } ?: 0
|
||||||
DoubleValue(lowest)
|
DoubleValue(lowest)
|
||||||
}
|
}
|
||||||
map["heal"] = {
|
functions["heal"] = {
|
||||||
for (pokemon in store) {
|
for (pokemon in store) {
|
||||||
pokemon.heal()
|
pokemon.heal()
|
||||||
}
|
}
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
map["healing_remainder_percent"] = { _ ->
|
functions["healing_remainder_percent"] = {
|
||||||
var totalPercent = 0.0f
|
var totalPercent = 0.0f
|
||||||
for (pokemon in store) {
|
for (pokemon in store) {
|
||||||
totalPercent += (1.0f - (pokemon.currentHealth.toFloat() / pokemon.maxHealth))
|
totalPercent += (1.0f - (pokemon.currentHealth.toFloat() / pokemon.maxHealth))
|
||||||
}
|
}
|
||||||
DoubleValue(totalPercent)
|
DoubleValue(totalPercent)
|
||||||
}
|
}
|
||||||
map["has_usable_pokemon"] = { _ -> DoubleValue(store.any { !it.isFainted() }) }
|
functions["has_usable_pokemon"] = { DoubleValue(store.any { !it.isFainted() }) }
|
||||||
map["pokemon"] = {
|
functions["pokemon"] = { store.map { it.asStruct() }.asArrayValue() }
|
||||||
store.map { it.asStruct() }.asArrayValue()
|
|
||||||
}
|
return functions
|
||||||
return map
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-20
@@ -25,62 +25,63 @@ import java.util.*
|
|||||||
object ServerMoLangFunctions : AbstractMoLangFunctionHolder<MinecraftServer>() {
|
object ServerMoLangFunctions : AbstractMoLangFunctionHolder<MinecraftServer>() {
|
||||||
override fun MinecraftServer.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
override fun MinecraftServer.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||||
val server = this
|
val server = this
|
||||||
val map = mutableMapOf<String, (MoParams) -> Any>()
|
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||||
|
|
||||||
map["get_world"] = getWorld@{ params ->
|
functions["get_world"] = getWorld@{ params ->
|
||||||
val world = server.getLevel(
|
val world =
|
||||||
ResourceKey.create(
|
server.getLevel(
|
||||||
Registries.DIMENSION,
|
ResourceKey.create(
|
||||||
params.getString(0).asIdentifierDefaultingNamespace(namespace = "minecraft")
|
Registries.DIMENSION,
|
||||||
)
|
params.getString(0).asIdentifierDefaultingNamespace(namespace = "minecraft"),
|
||||||
) ?: return@getWorld DoubleValue.ZERO
|
),
|
||||||
|
) ?: return@getWorld DoubleValue.ZERO
|
||||||
|
|
||||||
return@getWorld world
|
world
|
||||||
.registryAccess()
|
.registryAccess()
|
||||||
.registryOrThrow(Registries.DIMENSION)
|
.registryOrThrow(Registries.DIMENSION)
|
||||||
.wrapAsHolder(world)
|
.wrapAsHolder(world)
|
||||||
.asWorldMoLangValue()
|
.asWorldMoLangValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
map["broadcast"] = { params ->
|
functions["broadcast"] = { params ->
|
||||||
val message = params.getString(0)
|
val message = params.getString(0)
|
||||||
server.playerList.broadcastSystemMessage(message.text(), params.getBooleanOrNull(1) == true)
|
server.playerList.broadcastSystemMessage(message.text(), params.getBooleanOrNull(1) == true)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
|
|
||||||
map["get_player_by_uuid"] = getPlayerByUuid@{ params ->
|
functions["get_player_by_uuid"] = getPlayerByUuid@{ params ->
|
||||||
val uuid = UUID.fromString(params.getString(0))
|
val uuid = UUID.fromString(params.getString(0))
|
||||||
val player = server.playerList.getPlayer(uuid) ?: return@getPlayerByUuid DoubleValue.ZERO
|
val player = server.playerList.getPlayer(uuid) ?: return@getPlayerByUuid DoubleValue.ZERO
|
||||||
return@getPlayerByUuid player.asMoLangValue()
|
player.asMoLangValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
map["get_player_by_username"] = getPlayerByUsername@{ params ->
|
functions["get_player_by_username"] = getPlayerByUsername@{ params ->
|
||||||
val username = params.getString(0)
|
val username = params.getString(0)
|
||||||
val player = server.playerList.getPlayerByName(username) ?: return@getPlayerByUsername DoubleValue.ZERO
|
val player = server.playerList.getPlayerByName(username) ?: return@getPlayerByUsername DoubleValue.ZERO
|
||||||
return@getPlayerByUsername player.asMoLangValue()
|
player.asMoLangValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
map["data"] = { params ->
|
functions["data"] = { params ->
|
||||||
Cobblemon.molangData.load(
|
Cobblemon.molangData.load(
|
||||||
UUID(0L, 0L),
|
UUID(0L, 0L),
|
||||||
params.getStringOrNull(0)
|
params.getStringOrNull(0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
map["save_data"] = { params ->
|
functions["save_data"] = { params ->
|
||||||
Cobblemon.molangData.save(
|
Cobblemon.molangData.save(
|
||||||
UUID(0L, 0L),
|
UUID(0L, 0L),
|
||||||
params.getStringOrNull(index = 0)
|
params.getStringOrNull(index = 0),
|
||||||
)
|
)
|
||||||
DoubleValue.ONE
|
DoubleValue.ONE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe later...
|
// Maybe later...
|
||||||
// map.put("stop") { params ->
|
// functions.put("stop") { params ->
|
||||||
// Cobblemon.LOGGER.warn("Server is being stopped from a MoLang script.")
|
// Cobblemon.LOGGER.warn("Server is being stopped from a MoLang script.")
|
||||||
// server.stopServer()
|
// server.stopServer()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return map
|
return functions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user