forked from mirrors/cobblemon
Compare commits
374
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
925f4ebed5 | ||
|
|
8b79963129 | ||
|
|
3a533a6d9c | ||
|
|
0dbcf2539b | ||
|
|
6d9f865099 | ||
|
|
5d2fa8427a | ||
|
|
8f8b2627f7 | ||
|
|
4ad0686b03 | ||
|
|
a56ffe1742 | ||
|
|
6d1570302d | ||
|
|
811e9d3352 | ||
|
|
e610aa18d7 | ||
|
|
42ecd3e813 | ||
|
|
1299b8fee8 | ||
|
|
a12cf17cfa | ||
|
|
74faca60f2 | ||
|
|
6420176787 | ||
|
|
6ee81fe2ab | ||
|
|
96f4f988f8 | ||
|
|
4ccfbbcb37 | ||
|
|
ed0aa83013 | ||
|
|
b94394f8d1 | ||
|
|
b16687c132 | ||
|
|
56767b3e31 | ||
|
|
67eb3e1046 | ||
|
|
952ea8d3b7 | ||
|
|
cc764ff9db | ||
|
|
2e1f8af700 | ||
|
|
6c6a8e4679 | ||
|
|
9e9a22eb14 | ||
|
|
32bfaf152d | ||
|
|
d1b947b264 | ||
|
|
6122fb6107 | ||
|
|
14c7ee3216 | ||
|
|
1a00ae7fb8 | ||
|
|
36b3cbe3b8 | ||
|
|
49686a1670 | ||
|
|
2354888a73 | ||
|
|
f64065d54f | ||
|
|
005ab0ca74 | ||
|
|
c13307e931 | ||
|
|
bd21a6e1ca | ||
|
|
94ea15b9c5 | ||
|
|
bc6c9def56 | ||
|
|
9ca6a2e461 | ||
|
|
f7560a12ad | ||
|
|
8bc1767917 | ||
|
|
8b29d3a533 | ||
|
|
de1248b97e | ||
|
|
a654225ed5 | ||
|
|
2d18113e27 | ||
|
|
cdadc6fa67 | ||
|
|
ff7ef1b67e | ||
|
|
d91c819700 | ||
|
|
259e1d05cb | ||
|
|
549b88a4c2 | ||
|
|
68b60e7d50 | ||
|
|
a7787707f2 | ||
|
|
539097e681 | ||
|
|
8b70a4124d | ||
|
|
7e8b000311 | ||
|
|
00c86b89cb | ||
|
|
b2c9d96829 | ||
|
|
8ea5ea6804 | ||
|
|
1305e8a11d | ||
|
|
909cd8a6eb | ||
|
|
d60abdc940 | ||
|
|
ec8e6f58c8 | ||
|
|
12967e4813 | ||
|
|
d754cc69fe | ||
|
|
a2b54643fe | ||
|
|
896c195dd9 | ||
|
|
206bfacba0 | ||
|
|
b6ffbd1ed8 | ||
|
|
829900fb58 | ||
|
|
be3066f7b2 | ||
|
|
fb56ab5865 | ||
|
|
a3f02a8a7c | ||
|
|
6c2757b94b | ||
|
|
139ef56fdf | ||
|
|
d3e473ff85 | ||
|
|
fdebc5987e | ||
|
|
caeeb756fe | ||
|
|
67b5e5c6a8 | ||
|
|
720eef5e75 | ||
|
|
ebc7f67655 | ||
|
|
3c508c5bd1 | ||
|
|
c7052d295c | ||
|
|
9193e9a372 | ||
|
|
f6244cbe12 | ||
|
|
5743a04db7 | ||
|
|
439a5077c2 | ||
|
|
a8a028bb7a | ||
|
|
984e10a780 | ||
|
|
ad0571a782 | ||
|
|
a18581ae1c | ||
|
|
177ad70172 | ||
|
|
98fb731270 | ||
|
|
a98dbcf267 | ||
|
|
62e9294c8a | ||
|
|
314bd19dc6 | ||
|
|
c0344f5604 | ||
|
|
2f8a9f207c | ||
|
|
8c1416514c | ||
|
|
575c33612d | ||
|
|
889d193ad1 | ||
|
|
57ef37099e | ||
|
|
d7d311764d | ||
|
|
d7fb65d23b | ||
|
|
3e4449aed1 | ||
|
|
55aa50654c | ||
|
|
489170cf00 | ||
|
|
930eb42e76 | ||
|
|
87d76e8788 | ||
|
|
6d8bf59eee | ||
|
|
a8f431868a | ||
|
|
0c6e355c6b | ||
|
|
a2f6ab0ea4 | ||
|
|
719a56e7c3 | ||
|
|
bd4397ec55 | ||
|
|
d5e3781fc5 | ||
|
|
776ab05ac1 | ||
|
|
0da5d27851 | ||
|
|
48b28bc509 | ||
|
|
5547326798 | ||
|
|
bcf730a07f | ||
|
|
8be1e78fee | ||
|
|
c463c99b0f | ||
|
|
255829a9f8 | ||
|
|
46758b7ab0 | ||
|
|
aebcf42df8 | ||
|
|
2268640dbc | ||
|
|
bf3739c598 | ||
|
|
9c4ae189a1 | ||
|
|
502a314a6c | ||
|
|
ca1ea6385d | ||
|
|
9749acbb0c | ||
|
|
81d4e4ded1 | ||
|
|
3e5ab4328b | ||
|
|
d1993574f6 | ||
|
|
2b531ec32f | ||
|
|
a9985bbea8 | ||
|
|
8d00da2c57 | ||
|
|
f4d866537a | ||
|
|
e9f942687f | ||
|
|
d67d73351d | ||
|
|
74d3ce793d | ||
|
|
3223c8dfeb | ||
|
|
a84a897e84 | ||
|
|
92bf3ba2a2 | ||
|
|
84f79c89c5 | ||
|
|
248967256b | ||
|
|
ea19721998 | ||
|
|
e9408db7a1 | ||
|
|
15ab84297d | ||
|
|
94cfb23e66 | ||
|
|
2fbffa5b66 | ||
|
|
108b769928 | ||
|
|
3db39547f0 | ||
|
|
c4688c5db9 | ||
|
|
b0385fc37f | ||
|
|
e491e7de81 | ||
|
|
f7974767d1 | ||
|
|
d41e89ddbd | ||
|
|
37293d396a | ||
|
|
d598335112 | ||
|
|
a30ca92f0a | ||
|
|
dd5ec25345 | ||
|
|
e3f3f4e1b7 | ||
|
|
004890d050 | ||
|
|
e690a0ed92 | ||
|
|
1e240d879f | ||
|
|
5f52625b05 | ||
|
|
10746bea10 | ||
|
|
af1f607994 | ||
|
|
db9cefc8ba | ||
|
|
c467f9cad2 | ||
|
|
5f7fa85b58 | ||
|
|
eb3ffdfbd4 | ||
|
|
c7e512bc32 | ||
|
|
6889cb7936 | ||
|
|
b4af502997 | ||
|
|
9bffdf8df4 | ||
|
|
8dbdd78c86 | ||
|
|
e6812891b5 | ||
|
|
6a3c98ed1c | ||
|
|
991ec7cc1a | ||
|
|
e59f4e7891 | ||
|
|
a481bde4f5 | ||
|
|
787faf38e7 | ||
|
|
9a42c82a37 | ||
|
|
654d0f8975 | ||
|
|
66b3c4a4c6 | ||
|
|
2fc2f24dee | ||
|
|
0988411e13 | ||
|
|
b39fadcde8 | ||
|
|
8221386767 | ||
|
|
311a3e1005 | ||
|
|
aeb6bddba6 | ||
|
|
e11d1cb77c | ||
|
|
774e62bb4b | ||
|
|
716ab4fb95 | ||
|
|
766625bf31 | ||
|
|
14cde609c6 | ||
|
|
da6ac4b8d6 | ||
|
|
43ef224444 | ||
|
|
d65d23ad02 | ||
|
|
e32b540deb | ||
|
|
f416567005 | ||
|
|
1daf931a49 | ||
|
|
6bcbc58b0a | ||
|
|
a1218f6c1e | ||
|
|
b1eb21150b | ||
|
|
56d4a18474 | ||
|
|
f13b6ddde7 | ||
|
|
c3d119c197 | ||
|
|
eb7527c26c | ||
|
|
b6bc03d2b7 | ||
|
|
029a338aaf | ||
|
|
b3f794ddaa | ||
|
|
1c95686bf9 | ||
|
|
55b1e7c672 | ||
|
|
e532fbf2ae | ||
|
|
c7348d3dba | ||
|
|
b978bbe60e | ||
|
|
31c492c032 | ||
|
|
85a2142319 | ||
|
|
83e3d65918 | ||
|
|
9b053bef90 | ||
|
|
76211e81ff | ||
|
|
2cace9d153 | ||
|
|
33ad8ca12b | ||
|
|
8cce2c59b9 | ||
|
|
bdcb8da6b7 | ||
|
|
d0cfae8713 | ||
|
|
693b53704d | ||
|
|
3c46e3b5b9 | ||
|
|
5dec5ed008 | ||
|
|
22a479633e | ||
|
|
1d93df56ae | ||
|
|
136d47bd2f | ||
|
|
8ded0af5e9 | ||
|
|
36462b0a85 | ||
|
|
8a447a2487 | ||
|
|
bdc2c4d9de | ||
|
|
8d9a7d67b5 | ||
|
|
e1d9b2780a | ||
|
|
fafee79da9 | ||
|
|
71c6c12656 | ||
|
|
4e07128c80 | ||
|
|
df8640ce48 | ||
|
|
59e0a6369d | ||
|
|
8913252b79 | ||
|
|
f7bedc9866 | ||
|
|
e47529c10a | ||
|
|
3e6c6c21a6 | ||
|
|
d4f13b9435 | ||
|
|
e7b60abe2d | ||
|
|
85da2bd0cc | ||
|
|
b7af57f6e1 | ||
|
|
ca5b7e1aec | ||
|
|
2ec81679e4 | ||
|
|
08c048f4ba | ||
|
|
6589279339 | ||
|
|
4465e47f2e | ||
|
|
570d42df7a | ||
|
|
044e83449d | ||
|
|
6617558e71 | ||
|
|
eff410b714 | ||
|
|
482a7d9493 | ||
|
|
430891971c | ||
|
|
d88f2d80a3 | ||
|
|
2a3d74bd85 | ||
|
|
de94986156 | ||
|
|
f8afcb6a8f | ||
|
|
3c0cf1dc5b | ||
|
|
8225898a66 | ||
|
|
49faf60ea1 | ||
|
|
71bd4fb610 | ||
|
|
509feae420 | ||
|
|
5045a95cd0 | ||
|
|
07dfc89f63 | ||
|
|
34b6a3cc47 | ||
|
|
98fd61ec29 | ||
|
|
e1e545dd05 | ||
|
|
c403103018 | ||
|
|
d6a1d3f2bd | ||
|
|
87edf2bfd6 | ||
|
|
7711535a26 | ||
|
|
f65f6fd2c9 | ||
|
|
a4e144854d | ||
|
|
d6f7cd4b83 | ||
|
|
36cf258410 | ||
|
|
89df2a01e2 | ||
|
|
0a930cb54f | ||
|
|
2448fec2c4 | ||
|
|
ea2071b644 | ||
|
|
bae0d77699 | ||
|
|
f5f5cb19bc | ||
|
|
9aa7c65279 | ||
|
|
8f4071e181 | ||
|
|
9c4470bc51 | ||
|
|
c785480c32 | ||
|
|
4a50700bb9 | ||
|
|
0ad2ff552b | ||
|
|
44c5d4ea2e | ||
|
|
46661908e0 | ||
|
|
01372f2850 | ||
|
|
204ce8f003 | ||
|
|
784ddcb19a | ||
|
|
11d7cbfa46 | ||
|
|
f3325caaea | ||
|
|
123c348f73 | ||
|
|
29aae87f01 | ||
|
|
9f6ad98acb | ||
|
|
cecd291566 | ||
|
|
2f9d6a9f83 | ||
|
|
1e9ccbddcb | ||
|
|
9b5a381436 | ||
|
|
ed5bd7e899 | ||
|
|
587a90bb70 | ||
|
|
f883578046 | ||
|
|
b5d348eba6 | ||
|
|
fce389edfd | ||
|
|
b6954b4e07 | ||
|
|
f28a16c7cc | ||
|
|
230071a773 | ||
|
|
63534a242c | ||
|
|
1afb574aec | ||
|
|
ac9adb03cd | ||
|
|
f3a22b19b3 | ||
|
|
572e77c4f5 | ||
|
|
889a012932 | ||
|
|
eca4c6cd4c | ||
|
|
b570a6ec8b | ||
|
|
1f1c302bc9 | ||
|
|
adc1fa0063 | ||
|
|
ddc3a781a0 | ||
|
|
9eb3281c6f | ||
|
|
0cd5804e67 | ||
|
|
7000d0d82a | ||
|
|
b7695e55ea | ||
|
|
bea3ebe62b | ||
|
|
73cf736077 | ||
|
|
d31f8f0eff | ||
|
|
88dca4d7b1 | ||
|
|
27db85ee32 | ||
|
|
5e3561eba5 | ||
|
|
9dfa8a323e | ||
|
|
15c0d86996 | ||
|
|
0fbb5e7d95 | ||
|
|
5e8d27779c | ||
|
|
a4fabcd45d | ||
|
|
5259b8c93d | ||
|
|
397c2decbf | ||
|
|
12b6e7e49c | ||
|
|
242c1b01af | ||
|
|
ee76e19b85 | ||
|
|
2aac6cc9e7 | ||
|
|
3faa305f09 | ||
|
|
d1bbf5f079 | ||
|
|
52fa646420 | ||
|
|
f7c47d46cf | ||
|
|
e82c361bcb | ||
|
|
fa6d8e0f08 | ||
|
|
7eea6c8b49 | ||
|
|
c537ca438b | ||
|
|
d5cea9b9ad | ||
|
|
6c2494b7ab | ||
|
|
a5ab523ac1 | ||
|
|
847ae12ad5 | ||
|
|
cece9e051b | ||
|
|
02141ccd3e | ||
|
|
1dc3acc47d |
+5
-1
@@ -5,12 +5,16 @@
|
|||||||
- Dog Pokémon (Growlithe, Arcanine, etc.) intimidate Skeletons.
|
- Dog Pokémon (Growlithe, Arcanine, etc.) intimidate Skeletons.
|
||||||
- Cat Pokémon (Meowth, Persian, etc.) intimidate Creepers and Phantoms.
|
- Cat Pokémon (Meowth, Persian, etc.) intimidate Creepers and Phantoms.
|
||||||
- Sleep-related Pokémon (Munsharna, Komala, etc.) intimidate Phantoms.
|
- Sleep-related Pokémon (Munsharna, Komala, etc.) intimidate Phantoms.
|
||||||
|
- Some Pokémon naturally hunt each other.
|
||||||
- Added a Behaviour Editor to the NPC editing screen.
|
- Added a Behaviour Editor to the NPC editing screen.
|
||||||
- Added /behaviouredit command for opening the Behaviour Editor on Pokémon and NPCs.
|
- Added /behaviouredit command for opening the Behaviour Editor on Pokémon and NPCs.
|
||||||
- Editing variables for Pokémon is not yet supported.
|
- Editing variables for Pokémon is not yet supported.
|
||||||
|
|
||||||
|
### Developer
|
||||||
|
- baseScale in NPCs has been removed from classes and presets, and in the entity it is replaced with hitboxScale and renderScale.
|
||||||
|
|
||||||
### MoLang & Datapacks
|
### MoLang & Datapacks
|
||||||
- Added a `behaviours` datapack folder which motivates the Behaviour Editor screen on NPCs and Pokémon.
|
- Added a `behaviours` datapack folder which motivates the Behaviour Editor screen on NPCs and Pokémon.
|
||||||
- Added many default behaviours.
|
- Added very many behaviours to choose from.
|
||||||
- Removed many NPC presets that now exist as behaviours. This is a breaking change if you are using NPCs with these presets.
|
- Removed many NPC presets that now exist as behaviours. This is a breaking change if you are using NPCs with these presets.
|
||||||
- NPCs with these presets should be modified to instead list under `"behaviours"` all the equivalent behaviours.
|
- NPCs with these presets should be modified to instead list under `"behaviours"` all the equivalent behaviours.
|
||||||
+7
-1
@@ -4,10 +4,16 @@
|
|||||||
- The button on the right allows for changing the box wallpaper.
|
- The button on the right allows for changing the box wallpaper.
|
||||||
- The option buttons on the left side allow for sorting the box by name, level, Pokédex number, gender, and type. Shift clicking allows for sorting in reverse order.
|
- The option buttons on the left side allow for sorting the box by name, level, Pokédex number, gender, and type. Shift clicking allows for sorting in reverse order.
|
||||||
- Added filter functionality in PC UI, which supports `PokemonProperties` (e.g. `shiny=yes` shows all shiny Pokémon).
|
- Added filter functionality in PC UI, which supports `PokemonProperties` (e.g. `shiny=yes` shows all shiny Pokémon).
|
||||||
|
- Names can be filtered by exact or partial matches, e.g. entering "cha" will show Charmander, Charmeleon, etc.
|
||||||
- Added `/changewallpaper <player> <boxNumber> <wallpaper>` command to change a box wallpaper through commands.
|
- Added `/changewallpaper <player> <boxNumber> <wallpaper>` command to change a box wallpaper through commands.
|
||||||
- Added `/renamebox <player> <boxNumber> <name>` command to rename a PC box through commands.
|
- Added `/renamebox <player> <boxNumber> <name>` command to rename a PC box through commands.
|
||||||
- Added IVs and EVs stat displays in PC.
|
- Added IVs and EVs stat displays in PC.
|
||||||
- improved filter by Name, now is available search by exact names or partial matches, for example "cha" will show Charmander, Charmeleon and Charizard among others that match.
|
- Added ability to change boxes by scrolling.
|
||||||
|
- PC will now open to last box viewed within a session.
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Slots in pastures will now have darker backgrounds and italicised Pokémon names if the Pokémon is not owned by the player.
|
||||||
|
- The pasture slot will show the name of the Pokémon owner when hovered if the Pokémon is not owned.
|
||||||
|
|
||||||
### Developer
|
### Developer
|
||||||
- Added `RenamePCBoxEvent.Pre` and `RenamePCBoxEvent.Post` events to prevent players from renaming a box or changing their input.
|
- Added `RenamePCBoxEvent.Pre` and `RenamePCBoxEvent.Post` events to prevent players from renaming a box or changing their input.
|
||||||
|
|||||||
+17
-7
@@ -20,9 +20,8 @@
|
|||||||
- The player executing the command must be facing the target pokemon entity. Transformations are not persistent and will revert when resources are reloaded.
|
- The player executing the command must be facing the target pokemon entity. Transformations are not persistent and will revert when resources are reloaded.
|
||||||
- Added `legacy` and `special` sourced moves to Pokémon.
|
- Added `legacy` and `special` sourced moves to Pokémon.
|
||||||
- Added lang keys for all moves and abilities up to Generation 9.
|
- Added lang keys for all moves and abilities up to Generation 9.
|
||||||
- Fixed Moon Ball moon phase logic to actually work correctly
|
|
||||||
- Added `translucent_cull` boolean option into resolver's layer to allow for translucent textures with culling
|
- Added `translucent_cull` boolean option into resolver's layer to allow for translucent textures with culling
|
||||||
- Added [LambDynamicLights](https://modrinth.com/mod/lambdynamiclights) support for items held by Pokémon.
|
- Added [LambDynamicLights](https://modrinth.com/mod/lambdynamiclights) support for items held by Pokémon, evolution stone blocks, evolution stone items, Pokédex, Luminous Moss, Flame Orb, and Magmarizer.
|
||||||
- Added the Clear Amulet, Grip Claw, Lagging Tail, Luminous Moss, Metal Alloy, Scroll of Darkness, Scroll of Waters
|
- Added the Clear Amulet, Grip Claw, Lagging Tail, Luminous Moss, Metal Alloy, Scroll of Darkness, Scroll of Waters
|
||||||
- Added Recipes for Masterpiece Cup, Eject Pack
|
- Added Recipes for Masterpiece Cup, Eject Pack
|
||||||
- Added modification to Minecraft Creative Inventory search to account for item names that contain `poké` when input contains `poke`.
|
- Added modification to Minecraft Creative Inventory search to account for item names that contain `poké` when input contains `poke`.
|
||||||
@@ -33,6 +32,7 @@
|
|||||||
- Added `/pctake <player> <box> <slot>` command that takes a specific Pokémon from a player's PC. Removes the pokemon if target is self or ran from the server.
|
- Added `/pctake <player> <box> <slot>` command that takes a specific Pokémon from a player's PC. Removes the pokemon if target is self or ran from the server.
|
||||||
- Added Hyper Training items (IV Modification) as well as some additional candy items to do so (Health Candy, Sickly Candy)
|
- Added Hyper Training items (IV Modification) as well as some additional candy items to do so (Health Candy, Sickly Candy)
|
||||||
- Added Galarica Nut Bushes
|
- Added Galarica Nut Bushes
|
||||||
|
- Added functionality to Everstone when held by a Pokémon; suppresses evolution notification and hides evolve button in summary interface.
|
||||||
|
|
||||||
### Pokémon Added
|
### Pokémon Added
|
||||||
|
|
||||||
@@ -226,6 +226,9 @@
|
|||||||
- Saccharine Leaves Age 1 or higher will now show Yellow particles when broken
|
- Saccharine Leaves Age 1 or higher will now show Yellow particles when broken
|
||||||
- Destroying a Saccharine Honey Log will now drop a Saccharine Log in stead of nothing
|
- Destroying a Saccharine Honey Log will now drop a Saccharine Log in stead of nothing
|
||||||
- Reworked some compost chances
|
- Reworked some compost chances
|
||||||
|
- Updated interaction interface to include 4 more option spaces
|
||||||
|
- Made lecterns that hold a Pokédex emit light.
|
||||||
|
- Updated light levels for active PC, Pasture, Healing Machine, and Data Monitor.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Fixed game crashing when removing national pokedex using datapacks
|
- Fixed game crashing when removing national pokedex using datapacks
|
||||||
@@ -280,12 +283,17 @@
|
|||||||
- Fixed Cobblemon crashing if it tries to load a bedrock model not meant for cobblemon (example: Qlipoth Awakening)
|
- Fixed Cobblemon crashing if it tries to load a bedrock model not meant for cobblemon (example: Qlipoth Awakening)
|
||||||
- Fixed Berries (and thus mulches) not being plantable on Farmers delight rich soil farmland
|
- Fixed Berries (and thus mulches) not being plantable on Farmers delight rich soil farmland
|
||||||
- Fixed wild Pokémon vanishing when third party mods try to tame them the "vanilla" way
|
- Fixed wild Pokémon vanishing when third party mods try to tame them the "vanilla" way
|
||||||
- Fixed Pokemon not being able to path over skulk veins, pressure plates, fence gates, signs, lanterns, chains, and many other short blocks.
|
- Fixed Pokémon not being able to path over skulk veins, pressure plates, fence gates, signs, lanterns, chains, and many other short blocks.
|
||||||
- Fixed some cases in which Pokemon could not path over fence posts situations.
|
- Fixed some cases in which Pokémon could not path over fence posts situations.
|
||||||
- Fixed flyers not being able to do vertical takeoff if surrounded by blocks.
|
- Fixed flyers not being able to do vertical takeoff if surrounded by blocks.
|
||||||
- Fixed swimming Pokemon attempting to swim up through solid blocks.
|
- Fixed swimming Pokémon attempting to swim up through solid blocks.
|
||||||
- Fixed Pokemon surface swimming diving downward a block for the duration of the swim.
|
- Fixed Pokémon surface swimming diving downward a block for the duration of the swim.
|
||||||
- Improved flyers avoiding getting stuck on fence posts.
|
- Improved flyers avoiding getting stuck on fence posts.
|
||||||
|
- Fixed air balloon battle text not correctly displaying the Pokémon or item name
|
||||||
|
- Fixed an issue where items retrieved from a Display case would disappear if a player's inventory is full
|
||||||
|
- Fixed Pokédex Scanner not respecting the "Invert Mouse" option.
|
||||||
|
- Fixed a crash due to a ConcurrentModificationException that could occur during world generation.
|
||||||
|
- Fixed Moon Ball moon phase logic to actually work correctly
|
||||||
- Fixed recoil eyes on Shellder & Cloyster.
|
- Fixed recoil eyes on Shellder & Cloyster.
|
||||||
- Fixed Shroomish spinning at lightning speed when fainting (no longer allowed to let it rip.)
|
- Fixed Shroomish spinning at lightning speed when fainting (no longer allowed to let it rip.)
|
||||||
- Fixed Quaxly's animations showing hidden wing sets
|
- Fixed Quaxly's animations showing hidden wing sets
|
||||||
@@ -324,7 +332,9 @@
|
|||||||
- Added `Pokemon#hyperTrainIV()` and `IVs#setHyperTrainedIV(Stat, Int)`.
|
- Added `Pokemon#hyperTrainIV()` and `IVs#setHyperTrainedIV(Stat, Int)`.
|
||||||
- Added `HyperTrainedIvEvent.Pre` and `HyperTrainedIvEvent.Post`.
|
- Added `HyperTrainedIvEvent.Pre` and `HyperTrainedIvEvent.Post`.
|
||||||
- Added a `hoverText` option to PartySelectCallback, to display a tooltip on hovering over a Pokémon in the selection screen.
|
- Added a `hoverText` option to PartySelectCallback, to display a tooltip on hovering over a Pokémon in the selection screen.
|
||||||
|
- `PokemonEntity` instances spawned into the world now appropriately finalize the spawn for mod compatibility.
|
||||||
|
- Added PokedexManager.obtain as a replacement for .catch which is not a friendly function name in Java.
|
||||||
|
|
||||||
### MoLang & Datapacks
|
### MoLang & Datapacks
|
||||||
- The following usages for item predicates can now use item conditions like advancements do, you can learn about them in the [Minecraft wiki](https://minecraft.wiki/w/Advancement_definition#minecraft:filled_bucket)
|
- The following usages for item predicates can now use item conditions like advancements do, you can learn about them in the [Minecraft wiki](https://minecraft.wiki/w/Advancement_definition#minecraft:filled_bucket)
|
||||||
- The `requiredContext` for an item interaction evolution
|
- The `requiredContext` for an item interaction evolution
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.compat;
|
|||||||
import com.cobblemon.mod.common.CobblemonEntities;
|
import com.cobblemon.mod.common.CobblemonEntities;
|
||||||
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer;
|
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer;
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||||
|
import com.cobblemon.mod.common.item.PokedexItem;
|
||||||
import com.cobblemon.mod.common.pokemon.FormData;
|
import com.cobblemon.mod.common.pokemon.FormData;
|
||||||
import com.cobblemon.mod.common.pokemon.lighthing.LightingData;
|
import com.cobblemon.mod.common.pokemon.lighthing.LightingData;
|
||||||
import dev.lambdaurora.lambdynlights.LambDynLights;
|
import dev.lambdaurora.lambdynlights.LambDynLights;
|
||||||
@@ -36,20 +37,20 @@ public class LambDynamicLightsCompat {
|
|||||||
public static void hookCompat() {
|
public static void hookCompat() {
|
||||||
// Pokémon entities
|
// Pokémon entities
|
||||||
DynamicLightHandlers.registerDynamicLightHandler(
|
DynamicLightHandlers.registerDynamicLightHandler(
|
||||||
CobblemonEntities.POKEMON,
|
CobblemonEntities.POKEMON,
|
||||||
DynamicLightHandler.makeHandler(
|
DynamicLightHandler.makeHandler(
|
||||||
LambDynamicLightsCompat::resolvedPokemonLightLevel,
|
LambDynamicLightsCompat::resolvedPokemonLightLevel,
|
||||||
pokemon -> false
|
pokemon -> false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Shouldered Pokémon
|
// Shouldered Pokémon
|
||||||
DynamicLightHandlers.registerDynamicLightHandler(
|
DynamicLightHandlers.registerDynamicLightHandler(
|
||||||
EntityType.PLAYER,
|
EntityType.PLAYER,
|
||||||
DynamicLightHandler.makeHandler(
|
DynamicLightHandler.makeHandler(
|
||||||
LambDynamicLightsCompat::resolvedShoulderLightLevel,
|
LambDynamicLightsCompat::resolvedPlayerLightLevel,
|
||||||
player -> false
|
player -> false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,11 +64,13 @@ public class LambDynamicLightsCompat {
|
|||||||
return Math.max(itemLightLevel, formLightLevel);
|
return Math.max(itemLightLevel, formLightLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int resolvedShoulderLightLevel(Player player) {
|
private static int resolvedPlayerLightLevel(Player player) {
|
||||||
var underwater = !player.level().getFluidState(BlockPos.containing(player.getX(), player.getEyeY(), player.getZ())).isEmpty();
|
var underwater = !player.level().getFluidState(BlockPos.containing(player.getX(), player.getEyeY(), player.getZ())).isEmpty();
|
||||||
final int leftLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityLeft()), underwater);
|
final int leftShoulderLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityLeft()), underwater);
|
||||||
final int rightLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityRight()), underwater);
|
final int rightShoulderLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityRight()), underwater);
|
||||||
return Math.max(leftLightLevel, rightLightLevel);
|
final int itemLightLevel = customHeldItemLightLevel(player.getMainHandItem(), player.getOffhandItem());
|
||||||
|
|
||||||
|
return Math.max(itemLightLevel, Math.max(leftShoulderLightLevel, rightShoulderLightLevel));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<Integer> extractFormLightLevel(@NotNull FormData form, boolean underwater) {
|
private static Optional<Integer> extractFormLightLevel(@NotNull FormData form, boolean underwater) {
|
||||||
@@ -83,14 +86,17 @@ public class LambDynamicLightsCompat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ItemStack item = shoulderData.getShownItem();
|
ItemStack item = shoulderData.getShownItem();
|
||||||
int itemLightLevel = item.isEmpty()?0:LambDynLights.getLuminanceFromItemStack(item, underwater);
|
int itemLightLevel = item.isEmpty() ? 0 :LambDynLights.getLuminanceFromItemStack(item, underwater);
|
||||||
int formLightLevel = extractFormLightLevel(shoulderData.getForm(), underwater).orElse(0);
|
int formLightLevel = extractFormLightLevel(shoulderData.getForm(), underwater).orElse(0);
|
||||||
|
|
||||||
return Math.max(itemLightLevel, formLightLevel);
|
return Math.max(itemLightLevel, formLightLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int customHeldItemLightLevel(ItemStack mainhand, ItemStack offhand) {
|
||||||
|
return (mainhand.getItem() instanceof PokedexItem || offhand.getItem() instanceof PokedexItem) ? 13 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean liquidGlowModeSupport(@NotNull LightingData.LiquidGlowMode liquidGlowMode, boolean underwater) {
|
private static boolean liquidGlowModeSupport(@NotNull LightingData.LiquidGlowMode liquidGlowMode, boolean underwater) {
|
||||||
return underwater ? liquidGlowMode.getGlowsUnderwater() : liquidGlowMode.getGlowsInLand();
|
return underwater ? liquidGlowMode.getGlowsUnderwater() : liquidGlowMode.getGlowsInLand();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,12 @@ import com.cobblemon.mod.common.block.SaccharineLeafBlock;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.objectweb.asm.Opcodes;
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
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;
|
||||||
import org.spongepowered.asm.mixin.injection.Desc;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
import org.spongepowered.asm.mixin.injection.Slice;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
@@ -42,8 +40,9 @@ public abstract class BeeEntityMixin {
|
|||||||
if (block instanceof SaccharineLeafBlock) {
|
if (block instanceof SaccharineLeafBlock) {
|
||||||
|
|
||||||
int age = blockState.getValue(SaccharineLeafBlock.Companion.getAGE());
|
int age = blockState.getValue(SaccharineLeafBlock.Companion.getAGE());
|
||||||
|
boolean waterlogged = blockState.getValue(BlockStateProperties.WATERLOGGED);
|
||||||
|
|
||||||
if (age < 2) {
|
if (age < 2 && !waterlogged) {
|
||||||
this.cobblemon$result = blockState.setValue(SaccharineLeafBlock.Companion.getAGE(), age + 1);
|
this.cobblemon$result = blockState.setValue(SaccharineLeafBlock.Companion.getAGE(), age + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.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));
|
||||||
|
}
|
||||||
|
Arrays
|
||||||
|
.stream(pokemon.getOccupiedSeats())
|
||||||
|
.filter(x -> !passengers.contains(x))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(Entity::stopRiding);
|
||||||
|
|
||||||
|
var occupiedSeats = Arrays.asList(pokemon.getOccupiedSeats());
|
||||||
|
passengers.stream()
|
||||||
|
.filter(x -> !occupiedSeats.contains(x))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(x -> x.startRiding(pokemon, true));
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+22
-11
@@ -9,20 +9,19 @@
|
|||||||
package com.cobblemon.mod.common.mixin;
|
package com.cobblemon.mod.common.mixin;
|
||||||
|
|
||||||
import com.cobblemon.mod.common.client.CobblemonClient;
|
import com.cobblemon.mod.common.client.CobblemonClient;
|
||||||
import com.cobblemon.mod.common.client.render.MatrixWrapper;
|
|
||||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel;
|
|
||||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState;
|
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState;
|
||||||
import com.cobblemon.mod.common.entity.PosableEntity;
|
import com.cobblemon.mod.common.entity.PosableEntity;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||||
|
import net.minecraft.client.resources.PlayerSkin;
|
||||||
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
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 org.joml.Vector3f;
|
|
||||||
import org.spongepowered.asm.mixin.Debug;
|
|
||||||
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.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -30,11 +29,6 @@ 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.Map;
|
import java.util.Map;
|
||||||
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
|
||||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
|
||||||
import net.minecraft.client.resources.PlayerSkin;
|
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
|
|
||||||
@Mixin(EntityRenderDispatcher.class)
|
@Mixin(EntityRenderDispatcher.class)
|
||||||
public class EntityRenderDispatcherMixin {
|
public class EntityRenderDispatcherMixin {
|
||||||
@@ -77,6 +71,23 @@ public class EntityRenderDispatcherMixin {
|
|||||||
0F,
|
0F,
|
||||||
1F
|
1F
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*if (locator.contains("middle")){
|
||||||
|
PoseStack.Pose pose = poseStack.last();
|
||||||
|
Vector3f vec = matrix.getMatrix().getRotation(new AxisAngle4f()).transform(new Vector3f(0, 0, -1));
|
||||||
|
buffer.addVertex(pose, pos.toVector3f()).setColor(0xffff00ff).setNormal(pose, vec.x, vec.y, vec.z); //Forward, pink
|
||||||
|
buffer.addVertex(pose, (float)(pos.x() + vec.x), (float)(pos.y() + vec.y), (float)(pos.z() + vec.z)).setColor(0xffff00ff).setNormal(pose, vec.x, vec.y, vec.z);
|
||||||
|
|
||||||
|
vec = matrix.getMatrix().getRotation(new AxisAngle4f()).transform(new Vector3f(0, 1, 0));
|
||||||
|
buffer.addVertex(pose, pos.toVector3f()).setColor(0xffffff00).setNormal(pose, vec.x, vec.y, vec.z); //Up, yellow
|
||||||
|
buffer.addVertex(pose, (float)(pos.x() + vec.x), (float)(pos.y() + vec.y), (float)(pos.z() + vec.z)).setColor(0xffffff00).setNormal(pose, vec.x, vec.y, vec.z);
|
||||||
|
|
||||||
|
vec = matrix.getMatrix().getRotation(new AxisAngle4f()).transform(new Vector3f(-1, 0, 0));
|
||||||
|
buffer.addVertex(pose, pos.toVector3f()).setColor(0xff00ffff).setNormal(pose, vec.x, vec.y, vec.z); //Left, cyan
|
||||||
|
buffer.addVertex(pose, (float)(pos.x() + vec.x), (float)(pos.y() + vec.y), (float)(pos.z() + vec.z)).setColor(0xff00ffff).setNormal(pose, vec.x, vec.y, vec.z);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
poseStack.popPose();
|
poseStack.popPose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -119,14 +119,12 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer implements O
|
|||||||
public HitResult pick(double hitDistance, float partialTicks, boolean hitFluids) {
|
public HitResult pick(double hitDistance, float partialTicks, boolean hitFluids) {
|
||||||
Entity vehicle = this.getVehicle();
|
Entity vehicle = this.getVehicle();
|
||||||
if (vehicle instanceof PokemonEntity pokemonEntity) {
|
if (vehicle instanceof PokemonEntity pokemonEntity) {
|
||||||
int seatIndex = pokemonEntity.getPassengers().indexOf(this);
|
|
||||||
Seat seat = pokemonEntity.getSeats().get(seatIndex);
|
|
||||||
|
|
||||||
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemonEntity.getDelegate();
|
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemonEntity.getDelegate();
|
||||||
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
|
String locatorName = delegate.getSeatLocator(this);
|
||||||
|
MatrixWrapper locator = delegate.getLocatorStates().get(locatorName);
|
||||||
|
|
||||||
if (locator == null) {
|
if (locator == null) {
|
||||||
super.pick(hitDistance, partialTicks, hitFluids);
|
return super.pick(hitDistance, partialTicks, hitFluids);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
|
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
|
||||||
@@ -138,7 +136,7 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer implements O
|
|||||||
|
|
||||||
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) {
|
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) {
|
||||||
PosableModel model = VaryingModelRepository.INSTANCE.getPoser(pokemonEntity.getPokemon().getSpecies().getResourceIdentifier(), new FloatingState());
|
PosableModel model = VaryingModelRepository.INSTANCE.getPoser(pokemonEntity.getPokemon().getSpecies().getResourceIdentifier(), new FloatingState());
|
||||||
offset.add(cobblemon$getFirstPersonOffset(model, seat));
|
offset.add(cobblemon$getFirstPersonOffset(model, locatorName));
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix3f orientation = controller.isActive() && controller.getOrientation() != null ? controller.getOrientation() : new Matrix3f();
|
Matrix3f orientation = controller.isActive() && controller.getOrientation() != null ? controller.getOrientation() : new Matrix3f();
|
||||||
@@ -160,11 +158,11 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer implements O
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private static @NotNull Vector3f cobblemon$getFirstPersonOffset(PosableModel model, Seat seat) {
|
private static @NotNull Vector3f cobblemon$getFirstPersonOffset(PosableModel model, String locatorName) {
|
||||||
Map<String, Vec3> cameraOffsets = model.getFirstPersonCameraOffset();
|
Map<String, Vec3> cameraOffsets = model.getFirstPersonCameraOffset();
|
||||||
|
|
||||||
if (cameraOffsets.containsKey(seat.getLocator())) {
|
if (cameraOffsets.containsKey(locatorName)) {
|
||||||
return cameraOffsets.get(seat.getLocator()).toVector3f();
|
return cameraOffsets.get(locatorName).toVector3f();
|
||||||
} else {
|
} else {
|
||||||
return new Vector3f(0f, 0f, 0f);
|
return new Vector3f(0f, 0f, 0f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import org.spongepowered.asm.mixin.Unique;
|
|||||||
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.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|
||||||
|
|
||||||
@Mixin(MouseHandler.class)
|
@Mixin(MouseHandler.class)
|
||||||
public abstract class MouseHandlerMixin {
|
public abstract class MouseHandlerMixin {
|
||||||
@@ -121,11 +120,12 @@ public abstract class MouseHandlerMixin {
|
|||||||
if (usageContext.getScanningGuiOpen()) {
|
if (usageContext.getScanningGuiOpen()) {
|
||||||
this.smoothTurnY.reset();
|
this.smoothTurnY.reset();
|
||||||
this.smoothTurnX.reset();
|
this.smoothTurnX.reset();
|
||||||
var defaultSensitivity = this.minecraft.options.sensitivity().get() * 0.6000000238418579 + 0.20000000298023224;
|
var defaultSensitivity = this.minecraft.options.sensitivity().get() * 0.6 + 0.2;
|
||||||
var spyglassSensitivity = Math.pow(defaultSensitivity, 3);
|
var spyglassSensitivity = Math.pow(defaultSensitivity, 3);
|
||||||
var lookSensitivity = spyglassSensitivity * 8.0;
|
var lookSensitivity = spyglassSensitivity * 8.0;
|
||||||
var sensitivity = Mth.lerp(usageContext.getFovMultiplier(), spyglassSensitivity, lookSensitivity);
|
var sensitivity = Mth.lerp(usageContext.getFovMultiplier(), spyglassSensitivity, lookSensitivity);
|
||||||
player.turn(this.accumulatedDX * sensitivity, (this.accumulatedDY * sensitivity));
|
var yRotationFlip = this.minecraft.options.invertYMouse().get() ? -1 : 1;
|
||||||
|
player.turn(this.accumulatedDX * sensitivity, (this.accumulatedDY * sensitivity * yRotationFlip));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.mixin.client.snapshots;
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.CobblemonBuildDetails;
|
||||||
|
import com.cobblemon.mod.common.client.gui.snapshots.SnapshotWarningScreen;
|
||||||
|
import com.cobblemon.mod.common.client.snapshots.SnapshotAcknowledgementData;
|
||||||
|
import com.cobblemon.mod.common.client.snapshots.SnapshotAcknowledgementReader;
|
||||||
|
import kotlin.Unit;
|
||||||
|
import net.minecraft.SharedConstants;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
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.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Mixin(Minecraft.class)
|
||||||
|
public final class SnapshotWarningMixin {
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private final Pattern VERSION = Pattern.compile("^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$");
|
||||||
|
|
||||||
|
@Inject(method = "addInitialScreens", at = @At("TAIL"))
|
||||||
|
public void cobblemon$addSnapshotWarningScreen(List<Function<Runnable, Screen>> output, CallbackInfo callback) {
|
||||||
|
if (CobblemonBuildDetails.SNAPSHOT && !this.cobblemon$isAcknowledged() && !SharedConstants.IS_RUNNING_IN_IDE) {
|
||||||
|
output.add((runnable) -> new SnapshotWarningScreen((acknowledgement, dsa) -> {
|
||||||
|
if (acknowledgement == SnapshotWarningScreen.Acknowledgement.NO) {
|
||||||
|
Minecraft.getInstance().stop();
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SnapshotAcknowledgementReader.INSTANCE.write(new SnapshotAcknowledgementData(CobblemonBuildDetails.VERSION, dsa));
|
||||||
|
|
||||||
|
runnable.run();
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
|
private boolean cobblemon$isAcknowledged() {
|
||||||
|
SnapshotAcknowledgementData data = SnapshotAcknowledgementReader.INSTANCE.read();
|
||||||
|
if (data == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matcher current = VERSION.matcher(CobblemonBuildDetails.VERSION);
|
||||||
|
current.find();
|
||||||
|
|
||||||
|
Matcher when = VERSION.matcher(data.getVersion());
|
||||||
|
when.find();
|
||||||
|
|
||||||
|
boolean alert = current.group("minor").compareTo(when.group("minor")) > 0 || current.group("major").compareTo(when.group("major")) > 0;
|
||||||
|
return !alert && data.getDontShowAgain();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -25,6 +25,8 @@ import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
|
|||||||
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
|
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
|
||||||
import com.cobblemon.mod.common.util.adapters.ExpressionOrEntityVariableAdapter
|
import com.cobblemon.mod.common.util.adapters.ExpressionOrEntityVariableAdapter
|
||||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
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.TaskConfigAdapter
|
||||||
import com.cobblemon.mod.common.util.adapters.TranslatedTextAdapter
|
import com.cobblemon.mod.common.util.adapters.TranslatedTextAdapter
|
||||||
import com.cobblemon.mod.common.util.cobblemonResource
|
import com.cobblemon.mod.common.util.cobblemonResource
|
||||||
@@ -39,6 +41,8 @@ import net.minecraft.resources.ResourceLocation
|
|||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.server.packs.PackType
|
import net.minecraft.server.packs.PackType
|
||||||
import net.minecraft.server.packs.resources.ResourceManager
|
import net.minecraft.server.packs.resources.ResourceManager
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
import net.minecraft.world.entity.schedule.Activity
|
import net.minecraft.world.entity.schedule.Activity
|
||||||
|
|
||||||
object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
|
object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
|
||||||
@@ -47,6 +51,8 @@ object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
|
|||||||
.registerTypeAdapter(Activity::class.java, ActivityAdapter)
|
.registerTypeAdapter(Activity::class.java, ActivityAdapter)
|
||||||
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
|
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
|
||||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||||
|
.registerTypeAdapter(MemoryModuleType::class.java, MemoryModuleTypeAdapter)
|
||||||
|
.registerTypeAdapter(SensorType::class.java, SensorTypeAdapter)
|
||||||
.registerTypeAdapter(BehaviourConfig::class.java, BehaviourConfigAdapter)
|
.registerTypeAdapter(BehaviourConfig::class.java, BehaviourConfigAdapter)
|
||||||
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
|
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
|
||||||
.registerTypeAdapter(
|
.registerTypeAdapter(
|
||||||
|
|||||||
@@ -34,13 +34,10 @@ import net.minecraft.resources.ResourceKey
|
|||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.util.valueproviders.UniformInt
|
import net.minecraft.util.valueproviders.UniformInt
|
||||||
import net.minecraft.world.effect.MobEffects
|
import net.minecraft.world.effect.MobEffects
|
||||||
import net.minecraft.world.entity.Entity
|
|
||||||
import net.minecraft.world.entity.EntityType
|
import net.minecraft.world.entity.EntityType
|
||||||
import net.minecraft.world.level.BlockGetter
|
import net.minecraft.world.level.BlockGetter
|
||||||
import net.minecraft.world.level.Level
|
|
||||||
import net.minecraft.world.level.block.*
|
import net.minecraft.world.level.block.*
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour
|
import net.minecraft.world.level.block.state.BlockBehaviour
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour.Properties
|
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.world.level.block.state.properties.BlockSetType
|
import net.minecraft.world.level.block.state.properties.BlockSetType
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.LIT
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties.LIT
|
||||||
@@ -179,7 +176,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
|||||||
@JvmField
|
@JvmField
|
||||||
val SACCHARINE_LOG = this.create("saccharine_log", SaccharineLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
|
val SACCHARINE_LOG = this.create("saccharine_log", SaccharineLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
|
||||||
@JvmField
|
@JvmField
|
||||||
val SACCHARINE_HONEY_LOG = this.create("saccharine_honey_log", SaccharineHoneyLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
|
val SACCHARINE_LOG_SLATHERED = this.create("saccharine_log_slathered", SaccharineLogSlatheredBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val STRIPPED_SACCHARINE_LOG = this.create("stripped_saccharine_log", RotatedPillarBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
|
val STRIPPED_SACCHARINE_LOG = this.create("stripped_saccharine_log", RotatedPillarBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
|
||||||
@@ -208,7 +205,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
|||||||
val SACCHARINE_FENCE = this.create("saccharine_fence", FenceBlock(BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
val SACCHARINE_FENCE = this.create("saccharine_fence", FenceBlock(BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||||
@JvmField
|
@JvmField
|
||||||
val SACCHARINE_FENCE_GATE = this.create("saccharine_fence_gate", FenceGateBlock(SACCHARINE_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
val SACCHARINE_FENCE_GATE = this.create("saccharine_fence_gate", FenceGateBlock(SACCHARINE_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
|
||||||
|
@JvmField
|
||||||
val SACCHARINE_BUTTON = this.create("saccharine_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
|
val SACCHARINE_BUTTON = this.create("saccharine_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
|
||||||
@JvmField
|
@JvmField
|
||||||
val SACCHARINE_PRESSURE_PLATE = this.create("saccharine_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).noCollission().strength(0.5f).sound(SoundType.WOOD)))
|
val SACCHARINE_PRESSURE_PLATE = this.create("saccharine_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).noCollission().strength(0.5f).sound(SoundType.WOOD)))
|
||||||
@@ -477,20 +474,20 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
|||||||
val GIMMIGHOUL_CHEST = create("gimmighoul_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.FAKE))
|
val GIMMIGHOUL_CHEST = create("gimmighoul_chest", GildedChestBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.CHEST).noOcclusion().sound(CobblemonSounds.GILDED_CHEST_SOUNDS), GildedChestBlock.Type.FAKE))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val MONITOR = create("monitor", MonitorBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).lightLevel { if (it.getValue(MonitorBlock.SCREEN) != MonitorBlock.MonitorScreen.OFF) 15 else 0 }))
|
val MONITOR = create("monitor", MonitorBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).lightLevel { if (it.getValue(MonitorBlock.SCREEN) != MonitorBlock.MonitorScreen.OFF) 13 else 0 }))
|
||||||
@JvmField
|
@JvmField
|
||||||
val FOSSIL_ANALYZER = create("fossil_analyzer", FossilAnalyzerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).noOcclusion()))
|
val FOSSIL_ANALYZER = create("fossil_analyzer", FossilAnalyzerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).noOcclusion()))
|
||||||
@JvmField
|
@JvmField
|
||||||
val RESTORATION_TANK = create("restoration_tank", RestorationTankBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.GLASS).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).noOcclusion()))
|
val RESTORATION_TANK = create("restoration_tank", RestorationTankBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.GLASS).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops().strength(5.0F, 6.0F).noOcclusion()))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val HEALING_MACHINE = create("healing_machine", HealingMachineBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2f).noOcclusion().lightLevel { if (it.getValue(HealingMachineBlock.CHARGE_LEVEL) >= HealingMachineBlock.MAX_CHARGE_LEVEL) 7 else 2 }))
|
val HEALING_MACHINE = create("healing_machine", HealingMachineBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2f).noOcclusion().lightLevel { if (it.getValue(HealingMachineBlock.CHARGE_LEVEL) >= HealingMachineBlock.MAX_CHARGE_LEVEL) 12 else 5 }))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val PC = create("pc", PCBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2F).noOcclusion().lightLevel { if ((it.getValue(PCBlock.ON) as Boolean) && (it.getValue(PCBlock.PART) == PCBlock.PCPart.TOP)) 10 else 0 }))
|
val PC = create("pc", PCBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2F).noOcclusion().lightLevel { if ((it.getValue(PCBlock.ON) as Boolean) && (it.getValue(PCBlock.PART) == PCBlock.PCPart.TOP)) 13 else 0 }))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val LECTERN = create("lectern", LecternBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).sound(SoundType.WOOD).strength(2.5F).ignitedByLava()))
|
val LECTERN = create("lectern", LecternBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).sound(SoundType.WOOD).strength(2.5F).ignitedByLava().lightLevel { if (it.getValue(LecternBlock.EMIT_LIGHT) as Boolean) 13 else 0 }))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val DISPLAY_CASE = create("display_case", DisplayCaseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F).requiresCorrectToolForDrops()))
|
val DISPLAY_CASE = create("display_case", DisplayCaseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F).requiresCorrectToolForDrops()))
|
||||||
@@ -499,7 +496,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
|||||||
val INCENSE_SWEET = create("incense_sweet", SweetIncenseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3f)))
|
val INCENSE_SWEET = create("incense_sweet", SweetIncenseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3f)))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val PASTURE = create("pasture", PastureBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BROWN).sound(SoundType.WOOD).strength(2F).noOcclusion().pushReaction(PushReaction.BLOCK).lightLevel { if ((it.getValue(PastureBlock.ON) as Boolean) && (it.getValue(PastureBlock.PART) == PastureBlock.PasturePart.TOP)) 10 else 0 }))
|
val PASTURE = create("pasture", PastureBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BROWN).sound(SoundType.WOOD).strength(2F).noOcclusion().pushReaction(PushReaction.BLOCK).lightLevel { if ((it.getValue(PastureBlock.ON) as Boolean) && (it.getValue(PastureBlock.PART) == PastureBlock.PasturePart.TOP)) 13 else 0 }))
|
||||||
|
|
||||||
val RED_MINT = create("red_mint", MintBlock(MintType.RED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_RED).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MINT_SOUNDS).pushReaction(PushReaction.DESTROY)))
|
val RED_MINT = create("red_mint", MintBlock(MintType.RED, BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_RED).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MINT_SOUNDS).pushReaction(PushReaction.DESTROY)))
|
||||||
@JvmField
|
@JvmField
|
||||||
@@ -523,7 +520,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
|||||||
val HEARTY_GRAINS = this.create("hearty_grains", HeartyGrainsBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.PLANT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.VIVICHOKE_SOUNDS)))
|
val HEARTY_GRAINS = this.create("hearty_grains", HeartyGrainsBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.PLANT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.VIVICHOKE_SOUNDS)))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val GALARICA_NUT_BUSH = this.create("galarica_nut_bush", NutBushBlock(Properties.of().mapColor(MapColor.PLANT).randomTicks().noCollission().sound(SoundType.SWEET_BERRY_BUSH).pushReaction(PushReaction.DESTROY)))
|
val GALARICA_NUT_BUSH = this.create("galarica_nut_bush", NutBushBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).randomTicks().noCollission().sound(SoundType.SWEET_BERRY_BUSH).pushReaction(PushReaction.DESTROY)))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val POTTED_RED_APRICORN_SAPLING = this.create("potted_red_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(RED_APRICORN_SAPLING))
|
val POTTED_RED_APRICORN_SAPLING = this.create("potted_red_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(RED_APRICORN_SAPLING))
|
||||||
@@ -545,9 +542,9 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
|||||||
@JvmField
|
@JvmField
|
||||||
val HEARTY_GRAIN_BALE = this.create("hearty_grain_bale", BaleBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).instrument(NoteBlockInstrument.BANJO).strength(0.5F).sound(SoundType.GRASS)))
|
val HEARTY_GRAIN_BALE = this.create("hearty_grain_bale", BaleBlock(BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).instrument(NoteBlockInstrument.BANJO).strength(0.5F).sound(SoundType.GRASS)))
|
||||||
@JvmField
|
@JvmField
|
||||||
val TATAMI_BLOCK = this.create("tatami_block", HorizontalRotationalBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).strength(0.1F).sound(SoundType.GRASS)))
|
val TATAMI_BLOCK = this.create("tatami_block", HorizontalRotationalBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).strength(0.1F).sound(SoundType.MOSS_CARPET)))
|
||||||
@JvmField
|
@JvmField
|
||||||
val TATAMI_MAT = this.create("tatami_mat", HorizontalRotationCarpetBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).strength(0.1F).sound(SoundType.GRASS)))
|
val TATAMI_MAT = this.create("tatami_mat", HorizontalRotationCarpetBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).strength(0.1F).sound(SoundType.MOSS_CARPET)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a map of all the blocks that can be stripped with an axe in the format of input - output.
|
* Returns a map of all the blocks that can be stripped with an axe in the format of input - output.
|
||||||
@@ -559,11 +556,9 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
|||||||
APRICORN_LOG to STRIPPED_APRICORN_LOG,
|
APRICORN_LOG to STRIPPED_APRICORN_LOG,
|
||||||
SACCHARINE_WOOD to STRIPPED_SACCHARINE_WOOD,
|
SACCHARINE_WOOD to STRIPPED_SACCHARINE_WOOD,
|
||||||
SACCHARINE_LOG to STRIPPED_SACCHARINE_LOG,
|
SACCHARINE_LOG to STRIPPED_SACCHARINE_LOG,
|
||||||
SACCHARINE_HONEY_LOG to STRIPPED_SACCHARINE_LOG
|
SACCHARINE_LOG_SLATHERED to STRIPPED_SACCHARINE_LOG
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private fun apricornBlock(name: String, apricorn: Apricorn): ApricornBlock = this.create(name, ApricornBlock(BlockBehaviour.Properties.of().mapColor(apricorn.mapColor()).randomTicks().strength(Blocks.OAK_LOG.defaultDestroyTime(), Blocks.OAK_LOG.explosionResistance).sound(SoundType.WOOD).noOcclusion(), apricorn))
|
private fun apricornBlock(name: String, apricorn: Apricorn): ApricornBlock = this.create(name, ApricornBlock(BlockBehaviour.Properties.of().mapColor(apricorn.mapColor()).randomTicks().strength(Blocks.OAK_LOG.defaultDestroyTime(), Blocks.OAK_LOG.explosionResistance).sound(SoundType.WOOD).noOcclusion(), apricorn))
|
||||||
|
|
||||||
private fun tumblestoneBlock(name: String, stage: Int, height: Int, xzOffset: Int, nextStage: Block?) : Block {
|
private fun tumblestoneBlock(name: String, stage: Int, height: Int, xzOffset: Int, nextStage: Block?) : Block {
|
||||||
@@ -663,7 +658,19 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
|||||||
Triple(APRICORN_FENCE, 5, 20),
|
Triple(APRICORN_FENCE, 5, 20),
|
||||||
Triple(APRICORN_FENCE_GATE, 5, 20),
|
Triple(APRICORN_FENCE_GATE, 5, 20),
|
||||||
Triple(APRICORN_SLAB, 5, 20),
|
Triple(APRICORN_SLAB, 5, 20),
|
||||||
Triple(APRICORN_STAIRS, 5, 20)
|
Triple(APRICORN_STAIRS, 5, 20),
|
||||||
|
Triple(SACCHARINE_LOG, 5, 5),
|
||||||
|
Triple(SACCHARINE_LOG_SLATHERED, 5, 5),
|
||||||
|
Triple(STRIPPED_SACCHARINE_LOG, 5, 5),
|
||||||
|
Triple(SACCHARINE_WOOD, 5, 5),
|
||||||
|
Triple(STRIPPED_SACCHARINE_WOOD, 5, 5),
|
||||||
|
Triple(SACCHARINE_PLANKS, 5, 20),
|
||||||
|
Triple(SACCHARINE_LEAVES, 30, 60),
|
||||||
|
Triple(SACCHARINE_FENCE, 5, 20),
|
||||||
|
Triple(SACCHARINE_FENCE_GATE, 5, 20),
|
||||||
|
Triple(SACCHARINE_SLAB, 5, 20),
|
||||||
|
Triple(SACCHARINE_STAIRS, 5, 20)
|
||||||
|
|
||||||
).onEach{ data -> setFlammable(data.first, data.second, data.third) }
|
).onEach{ data -> setFlammable(data.first, data.second, data.third) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
|||||||
@JvmField
|
@JvmField
|
||||||
val SACCHARINE_LOG = blockItem("saccharine_log", CobblemonBlocks.SACCHARINE_LOG)
|
val SACCHARINE_LOG = blockItem("saccharine_log", CobblemonBlocks.SACCHARINE_LOG)
|
||||||
@JvmField
|
@JvmField
|
||||||
val SACCHARINE_HONEY_LOG = blockItem("saccharine_honey_log", CobblemonBlocks.SACCHARINE_HONEY_LOG)
|
val SACCHARINE_LOG_SLATHERED = blockItem("saccharine_log_slathered", CobblemonBlocks.SACCHARINE_LOG_SLATHERED)
|
||||||
@JvmField
|
@JvmField
|
||||||
val STRIPPED_SACCHARINE_LOG = blockItem("stripped_saccharine_log", CobblemonBlocks.STRIPPED_SACCHARINE_LOG)
|
val STRIPPED_SACCHARINE_LOG = blockItem("stripped_saccharine_log", CobblemonBlocks.STRIPPED_SACCHARINE_LOG)
|
||||||
@JvmField
|
@JvmField
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common
|
package com.cobblemon.mod.common
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.api.ai.CobblemonAttackTargetData
|
||||||
import com.cobblemon.mod.common.api.dialogue.ActiveDialogue
|
import com.cobblemon.mod.common.api.dialogue.ActiveDialogue
|
||||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
@@ -46,6 +47,7 @@ object CobblemonMemories {
|
|||||||
val HERD_LEADER = register<String>("herd_leader", PrimitiveCodec.STRING)
|
val HERD_LEADER = register<String>("herd_leader", PrimitiveCodec.STRING)
|
||||||
/** how many are following me rn? */
|
/** how many are following me rn? */
|
||||||
val HERD_SIZE = register<Int>("herd_size") // Don't bother saving it, we'll try to keep count roughly.
|
val HERD_SIZE = register<Int>("herd_size") // Don't bother saving it, we'll try to keep count roughly.
|
||||||
|
val ATTACK_TARGET_DATA = register<CobblemonAttackTargetData>("attack_target_data") // This is used to store additional information about the attack target, such as when to give up pursuit.
|
||||||
|
|
||||||
fun <U> register(id: String, codec: Codec<U>): MemoryModuleType<U> {
|
fun <U> register(id: String, codec: Codec<U>): MemoryModuleType<U> {
|
||||||
val memoryModule = MemoryModuleType(Optional.of(codec))
|
val memoryModule = MemoryModuleType(Optional.of(codec))
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import com.cobblemon.mod.common.client.net.pasture.ClosePastureHandler
|
|||||||
import com.cobblemon.mod.common.client.net.pasture.OpenPastureHandler
|
import com.cobblemon.mod.common.client.net.pasture.OpenPastureHandler
|
||||||
import com.cobblemon.mod.common.client.net.pasture.PokemonPasturedHandler
|
import com.cobblemon.mod.common.client.net.pasture.PokemonPasturedHandler
|
||||||
import com.cobblemon.mod.common.client.net.pasture.PokemonUnpasturedHandler
|
import com.cobblemon.mod.common.client.net.pasture.PokemonUnpasturedHandler
|
||||||
|
import com.cobblemon.mod.common.client.net.pasture.UpdatePastureConflictFlagHandler
|
||||||
import com.cobblemon.mod.common.client.net.pokedex.ServerConfirmedRegisterHandler
|
import com.cobblemon.mod.common.client.net.pokedex.ServerConfirmedRegisterHandler
|
||||||
import com.cobblemon.mod.common.client.net.pokemon.update.ClientboundUpdateRidingStateHandler
|
import com.cobblemon.mod.common.client.net.pokemon.update.ClientboundUpdateRidingStateHandler
|
||||||
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
|
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
|
||||||
@@ -85,6 +86,7 @@ import com.cobblemon.mod.common.net.messages.client.pasture.ClosePasturePacket
|
|||||||
import com.cobblemon.mod.common.net.messages.client.pasture.OpenPasturePacket
|
import com.cobblemon.mod.common.net.messages.client.pasture.OpenPasturePacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonPasturedPacket
|
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonPasturedPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonUnpasturedPacket
|
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonUnpasturedPacket
|
||||||
|
import com.cobblemon.mod.common.net.messages.client.pasture.UpdatePastureConflictFlagPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.pokedex.ServerConfirmedRegisterPacket
|
import com.cobblemon.mod.common.net.messages.client.pokedex.ServerConfirmedRegisterPacket
|
||||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.*
|
import com.cobblemon.mod.common.net.messages.client.pokemon.update.*
|
||||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.AddEvolutionPacket
|
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.AddEvolutionPacket
|
||||||
@@ -140,6 +142,7 @@ import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamRequestPack
|
|||||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamResponsePacket
|
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamResponsePacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
|
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
|
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
|
||||||
|
import com.cobblemon.mod.common.net.messages.server.behaviour.DamageOnCollisionPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.behaviour.SetEntityBehaviourPacket
|
import com.cobblemon.mod.common.net.messages.server.behaviour.SetEntityBehaviourPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.block.AdjustBlockEntityViewerCountPacket
|
import com.cobblemon.mod.common.net.messages.server.block.AdjustBlockEntityViewerCountPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectCancelledPacket
|
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectCancelledPacket
|
||||||
@@ -155,6 +158,7 @@ import com.cobblemon.mod.common.net.messages.server.dialogue.InputToDialoguePack
|
|||||||
import com.cobblemon.mod.common.net.messages.server.npc.SaveNPCPacket
|
import com.cobblemon.mod.common.net.messages.server.npc.SaveNPCPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.orientation.ServerboundUpdateOrientationPacket
|
import com.cobblemon.mod.common.net.messages.server.orientation.ServerboundUpdateOrientationPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.pasture.PasturePokemonPacket
|
import com.cobblemon.mod.common.net.messages.server.pasture.PasturePokemonPacket
|
||||||
|
import com.cobblemon.mod.common.net.messages.server.pasture.SetPastureConflictPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.pasture.UnpastureAllPokemonPacket
|
import com.cobblemon.mod.common.net.messages.server.pasture.UnpastureAllPokemonPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.pasture.UnpasturePokemonPacket
|
import com.cobblemon.mod.common.net.messages.server.pasture.UnpasturePokemonPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.FinishScanningPacket
|
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.FinishScanningPacket
|
||||||
@@ -166,6 +170,7 @@ import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetActiveMark
|
|||||||
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.ServerboundUpdateRidingStatePacket
|
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
|
||||||
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.riding.DismountPokemonPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.starter.RequestStarterScreenPacket
|
import com.cobblemon.mod.common.net.messages.server.starter.RequestStarterScreenPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.storage.SwapPCPartyPokemonPacket
|
import com.cobblemon.mod.common.net.messages.server.storage.SwapPCPartyPokemonPacket
|
||||||
import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokemonPacket
|
import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokemonPacket
|
||||||
@@ -187,6 +192,7 @@ import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
|
|||||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamLeaveHandler
|
import com.cobblemon.mod.common.net.serverhandling.battle.TeamLeaveHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestHandler
|
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestResponseHandler
|
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestResponseHandler
|
||||||
|
import com.cobblemon.mod.common.net.serverhandling.behaviour.DamageOnCollisionPacketHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.behaviour.SetEntityBehaviourHandler
|
import com.cobblemon.mod.common.net.serverhandling.behaviour.SetEntityBehaviourHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.block.AdjustBlockEntityViewerCountHandler
|
import com.cobblemon.mod.common.net.serverhandling.block.AdjustBlockEntityViewerCountHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectCancelledHandler
|
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectCancelledHandler
|
||||||
@@ -203,6 +209,7 @@ import com.cobblemon.mod.common.net.serverhandling.evolution.AcceptEvolutionHand
|
|||||||
import com.cobblemon.mod.common.net.serverhandling.npc.SaveNPCHandler
|
import com.cobblemon.mod.common.net.serverhandling.npc.SaveNPCHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.orientation.OrientationPacketHandler
|
import com.cobblemon.mod.common.net.serverhandling.orientation.OrientationPacketHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.pasture.PasturePokemonHandler
|
import com.cobblemon.mod.common.net.serverhandling.pasture.PasturePokemonHandler
|
||||||
|
import com.cobblemon.mod.common.net.serverhandling.pasture.SetPastureConflictHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.pasture.UnpastureAllPokemonHandler
|
import com.cobblemon.mod.common.net.serverhandling.pasture.UnpastureAllPokemonHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.pasture.UnpasturePokemonHandler
|
import com.cobblemon.mod.common.net.serverhandling.pasture.UnpasturePokemonHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.FinishScanningHandler
|
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.FinishScanningHandler
|
||||||
@@ -213,6 +220,7 @@ import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetNicknameHan
|
|||||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetActiveMarkHandler
|
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetActiveMarkHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetMarkingsHandler
|
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetMarkingsHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.ServerboundUpdateRidingStateHandler
|
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.ServerboundUpdateRidingStateHandler
|
||||||
|
import com.cobblemon.mod.common.net.serverhandling.riding.DismountPokemonPacketHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.starter.RequestStarterScreenHandler
|
import com.cobblemon.mod.common.net.serverhandling.starter.RequestStarterScreenHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.starter.SelectStarterPacketHandler
|
import com.cobblemon.mod.common.net.serverhandling.starter.SelectStarterPacketHandler
|
||||||
import com.cobblemon.mod.common.net.serverhandling.storage.BenchMoveHandler
|
import com.cobblemon.mod.common.net.serverhandling.storage.BenchMoveHandler
|
||||||
@@ -418,6 +426,7 @@ object CobblemonNetwork {
|
|||||||
list.add(PacketRegisterInfo(ClosePasturePacket.ID, ClosePasturePacket::decode, ClosePastureHandler))
|
list.add(PacketRegisterInfo(ClosePasturePacket.ID, ClosePasturePacket::decode, ClosePastureHandler))
|
||||||
list.add(PacketRegisterInfo(PokemonPasturedPacket.ID, PokemonPasturedPacket::decode, PokemonPasturedHandler))
|
list.add(PacketRegisterInfo(PokemonPasturedPacket.ID, PokemonPasturedPacket::decode, PokemonPasturedHandler))
|
||||||
list.add(PacketRegisterInfo(PokemonUnpasturedPacket.ID, PokemonUnpasturedPacket::decode, PokemonUnpasturedHandler))
|
list.add(PacketRegisterInfo(PokemonUnpasturedPacket.ID, PokemonUnpasturedPacket::decode, PokemonUnpasturedHandler))
|
||||||
|
list.add(PacketRegisterInfo(UpdatePastureConflictFlagPacket.ID, UpdatePastureConflictFlagPacket::decode, UpdatePastureConflictFlagHandler))
|
||||||
|
|
||||||
// Orientation
|
// Orientation
|
||||||
list.add(PacketRegisterInfo(ClientboundUpdateOrientationPacket.ID, ClientboundUpdateOrientationPacket::decode, S2CUpdateOrientationHandler))
|
list.add(PacketRegisterInfo(ClientboundUpdateOrientationPacket.ID, ClientboundUpdateOrientationPacket::decode, S2CUpdateOrientationHandler))
|
||||||
@@ -528,6 +537,8 @@ object CobblemonNetwork {
|
|||||||
list.add(PacketRegisterInfo(PasturePokemonPacket.ID, PasturePokemonPacket::decode, PasturePokemonHandler))
|
list.add(PacketRegisterInfo(PasturePokemonPacket.ID, PasturePokemonPacket::decode, PasturePokemonHandler))
|
||||||
list.add(PacketRegisterInfo(UnpasturePokemonPacket.ID, UnpasturePokemonPacket::decode, UnpasturePokemonHandler))
|
list.add(PacketRegisterInfo(UnpasturePokemonPacket.ID, UnpasturePokemonPacket::decode, UnpasturePokemonHandler))
|
||||||
list.add(PacketRegisterInfo(UnpastureAllPokemonPacket.ID, UnpastureAllPokemonPacket::decode, UnpastureAllPokemonHandler))
|
list.add(PacketRegisterInfo(UnpastureAllPokemonPacket.ID, UnpastureAllPokemonPacket::decode, UnpastureAllPokemonHandler))
|
||||||
|
list.add(PacketRegisterInfo(SetPastureConflictPacket.ID, SetPastureConflictPacket::decode, SetPastureConflictHandler))
|
||||||
|
|
||||||
|
|
||||||
// Block entity
|
// Block entity
|
||||||
list.add(PacketRegisterInfo(AdjustBlockEntityViewerCountPacket.ID, AdjustBlockEntityViewerCountPacket::decode, AdjustBlockEntityViewerCountHandler))
|
list.add(PacketRegisterInfo(AdjustBlockEntityViewerCountPacket.ID, AdjustBlockEntityViewerCountPacket::decode, AdjustBlockEntityViewerCountHandler))
|
||||||
@@ -556,12 +567,14 @@ object CobblemonNetwork {
|
|||||||
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatePacket.ID, ServerboundUpdateRidingStatePacket::decode, ServerboundUpdateRidingStateHandler))
|
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatePacket.ID, ServerboundUpdateRidingStatePacket::decode, ServerboundUpdateRidingStateHandler))
|
||||||
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatsPacket.ID, ServerboundUpdateRidingStatsPacket::decode, ServerboundUpdateRidingStatsHandler))
|
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatsPacket.ID, ServerboundUpdateRidingStatsPacket::decode, ServerboundUpdateRidingStatsHandler))
|
||||||
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatRangePacket.ID, ServerboundUpdateRidingStatRangePacket::decode, ServerboundUpdateRidingStatRangeHandler))
|
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatRangePacket.ID, ServerboundUpdateRidingStatRangePacket::decode, ServerboundUpdateRidingStatRangeHandler))
|
||||||
|
list.add(PacketRegisterInfo(DismountPokemonPacket.ID, DismountPokemonPacket::decode, DismountPokemonPacketHandler))
|
||||||
|
|
||||||
// Cooking
|
// Cooking
|
||||||
list.add(PacketRegisterInfo(ToggleCookingPotLidPacket.ID, ToggleCookingPotLidPacket::decode, ToggleCookingPotLidHandler))
|
list.add(PacketRegisterInfo(ToggleCookingPotLidPacket.ID, ToggleCookingPotLidPacket::decode, ToggleCookingPotLidHandler))
|
||||||
|
|
||||||
// Behaviour Packets
|
// Behaviour Packets
|
||||||
list.add(PacketRegisterInfo(SetEntityBehaviourPacket.ID, SetEntityBehaviourPacket::decode, SetEntityBehaviourHandler))
|
list.add(PacketRegisterInfo(SetEntityBehaviourPacket.ID, SetEntityBehaviourPacket::decode, SetEntityBehaviourHandler))
|
||||||
|
list.add(PacketRegisterInfo(DamageOnCollisionPacket.ID, DamageOnCollisionPacket::decode, DamageOnCollisionPacketHandler))
|
||||||
|
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,23 +24,18 @@ object CobblemonPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Regist
|
|||||||
override val resourceKey: ResourceKey<Registry<PoiType>> = Registries.POINT_OF_INTEREST_TYPE
|
override val resourceKey: ResourceKey<Registry<PoiType>> = Registries.POINT_OF_INTEREST_TYPE
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val NURSE_KEY: ResourceKey<PoiType> = createKey("nurse")
|
val NURSE_KEY = createKey("nurse", CobblemonBlocks.HEALING_MACHINE, 1, 1)
|
||||||
@JvmField
|
@JvmField
|
||||||
val NURSE = create(NURSE_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.HEALING_MACHINE), 1, 1))
|
val LURE_CAKE_KEY = createKey("lure_cake", CobblemonBlocks.LURE_CAKE, 0, 1)
|
||||||
@JvmField
|
@JvmField
|
||||||
val LURE_CAKE_KEY: ResourceKey<PoiType> = createKey("lure_cake")
|
val SACCHARINE_LOG_SLATHERED_KEY = createKey("saccharine_log_slathered", CobblemonBlocks.SACCHARINE_LOG_SLATHERED, 0, 1)
|
||||||
@JvmField
|
@JvmField
|
||||||
val LURE_CAKE = create(LURE_CAKE_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.LURE_CAKE), 0, 1))
|
val INCENSE_SWEET_KEY = createKey("incense_sweet", CobblemonBlocks.INCENSE_SWEET, 0, 1)
|
||||||
@JvmField
|
|
||||||
val SACCHARINE_HONEY_LOG_KEY: ResourceKey<PoiType> = createKey("saccharine_honey_log")
|
|
||||||
@JvmField
|
|
||||||
val SACCHARINE_HONEY_LOG = create(SACCHARINE_HONEY_LOG_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.SACCHARINE_HONEY_LOG), 0, 1))
|
|
||||||
@JvmField
|
|
||||||
val INCENSE_SWEET_KEY: ResourceKey<PoiType> = createKey("incense_sweet")
|
|
||||||
@JvmField
|
|
||||||
val INCENSE_SWEET = create(INCENSE_SWEET_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.INCENSE_SWEET), 0, 1))
|
|
||||||
|
|
||||||
private fun createKey(string: String): ResourceKey<PoiType> = ResourceKey.create(Registries.POINT_OF_INTEREST_TYPE, cobblemonResource(string))
|
private fun createKey(string: String, block: Block, maxTickets: Int, validRange: Int ): ResourceKey<PoiType> =
|
||||||
|
ResourceKey.create(Registries.POINT_OF_INTEREST_TYPE, cobblemonResource(string)).also { resourceKey ->
|
||||||
|
create(resourceKey.location().path, PoiType(getBlockStates(block), maxTickets, validRange))
|
||||||
|
}
|
||||||
|
|
||||||
private fun getBlockStates(block: Block): Set<BlockState> = ImmutableSet.copyOf(block.stateDefinition.possibleStates)
|
private fun getBlockStates(block: Block): Set<BlockState> = ImmutableSet.copyOf(block.stateDefinition.possibleStates)
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-2
@@ -10,8 +10,11 @@ package com.cobblemon.mod.common.api.ai
|
|||||||
|
|
||||||
import com.cobblemon.mod.common.api.ai.config.BehaviourConfig
|
import com.cobblemon.mod.common.api.ai.config.BehaviourConfig
|
||||||
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||||
|
import com.mojang.serialization.Dynamic
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
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.sensing.SensorType
|
||||||
import net.minecraft.world.entity.schedule.Activity
|
import net.minecraft.world.entity.schedule.Activity
|
||||||
import net.minecraft.world.entity.schedule.Schedule
|
import net.minecraft.world.entity.schedule.Schedule
|
||||||
|
|
||||||
@@ -22,13 +25,30 @@ class BehaviourConfigurationContext {
|
|||||||
var coreActivities = setOf(Activity.CORE)
|
var coreActivities = setOf(Activity.CORE)
|
||||||
val activities = mutableListOf<ActivityConfigurationContext>()
|
val activities = mutableListOf<ActivityConfigurationContext>()
|
||||||
val schedule = Schedule.EMPTY
|
val schedule = Schedule.EMPTY
|
||||||
|
val memories = mutableSetOf<MemoryModuleType<*>>()
|
||||||
|
val sensors = mutableSetOf<SensorType<*>>()
|
||||||
|
|
||||||
fun getOrCreateActivity(activity: Activity): ActivityConfigurationContext {
|
fun getOrCreateActivity(activity: Activity): ActivityConfigurationContext {
|
||||||
return activities.firstOrNull { it.activity == activity } ?: ActivityConfigurationContext(activity).also(activities::add)
|
return activities.firstOrNull { it.activity == activity } ?: ActivityConfigurationContext(activity).also(activities::add)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun apply(entity: LivingEntity, behaviourConfigs: List<BehaviourConfig>) {
|
fun addMemories(vararg memory: MemoryModuleType<*>) {
|
||||||
val brain = entity.brain
|
memories.addAll(memory)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addMemories(memories: Collection<MemoryModuleType<*>>) {
|
||||||
|
this.memories.addAll(memories)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addSensors(vararg sensor: SensorType<*>) {
|
||||||
|
sensors.addAll(sensor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addSensors(sensors: Collection<SensorType<*>>) {
|
||||||
|
this.sensors.addAll(sensors)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun apply(entity: LivingEntity, behaviourConfigs: List<BehaviourConfig>, dynamic: Dynamic<*>) {
|
||||||
|
|
||||||
if (entity is MoLangScriptingEntity) {
|
if (entity is MoLangScriptingEntity) {
|
||||||
entity.registerVariables(behaviourConfigs.flatMap { it.getVariables(entity) })
|
entity.registerVariables(behaviourConfigs.flatMap { it.getVariables(entity) })
|
||||||
@@ -38,7 +58,11 @@ class BehaviourConfigurationContext {
|
|||||||
// Setup the brain config
|
// Setup the brain config
|
||||||
behaviourConfigs.forEach { it.configure(entity, this) }
|
behaviourConfigs.forEach { it.configure(entity, this) }
|
||||||
|
|
||||||
|
var brain = entity.brain
|
||||||
// Apply the brain config
|
// Apply the brain config
|
||||||
|
if (entity is MoLangScriptingEntity) {
|
||||||
|
brain = entity.assignNewBrainWithMemoriesAndSensors(dynamic, memories, sensors)
|
||||||
|
}
|
||||||
activities.forEach { it.apply(entity) }
|
activities.forEach { it.apply(entity) }
|
||||||
brain.setCoreActivities(coreActivities)
|
brain.setCoreActivities(coreActivities)
|
||||||
brain.setDefaultActivity(defaultActivity)
|
brain.setDefaultActivity(defaultActivity)
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.api.ai
|
||||||
|
|
||||||
|
import com.bedrockk.molang.Expression
|
||||||
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is used in the AI system to store optional additional information about the attack target,
|
||||||
|
* mainly things like when to give up pursuit, what sort of attacks are permitted, whatever. It's
|
||||||
|
* a temporary memory, same as ATTACK_TARGET, so relogs will clear it and that's why it has no codec.
|
||||||
|
*
|
||||||
|
* To help you get a sense of a use case, imagine a Pidgeotto has an AI task that says it should hunt
|
||||||
|
* Magikarp that are close to the surface. Once they've found one and chosen them as the attack target,
|
||||||
|
* they should give up the target if the Magikarp goes too deep, but if it's attacking an entity because
|
||||||
|
* they attacked its owner, it shouldn't give up on the target for that reason. To address this, when
|
||||||
|
* hunting Magikarp, the Pidgeotto will set this memory to a CobblemonAttackTargetData with some
|
||||||
|
* [Expression] that encourages the entity to give up the target if the Magikarp goes too deep.
|
||||||
|
*
|
||||||
|
* To make this work, any transition from the FIGHT activity will erase this memory.
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since June 23rd, 2025
|
||||||
|
*/
|
||||||
|
class CobblemonAttackTargetData(
|
||||||
|
/** An expression that returns false when the target is no longer worth attacking. */
|
||||||
|
val shouldContinue: Expression = "true".asExpression()
|
||||||
|
)
|
||||||
@@ -15,6 +15,11 @@ import kotlin.jvm.optionals.getOrNull
|
|||||||
|
|
||||||
typealias ExpressionOrEntityVariable = Either<Expression, MoLangConfigVariable>
|
typealias ExpressionOrEntityVariable = Either<Expression, MoLangConfigVariable>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In the case of [ExpressionOrEntityVariable] the right side is the only one that requires visibility for a user,
|
||||||
|
* this function is a shorthand for finding all of the values in the list that have something to show the user to
|
||||||
|
* potentially edit.
|
||||||
|
*/
|
||||||
fun List<ExpressionOrEntityVariable>.asVariables() = mapNotNull { it.right().getOrNull() }
|
fun List<ExpressionOrEntityVariable>.asVariables() = mapNotNull { it.right().getOrNull() }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+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.ai.config
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
|
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||||
|
import com.cobblemon.mod.common.api.ai.asVariables
|
||||||
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
|
import com.mojang.datafixers.util.Either
|
||||||
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does nothing except conditionally add some memories and sensors to the brain of the entity.
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since June 27th, 2025
|
||||||
|
*/
|
||||||
|
class AddMemoriesAndSensorsConfig : BehaviourConfig {
|
||||||
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
|
val memories: Set<MemoryModuleType<*>> = emptySet()
|
||||||
|
val sensors: Set<SensorType<*>> = mutableSetOf()
|
||||||
|
|
||||||
|
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
||||||
|
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
||||||
|
if (!checkCondition(entity, condition)) return
|
||||||
|
behaviourConfigurationContext.addMemories(memories)
|
||||||
|
behaviourConfigurationContext.addSensors(sensors)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,8 +23,8 @@ class AddTasksToActivity : BehaviourConfig {
|
|||||||
val activities = mutableListOf<Activity>()
|
val activities = mutableListOf<Activity>()
|
||||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
val tasksByPriority = mutableMapOf<Int, List<TaskConfig>>()
|
val tasksByPriority = mutableMapOf<Int, List<TaskConfig>>()
|
||||||
override fun getVariables(entity: LivingEntity) = tasksByPriority.values.flatten().flatMap { it.getVariables(entity) } + listOf(condition).asVariables()
|
|
||||||
|
|
||||||
|
override fun getVariables(entity: LivingEntity) = tasksByPriority.values.flatten().flatMap { it.getVariables(entity) } + listOf(condition).asVariables()
|
||||||
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
||||||
if (!checkCondition(entity, condition)) return
|
if (!checkCondition(entity, condition)) return
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class ApplyBehaviours : BehaviourConfig {
|
|||||||
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
@SerializedName("behaviours", alternate = ["behaviors"])
|
@SerializedName("behaviours", alternate = ["behaviors"])
|
||||||
val behaviours = mutableListOf<ResourceLocation>()
|
val behaviours = mutableListOf<ResourceLocation>()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
||||||
return if (checkCondition(entity, condition)) {
|
return if (checkCondition(entity, condition)) {
|
||||||
behaviours.flatMap {
|
behaviours.flatMap {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ interface BehaviourConfig {
|
|||||||
cobblemonResource("set_core_activities") to SetCoreActivities::class.java,
|
cobblemonResource("set_core_activities") to SetCoreActivities::class.java,
|
||||||
cobblemonResource("add_variables") to AddVariablesConfig::class.java,
|
cobblemonResource("add_variables") to AddVariablesConfig::class.java,
|
||||||
cobblemonResource("set_variables") to SetVariablesConfig::class.java,
|
cobblemonResource("set_variables") to SetVariablesConfig::class.java,
|
||||||
|
cobblemonResource("add_memories_and_sensors") to AddMemoriesAndSensorsConfig::class.java,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-4
@@ -21,19 +21,25 @@ import com.cobblemon.mod.common.util.resolve
|
|||||||
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 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.sensing.SensorType
|
||||||
|
|
||||||
class CustomScriptBehaviourConfig : BehaviourConfig {
|
class CustomScriptBehaviourConfig : BehaviourConfig {
|
||||||
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
|
||||||
val variables: List<MoLangConfigVariable> = emptyList()
|
|
||||||
val script: ExpressionLike = "0".asExpressionLike()
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val runtime = MoLangRuntime().setup()
|
val runtime = MoLangRuntime().setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
|
val variables: List<MoLangConfigVariable> = emptyList()
|
||||||
|
val script: ExpressionLike = "0".asExpressionLike()
|
||||||
|
val memories = emptySet<MemoryModuleType<*>>()
|
||||||
|
val sensors = emptySet<SensorType<*>>()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = variables
|
override fun getVariables(entity: LivingEntity) = variables
|
||||||
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
||||||
if (!checkCondition(entity, condition)) return
|
if (!checkCondition(entity, condition)) return
|
||||||
|
behaviourConfigurationContext.addMemories(memories)
|
||||||
|
behaviourConfigurationContext.addSensors(sensors)
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
runtime.resolve(script)
|
runtime.resolve(script)
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-6
@@ -14,6 +14,7 @@ import com.bedrockk.molang.runtime.value.DoubleValue
|
|||||||
import com.cobblemon.mod.common.Cobblemon
|
import com.cobblemon.mod.common.Cobblemon
|
||||||
import com.cobblemon.mod.common.api.ai.ActivityConfigurationContext
|
import com.cobblemon.mod.common.api.ai.ActivityConfigurationContext
|
||||||
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.molang.MoLangFunctions.addStandardFunctions
|
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
|
||||||
@@ -21,34 +22,42 @@ import com.cobblemon.mod.common.api.molang.ObjectValue
|
|||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
||||||
import com.cobblemon.mod.common.util.activityRegistry
|
import com.cobblemon.mod.common.util.activityRegistry
|
||||||
import com.cobblemon.mod.common.util.asExpressionLike
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||||
import com.cobblemon.mod.common.util.cobblemonResource
|
import com.cobblemon.mod.common.util.cobblemonResource
|
||||||
import com.cobblemon.mod.common.util.resolve
|
import com.cobblemon.mod.common.util.resolve
|
||||||
import com.cobblemon.mod.common.util.resolveBoolean
|
|
||||||
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.Pair
|
import com.mojang.datafixers.util.Pair
|
||||||
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
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
class ScriptBehaviourConfig : BehaviourConfig {
|
class ScriptBehaviourConfig : BehaviourConfig {
|
||||||
val condition = "true".asExpressionLike()
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
val script = cobblemonResource("dummy")
|
val script = cobblemonResource("dummy")
|
||||||
val variables = mutableListOf<MoLangConfigVariable>()
|
val variables = mutableListOf<MoLangConfigVariable>()
|
||||||
|
val memories = emptySet<MemoryModuleType<*>>()
|
||||||
|
val sensors = emptySet<SensorType<*>>()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = variables
|
override fun getVariables(entity: LivingEntity) = variables
|
||||||
|
|
||||||
override fun configure(entity: LivingEntity, context: BehaviourConfigurationContext) {
|
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
||||||
|
if (!checkCondition(entity, condition)) return
|
||||||
val runtime = MoLangRuntime().setup()
|
val runtime = MoLangRuntime().setup()
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!runtime.resolveBoolean(condition)) return
|
|
||||||
|
|
||||||
val struct = createBrainStruct(entity, context)
|
val struct = createBrainStruct(entity, behaviourConfigurationContext)
|
||||||
val script = CobblemonScripts.scripts[this.script]
|
val script = CobblemonScripts.scripts[this.script]
|
||||||
?: run {
|
?: run {
|
||||||
Cobblemon.LOGGER.error("Tried loading script $script as part of an entity brain but that script does not exist")
|
Cobblemon.LOGGER.error("Tried loading script $script as part of an entity brain but that script does not exist")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(memories)
|
||||||
|
behaviourConfigurationContext.addSensors(sensors)
|
||||||
|
|
||||||
runtime.resolve(script, mapOf("brain" to struct))
|
runtime.resolve(script, mapOf("brain" to struct))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import net.minecraft.world.entity.schedule.Activity
|
|||||||
|
|
||||||
class SetDefaultActivity : BehaviourConfig {
|
class SetDefaultActivity : BehaviourConfig {
|
||||||
val activity: Activity = Activity.IDLE
|
val activity: Activity = Activity.IDLE
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
||||||
behaviourConfigurationContext.defaultActivity = activity
|
behaviourConfigurationContext.defaultActivity = activity
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ class SetVariablesConfig : BehaviourConfig {
|
|||||||
var variableValues = mutableMapOf<String, ExpressionLike>()
|
var variableValues = mutableMapOf<String, ExpressionLike>()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
|
|
||||||
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
|
||||||
val runtime = MoLangRuntime().setup()
|
val runtime = MoLangRuntime().setup()
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
|
|||||||
+1
-2
@@ -15,8 +15,6 @@ import com.cobblemon.mod.common.api.ai.asVariables
|
|||||||
import com.cobblemon.mod.common.api.ai.config.task.WanderTaskConfig.Companion.WANDER
|
import com.cobblemon.mod.common.api.ai.config.task.WanderTaskConfig.Companion.WANDER
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
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.entity.pokemon.PokemonEntity
|
|
||||||
import com.cobblemon.mod.common.entity.pokemon.ai.PokemonMoveControl
|
|
||||||
import com.cobblemon.mod.common.util.asExpression
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
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
|
||||||
@@ -50,6 +48,7 @@ class AirWanderTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, MemoryModuleType.LOOK_TARGET, CobblemonMemories.PATH_COOLDOWN)
|
||||||
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
|
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
|
||||||
|
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
|
|||||||
+2
-9
@@ -10,9 +10,7 @@ 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.molang.MoLangFunctions.asMostSpecificMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
|
||||||
import com.cobblemon.mod.common.util.asExpression
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
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
|
||||||
@@ -23,19 +21,14 @@ class AllOfTaskConfig : TaskConfig {
|
|||||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
val tasks: List<TaskConfig> = emptyList()
|
val tasks: List<TaskConfig> = emptyList()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
override fun getVariables(entity: LivingEntity) = tasks.flatMap { it.getVariables(entity) }
|
||||||
return if (checkCondition(entity, condition))
|
|
||||||
tasks.flatMap { it.getVariables(entity) } + listOf(condition).asVariables()
|
|
||||||
else
|
|
||||||
listOf(condition).asVariables()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createTasks(
|
override fun createTasks(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): List<BehaviorControl<in LivingEntity>> {
|
): List<BehaviorControl<in LivingEntity>> {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return emptyList()
|
if (!condition.resolveBoolean()) return emptyList()
|
||||||
|
|
||||||
return tasks.flatMap { it.createTasks(entity, behaviourConfigurationContext) }
|
return tasks.flatMap { it.createTasks(entity, behaviourConfigurationContext) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+5
-8
@@ -8,24 +8,21 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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.asVariables
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
|
||||||
import com.cobblemon.mod.common.entity.ai.AttackAngryAtTask
|
import com.cobblemon.mod.common.entity.ai.AttackAngryAtTask
|
||||||
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.memory.MemoryModuleType
|
||||||
|
|
||||||
class AttackAngryAtTaskConfig : SingleTaskConfig {
|
class AttackAngryAtTaskConfig : SingleTaskConfig {
|
||||||
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "should_attack_angry_at", true).asExpressible()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
|
||||||
|
|
||||||
override fun createTask(
|
override fun createTask(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
behaviourConfigurationContext.addMemories(MemoryModuleType.ANGRY_AT, MemoryModuleType.ATTACK_TARGET, CobblemonMemories.POKEMON_SLEEPING)
|
||||||
if (!condition.resolveBoolean()) return null
|
|
||||||
return AttackAngryAtTask.create()
|
return AttackAngryAtTask.create()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
|
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.AttackHostileMobsTask
|
||||||
|
import com.mojang.serialization.Codec
|
||||||
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
|
|
||||||
|
class AttackHostileMobsTaskConfig : SingleTaskConfig {
|
||||||
|
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
||||||
|
return emptyList<MoLangConfigVariable>()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTask(
|
||||||
|
entity: LivingEntity,
|
||||||
|
brainConfigurationContext: BehaviourConfigurationContext
|
||||||
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
return AttackHostileMobsTask.create()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val CODEC: Codec<AttackHostileMobsTaskConfig> = Codec.unit(AttackHostileMobsTaskConfig())
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-1
@@ -12,22 +12,31 @@ 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.MoLangFunctions.asMostSpecificMoLangValue
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||||
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
import com.cobblemon.mod.common.util.asExpression
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
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 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.VillagerCalmDown
|
import net.minecraft.world.entity.ai.behavior.VillagerCalmDown
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
class CalmDownTaskConfig : SingleTaskConfig {
|
class CalmDownTaskConfig : SingleTaskConfig {
|
||||||
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
override fun createTask(
|
override fun createTask(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.HURT_BY,
|
||||||
|
MemoryModuleType.HURT_BY_ENTITY,
|
||||||
|
MemoryModuleType.NEAREST_HOSTILE,
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.VILLAGER_HOSTILES)
|
||||||
return VillagerCalmDown.create()
|
return VillagerCalmDown.create()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+15
-2
@@ -24,6 +24,7 @@ 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.sensing.SensorType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks nearby entities and counts how many have nominated this entity as their leader.
|
* Checks nearby entities and counts how many have nominated this entity as their leader.
|
||||||
@@ -44,6 +45,12 @@ class CountFollowersTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
val checkTicksValue = checkTicks.resolveInt()
|
val checkTicksValue = checkTicks.resolveInt()
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
|
||||||
|
CobblemonMemories.HERD_SIZE,
|
||||||
|
CobblemonMemories.HERD_LEADER
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
|
||||||
return BehaviorBuilder.create { instance ->
|
return BehaviorBuilder.create { instance ->
|
||||||
instance.group(
|
instance.group(
|
||||||
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
|
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
|
||||||
@@ -55,9 +62,15 @@ class CountFollowersTaskConfig : SingleTaskConfig {
|
|||||||
}
|
}
|
||||||
val myUUID = entity.uuid.toString()
|
val myUUID = entity.uuid.toString()
|
||||||
val followersCount = instance.get(nearbyEntities).findAll {
|
val followersCount = instance.get(nearbyEntities).findAll {
|
||||||
it is PokemonEntity && it.brain.getMemory(CobblemonMemories.HERD_LEADER).getOrNull() == myUUID
|
it is PokemonEntity
|
||||||
|
&& it.brain.hasMemoryValue(CobblemonMemories.HERD_LEADER)
|
||||||
|
&& it.brain.getMemory(CobblemonMemories.HERD_LEADER).getOrNull() == myUUID
|
||||||
}.count()
|
}.count()
|
||||||
herdCount.set(followersCount)
|
if (followersCount == 0) {
|
||||||
|
herdCount.erase()
|
||||||
|
} else {
|
||||||
|
herdCount.set(followersCount)
|
||||||
|
}
|
||||||
return@Trigger true
|
return@Trigger true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ class DoNothingTaskConfig : SingleTaskConfig {
|
|||||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
val minDurationTicks: ExpressionOrEntityVariable = Either.left("40".asExpression())
|
val minDurationTicks: ExpressionOrEntityVariable = Either.left("40".asExpression())
|
||||||
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("80".asExpression())
|
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("80".asExpression())
|
||||||
override fun getVariables(entity: LivingEntity) = listOf(condition, minDurationTicks, maxDurationTicks).asVariables()
|
override fun getVariables(entity: LivingEntity) = listOf(minDurationTicks, maxDurationTicks).asVariables()
|
||||||
|
|
||||||
override fun createTask(
|
override fun createTask(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
|
|||||||
+4
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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
|
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||||
import com.cobblemon.mod.common.api.ai.asVariables
|
import com.cobblemon.mod.common.api.ai.asVariables
|
||||||
@@ -16,6 +17,7 @@ import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
|||||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.EatGrassTask
|
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.EatGrassTask
|
||||||
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 EatGrassTaskConfig : SingleTaskConfig {
|
class EatGrassTaskConfig : SingleTaskConfig {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -47,6 +49,8 @@ class EatGrassTaskConfig : SingleTaskConfig {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, CobblemonMemories.RECENTLY_ATE_GRASS)
|
||||||
|
|
||||||
return WrapperLivingEntityTask(
|
return WrapperLivingEntityTask(
|
||||||
EatGrassTask(
|
EatGrassTask(
|
||||||
chance,
|
chance,
|
||||||
|
|||||||
+13
-1
@@ -9,6 +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.CobblemonMemories
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.CobblemonSensors
|
||||||
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.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||||
@@ -21,6 +22,7 @@ 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.sensing.SensorType
|
||||||
|
|
||||||
class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
|
class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
|
||||||
var condition = booleanVariable(SharedEntityVariables.BATTLING_CATEGORY, "exit_battle_when_hurt", true).asExpressible()
|
var condition = booleanVariable(SharedEntityVariables.BATTLING_CATEGORY, "exit_battle_when_hurt", true).asExpressible()
|
||||||
@@ -36,10 +38,19 @@ class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
|
|||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
val includePassiveDamage = includePassiveDamage.resolveBoolean()
|
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
|
||||||
|
val includePassiveDamage = includePassiveDamage.resolveBoolean()
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.HURT_BY,
|
||||||
|
MemoryModuleType.HURT_BY_ENTITY
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.HURT_BY)
|
||||||
|
|
||||||
if (entity is NPCEntity) {
|
if (entity is NPCEntity) {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.NPC_BATTLING)
|
||||||
|
behaviourConfigurationContext.addSensors(CobblemonSensors.NPC_BATTLING)
|
||||||
fun cancelNPCBattles(npcEntity: NPCEntity): Boolean {
|
fun cancelNPCBattles(npcEntity: NPCEntity): Boolean {
|
||||||
val battles = npcEntity.battleIds.mapNotNull(BattleRegistry::getBattle)
|
val battles = npcEntity.battleIds.mapNotNull(BattleRegistry::getBattle)
|
||||||
battles.forEach { it.end() }
|
battles.forEach { it.end() }
|
||||||
@@ -58,6 +69,7 @@ class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (entity is PokemonEntity) {
|
} else if (entity is PokemonEntity) {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.POKEMON_BATTLE)
|
||||||
fun cancelPokemonBattle(pokemonEntity: PokemonEntity): Boolean {
|
fun cancelPokemonBattle(pokemonEntity: PokemonEntity): Boolean {
|
||||||
val battle = BattleRegistry.getBattle(pokemonEntity.battleId ?: return false)
|
val battle = BattleRegistry.getBattle(pokemonEntity.battleId ?: return false)
|
||||||
battle?.end()
|
battle?.end()
|
||||||
|
|||||||
+4
@@ -43,6 +43,10 @@ class FindAirTaskConfig : SingleTaskConfig {
|
|||||||
if (entity !is PathfinderMob) {
|
if (entity !is PathfinderMob) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
CobblemonMemories.PATH_COOLDOWN
|
||||||
|
)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.absent(MemoryModuleType.WALK_TARGET),
|
it.absent(MemoryModuleType.WALK_TARGET),
|
||||||
|
|||||||
+66
-22
@@ -16,6 +16,7 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangV
|
|||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
import com.cobblemon.mod.common.api.storage.party.PartyStore
|
import com.cobblemon.mod.common.api.storage.party.PartyStore
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||||
|
import com.cobblemon.mod.common.pokemon.ai.ToleratedHerdLeader
|
||||||
import com.cobblemon.mod.common.util.asExpression
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
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
|
||||||
@@ -24,8 +25,58 @@ 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.NearestVisibleLivingEntities
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
class FindHerdLeaderTaskConfig : SingleTaskConfig {
|
class FindHerdLeaderTaskConfig : SingleTaskConfig {
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Logic used to choose the best herd leader from nearby visible entities.
|
||||||
|
*
|
||||||
|
* - Higher tier leaders are always preferred.
|
||||||
|
* - Same-tier leaders that are closer are preferred except for when they're the same tier as the current leader.
|
||||||
|
* - We don't want to exceed the target's herd size limit.
|
||||||
|
* - We don't want to choose a leader that is themselves following a leader.
|
||||||
|
* - Some leader definitions allow lower-level Pokémon to lead them.
|
||||||
|
* - Leaders just have to not be in a party - pastured and wild Pokémon can mingle.
|
||||||
|
*/
|
||||||
|
fun getBestHerdLeader(
|
||||||
|
currentLeader: Pair<PokemonEntity, ToleratedHerdLeader>?,
|
||||||
|
nearbyEntities: NearestVisibleLivingEntities,
|
||||||
|
entity: PokemonEntity
|
||||||
|
): PokemonEntity? {
|
||||||
|
var bestLeader: PokemonEntity? = null
|
||||||
|
val (currentLeaderEntity, currentLeaderDefinition) = currentLeader ?: Pair(null, null)
|
||||||
|
var bestTier = currentLeaderDefinition?.tier?.let { it + 1 } ?: 0 // Only upgrade to a higher tier leader
|
||||||
|
var bestDistance = Float.MAX_VALUE
|
||||||
|
nearbyEntities.findAll {
|
||||||
|
it is PokemonEntity &&
|
||||||
|
it != currentLeader &&
|
||||||
|
it.pokemon.storeCoordinates.get()?.store !is PartyStore &&
|
||||||
|
it.getHerdSize() < it.behaviour.herd.maxSize
|
||||||
|
}.forEach { possibleLeader ->
|
||||||
|
possibleLeader as PokemonEntity
|
||||||
|
val matchingHerdLeader = entity.behaviour.herd.bestMatchLeader(entity, possibleLeader) ?: return@forEach
|
||||||
|
val alreadyIsALeader = possibleLeader.brain.hasMemoryValue(CobblemonMemories.HERD_SIZE)
|
||||||
|
val nestedHerdTier = currentLeaderEntity?.getHerdTier() ?: 0
|
||||||
|
if (nestedHerdTier >= matchingHerdLeader.tier) {
|
||||||
|
return@forEach // This leader is following a leader of a higher tier, we can't replace them
|
||||||
|
}
|
||||||
|
val distance = entity.distanceTo(possibleLeader)
|
||||||
|
if (matchingHerdLeader.tier < bestTier) {
|
||||||
|
return@forEach // No need to check further if this leader is worse than the best found so far
|
||||||
|
} else if ((distance > bestDistance && !alreadyIsALeader) && matchingHerdLeader.tier == bestTier) {
|
||||||
|
return@forEach // No need to check further if this leader is farther than the best found so far, unless they are already a leader - I'd prefer to join a pack
|
||||||
|
} else {
|
||||||
|
bestLeader = possibleLeader
|
||||||
|
bestDistance = distance
|
||||||
|
bestTier = matchingHerdLeader.tier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestLeader ?: currentLeaderEntity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// How frequently to check for whether it should herd. Probably isn't that expensive but might use this for chance.
|
// How frequently to check for whether it should herd. Probably isn't that expensive but might use this for chance.
|
||||||
val checkTicks: ExpressionOrEntityVariable = Either.left("60".asExpression())
|
val checkTicks: ExpressionOrEntityVariable = Either.left("60".asExpression())
|
||||||
|
|
||||||
@@ -41,40 +92,33 @@ class FindHerdLeaderTaskConfig : SingleTaskConfig {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
|
||||||
|
CobblemonMemories.HERD_LEADER,
|
||||||
|
MemoryModuleType.WALK_TARGET
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
val checkTicksValue = checkTicks.resolveInt()
|
val checkTicksValue = checkTicks.resolveInt()
|
||||||
return BehaviorBuilder.create { instance ->
|
return BehaviorBuilder.create { instance ->
|
||||||
instance.group(
|
instance.group(
|
||||||
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
|
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
|
||||||
instance.absent(CobblemonMemories.HERD_LEADER),
|
instance.absent(CobblemonMemories.HERD_LEADER)
|
||||||
instance.absent(MemoryModuleType.WALK_TARGET)
|
).apply(instance) { nearbyEntities, herdLeader ->
|
||||||
).apply(instance) { nearbyEntities, herdLeader, _ ->
|
|
||||||
Trigger { world, entity, _ ->
|
Trigger { world, entity, _ ->
|
||||||
if (world.gameTime % checkTicksValue != 0L) {
|
if (world.gameTime % checkTicksValue != 0L) {
|
||||||
return@Trigger false
|
return@Trigger false
|
||||||
}
|
}
|
||||||
|
|
||||||
entity as PokemonEntity
|
entity as PokemonEntity
|
||||||
val toleratedLeaders = entity.behaviour.herd.toleratedLeaders
|
val bestLeader = getBestHerdLeader(
|
||||||
val nearbyLeaders = instance.get(nearbyEntities).findAll {
|
currentLeader = null,
|
||||||
it is PokemonEntity &&
|
nearbyEntities = instance.get(nearbyEntities),
|
||||||
it.pokemon.storeCoordinates.get()?.store !is PartyStore &&
|
entity = entity
|
||||||
it.exposedSpecies.resourceIdentifier in toleratedLeaders &&
|
) ?: return@Trigger false
|
||||||
!it.brain.hasMemoryValue(CobblemonMemories.HERD_LEADER) &&
|
|
||||||
it.pokemon.level >= entity.pokemon.level
|
|
||||||
}.toList()
|
|
||||||
|
|
||||||
if (nearbyLeaders.isEmpty()) {
|
herdLeader.set(bestLeader.uuid.toString())
|
||||||
return@Trigger false
|
bestLeader.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
|
||||||
}
|
|
||||||
|
|
||||||
val leader = nearbyLeaders
|
|
||||||
.filterIsInstance<PokemonEntity>()
|
|
||||||
.filter { it.getHerdSize() < entity.behaviour.herd.maxSize }
|
|
||||||
.maxByOrNull { it.pokemon.level }
|
|
||||||
?: return@Trigger false
|
|
||||||
|
|
||||||
herdLeader.set(leader.uuid.toString())
|
|
||||||
return@Trigger true
|
return@Trigger true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.CobblemonSensors
|
||||||
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.WrapperLivingEntityTask
|
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||||
@@ -18,6 +20,7 @@ import com.cobblemon.mod.common.util.asExpression
|
|||||||
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
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class FindRestingPlaceTaskConfig : SingleTaskConfig {
|
class FindRestingPlaceTaskConfig : SingleTaskConfig {
|
||||||
val horizontalSearchDistance: ExpressionOrEntityVariable = Either.left("16".asExpression())
|
val horizontalSearchDistance: ExpressionOrEntityVariable = Either.left("16".asExpression())
|
||||||
@@ -28,6 +31,13 @@ class FindRestingPlaceTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
CobblemonMemories.PATH_COOLDOWN,
|
||||||
|
CobblemonMemories.POKEMON_DROWSY,
|
||||||
|
MemoryModuleType.WALK_TARGET
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(CobblemonSensors.POKEMON_DROWSY)
|
||||||
|
|
||||||
return WrapperLivingEntityTask(
|
return WrapperLivingEntityTask(
|
||||||
FindRestingPlaceTask.create(horizontalSearchDistance.resolveInt(), verticalSearchDistance.resolveInt()),
|
FindRestingPlaceTask.create(horizontalSearchDistance.resolveInt(), verticalSearchDistance.resolveInt()),
|
||||||
PokemonEntity::class.java
|
PokemonEntity::class.java
|
||||||
|
|||||||
+5
@@ -20,6 +20,7 @@ import net.minecraft.world.entity.PathfinderMob
|
|||||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
import net.minecraft.world.entity.ai.behavior.SetWalkTargetAwayFrom
|
import net.minecraft.world.entity.ai.behavior.SetWalkTargetAwayFrom
|
||||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
class FleeAttackerTaskConfig : SingleTaskConfig {
|
class FleeAttackerTaskConfig : SingleTaskConfig {
|
||||||
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "flee_attacker", true).asExpressible()
|
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "flee_attacker", true).asExpressible()
|
||||||
@@ -38,6 +39,10 @@ class FleeAttackerTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean() || entity !is PathfinderMob) return null
|
if (!condition.resolveBoolean() || entity !is PathfinderMob) return null
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.WALK_TARGET)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.HURT_BY)
|
||||||
|
|
||||||
val speedMultiplier = speedMultiplier.resolveFloat()
|
val speedMultiplier = speedMultiplier.resolveFloat()
|
||||||
val desiredDistance = desiredDistance.resolveInt()
|
val desiredDistance = desiredDistance.resolveInt()
|
||||||
return WrapperLivingEntityTask(
|
return WrapperLivingEntityTask(
|
||||||
|
|||||||
+3
@@ -20,6 +20,7 @@ import net.minecraft.world.entity.PathfinderMob
|
|||||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
import net.minecraft.world.entity.ai.behavior.SetWalkTargetAwayFrom
|
import net.minecraft.world.entity.ai.behavior.SetWalkTargetAwayFrom
|
||||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
class FleeNearestHostileTaskConfig : SingleTaskConfig {
|
class FleeNearestHostileTaskConfig : SingleTaskConfig {
|
||||||
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "flee_nearest_hostile", true).asExpressible()
|
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "flee_nearest_hostile", true).asExpressible()
|
||||||
@@ -34,6 +35,8 @@ class FleeNearestHostileTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean() || entity !is PathfinderMob) return null
|
if (!condition.resolveBoolean() || entity !is PathfinderMob) return null
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.NEAREST_HOSTILE, MemoryModuleType.WALK_TARGET)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.VILLAGER_HOSTILES)
|
||||||
val speedMultiplier = speedMultiplier.resolveFloat()
|
val speedMultiplier = speedMultiplier.resolveFloat()
|
||||||
val desiredDistance = desiredDistance.resolveInt()
|
val desiredDistance = desiredDistance.resolveInt()
|
||||||
return WrapperLivingEntityTask(
|
return WrapperLivingEntityTask(
|
||||||
|
|||||||
+3
-1
@@ -23,6 +23,7 @@ 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
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class FlyInCirclesTaskConfig : SingleTaskConfig {
|
class FlyInCirclesTaskConfig : SingleTaskConfig {
|
||||||
val poseTypes: Set<PoseType> = setOf(
|
val poseTypes: Set<PoseType> = setOf(
|
||||||
@@ -31,7 +32,7 @@ class FlyInCirclesTaskConfig : SingleTaskConfig {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val minAngularVelocityDegrees = numberVariable(WANDER, "min_fly_circling_angular_velocity", 0.0).asExpressible()
|
val minAngularVelocityDegrees = numberVariable(WANDER, "min_fly_circling_angular_velocity", 0.0).asExpressible()
|
||||||
val maxAngularVelocityDegrees = numberVariable(WANDER, "max_fly_circling_angular_velocity", 2.0).asExpressible()
|
val maxAngularVelocityDegrees = numberVariable(WANDER, "max_fly_circling_angular_velocity", 1.0).asExpressible()
|
||||||
val speed = numberVariable(WANDER, "fly_circling_speed", 0.6).asExpressible()
|
val speed = numberVariable(WANDER, "fly_circling_speed", 0.6).asExpressible()
|
||||||
val verticalSpeed: ExpressionOrEntityVariable = Either.left("0.0".asExpression())
|
val verticalSpeed: ExpressionOrEntityVariable = Either.left("0.0".asExpression())
|
||||||
val minDurationTicks: ExpressionOrEntityVariable = Either.left("60".asExpression())
|
val minDurationTicks: ExpressionOrEntityVariable = Either.left("60".asExpression())
|
||||||
@@ -55,6 +56,7 @@ class FlyInCirclesTaskConfig : SingleTaskConfig {
|
|||||||
if (entity !is PokemonEntity) {
|
if (entity !is PokemonEntity) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, MemoryModuleType.PATH)
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
return CircleAroundTask(
|
return CircleAroundTask(
|
||||||
poseTypes = poseTypes,
|
poseTypes = poseTypes,
|
||||||
|
|||||||
+8
-1
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
@@ -15,16 +16,22 @@ import com.cobblemon.mod.common.entity.ai.FollowHerdLeaderTask
|
|||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||||
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 FollowHerdLeaderTaskConfig : SingleTaskConfig {
|
class FollowHerdLeaderTaskConfig : SingleTaskConfig {
|
||||||
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
|
||||||
return listOf() // TODO add tooFar and closeEnough variables
|
return listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createTask(
|
override fun createTask(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
if (entity !is PokemonEntity) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.HERD_LEADER, MemoryModuleType.WALK_TARGET)
|
||||||
return FollowHerdLeaderTask().wrapped<PokemonEntity>()
|
return FollowHerdLeaderTask().wrapped<PokemonEntity>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
@@ -20,6 +20,7 @@ import com.mojang.datafixers.util.Either
|
|||||||
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
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class FollowWalkTargetTaskConfig : SingleTaskConfig {
|
class FollowWalkTargetTaskConfig : SingleTaskConfig {
|
||||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
@@ -30,6 +31,7 @@ class FollowWalkTargetTaskConfig : SingleTaskConfig {
|
|||||||
|
|
||||||
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<LivingEntity>? {
|
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, MemoryModuleType.PATH, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)
|
||||||
return WrapperLivingEntityTask(
|
return WrapperLivingEntityTask(
|
||||||
FollowWalkTargetTask(minRunTicks.resolveInt(), maxRunTicks.resolveInt()),
|
FollowWalkTargetTask(minRunTicks.resolveInt(), maxRunTicks.resolveInt()),
|
||||||
PathfinderMob::class.java
|
PathfinderMob::class.java
|
||||||
|
|||||||
+7
@@ -16,6 +16,8 @@ import com.cobblemon.mod.common.entity.ai.GetAngryAtAttackerTask
|
|||||||
import com.cobblemon.mod.common.util.withQueryValue
|
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.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
class GetAngryAtAttackerTaskConfig : SingleTaskConfig {
|
class GetAngryAtAttackerTaskConfig : SingleTaskConfig {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -32,6 +34,11 @@ class GetAngryAtAttackerTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.HURT_BY_ENTITY,
|
||||||
|
MemoryModuleType.ANGRY_AT,
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.HURT_BY)
|
||||||
return GetAngryAtAttackerTask.create()
|
return GetAngryAtAttackerTask.create()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+10
-1
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.CobblemonSensors
|
||||||
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
|
||||||
@@ -18,6 +20,8 @@ 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
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
class GoToHealingMachineTaskConfig : SingleTaskConfig {
|
class GoToHealingMachineTaskConfig : SingleTaskConfig {
|
||||||
val condition = booleanVariable(SELF_HEALING, USE_HEALING_MACHINES, true).asExpressible()
|
val condition = booleanVariable(SELF_HEALING, USE_HEALING_MACHINES, true).asExpressible()
|
||||||
@@ -39,7 +43,12 @@ class GoToHealingMachineTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
MemoryModuleType.LOOK_TARGET,
|
||||||
|
CobblemonMemories.NPC_BATTLING
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(CobblemonSensors.NPC_BATTLING)
|
||||||
return GoToHealingMachineTask.create(
|
return GoToHealingMachineTask.create(
|
||||||
horizontalSearchRange = horizontalSearchRange.asExpression(),
|
horizontalSearchRange = horizontalSearchRange.asExpression(),
|
||||||
verticalSearchRange = verticalSearchRange.asExpression(),
|
verticalSearchRange = verticalSearchRange.asExpression(),
|
||||||
|
|||||||
+9
-3
@@ -12,6 +12,7 @@ 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.asVariables
|
import com.cobblemon.mod.common.api.ai.asVariables
|
||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
|
import com.cobblemon.mod.common.entity.OmniPathingEntity
|
||||||
import com.cobblemon.mod.common.util.closestPosition
|
import com.cobblemon.mod.common.util.closestPosition
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
@@ -43,7 +44,10 @@ class GoToLandTaskConfig : SingleTaskConfig {
|
|||||||
if (entity !is PathfinderMob) {
|
if (entity !is PathfinderMob) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
CobblemonMemories.PATH_COOLDOWN
|
||||||
|
)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.absent(MemoryModuleType.WALK_TARGET),
|
it.absent(MemoryModuleType.WALK_TARGET),
|
||||||
@@ -56,6 +60,8 @@ class GoToLandTaskConfig : SingleTaskConfig {
|
|||||||
|
|
||||||
entity as PathfinderMob
|
entity as PathfinderMob
|
||||||
|
|
||||||
|
val walkSpeedValue = walkSpeed.resolveFloat()
|
||||||
|
|
||||||
val iterable = BlockPos.betweenClosed(
|
val iterable = BlockPos.betweenClosed(
|
||||||
Mth.floor(entity.x - 8.0),
|
Mth.floor(entity.x - 8.0),
|
||||||
entity.blockY,
|
entity.blockY,
|
||||||
@@ -71,7 +77,7 @@ class GoToLandTaskConfig : SingleTaskConfig {
|
|||||||
isSafeLandPosAround(entity.level() as ServerLevel, it, entity)
|
isSafeLandPosAround(entity.level() as ServerLevel, it, entity)
|
||||||
} ?: return@Trigger false
|
} ?: return@Trigger false
|
||||||
|
|
||||||
walkTarget.set(WalkTarget(blockPos.above(), 0.35F, 1))
|
walkTarget.set(WalkTarget(blockPos.above(), walkSpeedValue, 0))
|
||||||
return@Trigger true
|
return@Trigger true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +88,7 @@ class GoToLandTaskConfig : SingleTaskConfig {
|
|||||||
val blockState = world.getBlockState(pos)
|
val blockState = world.getBlockState(pos)
|
||||||
|
|
||||||
val isFluid = world.getFluidState(pos.above()).isEmpty.not()
|
val isFluid = world.getFluidState(pos.above()).isEmpty.not()
|
||||||
val solidBelow = blockState.isSolid
|
val solidBelow = blockState.isSolid || (mob is OmniPathingEntity && mob.canFly())
|
||||||
|
|
||||||
if (isFluid || !solidBelow) {
|
if (isFluid || !solidBelow) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
+12
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.CobblemonSensors
|
||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
@@ -15,6 +17,7 @@ import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
|||||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.GoToSleepTask
|
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.GoToSleepTask
|
||||||
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 GoToSleepTaskConfig : SingleTaskConfig {
|
class GoToSleepTaskConfig : SingleTaskConfig {
|
||||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
@@ -22,6 +25,15 @@ class GoToSleepTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
if (entity !is PokemonEntity) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
CobblemonMemories.POKEMON_DROWSY,
|
||||||
|
CobblemonMemories.POKEMON_SLEEPING
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(CobblemonSensors.POKEMON_DROWSY)
|
||||||
return WrapperLivingEntityTask(GoToSleepTask.create(), PokemonEntity::class.java)
|
return WrapperLivingEntityTask(GoToSleepTask.create(), PokemonEntity::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.bedrockk.molang.Expression
|
||||||
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
|
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||||
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||||
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
|
import com.cobblemon.mod.common.util.resolveBoolean
|
||||||
|
import com.cobblemon.mod.common.util.withQueryValue
|
||||||
|
import com.mojang.datafixers.util.Either
|
||||||
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
|
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||||
|
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immediately gets angry at the nearest visible entity that matches the [entityCondition] and is within the [range].
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since June 23rd, 2025
|
||||||
|
*/
|
||||||
|
class HateEntityTaskConfig : SingleTaskConfig {
|
||||||
|
val entityCondition: Expression = "true".asExpression()
|
||||||
|
val range: ExpressionOrEntityVariable = Either.left("24".asExpression())
|
||||||
|
|
||||||
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
|
override fun createTask(
|
||||||
|
entity: LivingEntity,
|
||||||
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
val range = range.resolveFloat()
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
|
||||||
|
MemoryModuleType.ANGRY_AT
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
|
||||||
|
return BehaviorBuilder.create { instance ->
|
||||||
|
instance.group(
|
||||||
|
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
|
||||||
|
instance.registered(MemoryModuleType.ANGRY_AT)
|
||||||
|
).apply(instance) { entities, angryAt ->
|
||||||
|
Trigger { world, entity, _ ->
|
||||||
|
val target = instance.get(entities).findClosest {
|
||||||
|
runtime.withQueryValue("entity", it.asMostSpecificMoLangValue())
|
||||||
|
return@findClosest runtime.resolveBoolean(entityCondition)
|
||||||
|
}.orElse(null)
|
||||||
|
|
||||||
|
if (target != null && target.distanceTo(entity) <= range) {
|
||||||
|
angryAt.set(target.uuid)
|
||||||
|
}
|
||||||
|
return@Trigger true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.CobblemonSensors
|
||||||
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
|
||||||
@@ -20,6 +22,7 @@ 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
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class HealUsingHealingMachineTaskConfig : SingleTaskConfig {
|
class HealUsingHealingMachineTaskConfig : SingleTaskConfig {
|
||||||
val condition = booleanVariable(SELF_HEALING, USE_HEALING_MACHINES, true).asExpressible()
|
val condition = booleanVariable(SELF_HEALING, USE_HEALING_MACHINES, true).asExpressible()
|
||||||
@@ -34,6 +37,8 @@ class HealUsingHealingMachineTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, CobblemonMemories.NPC_BATTLING,)
|
||||||
|
behaviourConfigurationContext.addSensors(CobblemonSensors.NPC_BATTLING)
|
||||||
return HealUsingHealingMachineTask(horizontalUseRange.asExpression(), verticalUseRange.asExpression())
|
return HealUsingHealingMachineTask(horizontalUseRange.asExpression(), verticalUseRange.asExpression())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+8
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.CobblemonSensors
|
||||||
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
|
||||||
@@ -18,6 +20,7 @@ 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
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class LookAtBattlingPokemonTaskConfig : SingleTaskConfig {
|
class LookAtBattlingPokemonTaskConfig : SingleTaskConfig {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -40,6 +43,11 @@ class LookAtBattlingPokemonTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!resolveBooleanVariable(LOOK_AT_BATTLING_POKEMON)) return null
|
if (!resolveBooleanVariable(LOOK_AT_BATTLING_POKEMON)) return null
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.LOOK_TARGET,
|
||||||
|
CobblemonMemories.BATTLING_POKEMON
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(CobblemonSensors.BATTLING_POKEMON)
|
||||||
return LookAtBattlingPokemonTask.create(
|
return LookAtBattlingPokemonTask.create(
|
||||||
minDurationTicks = minDurationTicks.resolveInt(),
|
minDurationTicks = minDurationTicks.resolveInt(),
|
||||||
maxDurationTicks = maxDurationTicks.resolveInt()
|
maxDurationTicks = maxDurationTicks.resolveInt()
|
||||||
|
|||||||
+4
@@ -16,6 +16,8 @@ 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.SetEntityLookTarget
|
import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
class LookAtEntitiesTaskConfig : SingleTaskConfig {
|
class LookAtEntitiesTaskConfig : SingleTaskConfig {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -36,6 +38,8 @@ class LookAtEntitiesTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.LOOK_TARGET)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
|
||||||
return SetEntityLookTarget.create(maxDistance.resolveFloat())
|
return SetEntityLookTarget.create(maxDistance.resolveFloat())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+5
-1
@@ -8,15 +8,19 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
import com.cobblemon.mod.common.entity.npc.ai.LookAtSpeakerTask
|
import com.cobblemon.mod.common.entity.npc.ai.LookAtSpeakerTask
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class LookAtSpeakerTaskConfig : SingleTaskConfig {
|
class LookAtSpeakerTaskConfig : SingleTaskConfig {
|
||||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
override fun createTask(
|
override fun createTask(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
) = LookAtSpeakerTask.create()
|
) = LookAtSpeakerTask.create().also {
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET, CobblemonMemories.DIALOGUES)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+2
@@ -20,6 +20,7 @@ import net.minecraft.world.entity.LivingEntity
|
|||||||
import net.minecraft.world.entity.Mob
|
import net.minecraft.world.entity.Mob
|
||||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
import net.minecraft.world.entity.ai.behavior.LookAtTargetSink
|
import net.minecraft.world.entity.ai.behavior.LookAtTargetSink
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class LookAtTargetTaskConfig : SingleTaskConfig {
|
class LookAtTargetTaskConfig : SingleTaskConfig {
|
||||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
@@ -38,6 +39,7 @@ class LookAtTargetTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET)
|
||||||
return WrapperLivingEntityTask(LookAtTargetSink(minDurationTicks.resolveInt(), maxDurationTicks.resolveInt()), Mob::class.java)
|
return WrapperLivingEntityTask(LookAtTargetSink(minDurationTicks.resolveInt(), maxDurationTicks.resolveInt()), Mob::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+11
-1
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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
|
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
@@ -15,13 +16,22 @@ import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
|||||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.LookAtTargetedBattlePokemonTask
|
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.LookAtTargetedBattlePokemonTask
|
||||||
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 LookAtTargetedBattlePokemonTaskConfig : SingleTaskConfig {
|
class LookAtTargetedBattlePokemonTaskConfig : SingleTaskConfig {
|
||||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
override fun createTask(
|
override fun createTask(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity> {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
if (entity !is PokemonEntity) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
CobblemonMemories.POKEMON_BATTLE,
|
||||||
|
CobblemonMemories.TARGETED_BATTLE_POKEMON,
|
||||||
|
MemoryModuleType.LOOK_TARGET,
|
||||||
|
)
|
||||||
return WrapperLivingEntityTask(LookAtTargetedBattlePokemonTask.create(), PokemonEntity::class.java)
|
return WrapperLivingEntityTask(LookAtTargetedBattlePokemonTask.create(), PokemonEntity::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-1
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.api.ai.asVariables
|
|||||||
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.LOOKING_CATEGORY
|
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.LOOKING_CATEGORY
|
||||||
import com.cobblemon.mod.common.entity.ai.LookInDirectionTask
|
import com.cobblemon.mod.common.entity.ai.LookInDirectionTask
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class LookInDirectionTaskConfig : SingleTaskConfig {
|
class LookInDirectionTaskConfig : SingleTaskConfig {
|
||||||
var condition = booleanVariable(LOOKING_CATEGORY, "locked_rotation", true).asExpressible()
|
var condition = booleanVariable(LOOKING_CATEGORY, "locked_rotation", true).asExpressible()
|
||||||
@@ -32,5 +33,7 @@ class LookInDirectionTaskConfig : SingleTaskConfig {
|
|||||||
shouldLock = condition.asExpression(),
|
shouldLock = condition.asExpression(),
|
||||||
yaw = yaw.asExpression(),
|
yaw = yaw.asExpression(),
|
||||||
pitch = pitch.asExpression()
|
pitch = pitch.asExpression()
|
||||||
)
|
).also {
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+19
-19
@@ -14,7 +14,6 @@ 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.MoLangFunctions.asMostSpecificMoLangValue
|
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.api.storage.party.PartyStore
|
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||||
import com.cobblemon.mod.common.util.asExpression
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
import com.cobblemon.mod.common.util.withQueryValue
|
import com.cobblemon.mod.common.util.withQueryValue
|
||||||
@@ -25,6 +24,7 @@ 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.sensing.SensorType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task that looks around for a better herd leader or gives up on a leader
|
* Task that looks around for a better herd leader or gives up on a leader
|
||||||
@@ -48,6 +48,11 @@ class MaintainHerdLeaderTaskConfig : SingleTaskConfig {
|
|||||||
if (entity !is PokemonEntity) {
|
if (entity !is PokemonEntity) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
CobblemonMemories.HERD_LEADER,
|
||||||
|
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
val checkTicks = checkTicks.resolveInt()
|
val checkTicks = checkTicks.resolveInt()
|
||||||
return BehaviorBuilder.create { instance ->
|
return BehaviorBuilder.create { instance ->
|
||||||
@@ -62,26 +67,22 @@ class MaintainHerdLeaderTaskConfig : SingleTaskConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val leader = instance.get(herdLeader).let(UUID::fromString).let(world::getEntity) as? PokemonEntity
|
val leader = instance.get(herdLeader).let(UUID::fromString).let(world::getEntity) as? PokemonEntity
|
||||||
if (leader == null) {
|
val currentLeaderDefinition = leader?.let { leader ->
|
||||||
|
entity.behaviour.herd.toleratedLeaders.find { it.pokemon.matches(leader) }
|
||||||
|
}
|
||||||
|
if (leader == null || currentLeaderDefinition == null) {
|
||||||
entity.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
|
entity.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
|
||||||
return@Trigger true // No leader, so we erase the memory
|
return@Trigger true // No leader, so we erase the memory
|
||||||
} else if (leader.brain.hasMemoryValue(CobblemonMemories.HERD_LEADER)) {
|
|
||||||
entity.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
|
|
||||||
return@Trigger true
|
|
||||||
} else if (leader.exposedSpecies.resourceIdentifier !in entity.behaviour.herd.toleratedLeaders) {
|
|
||||||
// Zoroark getting exposed then herd members pausing and saying "hey wait a minute"
|
|
||||||
entity.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
|
|
||||||
} else {
|
} else {
|
||||||
val bestSurroundingLeader = instance.get(nearbyEntities).findAll {
|
val bestLeader = FindHerdLeaderTaskConfig.getBestHerdLeader(
|
||||||
it is PokemonEntity &&
|
currentLeader = (leader to currentLeaderDefinition),
|
||||||
it != leader &&
|
nearbyEntities = instance.get(nearbyEntities),
|
||||||
it.pokemon.storeCoordinates.get()?.store !is PartyStore &&
|
entity = entity
|
||||||
it.exposedSpecies.resourceIdentifier in entity.behaviour.herd.toleratedLeaders &&
|
)
|
||||||
!it.brain.hasMemoryValue(CobblemonMemories.HERD_LEADER) &&
|
|
||||||
it.pokemon.level > leader.pokemon.level // Has to be a superior leader to the existing one
|
if (bestLeader != null && bestLeader != leader) {
|
||||||
}.maxByOrNull { (it as PokemonEntity).pokemon.level } as? PokemonEntity
|
bestLeader.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
|
||||||
if (bestSurroundingLeader != null) {
|
entity.brain.setMemory(CobblemonMemories.HERD_LEADER, bestLeader.uuid.toString())
|
||||||
entity.brain.setMemory(CobblemonMemories.HERD_LEADER, bestSurroundingLeader.uuid.toString())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@Trigger true
|
return@Trigger true
|
||||||
@@ -89,5 +90,4 @@ class MaintainHerdLeaderTaskConfig : SingleTaskConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+5
-10
@@ -8,22 +8,16 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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
|
|
||||||
import com.cobblemon.mod.common.api.ai.asVariables
|
|
||||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
|
||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
import com.cobblemon.mod.common.entity.npc.ai.MeleeAttackTask
|
|
||||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.BattleFlightTask
|
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.ManageFlightInBattleTask
|
||||||
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
|
||||||
|
|
||||||
class BattleFlightTaskConfig : SingleTaskConfig {
|
class ManageFlightInBattleTaskConfig : SingleTaskConfig {
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
|
|
||||||
override fun createTask(
|
override fun createTask(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
@@ -31,6 +25,7 @@ class BattleFlightTaskConfig : SingleTaskConfig {
|
|||||||
if (entity !is PokemonEntity) {
|
if (entity !is PokemonEntity) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return BattleFlightTask.create()
|
behaviourConfigurationContext.addMemories(CobblemonMemories.POKEMON_BATTLE)
|
||||||
|
return ManageFlightInBattleTask.create()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-2
@@ -15,11 +15,12 @@ import com.cobblemon.mod.common.entity.npc.ai.MeleeAttackTask
|
|||||||
import com.cobblemon.mod.common.util.withQueryValue
|
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.memory.MemoryModuleType
|
||||||
|
|
||||||
class MeleeAttackTaskConfig : SingleTaskConfig {
|
class MeleeAttackTaskConfig : SingleTaskConfig {
|
||||||
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "attacks_melee", true).asExpressible()
|
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "attacks_melee", true).asExpressible()
|
||||||
val range = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_range", 1.5F).asExpressible()
|
val range = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_range", 1.5F).asExpressible()
|
||||||
val cooldownTicks = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_cooldown", 30).asExpressible()
|
val cooldownTicks = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_cooldown", 20).asExpressible()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = listOf(
|
override fun getVariables(entity: LivingEntity) = listOf(
|
||||||
condition,
|
condition,
|
||||||
@@ -33,7 +34,10 @@ class MeleeAttackTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.ATTACK_TARGET,
|
||||||
|
MemoryModuleType.ATTACK_COOLING_DOWN
|
||||||
|
)
|
||||||
return MeleeAttackTask.create(
|
return MeleeAttackTask.create(
|
||||||
range = range.asExpression(),
|
range = range.asExpression(),
|
||||||
cooldownTicks = cooldownTicks.asExpression()
|
cooldownTicks = cooldownTicks.asExpression()
|
||||||
|
|||||||
+4
@@ -63,6 +63,10 @@ class MoveIntoFluidTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
CobblemonMemories.PATH_COOLDOWN
|
||||||
|
)
|
||||||
val movesIntoWater = this@MoveIntoFluidTaskConfig.movesIntoWater.resolveBoolean()
|
val movesIntoWater = this@MoveIntoFluidTaskConfig.movesIntoWater.resolveBoolean()
|
||||||
val movesIntoLava = movesIntoLava.resolveBoolean()
|
val movesIntoLava = movesIntoLava.resolveBoolean()
|
||||||
val speedModifier = speedModifier.resolveFloat()
|
val speedModifier = speedModifier.resolveFloat()
|
||||||
|
|||||||
+8
-2
@@ -15,10 +15,11 @@ import com.cobblemon.mod.common.entity.ai.MoveToAttackTargetTask
|
|||||||
import com.cobblemon.mod.common.util.asExpression
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
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.memory.MemoryModuleType
|
||||||
|
|
||||||
class MoveToAttackTargetTaskConfig : SingleTaskConfig {
|
class MoveToAttackTargetTaskConfig : SingleTaskConfig {
|
||||||
val speedMultiplier = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "attacking_movement_speed", 0.5).asExpressible()
|
val speedMultiplier = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "attacking_movement_speed", 0.5).asExpressible()
|
||||||
val closeEnoughDistance: ExpressionOrEntityVariable = Either.left("1".asExpression())
|
val closeEnoughDistance: ExpressionOrEntityVariable = Either.left("0".asExpression())
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = listOf(
|
override fun getVariables(entity: LivingEntity) = listOf(
|
||||||
speedMultiplier,
|
speedMultiplier,
|
||||||
@@ -31,5 +32,10 @@ class MoveToAttackTargetTaskConfig : SingleTaskConfig {
|
|||||||
) = MoveToAttackTargetTask.create(
|
) = MoveToAttackTargetTask.create(
|
||||||
speedMultiplier = speedMultiplier.asExpression(),
|
speedMultiplier = speedMultiplier.asExpression(),
|
||||||
closeEnoughDistance = closeEnoughDistance.asExpression()
|
closeEnoughDistance = closeEnoughDistance.asExpression()
|
||||||
)
|
).also {
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.ATTACK_TARGET,
|
||||||
|
MemoryModuleType.WALK_TARGET
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+5
@@ -18,6 +18,7 @@ import com.cobblemon.mod.common.util.asExpression
|
|||||||
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
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class MoveToOwnerTaskConfig : SingleTaskConfig {
|
class MoveToOwnerTaskConfig : SingleTaskConfig {
|
||||||
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
@@ -38,6 +39,10 @@ class MoveToOwnerTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
MemoryModuleType.LOOK_TARGET
|
||||||
|
)
|
||||||
return WrapperLivingEntityTask(
|
return WrapperLivingEntityTask(
|
||||||
MoveToOwnerTask.create(
|
MoveToOwnerTask.create(
|
||||||
condition = condition.asExpression(),
|
condition = condition.asExpression(),
|
||||||
|
|||||||
+5
-5
@@ -9,12 +9,12 @@
|
|||||||
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.ExpressionLike
|
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.asMostSpecificMoLangValue
|
||||||
import com.cobblemon.mod.common.util.asExpressionLike
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
import com.cobblemon.mod.common.util.resolveBoolean
|
|
||||||
import com.cobblemon.mod.common.util.toDF
|
import com.cobblemon.mod.common.util.toDF
|
||||||
import com.cobblemon.mod.common.util.withQueryValue
|
import com.cobblemon.mod.common.util.withQueryValue
|
||||||
|
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
|
||||||
import net.minecraft.world.entity.ai.behavior.RunOne
|
import net.minecraft.world.entity.ai.behavior.RunOne
|
||||||
@@ -35,14 +35,14 @@ class OneOfTaskConfig : SingleTaskConfig {
|
|||||||
val task: TaskConfig = SingleTaskConfig.nothing()
|
val task: TaskConfig = SingleTaskConfig.nothing()
|
||||||
}
|
}
|
||||||
|
|
||||||
val condition: ExpressionLike = "true".asExpressionLike()
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
val options = mutableListOf<OneOfTaskOption>()
|
val options = mutableListOf<OneOfTaskOption>()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = options.flatMap { it.task.getVariables(entity) }
|
override fun getVariables(entity: LivingEntity) = options.flatMap { it.task.getVariables(entity) }
|
||||||
|
|
||||||
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<in LivingEntity>? {
|
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!runtime.resolveBoolean(condition)) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
return RunOne(options.map { it.task.createTasks(entity, behaviourConfigurationContext).first() toDF it.weight })
|
return RunOne(options.map { it.task.createTasks(entity, behaviourConfigurationContext).first() toDF it.weight })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
@@ -22,6 +22,7 @@ import net.minecraft.world.phys.Vec3
|
|||||||
class PointToSpawnTaskConfig : SingleTaskConfig {
|
class PointToSpawnTaskConfig : SingleTaskConfig {
|
||||||
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<in LivingEntity>? {
|
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<in LivingEntity>? {
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.registered(MemoryModuleType.LOOK_TARGET),
|
it.registered(MemoryModuleType.LOOK_TARGET),
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ The 'look_in_direction' type creates a task that will make the entity look in a
|
|||||||
### move_to_owner
|
### move_to_owner
|
||||||
The 'move_to_owner' type creates a task that will make the entity move to its owner. This will only work for entities that
|
The 'move_to_owner' type creates a task that will make the entity move to its owner. This will only work for entities that
|
||||||
can be owned, like Pokémon.
|
can be owned, like Pokémon.
|
||||||
- `condition`: A MoLang expression (with `q.entity` as the entity) that determines if this entire task should exist on the entity or not. This runs at the time of entity creation, not on tick.
|
- `condition`: A MoLang expression (with `q.entity` as the entity) that determines if the entity should move to its owner this tick. Defaults to true.
|
||||||
- `completionRange`: A MoLang expression that determines the distance from the owner that the entity needs to be for the path to be considered complete. Defaults to 4.
|
- `completionRange`: A MoLang expression that determines the distance from the owner that the entity needs to be for the path to be considered complete. Defaults to 4.
|
||||||
- `speedMultiplier`: A MoLang expression that determines the speed multiplier for moving to the owner. Defaults to 0.4 which is slightly above the normal walk speed.
|
- `speedMultiplier`: A MoLang expression that determines the speed multiplier for moving to the owner. Defaults to 0.4 which is slightly above the normal walk speed.
|
||||||
- `teleportDistance`: A MoLang expression that determines the distance from the owner the entity must be before it resorts to teleporting. A value of -1 will cause it to never teleport. Defaults to 24.
|
- `teleportDistance`: A MoLang expression that determines the distance from the owner the entity must be before it resorts to teleporting. A value of -1 will cause it to never teleport. Defaults to 24.
|
||||||
|
|||||||
+7
-4
@@ -9,12 +9,16 @@
|
|||||||
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.ai.ExpressionOrEntityVariable
|
||||||
|
import com.cobblemon.mod.common.api.ai.asVariables
|
||||||
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.util.asExpression
|
||||||
import com.cobblemon.mod.common.util.asExpressionLike
|
import com.cobblemon.mod.common.util.asExpressionLike
|
||||||
import com.cobblemon.mod.common.util.resolveBoolean
|
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.cobblemon.mod.common.util.withQueryValue
|
||||||
|
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
|
||||||
|
|
||||||
@@ -35,17 +39,16 @@ class RandomTaskConfig : TaskConfig {
|
|||||||
val task: TaskConfig = SingleTaskConfig.nothing()
|
val task: TaskConfig = SingleTaskConfig.nothing()
|
||||||
}
|
}
|
||||||
|
|
||||||
val condition: ExpressionLike = "true".asExpressionLike()
|
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
|
||||||
val choices = mutableListOf<RandomTaskChoice>()
|
val choices = mutableListOf<RandomTaskChoice>()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = choices.flatMap { it.task.getVariables(entity) }
|
override fun getVariables(entity: LivingEntity) = choices.flatMap { it.task.getVariables(entity) } + listOf(condition).asVariables()
|
||||||
|
|
||||||
override fun createTasks(
|
override fun createTasks(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): List<BehaviorControl<in LivingEntity>> {
|
): List<BehaviorControl<in LivingEntity>> {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!runtime.resolveBoolean(condition)) return emptyList()
|
if (!condition.resolveBoolean()) return emptyList()
|
||||||
val task = choices.weightedSelection { it.weight }?.task ?: throw IllegalStateException("No tasks to choose from in random_task config")
|
val task = choices.weightedSelection { it.weight }?.task ?: throw IllegalStateException("No tasks to choose from in random_task config")
|
||||||
return task.createTasks(entity, behaviourConfigurationContext)
|
return task.createTasks(entity, behaviourConfigurationContext)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ 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.sensing.SensorType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a registered MoLang script (from the molang datapack folder) each tick.
|
* Runs a registered MoLang script (from the molang datapack folder) each tick.
|
||||||
@@ -38,6 +39,8 @@ class RunScript : SingleTaskConfig {
|
|||||||
|
|
||||||
val script = stringVariable(SCRIPT_CATEGORY, "script", "cobblemon:dummy_script").asExpressible()
|
val script = stringVariable(SCRIPT_CATEGORY, "script", "cobblemon:dummy_script").asExpressible()
|
||||||
val variables = mutableListOf<MoLangConfigVariable>()
|
val variables = mutableListOf<MoLangConfigVariable>()
|
||||||
|
val memories = emptySet<MemoryModuleType<*>>()
|
||||||
|
val sensors = emptySet<SensorType<*>>()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = listOf(script).asVariables() + variables
|
override fun getVariables(entity: LivingEntity) = listOf(script).asVariables() + variables
|
||||||
|
|
||||||
@@ -45,6 +48,8 @@ class RunScript : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? = BehaviorBuilder.create {
|
): BehaviorControl<in LivingEntity>? = BehaviorBuilder.create {
|
||||||
|
behaviourConfigurationContext.addMemories(memories + MemoryModuleType.LOOK_TARGET)
|
||||||
|
behaviourConfigurationContext.addSensors(sensors)
|
||||||
it.group(
|
it.group(
|
||||||
it.registered(MemoryModuleType.LOOK_TARGET) // I think I need to have at least something here?
|
it.registered(MemoryModuleType.LOOK_TARGET) // I think I need to have at least something here?
|
||||||
).apply(it) { _ ->
|
).apply(it) { _ ->
|
||||||
|
|||||||
+4
@@ -25,6 +25,10 @@ class SleepIfOnTrainerBedTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity> {
|
): BehaviorControl<in LivingEntity> {
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
CobblemonMemories.POKEMON_SLEEPING
|
||||||
|
)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.registered(MemoryModuleType.WALK_TARGET),
|
it.registered(MemoryModuleType.WALK_TARGET),
|
||||||
|
|||||||
+3
-5
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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
|
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||||
import com.cobblemon.mod.common.api.ai.asVariables
|
import com.cobblemon.mod.common.api.ai.asVariables
|
||||||
@@ -22,14 +23,11 @@ class StayAfloatTaskConfig : SingleTaskConfig {
|
|||||||
val condition = booleanVariable(SharedEntityVariables.MOVEMENT_CATEGORY, "can_float", true).asExpressible()
|
val condition = booleanVariable(SharedEntityVariables.MOVEMENT_CATEGORY, "can_float", true).asExpressible()
|
||||||
val chance = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, "float_chance", 0.8F).asExpressible()
|
val chance = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, "float_chance", 0.8F).asExpressible()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = listOf(
|
override fun getVariables(entity: LivingEntity) = listOf(condition, chance).asVariables()
|
||||||
condition,
|
|
||||||
chance
|
|
||||||
).asVariables()
|
|
||||||
|
|
||||||
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<LivingEntity>? {
|
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.POKEMON_BATTLE)
|
||||||
return WrapperLivingEntityTask(
|
return WrapperLivingEntityTask(
|
||||||
StayAfloatTask(chance.resolveFloat()),
|
StayAfloatTask(chance.resolveFloat()),
|
||||||
PathfinderMob::class.java
|
PathfinderMob::class.java
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||||
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
|
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.setup
|
||||||
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
|
import com.cobblemon.mod.common.util.resolveBoolean
|
||||||
|
import com.cobblemon.mod.common.util.withQueryValue
|
||||||
|
import java.util.function.Predicate
|
||||||
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.Mob
|
||||||
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
|
import net.minecraft.world.entity.ai.behavior.StopAttackingIfTargetInvalid
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A task config wrapping around vanilla's [StopAttackingIfTargetInvalid] that supports the optional ATTACK_TARGET_DATA
|
||||||
|
* memory to determine if the target is still valid for attacking.
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since June 23rd, 2025
|
||||||
|
*/
|
||||||
|
class StopAttackingIfTargetInvalidTaskConfig : SingleTaskConfig {
|
||||||
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
|
override fun createTask(
|
||||||
|
entity: LivingEntity,
|
||||||
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
val runtime = MoLangRuntime().setup()
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.ATTACK_TARGET_DATA, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)
|
||||||
|
return StopAttackingIfTargetInvalid.create<Mob>(
|
||||||
|
Predicate { target ->
|
||||||
|
val targetData = entity.brain.getMemory(CobblemonMemories.ATTACK_TARGET_DATA).orElse(null) ?: return@Predicate false
|
||||||
|
runtime.withQueryValue("entity", target.asMostSpecificMoLangValue())
|
||||||
|
return@Predicate !runtime.resolveBoolean(targetData.shouldContinue)
|
||||||
|
}
|
||||||
|
).wrapped()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -15,18 +15,19 @@ 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
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
|
||||||
class StopBeingAngryIfAttackerDeadTaskConfig : SingleTaskConfig {
|
class StopBeingAngryIfAttackerDeadTaskConfig : SingleTaskConfig {
|
||||||
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "stop_being_angry_if_attacker_dead", true).asExpressible()
|
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "stop_being_angry_if_attacker_dead", true).asExpressible()
|
||||||
|
|
||||||
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
|
||||||
|
|
||||||
override fun createTask(
|
override fun createTask(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.ANGRY_AT)
|
||||||
return StopBeingAngryIfTargetDead.create()
|
return StopBeingAngryIfTargetDead.create()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
@@ -29,5 +29,7 @@ class SwitchFromActionEffectTaskConfig : SingleTaskConfig {
|
|||||||
return@Trigger true
|
return@Trigger true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.also {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.ACTIVE_ACTION_EFFECT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
@@ -29,5 +29,7 @@ class SwitchFromChattingTaskConfig : SingleTaskConfig {
|
|||||||
return@Trigger true
|
return@Trigger true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.also {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.DIALOGUES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
@@ -25,9 +26,12 @@ class SwitchFromFightTaskConfig : SingleTaskConfig {
|
|||||||
it.absent(MemoryModuleType.ATTACK_TARGET)
|
it.absent(MemoryModuleType.ATTACK_TARGET)
|
||||||
).apply(it) { _ ->
|
).apply(it) { _ ->
|
||||||
Trigger { level, entity, _ ->
|
Trigger { level, entity, _ ->
|
||||||
|
entity.brain.eraseMemory(CobblemonMemories.ATTACK_TARGET_DATA)
|
||||||
entity.brain.updateActivityFromSchedule(level.dayTime, level.gameTime)
|
entity.brain.updateActivityFromSchedule(level.dayTime, level.gameTime)
|
||||||
return@Trigger true
|
return@Trigger true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.also {
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.ATTACK_TARGET)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
@@ -22,6 +22,7 @@ class SwitchFromHerdTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.HERD_LEADER)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.absent(CobblemonMemories.HERD_LEADER)
|
it.absent(CobblemonMemories.HERD_LEADER)
|
||||||
|
|||||||
+1
@@ -22,6 +22,7 @@ class SwitchFromNPCBattleTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.NPC_BATTLING)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(it.absent(CobblemonMemories.NPC_BATTLING)).apply(it) { _ ->
|
it.group(it.absent(CobblemonMemories.NPC_BATTLING)).apply(it) { _ ->
|
||||||
Trigger { level, entity, _ ->
|
Trigger { level, entity, _ ->
|
||||||
|
|||||||
+1
@@ -22,6 +22,7 @@ class SwitchFromPokemonBattleTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.POKEMON_BATTLE)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(it.absent(CobblemonMemories.POKEMON_BATTLE)).apply(it) { _ ->
|
it.group(it.absent(CobblemonMemories.POKEMON_BATTLE)).apply(it) { _ ->
|
||||||
Trigger { level, entity, _ ->
|
Trigger { level, entity, _ ->
|
||||||
|
|||||||
+1
@@ -29,6 +29,7 @@ class SwitchFromSleepOnTrainerBedTaskConfig : SingleTaskConfig {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.POKEMON_SLEEPING)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.registered(CobblemonMemories.POKEMON_SLEEPING)
|
it.registered(CobblemonMemories.POKEMON_SLEEPING)
|
||||||
|
|||||||
+1
@@ -23,6 +23,7 @@ class SwitchToActionEffectTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.ACTIVE_ACTION_EFFECT)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.absent(CobblemonMemories.ACTIVE_ACTION_EFFECT)
|
it.absent(CobblemonMemories.ACTIVE_ACTION_EFFECT)
|
||||||
|
|||||||
+3
-4
@@ -24,11 +24,10 @@ class SwitchToChattingTaskConfig : SingleTaskConfig {
|
|||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
) = BehaviorBuilder.create {
|
) = BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.present(CobblemonMemories.DIALOGUES),
|
it.present(CobblemonMemories.DIALOGUES)
|
||||||
it.registered(MemoryModuleType.WALK_TARGET)
|
).apply(it) { _ ->
|
||||||
).apply(it) { _, walkTarget ->
|
|
||||||
Trigger { world, entity, _ ->
|
Trigger { world, entity, _ ->
|
||||||
walkTarget.erase()
|
entity.brain.eraseMemory(MemoryModuleType.WALK_TARGET) // it may not even have this memory but clear it if it got it
|
||||||
entity.brain.setActiveActivityIfPossible(CobblemonActivities.NPC_CHATTING)
|
entity.brain.setActiveActivityIfPossible(CobblemonActivities.NPC_CHATTING)
|
||||||
return@Trigger true
|
return@Trigger true
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -40,5 +40,7 @@ class SwitchToFightTaskConfig : SingleTaskConfig {
|
|||||||
return@Trigger true
|
return@Trigger true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.also {
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.ATTACK_TARGET)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
@@ -23,6 +23,7 @@ class SwitchToHerdTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.HERD_LEADER)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.present(CobblemonMemories.HERD_LEADER)
|
it.present(CobblemonMemories.HERD_LEADER)
|
||||||
|
|||||||
+7
-1
@@ -8,16 +8,22 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.CobblemonSensors
|
||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
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) = emptyList<MoLangConfigVariable>()
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
override fun createTask(
|
override fun createTask(
|
||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity> = SwitchToBattleTask.create()
|
): BehaviorControl<in LivingEntity> = SwitchToBattleTask.create().also {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.NPC_BATTLING)
|
||||||
|
behaviourConfigurationContext.addSensors(CobblemonSensors.NPC_BATTLING)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
@@ -18,6 +18,7 @@ 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.sensing.SensorType
|
||||||
import net.minecraft.world.entity.schedule.Activity
|
import net.minecraft.world.entity.schedule.Activity
|
||||||
|
|
||||||
class SwitchToPanicWhenHostilesNearbyTaskConfig : SingleTaskConfig {
|
class SwitchToPanicWhenHostilesNearbyTaskConfig : SingleTaskConfig {
|
||||||
@@ -30,6 +31,8 @@ class SwitchToPanicWhenHostilesNearbyTaskConfig : SingleTaskConfig {
|
|||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.NEAREST_HOSTILE)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.VILLAGER_HOSTILES)
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(it.present(MemoryModuleType.NEAREST_HOSTILE))
|
it.group(it.present(MemoryModuleType.NEAREST_HOSTILE))
|
||||||
.apply(it) { nearestHostile ->
|
.apply(it) { nearestHostile ->
|
||||||
|
|||||||
+5
@@ -18,6 +18,7 @@ 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.sensing.SensorType
|
||||||
import net.minecraft.world.entity.schedule.Activity
|
import net.minecraft.world.entity.schedule.Activity
|
||||||
|
|
||||||
class SwitchToPanicWhenHurtTaskConfig : SingleTaskConfig {
|
class SwitchToPanicWhenHurtTaskConfig : SingleTaskConfig {
|
||||||
@@ -36,6 +37,8 @@ class SwitchToPanicWhenHurtTaskConfig : SingleTaskConfig {
|
|||||||
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||||
if (!condition.resolveBoolean()) return null
|
if (!condition.resolveBoolean()) return null
|
||||||
return if (includePassiveDamage.resolveBoolean()) {
|
return if (includePassiveDamage.resolveBoolean()) {
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.HURT_BY)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.HURT_BY)
|
||||||
BehaviorBuilder.create {
|
BehaviorBuilder.create {
|
||||||
it.group(it.present(MemoryModuleType.HURT_BY))
|
it.group(it.present(MemoryModuleType.HURT_BY))
|
||||||
.apply(it) { _ ->
|
.apply(it) { _ ->
|
||||||
@@ -47,6 +50,8 @@ class SwitchToPanicWhenHurtTaskConfig : SingleTaskConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
behaviourConfigurationContext.addMemories(MemoryModuleType.HURT_BY_ENTITY)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.HURT_BY)
|
||||||
BehaviorBuilder.create {
|
BehaviorBuilder.create {
|
||||||
it.group(it.present(MemoryModuleType.HURT_BY_ENTITY))
|
it.group(it.present(MemoryModuleType.HURT_BY_ENTITY))
|
||||||
.apply(it) { _ ->
|
.apply(it) { _ ->
|
||||||
|
|||||||
+2
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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.npc.configuration.MoLangConfigVariable
|
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
|
||||||
@@ -20,6 +21,7 @@ class SwitchToPokemonBattleTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity> {
|
): BehaviorControl<in LivingEntity> {
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.POKEMON_BATTLE)
|
||||||
return SwitchToBattleTask.createForPokemon()
|
return SwitchToBattleTask.createForPokemon()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
@@ -36,6 +36,12 @@ class SwitchToSleepOnTrainerBedTaskConfig : SingleTaskConfig {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
CobblemonMemories.POKEMON_SLEEPING,
|
||||||
|
CobblemonMemories.POKEMON_BATTLE,
|
||||||
|
MemoryModuleType.WALK_TARGET
|
||||||
|
)
|
||||||
|
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.absent(CobblemonMemories.POKEMON_BATTLE),
|
it.absent(CobblemonMemories.POKEMON_BATTLE),
|
||||||
|
|||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.bedrockk.molang.Expression
|
||||||
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
|
import com.cobblemon.mod.common.api.ai.CobblemonAttackTargetData
|
||||||
|
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
|
||||||
|
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||||
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
|
import com.cobblemon.mod.common.util.asExpression
|
||||||
|
import com.cobblemon.mod.common.util.resolveBoolean
|
||||||
|
import com.cobblemon.mod.common.util.withQueryValue
|
||||||
|
import com.mojang.datafixers.util.Either
|
||||||
|
import net.minecraft.world.entity.LivingEntity
|
||||||
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
|
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||||
|
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryStatus
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly sets the attack target of the entity to the nearest visible entity that matches the [entityCondition]
|
||||||
|
* and is within the [range].
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since June 23rd, 2025
|
||||||
|
*/
|
||||||
|
class TargetEntityTaskConfig : SingleTaskConfig {
|
||||||
|
val entityCondition: Expression = "true".asExpression()
|
||||||
|
val range: ExpressionOrEntityVariable = Either.left("24".asExpression())
|
||||||
|
|
||||||
|
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
|
||||||
|
override fun createTask(
|
||||||
|
entity: LivingEntity,
|
||||||
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
val range = range.resolveFloat()
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
|
||||||
|
MemoryModuleType.ATTACK_TARGET,
|
||||||
|
CobblemonMemories.ATTACK_TARGET_DATA
|
||||||
|
)
|
||||||
|
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
|
||||||
|
return BehaviorBuilder.create { instance ->
|
||||||
|
instance.group(
|
||||||
|
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
|
||||||
|
instance.registered(MemoryModuleType.ATTACK_TARGET)
|
||||||
|
).apply(instance) { entities, attackTarget ->
|
||||||
|
Trigger { world, entity, _ ->
|
||||||
|
val target = instance.get(entities).findClosest {
|
||||||
|
runtime.withQueryValue("entity", it.asMostSpecificMoLangValue())
|
||||||
|
return@findClosest runtime.resolveBoolean(entityCondition)
|
||||||
|
}.orElse(null)
|
||||||
|
|
||||||
|
if (target != null && target.distanceTo(entity) <= range) {
|
||||||
|
val attackTargetData = CobblemonAttackTargetData(shouldContinue = entityCondition)
|
||||||
|
entity.brain.setMemory(CobblemonMemories.ATTACK_TARGET_DATA, attackTargetData)
|
||||||
|
attackTarget.set(target)
|
||||||
|
}
|
||||||
|
return@Trigger true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,8 @@ 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
|
||||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||||
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||||
|
import net.minecraft.world.entity.ai.sensing.SensorType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A configuration for a brain task. Its purpose is to generate a list of tasks to add to the brain of
|
* A configuration for a brain task. Its purpose is to generate a list of tasks to add to the brain of
|
||||||
@@ -57,6 +59,7 @@ interface TaskConfig {
|
|||||||
cobblemonResource("do_nothing") to DoNothingTaskConfig::class.java,
|
cobblemonResource("do_nothing") to DoNothingTaskConfig::class.java,
|
||||||
cobblemonResource("get_angry_at_attacker") to GetAngryAtAttackerTaskConfig::class.java,
|
cobblemonResource("get_angry_at_attacker") to GetAngryAtAttackerTaskConfig::class.java,
|
||||||
cobblemonResource("stop_being_angry_if_attacker_dead") to StopBeingAngryIfAttackerDeadTaskConfig::class.java,
|
cobblemonResource("stop_being_angry_if_attacker_dead") to StopBeingAngryIfAttackerDeadTaskConfig::class.java,
|
||||||
|
cobblemonResource("stop_attacking_if_target_invalid") to StopAttackingIfTargetInvalidTaskConfig::class.java,
|
||||||
cobblemonResource("switch_npc_to_battle") to SwitchToNPCBattleTaskConfig::class.java,
|
cobblemonResource("switch_npc_to_battle") to SwitchToNPCBattleTaskConfig::class.java,
|
||||||
cobblemonResource("look_at_battling_pokemon") to LookAtBattlingPokemonTaskConfig::class.java,
|
cobblemonResource("look_at_battling_pokemon") to LookAtBattlingPokemonTaskConfig::class.java,
|
||||||
cobblemonResource("switch_npc_from_battle") to SwitchFromNPCBattleTaskConfig::class.java,
|
cobblemonResource("switch_npc_from_battle") to SwitchFromNPCBattleTaskConfig::class.java,
|
||||||
@@ -96,7 +99,8 @@ interface TaskConfig {
|
|||||||
cobblemonResource("eat_grass") to EatGrassTaskConfig::class.java,
|
cobblemonResource("eat_grass") to EatGrassTaskConfig::class.java,
|
||||||
cobblemonResource("find_air") to FindAirTaskConfig::class.java,
|
cobblemonResource("find_air") to FindAirTaskConfig::class.java,
|
||||||
cobblemonResource("go_to_land") to GoToLandTaskConfig::class.java,
|
cobblemonResource("go_to_land") to GoToLandTaskConfig::class.java,
|
||||||
cobblemonResource("battle_flight_task") to BattleFlightTaskConfig::class.java,
|
cobblemonResource("manage_flight_in_battle") to ManageFlightInBattleTaskConfig::class.java,
|
||||||
|
cobblemonResource("attack_hostile_mobs") to AttackHostileMobsTaskConfig::class.java,
|
||||||
cobblemonResource("move_into_fluid") to MoveIntoFluidTaskConfig::class.java,
|
cobblemonResource("move_into_fluid") to MoveIntoFluidTaskConfig::class.java,
|
||||||
cobblemonResource("find_herd_leader") to FindHerdLeaderTaskConfig::class.java,
|
cobblemonResource("find_herd_leader") to FindHerdLeaderTaskConfig::class.java,
|
||||||
cobblemonResource("follow_herd_leader") to FollowHerdLeaderTaskConfig::class.java,
|
cobblemonResource("follow_herd_leader") to FollowHerdLeaderTaskConfig::class.java,
|
||||||
@@ -104,8 +108,10 @@ interface TaskConfig {
|
|||||||
cobblemonResource("switch_from_herd") to SwitchFromHerdTaskConfig::class.java,
|
cobblemonResource("switch_from_herd") to SwitchFromHerdTaskConfig::class.java,
|
||||||
cobblemonResource("maintain_herd_leader") to MaintainHerdLeaderTaskConfig::class.java,
|
cobblemonResource("maintain_herd_leader") to MaintainHerdLeaderTaskConfig::class.java,
|
||||||
cobblemonResource("count_followers") to CountFollowersTaskConfig::class.java,
|
cobblemonResource("count_followers") to CountFollowersTaskConfig::class.java,
|
||||||
|
cobblemonResource("hate_entity") to HateEntityTaskConfig::class.java,
|
||||||
|
cobblemonResource("target_entity") to TargetEntityTaskConfig::class.java,
|
||||||
)
|
)
|
||||||
|
|
||||||
val runtime = MoLangRuntime().setup()
|
val runtime = MoLangRuntime().setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.CobblemonMemories
|
||||||
|
import com.cobblemon.mod.common.CobblemonSensors
|
||||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||||
@@ -22,6 +24,11 @@ class WakeUpTaskConfig : SingleTaskConfig {
|
|||||||
entity: LivingEntity,
|
entity: LivingEntity,
|
||||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||||
): BehaviorControl<in LivingEntity>? {
|
): BehaviorControl<in LivingEntity>? {
|
||||||
|
if (entity !is PokemonEntity) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
behaviourConfigurationContext.addMemories(CobblemonMemories.POKEMON_DROWSY, CobblemonMemories.POKEMON_SLEEPING)
|
||||||
|
behaviourConfigurationContext.addSensors(CobblemonSensors.POKEMON_DROWSY)
|
||||||
return WrapperLivingEntityTask(WakeUpTask.create(), PokemonEntity::class.java)
|
return WrapperLivingEntityTask(WakeUpTask.create(), PokemonEntity::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-3
@@ -98,6 +98,12 @@ class WanderTaskConfig : SingleTaskConfig {
|
|||||||
|
|
||||||
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
|
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
MemoryModuleType.LOOK_TARGET,
|
||||||
|
CobblemonMemories.PATH_COOLDOWN
|
||||||
|
)
|
||||||
|
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.absent(MemoryModuleType.WALK_TARGET),
|
it.absent(MemoryModuleType.WALK_TARGET),
|
||||||
@@ -134,9 +140,6 @@ class WanderTaskConfig : SingleTaskConfig {
|
|||||||
maximumHeight = maximumHeight,
|
maximumHeight = maximumHeight,
|
||||||
world = world
|
world = world
|
||||||
)
|
)
|
||||||
// if (targetVec.y < minimumHeight || targetVec.y > maximumHeight) {
|
|
||||||
// return@Trigger false
|
|
||||||
// }
|
|
||||||
walkTarget.set(
|
walkTarget.set(
|
||||||
CobblemonWalkTarget(
|
CobblemonWalkTarget(
|
||||||
pos = pos,
|
pos = pos,
|
||||||
|
|||||||
+12
-2
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
package com.cobblemon.mod.common.api.ai.config.task
|
package com.cobblemon.mod.common.api.ai.config.task
|
||||||
|
|
||||||
|
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.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
|
||||||
@@ -50,11 +51,18 @@ class WaterWanderTaskConfig : SingleTaskConfig {
|
|||||||
|
|
||||||
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
|
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
|
||||||
|
|
||||||
|
behaviourConfigurationContext.addMemories(
|
||||||
|
MemoryModuleType.WALK_TARGET,
|
||||||
|
MemoryModuleType.LOOK_TARGET,
|
||||||
|
CobblemonMemories.PATH_COOLDOWN
|
||||||
|
)
|
||||||
|
|
||||||
return BehaviorBuilder.create {
|
return BehaviorBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
it.absent(MemoryModuleType.WALK_TARGET),
|
it.absent(MemoryModuleType.WALK_TARGET),
|
||||||
it.registered(MemoryModuleType.LOOK_TARGET)
|
it.registered(MemoryModuleType.LOOK_TARGET),
|
||||||
).apply(it) { walkTarget, lookTarget ->
|
it.registered(CobblemonMemories.PATH_COOLDOWN)
|
||||||
|
).apply(it) { walkTarget, lookTarget, pathCooldown ->
|
||||||
Trigger { world, entity, time ->
|
Trigger { world, entity, time ->
|
||||||
if (entity !is PathfinderMob || !entity.isInWater) {
|
if (entity !is PathfinderMob || !entity.isInWater) {
|
||||||
return@Trigger false
|
return@Trigger false
|
||||||
@@ -66,6 +74,8 @@ class WaterWanderTaskConfig : SingleTaskConfig {
|
|||||||
return@Trigger false
|
return@Trigger false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pathCooldown.setWithExpiry(true, 60L)
|
||||||
|
|
||||||
val target = BehaviorUtils.getRandomSwimmablePos(entity, horizontalRange.resolveInt(), verticalRange.resolveInt()) ?: return@Trigger false
|
val target = BehaviorUtils.getRandomSwimmablePos(entity, horizontalRange.resolveInt(), verticalRange.resolveInt()) ?: return@Trigger false
|
||||||
walkTarget.set(
|
walkTarget.set(
|
||||||
CobblemonWalkTarget(
|
CobblemonWalkTarget(
|
||||||
|
|||||||
+1
-1
@@ -83,7 +83,7 @@ interface ExperienceCandyUseEvent {
|
|||||||
*
|
*
|
||||||
* @return If any experience was gained from the candy and if it was consumed.
|
* @return If any experience was gained from the candy and if it was consumed.
|
||||||
*/
|
*/
|
||||||
fun wasCandyConsumed() = this.experienceResult.experienceAdded > 0 && !player.isCreative
|
fun wasCandyConsumed() = this.experienceResult.experienceAdded > 0 && !player.hasInfiniteMaterials()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -30,7 +30,7 @@ data class PokemonInteractionGUICreationEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getNextFreeOrientation(): Orientation {
|
private fun getNextFreeOrientation(): Orientation {
|
||||||
var largest = Orientation.TOP_LEFT
|
var largest = Orientation.NORTH
|
||||||
for (orientation in Orientation.entries) {
|
for (orientation in Orientation.entries) {
|
||||||
if(!options.containsKey(orientation)) {
|
if(!options.containsKey(orientation)) {
|
||||||
return orientation
|
return orientation
|
||||||
@@ -42,4 +42,4 @@ data class PokemonInteractionGUICreationEvent(
|
|||||||
}
|
}
|
||||||
return largest
|
return largest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,20 +29,4 @@ interface EntityInteraction<T : Entity> {
|
|||||||
* @return true if the interaction was successful and no further interactions should be processed
|
* @return true if the interaction was successful and no further interactions should be processed
|
||||||
*/
|
*/
|
||||||
fun onInteraction(player: ServerPlayer, entity: T, stack: ItemStack): Boolean
|
fun onInteraction(player: ServerPlayer, entity: T, stack: ItemStack): Boolean
|
||||||
|
|
||||||
/**
|
|
||||||
* Decreases the stack size by a given amount.
|
|
||||||
* The stack size should be validated beforehand.
|
|
||||||
* If the [player] is in creative mode the decrement won't be performed.
|
|
||||||
*
|
|
||||||
* @param player The [ServerPlayer] that caused the interaction, this is used to check for creative mode.
|
|
||||||
* @param stack The [ItemStack] being mutated.
|
|
||||||
* @param amount The amount to deduct from the stack, default is 1.
|
|
||||||
*/
|
|
||||||
fun consumeItem(player: ServerPlayer, stack: ItemStack, amount: Int = 1) {
|
|
||||||
if (!player.isCreative) {
|
|
||||||
stack.shrink(amount)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -112,7 +112,7 @@ class ShrinkItemEffect(val amount: Int = 1): InteractionEffect {
|
|||||||
if (player.getItemInHand(InteractionHand.MAIN_HAND).isDamageableItem)
|
if (player.getItemInHand(InteractionHand.MAIN_HAND).isDamageableItem)
|
||||||
player.getItemInHand(InteractionHand.MAIN_HAND).hurtAndBreak(amount, player, EquipmentSlot.MAINHAND)
|
player.getItemInHand(InteractionHand.MAIN_HAND).hurtAndBreak(amount, player, EquipmentSlot.MAINHAND)
|
||||||
else
|
else
|
||||||
player.getItemInHand(InteractionHand.MAIN_HAND).shrink(amount)
|
player.getItemInHand(InteractionHand.MAIN_HAND).consume(amount, player)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
+1
-3
@@ -87,9 +87,7 @@ interface PokemonAndMoveSelectingItem {
|
|||||||
player.sendSystemMessage(battleLang("bagitem.invalid").red())
|
player.sendSystemMessage(battleLang("bagitem.invalid").red())
|
||||||
} else {
|
} else {
|
||||||
battlePokemon.actor.forceChoose(BagItemActionResponse(bagItem, battlePokemon, move.template.name))
|
battlePokemon.actor.forceChoose(BagItemActionResponse(bagItem, battlePokemon, move.template.name))
|
||||||
if (!player.isCreative) {
|
stack.consume(1, player)
|
||||||
stack.shrink(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ interface PokemonSelectingItem {
|
|||||||
} else {
|
} else {
|
||||||
battlePokemon.actor.forceChoose(BagItemActionResponse(bagItem, battlePokemon))
|
battlePokemon.actor.forceChoose(BagItemActionResponse(bagItem, battlePokemon))
|
||||||
val stackName = BuiltInRegistries.ITEM.getKey(stack.item)
|
val stackName = BuiltInRegistries.ITEM.getKey(stack.item)
|
||||||
if (!player.isCreative) {
|
if (!player.hasInfiniteMaterials()) {
|
||||||
stack.shrink(1)
|
stack.shrink(1)
|
||||||
battlePokemon.actor.itemsUsed.add(bagItem)
|
battlePokemon.actor.itemsUsed.add(bagItem)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ import net.minecraft.tags.TagKey
|
|||||||
import net.minecraft.world.damagesource.DamageSource
|
import net.minecraft.world.damagesource.DamageSource
|
||||||
import net.minecraft.world.damagesource.DamageTypes
|
import net.minecraft.world.damagesource.DamageTypes
|
||||||
import net.minecraft.world.entity.Entity
|
import net.minecraft.world.entity.Entity
|
||||||
|
import net.minecraft.world.entity.EntityDimensions
|
||||||
import net.minecraft.world.entity.EntityType
|
import net.minecraft.world.entity.EntityType
|
||||||
import net.minecraft.world.entity.LightningBolt
|
import net.minecraft.world.entity.LightningBolt
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
@@ -296,6 +297,13 @@ object MoLangFunctions {
|
|||||||
}
|
}
|
||||||
world.setBlock(BlockPos(x, y, z), block.defaultBlockState(), Block.UPDATE_ALL)
|
world.setBlock(BlockPos(x, y, z), block.defaultBlockState(), Block.UPDATE_ALL)
|
||||||
}
|
}
|
||||||
|
map.put("is_air") { params ->
|
||||||
|
val x = params.getDouble(0).toInt()
|
||||||
|
val y = params.getDouble(1).toInt()
|
||||||
|
val z = params.getDouble(2).toInt()
|
||||||
|
val blockState = world.getBlockState(BlockPos(x, y, z))
|
||||||
|
return@put DoubleValue(blockState.isAir)
|
||||||
|
}
|
||||||
map.put("get_block") { params ->
|
map.put("get_block") { params ->
|
||||||
val x = params.getInt(0)
|
val x = params.getInt(0)
|
||||||
val y = params.getInt(1)
|
val y = params.getInt(1)
|
||||||
@@ -920,6 +928,34 @@ object MoLangFunctions {
|
|||||||
return@put DoubleValue.ZERO
|
return@put DoubleValue.ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
map.put("set_render_scale") { params ->
|
||||||
|
val scale = params.getDouble(0)
|
||||||
|
npc.renderScale = scale.toFloat()
|
||||||
|
return@put DoubleValue.ONE
|
||||||
|
}
|
||||||
|
map.put("render_scale") { _ -> DoubleValue(npc.renderScale) }
|
||||||
|
map.put("set_hitbox_scale") { params ->
|
||||||
|
val scale = params.getDouble(0).toFloat()
|
||||||
|
npc.hitboxScale = scale
|
||||||
|
npc.refreshDimensions()
|
||||||
|
return@put DoubleValue.ONE
|
||||||
|
}
|
||||||
|
map.put("hitbox_scale") { _ -> DoubleValue(npc.hitboxScale) }
|
||||||
|
map.put("set_hitbox") { params ->
|
||||||
|
if (params.params.size == 0) {
|
||||||
|
npc.hitbox = null
|
||||||
|
return@put DoubleValue.ONE
|
||||||
|
}
|
||||||
|
val width = params.getDouble(0).toFloat()
|
||||||
|
val height = params.getDouble(1).toFloat()
|
||||||
|
val eyeHeight = params.getDoubleOrNull(2)?.toFloat() ?: (height * 0.85F)
|
||||||
|
npc.hitbox = EntityDimensions.scalable(width, height).withEyeHeight(eyeHeight)
|
||||||
|
return@put DoubleValue.ONE
|
||||||
|
}
|
||||||
|
map.put("unset_hitbox") {
|
||||||
|
npc.hitbox = null
|
||||||
|
return@put DoubleValue.ONE
|
||||||
|
}
|
||||||
map.put("aspects") {
|
map.put("aspects") {
|
||||||
val aspects = npc.aspects
|
val aspects = npc.aspects
|
||||||
return@put aspects.asArrayValue { StringValue(it) }
|
return@put aspects.asArrayValue { StringValue(it) }
|
||||||
@@ -1235,6 +1271,7 @@ object MoLangFunctions {
|
|||||||
map.put("is_sprinting") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("sprinting"))) }
|
map.put("is_sprinting") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("sprinting"))) }
|
||||||
map.put("in_air") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("in_air"))) }
|
map.put("in_air") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("in_air"))) }
|
||||||
map.put("is_wild") { DoubleValue(pokemonEntity.ownerUUID == null) }
|
map.put("is_wild") { DoubleValue(pokemonEntity.ownerUUID == null) }
|
||||||
|
map.put("is_in_party") { DoubleValue(pokemonEntity.pokemon.storeCoordinates.get()?.store is PartyStore) }
|
||||||
map.put("is_ridden") { DoubleValue(pokemonEntity.hasControllingPassenger()) }
|
map.put("is_ridden") { DoubleValue(pokemonEntity.hasControllingPassenger()) }
|
||||||
map.put("has_aspect") { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
|
map.put("has_aspect") { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
|
||||||
map.put("is_pokemon") { DoubleValue.ONE }
|
map.put("is_pokemon") { DoubleValue.ONE }
|
||||||
@@ -1243,6 +1280,12 @@ object MoLangFunctions {
|
|||||||
}) }
|
}) }
|
||||||
map.put("is_wearing_hat") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS)) }
|
map.put("is_wearing_hat") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS)) }
|
||||||
map.put("is_wearing_face") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)) }
|
map.put("is_wearing_face") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)) }
|
||||||
|
map.put("is_pastured") {
|
||||||
|
DoubleValue((pokemonEntity.tethering != null))
|
||||||
|
}
|
||||||
|
map.put("pasture_conflict_enabled") {
|
||||||
|
DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.PASTURE_CONFLICT))
|
||||||
|
}
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -39,9 +39,8 @@ class NPCClass {
|
|||||||
var resourceIdentifier: ResourceLocation = cobblemonResource("dummy")
|
var resourceIdentifier: ResourceLocation = cobblemonResource("dummy")
|
||||||
var names: MutableList<Component> = mutableListOf()
|
var names: MutableList<Component> = mutableListOf()
|
||||||
var aspects: MutableSet<String> = mutableSetOf() // These only make sense when applied via presets
|
var aspects: MutableSet<String> = mutableSetOf() // These only make sense when applied via presets
|
||||||
var baseScale: Float = 1F
|
|
||||||
var hitbox = EntityDimensions.scalable(0.6F, 1.8F).withEyeHeight(1.62F)
|
var hitbox = EntityDimensions.scalable(0.6F, 1.8F).withEyeHeight(1.62F)
|
||||||
var modelScale: Float = 0.9375F
|
var modelScale: Float = 0.9375F // Should this be removed in favour of the render scale stuff set on the entity?
|
||||||
var battleConfiguration = NPCBattleConfiguration()
|
var battleConfiguration = NPCBattleConfiguration()
|
||||||
var interaction: NPCInteractConfiguration? = null
|
var interaction: NPCInteractConfiguration? = null
|
||||||
var canDespawn = true
|
var canDespawn = true
|
||||||
@@ -66,7 +65,6 @@ class NPCClass {
|
|||||||
fun encode(buffer: RegistryFriendlyByteBuf) {
|
fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||||
buffer.writeString(resourceIdentifier.toString())
|
buffer.writeString(resourceIdentifier.toString())
|
||||||
buffer.writeCollection(names) { _, v -> buffer.writeText(v) }
|
buffer.writeCollection(names) { _, v -> buffer.writeText(v) }
|
||||||
buffer.writeFloat(baseScale)
|
|
||||||
buffer.writeFloat(hitbox.width)
|
buffer.writeFloat(hitbox.width)
|
||||||
buffer.writeFloat(hitbox.height)
|
buffer.writeFloat(hitbox.height)
|
||||||
buffer.writeBoolean(hitbox.fixed)
|
buffer.writeBoolean(hitbox.fixed)
|
||||||
@@ -107,7 +105,6 @@ class NPCClass {
|
|||||||
fun decode(buffer: RegistryFriendlyByteBuf) {
|
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||||
resourceIdentifier = ResourceLocation.parse(buffer.readString().toString())
|
resourceIdentifier = ResourceLocation.parse(buffer.readString().toString())
|
||||||
names = buffer.readList { buffer.readText().copy() }.toMutableList()
|
names = buffer.readList { buffer.readText().copy() }.toMutableList()
|
||||||
baseScale = buffer.readFloat()
|
|
||||||
val length = buffer.readFloat()
|
val length = buffer.readFloat()
|
||||||
val width = buffer.readFloat()
|
val width = buffer.readFloat()
|
||||||
val fixed = buffer.readBoolean()
|
val fixed = buffer.readBoolean()
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user