Compare commits

...
Author SHA1 Message Date
JPAKx4 9163046b45 Merge branch 'main' into irl_date_time
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/molang/MoLangFunctions.kt
2025-08-08 21:03:49 -05:00
Paul 325d1af484 Fixed swim wanders not working 2025-08-09 10:44:55 +10:00
Polymeta 6ae71f28e6 Merge branch 'spicy-molang' into 'main'
Added string utility related MoLang functions

See merge request cable-mc/cobblemon!1754
2025-08-08 23:29:38 +00:00
SpicyandPolymeta 5687a71de4 Added string utility related MoLang functions 2025-08-08 23:29:38 +00:00
Polymeta 8199f8d7c2 Merge branch 'josh/helditem-render-fix' into 'main'
Fixed locators being flipped for shoulder mounts and model widgets

See merge request cable-mc/cobblemon!1764
2025-08-08 21:41:09 +00:00
Polymeta 6b39251d65 Merge branch 'Shipwreck-Loot-Table-Adjustments' into 'main'
Shipwreck loot table adjustments

See merge request cable-mc/cobblemon!1765
2025-08-08 21:40:50 +00:00
Slippy cd03e6f8c4 Replaced the Phantoms with Breezes in the Lush Shipwreck Cove 2025-08-08 00:48:19 -05:00
Slippy a1b53f90ad Adjusting the loot table to trial spawners in shipwreck coves a little bit. 2025-08-08 00:40:54 -05:00
Josh c0677c6353 Fixed item rendering being flipped for shoulder mounts and model widgets 2025-08-05 13:11:14 -04:00
Paul 756989b0c0 Fixed storages not saving (OOPS) 2025-08-04 21:26:01 +10:00
Paul 58a4267f42 Added a living entity look_at_position function so we can make funny battle effects 2025-08-04 21:25:54 +10:00
Hiroku e8826a3d0e Merge branch 'trigger-behaviour' into 'main'
EntityCallbacks

See merge request cable-mc/cobblemon!1757
2025-08-04 07:58:43 +00:00
Veraxiel 0606d57ef1 Edit README.md 2025-08-04 03:50:21 -04:00
Veraxiel ef2578c1a7 Fixed typo on tag readme 2025-08-04 03:49:26 -04:00
Veraxiel 3812de7558 Edit README.md 2025-08-04 03:46:47 -04:00
Hiroku ef558981c2 Add readme 2025-08-04 06:18:14 +00:00
Paul e4f928bce1 Revert "Removed #c:is_cold from #cobblemon:is_cold to prevent pokes in the end that should not be in the end"
This reverts commit 6090fce254.
2025-08-04 15:55:43 +10:00
Paul 6090fce254 Removed #c:is_cold from #cobblemon:is_cold to prevent pokes in the end that should not be in the end 2025-08-04 14:29:20 +10:00
Hiroku 5a5d43404f Merge branch 'safer-change-detection' into 'main'
Removed observable use from Pokemon to better secure saving from rollback issues

See merge request cable-mc/cobblemon!1759
2025-08-04 00:52:56 +00:00
Paul 931c3a7e6c Removed observable use from Pokemon to better secure saving from rollback issues 2025-08-04 10:09:16 +10:00
Paul d5a6e0dffd Ohhh, THAT's why it was written that way 2025-08-03 15:40:56 +10:00
Polymeta f56c357e4e Merge branch 'retype' into 'main'
Small Asset Updates

See merge request cable-mc/cobblemon!1758
2025-08-02 21:16:38 +00:00
dhi_holoandPolymeta 4bfca0da43 Small Asset Updates 2025-08-02 21:16:38 +00:00
Paul 52cff2e99d prepare_{id}, damage_{id} hooks for action effects, q.has_argument for battle messages, added q.hit_count to move action effects 2025-08-02 13:11:20 +10:00
Paul 52f21ffc82 License and registration please 2025-08-01 20:38:14 +10:00
Paul 9c31899f3c Fixed up some missing lang for behaviours 2025-08-01 20:32:17 +10:00
Polymeta 9a5172f1cc fix encoding issue with boat ride style
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-08-01 10:48:23 +01:00
Polymeta 11051f2b54 Merge branch 'riding-looping-sound' into 'main'
Ride specific sound implementation

See merge request cable-mc/cobblemon!1641
2025-08-01 08:12:32 +00:00
Jackson BowesandPolymeta 8b48cfaa50 Ride specific sound implementation 2025-08-01 08:12:32 +00:00
Polymeta 50c3ffc774 Merge branch 'bugfix-entity-health' into 'main'
Couple Pokémon HP / Entity health in a more sensible way.

See merge request cable-mc/cobblemon!1750
2025-07-28 08:58:23 +00:00
Polymeta daf32a5cf3 Merge branch 'food-tweaks' into 'main'
Eat your, well, lots of things

Closes #1616

See merge request cable-mc/cobblemon!1756
2025-07-28 08:56:41 +00:00
dhi_holoandPolymeta af4d2077ae Eat your, well, lots of things 2025-07-28 08:56:41 +00:00
Paul 3f090ce691 Merge remote-tracking branch 'origin/main' into trigger-behaviour 2025-07-28 11:34:37 +10:00
Polymeta b1a3cbf29d Merge branch 'cleanup-crew' into 'main'
Small Fixes

Closes #1640 and #1199

See merge request cable-mc/cobblemon!1753
2025-07-27 21:08:36 +00:00
dhi_holoandPolymeta 130c50a2d6 Small Fixes 2025-07-27 21:08:35 +00:00
Hiroku 0b65259ee7 Merge branch 'let-me-break-it-down-for-you-mark-we-can-bee-bees' into 'main'
Species JSON dictates if something acts like a bee (pollinates flowers and delivers to hive/nest)

See merge request cable-mc/cobblemon!1709
2025-07-27 12:16:12 +00:00
Paul 53897a2613 Removed debug code 2025-07-27 22:04:17 +10:00
Paul 8e6681b3aa Introduced EntityCallbacks 2025-07-27 22:02:30 +10:00
Paul 50427965ab Merge remote-tracking branch 'origin/main' into trigger-behaviour 2025-07-26 21:41:09 +10:00
Hiroku 3318ee801a Merge branch 'extra_flows' into 'main'
Many more Pokemon function refinements and Molang Flows

See merge request cable-mc/cobblemon!1710
2025-07-26 11:04:31 +00:00
Hiroku 0b97d139af Edit CobblemonFlows.kt 2025-07-26 10:51:35 +00:00
Paul 3966607373 Tidy up the script actions for adding/removing a Behaviour on an entity 2025-07-26 18:34:40 +10:00
Paul b7c5f489fd More cleanup 2025-07-26 14:31:57 +10:00
Paul 39ec6187b5 Various cleanup items and important fixes for wandering caused by bee stuff 2025-07-26 14:29:05 +10:00
Paul b7681b43f9 Merge remote-tracking branch 'origin/main' into let-me-break-it-down-for-you-mark-we-can-bee-bees 2025-07-26 13:26:19 +10:00
Konoha ae594a0790 Merge branch 'main' into extra_flows
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/molang/MoLangFunctions.kt
2025-07-24 08:04:14 -04:00
Konoha 6af299406d Merge remote-tracking branch 'origin/main' 2025-07-24 07:57:51 -04:00
Nadja Reitzenstein 29833df50e Couple Pokémon HP / Entity health in a more sensible way.
Specifically, don't touch Battle HP for wild Pokémon so that you can't hurt a Pokémon down out of battle for an easier catch, and always round entity health up so that only a HP of 0 is a health of 0
2025-07-24 13:09:33 +02:00
Paul 01d42abdb2 look_at_target requires nearest living entities memory and sensor 2025-07-23 23:16:32 +10:00
Paul baa3f47769 Removed unused memory 2025-07-23 19:11:19 +10:00
Paul 16e716411a Merge remote-tracking branch 'origin/main' into let-me-break-it-down-for-you-mark-we-can-bee-bees
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/npc/NPCBrain.kt
2025-07-23 18:58:19 +10:00
Paul 3bbc551fd7 Wander controls supporting keeping wanderers around a point, bees stay around their hive 2025-07-23 18:55:52 +10:00
Polymeta 74381d8e3c move mixin away from ModifyConstant to improve compatibility with other mods
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-07-22 23:48:21 +01:00
Polymeta 6688c32a1d Merge branch 'smashling' into 'main'
Create saccharine_sapling.json

See merge request cable-mc/cobblemon!1749
2025-07-22 21:39:24 +00:00
dhi_holo 45dcf6f23b Create saccharine_sapling.json 2025-07-22 17:02:54 +10:00
Polymeta e4d92ead6a Merge branch 'log-spawn' into 'main'
Update saccharine log spawning

See merge request cable-mc/cobblemon!1742
2025-07-19 20:11:01 +00:00
TestandPolymeta 9631f3c9d5 Update saccharine log spawning 2025-07-19 20:11:01 +00:00
Polymeta 0787f2772d Merge branch '1.7-Tree-and-Crop-Generation' into 'main'
SaccharineTreeFeature to consider #cobblemon:has_feature/saccharine_tree

See merge request cable-mc/cobblemon!1748
2025-07-19 19:24:00 +00:00
Polymeta 4011502e54 changelog and license
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-07-19 08:35:51 +01:00
Polymeta 06855f6404 adding placed features for grains and galarica nuts
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-07-19 08:17:37 +01:00
Slippy 815955b904 Hearty Grains, Galarica Nut Bushes, and Saccharine Trees now generate with appropriate rates and locations. Just need Poly to do the mixin work 2025-07-19 01:50:24 -05:00
Polymeta df9eed0da3 Merge branch '1,21-Gigawatts' into 'main'
Lightning Interactions with Pokemon

See merge request cable-mc/cobblemon!1733
2025-07-19 06:08:35 +00:00
JazzMcNadeandPolymeta 99b73aa8dd Lightning Interactions with Pokemon 2025-07-19 06:08:34 +00:00
Polymeta f2d5073c7c enforce fabric versions to match what cobblemon is built against for consistency
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-07-19 00:02:49 +01:00
Paul 3fda5f7c7a give all NPCs the dialogues and battling memories 2025-07-18 18:18:44 +10:00
Hiroku 9b81666437 Merge branch 'pokedex-percentage-command' into 'main'
Fix Pokedex Percentage Command

Closes #1525

See merge request cable-mc/cobblemon!1692
2025-07-18 04:58:34 +00:00
CeejayandHiroku b43f969c02 Fix Pokedex Percentage Command 2025-07-18 04:58:34 +00:00
Polymeta 02c4947513 fixed some typos in pokemon interactions
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-07-17 23:10:07 +01:00
Slippy 6158b36103 Saccharine trees are now rarer and generate in the correct biomes 2025-07-16 12:18:39 -05:00
Polymeta 2e14f8f8e8 hearty grains will generate with both blocks when of the right age
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-07-16 10:22:48 +01:00
Polymeta bc80d6a171 SaccharineTreeFeature to consider #cobblemon:has_feature/saccharine_tree
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-07-16 08:30:32 +01:00
Konoha 65a7fc6fd7 Implement includeLegacy parameters 2025-07-15 22:11:47 -04:00
Konoha ce019631ce Merge branch 'main' into extra_flows 2025-07-15 21:58:19 -04:00
Konoha 0534e0d201 Merge remote-tracking branch 'origin/main' 2025-07-15 21:51:31 -04:00
Konoha 895e3ca378 Update Benched Moves after teachLearnableMoves call 2025-07-15 21:51:14 -04:00
Test 3048e3d81d fix data for variations and species features 2025-07-15 02:14:53 -04:00
Polymeta 77fb94d9ef Merge branch 'fix-x-axis-offsets' into 'main'
Fix X-axis being a different direction than Blockbench and addded new property attachment_options

See merge request cable-mc/cobblemon!1730
2025-07-13 23:25:25 +00:00
JordanandPolymeta 9078ee2191 Fix X-axis being a different direction than Blockbench and addded new property attachment_options 2025-07-13 23:25:24 +00:00
Polymeta 06edc2810e Merge branch 'cooking-fixes-gert' into 'main'
Plefora of Cooking related fixes/implementations

See merge request cable-mc/cobblemon!1739
2025-07-13 22:56:49 +00:00
GertimoshkaandPolymeta 81b83aabc1 Plefora of Cooking related fixes/implementations 2025-07-13 22:56:49 +00:00
Polymeta 6e7895c3b3 Merge branch 'PhantomsFearTheFurySwipes' into 'main'
Implement avoidedByPhantom behavior

See merge request cable-mc/cobblemon!1737
2025-07-12 20:26:33 +00:00
JazzMcNade c69de804b9 Merge branch 'main' into PhantomsFearTheFurySwipes 2025-07-12 11:15:39 -05:00
JazzMcNade fbbed7b20a More license 2025-07-12 11:15:27 -05:00
Polymeta a1b5f0a567 Merge branch 'i-cant-take-it-anymore' into 'main'
Block Texture Clean Up

See merge request cable-mc/cobblemon!1738
2025-07-12 12:07:01 +00:00
Polymeta e42e06781d Merge branch 'flora-heals-an-aching-soul' into 'main'
Design Meeting Changes - Recipe/Loot Table Tweaks

See merge request cable-mc/cobblemon!1740
2025-07-12 12:03:35 +00:00
Konoha 6a7b71d5a7 Cleanup 2025-07-11 22:30:30 -04:00
dhi_holo 0a48014931 Design Meeting Changes
- Healing Machine recipe rebalanced
- Vivichoke Crops now drop one seed at full grown stage as well as the crop
- Vivichoke now can only be crafted into one seed, rather than two, to compensate for the above
2025-07-12 11:23:21 +10:00
Polymeta a70fed25c5 Merge branch 'feature/type-madness' into 'main'
make elementaltypes showdown identifiable for consistency

See merge request cable-mc/cobblemon!1688
2025-07-11 21:01:59 +00:00
Polymeta c2daed803f make elementaltypes showdown identifiable for consistency 2025-07-11 21:01:58 +00:00
Konoha a56ffe1742 Merge remote-tracking branch 'origin/main' 2025-07-11 11:04:14 -04:00
dhi_holo 658fed638d Update saccharine_log_slathered.json
Should remove errors from that blockstate too
2025-07-11 19:39:10 +10:00
dhi_holo 3faa2a0467 Saccharine and Candles
Fixed all Saccharine wood recipes missing advancements, and the log spamming Candle Poké Cake Blockstate being missin
2025-07-11 19:05:32 +10:00
dhi_holo 77788a91b7 Merge branch 'main' into i-cant-take-it-anymore 2025-07-11 19:01:21 +10:00
Hiroku 6d1570302d Merge branch 'unbreak-servers' into 'main'
Random bullshit go!

See merge request cable-mc/cobblemon!1736
2025-07-09 11:35:21 +00:00
Nadja Reitzenstein 811e9d3352 Don't return items after battles that weren't actually used. 2025-07-09 12:48:41 +02:00
dhi_holo 745b48e77b Update CHANGELOG.md
Changelog.
2025-07-09 15:06:40 +10:00
dhi_holo 9a4815f453 Block Texture Clean Up
Re-organised all the Block textures to match how the Item textures are sorted

Also did a very minor clean up of the item texture folder to just keep it clean.
2025-07-09 15:06:09 +10:00
JazzMcNade 2ff41cdf9b Updated Cresselia to scare off phantoms 2025-07-08 23:35:08 -05:00
JazzMcNade d5268e8751 Added TODO for should mount cries 2025-07-08 21:40:46 -05:00
JazzMcNade 518799ee25 Updated Changelog 2025-07-08 21:38:07 -05:00
JazzMcNade b597bb0818 Clean up multiple entity searches. 2025-07-08 21:31:42 -05:00
JazzMcNade 1b39a64927 Added check for shoulder mounted phantom feared pokemon 2025-07-08 21:01:45 -05:00
Nadja Reitzenstein e610aa18d7 Clean up imports and other assorted compiler warnings 2025-07-09 00:56:02 +02:00
Nadja Reitzenstein 42ecd3e813 Replace if-creative-then-stack.shrink with the proper stack.consume method.
This is both nicer to read and also reduces our code by a few lines. Additionally, this replaces all player.isCreative checks with the more appropriate player.hasInfiniteMaterials one.
2025-07-09 00:44:33 +02:00
Nadja Reitzenstein 1299b8fee8 Fix an ExceptionInInitializer error on specifically dedicated servers. 2025-07-08 23:53:35 +02:00
Landon a12cf17cfa Merge branch 'hotfix-infinite-falldamage' into 'main'
Correctly reset a ridden Pokémon's fall damage server-side

See merge request cable-mc/cobblemon!1735
2025-07-08 21:52:22 +00:00
Nadja Reitzenstein 74faca60f2 Correctly reset a ridden Pokémon's fall damage server-side 2025-07-08 23:12:15 +02:00
Landon 6420176787 Merge branch 'change-a-few-numbers-nothing-to-see-here' into 'main'
Change a few numbers here and there, nothing to see here :)

See merge request cable-mc/cobblemon!1734
2025-07-08 20:37:39 +00:00
Nadja Reitzenstein 6ee81fe2ab Fix a fun build error 2025-07-08 22:24:37 +02:00
Nadja Reitzenstein 96f4f988f8 Update dependencies chore 2025-07-08 21:31:56 +02:00
Hiroku 4ccfbbcb37 Merge branch '1622-fix-battle-screen-closing' into 'main'
Fix battle GUI not closing

Closes #1622

See merge request cable-mc/cobblemon!1723
2025-07-08 14:02:38 +00:00
Hiroku ed0aa83013 Merge branch 'light' into 'main'
Update block lighting + lambdynamiclights compat items

See merge request cable-mc/cobblemon!1731
2025-07-08 12:42:22 +00:00
Hiroku b94394f8d1 Merge branch 'forever-rock' into 'main'
suppress evolution notification and hide evolve button if holding everstone

See merge request cable-mc/cobblemon!1732
2025-07-08 12:39:45 +00:00
Hiroku b16687c132 Merge branch 'evolution-concurrent-hotpatch' into 'main'
Make Evolution more resilient against concurrent modification exceptions.

Closes #1536

See merge request cable-mc/cobblemon!1725
2025-07-08 10:31:50 +00:00
Hiroku 56767b3e31 Merge branch 'jet-momentum-damage' into 'main'
Jet behaviour momentum damage logic

Closes #1555

See merge request cable-mc/cobblemon!1715
2025-07-08 10:31:05 +00:00
AramandHiroku 67eb3e1046 Jet behaviour momentum damage logic 2025-07-08 10:31:04 +00:00
JazzMcNade dda128e9e3 implemented mixin for avoidedByPhantom behavior flag 2025-07-08 02:42:24 -05:00
Test 952ea8d3b7 suppress evolution notification and hides evolve button in summary interface if Pokémon is holding Everstone 2025-07-07 22:27:37 -04:00
Test cc764ff9db add farmland to water plantable for hearty 2025-07-07 18:51:22 -04:00
Nadja Reitzenstein 2e1f8af700 Make Evolution more resilient against concurrent modification exceptions.
BenchedMoves is quite vulnerable to concurrent modifications as it does no internal locking. The code changed in this commit showcases that issue extremely well: As `pokemon.benchedMoves` was updated one-by-one and each update send a separate BenchedMovesUpdatePacket which would all be handled in parallel by the Client evolving a Pokémon which lears a bunch of moves on evolution was an almost sure-fire way to crash the game.

This *isn't a fix* for that! It's merely a hotpatch to make sure this common a crash doesn't sneak itself into the next release.

Fixes: #1536
2025-07-07 18:16:24 +02:00
Test 6c6a8e4679 indents 2025-07-06 16:12:28 -04:00
Test 9e9a22eb14 Update block lighting, add lambdynamiclights support for items 2025-07-06 16:08:14 -04:00
Test 32bfaf152d +vibrance galarica, fix hearty stage + allow planting on dry farmland 2025-07-06 04:59:25 -04:00
Hiroku d1b947b264 Merge branch 'blox' into 'main'
update sacch/crops/blocks, consolidate POI registration

See merge request cable-mc/cobblemon!1729
2025-07-06 05:29:46 +00:00
Test 6122fb6107 disallow honey on leaves if waterlogged 2025-07-06 00:49:29 -04:00
Paul 14c7ee3216 Added PokedexManager.obtain as a replacement for catch (java interop) 2025-07-06 14:04:59 +10:00
Hiroku 1a00ae7fb8 Merge branch 'particle-fix' into 'main'
Fixed rotation of locators relative to entities.

Closes #1573

See merge request cable-mc/cobblemon!1726
2025-07-06 01:45:57 +00:00
JPAKx4 36b3cbe3b8 Fix Formatting. 2025-07-05 20:03:18 -05:00
JPAKx4 49686a1670 Merge remote-tracking branch 'origin/particle-fix' into particle-fix 2025-07-05 20:00:53 -05:00
JPAKx4andJordan 2354888a73 Cleanup some now unused code and comment out some debug code. 2025-07-06 00:09:33 +00:00
JPAKx4andJordan f64065d54f this suckssssss 2025-07-06 00:09:33 +00:00
JPAKandJordan 005ab0ca74 Locator Debug Code 2025-07-06 00:09:33 +00:00
JPAKandJordan c13307e931 temp commit 2025-07-06 00:09:33 +00:00
JPAKx4andJordan bd21a6e1ca Fixed the root locator losing rotation and removed unnecessary scaling. 2025-07-06 00:09:33 +00:00
JPAKx4 94ea15b9c5 Cleanup some now unused code and comment out some debug code. 2025-07-05 19:08:41 -05:00
Test bc6c9def56 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into blox 2025-07-05 17:50:12 -04:00
Test 9ca6a2e461 fix block drop, prevent smearing honey in water, +log cosmetics 2025-07-05 15:26:09 -04:00
Paul 599603501a Combee should fly instead of walk, and not fly crazy fast 2025-07-05 22:42:30 +10:00
Paul 891ed6045d This is good news 2025-07-05 22:30:07 +10:00
Test f7560a12ad update sacch/crops/blocks, consolidate POI registration 2025-07-05 04:12:58 -04:00
Test 8bc1767917 Merge branch 'we-must-defend-our-way-of-life' into 'main'
Pokemon can be made to hunt from the pasture block

See merge request cable-mc/cobblemon!1728
2025-07-05 06:45:27 +00:00
Test 8b29d3a533 Merge branch '1603-out-of-sync-guis' into 'main'
Resolve "Staying on party screen while a Pokémon evolves causes temporary weirdness."

Closes #1603

See merge request cable-mc/cobblemon!1717
2025-07-05 06:44:33 +00:00
JPAKx4 de1248b97e this suckssssss 2025-07-04 21:36:44 -05:00
Paul a654225ed5 Improve handling of pasture conflict behaviour flag 2025-07-05 11:31:29 +10:00
JPAK 2d18113e27 Locator Debug Code 2025-07-04 20:21:57 -05:00
JPAK cdadc6fa67 temp commit 2025-07-04 20:21:40 -05:00
Paul a15aa86c66 Merge remote-tracking branch 'origin/we-must-defend-our-way-of-life' into let-me-break-it-down-for-you-mark-we-can-bee-bees
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/ai/config/task/TaskConfig.kt
2025-07-05 10:14:41 +10:00
JPAKx4 ff7ef1b67e Merge remote-tracking branch 'origin/particle-fix' into particle-fix 2025-07-04 16:45:34 -05:00
JPAKx4 d91c819700 Fixed the root locator losing rotation and removed unnecessary scaling. 2025-07-04 16:45:19 -05:00
Josh 259e1d05cb Changing nickname no longer causes ModelWidget state to updated 2025-07-04 04:35:05 -04:00
Paul 549b88a4c2 Removed unnecessary thing 2025-07-04 14:43:24 +10:00
Hiroku 68b60e7d50 Merge branch 'wheel' into 'main'
Tetragon ➜ Octagon

See merge request cable-mc/cobblemon!1727
2025-07-04 03:33:42 +00:00
Test a7787707f2 changelog 2025-07-03 22:52:50 -04:00
Test 539097e681 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into wheel
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/gui/interact/wheel/InteractWheelGUI.kt
2025-07-03 22:39:06 -04:00
Test 8b70a4124d Interact Tetragon ➜ Interact Octagon 2025-07-03 22:38:49 -04:00
Test 7e8b000311 Merge branch 'bugfix/fix-interact-wheel-issues' into 'main'
Fix minor bugs related to the Pokemon interaction wheel

See merge request cable-mc/cobblemon!1722
2025-07-04 02:30:58 +00:00
StarliteHeartandTest 00c86b89cb Fix minor bugs related to the Pokemon interaction wheel 2025-07-04 02:30:57 +00:00
JPAKx4 b2c9d96829 Fixed the root locator losing rotation. 2025-07-03 20:35:49 -05:00
Hiroku 8ea5ea6804 changelog [skip-ci] 2025-07-03 11:15:23 +00:00
Hiroku 1305e8a11d Merge branch 'level-rng-fixes' into 'main'
Rewrite potentially sketchy uses of randomness.

Closes #1560

See merge request cable-mc/cobblemon!1724
2025-07-03 11:14:09 +00:00
Nadja Reitzenstein 909cd8a6eb Adds the Concurrent Chunk Management Engine (C2ME) to runtime dependencies.
While no code relies on any internals or even features of C2ME that mod increases performance massively, especially on servers. This means it's reasonably often used and compatability with it is a reasonable goal to have.

Additionally, it helps to detect multithreading bugs by distributing workload over more threads than vanilla and thus making it much more likely to hit those bugs.
2025-07-03 12:53:29 +02:00
Nadja Reitzenstein d60abdc940 Rewrite potentially sketchy uses of randomness.
Using the random source stored in `Level` from a different thread can lead to hard-to-debug ConcurrentAccessExceptions. A common source for these problems is using level randomness in networking code such as synced data.

This commit rewrites three potentially sketchy usages of level randomness into a form that I think is safe from this particular problem.

Fixes: #1560
2025-07-03 12:53:29 +02:00
Paul ec8e6f58c8 Merge remote-tracking branch 'origin/we-must-defend-our-way-of-life' into we-must-defend-our-way-of-life 2025-07-03 18:35:15 +10:00
Paul 12967e4813 Bits of AI cleanup and fixed non-look pokemon still looking 2025-07-03 18:35:08 +10:00
Paul d754cc69fe Merge remote-tracking branch 'origin/main' into we-must-defend-our-way-of-life 2025-07-03 18:29:10 +10:00
Charzard4261 a2b54643fe Remove fake PartySendBinding press on BattleGUI close 2025-07-03 00:09:12 +01:00
Test 896c195dd9 reverse pc scroll direction 2025-07-02 18:59:47 -04:00
Landon 206bfacba0 Merge branch 'multi-seat-mounts' into 'main'
Multi seat mounts

See merge request cable-mc/cobblemon!1721
2025-07-02 18:07:40 +00:00
Landon Wills b6ffbd1ed8 Update licenses 2025-07-02 13:55:11 -04:00
Landon Wills 829900fb58 Prevent seat shifts when passengers dismount 2025-07-02 02:13:26 -04:00
Test be3066f7b2 rm commented 2025-07-02 00:07:57 -04:00
Test fb56ab5865 update pc, pasture slots 2025-07-01 23:40:54 -04:00
Test a3f02a8a7c Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into we-must-defend-our-way-of-life 2025-07-01 19:42:09 -04:00
Paul 6c2757b94b Fixed issues with sending out pokes 2025-07-01 21:33:05 +10:00
Test 139ef56fdf account for users putting in negative numbers for control overlay duration 2025-06-30 23:32:22 +00:00
Paul d3e473ff85 Merge remote-tracking branch 'origin/main' into we-must-defend-our-way-of-life 2025-06-30 20:05:40 +10:00
Paul fdebc5987e Merge remote-tracking branch 'origin/main' 2025-06-30 19:53:09 +10:00
Paul caeeb756fe Fixed crash with several pokemon due to particle locators not being there at the time effects played 2025-06-30 19:52:47 +10:00
Polymeta 67b5e5c6a8 fixes for scanner overlay and display case block
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-30 10:45:02 +01:00
Paul 720eef5e75 finalizeSpawn for PokemonEntity's 2025-06-30 16:33:04 +10:00
Landon ebc7f67655 Merge branch 'snapshot-warnings' into 'main'
Prepare for displaying a snapshot warning to users

See merge request cable-mc/cobblemon!1706
2025-06-30 06:10:47 +00:00
NickandLandon 3c508c5bd1 Prepare for displaying a snapshot warning to users 2025-06-30 06:10:46 +00:00
Landon c7052d295c Merge branch 'controls-overlay' into 'main'
Ride Controls Overlay

See merge request cable-mc/cobblemon!1720
2025-06-30 05:52:31 +00:00
Landon Wills 9193e9a372 Reduce default display second config value slightly 2025-06-30 01:07:44 -04:00
Test f6244cbe12 controls overlay 2025-06-30 00:11:35 -04:00
Paul 5743a04db7 Fixed sleeping pokemon outside of battle never waking up (DUN DUNNN) 2025-06-30 10:40:27 +10:00
Paul 439a5077c2 Merge remote-tracking branch 'origin/main' into we-must-defend-our-way-of-life
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/ai/config/task/TaskConfig.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/ai/CombatBehaviour.kt
#	common/src/main/resources/data/cobblemon/species/generation1/charizard.json
2025-06-30 10:16:59 +10:00
Polymeta a8a028bb7a Merge branch 'more-ai' into 'main'
Lots more brain work and some fixes

See merge request cable-mc/cobblemon!1719
2025-06-29 23:12:56 +00:00
Konoha 1984990a7e Array Utilities 2025-06-29 08:42:28 -04:00
Paul 984e10a780 Prototype for behaviour scraper 2025-06-29 18:51:38 +10:00
Paul ad0571a782 lil renames and stuff 2025-06-29 18:37:59 +10:00
Paul a18581ae1c Merge remote-tracking branch 'origin/lang-updates' 2025-06-29 10:29:50 +10:00
Konoha 49e2e635db Ability Pokemon Function 2025-06-28 19:09:37 -04:00
Zack the GhastandWeblate 177ad70172 Translated using Weblate (Portuguese (Portugal))
Currently translated at 63.0% (5365 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-06-28 18:20:05 +00:00
washashu0905andWeblate 98fb731270 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 94.7% (8062 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-28 18:20:04 +00:00
阿鱼andWeblate a98dbcf267 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 87.9% (7480 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-28 18:20:02 +00:00
Konoha 62e9294c8a Merge remote-tracking branch 'origin/main' 2025-06-28 11:41:40 -04:00
Paul 314bd19dc6 Fixed clicking on combat icon in pasture block 'selecting' the entry, also licenses 2025-06-28 10:23:55 +10:00
Paul c0344f5604 Fixed entity lookup for pasture S2C packet 2025-06-28 10:09:35 +10:00
Konoha d795dca4fa Inventory player function 2025-06-27 16:02:18 -04:00
Konoha 503511e0ae teach_move, can_learn_move, set_iv, set_ev` Pokemon functions 2025-06-27 14:39:04 -04:00
Paul 2f8a9f207c Removed unnecessary fields from cosmetic item definitions 2025-06-27 22:22:54 +10:00
Paul 8c1416514c Merge remote-tracking branch 'weblate/lang-updates' 2025-06-27 22:08:55 +10:00
washashu0905andWeblate 575c33612d Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 94.1% (8009 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-27 12:08:24 +00:00
Paul 889d193ad1 Shouldn't have vi.json, only vi_vn.json 2025-06-27 22:07:19 +10:00
Paul 57ef37099e Merge remote-tracking branch 'weblate/lang-updates' 2025-06-27 22:05:04 +10:00
Paul d7d311764d Fixed a few brain memory crashes, made herds more complicated with tiers of leaders 2025-06-27 22:04:06 +10:00
Zack the GhastandWeblate d7fb65d23b Translated using Weblate (Portuguese (Portugal))
Currently translated at 62.1% (5285 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-06-27 12:01:01 +00:00
washashu0905andWeblate 3e4449aed1 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 94.0% (7999 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-27 12:01:00 +00:00
plastered_crab 55aa50654c Safer getPokemon on pasture block 2025-06-27 03:03:54 -07:00
plastered_crab 489170cf00 DTO FAFO 2025-06-27 02:32:17 -07:00
Polymeta 930eb42e76 Merge branch '1594-sounds-while-capturing' into 'main'
Resolve "[1.7] Wing flap sounds continue to play while target is struggling inside of a pokeball."

Closes #1594

See merge request cable-mc/cobblemon!1718
2025-06-27 09:19:49 +00:00
plastered_crab 87d76e8788 Trying to get the Pokemon DTO to load on the pasture UI properly to reflect behavior flags on the entity 2025-06-27 01:55:00 -07:00
Landon Wills 6d8bf59eee Add dedicated dismount packet, clear up dismount logic, recall all pokemon on mount 2025-06-27 03:58:50 -04:00
Paul a8f431868a Merge remote-tracking branch 'origin/main' into more-ai 2025-06-27 17:26:39 +10:00
Landon Wills 0c6e355c6b Merge branch 'main' into multi-seat-mounts 2025-06-27 00:38:00 -04:00
Josh a2f6ab0ea4 Silence pokemon while in ball 2025-06-26 09:36:22 -04:00
Paul 719a56e7c3 Remove all that is unnecessary and you will come to know true peace 2025-06-26 20:52:29 +10:00
Konoha bd4397ec55 Merge remote-tracking branch 'origin/main' 2025-06-25 21:11:08 -04:00
Konoha d5e3781fc5 Merge remote-tracking branch 'origin/legacy_and_event_moves' 2025-06-25 21:10:53 -04:00
Josh 776ab05ac1 nickname widget now updates properly 2025-06-25 21:06:45 -04:00
Konoha a7f8a281a8 Minor comment fix 2025-06-25 19:53:54 -04:00
Konoha 5ba6679a84 Changelog 2025-06-25 19:49:17 -04:00
Konoha 4ecd64bdf6 Set Level and clone party for NPC / MoLang battles 2025-06-25 19:46:51 -04:00
Josh 0da5d27851 Added observer to Summary UI with clean up 2025-06-25 18:22:51 -04:00
Josh 48b28bc509 Removed observer from RenderablePokemon 2025-06-25 18:22:10 -04:00
Josh 5547326798 Updated RenderablePokemon to have an option to sync to a Pokemon so the render updates automatically 2025-06-25 14:06:39 -04:00
Josh bcf730a07f updated PokemonProperties to use swapHeldItem() rather then setting directly in order to sync client and server mons 2025-06-25 14:04:44 -04:00
washashu0905andWeblate 8be1e78fee Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 93.1% (7924 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-25 17:32:15 +00:00
Zack the GhastandWeblate c463c99b0f Translated using Weblate (Portuguese (Portugal))
Currently translated at 60.8% (5178 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-06-25 17:32:13 +00:00
Polymeta 255829a9f8 Merge branch '1604-1-7-flying-crashes-the-game-if-pokeedit-is-used-on-the-specified-pokemon-beforehand-2' into 'main'
Resolve "[1.7] Flying crashes the game if /pokeedit is used on the specified Pokémon beforehand."

Closes #1575

See merge request cable-mc/cobblemon!1716
2025-06-25 14:43:18 +00:00
Josh 46758b7ab0 added ejectPassengers() to PokemonEntity#refreshRiding() 2025-06-25 09:57:14 -04:00
Polymeta aebcf42df8 Merge branch 'car-please-stop' into 'main'
Car please stop (Bug Fixes)

Closes #1584 and #1586

See merge request cable-mc/cobblemon!1698
2025-06-25 13:32:05 +00:00
AramandPolymeta 2268640dbc Car please stop (Bug Fixes) 2025-06-25 13:32:05 +00:00
Polymeta bf3739c598 Merge branch '1602-1-7-visible-held-items-appearing-on-unsupported-pokemon-through-pokeedit-command' into 'main'
Resolve "[1.7] Visible held items appearing on unsupported Pokémon through /pokeedit command."

Closes #1602

See merge request cable-mc/cobblemon!1714
2025-06-25 13:04:18 +00:00
Paul 9c4ae189a1 Optimize scriptable AI entities by only registering memories and sensors that are used by the task list 2025-06-25 22:29:16 +10:00
Zack the GhastandWeblate 502a314a6c Translated using Weblate (Portuguese (Portugal))
Currently translated at 60.6% (5159 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-06-25 03:50:36 +00:00
washashu0905andWeblate ca1ea6385d Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 89.3% (7598 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-25 03:50:36 +00:00
Konoha 6863cd0602 Battle Format Parameters 2025-06-24 22:03:49 -04:00
plastered_crab 9749acbb0c Fixes for behavior assignment of attacking hostile mobs 2025-06-24 08:29:17 -07:00
Josh 81d4e4ded1 refreshing riding settings in the ServerDelegate when the species is updated 2025-06-24 11:18:08 -04:00
Josh 3e5ab4328b locatorStates are now cleared when the species updates to remove non-existent locators 2025-06-24 10:50:55 -04:00
plastered_crab d1993574f6 some cleanup 2025-06-24 07:33:12 -07:00
plastered_crab 2b531ec32f Mons set to defend a Pasture are visually shown in the UI now 2025-06-24 06:28:34 -07:00
Paul a9985bbea8 Some pokemon have generational beef 2025-06-24 20:23:45 +10:00
plastered_crab 8d00da2c57 comma was missing for some reason 2025-06-24 00:45:50 -07:00
Zack the GhastandWeblate f4d866537a Translated using Weblate (Portuguese (Portugal))
Currently translated at 59.9% (5096 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-06-24 02:15:25 +00:00
Zack the GhastandWeblate e9f942687f Translated using Weblate (Portuguese (Portugal))
Currently translated at 59.8% (5092 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-06-23 23:36:40 +00:00
Josh d67d73351d updated LocatorAccess#update to remove locators that no longer exists 2025-06-23 16:03:26 -04:00
Josh 74d3ce793d removed the model argument for HeldItemRenderer since it is not really necessary 2025-06-23 16:00:19 -04:00
Polymeta 3223c8dfeb Merge branch 'Air-Ballon-Battle-Text-Fix' into 'main'
Fixed air balloon battle text not displaying the Pokemon or item name

See merge request cable-mc/cobblemon!1713
2025-06-23 13:03:56 +00:00
washashu0905andWeblate a84a897e84 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 88.2% (7505 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-23 12:08:59 +00:00
Landon Wills 92bf3ba2a2 Prevent players from mounting other players pokemon when owner is not mounted 2025-06-23 01:36:34 -04:00
Landon Wills 84f79c89c5 Dismount all passengers if driver dismounts 2025-06-22 23:16:35 -04:00
Landon Wills 248967256b Use bottom of pokemon hitbox for dismount position 2025-06-22 23:12:46 -04:00
Landon Wills ea19721998 Merge branch 'main' into multi-seat-mounts
# Conflicts:
#	common/src/main/resources/assets/cobblemon/bedrock/pokemon/models/0750_mudsdale/mudsdale.geo.json
2025-06-22 23:05:18 -04:00
Landon Wills e9408db7a1 Fix seat locator name always defaulting to seat_1 2025-06-22 23:03:54 -04:00
Konoha b9e6d63049 Extra Battle Format MoLang parameters 2025-06-22 21:52:34 -04:00
JazzMcNade 15ab84297d Update Changelog 2025-06-22 15:51:44 -05:00
JazzMcNade 94cfb23e66 Fixed air balloon battle text not displaying the pokemon or item name 2025-06-22 15:42:39 -05:00
Konoha cb002ff530 Battle Format and Rule Selection via MoLang Test 2025-06-22 13:34:50 -04:00
Konoha 19da349e78 Merge AI Shenanigans 2025-06-22 11:25:28 -04:00
Konoha 30c3b605a3 Merge branch 'refs/heads/feature/ai-shenanigans' into extra_flows
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/npc/NPCServerDelegate.kt
2025-06-22 11:23:06 -04:00
Paul 2fbffa5b66 Birds will fly if it gets them out of water faster 2025-06-22 21:23:44 +10:00
washashu0905andWeblate 108b769928 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 84.0% (7145 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-22 06:31:58 +00:00
washashu0905andWeblate 3db39547f0 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 82.9% (7057 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-22 02:53:26 +00:00
Konoha b8e79d2d3e Attempt to not publish HELD_ITEM_PRE on the client (spoilers, it doesn't work :[ ) 2025-06-21 22:27:02 -04:00
washashu0905andWeblate c4688c5db9 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 81.9% (6969 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-22 02:11:11 +00:00
Paul b0385fc37f Added behaviour for NPC scale configuration 2025-06-22 11:59:36 +10:00
Konoha 60c2721b53 Cleanup LootDroppedEvent Flow 2025-06-21 20:50:46 -04:00
Konoha b6f2ab25e1 Fix berry in BerryHarvestEvent 2025-06-21 20:49:07 -04:00
Konoha 6417f8cfa8 Cleanup 2025-06-21 20:45:18 -04:00
Konoha 1d473437de MoLang moveset queries
Viewable Hyper Trained IVs in PC
2025-06-21 20:19:41 -04:00
Konoha c24b60785f Player battle function and battle format setting parameters. 2025-06-21 14:17:31 -04:00
Konoha 08df2fef6c Molang setter functions for Party & PC 2025-06-21 12:13:07 -04:00
washashu0905andWeblate e491e7de81 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 81.3% (6922 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-06-21 15:11:30 +00:00
Tobias (Targ)andWeblate f7974767d1 Translated using Weblate (German)
Currently translated at 61.4% (5225 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2025-06-21 15:11:29 +00:00
Hiroku d41e89ddbd Merge branch 'we-arent-pushovers-anymore' into 'main'
Species JSON dictates if a species fights back or runs away from player that hurts it

See merge request cable-mc/cobblemon!1708
2025-06-21 03:44:48 +00:00
Hiroku 37293d396a Pastured pokemon react to damage too 2025-06-21 03:04:43 +00:00
Hiroku d598335112 Merge branch 'implement_pokemon' into 'main'
Implementation merge request, your majesty.

See merge request cable-mc/cobblemon!1711
2025-06-21 00:54:10 +00:00
Hiroku b3b63941e7 Add Mienfoo and Mienshao to changelog 2025-06-21 00:13:20 +00:00
Sterrezo 596122ecf0 Merge branch 'main' into implement_pokemon 2025-06-20 21:44:30 +02:00
Sterrezo e934ebf781 Merge branch 'main' into implement_pokemon 2025-06-20 21:43:03 +02:00
Polymeta 3b7bd22567 put gitCommit in maven pom file... this will be useful for later
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-20 14:26:13 +01:00
plastered_crab bae3da9411 Merge branch 'refs/heads/main' into let-me-break-it-down-for-you-mark-we-can-bee-bees
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonMemories.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/ai/config/task/TaskConfig.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/ai/PokemonBrain.kt
2025-06-20 06:07:01 -07:00
plastered_crab a30ca92f0a Merge branch 'refs/heads/main' into we-must-defend-our-way-of-life
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/ai/config/task/TaskConfig.kt
2025-06-20 06:05:25 -07:00
plastered_crab dd5ec25345 Merge branch 'refs/heads/main' into we-arent-pushovers-anymore
# Conflicts:
#	common/src/main/resources/data/cobblemon/behaviours/pokemon/auto/pokemon_non_party.json
2025-06-20 06:03:58 -07:00
Polymeta 40309e9913 Merge branch 'more-ai' into 'main'
More AI tasks, AI fixes

See merge request cable-mc/cobblemon!1704
2025-06-20 12:52:48 +00:00
Paul 5346f0f864 ok i admit i have ocd 2025-06-20 21:46:25 +10:00
Paul c4e0d19613 Merge remote-tracking branch 'origin/main' into more-ai
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/ai/OmniPathNodeMaker.kt
2025-06-20 21:36:43 +10:00
Paul de9fe73a31 Added more variables to move_into_fluid, added moves_to_lava preset, some lang 2025-06-20 21:30:02 +10:00
Paul 47fd191fea Fixed lava pathing not working properly 2025-06-20 20:32:20 +10:00
plastered_crab e3f3f4e1b7 fix rretaliation against attacking players 2025-06-19 21:45:34 -07:00
plastered_crab 004890d050 fix application of behavior 2025-06-19 21:39:27 -07:00
plastered_crab e690a0ed92 fix species json 2025-06-19 21:19:37 -07:00
plastered_crab 1e240d879f fix logic and species json 2025-06-19 21:04:26 -07:00
Konoha db7745589a Cleanup 2025-06-19 21:27:55 -04:00
Konoha 65f0f69726 Teach All Learnable Moves MoLang Function 2025-06-19 21:25:26 -04:00
Konoha 19263ddec6 Minor fix 2025-06-19 17:29:40 -04:00
Konoha dde4680ce0 Refactor Client Context on HeldItemEvent 2025-06-19 16:13:36 -04:00
Konoha a2939e34a0 Cosmetic Item Property, MoLang functions for fullness, unlearning moves. 2025-06-19 14:25:20 -04:00
plastered_crab 6a937492dd Licenses 2025-06-19 07:37:53 -07:00
plastered_crab 5f52625b05 PasturePos is saved on tethering object. and make sure pasture mons don't defend areas too far away 2025-06-19 07:13:51 -07:00
Paul a64f201fd2 Fixed is_wild not working properly for brain stuff 2025-06-19 21:17:03 +10:00
plastered_crab 10746bea10 These darn u letters man 2025-06-19 03:29:39 -07:00
plastered_crab af1f607994 is_wild is now a pokemon entity Molang variable 2025-06-19 03:26:07 -07:00
plastered_crab db9cefc8ba is_wild is now a pokemon entity Molang variable 2025-06-19 03:14:17 -07:00
Polymeta 952eee67a6 Merge branch 'PathingForDummies' into 'main'
Pathing improvements

Closes #1480

See merge request cable-mc/cobblemon!1705
2025-06-19 09:35:30 +00:00
JazzMcNadeandPolymeta 87d7049a64 Pathing improvements 2025-06-19 09:35:29 +00:00
plastered_crab c467f9cad2 They call it AU because they add a u to everything 2025-06-19 01:53:34 -07:00
plastered_crab 5f7fa85b58 fix bool 2025-06-18 23:57:50 -07:00
plastered_crab eb3ffdfbd4 fix typos lol 2025-06-18 23:45:44 -07:00
阿鱼andWeblate c7e512bc32 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 87.9% (7479 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-18 10:11:29 +00:00
Watuneni iteiteandWeblate 6889cb7936 Translated using Weblate (Japanese)
Currently translated at 59.7% (5078 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-06-18 10:11:26 +00:00
plastered_crab b4af502997 testing with Charizard 2025-06-17 19:39:46 -07:00
plastered_crab 9bffdf8df4 testing with Charizard and Wimpod 2025-06-17 19:38:08 -07:00
plastered_crab 8dbdd78c86 testing with Charizard 2025-06-17 19:33:26 -07:00
Konoha d13e456d17 Minor Optimization ft. landon 2025-06-17 22:08:29 -04:00
Konoha e36de84927 1.7: The Flowing Mapmaker's Update (Friendship, Fullness, AspectChanged, CatchRate, PokeRod, ShoulderMount event flows) 2025-06-17 22:05:44 -04:00
plastered_crab e6812891b5 species json to allow for deciding if mons will defend their owner if in their party 2025-06-17 18:43:34 -07:00
plastered_crab 6a3c98ed1c species json to allow for deciding if mons will defend their owner if in their party 2025-06-17 18:42:34 -07:00
plastered_crab 991ec7cc1a species json to allow for deciding if mons flee or fight back when attacked 2025-06-17 18:06:36 -07:00
Konoha 54cbaa9a10 Flows for PokemonHealed, PokemonSent, and ChangePCBoxWallpaper. 2025-06-17 12:43:24 -04:00
Paul 1eaca5110b Polymeta has OCD :sadge: 2025-06-17 23:01:06 +10:00
Paul d7f2b1dce1 Fixed dangling herd leaders after they're dead 2025-06-17 22:59:46 +10:00
Paul 4952b3bda7 Remove println 2025-06-17 22:54:59 +10:00
Konoha dbe743b50a Do not publish HelpItemEvent if it's running on client. 2025-06-17 08:47:38 -04:00
Paul 82acd07ea5 Keep count of herd size 2025-06-17 21:45:20 +10:00
Konoha 7d26870a13 Pokemon Scanned, Loot Dropped, Berry Harvest Flows 2025-06-16 14:50:53 -04:00
Konoha a418cbd118 Pokemon Seen Flow 2025-06-16 12:03:00 -04:00
Konoha e45af26af3 Split Cosmetic Item Event from HeldItemEvent. 2025-06-16 10:08:52 -04:00
Paul bcb1d412b1 Leader maintenance for pokemon in herds 2025-06-16 20:28:56 +10:00
RedGenesectNinja c4a21c19ea Implemented Mienfoo and Mienshao 2025-06-16 01:19:35 -05:00
RedGenesectNinja 5d86d03a13 Adjusted Drampa's size 2025-06-16 01:04:26 -05:00
Paul 867eb5f0d9 Rudimentary herding for karps 2025-06-16 14:29:42 +10:00
plastered_crab e59f4e7891 Guards find new targets once their first one dies 2025-06-15 21:03:57 -07:00
Konoha bdc260abca Aspects MoLang function for Pokemon 2025-06-15 21:54:39 -04:00
Konoha d9e5e52d9f Flows for ExperienceGainedEvent, CollectEggEvent, HatchEggEvent. MoLang functions to add exp, initialize a Pokemon's moveset, and validate an existing moveset. 2025-06-15 21:31:10 -04:00
plastered_crab a481bde4f5 The guards are on active duty 2025-06-15 09:59:57 -07:00
阿鱼andWeblate 787faf38e7 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 82.9% (7051 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-15 14:09:31 +00:00
Watuneni iteiteandWeblate 9a42c82a37 Translated using Weblate (Japanese)
Currently translated at 57.6% (4907 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-06-15 14:09:29 +00:00
plastered_crab 654d0f8975 You've never seen guard dogs like these before 2025-06-15 06:43:15 -07:00
plastered_crab 66b3c4a4c6 Scott has pooped so I must go 2025-06-15 04:57:53 -07:00
Paul 77333d9a13 Burnout 3 is one of the most impressive racing games of its era and holds up very well for a PS2 game 2025-06-15 16:09:47 +10:00
Paul 045613ef79 Fixed PokemonEntity#struct pokemonFunctions coming from a random pokemon on reload, causing the wrong AI to apply 2025-06-15 16:05:51 +10:00
Paul d78963daf3 Fish return to water when they get the chance 2025-06-15 15:29:39 +10:00
plastered_crab 2fc2f24dee yay it compiles. time for sleep finally. testing later 2025-06-14 16:57:50 -07:00
plastered_crab 0988411e13 Nothing to see here just some AI upgrade stuff 2025-06-14 14:52:56 -07:00
plastered_crab b39fadcde8 Nothing to see here just some AI upgrade stuff 2025-06-14 07:04:17 -07:00
Hiroku 61cfdd485e Merge branch 'extra_flows' into 'main'
Additional Flows

See merge request cable-mc/cobblemon!1685
2025-06-14 04:47:55 +00:00
Konoha 6f263845a0 Gee I sure hope these MoLang functions help somebody! 2025-06-14 00:36:06 -04:00
Paul 51720489ae Improved hovering, fixed magikarp, tatsu, and wailord not being able to sink from the surface 2025-06-14 13:59:42 +10:00
Polymeta c12f991b18 testing round no1
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-13 01:20:15 +01:00
Polymeta 977d66dafd fixing some errors
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-13 01:05:55 +01:00
Polymeta f0b1843b71 StrongBattleAI without build errors
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-13 01:05:54 +01:00
Polymeta 785e63c7d4 rafactoring of the ActiveTracker to be on a "seen" basis with opposing pokemon
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-13 01:05:54 +01:00
Polymeta 61c3c995aa tidying up
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-13 01:05:43 +01:00
阿鱼andWeblate 8221386767 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 79.0% (6722 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-11 18:24:33 +00:00
Polymeta 8d2cf1ad81 Merge branch 'harvester' into 'main'
Small Fixes

See merge request cable-mc/cobblemon!1703
2025-06-11 12:21:31 +00:00
dhi_holoandPolymeta e230d6fda5 Small Fixes 2025-06-11 12:21:31 +00:00
plastered_crab 5dc56bd4fc Merge branch 'refs/heads/main' into let-me-break-it-down-for-you-mark-we-can-bee-bees
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/ai/config/task/TaskConfig.kt
2025-06-10 18:11:57 -07:00
Nick 274f7e6c81 Merge branch 'monster-milker-2000' into 'main'
Datapackable Pokemon Item Interactions

See merge request cable-mc/cobblemon!1683
2025-06-10 14:22:44 -07:00
Plastered_CrabandNick 664f8e4484 Datapackable Pokemon Item Interactions 2025-06-10 14:22:43 -07:00
Paul d4700bcbd3 Circle banking fishies and birds, regular wander avoids targeting air as a final position 2025-06-10 20:59:50 +10:00
plastered_crab f9afd1d3e6 My kid pooped his pants and fell back asleep so let's code real fast 2025-06-10 02:46:26 -07:00
Polymeta 9d7198e4cd prevent pokemon crashing when 3rd party mods try to tame them
Closes #1513

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-09 21:27:48 +01:00
Nico MerenqandWeblate 311a3e1005 Translated using Weblate (Russian)
Currently translated at 51.9% (4417 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-06-09 15:14:52 +00:00
阿鱼andWeblate aeb6bddba6 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 64.9% (5521 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-09 15:14:52 +00:00
阿鱼andWeblate e11d1cb77c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 63.9% (5436 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-09 14:54:27 +00:00
阿鱼andWeblate 774e62bb4b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 55.1% (4691 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-09 14:46:08 +00:00
阿鱼andWeblate 716ab4fb95 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 50.5% (4296 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-09 14:39:15 +00:00
阿鱼andWeblate 766625bf31 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 81.2% (6912 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-09 14:23:36 +00:00
Nico MerenqandWeblate 14cde609c6 Translated using Weblate (Russian)
Currently translated at 51.9% (4416 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-06-09 14:23:35 +00:00
Polymeta 199128bb0d allow berries to be planted on FD rich soil
Closes #785

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-09 00:04:58 +01:00
Polymeta 4d2b7f319c Merge branch 'bugfix-dex-removal-error' into 'main'
Bugfix dex removal error

Closes #1564

See merge request cable-mc/cobblemon!1694
2025-06-08 22:18:51 +00:00
Leandro M.andPolymeta 698cc5218d Bugfix dex removal error 2025-06-08 22:18:50 +00:00
Nico MerenqandWeblate da6ac4b8d6 Translated using Weblate (Russian)
Currently translated at 51.9% (4416 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-06-08 20:39:07 +00:00
Polymeta 804dfe9131 Merge branch 'nutty' into 'main'
Nutty!

See merge request cable-mc/cobblemon!1701
2025-06-08 00:20:16 +00:00
dhi_holoandPolymeta afd007856e Nutty! 2025-06-08 00:20:16 +00:00
Nico MerenqandWeblate 43ef224444 Translated using Weblate (Russian)
Currently translated at 51.8% (4410 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-06-07 13:22:58 +00:00
Polymeta c99bf99052 correct pokemon model item offset and GUI lighting
Closes #1597

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-07 00:40:52 +01:00
Polymeta e8019a0623 make model loading not crash the game if a non-cobblemon model gets caught up in the parsing
Closes #1593

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-06 17:05:29 +01:00
Polymeta 4c95cfc1b3 some neoforge fixes
Closes #1437

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-06 16:19:54 +01:00
Polymeta 51a096913d simplify HeartyGrainsItem logic and update survival conditions for HeartyGrainsBlock to use tags
Closes #1591

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-06 11:58:23 +01:00
Polymeta 980d95819e make DrowsySensor consider sleep status to allow it to wake/sleep during battles no matter the time
Closes #1554
Closes #1596

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-06 01:19:34 +01:00
Polymeta 24aa65b2f1 Merge branch 'POLISH-POLISH' into 'main'
Little bit of refactoring

See merge request cable-mc/cobblemon!1699
2025-06-05 15:45:40 +00:00
Polymeta 19f33fe530 small cleanup and move component to correct place
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-05 16:02:32 +01:00
Polymeta bbe8a6948a fix license, refactor saplingblock and make falldamagemultiplier configurable
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-05 14:32:52 +01:00
Hiroku e46aaa5725 Merge branch 'party-select-tooltips' into 'main'
Adds a hoverText option to Party Select Callbacks.

See merge request cable-mc/cobblemon!1700
2025-06-05 11:08:34 +00:00
DeltricandHiroku fc6c302c71 Adds a hoverText option to Party Select Callbacks. 2025-06-05 11:08:34 +00:00
dhi_holo 76cf856907 Update CobblemonBlocks.kt
Didn't work properly, damn private classes
2025-06-05 20:46:43 +10:00
dhi_holo 145d56e205 Resolves Threads
I'm not done though, reverting the bale to a separate class makes me want to try learning something, if I can't work it out then no more commits
2025-06-05 20:10:20 +10:00
dhi_holo 969b070300 Very minor fix to kings rock model 2025-06-05 20:02:51 +10:00
阿鱼andWeblate d65d23ad02 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 78.4% (6671 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-06-05 09:16:15 +00:00
Polymeta e474ef607c Ignore vitalspirit activation message
Closes #1595

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-04 14:29:24 +01:00
Polymeta a2ecccfac4 Merge branch 'Saccharine-Tree-Bee-Nest-Orientation-Fix' into 'main'
Saccharine tree bee nest orientation fix

See merge request cable-mc/cobblemon!1695
2025-06-04 13:15:39 +00:00
Polymeta 1a475bff87 fix two mons using old behaviour keys
Closes #1598

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-04 13:43:43 +01:00
Polymeta 8b6f5f55e6 Merge branch 'RaftsAndFlyingForSmartererPokemon' into 'main'
Battle flight migrated to brains, fixed illusion mobility for brains, fixed...

Closes #1496

See merge request cable-mc/cobblemon!1696
2025-06-04 10:43:47 +00:00
Polymeta 39ed65e8ca Merge branch 'main' into 'RaftsAndFlyingForSmartererPokemon'
# Conflicts:
#   common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
2025-06-04 10:43:06 +00:00
dhi_holo 35dab86ef4 Kings Rock Model Switch
Changing to the original model, rather than the newer one that causes more problems
2025-06-04 20:27:14 +10:00
Konoha 3ad609b63e Oodles more species-related Pokemon MoLang Functions. 2025-06-04 05:02:14 -04:00
FrankTheFarmer 765a9e83ec Wailord model updated with locators 2025-06-04 18:57:45 +10:00
FrankTheFarmer ec8373ed04 Mudsdale model updated with locators 2025-06-04 18:53:59 +10:00
FrankTheFarmer 2a7c663071 Goldeen models updated with locators 2025-06-04 18:50:13 +10:00
dhi_holo 2cc14d26b1 leftover files
damn refactors missed a bit
2025-06-04 18:31:31 +10:00
dhi_holo c29da11541 Modern Major General
I prefer `general` as a term for block classes that exist to be a baseline for many blocks (in theory) to `varied`, so swapping that over
2025-06-04 18:29:08 +10:00
dhi_holo 8188ce0ed2 The Beningging
Refactoring some stuff to simplify down
2025-06-04 18:22:28 +10:00
JazzMcNade 301de140e3 canStandOnFluid now looks at the exposed form of the pokemon 2025-06-03 23:26:32 -05:00
FrankTheFarmer 1b78cae080 Merge branch 'main' into implement_pokemon 2025-06-04 12:46:57 +10:00
Konoha 4cf0dda554 Update and resolve conflicts 2025-06-03 21:59:33 -04:00
Polymeta ac55636c51 small recipe fix for loaded dice
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-03 23:31:49 +01:00
Polymeta 18eb50d4d2 Merge branch 'data-driven-brewing' into 'main'
Wrapped the Brewing Stand to allow Data Driven Recipes

See merge request cable-mc/cobblemon!1667
2025-06-03 13:22:44 +00:00
Aram 87276de14d Update CHANGELOG.md 2025-06-03 14:42:22 +02:00
Aram b7dc9ea6f6 Removed Unneccerry files 2025-06-03 14:30:34 +02:00
Aram ff59604526 Merge branch 'main' into data-driven-brewing 2025-06-03 14:27:40 +02:00
Polymeta b620ad27b6 rename OmniPathingEntity#isOnGround > entityOnGround to get around yarn mapping conflict
Fixes #1590

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-06-03 11:32:28 +01:00
Polymeta 5565f22610 Merge branch 'hyper_trained_ivs' into 'main'
Hyper Training Event and MoLang Functions

See merge request cable-mc/cobblemon!1689
2025-06-03 06:22:07 +00:00
Konoha DandPolymeta 7582b08d56 Hyper Training Event and MoLang Functions 2025-06-03 06:22:07 +00:00
Polymeta 2e101f023f Merge branch 'cleanup' into 'main'
Crash Fix

See merge request cable-mc/cobblemon!1697
2025-06-03 06:19:26 +00:00
dhi_holo d98cccfc0f Edit evolution_items.json 2025-06-03 16:12:46 +10:00
dhi_holo f83bde399c no crash
Removed some duplicates
2025-06-03 14:20:32 +10:00
JazzMcNade af77534b96 Removed escaped quotation marks 2025-06-02 20:01:30 -05:00
Karl Martin fa5193a3db Fix for bee nest entrances being blocked on saccharine trees 2025-06-02 22:06:10 +01:00
Polymeta e3c95aa4a5 Merge branch 'cooking-redstone' into 'main'
A ton of Redstone Compatibility inside the Cooking System

See merge request cable-mc/cobblemon!1640
2025-06-02 13:57:10 +00:00
AramandPolymeta 72740fb418 A ton of Redstone Compatibility inside the Cooking System 2025-06-02 13:57:10 +00:00
Watuneni iteiteandWeblate e32b540deb Translated using Weblate (Japanese)
Currently translated at 56.9% (4847 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-06-02 12:09:39 +00:00
Tobias (Targ)andWeblate f416567005 Translated using Weblate (German)
Currently translated at 61.3% (5217 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2025-06-02 12:09:37 +00:00
queao dda0c08fae Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-06-02 22:05:41 +10:00
queao d5e0364372 ow! that's sharp! (remodels for honedge line) 2025-06-02 22:05:00 +10:00
Paul 250f9e3cec Cleanup 2025-06-02 20:15:03 +10:00
Paul 26078ec29d Merge remote-tracking branch 'origin/main' 2025-06-02 20:09:11 +10:00
Paul 5b68889689 Fixed non-walking fliers not being able to wander 2025-06-02 20:09:00 +10:00
Paul bb3e86ac02 Fixed wander not being added to flying non-walkers 2025-06-02 20:08:21 +10:00
Polymeta b96a6282d8 Merge branch 'implement_pokemon' into 'main'
Fruity Implementation Merge to Main

See merge request cable-mc/cobblemon!1691
2025-06-02 08:18:00 +00:00
Frank The FarmerandPolymeta 14ee3cd754 Fruity Implementation Merge to Main 2025-06-02 08:17:59 +00:00
Paul 9c66c65b9e Merge remote-tracking branch 'origin/main' 2025-06-02 16:06:13 +10:00
Paul 9ffbd14a81 The wiki says it's called "artificial" 2025-06-02 16:06:03 +10:00
FrankTheFarmer fb36ba9720 Changelog where i log the changes i just made 2025-06-02 14:47:20 +10:00
FrankTheFarmer 87c2ce8f1a Floragato and Meowscarada swapped to json posers 2025-06-02 14:43:53 +10:00
FrankTheFarmer bb128fa7e1 Merged Floragato's battle cry with idle as a primary animation as a solution to its messed up battle cry 2025-06-02 14:43:27 +10:00
FrankTheFarmer dfcc6f2243 Uh oh spaghettio's portrait update 2025-06-02 14:42:40 +10:00
JazzMcNade 5053c765fb Merge branch 'main' into RaftsAndFlyingForSmartererPokemon 2025-06-01 17:20:39 -05:00
JazzMcNade bfe8d41102 Refactored BattleFlight as a OneShot Task, removed unnecessary memory flag. 2025-06-01 17:20:28 -05:00
plastered_crab ad3cfe3708 You'll be a pet 2025-06-01 14:14:31 -07:00
JazzMcNade a4a094a624 spawnallpokemon no longer calls sendOut() 2025-05-31 21:29:13 -05:00
plastered_crab 109895c0ff Mark this is good news 2025-05-31 17:13:36 -07:00
plastered_crab 96bcffcc84 We can finally be bees Mark 2025-05-31 14:29:35 -07:00
plastered_crab dc4f204db6 This is not our home 2025-05-31 01:11:50 -07:00
plastered_crab c07c78c331 You'll live for 30 years 2025-05-31 00:39:00 -07:00
Plastered_Crab e902e034ad This is good news 2025-05-30 14:19:31 -07:00
Plastered_Crab 77218f5250 Mark, we can BEE bees 2025-05-30 13:23:16 -07:00
JazzMcNade 0215a30c8d Battle flight migrated to brains, fixed illusion mobility for brains, fixed pokemon spawning with rafts outside of battle, 2025-05-30 01:17:56 -05:00
Konoha a0283b890b Changelog 2025-05-29 22:44:33 -04:00
FrankTheFarmer 0b4d0d3e2e Tweaks to Quaxly poser. Mind your camel cases 2025-05-30 12:41:23 +10:00
Konoha 4bca5dc092 Cleanup redundant held_item MoLang function and Registry Access 2025-05-29 22:40:57 -04:00
Konoha b4ce5f0ee6 Cleanup. Fix MoLang variable conventions and questionable player owner assertions. 2025-05-29 22:39:44 -04:00
FrankTheFarmer 561b5f25bb Merge branch 'main' into implement_pokemon 2025-05-30 12:33:50 +10:00
Konoha 603bf45998 Merge branch 'main' into extra_flows 2025-05-29 20:49:35 -04:00
washashu0905andWeblate 1daf931a49 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 80.7% (6870 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-29 20:29:11 +00:00
Konoha d12003cc7d Held Item Flow 2025-05-28 20:03:22 -04:00
Konoha 4723d26c13 Starter Chosen Event flow
Add nickname context to Pokemon Nicknamed flow
2025-05-28 18:12:13 -04:00
Konoha 664da45376 Pokemon EV Gained Flow
Minor comment fix on ReleasePokemonEvent
2025-05-28 17:02:59 -04:00
Konoha d8d017b7b3 Pokemon Nicknamed flow 2025-05-28 13:50:29 -04:00
Konoha f7acc73482 Trade Completed flow 2025-05-28 13:12:28 -04:00
Konoha a15d413ce8 Release Pokemon flow 2025-05-28 12:30:25 -04:00
Weblate 6bcbc58b0a Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-05-27 00:09:40 +00:00
Watuneni iteiteandWeblate a1218f6c1e Translated using Weblate (Japanese)
Currently translated at 55.6% (4731 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-05-27 00:09:36 +00:00
Tobias (Targ)andWeblate b1eb21150b Translated using Weblate (German)
Currently translated at 61.2% (5212 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2025-05-27 00:09:35 +00:00
Polymeta 43aa0ec04a oop this is not needed anymore
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-05-27 00:54:28 +01:00
Polymeta b4bf044f76 small refactors in mixins and JEI integration
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-05-27 00:49:26 +01:00
Carmendar a062b64588 Seel and Dewgong are now crying :( 2025-05-26 17:40:01 -05:00
GenotypeXD-Dev ee01ad20d9 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-05-26 12:15:00 -06:00
GenotypeXD-Dev b0b5aa4169 Seel and Dewgong Remodel Texture fixes 2025-05-26 12:14:44 -06:00
Sterrezo 6b042cea47 Updated sounds.json and empty cries with the latest Pokémon 2025-05-26 12:03:15 +02:00
Carmendar 1461b7231a Added/Updated cries for many Pocket Monsters. 2025-05-26 04:18:34 -05:00
GenotypeXD-Dev f115443bea Added implemented tag to Hawlucha 2025-05-25 12:57:41 -06:00
GenotypeXD-Dev 3bd946fb6b Added implemented tag to Noibat and Noivern 2025-05-25 12:56:20 -06:00
GenotypeXD-Dev 10818d4578 Implemented Clobbopus, Grapploct, Bramblin, Brambleghast, Rellor, and Rabsca 2025-05-25 12:40:42 -06:00
Konoha 0cda6d13b7 Merge branch 'implement_pokemon' into legacy_and_event_moves 2025-05-24 09:05:18 -04:00
Zack the GhastandWeblate 56d4a18474 Translated using Weblate (Portuguese (Portugal))
Currently translated at 59.5% (5062 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-24 03:06:49 +00:00
Zack the GhastandWeblate f13b6ddde7 Translated using Weblate (Portuguese (Portugal))
Currently translated at 59.3% (5051 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-23 22:41:49 +00:00
MiaandWeblate c3d119c197 Translated using Weblate (German)
Currently translated at 61.2% (5206 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2025-05-23 22:41:48 +00:00
Tobias (Targ)andWeblate eb7527c26c Translated using Weblate (German)
Currently translated at 61.2% (5206 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2025-05-23 22:41:48 +00:00
Aram 2e615800ae Update RecipeAwareSlot.java 2025-05-23 20:48:33 +02:00
Polymeta 4a4aaf3a94 fix mixin target for menu
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-05-23 17:03:33 +01:00
Aram 53ca8f009d Tried to Resolve getting the Level, sadly it checks twice, Server and Client, and Server is Null 2025-05-23 17:20:52 +02:00
Aram 5b5c756d3c Merge branch 'main' into data-driven-brewing 2025-05-23 14:24:38 +02:00
Aram 75410c3a72 Update BrewingStandBlockEntityMixin.java 2025-05-23 12:48:03 +02:00
Aram 87d001da80 Removed Client stuff from the server 2025-05-23 12:37:29 +02:00
GenotypeXD-Dev 33ceb6ce32 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-05-22 00:59:49 -06:00
GenotypeXD-Dev be97509127 Tea Size changes+animation fix 2025-05-22 00:59:33 -06:00
Kenji_64 508e9dc923 Turned Quaxly's poser into JSON. Still needs some fixes. Frank save me 2025-05-22 03:28:52 +02:00
Kenji_64 f3565e2ab7 Updated Dunsparce line scales 2025-05-21 23:46:02 +02:00
Kenji_64 b1facea991 Fixed Quaxwell's icon position 2025-05-21 23:39:06 +02:00
Kenji_64 7b4f7b06ed Changed Milcery's scale (0.5 > 0.9) 2025-05-21 23:38:37 +02:00
Aram be466ad252 Oops 2025-05-21 12:23:13 +02:00
GenotypeXD-Dev 8ab0534482 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-05-21 02:10:55 -06:00
GenotypeXD-Dev a00ab40c82 The Boston tea party update 2025-05-21 02:10:34 -06:00
washashu0905andWeblate b6bc03d2b7 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 79.1% (6731 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-20 19:53:05 +00:00
Zack the GhastandWeblate 029a338aaf Translated using Weblate (Portuguese (Portugal))
Currently translated at 59.0% (5026 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-20 19:53:04 +00:00
FrankTheFarmer 46cba69ab7 The Wiglett line will now sink in water again. 2025-05-20 11:02:40 +10:00
FrankTheFarmer b1ed170f99 Merge branch 'main' into implement_pokemon 2025-05-20 08:30:41 +10:00
washashu0905andWeblate b3f794ddaa Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 78.8% (6704 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-19 21:15:54 +00:00
Aram d37d95ee70 Fixed the Build Error 2025-05-19 19:32:52 +02:00
Zack the GhastandWeblate 1c95686bf9 Translated using Weblate (Portuguese (Portugal))
Currently translated at 59.0% (5021 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-19 11:32:46 +00:00
Zack the GhastandWeblate 55b1e7c672 Translated using Weblate (Portuguese (Portugal))
Currently translated at 58.3% (4965 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-18 19:03:26 +00:00
GenotypeXD-Dev 3867738d11 Added a Head_ai bone to dewgong for proper head turning 2025-05-17 23:50:12 -06:00
GenotypeXD-Dev 00e4864507 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-05-17 23:35:55 -06:00
GenotypeXD-Dev c46403268b Implemented Seel and Dewgong Remodels 2025-05-17 23:35:18 -06:00
FrankTheFarmer c2dab93619 Merge branch 'main' into implement_pokemon 2025-05-18 15:17:02 +10:00
washashu0905andWeblate e532fbf2ae Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 78.3% (6666 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-17 01:44:11 +00:00
Zack the GhastandWeblate c7348d3dba Translated using Weblate (Portuguese (Portugal))
Currently translated at 57.9% (4928 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-17 01:44:10 +00:00
Watuneni iteiteandWeblate b978bbe60e Translated using Weblate (Japanese)
Currently translated at 54.8% (4663 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-05-17 01:44:09 +00:00
Plastered_Crab 36cd5f3894 Merge remote-tracking branch 'origin/data-driven-brewing' into data-driven-brewing 2025-05-16 10:05:17 -07:00
Plastered_Crab b86f08b069 Merge branch 'main' into data-driven-brewing
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonRecipeCategories.kt
2025-05-16 10:04:03 -07:00
plastered_crab 75927fc1a9 licenses 2025-05-16 06:34:03 -07:00
RedGenesectNinja e49dd8eb54 Added Drilbur and Excadrill to changelog 2025-05-15 23:07:48 -05:00
RedGenesectNinja bf0c47c377 Implemented Drilbur and Excadrill 2025-05-15 22:17:58 -05:00
Aram 628db514b3 Fixed JEI With Data Driven Brewing Stand Recipe 2025-05-16 03:29:44 +02:00
Aram 9046217867 Fixed the Recipe + Shift Clicking Items 2025-05-16 02:07:44 +02:00
Aram 09c7bd8e61 Added Last Recipe 2025-05-15 23:43:26 +02:00
Aram 8df8cb9cfe Added All Recipe 2025-05-15 23:38:52 +02:00
Aram c048e5752b Updated Recipes to allow Tags AND Item IDs 2025-05-15 23:33:57 +02:00
Aram e8aa06d633 Update super_potion_brewing_stand.json 2025-05-15 22:16:23 +02:00
Aram 64979ff742 Merge branch 'main' into data-driven-brewing 2025-05-15 22:14:55 +02:00
Aram 0163619e87 Made Potion Brewing Recipes, gotta get the Tags from Main 2025-05-15 22:14:48 +02:00
Aram 258ffd25ea Nuked the old Brewing Stand code, time to Refactor 2025-05-15 21:47:52 +02:00
Aram b7de250457 Merge branch 'data-mixin-brewing' into 'data-driven-brewing'
Rewrote Data Driven to Mixin

See merge request cable-mc/cobblemon!1666
2025-05-15 21:12:46 +02:00
Aram 8d0c5bc05c Rewrote Data Driven to Mixin 2025-05-15 21:12:45 +02:00
washashu0905andWeblate 31c492c032 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 77.7% (6612 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-15 02:48:34 +00:00
阿鱼andWeblate 85a2142319 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 78.4% (6671 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-15 02:48:33 +00:00
Zack the GhastandWeblate 83e3d65918 Translated using Weblate (Portuguese (Portugal))
Currently translated at 56.6% (4818 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-15 02:48:32 +00:00
Watuneni iteiteandWeblate 9b053bef90 Translated using Weblate (Japanese)
Currently translated at 54.3% (4621 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-05-15 02:48:30 +00:00
FrankTheFarmer 21d1ae4eb5 Merge branch 'main' into implement_pokemon 2025-05-14 14:40:11 +10:00
FrankTheFarmer 3fd18319ee Somebody forgot the portrait and profile for the birds smh 2025-05-14 14:39:25 +10:00
Kenji_64 4d2b3697cc Shiny Glimmora texture fix 2025-05-14 03:37:57 +02:00
Kenji_64 a9166bbf13 Implemented the Eon Duo: Latias and Latios! Added Jet controls to both of them 2025-05-14 03:28:10 +02:00
GenotypeXD-Dev c7b2155a7c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-05-13 18:58:14 -06:00
GenotypeXD-Dev f8cec9843f Implemented Inkay line and Dedenne 2025-05-13 18:57:48 -06:00
FrankTheFarmer d417f95da7 Changelog of dungeon prevention 2025-05-14 09:23:59 +10:00
FrankTheFarmer d9b9b75e0e Swellow remodel 2025-05-14 09:22:14 +10:00
FrankTheFarmer 48e91bcb72 Taillow remodel with some z fighting for now 2025-05-14 09:22:03 +10:00
FrankTheFarmer b4e3072020 Merge branch 'main' into implement_pokemon 2025-05-14 07:52:27 +10:00
Aram 1ed4d9ff9a Shift Clicking items into the brewing stand is almost perfect! 2025-05-13 21:07:24 +02:00
Aram 8d0fc77be2 Update BrewingStandBlockMixin.java 2025-05-13 20:42:59 +02:00
Aram c45ef65645 Hard Coded Recipes still work to remain compatible with mods 2025-05-13 20:30:40 +02:00
Aram 0adfc64e35 DATAPACK BREWING STAND RECIPE HERE WE GO 2025-05-13 19:56:12 +02:00
Aram 80b4238c7e DATA DRIVEN RECIPE IN BREWING STAND 2025-05-13 19:55:55 +02:00
Aram f182cf4335 Update CobblemonRecipeCategories.kt 2025-05-13 17:38:51 +02:00
Aram f5840c4794 Nuked the Recipe Book 2025-05-13 17:38:45 +02:00
Aram 10e7962d85 Merge branch 'main' into data-driven-brewing 2025-05-13 14:39:59 +02:00
FrankTheFarmer 4d1fe48e99 Merge branch 'main' into implement_pokemon 2025-05-13 09:32:21 +10:00
Zack the GhastandWeblate 76211e81ff Translated using Weblate (Portuguese (Portugal))
Currently translated at 55.0% (4682 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-12 18:01:03 +00:00
washashu0905andWeblate 2cace9d153 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 76.5% (6510 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-12 04:29:57 +00:00
Zack the GhastandWeblate 33ad8ca12b Translated using Weblate (Portuguese (Portugal))
Currently translated at 54.4% (4633 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-12 04:29:56 +00:00
washashu0905andWeblate 8cce2c59b9 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 75.8% (6455 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-11 16:29:39 +00:00
阿鱼andWeblate bdcb8da6b7 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 77.0% (6553 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-11 16:29:38 +00:00
Zack the GhastandWeblate d0cfae8713 Translated using Weblate (Portuguese (Portugal))
Currently translated at 53.1% (4519 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-11 16:29:37 +00:00
阿鱼andWeblate 693b53704d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 76.9% (6543 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:55:19 +00:00
阿鱼andWeblate 3c46e3b5b9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:52:03 +00:00
阿鱼andWeblate 5dec5ed008 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:52:00 +00:00
阿鱼andWeblate 22a479633e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:57 +00:00
阿鱼andWeblate 1d93df56ae Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:53 +00:00
阿鱼andWeblate 136d47bd2f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:51 +00:00
阿鱼andWeblate 8ded0af5e9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:47 +00:00
阿鱼andWeblate 36462b0a85 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:44 +00:00
阿鱼andWeblate 8a447a2487 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:41 +00:00
阿鱼andWeblate bdc2c4d9de Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:38 +00:00
阿鱼andWeblate 8d9a7d67b5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:35 +00:00
阿鱼andWeblate e1d9b2780a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:32 +00:00
阿鱼andWeblate fafee79da9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:29 +00:00
阿鱼andWeblate 71c6c12656 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:26 +00:00
阿鱼andWeblate 4e07128c80 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:23 +00:00
north_82andWeblate df8640ce48 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:20 +00:00
阿鱼andWeblate 59e0a6369d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 72.8% (6194 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-10 12:51:19 +00:00
Zack the GhastandWeblate 8913252b79 Translated using Weblate (Portuguese (Portugal))
Currently translated at 51.1% (4353 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-10 12:51:17 +00:00
Zack the GhastandWeblate f7bedc9866 Translated using Weblate (Portuguese (Portugal))
Currently translated at 50.4% (4288 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-10 01:05:34 +00:00
washashu0905andWeblate e47529c10a Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 74.3% (6324 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-09 23:42:48 +00:00
Zack the GhastandWeblate 3e6c6c21a6 Translated using Weblate (Portuguese (Portugal))
Currently translated at 50.1% (4267 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-09 23:42:47 +00:00
FrankTheFarmer 2b59276384 Merge branch 'main' into implement_pokemon 2025-05-10 07:13:04 +10:00
washashu0905andWeblate d4f13b9435 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 73.0% (6216 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-09 12:41:51 +00:00
Zack the GhastandWeblate e7b60abe2d Translated using Weblate (Portuguese (Portugal))
Currently translated at 48.6% (4134 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-09 12:41:50 +00:00
TeggyandWeblate 85da2bd0cc Translated using Weblate (Spanish)
Currently translated at 77.0% (6554 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-05-09 12:41:48 +00:00
Aram c3d482c78f Recipe Book is workingggg!!!!!!!!! 2025-05-08 17:47:43 +02:00
queao b6188af659 changelog for solosis line 2025-05-08 17:19:28 +10:00
queao f0a2f55054 cats n dogs in the changelog?! 2025-05-08 17:17:24 +10:00
queao fe27cbf56a Phantoms hate this 1 simple trick! 2025-05-08 16:48:53 +10:00
queao ea273d6466 meow meow 2025-05-08 16:46:08 +10:00
queao 3da96ccaaa bark bark 2025-05-08 16:06:57 +10:00
FrankTheFarmer 37c9a903a1 Merge branch 'main' into implement_pokemon 2025-05-08 12:20:56 +10:00
Aram 7effc4c853 NON FUNCTIONAL: Finally added the Recipe Book, 2025-05-07 20:17:41 +02:00
Aram 4cd504126b BROKEN: Started adding the Recipe Book 2025-05-07 17:18:30 +02:00
Aram 60ee7b819c Created the Recipe 2025-05-07 12:48:06 +02:00
Aram 28548d5b19 Small rename? 2025-05-07 12:47:46 +02:00
Aram e6ec690811 Wrapped the Brewing Stand to allow Data Driven Recipes Soon!!!
Check previous commit
2025-05-07 01:42:51 +02:00
Aram dac49c2f42 Wrapped the Brewing Stand to allow Data Driven Recipes Soon!!!
Some small issues
* Right clicking Brewing stand first time converts it and wont open gui, so fix that
* The entire code is a Copy Paste of Vanilla ATM, need to start modifying the shit out of it
2025-05-07 01:41:30 +02:00
Kenji_64 7d57c1450e Translated Dratini line posers to .json, added their cries and water_sleep anims 2025-05-06 15:02:38 +02:00
washashu0905andWeblate b7af57f6e1 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 72.7% (6187 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-06 09:41:57 +00:00
Aiser(CCHusky)andWeblate ca5b7e1aec Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 68.7% (5843 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-06 09:41:56 +00:00
阿鱼andWeblate 2ec81679e4 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 68.7% (5843 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-05-06 09:41:56 +00:00
Zack the GhastandWeblate 08c048f4ba Translated using Weblate (Portuguese (Portugal))
Currently translated at 41.2% (3508 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-06 09:41:55 +00:00
Watuneni iteiteandWeblate 6589279339 Translated using Weblate (Japanese)
Currently translated at 53.7% (4573 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-05-06 09:41:53 +00:00
Alexis SalgueiroandWeblate 4465e47f2e Translated using Weblate (French)
Currently translated at 100.0% (8505 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-05-06 09:41:52 +00:00
YasitoandWeblate 570d42df7a Translated using Weblate (French)
Currently translated at 100.0% (8505 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-05-06 09:41:52 +00:00
YasitoandWeblate 044e83449d Translated using Weblate (French (Canada))
Currently translated at 100.0% (8505 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-05-06 09:41:50 +00:00
Felipe Bermudes OrmeñoandWeblate 6617558e71 Translated using Weblate (Spanish (Mexico))
Currently translated at 26.4% (2252 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-05-06 09:41:49 +00:00
TeggyandWeblate eff410b714 Translated using Weblate (Spanish)
Currently translated at 76.4% (6504 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-05-06 09:41:48 +00:00
FrankTheFarmer 4aee0b291c Merge branch 'main' into implement_pokemon 2025-05-05 20:55:15 +10:00
FrankTheFarmer bcff96013e Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-05-05 20:54:50 +10:00
FrankTheFarmer be46c59934 Restored sigilyph's ability to move, adjusted its hitbox and scale, and tweaked its poser 2025-05-05 20:54:41 +10:00
violet 73c1a92a17 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-05-05 06:07:14 -04:00
violet 04a773d35c BLOBS 2025-05-05 06:06:33 -04:00
FrankTheFarmer 01a7461a9a Merge branch 'main' into implement_pokemon 2025-05-05 15:23:40 +10:00
Zack the GhastandWeblate 482a7d9493 Translated using Weblate (Portuguese (Portugal))
Currently translated at 35.9% (3058 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-03 09:32:24 +00:00
YasitoandWeblate 430891971c Translated using Weblate (French)
Currently translated at 97.2% (8275 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-05-03 09:32:24 +00:00
YasitoandWeblate d88f2d80a3 Translated using Weblate (French (Canada))
Currently translated at 100.0% (8505 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-05-03 09:32:23 +00:00
washashu0905andWeblate 2a3d74bd85 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 71.9% (6117 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-03 02:45:17 +00:00
Zack the GhastandWeblate de94986156 Translated using Weblate (Portuguese (Portugal))
Currently translated at 33.6% (2865 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-03 02:45:17 +00:00
YasitoandWeblate f8afcb6a8f Translated using Weblate (French)
Currently translated at 97.0% (8255 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-05-03 02:45:15 +00:00
YasitoandWeblate 3c0cf1dc5b Translated using Weblate (French (Canada))
Currently translated at 95.9% (8158 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-05-03 02:45:14 +00:00
Zack the GhastandWeblate 8225898a66 Translated using Weblate (Portuguese (Portugal))
Currently translated at 26.8% (2283 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-02 07:52:09 +00:00
washashu0905andWeblate 49faf60ea1 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 70.2% (5976 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-02 07:52:09 +00:00
Weblate 71bd4fb610 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-05-01 21:54:39 +00:00
Felipe Bermudes OrmeñoandWeblate 509feae420 Translated using Weblate (Spanish (Mexico))
Currently translated at 24.7% (2103 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-05-01 21:54:34 +00:00
washashu0905andWeblate 5045a95cd0 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 69.9% (5946 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-05-01 21:54:33 +00:00
TeggyandWeblate 07dfc89f63 Translated using Weblate (Spanish)
Currently translated at 72.8% (6196 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-05-01 21:54:30 +00:00
Zack the GhastandWeblate 34b6a3cc47 Translated using Weblate (Portuguese (Portugal))
Currently translated at 26.6% (2266 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-05-01 21:54:29 +00:00
FrankTheFarmer c56529030b Merge branch 'main' into implement_pokemon 2025-05-01 18:26:08 +10:00
FrankTheFarmer bd81f84643 Changelog of Cacti and Spiders 2025-05-01 18:25:36 +10:00
FrankTheFarmer e840eb6e70 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-05-01 18:23:10 +10:00
FrankTheFarmer ed64b0cbc6 Cacturne remodel and json poser 2025-05-01 18:22:59 +10:00
FrankTheFarmer d821677411 Cacnea given a json poser 2025-05-01 18:22:30 +10:00
FrankTheFarmer c42d090862 Garchomp model updated so it can wear hats 2025-05-01 18:22:10 +10:00
RedGenesectNinja 2b85024b75 Implemented Tarountula and Spidops, and also adjusted Joltik's eye height. I love arachnids 2025-05-01 02:12:13 -05:00
plastered_crab 07497d653e More data, models, etc for Ponigiri 2025-04-30 19:08:44 -07:00
plastered_crab dfb28ed185 langs for Base, Frosted, Fancy, and Deluxe Poke Puffs 2025-04-30 14:54:08 -07:00
plastered_crab 0cc9a75255 Rough draft on Poke Puff tooltips 2025-04-30 12:59:14 -07:00
plastered_crab abfd718681 Poke Puffs are starting to work great now (visually) 2025-04-30 12:00:32 -07:00
FrankTheFarmer ab6d08ad14 Changelog of pain and suffering 2025-04-30 20:03:21 +10:00
FrankTheFarmer fa64eb7333 Scizor remodel with locators 2025-04-30 20:01:48 +10:00
FrankTheFarmer 5dd17752b6 Scyther remodel with locators 2025-04-30 20:01:29 +10:00
FrankTheFarmer 3a351a3195 Clodsire is now 15% larger❗ 2025-04-30 20:00:35 +10:00
FrankTheFarmer 81922a8d2c Merge branch 'main' into implement_pokemon 2025-04-30 19:58:34 +10:00
plastered_crab 8271b7a979 I am so close but I must sleep 2025-04-30 01:42:12 -07:00
plastered_crab 251c2df78e tweak parent of first predicate 2025-04-29 23:03:38 -07:00
plastered_crab c03e30bd9c Test poke puff predicate stuff 2025-04-29 21:32:24 -07:00
Plastered_Crab ecc793350a New experimental food stuff 2025-04-29 16:33:50 -07:00
YasitoandWeblate 98fd61ec29 Translated using Weblate (French (Canada))
Currently translated at 92.5% (7875 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-29 16:26:11 +00:00
washashu0905andWeblate e1e545dd05 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 58.5% (4979 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-04-29 16:26:07 +00:00
Zack the GhastandWeblate c403103018 Translated using Weblate (Portuguese (Portugal))
Currently translated at 21.2% (1811 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-04-29 16:26:05 +00:00
Alexis SalgueiroandWeblate d6a1d3f2bd Translated using Weblate (French)
Currently translated at 95.3% (8110 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-29 16:26:05 +00:00
YasitoandWeblate 87edf2bfd6 Translated using Weblate (French)
Currently translated at 95.3% (8110 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-29 16:26:04 +00:00
阿鱼andWeblate 7711535a26 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 67.3% (5731 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-04-29 16:26:02 +00:00
FrankTheFarmer f819909446 Merge branch 'main' into implement_pokemon 2025-04-29 07:20:21 +10:00
Sterrezo dd195317f9 Turned sound keyframes into scripts for Pidgey, Pidgeotto, Pidgeot, Golbat, Aerodactyl, Dragonite 2025-04-28 17:12:54 +02:00
Sterrezo ab00285a4c Added wing flaps to Butterfree 2025-04-28 17:00:49 +02:00
Sterrezo 953d724c87 Updated animation sounds, added more variation and chitin wing sounds 2025-04-28 16:33:08 +02:00
YasitoandWeblate f65f6fd2c9 Translated using Weblate (French (Canada))
Currently translated at 89.0% (7575 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 07:11:57 +00:00
YasitoandWeblate a4e144854d Translated using Weblate (French)
Currently translated at 93.8% (7981 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-28 07:11:56 +00:00
Weblate d6f7cd4b83 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-04-28 06:06:01 +00:00
YasitoandWeblate 36cf258410 Translated using Weblate (French)
Currently translated at 92.6% (7876 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-28 06:05:56 +00:00
YasitoandWeblate 89df2a01e2 Translated using Weblate (French)
Currently translated at 86.8% (7387 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-28 05:33:24 +00:00
YasitoandWeblate 0a930cb54f Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-28 05:07:13 +00:00
YasitoandWeblate 2448fec2c4 Translated using Weblate (French (Canada))
Currently translated at 88.9% (7568 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 05:07:13 +00:00
YasitoandWeblate ea2071b644 Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-28 04:50:27 +00:00
YasitoandWeblate bae0d77699 Translated using Weblate (French (Canada))
Currently translated at 88.9% (7564 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 04:50:27 +00:00
YasitoandWeblate f5f5cb19bc Translated using Weblate (French (Canada))
Currently translated at 88.5% (7527 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 04:41:03 +00:00
YasitoandWeblate 9aa7c65279 Translated using Weblate (French (Canada))
Currently translated at 87.6% (7451 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 04:21:08 +00:00
YasitoandWeblate 8f4071e181 Translated using Weblate (French (Canada))
Currently translated at 83.6% (7114 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 03:12:58 +00:00
YasitoandWeblate 9c4470bc51 Translated using Weblate (French (Canada))
Currently translated at 82.8% (7043 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 02:57:15 +00:00
YasitoandWeblate c785480c32 Translated using Weblate (French (Canada))
Currently translated at 82.7% (7034 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 02:55:09 +00:00
YasitoandWeblate 4a50700bb9 Translated using Weblate (French (Canada))
Currently translated at 82.4% (7014 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 02:31:04 +00:00
YasitoandWeblate 0ad2ff552b Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-28 02:31:03 +00:00
YasitoandWeblate 44c5d4ea2e Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-28 02:07:34 +00:00
YasitoandWeblate 46661908e0 Translated using Weblate (French (Canada))
Currently translated at 82.4% (7013 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 02:07:33 +00:00
YasitoandWeblate 01372f2850 Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-28 01:26:15 +00:00
YasitoandWeblate 204ce8f003 Translated using Weblate (French (Canada))
Currently translated at 81.7% (6954 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 01:26:15 +00:00
Zack the GhastandWeblate 784ddcb19a Translated using Weblate (Portuguese (Portugal))
Currently translated at 20.9% (1785 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-04-28 01:26:13 +00:00
Zack the GhastandWeblate 11d7cbfa46 Translated using Weblate (Portuguese (Portugal))
Currently translated at 20.9% (1785 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-04-28 00:34:45 +00:00
YasitoandWeblate f3325caaea Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-28 00:34:44 +00:00
YasitoandWeblate 123c348f73 Translated using Weblate (French (Canada))
Currently translated at 81.2% (6910 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-28 00:34:43 +00:00
Zack the GhastandWeblate 29aae87f01 Translated using Weblate (Portuguese (Portugal))
Currently translated at 20.9% (1785 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_PT/
2025-04-27 23:55:57 +00:00
YasitoandWeblate 9f6ad98acb Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 23:45:29 +00:00
YasitoandWeblate cecd291566 Translated using Weblate (French (Canada))
Currently translated at 81.1% (6905 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 23:45:28 +00:00
YasitoandWeblate 2f9d6a9f83 Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 22:59:22 +00:00
YasitoandWeblate 1e9ccbddcb Translated using Weblate (French (Canada))
Currently translated at 81.0% (6893 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 22:59:21 +00:00
YasitoandWeblate 9b5a381436 Translated using Weblate (French (Canada))
Currently translated at 81.0% (6891 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 22:53:05 +00:00
YasitoandWeblate ed5bd7e899 Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 22:53:04 +00:00
YasitoandWeblate 587a90bb70 Translated using Weblate (French)
Currently translated at 86.8% (7386 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 22:24:54 +00:00
YasitoandWeblate f883578046 Translated using Weblate (French (Canada))
Currently translated at 80.8% (6873 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 22:24:48 +00:00
YasitoandWeblate b5d348eba6 Translated using Weblate (French (Canada))
Currently translated at 80.3% (6830 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 21:40:48 +00:00
YasitoandWeblate fce389edfd Translated using Weblate (French (Canada))
Currently translated at 77.5% (6594 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 19:59:05 +00:00
YasitoandWeblate b6954b4e07 Translated using Weblate (French (Canada))
Currently translated at 76.6% (6523 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 19:31:52 +00:00
YasitoandWeblate f28a16c7cc Translated using Weblate (French (Canada))
Currently translated at 76.2% (6488 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 19:17:12 +00:00
YasitoandWeblate 230071a773 Translated using Weblate (French (Canada))
Currently translated at 75.9% (6456 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 18:59:21 +00:00
YasitoandWeblate 63534a242c Translated using Weblate (French (Canada))
Currently translated at 75.8% (6449 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 18:54:07 +00:00
YasitoandWeblate 1afb574aec Translated using Weblate (French (Canada))
Currently translated at 75.5% (6427 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 17:58:35 +00:00
YasitoandWeblate ac9adb03cd Translated using Weblate (French)
Currently translated at 81.5% (6938 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 17:58:34 +00:00
YasitoandWeblate f3a22b19b3 Translated using Weblate (French (Canada))
Currently translated at 75.5% (6427 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 17:23:59 +00:00
YasitoandWeblate 572e77c4f5 Translated using Weblate (French (Canada))
Currently translated at 75.5% (6426 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 08:45:10 +00:00
YasitoandWeblate 889a012932 Translated using Weblate (French)
Currently translated at 81.5% (6938 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 08:45:09 +00:00
YasitoandWeblate eca4c6cd4c Translated using Weblate (French)
Currently translated at 81.5% (6938 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 08:29:53 +00:00
YasitoandWeblate b570a6ec8b Translated using Weblate (French (Canada))
Currently translated at 75.5% (6426 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 08:29:52 +00:00
YasitoandWeblate 1f1c302bc9 Translated using Weblate (French (Canada))
Currently translated at 75.5% (6426 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 08:13:24 +00:00
YasitoandWeblate adc1fa0063 Translated using Weblate (French)
Currently translated at 81.5% (6938 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 08:13:23 +00:00
YasitoandWeblate ddc3a781a0 Translated using Weblate (French)
Currently translated at 81.4% (6930 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 06:49:52 +00:00
YasitoandWeblate 9eb3281c6f Translated using Weblate (French)
Currently translated at 79.8% (6793 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 06:26:21 +00:00
YasitoandWeblate 0cd5804e67 Translated using Weblate (French)
Currently translated at 77.0% (6549 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 05:59:16 +00:00
YasitoandWeblate 7000d0d82a Translated using Weblate (French)
Currently translated at 74.8% (6369 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 05:26:22 +00:00
YasitoandWeblate b7695e55ea Translated using Weblate (French)
Currently translated at 68.5% (5829 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 04:36:54 +00:00
YasitoandWeblate bea3ebe62b Translated using Weblate (French)
Currently translated at 68.4% (5825 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 04:35:43 +00:00
YasitoandWeblate 73cf736077 Translated using Weblate (French (Canada))
Currently translated at 75.4% (6413 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 04:05:10 +00:00
YasitoandWeblate d31f8f0eff Translated using Weblate (French)
Currently translated at 68.1% (5797 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 04:05:09 +00:00
YasitoandWeblate 88dca4d7b1 Translated using Weblate (French (Canada))
Currently translated at 75.3% (6410 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 03:22:47 +00:00
YasitoandWeblate 27db85ee32 Translated using Weblate (French (Canada))
Currently translated at 75.3% (6406 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 03:09:50 +00:00
YasitoandWeblate 5e3561eba5 Translated using Weblate (French (Canada))
Currently translated at 75.2% (6400 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 03:02:48 +00:00
YasitoandWeblate 9dfa8a323e Translated using Weblate (French)
Currently translated at 68.1% (5797 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 02:21:41 +00:00
YasitoandWeblate 15c0d86996 Translated using Weblate (French (Canada))
Currently translated at 74.9% (6371 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 02:21:37 +00:00
Weblate 0fbb5e7d95 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-04-27 00:08:16 +00:00
YasitoandWeblate 5e8d27779c Translated using Weblate (French (Canada))
Currently translated at 73.6% (6265 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-27 00:08:12 +00:00
阿鱼andWeblate a4fabcd45d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 66.3% (5647 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-04-27 00:08:10 +00:00
YasitoandWeblate 5259b8c93d Translated using Weblate (French)
Currently translated at 68.1% (5797 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-27 00:08:09 +00:00
FrankTheFarmer 41b1e25816 Merge branch 'main' into implement_pokemon 2025-04-27 07:37:37 +10:00
FrankTheFarmer 7c9490db2a Merge branch 'main' into implement_pokemon 2025-04-27 03:28:14 +10:00
FrankTheFarmer e53b4fc36b Changelog 2025-04-26 11:27:10 +10:00
FrankTheFarmer 5eef6628c3 🌵Maractus💚 remodel 2025-04-26 11:26:46 +10:00
FrankTheFarmer 509f44dca0 Forgot Sigilyph portrait and profile 2025-04-26 11:26:22 +10:00
FrankTheFarmer 2e3db889a3 Merge branch 'main' into implement_pokemon 2025-04-26 10:29:52 +10:00
FrankTheFarmer 4c81e244e3 Sharpedo on the changelog 2025-04-26 10:28:55 +10:00
FrankTheFarmer cc4a381956 Locators added to Sharpedo 2025-04-26 10:21:49 +10:00
FrankTheFarmer a4ee09f4f7 Quick Corviknight asset push 2025-04-26 06:18:16 +10:00
FrankTheFarmer c3a13e35a0 Changelog moment 2025-04-26 05:09:53 +10:00
FrankTheFarmer 1897992093 Sigilyph remodel 2025-04-26 05:05:51 +10:00
FrankTheFarmer 4dfed5ffcf Merge branch 'main' into implement_pokemon 2025-04-26 04:08:40 +10:00
FrankTheFarmer 150ebff24f Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-04-26 04:07:51 +10:00
FrankTheFarmer 40721c1ce5 Gabite model tweaks with locators added 2025-04-26 04:07:37 +10:00
FrankTheFarmer 89fbf299d2 Gible model tweaks with locators added 2025-04-26 04:07:27 +10:00
QriviateA 83961e80a3 Forgor to give blinks to Gothita Line + reduced gothita head clipping into bowtie when looking down 2025-04-25 18:32:41 +01:00
YasitoandWeblate 397c2decbf Translated using Weblate (French)
Currently translated at 67.8% (5772 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-25 04:29:11 +00:00
Felipe Bermudes OrmeñoandWeblate 12b6e7e49c Translated using Weblate (Spanish (Mexico))
Currently translated at 24.6% (2098 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-04-25 04:29:10 +00:00
YasitoandWeblate 242c1b01af Translated using Weblate (French (Canada))
Currently translated at 69.4% (5906 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-25 04:29:09 +00:00
FrankTheFarmer 7b992802ce Metang model updated with locators 2025-04-25 14:00:22 +10:00
FrankTheFarmer ba12ed5f98 Beldum model updated with locators 2025-04-25 14:00:12 +10:00
FrankTheFarmer 56f68ff0a9 Merge branch 'main' into implement_pokemon 2025-04-25 11:12:58 +10:00
FrankTheFarmer e7d27686e8 Logged Changes 2025-04-25 11:12:27 +10:00
FrankTheFarmer 3592ef4150 Magneton remodel 🧲⚪⚪⚪🧲 2025-04-25 11:10:28 +10:00
FrankTheFarmer dd76a16e08 Magnemite remodel 🧲⚪🧲 2025-04-25 11:08:27 +10:00
FrankTheFarmer f882c89485 Merge branch 'main' into implement_pokemon 2025-04-25 09:18:51 +10:00
FrankTheFarmer 06a989df5e Oh no i forgot the changelog 2025-04-24 21:15:02 +10:00
FrankTheFarmer def77d197f Bouffalant Remodel 🟫 2025-04-24 21:13:25 +10:00
FrankTheFarmer 382b740505 💖Heatmor✨ Remodel 😹👉🐜🚫 2025-04-24 21:12:44 +10:00
FrankTheFarmer 7a65ec3602 Frog on da changelog 2025-04-23 20:42:31 +10:00
FrankTheFarmer 57abb2b020 Finally added Toxicroak 🐸 2025-04-23 20:40:53 +10:00
FrankTheFarmer 4decbe421b Small portrait tweak for croagunk 2025-04-23 20:29:24 +10:00
FrankTheFarmer e7746e2fa4 Realigned croagunk posers 2025-04-23 15:38:18 +10:00
FrankTheFarmer 862dc0176c Removed isBattle condition in croagunk poser 2025-04-23 15:34:19 +10:00
FrankTheFarmer 7123d40084 Specified missing rootbone in croagunk's poser 2025-04-23 15:32:35 +10:00
FrankTheFarmer cd21e0faf8 Fixed broken charizard sleep animation data 2025-04-23 14:41:45 +10:00
FrankTheFarmer 26586599a7 Added custom placeholder walk to Ursaluna 2025-04-23 13:09:21 +10:00
JPAK 06732e89fd Update Changelog and error handling. 2025-04-22 14:27:40 -05:00
QriviateA d153dd49b7 Added Gothitelle 🎀 2025-04-22 20:18:04 +01:00
QriviateA 6e3cc5054a Added Gothorita 🎀 2025-04-22 20:17:45 +01:00
QriviateA c06969815a Added Gothita 🎀 2025-04-22 20:17:32 +01:00
QriviateA 502bd38aa7 Added Purugly 😼 2025-04-22 20:16:50 +01:00
QriviateA 11071eb44a Added Glameow 😼 2025-04-22 20:16:15 +01:00
QriviateA dd6ca6c803 Added Cyclizar 🚲 2025-04-22 20:15:07 +01:00
QriviateA 3ebba90f98 Updated Changelog 2025-04-22 20:12:56 +01:00
JPAK 9e8d6a4f39 Add an option for String timezones to "date_of" and "date_local_time" functions. 2025-04-22 12:33:45 -05:00
JPAK 662efa55c6 Fix imports. 2025-04-22 12:10:39 -05:00
JPAK efb9e538f3 Merge branch 'main' into irl_date_time_molang
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/molang/MoLangFunctions.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/config/Category.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/config/CobblemonConfig.kt
2025-04-22 12:03:37 -05:00
FrankTheFarmer 889ace7632 Merge branch 'main' into implement_pokemon 2025-04-22 19:16:07 +10:00
Felipe Bermudes OrmeñoandWeblate ee76e19b85 Translated using Weblate (Spanish (Mexico))
Currently translated at 23.7% (2017 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es_MX/
2025-04-22 09:14:36 +00:00
YasitoandWeblate 2aac6cc9e7 Translated using Weblate (French)
Currently translated at 67.6% (5754 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-22 09:14:35 +00:00
YasitoandWeblate 3faa305f09 Translated using Weblate (French (Canada))
Currently translated at 59.0% (5026 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-22 09:14:34 +00:00
YasitoandWeblate d1bbf5f079 Translated using Weblate (French)
Currently translated at 67.1% (5715 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-21 23:59:12 +00:00
YasitoandWeblate 52fa646420 Translated using Weblate (French (Canada))
Currently translated at 56.5% (4813 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-21 23:59:11 +00:00
Alexis SalgueiroandWeblate f7c47d46cf Translated using Weblate (French)
Currently translated at 66.5% (5658 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-21 14:21:10 +00:00
YasitoandWeblate e82c361bcb Translated using Weblate (French)
Currently translated at 66.5% (5658 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-21 14:21:10 +00:00
TeggyandWeblate fa6d8e0f08 Translated using Weblate (Spanish)
Currently translated at 72.5% (6168 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-21 14:21:06 +00:00
阿鱼andWeblate 7eea6c8b49 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 66.3% (5643 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-04-21 14:21:03 +00:00
YasitoandWeblate c537ca438b Translated using Weblate (French (Canada))
Currently translated at 55.4% (4720 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr_CA/
2025-04-21 14:21:01 +00:00
washashu0905andWeblate d5cea9b9ad Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 53.1% (4518 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hant/
2025-04-21 14:20:57 +00:00
TeggyandWeblate 6c2494b7ab Translated using Weblate (Spanish)
Currently translated at 68.2% (5806 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-19 19:31:37 +00:00
Fiestorra ISVandWeblate a5ab523ac1 Translated using Weblate (Spanish)
Currently translated at 66.6% (5672 of 8505 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-19 06:05:19 +00:00
Konoha bd493a147c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-04-18 20:39:14 -04:00
Konoha 1e4665d600 Toxel Low Key evolution fix
Distinguishes the evolution ids for Toxel to the Low Key form Toxtricity so that natures other than Lonely can function.
2025-04-18 20:38:54 -04:00
Weblate 847ae12ad5 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-04-18 21:50:21 +00:00
TeggyandWeblate cece9e051b Translated using Weblate (Spanish)
Currently translated at 98.9% (6948 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-18 21:50:21 +00:00
Fiestorra ISVandWeblate 02141ccd3e Translated using Weblate (Spanish)
Currently translated at 98.9% (6948 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-18 21:50:21 +00:00
MiaandWeblate 1dc3acc47d Translated using Weblate (German)
Currently translated at 87.2% (6124 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2025-04-18 21:50:21 +00:00
FrankTheFarmer 03374c5c78 Merge branch 'main' into implement_pokemon 2025-04-18 20:04:52 +10:00
FrankTheFarmer 594eca13d3 Changelogs 2025-04-18 20:03:43 +10:00
FrankTheFarmer bf1bdc2475 Ursaluna remodel 🐻 2025-04-18 20:02:53 +10:00
FrankTheFarmer 6f6f9b088e Ursaring remodel, locators, and temp animations i stole from charizard 2025-04-18 19:40:03 +10:00
FrankTheFarmer 2bbc00022b Teddiursa remodel and locators 🧸 2025-04-18 16:47:03 +10:00
Sterrezo 14f4e04a86 Added animation sounds to Pidgey, Pidgeotto and Golbat 2025-04-17 13:36:53 +02:00
Sterrezo 944d342d36 Updated Ceruledge's cries 2025-04-17 12:33:59 +02:00
FrankTheFarmer 638524f7f7 Changelog moment 2025-04-17 13:57:37 +10:00
FrankTheFarmer 47750e894b Noctowl model updated with open and closed wings🦉 2025-04-17 13:56:22 +10:00
FrankTheFarmer 9e31d8e1e1 Hoothoot model update 🦉 2025-04-17 13:55:55 +10:00
FrankTheFarmer 59d8adc48d Merge branch 'main' into implement_pokemon 2025-04-17 13:55:06 +10:00
QriviateA f4ab23c167 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-04-16 21:28:50 +01:00
QriviateA b7a8582ae8 Updated Wailmer anims 2025-04-16 21:28:26 +01:00
QriviateA b68910897c Updated Stonjourner texture + anims 2025-04-16 21:28:10 +01:00
QriviateA 7204ea828f Updated Lechonk line anims 2025-04-16 21:26:52 +01:00
QriviateA 0a4a71123c Updated Gossifleur line anims 2025-04-16 21:25:57 +01:00
QriviateA ec385b9963 Updated Changelog 2025-04-16 21:24:49 +01:00
Konoha 1d40d424d0 Update changelog 2025-04-15 10:31:32 -04:00
Konoha 938721c0bb Merge branch 'implement_pokemon' into legacy_and_event_moves 2025-04-15 09:11:50 -04:00
FrankTheFarmer 8aa37fda9d Merge branch 'main' into implement_pokemon 2025-04-15 13:40:25 +10:00
Konoha 52533236ca Merge branch 'implement_pokemon' into legacy_and_event_moves 2025-04-14 07:56:05 -04:00
Konoha d560918b55 Merge branch 'main' into legacy_and_event_moves
# Conflicts:
#	common/src/main/resources/data/cobblemon/species/generation1/farfetchd.json
#	common/src/main/resources/data/cobblemon/species/generation7/oricorio.json
#	common/src/main/resources/data/cobblemon/species/generation8/sirfetchd.json
2025-04-01 08:05:27 -04:00
Konoha 427bf34a56 Add Legal move query 2025-02-12 20:15:39 -05:00
Konoha 479daa49ce Merge branch 'implement_pokemon' into legacy_and_event_moves 2025-02-12 20:10:03 -05:00
Konoha 729156924d Fix post-processing errors and Genesect form conventions 2025-02-12 20:09:33 -05:00
JPAK 42c711cfc7 Fix config and add langs for config. 2025-02-07 14:35:59 -06:00
JPAK 681d5f8bcc Merge remote-tracking branch 'origin/irl_date_time' into irl_date_time_molang
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/config/Category.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/config/CobblemonConfig.kt
2025-02-07 12:27:49 -06:00
JordanandJPAK a52d8452b4 Revert "Add "irlDateRange" and "irlTimeRange" as a pokemon spawning condition."
This reverts commit b0be0b2dca
2025-02-07 12:23:13 -06:00
JPAK e65298b587 Add "irlDateRange" and "irlTimeRange" as a pokemon spawning condition. 2025-02-07 12:23:13 -06:00
JPAK f8c09b8e26 Add config for time zones and add an optional parameter to MoLangFunction's "date_local_time" and "date_of" to use the config time zone instead of the system time zone. 2025-02-07 12:23:11 -06:00
JPAK 5d1019afd5 Add config for time zones and add an optional parameter to MoLangFunction's "date_local_time" and "date_of" to use the config time zone instead of the system time zone. 2025-02-07 12:22:28 -06:00
Konoha a34db1dc1b Legacy and event move support 2025-02-01 09:37:12 -05:00
JPAK eb9bd116b2 Merge remote-tracking branch 'origin/irl_date_time' into irl_date_time_molang
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/config/CobblemonConfig.kt
2024-12-29 14:28:06 -06:00
JPAK 70bf4d6654 Add config for time zones and add an optional parameter to MoLangFunction's "date_local_time" and "date_of" to use the config time zone instead of the system time zone. 2024-12-29 14:14:43 -06:00
Jordan 080a5b9c74 Revert "Add "irlDateRange" and "irlTimeRange" as a pokemon spawning condition."
This reverts commit b0be0b2dca
2024-12-27 19:45:08 +00:00
JPAK b0be0b2dca Add "irlDateRange" and "irlTimeRange" as a pokemon spawning condition. 2024-12-27 13:35:41 -06:00
JPAK d8300436c9 Add config for time zones and add an optional parameter to MoLangFunction's "date_local_time" and "date_of" to use the config time zone instead of the system time zone. 2024-12-26 22:25:15 -06:00
3927 changed files with 140284 additions and 38166 deletions
+10 -3
View File
@@ -2,14 +2,21 @@
- Rebuilt Pokémon AI to use Minecraft's Brain system, allowing for more complex behaviours and interactions.
- As an early pass of this, pastured Pokémon will now sleep when appropriate, and may come up to you when they see you.
- Probably also added a whole bunch of bugs.
- Growlithe and Arcanine intimidate Skeletons.
- Meowth intimidate Creepers and Phantoms.
- Dog Pokémon (Growlithe, Arcanine, etc.) intimidate Skeletons.
- Cat Pokémon (Meowth, Persian, etc.) intimidate Creepers and Phantoms.
- Sleep-related Pokémon (Munsharna, Komala, etc.) intimidate Phantoms.
- Some Pokémon naturally hunt each other.
- Added a Behaviour Editor to the NPC editing screen.
- Added /behaviouredit command for opening the Behaviour Editor on Pokémon and NPCs.
- Editing variables for Pokémon is not yet supported.
### Developer
- baseScale in NPCs has been removed from classes and presets, and in the entity it is replaced with hitboxScale and renderScale.
- Added `EntityCallbacks` to `NPCEntity` and `PokemonEntity`. You can trigger custom callback types by using `[Entity].callbacks.process(...)`
### MoLang & Datapacks
- Added a `behaviours` datapack folder which motivates the Behaviour Editor screen on NPCs and Pokémon.
- Added many default behaviours.
- Added "callback" support on PokemonEntity and NPCEntity that allows MoLang scripts to be executed in response to certain scenarios.
- 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.
- NPCs with these presets should be modified to instead list under `"behaviours"` all the equivalent behaviours.
+24
View File
@@ -4,6 +4,30 @@
- There is a different pot for each apricorn colour because at this point I think we may have an addiction.
- Added Aprijuice, made from the Campfire Pot using apricorns with seasoning to give flavours.
- Aprijuice can be fed to ride-able Pokémon to improve their riding characteristics, depending on the flavour and the Pokémon's nature.
- Added Lure Cakes, made from the Campfire Pot using honey and berries.
- Lure Cakes can be used to modify the spawn rate of Pokémon in the wild.
- Added the Saccharine Tree, which can be found in the wild and is used to obtain Honey Bottles.
- The leaves of the tree can be harvested to obtain honey, which can be used in the Campfire Pot to make Lure Cakes.
- The Log of the tree can be interacted with using a honey bottle to create a Honey-Slathered Saccharine Log, which increases the change of spawning a Pokémon with a Hidden Ability.
- Added Hearty Grains
- Clicking on the Progress Arrow will show the JEI Recipe Book for the Campfire Pot, which will show all recipes that can be made with it.
- Added a Ton of Redstone Compatibility.
- Dispenser can now Honey and Unhoney:
- Saccharine Log
- Saccharine Leaves
- Redstone can Close and Open the Lid of a Cooking Pot
- Powered = Closed
- Unpowered = Open
- Hoppers can be used to insert items into a Cooking pot
- Top = Seasonals
- All Sides = Crafting
- Bottom = Extract the Result
- Observer will recognise when a Cooking pot is Closed or Opened
- Comparator Calculates a Signal Strength depending on the items inside the cooking pot
- Sculk Sensor
- Saccharine Leaves
- Opening and Closing the Cooking Pot
- Saccharine Log
### Datapack and Addon Changes
- Renamed the fishing_baits datapack folder to spawn_bait_effects.
+7 -1
View File
@@ -4,10 +4,16 @@
- 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.
- 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 `/renamebox <player> <boxNumber> <name>` command to rename a PC box through commands.
- Added IVs and EVs stat displays in PC.
- improved filter by Name, now is available search by exact names or partial matches, for example "cha" will show Charmander, Charmeleon and Charizard among others that match.
- 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
- Added `RenamePCBoxEvent.Pre` and `RenamePCBoxEvent.Post` events to prevent players from renaming a box or changing their input.
+162 -3
View File
@@ -7,6 +7,7 @@
- Added `/cobblemonconfig reload` command to reload `main.json` configuration. **Note:** Some settings require a server restart to take effect; use this command cautiously.
- Added `blacklisted_items_to_hold` and `whitelisted_items_to_hold` tags to allow for controlling which items players can give to their Pokémon. If the whitelist is empty, it will consider all item as allowed (unless they are in the blacklist).
- Pokémon now follow the mouse cursor on the Summary screen, with an option to disable this in the settings.
- Added Datapackable Item interactions with Pokemon
- Pokémon's held items can now be rendered, with a visibility toggle in the Summary screen.
- Added cosmetic item functionality for Pokémon. Certain cosmetic items can be given to applicable Pokémon via the interact menu.
- Added the various log blocks as cosmetic items for Timburr and Komala.
@@ -17,10 +18,10 @@
- Added cosmetics for Gurdurr, Conkeldurr, Squirtle Line, Sneasler, Sandle line, Treecko line, Braixen, Delphox, and Dragonite.
- Added `/transformmodelpart (position|rotation|scale) <modelPart> <transform: x y z>` command that can add transformations to a pokemon's model part.
- 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 lang keys for all moves and abilities up to Generation 9.
- Fixed Moon Ball moon phase logic to actually work correctly
- Added `translucent_cull` boolean option into resolver's layer to allow for translucent textures with culling
- Added [LambDynamicLights](https://modrinth.com/mod/lambdynamiclights) support for items held by Pokémon.
- Added [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 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`.
@@ -30,6 +31,16 @@
- Added `/pcsearch <player> <pokemonProperties>` command that searches for a specific Pokémon within a player's PC.
- Added `/pctake <player> <box> <slot>` command that takes a specific Pokémon from a player's PC. Removes the pokemon if target is self or ran from the server.
- Added Hyper Training items (IV Modification) as well as some additional candy items to do so (Health Candy, Sickly Candy)
- Added Galarica Nut Bushes
- Many Pokémon (mostly cats) are now feared by phantoms
- Lightning is now affected by a Pokemon's ability/typing
- Pokémon with the ability Lightning Rod draw in lightning similar to a lightning rod block albeit with a lower priority and range, gain immunity to lightning damage, and receive a temporary damage buff.
- Pokémon with the ability Motor Drive are immune to lightning damage and receive a temporary speed buff when struck by lightning
- Pokémon with the ability Volt Absorb are immune to lightning damage and receive Regeneration II for a short duration
- Ground type Pokémon are immune to lightning damage
- Added functionality to Everstone when held by a Pokémon; suppresses evolution notification and hides evolve button in summary interface.
- Added new optional property `attachment_options` for most EmitterShapes to be attached to the locator/entities scale, rotation, and/or position. Position is true by default.
- Galarica Nut bushes now generate on beaches
### Pokémon Added
@@ -41,12 +52,17 @@
- Grumpig
- Snorunt
- Glalie
- Latias
- Latios
#### Gen 4
- Bronzor
- Bronzong
- Croagunk
- Toxicroak
- Froslass
- Glameow
- Purugly
#### Gen 5
- Pansage
@@ -59,10 +75,24 @@
- Musharna
- Blitzle
- Zebstrika
- Drilbur
- Excadrill
- Trubbish
- Garbodor
- Gothita
- Gothorita
- Gothitelle
- Solosis
- Duosion
- Reuniclus
- Mienfoo
- Mienshao
#### Gen 6
- Inkay
- Malamar
- Hawlucha
- Dedenne
- Noibat
- Noivern
@@ -72,13 +102,20 @@
#### Gen 8
- Silicobra
- Sandaconda
- Sinistea
- Polteageist
#### Gen 9
- Smoliv
- Dolliv
- Arboliva
- Tarountula
- Spidops
- Orthworm
- Dudunsparce
- Cyclizar
- Poltchageist
- Sinistcha
### Animation updates for the following Pokémon
- Garchomp
@@ -91,6 +128,15 @@
- Delphox
- Cinderace
- Kangaskhan
- Gossifleur
- Eldegoss
- Stonjourner
- Wailmer
- Lechonk
- Oinkologne
- Dratini
- Dragonair
- Dragonite
### Model updates for the following Pokémon
- Gyarados
@@ -108,18 +154,57 @@
- Grovyle
- Sceptile
- Honchkrow
- Gible
- Gabite
- Garchomp
- Pidgeot
- Nosepass
- Probopass
- Kangaskhan
- Cinderace
- Magnemite
- Magneton
- Magnezone
- Beldum
- Metang
- Metagross
- Hoothoot
- Noctowl
- Teddiursa
- Ursaring
- Ursaluna
- Heatmor
- Bouffalant
- Sigilyph
- Sharpedo
- Maractus
- Clodsire
- Scyther
- Scizor
- Cacturne
- Taillow
- Swellow
- Added Syrupy Apples.
- Seel
- Dewgong
- Honedge
- Doublade
- Aegislash
### Changes
- Changed pokemon caught and seen count to update based on the current pokedex being looked
- Renamed `chargeGainedPerTick` config to `secondsToChargeHealingMachine`.
- Added config setting `maxPokedexScanningDetectionRange` to control from what distance the player can scan Pokémon using the Pokédex.
- Added the `is_standing_on_blocks(depth, blocks...)` MoLang function, which returns whether the specified entity is standing on a specific block or set of blocks. Example usage: `q.is_standing_on_blocks(2, minecraft:sand)`
- Added config setting `hideUnimplementedPokemonInThePokedex` which hides unimplemented Pokémon from the Pokédex when set to true.
- Added molang particle queries for getting distance to targeted entities
- Added debug renderer for poseable entity locators
- Added time zone as a config option
- Added an optional MoValue to either use system timezone when set as true, or use the supplied string as a timezone for MoLang functions `date_local_time` and `date_of`. If the timezone supplied fails to parse this function now returns `0.0`.
### Additions
- Added time zone as a config option
- Added optional boolean to use time zone for MoLang function "date_local_time" and "date_of"
- Made Blocks of Gold count as Big Nuggets when held by a Pokémon (for Fling functionality)
- Players can now eat Sweet and Tart Apples, Whipped Dreams, and the Alcremie Sweets.
- Updated Sweet and Tart Apple sprites
@@ -153,8 +238,22 @@
- Added all Potted Apricorn Sprouts, Potted Saccharine Saplings, and Potted Pep-Up Flowers to the `#minecraft:flower_pots` block tag
- Corrected the healing values of the remedies and energy root, and reintroduced the friendship lowering mechanics for them, revivl herb, and heal powder
- Updated battle language keys for side effects to use position-specific formats, improving grammatical consistency
- Saccharine Leaves are now Collectable
- Saccharine Leaves Age 1 or higher will now show Yellow particles when broken
- Destroying a Saccharine Honey Log will now drop a Saccharine Log in stead of nothing
- 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.
- Vivichokes now always drop one seed when harvested, and converting a fully grown Vivichoke to seeds via crafting results in 1 seed.
- Healing Machine recipe rebalanced.
- Reorganised the `block` texture folder to be more organised, in line with the `item` texture folder.
- Offset in EmitterShape now ignores scale to be more like Blockbench by default. You can get this behaviour back by adding `"scale": true` in the `attachment_options` property in most EmitterShapes.
- Not specifying a dex in `/pokedex printcalculations {player} {dex}` will now print the National Dex statistics instead of showing all dexes. `/pokedex printcalculations {player} all` is how to view all dex statistics in one command.
- Removed Braised Vivichoke
### Fixes
- Fixed game crashing when removing national pokedex using datapacks
- Fixed Particles sometimes facing the wrong direction (looking at you, Swords Dance)
- Fixed PCs always opening at box 2 instead of box 1.
- Fixed not being able to do complex item requirements aside from just NBT with evolution conditions, requirements and fossil items.
@@ -181,6 +280,7 @@
- Fixed Pokémon marked as silent still playing shiny sounds and effects.
- Fixed an issue with newer versions of Fabric API where underground Pokémon were spawning in The End.
- Fixed spawning not working well when you're at high points surrounded by lower altitude spawning areas, such as flying.
- Fixed some Pokémon having erroneous tutor moves if another move included a valid tutor move as a substring.
- Fixed certain Pokémon with forms not having appropriate stock Pokédex entries.
- Fixed issue with Pokédex Scanner that caused the open/close overlay to have the wrong opacity values
- Fixed dragon's breath not being usable on the restoration tank when it should be
@@ -193,10 +293,33 @@
- Fixed the `dimensions` spawning condition using the incorrect ResourceLocation, causing it to not function properly.
- Fix issue where locator X axis was not aligned with blockbench.
- Fix issue where particle effects that play on frame 1 on sendout would never play (Gastly)
- The Wiglett line will now sink in water again.
- Fixed the Sprigatito line's portraits being zoomed in too far.
- Fixed Floragato's battle cry animation from breaking.
- Fixed the block texture name for the Pep-Up Flower being inaccurate
- Fixed issue where the restoration tank would not accept valid items from a hopper.
- Fixed energy root not being shearable
- Fixed energy root always spreading into more energy roots instead of by chance (same as big root)
- Fixed issue where Pokémon spawned by the "spawnallpokemon" command potentially receiving a raft.
- Fixed logspam on NeoForge when adorn is not installed
- Fixed Cobblemon crashing if it tries to load a bedrock model not meant for cobblemon (example: Qlipoth Awakening)
- 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 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 Pokémon could not path over fence posts situations.
- Fixed flyers not being able to do vertical takeoff if surrounded by blocks.
- Fixed swimming Pokémon attempting to swim up through solid blocks.
- Fixed Pokémon surface swimming diving downward a block for the duration of the swim.
- 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 `/pokedex printcalculations` to now show the correct percentage completed of the Pokedex
- Fixed mod incompatibility with the `Raised` mod
- Fixed a vulnerability that could cause party and PC rollbacks under specific circumstances.
- Fixed a rare edge case where sorting your PC could be rolled back later.
### Developer
- A finished battle now has winners and losers set inside of `PokemonBattle` instead of them always being empty.
@@ -215,6 +338,11 @@
- Updated NPCEntity pokeball throw positioning to properly account for the baseScale property.
- Fixed `[Pokemon].copyFrom` error causing forms, IVs, and EVs to not be applied properly when using `[Pokemon].loadFromJSON` or `[Pokemon].loadFromNBT`
- Added new item class, `WearableItem`. Instances of this class should have a corresponding 3D model. These models render when the items display context is `HEAD`.
- Added new LearnsetQuery types:
- `LEGAL` for moves that are innately compatible and learnable by the Pokémon.
- `LEGACY` for moves that were once officially learnable by the Pokémon but aren't due to GameFreak's re-balancing.
- `SPECIAL` for moves that are not learnable by the Pokémon but may have appeared in a special event or distribution.
- Pokemon now have a fireImmune attribute in their behaviour that can be set to true to ignore all fire damage (lava, magma blocks, etc.)
`JSON
{
@@ -224,7 +352,16 @@
}
`
- The IVs class has now been extended to include Hyper Trained values.
- Added `Pokemon#hyperTrainIV()` and `IVs#setHyperTrainedIV(Stat, Int)`.
- Added `HyperTrainedIvEvent.Pre` and `HyperTrainedIvEvent.Post`.
- Added `Pokemon#validateMoveSet()` to validate an existing Pokemon's moveset, clearing illegal moves.
- 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.
- Added `Pokemon#hyperTrainIV()` and `IVs#setHyperTrainedIV(Stat, Int)`
- `ElementalType` now implements `ShowdownIdentifiable` to ensure the communcation with showdown stays consistent (also in regards to TeraTypes)
- Pokemon no longer have a change observable
### 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)
@@ -243,6 +380,9 @@
- Added `pokemon` as an available Molang function for the `battleActor` functions.
- Fixed `heldItem` property inside spawn files not working and causing crashes
- Fixed `spawn_bedrock_particles` MoLang causing crashes when used in a server environment
- The following move sources are now valid for the `moves` array in species data:
- `legacy:{move}`
- `special:{move}`
- The Pokédex form lang key definition now follows `cobblemon.ui.pokedex.info.form.{species}-{formname}` instead of `cobblemon.ui.pokedex.info.form.{formname}`.
- Added `play_sound_on_server` as an available Molang function for the `worldHolder` & `player` functions.
- Added `run_molang_after` as an available Molang function for the `entity` functions when schedulable.
@@ -252,6 +392,24 @@
- The format of the `remedies.json` file has changed to allow for individual friendshipDrop amounts per remedy
- Fixed `entity.find_nearby_block` causing crashes when attempting to use a block tag
- Spawn Filters can now access `v.spawn.class` to get the identifier of an NPC class for when trying to influence NPC spawns
- Added Molang functions for Party and PC: `set_pokemon`
- Added Molang functions for Pokémon: `pokeball`, `held_item`, `remove_held_item`, `hyper_train_iv`, `validate_moveset`, `initialize_moveset`, and `add_exp`.
- Added Molang functions for Pokémon: `aspects`, `form_aspects`, `unlearn_move`, `teach_learnable_moves`, `cosmetic_item`, and `remove_cosmetic_item`.
- Added Molang functions for Pokémon: `ability`, `set_iv`, `set_ev`, `teach_move`, and `can_learn_move`.
- Adds Flows for `STARTER_CHOSEN`, `SHOULDER_MOUNTED`, `EV_GAINED`, `POKEMON_RELEASED`, `POKEMON_NICKNAMED`, `HELD_ITEM`, and `TRADE_COMPLETED` events
- Adds Flows for `POKEMON_HEALED`, `POKEMON_SCANNED`, `BERRY_HARVEST`, `LOOT_DROPPED`, `POKEMON_SEEN`, `COLLECT_EGG`, `HATCH_EGG`, and `EXPERIENCE_GAINED`.
- Adds Flows for `POKEMON_CATCH_RATE`, `BAIT_SET`, `BAIT_SET_PRE`, `BAIT_CONSUMED`, `POKEROD_CAST_PRE`, `POKEROD_CAST_POST`, `POKEROD_REEL`, and `BOBBER_SPAWN_POKEMON_PRE`.
- Adds Flows for `POKEMON_ASPECTS_CHANGED`, `FRIENDSHIP_UPDATED`, `CHANGE_PC_BOX_WALLPAPER_EVENT_PRE`, `CHANGE_PC_BOX_WALLPAPER_EVENT_POST`, and `FULLNESS_UPDATED`.
- MoLang triggered battles may now set the battle format, whether to clone the player's party, set level, or heal prior.
- Added Molang function for Player: `inventory`
- Adds Flows for `STARTER_CHOSEN`, `EV_GAINED`, `POKEMON_RELEASED`, `POKEMON_NICKNAMED`, `HELD_ITEM`, and `TRADE_COMPLETED` events
- Adds Pokemon functions for `pokeball`, `held_item`, `remove_held_item`, `add_aspects`, and `remove_aspects`
- Added `pokemon.hyper_train_iv` as an available Molang function.
- Added `prepare_{effect}` and `damage_{effect}` action effect hooks in battles for more battle particle effects.
- Added `q.has_argument(<argument_name>, [argument_value])` MoLang function to several battle-related action effect contexts.
- Added `q.has_argument_at(<index>, [argument_value])` MoLang function to several battle-related action effect contexts.
- Added `q.hit_count` MoLang function to move action effect contexts.
- Added `is_included`, `to_lower`, `to_upper`, and `string_length` as available Molang functions.
## [1.6.1 (January 26th, 2025)](#1-6-1)
@@ -1066,6 +1224,7 @@
}
`
- Added support for custom stashes, similar to Gimmighoul's coin and scrap stashes.
- Added the ability to create custom brewing stand recipes.
### Localization
- Updated translations for:
@@ -2373,4 +2532,4 @@ Thank you so much to all of our community translators that bring the mod to the
- Added species, ability, and move translations for `ko_ko`, `jp_jp`, `fr_fr`, `es_es`, `it_it`, and `zh_cn`.
## [1.0.0 (November 12th, 2022)](#1-0-0)
- Initial release.
- Initial release.
-1
View File
@@ -1,6 +1,5 @@
plugins {
id("cobblemon.root-conventions")
id ("net.nemerosa.versioning") version "3.1.0"
}
version = "${project.property("mod_version")}+${project.property("mc_version")}"
-1
View File
@@ -21,7 +21,6 @@ plugins {
id("net.kyori.blossom")
id("org.jetbrains.gradle.plugin.idea-ext")
id("net.nemerosa.versioning") version "3.1.0"
}
architectury {
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.compat;
import com.cobblemon.mod.common.CobblemonEntities;
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer;
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.lighthing.LightingData;
import dev.lambdaurora.lambdynlights.LambDynLights;
@@ -36,20 +37,20 @@ public class LambDynamicLightsCompat {
public static void hookCompat() {
// Pokémon entities
DynamicLightHandlers.registerDynamicLightHandler(
CobblemonEntities.POKEMON,
DynamicLightHandler.makeHandler(
LambDynamicLightsCompat::resolvedPokemonLightLevel,
pokemon -> false
)
CobblemonEntities.POKEMON,
DynamicLightHandler.makeHandler(
LambDynamicLightsCompat::resolvedPokemonLightLevel,
pokemon -> false
)
);
// Shouldered Pokémon
DynamicLightHandlers.registerDynamicLightHandler(
EntityType.PLAYER,
DynamicLightHandler.makeHandler(
LambDynamicLightsCompat::resolvedShoulderLightLevel,
player -> false
)
EntityType.PLAYER,
DynamicLightHandler.makeHandler(
LambDynamicLightsCompat::resolvedPlayerLightLevel,
player -> false
)
);
}
@@ -63,11 +64,13 @@ public class LambDynamicLightsCompat {
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();
final int leftLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityLeft()), underwater);
final int rightLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityRight()), underwater);
return Math.max(leftLightLevel, rightLightLevel);
final int leftShoulderLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityLeft()), underwater);
final int rightShoulderLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityRight()), underwater);
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) {
@@ -83,14 +86,17 @@ public class LambDynamicLightsCompat {
}
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);
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) {
return underwater ? liquidGlowMode.getGlowsUnderwater() : liquidGlowMode.getGlowsInLand();
}
}
@@ -0,0 +1,17 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.duck;
public interface ChannelDuck {
void cobblemon$applyLowPassFilter(float gain, float hfGain);
void cobblemon$inverseAttenuation(float rolloffFactor);
void cobblemon$clearFilters();
// void cobblemon$exponentialAttenuation(float rolloff, float refDistance, float maxDistance);
}
@@ -6,8 +6,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.item
package com.cobblemon.mod.common.duck;
class GalaricaNutItem : CobblemonItem(Properties()) {
// Eventually, put some logic here for planting it or something
}
import net.minecraft.world.item.crafting.RecipeManager;
public interface RecipeAwareSlot {
void setRecipeManager(RecipeManager recipeManager);
}
@@ -12,14 +12,12 @@ import com.cobblemon.mod.common.block.SaccharineLeafBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import org.objectweb.asm.Opcodes;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Desc;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@@ -42,8 +40,9 @@ public abstract class BeeEntityMixin {
if (block instanceof SaccharineLeafBlock) {
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);
}
}
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.duck.ChannelDuck;
import com.mojang.blaze3d.audio.Channel;
import org.lwjgl.openal.AL10;
import org.lwjgl.openal.EXTEfx;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(Channel.class)
public abstract class ChannelMixin implements ChannelDuck {
@Shadow
private int source;
// Id of filter applied when sound is obstructed
private int cobblemon$lowPassFilterId = 0;
@Override
public void cobblemon$applyLowPassFilter(float gain, float hfGain) {
// Delete old filter if it exists
if (cobblemon$lowPassFilterId != 0) {
AL10.alSourcei(source, EXTEfx.AL_DIRECT_FILTER, 0); // Detach filter from source
EXTEfx.alDeleteFilters(cobblemon$lowPassFilterId); // Delete old filter
cobblemon$lowPassFilterId = 0;
}
// Generate a fresh filter
int filterId = EXTEfx.alGenFilters();
if (!EXTEfx.alIsFilter(filterId)) {
System.err.println("Failed to create OpenAL low-pass filter");
return;
}
EXTEfx.alFilteri(filterId, EXTEfx.AL_FILTER_TYPE, EXTEfx.AL_FILTER_LOWPASS);
EXTEfx.alFilterf(filterId, EXTEfx.AL_LOWPASS_GAIN, gain);
EXTEfx.alFilterf(filterId, EXTEfx.AL_LOWPASS_GAINHF, hfGain);
AL10.alSourcei(source, EXTEfx.AL_DIRECT_FILTER, filterId);
// Save the new filter ID
cobblemon$lowPassFilterId = filterId;
}
@Override
public void cobblemon$inverseAttenuation(float rolloffFactor) {
AL10.alSourcei(source, AL10.AL_DISTANCE_MODEL, AL10.AL_INVERSE_DISTANCE);
AL10.alSourcef(source, AL10.AL_ROLLOFF_FACTOR, rolloffFactor);
AL10.alSourcef(source, AL10.AL_REFERENCE_DISTANCE, 1.0f);
AL10.alSourcef(source, AL10.AL_MAX_DISTANCE, 0.0f);
}
@Override
public void cobblemon$clearFilters() {
AL10.alSourcei(source, EXTEfx.AL_DIRECT_FILTER, 0);
if (EXTEfx.alIsFilter(cobblemon$lowPassFilterId)) {
EXTEfx.alDeleteFilters(cobblemon$lowPassFilterId);
cobblemon$lowPassFilterId = 0;
}
}
}
@@ -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();
}
}
}
@@ -1,39 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import net.minecraft.world.entity.monster.Phantom;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(targets = "net/minecraft/world/entity/monster/Phantom$PhantomSweepAttackGoal")
public class EntityPhantomMixin {
// TODO: Figure out how to access the outer class that wraps SwoopMovementGoal
// Need to find the cat mons that are near the phantom
// @Inject(method = "shouldContinue", at = @At(value = "RETURN"), cancellable = true)
// public void cobblemon$shouldContinue(CallbackInfoReturnable<Boolean> ci) {
//// var goalSelectorField = PhantomEntity.class.getClasses();// PhantomEntity.class.getFields();// .class.getDeclaredField("goalSelector");
//
//// goalSelectorField.setAccessible(true);
//// GoalSelector goalSelector = (GoalSelector) goalSelectorField.get(mobEntity);
//// final SwoopMovementGoal phantom = (SwoopMovementGoal) (Object) this;
//// if(ci.getReturnValue() == false) {
//// var result = this$0.getWorld().getEntitiesByClass(
//// PokemonEntity.class,
//// this$0.getBoundingBox().expand(16.0),
//// entity -> {
//// return ((PokemonEntity) entity).getBehaviour().getEntityInteract().getAvoidedByPhantom();
//// }
//// ).isEmpty();
////
//// ci.setReturnValue(result);
//// }
// }
}
@@ -9,20 +9,19 @@
package com.cobblemon.mod.common.mixin;
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.entity.PosableEntity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
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.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.AABB;
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.Shadow;
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 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)
public class EntityRenderDispatcherMixin {
@@ -77,6 +71,23 @@ public class EntityRenderDispatcherMixin {
0F,
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();
});
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LightningBolt;
import net.minecraft.world.phys.AABB;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
@Mixin(LightningBolt.class)
public abstract class LightningBoltMixin {
@Inject(method = "spawnFire", at = @At(value = "Head"), cancellable = true)
private void cobblemon$spawnFire(int extraIgnitions, CallbackInfo ci) {
// This prevents fire from spawning around Pokemon who otherwise should be immune to lightning and effectively absorb the hit
final LightningBolt lightningBolt = (LightningBolt) (Object) this;
List<Entity> list = lightningBolt.level().getEntities(
lightningBolt,
new AABB(lightningBolt.getX() - 2.0, lightningBolt.getY() - 2.0, lightningBolt.getZ() - 2.0, lightningBolt.getX() + 2.0, lightningBolt.getY() + 2.0, lightningBolt.getZ() + 2.0),
it -> {
if (!it.isAlive() || !(it instanceof PokemonEntity)) {
return false;
}
String abilityName = ((PokemonEntity) it).getPokemon().getAbility().getName();
return abilityName.equals("lightningrod") || abilityName.equals("voltabsorb") || abilityName.equals("motordrive");
});
if (!list.isEmpty()) {
ci.cancel();
}
}
}
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokemon.ai.EntityBehaviour;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.monster.Phantom;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(targets = "net.minecraft.world.entity.monster.Phantom$PhantomSweepAttackGoal")
public abstract class PhantomSweepAttackGoalMixin extends Goal {
@Unique
private Phantom phantomSelf; // Allows access to the outer class
@Inject(method = "<init>", at = @At("TAIL"))
private void onInit(Phantom phantom, CallbackInfo ci) {
this.phantomSelf = phantom;
}
@Inject(method = "canContinueToUse", at = @At("RETURN"), cancellable = true)
private void modifyCanContinueToUse(CallbackInfoReturnable<Boolean> cir) {
Phantom phantom = this.phantomSelf; // Outer class instance
if(phantom == null) return;
if (cir.getReturnValue()) {
var nearbyFearedEntities = phantom.level().getEntities(phantom, phantom.getBoundingBox().inflate(16.0),
(entity -> ((entity instanceof PokemonEntity && ((PokemonEntity) entity).getBeamMode() == 0 && ((PokemonEntity) entity).getBehaviour().getEntityInteract().getAvoidedByPhantom())
|| (entity instanceof ServerPlayer && EntityBehaviour.Companion.hasPhantomFearedShoulderMount((ServerPlayer)entity)))));
if (!nearbyFearedEntities.isEmpty()) {
nearbyFearedEntities.forEach(entity -> {
if (entity instanceof PokemonEntity) {
((PokemonEntity) entity).cry();
}
//TODO: Find a way to make shoulder mounted Pokemon cry
});
cir.setReturnValue(false);
}
}
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.phys.AABB;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
import java.util.Optional;
@Mixin(ServerLevel.class)
public abstract class ServerLevelMixin {
@Inject(method = "findLightningRod", at = @At(value = "RETURN"), cancellable = true)
private void cobblemon$findLightningRod(BlockPos blockPos, CallbackInfoReturnable<Optional<BlockPos>> ci) {
final ServerLevel serverLevel = (ServerLevel) (Object) this;
if (ci.getReturnValue().isEmpty()) {
// Search for Pokemon with the ability Lightning Rod and redirect to them
AABB aABB = AABB.encapsulatingFullBlocks(blockPos, new BlockPos(blockPos.atY(serverLevel.getMaxBuildHeight()))).inflate(64.0);
List<LivingEntity> list = serverLevel.getEntitiesOfClass(LivingEntity.class, aABB, (livingEntity) -> livingEntity != null
&& livingEntity.isAlive()
&& livingEntity instanceof PokemonEntity
&& ((PokemonEntity) livingEntity).getBeamMode() == 0
&& ((PokemonEntity) livingEntity).getPokemon().getAbility().getName().equals("lightningrod"));
if (!list.isEmpty()) {
ci.setReturnValue(Optional.of((list.get(serverLevel.random.nextInt(list.size()))).blockPosition()));
}
}
}
}
@@ -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.mixin;
import com.cobblemon.mod.common.block.HeartyGrainsBlock;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.DoublePlantBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
import net.minecraft.world.level.levelgen.feature.SimpleBlockFeature;
import net.minecraft.world.level.levelgen.feature.configurations.SimpleBlockConfiguration;
import org.spongepowered.asm.mixin.Debug;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(SimpleBlockFeature.class)
@Debug(export = true, print = true)
public class SimpleBlockFeatureMixin {
//this mixin inserts the logic needed to ensure that when hearty grains are of a certain age, they place with the upper block too
//similarly to what the doubleblock logic is here
@Inject(method = "place", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;canSurvive(Lnet/minecraft/world/level/LevelReader;Lnet/minecraft/core/BlockPos;)Z", shift = At.Shift.AFTER), cancellable = true)
public void place(FeaturePlaceContext<SimpleBlockConfiguration> context, CallbackInfoReturnable<Boolean> cir,
@Local BlockState blockState, @Local BlockPos blockPos, @Local WorldGenLevel worldGenLevel) {
if (!(blockState.getBlock() instanceof HeartyGrainsBlock)) {
return;
}
if (blockState.getValue(HeartyGrainsBlock.Companion.getAGE()) <= HeartyGrainsBlock.AGE_AFTER_HARVEST) {
return; //block is too young to be double
}
if (!worldGenLevel.isEmptyBlock(blockPos.above())) {
cir.setReturnValue(false); //no space for the 2nd block above
return;
}
DoublePlantBlock.placeAt(worldGenLevel, blockState, blockPos, Block.UPDATE_CLIENTS);
cir.setReturnValue(true);
}
}
@@ -8,23 +8,33 @@
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.api.riding.sound.RideAttenuationModel;
import com.cobblemon.mod.common.api.riding.sound.RideLoopSound;
import com.cobblemon.mod.common.client.sound.BattleMusicController;
import com.cobblemon.mod.common.duck.ChannelDuck;
import com.cobblemon.mod.common.duck.SoundEngineDuck;
import com.google.common.collect.Multimap;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.audio.Channel;
import net.minecraft.client.resources.sounds.Sound;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.client.resources.sounds.TickableSoundInstance;
import net.minecraft.client.sounds.ChannelAccess;
import net.minecraft.client.sounds.SoundEngine;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.Iterator;
import java.util.Map;
@Mixin(SoundEngine.class)
@@ -45,6 +55,86 @@ public abstract class SoundEngineMixin implements SoundEngineDuck {
@Shadow
public abstract boolean isActive(SoundInstance sound);
@Inject(method = "play",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/sounds/ChannelAccess$ChannelHandle;execute(Ljava/util/function/Consumer;)V"
),
cancellable = true
)
private void cobblemon$overrideChannelExecute(
SoundInstance sound,
CallbackInfo ci,
@Local(name = "h") float h,
@Local(name = "i") float i,
@Local(name = "g") float g,
@Local(name = "bl2") boolean bl2,
@Local(name = "bl3") boolean bl3,
@Local(name = "bl") boolean bl,
@Local(name = "vec3") Vec3 vec3,
@Local(name = "channelHandle") ChannelAccess.ChannelHandle handle
) {
if (!(sound instanceof RideLoopSound rideSound)) return;
if (handle == null) return;
handle.execute((channel) -> {
channel.setPitch(i);
channel.setVolume(h);
if (rideSound.getRideAttenuation() == RideAttenuationModel.LINEAR) {
channel.linearAttenuation(g);
} else if (rideSound.getRideAttenuation() == RideAttenuationModel.EXPONENTIAL){
((ChannelDuck) channel).cobblemon$inverseAttenuation(g);
} else {
channel.disableAttenuation();
}
// Apply low pass filter if the rideSound dictate that it should be muffled
if (rideSound.getShouldMuffle()) {
((ChannelDuck) channel).cobblemon$applyLowPassFilter(1.0f, rideSound.getMuffleAmount());
} else {
((ChannelDuck) channel).cobblemon$clearFilters();
}
channel.setLooping(bl2 && !bl3);
channel.setSelfPosition(vec3);
channel.setRelative(bl);
});
}
@Inject(
method = "tickNonPaused",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/sounds/ChannelAccess$ChannelHandle;execute(Ljava/util/function/Consumer;)V",
ordinal = 0
)
)
private void cobblemon$tickableSoundTick(
CallbackInfo ci,
@Local(name = "tickableSoundInstance") TickableSoundInstance instance,
@Local(name = "channelHandle", ordinal = 0) ChannelAccess.ChannelHandle handle,
@Local(name = "f", ordinal = 0) float volume,
@Local(name = "g", ordinal = 0) float pitch,
@Local(name = "vec3", ordinal = 0) Vec3 vec3
) {
if (!(instance instanceof RideLoopSound rideSound)) return;
handle.execute(channel -> {
channel.setVolume(volume);
channel.setPitch(pitch);
channel.setSelfPosition(vec3);
// Apply low pass filter if the rideSound dictate that it should be muffled
if (rideSound.getShouldMuffle()) {
((ChannelDuck) channel).cobblemon$applyLowPassFilter(1.0f, rideSound.getMuffleAmount());
} else {
((ChannelDuck) channel).cobblemon$clearFilters();
}
});
}
/** Resumes the Source belonging to the queried SoundInstance. */
private void resume(SoundInstance sound) {
ChannelAccess.ChannelHandle sourceManager = this.instanceToChannel.get(sound);
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.brewing;
import com.cobblemon.mod.common.CobblemonRecipeTypes;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandInput;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.world.Containers;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.alchemy.PotionBrewing;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.LevelEvent;
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import java.util.List;
import java.util.Optional;
@Mixin(BrewingStandBlockEntity.class)
public class BrewingStandBlockEntityMixin {
@WrapOperation(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BrewingStandBlockEntity;doBrew(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/NonNullList;)V"))
private static void cobblemon$doBrew(Level level, BlockPos pos, NonNullList<ItemStack> slots, Operation<Void> original) {
var recipe = cobblemon$fetchBrewingRecipe(slots, level);
if(recipe == null) {
original.call(level, pos, slots);
return;
}
//copied from vanilla doBrew logic, but slightly tweaked to work for cobblemon, this was needed as replacing the loop was not quite possible inside doBrew
ItemStack itemStack = slots.get(3);
for(int i = 0; i < 3; ++i) {
slots.set(i, recipe.getResult().copy());
}
itemStack.shrink(1);
if (itemStack.getItem().hasCraftingRemainingItem()) {
ItemStack itemStack2 = new ItemStack(itemStack.getItem().getCraftingRemainingItem());
if (itemStack.isEmpty()) {
itemStack = itemStack2;
} else {
Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), itemStack2);
}
}
slots.set(3, itemStack);
level.levelEvent(LevelEvent.SOUND_BREWING_STAND_BREW, pos, 0);
}
@WrapOperation(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BrewingStandBlockEntity;isBrewable(Lnet/minecraft/world/item/alchemy/PotionBrewing;Lnet/minecraft/core/NonNullList;)Z"))
private static boolean cobblemon$isBrewable(PotionBrewing potionBrewing, NonNullList<ItemStack> items, Operation<Boolean> original,
@Local(argsOnly = true) Level level) {
return cobblemon$fetchBrewingRecipe(items, level) != null || original.call(potionBrewing, items);
}
@Unique
private static BrewingStandRecipe cobblemon$fetchBrewingRecipe(NonNullList<ItemStack> items, Level level) {
ItemStack ingredient = items.get(3);
List<ItemStack> bottles = items.subList(0, 3);
boolean allBottlesEmpty = true;
for (ItemStack bottle : bottles) {
if (!bottle.isEmpty()) {
allBottlesEmpty = false;
break;
}
}
if (ingredient.isEmpty() || allBottlesEmpty) {
return null;
}
BrewingStandInput input = new BrewingStandInput(ingredient, bottles);
RecipeManager recipeManager = level.getRecipeManager();
Optional<RecipeHolder<BrewingStandRecipe>> recipeHolder =
recipeManager.getRecipeFor(CobblemonRecipeTypes.INSTANCE.getBREWING_STAND(), input, level);
return recipeHolder.map(RecipeHolder::value).orElse(null);
}
}
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.brewing;
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.BrewingStandMenu;
import net.minecraft.world.inventory.ContainerData;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(BrewingStandMenu.class)
public abstract class BrewingStandMenuMixin {
@Inject(method = "<init>(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/Container;Lnet/minecraft/world/inventory/ContainerData;)V", at = @At("TAIL"))
private void captureLevel(int containerId, Inventory playerInventory, Container brewingStandContainer, ContainerData brewingStandData, CallbackInfo ci) {
var recipeManager = playerInventory.player.level().getRecipeManager();
for (Slot slot : ((BrewingStandMenu) (Object) this).slots) {
if (slot instanceof RecipeAwareSlot awareSlot) {
awareSlot.setRecipeManager(recipeManager);
}
}
}
@WrapOperation(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/BrewingStandMenu$PotionSlot;mayPlaceItem(Lnet/minecraft/world/item/ItemStack;)Z"))
private boolean cobblemon$isPotionBottle(ItemStack stack, Operation<Boolean> original, @Local(argsOnly = true) Player player) {
return BrewingStandRecipe.Companion.isBottle(stack, player.level().getRecipeManager()) || original.call(stack);
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.brewing;
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
import net.minecraft.world.inventory.BrewingStandMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BrewingStandMenu.IngredientsSlot.class)
public class IngredientSlotMixin implements RecipeAwareSlot {
@Unique
private RecipeManager cobblemon$recipeManager;
@Override
public void setRecipeManager(RecipeManager recipeManager) {
this.cobblemon$recipeManager = recipeManager;
}
@Inject(
method = "mayPlace",
at = @At("HEAD"),
cancellable = true
)
private void cobblemon$mayPlace(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
if (BrewingStandRecipe.Companion.isInput(stack, cobblemon$recipeManager)) {
cir.setReturnValue(true);
}
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.brewing;
import com.cobblemon.mod.common.duck.RecipeAwareSlot;
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe;
import net.minecraft.world.inventory.BrewingStandMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BrewingStandMenu.PotionSlot.class)
public class PotionSlotMixin implements RecipeAwareSlot {
@Unique
private RecipeManager cobblemon$recipeManager;
@Override
public void setRecipeManager(RecipeManager recipeManager) {
this.cobblemon$recipeManager = recipeManager;
}
@Inject(
method = "mayPlace",
at = @At("HEAD"),
cancellable = true
)
private void cobblemon$mayPlace(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
if (BrewingStandRecipe.Companion.isBottle(stack, cobblemon$recipeManager)) {
cir.setReturnValue(true);
}
}
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.CobblemonRecipeCategories;
import com.cobblemon.mod.common.item.crafting.CookingPotBookCategory;
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe;
import com.cobblemon.mod.common.item.crafting.CookingPotRecipeBase;
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -19,7 +20,6 @@ import net.minecraft.client.ClientRecipeBook;
import net.minecraft.client.RecipeBookCategories;
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import org.spongepowered.asm.mixin.Mixin;
@@ -40,17 +40,17 @@ public abstract class ClientRecipeBookMixin {
return null;
}
@Shadow private Map<RecipeBookCategories, List<RecipeCollection>> collectionsByTab;
@Shadow
private Map<RecipeBookCategories, List<RecipeCollection>> collectionsByTab;
@Shadow private List<RecipeCollection> allCollections;
@Shadow
private List<RecipeCollection> allCollections;
@Inject(method = "getCategory", at = @At(value = "HEAD"), cancellable = true)
private static void addCustomCategory(RecipeHolder<?> recipe, CallbackInfoReturnable<RecipeBookCategories> cir) {
Recipe<?> recipe2 = recipe.value();
if (recipe2 instanceof CookingPotRecipe || recipe2 instanceof CookingPotShapelessRecipe) {
CookingPotBookCategory category = recipe2 instanceof CookingPotRecipe
? ((CookingPotRecipe) recipe2).getCategory()
: ((CookingPotShapelessRecipe) recipe2).category();
if (recipe2 instanceof CookingPotRecipeBase) {
CookingPotBookCategory category = ((CookingPotRecipeBase) recipe2).getCategory();
RecipeBookCategories var7;
switch (category) {
case MISC -> var7 = CobblemonRecipeCategories.COOKING_POT_MISC.toVanillaCategory();
@@ -76,8 +76,8 @@ public abstract class ClientRecipeBookMixin {
.collect(ImmutableList.toImmutableList());
map2.put(recipeBookCategories, collections);
});
RecipeBookCategories.AGGREGATE_CATEGORIES.forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List)list.stream().flatMap((recipeBookCategoriesx) -> ((List)map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
CobblemonRecipeCategories.Companion.getCustomAggregateCategories().forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List)list.stream().flatMap((recipeBookCategoriesx) -> ((List)map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
RecipeBookCategories.AGGREGATE_CATEGORIES.forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
CobblemonRecipeCategories.Companion.getCustomAggregateCategories().forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List) list.stream().flatMap((recipeBookCategoriesx) -> ((List) map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
this.collectionsByTab = ImmutableMap.copyOf(map2);
this.allCollections = builder.build();
@@ -9,22 +9,21 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.client.gui.ScrollingWidget;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.client.gui.components.AbstractSelectionList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(AbstractSelectionList.class)
public abstract class EntryListWidgetMixin {
@SuppressWarnings("ConstantValue")
@ModifyConstant(method = "getEntryAtPosition", constant = @Constant(intValue = 4))
public int cobblemon$adjustOnlyIfNecessary(int input) {
@ModifyExpressionValue(method = "getEntryAtPosition", at = @At(value = "CONSTANT", args = {"intValue=4"}))
public int cobblemon$adjustOnlyIfNecessary(int original) {
if(ScrollingWidget.class.isInstance(this)) {
return 0;
}
return input;
return original;
}
}
@@ -119,14 +119,12 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer implements O
public HitResult pick(double hitDistance, float partialTicks, boolean hitFluids) {
Entity vehicle = this.getVehicle();
if (vehicle instanceof PokemonEntity pokemonEntity) {
int seatIndex = pokemonEntity.getPassengers().indexOf(this);
Seat seat = pokemonEntity.getSeats().get(seatIndex);
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemonEntity.getDelegate();
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
String locatorName = delegate.getSeatLocator(this);
MatrixWrapper locator = delegate.getLocatorStates().get(locatorName);
if (locator == null) {
super.pick(hitDistance, partialTicks, hitFluids);
return super.pick(hitDistance, partialTicks, hitFluids);
}
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) {
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();
@@ -160,11 +158,11 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer implements O
}
@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();
if (cameraOffsets.containsKey(seat.getLocator())) {
return cameraOffsets.get(seat.getLocator()).toVector3f();
if (cameraOffsets.containsKey(locatorName)) {
return cameraOffsets.get(locatorName).toVector3f();
} else {
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(MouseHandler.class)
public abstract class MouseHandlerMixin {
@@ -121,11 +120,12 @@ public abstract class MouseHandlerMixin {
if (usageContext.getScanningGuiOpen()) {
this.smoothTurnY.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 lookSensitivity = spyglassSensitivity * 8.0;
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;
}
@@ -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();
}
}
@@ -63,13 +63,10 @@ import com.cobblemon.mod.common.api.storage.player.adapter.PlayerDataMongoBacken
import com.cobblemon.mod.common.api.storage.player.factory.CachedPlayerDataStoreFactory
import com.cobblemon.mod.common.api.tags.CobblemonEntityTypeTags
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.battles.BagItems
import com.cobblemon.mod.common.battles.BattleFormat
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.BattleSide
import com.cobblemon.mod.common.battles.ShowdownThread
import com.cobblemon.mod.common.battles.*
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.block.DispenserBehaviorRegistry
import com.cobblemon.mod.common.client.CobblemonPack
import com.cobblemon.mod.common.command.argument.*
import com.cobblemon.mod.common.config.CobblemonConfig
@@ -78,6 +75,7 @@ import com.cobblemon.mod.common.config.constraint.IntConstraint
import com.cobblemon.mod.common.config.starter.StarterConfig
import com.cobblemon.mod.common.data.CobblemonDataProvider
import com.cobblemon.mod.common.events.AdvancementHandler
import com.cobblemon.mod.common.events.EntityCallbackHandler
import com.cobblemon.mod.common.events.FlowHandler
import com.cobblemon.mod.common.events.PokedexHandler
import com.cobblemon.mod.common.events.ServerTickHandler
@@ -91,23 +89,11 @@ import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
import com.cobblemon.mod.common.pokemon.properties.AspectPropertyType
import com.cobblemon.mod.common.pokemon.properties.BattleCloneProperty
import com.cobblemon.mod.common.pokemon.properties.FreezeFrameProperty
import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
import com.cobblemon.mod.common.pokemon.properties.NoAIProperty
import com.cobblemon.mod.common.pokemon.properties.UnaspectPropertyType
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
import com.cobblemon.mod.common.pokemon.properties.*
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.ifDedicatedServer
import com.cobblemon.mod.common.util.isLaterVersion
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.requestWallpapers
import com.cobblemon.mod.common.util.server
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.world.feature.CobblemonPlacedFeatures
import com.cobblemon.mod.common.world.feature.ore.CobblemonOrePlacedFeatures
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
@@ -115,20 +101,8 @@ import com.mongodb.ConnectionString
import com.mongodb.MongoClientSettings
import com.mongodb.client.MongoClient
import com.mongodb.client.MongoClients
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.PrintWriter
import java.util.UUID
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
import kotlin.properties.Delegates
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField
import net.minecraft.client.Minecraft
import net.minecraft.commands.synchronization.SingletonArgumentInfo
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
@@ -139,6 +113,17 @@ import net.minecraft.world.level.Level
import net.minecraft.world.level.storage.LevelResource
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.PrintWriter
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
import kotlin.properties.Delegates
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField
object Cobblemon {
const val MODID = CobblemonBuildDetails.MOD_ID
@@ -213,6 +198,7 @@ object Cobblemon {
implementation.registerEntityDataSerializers()
implementation.registerCriteria()
implementation.registerEntitySubPredicates()
DispenserBehaviorRegistry.registerDispenserBehaviors()
DropEntry.register("command", CommandDropEntry::class.java)
DropEntry.register("item", ItemDropEntry::class.java, isDefault = true)
@@ -312,9 +298,6 @@ object Cobblemon {
SpeciesFeatures.types["flag"] = FlagSpeciesFeatureProvider::class.java
SpeciesFeatures.types["integer"] = IntSpeciesFeatureProvider::class.java
SpeciesFeatures.register(
DataKeys.CAN_BE_MILKED,
FlagSpeciesFeatureProvider(keys = listOf(DataKeys.CAN_BE_MILKED), default = true))
SpeciesFeatures.register(
DataKeys.HAS_BEEN_SHEARED,
FlagSpeciesFeatureProvider(keys = listOf(DataKeys.HAS_BEEN_SHEARED), default = false))
@@ -331,6 +314,7 @@ object Cobblemon {
CobblemonEvents.POKEMON_PROPERTY_INITIALISED.emit(Unit)
FlowHandler.setup()
EntityCallbackHandler.setup()
ifDedicatedServer {
isDedicatedServer = true
@@ -18,6 +18,8 @@ object CobblemonActivities {
val POKEMON_SLEEPING_ACTIVITY = register(Activity("pokemon_sleeping"))
val POKEMON_GROW_CROP = register(Activity("pokemon_grow_crop"))
val POKEMON_SLEEP_ON_TRAINER_BED = register(Activity("pokemon_sleep_on_trainer_bed"))
val POKEMON_HERD = register(Activity("pokemon_herd"))
val POKEMON_POLLINATION = register(Activity("pokemon_pollination"))
fun register(activity: Activity): Activity {
activities.add(activity)
@@ -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.ExpressionOrEntityVariableAdapter
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.MemoryModuleTypeAdapter
import com.cobblemon.mod.common.util.adapters.SensorTypeAdapter
import com.cobblemon.mod.common.util.adapters.TaskConfigAdapter
import com.cobblemon.mod.common.util.adapters.TranslatedTextAdapter
import com.cobblemon.mod.common.util.cobblemonResource
@@ -39,6 +41,8 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
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
object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
@@ -47,6 +51,8 @@ object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
.registerTypeAdapter(Activity::class.java, ActivityAdapter)
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(MemoryModuleType::class.java, MemoryModuleTypeAdapter)
.registerTypeAdapter(SensorType::class.java, SensorTypeAdapter)
.registerTypeAdapter(BehaviourConfig::class.java, BehaviourConfigAdapter)
.registerTypeAdapter(TaskConfig::class.java, TaskConfigAdapter)
.registerTypeAdapter(
@@ -72,6 +78,9 @@ object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
*/
val autoPokemonBehaviours = mutableListOf<CobblemonBehaviour>()
/** See [autoPokemonBehaviours] but think npc instead of pokemon*/
val autoNPCBehaviours = mutableListOf<CobblemonBehaviour>()
val behaviours = mutableMapOf<ResourceLocation, CobblemonBehaviour>()
override fun sync(player: ServerPlayer) {
@@ -88,6 +97,8 @@ object CobblemonBehaviours : JsonDataRegistry<CobblemonBehaviour> {
val behaviour = parse(reader, resolvedIdentifier)
if ("pokemon/auto/" in identifier.path) {
autoPokemonBehaviours.add(behaviour)
} else if ("npc/auto/" in identifier.path) {
autoNPCBehaviours.add(behaviour)
}
data[resolvedIdentifier] = behaviour
}
@@ -15,10 +15,14 @@ import com.cobblemon.mod.common.block.LecternBlock
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.block.campfirepot.CampfirePotBlock
import com.cobblemon.mod.common.block.chest.GildedChestBlock
import com.cobblemon.mod.common.block.general.BaleBlock
import com.cobblemon.mod.common.block.grower.SaccharineTreeGrower
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
import com.cobblemon.mod.common.block.general.HorizontalRotationCarpetBlock
import com.cobblemon.mod.common.block.general.HorizontalRotationalBlock
import com.cobblemon.mod.common.mixin.invoker.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.util.cobblemonResource
@@ -172,14 +176,14 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val SACCHARINE_LOG = this.create("saccharine_log", SaccharineLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
@JvmField
val SACCHARINE_HONEY_LOG = this.create("saccharine_honey_log", SaccharineHoneyLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
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
val STRIPPED_SACCHARINE_LOG = this.create("stripped_saccharine_log", SaccharineStrippedLogBlock(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")
@JvmField
val SACCHARINE_WOOD = log("saccharine_wood")
@JvmField
val STRIPPED_SACCHARINE_WOOD = this.create("stripped_saccharine_wood", SaccharineStrippedLogBlock(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_WOOD = this.create("stripped_saccharine_wood", RotatedPillarBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
@JvmField
val SACCHARINE_PLANKS = this.create("saccharine_planks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
@JvmField
@@ -201,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)))
@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)))
@JvmField
val SACCHARINE_BUTTON = this.create("saccharine_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
@JvmField
val SACCHARINE_PRESSURE_PLATE = this.create("saccharine_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).noCollission().strength(0.5f).sound(SoundType.WOOD)))
@@ -222,7 +226,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val SACCHARINE_TRAPDOOR = this.create("saccharine_trapdoor", TrapdoorBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(3.0F).sound(SoundType.WOOD).noOcclusion()))
@JvmField
val SACCHARINE_SAPLING = this.create("saccharine_sapling", SaccharineSaplingBlock(PLANT_PROPERTIES))
val SACCHARINE_SAPLING = this.create("saccharine_sapling", SaplingBlock(SaccharineTreeGrower(), PLANT_PROPERTIES))
@JvmField
val MEDICINAL_LEEK = this.create("medicinal_leek", MedicinalLeekBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.CRIMSON_NYLIUM).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MEDICINAL_LEEK_SOUNDS)))
@@ -446,7 +450,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val CAMPFIRE = create("campfire", CampfireBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOD).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.PODZOL).strength(2.0F).lightLevel { if ((it.getValue(CampfireBlock.SOUL) as Boolean)) 9 else 14 }))
@JvmField
val RELIC_COIN_POUCH = create("relic_coin_pouch", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS).pushReaction(PushReaction.DESTROY).noOcclusion(), true))
@JvmField
@@ -470,29 +474,29 @@ 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))
@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
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
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
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
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
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
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)))
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()))
@JvmField
val INCENSE_SWEET = create("incense_sweet", SweetIncenseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3f)))
@JvmField
val PASTURE = create("pasture", PastureBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BROWN).sound(SoundType.WOOD).strength(2F).noOcclusion().pushReaction(PushReaction.BLOCK).lightLevel { if ((it.getValue(PastureBlock.ON) as Boolean) && (it.getValue(PastureBlock.PART) == PastureBlock.PasturePart.TOP)) 10 else 0 }))
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)))
@JvmField
@@ -515,6 +519,9 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val HEARTY_GRAINS = this.create("hearty_grains", HeartyGrainsBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.PLANT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.VIVICHOKE_SOUNDS)))
@JvmField
val 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
val POTTED_RED_APRICORN_SAPLING = this.create("potted_red_apricorn_sapling", BlocksInvoker.createFlowerPotBlock(RED_APRICORN_SAPLING))
@JvmField
@@ -533,11 +540,11 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val POTTED_SACCHARINE_SAPLING = this.create("potted_saccharine_sapling", BlocksInvoker.createFlowerPotBlock(SACCHARINE_SAPLING))
@JvmField
val HEARTY_GRAIN_BALE = this.create("hearty_grain_bale", HeartyGrainBaleBlock(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
val TATAMI_BLOCK = this.create("tatami_block", TatamiBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).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
val TATAMI_MAT = this.create("tatami_mat", TatamiMatBlock(BlockBehaviour.Properties.of().ignitedByLava().mapColor(MapColor.PLANT).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.
@@ -549,11 +556,9 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
APRICORN_LOG to STRIPPED_APRICORN_LOG,
SACCHARINE_WOOD to STRIPPED_SACCHARINE_WOOD,
SACCHARINE_LOG to STRIPPED_SACCHARINE_LOG,
SACCHARINE_HONEY_LOG to STRIPPED_SACCHARINE_LOG
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 tumblestoneBlock(name: String, stage: Int, height: Int, xzOffset: Int, nextStage: Block?) : Block {
@@ -653,7 +658,19 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
Triple(APRICORN_FENCE, 5, 20),
Triple(APRICORN_FENCE_GATE, 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) }
}
@@ -93,6 +93,8 @@ object CobblemonFlows : DataRegistry {
functions: Map<String, (MoParams) -> Any> = emptyMap(),
cancelable: Cancelable? = null
) {
if (eventResourceLocation !in flows) return
if (cancelable == null) {
runtime.environment.query.functions.remove("cancel")
} else {
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.block.PotComponent
import com.cobblemon.mod.common.item.components.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.mojang.serialization.Codec
@@ -58,6 +58,7 @@ import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.HangingSignItem
import net.minecraft.world.item.Item
import net.minecraft.world.item.Item.Properties
import net.minecraft.world.item.ItemNameBlockItem
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.Rarity
@@ -191,22 +192,22 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val campfire_pots = mutableListOf<CampfirePotItem>()
@JvmField
val CAMPFIRE_POT_BLACK = campfirePotItem(CobblemonBlocks.BLACK_CAMPFIRE_POT, "black")
val CAMPFIRE_POT_RED = campfirePotItem(CobblemonBlocks.RED_CAMPFIRE_POT, "red")
@JvmField
val CAMPFIRE_POT_BLUE = campfirePotItem(CobblemonBlocks.BLUE_CAMPFIRE_POT, "blue")
val CAMPFIRE_POT_YELLOW = campfirePotItem(CobblemonBlocks.YELLOW_CAMPFIRE_POT, "yellow")
@JvmField
val CAMPFIRE_POT_GREEN = campfirePotItem(CobblemonBlocks.GREEN_CAMPFIRE_POT, "green")
@JvmField
val CAMPFIRE_POT_BLUE = campfirePotItem(CobblemonBlocks.BLUE_CAMPFIRE_POT, "blue")
@JvmField
val CAMPFIRE_POT_PINK = campfirePotItem(CobblemonBlocks.PINK_CAMPFIRE_POT, "pink")
@JvmField
val CAMPFIRE_POT_RED = campfirePotItem(CobblemonBlocks.RED_CAMPFIRE_POT, "red")
val CAMPFIRE_POT_BLACK = campfirePotItem(CobblemonBlocks.BLACK_CAMPFIRE_POT, "black")
@JvmField
val CAMPFIRE_POT_WHITE = campfirePotItem(CobblemonBlocks.WHITE_CAMPFIRE_POT, "white")
@JvmField
val CAMPFIRE_POT_YELLOW = campfirePotItem(CobblemonBlocks.YELLOW_CAMPFIRE_POT, "yellow")
@JvmField
val HEARTY_GRAINS = compostableItem("hearty_grains", HeartyGrainsItem(CobblemonBlocks.HEARTY_GRAINS))
val HEARTY_GRAINS = compostableItem("hearty_grains", ItemNameBlockItem(CobblemonBlocks.HEARTY_GRAINS, Properties().rarity(Rarity.COMMON)))
@JvmField
val HEARTY_GRAIN_BALE = compostableBlockItem("hearty_grain_bale", CobblemonBlocks.HEARTY_GRAIN_BALE, 0.85f)
@@ -216,10 +217,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val TATAMI_MAT = blockItem("tatami_mat", CobblemonBlocks.TATAMI_MAT)
@JvmField
val VIVICHOKE = compostableItem("vivichoke")
val VIVICHOKE = compostableItem("vivichoke", CobblemonItem(Item.Properties()), 0.80f)
@JvmField
val VIVICHOKE_SEEDS = compostableItem("vivichoke_seeds", VivichokeItem(CobblemonBlocks.VIVICHOKE_SEEDS))
val VIVICHOKE_SEEDS = compostableItem("vivichoke_seeds", VivichokeItem(CobblemonBlocks.VIVICHOKE_SEEDS), 0.30f)
@JvmField
val RED_APRICORN = apricornItem("red", ApricornItem(CobblemonBlocks.RED_APRICORN))
@@ -262,7 +263,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val APRICORN_PLANKS = blockItem("apricorn_planks", CobblemonBlocks.APRICORN_PLANKS)
@JvmField
val APRICORN_LEAVES = compostableBlockItem("apricorn_leaves", CobblemonBlocks.APRICORN_LEAVES)
val APRICORN_LEAVES = compostableBlockItem("apricorn_leaves", CobblemonBlocks.APRICORN_LEAVES, 0.30f)
@JvmField
val APRICORN_BOAT = create("apricorn_boat", CobblemonBoatItem(CobblemonBoatType.APRICORN, false, Item.Properties().stacksTo(1)))
@JvmField
@@ -309,7 +310,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SACCHARINE_LOG = blockItem("saccharine_log", CobblemonBlocks.SACCHARINE_LOG)
@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
val STRIPPED_SACCHARINE_LOG = blockItem("stripped_saccharine_log", CobblemonBlocks.STRIPPED_SACCHARINE_LOG)
@JvmField
@@ -319,7 +320,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SACCHARINE_PLANKS = blockItem("saccharine_planks", CobblemonBlocks.SACCHARINE_PLANKS)
@JvmField
val SACCHARINE_LEAVES = compostableBlockItem("saccharine_leaves", CobblemonBlocks.SACCHARINE_LEAVES)
val SACCHARINE_LEAVES = compostableBlockItem("saccharine_leaves", CobblemonBlocks.SACCHARINE_LEAVES, 0.35f)
@JvmField
val SACCHARINE_BOAT = create("saccharine_boat", CobblemonBoatItem(CobblemonBoatType.SACCHARINE, false, Item.Properties().stacksTo(1)))
@JvmField
@@ -346,10 +347,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", HangingSignItem(CobblemonBlocks.SACCHARINE_HANGING_SIGN, CobblemonBlocks.SACCHARINE_WALL_HANGING_SIGN, Item.Properties().stacksTo(16)))
@JvmField
val SACCHARINE_SAPLING = saccharineSaplingItem("saccharine_sapling", SaccharineSaplingItem(CobblemonBlocks.SACCHARINE_SAPLING))
val SACCHARINE_SAPLING = compostableBlockItem("saccharine_sapling", CobblemonBlocks.SACCHARINE_SAPLING, 0.30f)
@JvmField
val BUGWORT = bugwortItem("bugwort", BugwortItem(CobblemonBlocks.BUGWORT))
val BUGWORT = compostableBlockItem("bugwort", CobblemonBlocks.BUGWORT)
@JvmField
val POKE_BAIT = noSettingsItem("poke_bait")
@@ -388,40 +389,28 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val SWEET_HEART = noSettingsItem("sweet_heart") // todo make a SweetHeartItem class for breeding purposes
@JvmField
val TASTY_TAIL = noSettingsItem("tasty_tail")
val TASTY_TAIL = create("tasty_tail", foodItem(3, 0.3f))
@JvmField // todo get final values for this from vera
val PEWTER_CRUNCHIES = regionalFoodItem("pewter_crunchies", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f, false)
@JvmField // todo get final values for this from vera
val RAGE_CANDY_BAR = regionalFoodItem("rage_candy_bar", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f, false)
@JvmField // todo get final values for this from vera
val LAVA_COOKIE = regionalFoodItem("lava_cookie", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
@JvmField // todo get final values for this from vera
val OLD_GATEAU = regionalFoodItem("old_gateau", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
@JvmField // todo get final values for this from vera
val CASTELIACONE = regionalFoodItem("casteliacone", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
@JvmField // todo get final values for this from vera
val SHALOUR_SABLE = regionalFoodItem("shalour_sable", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
@JvmField // todo get final values for this from vera
val LUMIOSE_GALETTE = regionalFoodItem("lumiose_galette", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
@JvmField // todo get final values for this from vera
val BIG_MALASADA = regionalFoodItem("big_malasada", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
@JvmField // todo get final values for this from vera
val SMOKED_TAIL_CURRY = regionalFoodItem("smoked_tail_curry", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f, false, ItemStack(Items.BOWL, 1))
@JvmField // todo get final values for this from vera
val JUBILIFE_MUFFIN = regionalFoodItem("jubilife_muffin", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
@JvmField // todo get final values for this from vera
val OPEN_FACED_SANDWICH = regionalFoodItem("open_faced_sandwich", 16, 10, 1.2f, MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1f)
@JvmField
val PEWTER_CRUNCHIES = regionalFoodItem("pewter_crunchies", 16, 7, 0.343f, false)
@JvmField
val RAGE_CANDY_BAR = regionalFoodItem("rage_candy_bar", 16, 8, 0.2f, false)
@JvmField
val LAVA_COOKIE = regionalFoodItem("lava_cookie", 16, 7, 0.343f, false)
@JvmField
val OLD_GATEAU = regionalFoodItem("old_gateau", 16, 9, 0.1335f, false)
@JvmField
val CASTELIACONE = regionalFoodItem("casteliacone", 16, 5, .28f, false)
@JvmField
val LUMIOSE_GALETTE = regionalFoodItem("lumiose_galette", 16, 8, 0.2f, false)
@JvmField
val BIG_MALASADA = regionalFoodItem("big_malasada", 16, 7, 0.343f, false)
@JvmField
val SMOKED_TAIL_CURRY = regionalFoodItem("smoked_tail_curry", 16, 10, 0.6f, false, ItemStack(Items.BOWL, 1))
@JvmField
val JUBILIFE_MUFFIN = regionalFoodItem("jubilife_muffin", 16, 8, 0.2f, false)
@JvmField
val OPEN_FACED_SANDWICH = regionalFoodItem("open_faced_sandwich", 16, 13, 0.5f, false)
// todo we might need to wait on these for later? These impact battles and may be harder to do
/*@JvmField
@@ -432,33 +421,25 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val TWICE_SPICED_BEETROOT = noSettingsItem("twice_spiced_beetroot") // todo make a TwiceSpiceBeetrootItem class for battle purposes
*/
@JvmField
val POTATO_MOCHI = create("potato_mochi", object : Item(Properties().stacksTo(16)
val POTATO_MOCHI = create("potato_mochi", CobblemonItem(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10) // todo get final values for this from vera
.saturationModifier(1.2F) // todo get final values for this from vera
.alwaysEdible()
.build())) {})
.nutrition(8)
.saturationModifier(0.2375F)
.build())))
@JvmField
val FRIED_RICE = create("fried_rice", object : Item(Properties().stacksTo(16)
val CANDIED_APPLE = create("candied_apple", CobblemonItem(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10) // todo get final values for this from vera
.saturationModifier(1.2F) // todo get final values for this from vera
.alwaysEdible()
.build())) {})
.nutrition(6)
.saturationModifier(0.2335F)
.usingConvertsTo(Items.STICK)
.build())))
@JvmField
val CANDIED_APPLE = create("candied_apple", object : Item(Properties().stacksTo(16)
val CANDIED_BERRY = create("candied_berry", CobblemonItem(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10) // todo get final values for this from vera
.saturationModifier(1.2F) // todo get final values for this from vera
.alwaysEdible()
.build())) {})
@JvmField
val CANDIED_BERRY = create("candied_berry", object : Item(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10) // todo get final values for this from vera
.saturationModifier(1.2F) // todo get final values for this from vera
.alwaysEdible()
.build())) {})
.nutrition(5)
.saturationModifier(0.22F)
.usingConvertsTo(Items.STICK)
.build())))
//@JvmField
//val SCATTER_BANG = this.create("scatter_bang", ScatterBangItem(Item.Settings()))
@@ -510,9 +491,9 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField val CRACKED_POT = noSettingsItem("cracked_pot")
@JvmField val MASTERPIECE_TEACUP = noSettingsItem("masterpiece_teacup")
@JvmField val UNREMARKABLE_TEACUP = noSettingsItem("unremarkable_teacup")
@JvmField val SWEET_APPLE = create("sweet_apple", foodItem(4, 0.3f))
@JvmField val TART_APPLE = create("tart_apple", foodItem(4, 0.3f))
@JvmField val SYRUPY_APPLE = create("syrupy_apple", foodItem(4, 0.3f))
@JvmField val SWEET_APPLE = compostableItem("sweet_apple", foodItem(4, 0.3f), 0.65f)
@JvmField val TART_APPLE = compostableItem("tart_apple", foodItem(4, 0.3f), 0.65f)
@JvmField val SYRUPY_APPLE = compostableItem("syrupy_apple", foodItem(4, 0.3f), 0.65f)
@JvmField val GALARICA_CUFF = noSettingsItem("galarica_cuff")
@JvmField val GALARICA_WREATH = noSettingsItem("galarica_wreath")
@JvmField val BLACK_AUGURITE = noSettingsItem("black_augurite")
@@ -601,7 +582,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField val BERRY_JUICE = this.create("berry_juice", BerryJuiceItem())
@JvmField
val GALARICA_NUTS = create("galarica_nuts", GalaricaNutItem())
val GALARICA_NUTS = compostableItemNameBlockItem("galarica_nuts", CobblemonBlocks.GALARICA_NUT_BUSH)
// Hyper Training Items
val hyperTrainingItems = mutableListOf<HyperTrainingItem>()
@@ -684,14 +665,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val MEDICINAL_LEEK = heldItem("medicinal_leek", MedicinalLeekItem(CobblemonBlocks.MEDICINAL_LEEK, Item.Properties().food(FoodProperties.Builder().fast().nutrition(1).saturationModifier(0.2f).build())), "leek")
@JvmField
val ROASTED_LEEK = create("roasted_leek", Item(Item.Properties().food(FoodProperties.Builder().fast().nutrition(3).saturationModifier(0.3f).build())))
val ROASTED_LEEK = compostableItem("roasted_leek", CobblemonItem(Item.Properties().food(FoodProperties.Builder().fast().nutrition(3).saturationModifier(0.2f).build())), 0.85f)
@JvmField
val BRAISED_VIVICHOKE = create("braised_vivichoke", Item(Item.Properties().food(FoodProperties.Builder().nutrition(6).saturationModifier(0.6f).build())))
@JvmField
val VIVICHOKE_DIP = create("vivichoke_dip", object : Item(Properties().stacksTo(1)
val VIVICHOKE_DIP = create("vivichoke_dip", object : CobblemonItem(Properties().stacksTo(1)
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.saturationModifier(0.6F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.usingConvertsTo(Items.BOWL)
@@ -702,21 +681,21 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
}
})
@JvmField
val ENERGY_ROOT = compostableItem("energy_root", EnergyRootItem(CobblemonBlocks.ENERGY_ROOT, Item.Properties().food(FoodProperties.Builder().nutrition(1).fast().saturationModifier(0.2f).build())))
val ENERGY_ROOT = compostableItem("energy_root", EnergyRootItem(CobblemonBlocks.ENERGY_ROOT, Properties()), 0.60f)
@JvmField
val REVIVAL_HERB = compostableItem("revival_herb", RevivalHerbItem(CobblemonBlocks.REVIVAL_HERB))
@JvmField
val PEP_UP_FLOWER = compostableBlockItem("pep_up_flower", CobblemonBlocks.PEP_UP_FLOWER)
@JvmField
val MEDICINAL_BREW = create("medicinal_brew", Item(Item.Properties()))
val MEDICINAL_BREW = noSettingsItem("medicinal_brew")
@JvmField
val REMEDY = create("remedy", RemedyItem(RemedyItem.NORMAL))
val REMEDY = compostableItem("remedy", RemedyItem(RemedyItem.NORMAL), 0.65f)
@JvmField
val FINE_REMEDY = create("fine_remedy", RemedyItem(RemedyItem.FINE))
val FINE_REMEDY = compostableItem("fine_remedy", RemedyItem(RemedyItem.FINE), 0.75f)
@JvmField
val SUPERB_REMEDY = create("superb_remedy", RemedyItem(RemedyItem.SUPERB))
val SUPERB_REMEDY = compostableItem("superb_remedy", RemedyItem(RemedyItem.SUPERB), 0.85f)
@JvmField
val MOOMOO_MILK = create("moomoo_milk", Item(Item.Properties()))
val MOOMOO_MILK = noSettingsItem("moomoo_milk")
@JvmField
val POTION = create("potion", PotionItem(PotionType.POTION))
@@ -732,7 +711,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val HEAL_POWDER = create("heal_powder", HealPowderItem())
@JvmField
val LEEK_AND_POTATO_STEW = create("leek_and_potato_stew", Item(Item.Properties().food(FoodProperties.Builder().nutrition(8).saturationModifier(0.6f).usingConvertsTo(Items.BOWL).build()).stacksTo(1)))
val LEEK_AND_POTATO_STEW = create("leek_and_potato_stew", CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(6).saturationModifier(0.6f).usingConvertsTo(Items.BOWL).build()).stacksTo(1)))
@JvmField
val REVIVE = create("revive", ReviveItem(max = false))
@JvmField
@@ -934,7 +913,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val ASSAULT_VEST = heldItem("assault_vest")
@JvmField
val BIG_ROOT = blockItem("big_root", CobblemonBlocks.BIG_ROOT)
val BIG_ROOT = compostableBlockItem("big_root", CobblemonBlocks.BIG_ROOT, 0.40f)
@JvmField
val BINDING_BAND = heldItem("binding_band")
@JvmField
@@ -992,7 +971,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val LAGGING_TAIL = heldItem("lagging_tail")
@JvmField
val LEFTOVERS = heldItem("leftovers")
val LEFTOVERS = compostableHeldItem("leftovers", null, 0.50f)
@JvmField
val LIFE_ORB = heldItem("life_orb")
@JvmField
@@ -1479,6 +1458,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
private fun blockItem(name: String, block: Block, rarity: Rarity = Rarity.COMMON): BlockItem = this.create(name, BlockItem(block, Item.Properties().rarity(rarity)))
private fun itemNameBlockItem(name: String, block: Block, rarity: Rarity = Rarity.COMMON): ItemNameBlockItem = this.create(name, ItemNameBlockItem(block, Item.Properties().rarity(rarity)))
private fun noSettingsItem(name: String): CobblemonItem = this.create(name, CobblemonItem(Item.Properties()))
private fun itemWithRarity(name: String, rarity: Rarity): CobblemonItem = this.create(name, CobblemonItem(Item.Properties().rarity(rarity)))
@@ -1541,8 +1522,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
stacksTo: Int,
nutrition: Int,
saturationModifier: Float,
effect: MobEffectInstance? = null,
effectChance: Float? = null,
alwaysEdible: Boolean = false,
convertsToOnUse: ItemStack? = null
): RegionalFoodItem {
@@ -1550,10 +1529,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
.nutrition(nutrition)
.saturationModifier(saturationModifier)
if (effect != null && effectChance != null) {
foodPropertiesBuilder.effect(effect, effectChance)
}
if (alwaysEdible == true) {
foodPropertiesBuilder.alwaysEdible()
}
@@ -1580,11 +1555,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
private fun heldItem(name: String, item: Item, remappedName: String? = null) = create(
name = name,
entry = item.also {
if (remappedName != null) {
remappedName?.let { remappedName ->
CobblemonHeldItemManager.registerRemap(it, remappedName)
CobblemonHeldItemManager.registerRemap(Items.BONE, "thickclub")
CobblemonHeldItemManager.registerRemap(Items.SNOWBALL, "snowball")
CobblemonHeldItemManager.registerRemap(Items.GOLD_BLOCK, "bignugget")
}
}
)
@@ -1610,7 +1582,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
private fun mintItem(name: String, mintItem: MintItem): MintItem {
val item = this.create(name, mintItem)
mints[item.nature.displayName] = item
compostable(item, .65f)
compostable(item, .95f)
return item
}
@@ -1630,21 +1602,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
private fun apricornSeedItem(name: String, apricornSeedItem: ApricornSeedItem): ApricornSeedItem {
val finalName = "${name}_apricorn_seed"
val item = this.create(finalName, apricornSeedItem)
compostable(item, .65f)
return item
}
private fun saccharineSaplingItem(name: String, saccharineSaplingItem: SaccharineSaplingItem): SaccharineSaplingItem {
val finalName = "saccharine_sapling"
val item = this.create(finalName, saccharineSaplingItem)
compostable(item, .65f)
return item
}
private fun bugwortItem(name: String, bugwortItem: BugwortItem): BugwortItem {
val finalName = "bugwort"
val item = this.create(finalName, bugwortItem)
compostable(item, .65f)
compostable(item, .30f)
return item
}
@@ -1652,19 +1610,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
private fun mintSeed(name: String, mintBlock: MintBlock): Item {
val finalName = "${name}_mint_seeds"
val item = this.blockItem(finalName, mintBlock)
compostable(item, .65f)
compostable(item, .30f)
return item
}
private fun mintLeaf(name: String, mintLeafItem: MintLeafItem): MintLeafItem {
val finalName = "${name}_mint_leaf"
val item = this.create(finalName, mintLeafItem)
compostable(item, .65f)
compostable(item, .50f)
return item
}
private fun compostableItem(name: String, item: Item? = null, increaseLevelChance: Float = .65f): Item {
val createdItem = this.create(name, item ?: Item(Item.Properties()))
val createdItem = this.create(name, item ?: CobblemonItem(Item.Properties()))
compostable(createdItem, increaseLevelChance)
return createdItem
}
@@ -1675,13 +1633,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
return createdItem
}
private fun compostableBlockItem(name: String, block: Block, increaseLevelChance: Float = .65f): Item {
private fun compostableBlockItem(name: String, block: Block, increaseLevelChance: Float = .85f): Item {
val createdItem = this.blockItem(name, block)
compostable(createdItem, increaseLevelChance)
return createdItem
}
private fun compostableItemNameBlockItem(name: String, block: Block, increaseLevelChance: Float = .30f): Item {
val createdItem = this.itemNameBlockItem(name, block)
compostable(createdItem, increaseLevelChance)
return createdItem
}
private fun foodItem(nutrition: Int, saturationModifier: Float): Item {
return Item(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
return CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
}
}
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.ai.CobblemonAttackTargetData
import com.cobblemon.mod.common.api.ai.CobblemonWanderControl
import com.cobblemon.mod.common.api.dialogue.ActiveDialogue
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.mojang.serialization.Codec
@@ -42,6 +44,16 @@ object CobblemonMemories {
val NEAREST_VISIBLE_ATTACKER = register<LivingEntity>("nearest_visible_attacker")
val NEARBY_GROWABLE_CROPS = register<BlockPos>("nearby_growable_crops")
val RECENTLY_ATE_GRASS = register<Boolean>("recently_ate_grass")
val HIVE_LOCATION = register<BlockPos>("hive_location")
val HIVE_COOLDOWN = register<Boolean>("hive_cooldown")
val NEARBY_FLOWERS = register<List<BlockPos>>("nearby_flower")
val POLLINATED = register<Boolean>("pollinated", PrimitiveCodec.BOOL)
/** who am i following rn? */
val HERD_LEADER = register<String>("herd_leader", PrimitiveCodec.STRING)
/** 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 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.
val WANDER_CONTROL = register<CobblemonWanderControl>("wander_control")
fun <U> register(id: String, codec: Codec<U>): MemoryModuleType<U> {
val memoryModule = MemoryModuleType(Optional.of(codec))
@@ -10,9 +10,7 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.block.campfirepot.CookingPotMenu
import com.cobblemon.mod.common.client.gui.cookingpot.CookingPotScreen
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.client.gui.screens.MenuScreens
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
@@ -24,6 +24,7 @@ import com.cobblemon.mod.common.client.net.data.UnlockReloadPacketHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueClosedHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueOpenedHandler
import com.cobblemon.mod.common.client.net.effect.RunPosableMoLangHandler
import com.cobblemon.mod.common.client.net.effect.SaccharineLogBlockParticlesHandler
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormEntityParticleHandler
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormParticleHandler
import com.cobblemon.mod.common.client.net.gui.InteractPokemonUIPacketHandler
@@ -36,6 +37,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.PokemonPasturedHandler
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.pokemon.update.ClientboundUpdateRidingStateHandler
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
@@ -76,6 +78,7 @@ import com.cobblemon.mod.common.net.messages.client.data.*
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueClosedPacket
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
import com.cobblemon.mod.common.net.messages.client.effect.SaccharineLogBlockParticlesPacket
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
import com.cobblemon.mod.common.net.messages.client.npc.CloseNPCEditorPacket
@@ -85,6 +88,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.PokemonPasturedPacket
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.pokemon.update.*
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.AddEvolutionPacket
@@ -140,6 +144,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.RemoveSpectatorPacket
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.block.AdjustBlockEntityViewerCountPacket
import com.cobblemon.mod.common.net.messages.server.callback.move.MoveSelectCancelledPacket
@@ -155,6 +160,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.orientation.ServerboundUpdateOrientationPacket
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.UnpasturePokemonPacket
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.FinishScanningPacket
@@ -166,6 +172,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.ServerboundUpdateRidingStatePacket
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.storage.SwapPCPartyPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokemonPacket
@@ -187,6 +194,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.TeamRequestHandler
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.block.AdjustBlockEntityViewerCountHandler
import com.cobblemon.mod.common.net.serverhandling.callback.move.MoveSelectCancelledHandler
@@ -203,6 +211,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.orientation.OrientationPacketHandler
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.UnpasturePokemonHandler
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.FinishScanningHandler
@@ -213,6 +222,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.SetMarkingsHandler
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.SelectStarterPacketHandler
import com.cobblemon.mod.common.net.serverhandling.storage.BenchMoveHandler
@@ -394,6 +404,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler))
list.add(PacketRegisterInfo(SpawnSnowstormEntityParticlePacket.ID, SpawnSnowstormEntityParticlePacket::decode, SpawnSnowstormEntityParticleHandler))
list.add(PacketRegisterInfo(RunPosableMoLangPacket.ID, RunPosableMoLangPacket::decode, RunPosableMoLangHandler))
list.add(PacketRegisterInfo(SaccharineLogBlockParticlesPacket.ID, SaccharineLogBlockParticlesPacket::decode, SaccharineLogBlockParticlesHandler))
// Hax
list.add(PacketRegisterInfo(UnvalidatedPlaySoundS2CPacket.ID, UnvalidatedPlaySoundS2CPacket::decode, UnvalidatedPlaySoundS2CPacketHandler))
@@ -418,6 +429,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(ClosePasturePacket.ID, ClosePasturePacket::decode, ClosePastureHandler))
list.add(PacketRegisterInfo(PokemonPasturedPacket.ID, PokemonPasturedPacket::decode, PokemonPasturedHandler))
list.add(PacketRegisterInfo(PokemonUnpasturedPacket.ID, PokemonUnpasturedPacket::decode, PokemonUnpasturedHandler))
list.add(PacketRegisterInfo(UpdatePastureConflictFlagPacket.ID, UpdatePastureConflictFlagPacket::decode, UpdatePastureConflictFlagHandler))
// Orientation
list.add(PacketRegisterInfo(ClientboundUpdateOrientationPacket.ID, ClientboundUpdateOrientationPacket::decode, S2CUpdateOrientationHandler))
@@ -528,6 +540,8 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(PasturePokemonPacket.ID, PasturePokemonPacket::decode, PasturePokemonHandler))
list.add(PacketRegisterInfo(UnpasturePokemonPacket.ID, UnpasturePokemonPacket::decode, UnpasturePokemonHandler))
list.add(PacketRegisterInfo(UnpastureAllPokemonPacket.ID, UnpastureAllPokemonPacket::decode, UnpastureAllPokemonHandler))
list.add(PacketRegisterInfo(SetPastureConflictPacket.ID, SetPastureConflictPacket::decode, SetPastureConflictHandler))
// Block entity
list.add(PacketRegisterInfo(AdjustBlockEntityViewerCountPacket.ID, AdjustBlockEntityViewerCountPacket::decode, AdjustBlockEntityViewerCountHandler))
@@ -556,12 +570,14 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatePacket.ID, ServerboundUpdateRidingStatePacket::decode, ServerboundUpdateRidingStateHandler))
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatsPacket.ID, ServerboundUpdateRidingStatsPacket::decode, ServerboundUpdateRidingStatsHandler))
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatRangePacket.ID, ServerboundUpdateRidingStatRangePacket::decode, ServerboundUpdateRidingStatRangeHandler))
list.add(PacketRegisterInfo(DismountPokemonPacket.ID, DismountPokemonPacket::decode, DismountPokemonPacketHandler))
// Cooking
list.add(PacketRegisterInfo(ToggleCookingPotLidPacket.ID, ToggleCookingPotLidPacket::decode, ToggleCookingPotLidHandler))
// Behaviour Packets
list.add(PacketRegisterInfo(SetEntityBehaviourPacket.ID, SetEntityBehaviourPacket::decode, SetEntityBehaviourHandler))
list.add(PacketRegisterInfo(DamageOnCollisionPacket.ID, DamageOnCollisionPacket::decode, DamageOnCollisionPacketHandler))
return list
}
@@ -24,23 +24,18 @@ object CobblemonPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Regist
override val resourceKey: ResourceKey<Registry<PoiType>> = Registries.POINT_OF_INTEREST_TYPE
@JvmField
val NURSE_KEY: ResourceKey<PoiType> = createKey("nurse")
val NURSE_KEY = createKey("nurse", CobblemonBlocks.HEALING_MACHINE, 1, 1)
@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
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
val LURE_CAKE = create(LURE_CAKE_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.LURE_CAKE), 0, 1))
@JvmField
val SACCHARINE_HONEY_LOG_KEY: ResourceKey<PoiType> = createKey("saccharine_honey_log")
@JvmField
val SACCHARINE_HONEY_LOG = create(SACCHARINE_HONEY_LOG_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.SACCHARINE_HONEY_LOG), 0, 1))
@JvmField
val INCENSE_SWEET_KEY: ResourceKey<PoiType> = createKey("incense_sweet")
@JvmField
val INCENSE_SWEET = create(INCENSE_SWEET_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.INCENSE_SWEET), 0, 1))
val INCENSE_SWEET_KEY = createKey("incense_sweet", 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)
}
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
@@ -24,6 +25,8 @@ object CobblemonRecipeSerializers : PlatformRegistry<Registry<RecipeSerializer<*
val COOKING_POT_COOKING: RecipeSerializer<*> = register("cobblemon:cooking_pot", CookingPotRecipe.Serializer())
val COOKING_POT_SHAPELESS: RecipeSerializer<*> = register("cobblemon:cooking_pot_shapeless", CookingPotShapelessRecipe.Serializer())
val BREWING_STAND: RecipeSerializer<*> = register("cobblemon:brewing_stand", BrewingStandRecipe.Serializer())
override val registry: Registry<RecipeSerializer<*>>
get() = BuiltInRegistries.RECIPE_SERIALIZER
override val resourceKey: ResourceKey<Registry<RecipeSerializer<*>>>
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
import com.cobblemon.mod.common.item.crafting.brewingstand.BrewingStandRecipe
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
@@ -24,6 +25,8 @@ object CobblemonRecipeTypes : PlatformRegistry<Registry<RecipeType<*>>, Resource
val COOKING_POT_COOKING: RecipeType<CookingPotRecipe> = register("cobblemon:cooking_pot")
val COOKING_POT_SHAPELESS: RecipeType<CookingPotShapelessRecipe> = register("cobblemon:cooking_pot_shapeless")
val BREWING_STAND: RecipeType<BrewingStandRecipe> = register("cobblemon:brewing_stand")
override val registry: Registry<RecipeType<*>>
get() = BuiltInRegistries.RECIPE_TYPE
override val resourceKey: ResourceKey<Registry<RecipeType<*>>>
@@ -8,10 +8,7 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.DefendOwnerSensor
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.DrowsySensor
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.PokemonAdultSensor
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.PokemonGrowableCropSensor
import com.cobblemon.mod.common.entity.pokemon.ai.sensors.*
import com.cobblemon.mod.common.pokemon.ai.PokemonDisturbancesSensor
import com.cobblemon.mod.common.entity.sensor.BattlingPokemonSensor
import com.cobblemon.mod.common.entity.sensor.NPCBattlingSensor
@@ -36,6 +33,10 @@ object CobblemonSensors {
val NEARBY_GROWABLE_CROPS = register("nearby_growable_crops", ::PokemonGrowableCropSensor)
val NEARBY_BEE_HIVE = register("nearby_bee_hive", ::BeeHiveSensor)
val NEARBY_FLOWER = register("nearby_flower", ::FlowerSensor)
fun <E : Entity, U : Sensor<E>> register(id: String, supplier: Supplier<U>): SensorType<U> {
val sensor = SensorType(supplier)
sensors[id] = sensor
@@ -275,6 +275,11 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
RELIC_COIN_SACK_STEP
)
@JvmField
val RIDE_LOOP_LEATHER = create("ride.loop.leather")
@JvmField
val RIDE_LOOP_PLUMAGE = create("ride.loop.plumage")
@JvmField
val MOVE_QUICKATTACK_TARGET = this.create("move.quickattack.target")
@JvmField
@@ -319,6 +324,8 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
@JvmField
val IMPACT_WATER = this.create("impact.water")
@JvmField
val TUMBLESTONE_SOUNDS = SoundType(1f, 1.1f,
TUMBLESTONE_BREAK,
@@ -8,10 +8,20 @@
package com.cobblemon.mod.common.api.ai
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.ai.config.BehaviourConfig
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.serialization.Dynamic
import net.minecraft.resources.ResourceLocation
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.Schedule
@@ -22,13 +32,41 @@ class BehaviourConfigurationContext {
var coreActivities = setOf(Activity.CORE)
val activities = mutableListOf<ActivityConfigurationContext>()
val schedule = Schedule.EMPTY
val memories = mutableSetOf<MemoryModuleType<*>>()
val sensors = mutableSetOf<SensorType<*>>()
val onAddScripts = mutableListOf<ResourceLocation>()
val onAdd = mutableListOf<ExpressionLike>()
fun getOrCreateActivity(activity: Activity): ActivityConfigurationContext {
return activities.firstOrNull { it.activity == activity } ?: ActivityConfigurationContext(activity).also(activities::add)
}
fun apply(entity: LivingEntity, behaviourConfigs: List<BehaviourConfig>) {
val brain = entity.brain
fun addMemories(vararg memory: MemoryModuleType<*>) {
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 addOnAddScript(script: ResourceLocation) {
onAddScripts.add(script)
}
fun addOnAddScript(script: ExpressionLike) {
onAdd.add(script)
}
fun apply(entity: LivingEntity, behaviourConfigs: List<BehaviourConfig>, dynamic: Dynamic<*>) {
if (entity is MoLangScriptingEntity) {
entity.registerVariables(behaviourConfigs.flatMap { it.getVariables(entity) })
@@ -38,7 +76,16 @@ class BehaviourConfigurationContext {
// Setup the brain config
behaviourConfigs.forEach { it.configure(entity, this) }
var brain = entity.brain
// Apply the brain config
if (entity is MoLangScriptingEntity) {
brain = entity.assignNewBrainWithMemoriesAndSensors(dynamic, memories, sensors)
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
onAddScripts.forEach { CobblemonScripts.run(it, runtime) }
onAdd.forEach { runtime.resolve(it) }
}
activities.forEach { it.apply(entity) }
brain.setCoreActivities(coreActivities)
brain.setDefaultActivity(defaultActivity)
@@ -0,0 +1,71 @@
/*
* 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.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.resolve
import net.minecraft.world.entity.Entity
/**
* 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. */
var shouldContinue: Expression = "true".asExpression(),
var hitsUntilDisengage: Int = -1, // -1 means no limit
var disengageAction: (entity: Entity) -> Unit = {}
) {
val struct = ObjectValue<CobblemonAttackTargetData>(this).also {
it.addFunction("hits_until_disengage") { DoubleValue(hitsUntilDisengage.toDouble()) }
it.addFunction("set_hits_until_disengage") { params ->
val value = params.getDouble(0)
hitsUntilDisengage = value.toInt()
DoubleValue(hitsUntilDisengage.toDouble())
}
it.addFunction("set_disengage_action") { params ->
val script = params.getString(0).asIdentifierDefaultingNamespace()
val function = CobblemonScripts.scripts[script] ?: run {
Cobblemon.LOGGER.warn("set_disengage_action was given script '$script' which does not exist.")
return@addFunction DoubleValue.ZERO
}
disengageAction = { entity ->
val runtime = MoLangRuntime().setup()
runtime.environment.query.addFunction("entity") { entity.asMostSpecificMoLangValue() }
runtime.resolve(function)
}
DoubleValue.ONE
}
it.addFunction("unset_disengage_action") { params ->
disengageAction = {}
}
}
}
@@ -17,6 +17,7 @@ import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.util.asTranslated
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.withQueryValue
import com.google.gson.annotations.SerializedName
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.LivingEntity
@@ -28,23 +29,35 @@ class CobblemonBehaviour(
val visible: Boolean = true,
val entityType: ResourceLocation? = null,
val configurations: List<BehaviourConfig> = mutableListOf(),
val undo: ExpressionLike? = null,
val undoScript: ResourceLocation? = null,
// I feel like the onAdd+onAddScript etc could be merged using some interface and a clever deserializer,
// detect if it's a ResourceLocation and failing that, Expression. The on[..]Script fields are kinda fringe though.
@SerializedName("onRemove", alternate = ["undo"])
val onRemove: ExpressionLike? = null,
@SerializedName("onRemoveScript", alternate = ["undoScript"])
val onRemoveScript: ResourceLocation? = null,
val onAdd: ExpressionLike? = null,
val onAddScript: ResourceLocation? = null,
) {
fun canBeApplied(entity: LivingEntity) = entityType?.let { entityType == entity.type.builtInRegistryHolder().unwrapKey().get().location() } != false
fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (onAdd != null) {
behaviourConfigurationContext.addOnAddScript(onAdd)
}
if (onAddScript != null) {
behaviourConfigurationContext.addOnAddScript(onAddScript)
}
configurations.forEach { it.configure(entity, behaviourConfigurationContext) }
}
/** Undoes anything that needs undoing once this configuration is being removed from an entity that had it before. */
fun undo(entity: LivingEntity) {
fun onRemove(entity: LivingEntity) {
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (undoScript != null) {
CobblemonScripts.run(undoScript, runtime)
if (onRemoveScript != null) {
CobblemonScripts.run(onRemoveScript, runtime)
}
if (undo != null) {
runtime.resolve(undo)
if (onRemove != null) {
runtime.resolve(onRemove)
}
}
}
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
import net.minecraft.world.phys.Vec3
/**
* Wraps around [BlockPosTracker] to add additional flags for Cobblemon-specific behavior.
*
* @author Hiroku
* @since August 4th, 2025
*/
class CobblemonBlockPosTracker(
pos: Vec3,
val flags: Set<String> = emptySet(),
) : BlockPosTracker(pos) {
companion object {
const val BATTLE_LOOK_BYPASS_FLAG = "battle_look_bypass"
}
fun isBattleLookBypass() = flags.contains(BATTLE_LOOK_BYPASS_FLAG)
}
@@ -0,0 +1,91 @@
/*
* 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.runtime.struct.QueryStruct
import com.cobblemon.mod.common.util.getBooleanOrNull
import com.cobblemon.mod.common.util.getDoubleOrNull
import kotlin.math.sqrt
import net.minecraft.core.BlockPos
import net.minecraft.world.entity.PathfinderMob
/**
* Used to maintain some settings around how the entity should wander this tick. The idea is you
* reset this with some script task at priority 0 then some number of steps before it gets to the wander
* tasks you can have other conditional tasks jump in to configure parts of this.
*
* @author Hiroku
* @since July 18, 2025
*/
class CobblemonWanderControl(
var center: WanderCenter? = null,
var maxAttempts: Int = 4, // How many times to try to find a suitable point before giving up on that tick.
var allowLand: Boolean = true,
var allowWater: Boolean = false,
var allowAir: Boolean = false,
var pathCooldownTicks: Int = 20 * 5, // Used to mitigate the cost of pathfinding.
var wanderSpeed: Float = 0.35F,
) {
class WanderCenter(val x: Number, val y: Number, val z: Number, val minRange: Float, val maxRange: Float)
@Transient
val struct: QueryStruct = QueryStruct(hashMapOf())
.addFunction("center_x") { center?.x ?: 0.0 }
.addFunction("center_y") { center?.y ?: 0.0 }
.addFunction("center_z") { center?.z ?: 0.0 }
.addFunction("max_attempts") { maxAttempts.toDouble() }
.addFunction("min_range") { center?.minRange ?: 0.0 }
.addFunction("max_range") { center?.maxRange ?: 0.0 }
.addFunction("allow_land") { if (allowLand) 1.0 else 0.0 }
.addFunction("allow_water") { if (allowWater) 1.0 else 0.0 }
.addFunction("allow_air") { if (allowAir) 1.0 else 0.0 }
.addFunction("path_cooldown_ticks") { pathCooldownTicks.toDouble() }
.addFunction("wander_speed") { wanderSpeed }
.addFunction("set_center") { params ->
if (params.params.size < 3) {
throw IllegalArgumentException("set_center requires at least 3 parameters: x, y, z")
}
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
val minRange = params.getDoubleOrNull(3) ?: 0.0
val maxRange = params.getDoubleOrNull(4) ?: Float.MAX_VALUE.toDouble()
center = WanderCenter(
x = x,
y = y,
z = z,
minRange = minRange.toFloat(),
maxRange = maxRange.toFloat(),
)
}
.addFunction("set_max_attempts") { params -> maxAttempts = params.getDoubleOrNull(0)?.toInt() ?: 4 }
.addFunction("set_allow_land") { params -> allowLand = params.getBooleanOrNull(0) ?: true }
.addFunction("set_allow_water") { params -> allowWater = params.getBooleanOrNull(0) ?: false }
.addFunction("set_allow_air") { params -> allowAir = params.getBooleanOrNull(0) ?: false }
.addFunction("set_path_cooldown_ticks") { params -> pathCooldownTicks = params.getDoubleOrNull(0)?.toInt() ?: (20 * 5) }
.addFunction("set_wander_speed") { params -> wanderSpeed = params.getDoubleOrNull(0)?.toFloat() ?: 0.35F }
.addFunction("reset") {
center = null
allowLand = false
allowWater = false
allowAir = false
pathCooldownTicks = 20 * 5
wanderSpeed = 0.35F
maxAttempts = 4
}
fun isSuitable(position: BlockPos): Boolean {
val center = center ?: return true
val centerPos = BlockPos(center.x.toInt(), center.y.toInt(), center.z.toInt())
val distance = sqrt(centerPos.distSqr(position))
val suitable = distance >= center.minRange && distance <= center.maxRange
return suitable
}
}
@@ -15,6 +15,11 @@ import kotlin.jvm.optionals.getOrNull
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() }
@@ -12,7 +12,20 @@ import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
/**
* A wrapper for [BehaviorControl] that allows it to be used with any [LivingEntity]. If the class the task was
* actually intended for is not the same as the entity being passed in, the task will just not run. This is just
* a trick to allow type safety.
*
* @author Hiroku
* @since October 19th, 2024
*/
class WrapperLivingEntityTask<T : LivingEntity>(val task: BehaviorControl<T>, val clazz: Class<T>) : BehaviorControl<LivingEntity> {
companion object {
inline fun <reified E : LivingEntity> BehaviorControl<E>.wrapped(): BehaviorControl<LivingEntity> {
return WrapperLivingEntityTask(this, E::class.java)
}
}
override fun tryStart(level: ServerLevel, entity: LivingEntity, gameTime: Long): Boolean {
if (clazz.isInstance(entity)) {
return task.tryStart(level, entity as T, gameTime)
@@ -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 condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val tasksByPriority = mutableMapOf<Int, List<TaskConfig>>()
override fun getVariables(entity: LivingEntity) = tasksByPriority.values.flatten().flatMap { it.getVariables(entity) } + listOf(condition).asVariables()
override fun getVariables(entity: LivingEntity) = tasksByPriority.values.flatten().flatMap { it.getVariables(entity) } + listOf(condition).asVariables()
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (!checkCondition(entity, condition)) return
@@ -24,6 +24,7 @@ class ApplyBehaviours : BehaviourConfig {
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
@SerializedName("behaviours", alternate = ["behaviors"])
val behaviours = mutableListOf<ResourceLocation>()
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
return if (checkCondition(entity, condition)) {
behaviours.flatMap {
@@ -44,6 +44,7 @@ interface BehaviourConfig {
cobblemonResource("set_core_activities") to SetCoreActivities::class.java,
cobblemonResource("add_variables") to AddVariablesConfig::class.java,
cobblemonResource("set_variables") to SetVariablesConfig::class.java,
cobblemonResource("add_memories_and_sensors") to AddMemoriesAndSensorsConfig::class.java,
)
}
@@ -21,19 +21,25 @@ import com.cobblemon.mod.common.util.resolve
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.memory.MemoryModuleType
import net.minecraft.world.entity.ai.sensing.SensorType
class CustomScriptBehaviourConfig : BehaviourConfig {
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val variables: List<MoLangConfigVariable> = emptyList()
val script: ExpressionLike = "0".asExpressionLike()
companion object {
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 configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (!checkCondition(entity, condition)) return
behaviourConfigurationContext.addMemories(memories)
behaviourConfigurationContext.addSensors(sensors)
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
runtime.resolve(script)
}
@@ -168,7 +168,7 @@ Example:
```json
{
"type": "set_variables",
"variables": {
"variableValues": {
"aggressive": true,
"attack_range": "10"
}
@@ -14,6 +14,7 @@ import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.ai.ActivityConfigurationContext
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.asMostSpecificMoLangValue
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.scripting.CobblemonScripts
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.cobblemonResource
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
import com.mojang.datafixers.util.Pair
import net.minecraft.world.entity.LivingEntity
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 {
val condition = "true".asExpressionLike()
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val script = cobblemonResource("dummy")
val variables = mutableListOf<MoLangConfigVariable>()
val memories = emptySet<MemoryModuleType<*>>()
val sensors = emptySet<SensorType<*>>()
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()
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]
?: run {
Cobblemon.LOGGER.error("Tried loading script $script as part of an entity brain but that script does not exist")
return
}
behaviourConfigurationContext.addMemories(memories)
behaviourConfigurationContext.addSensors(sensors)
runtime.resolve(script, mapOf("brain" to struct))
}
@@ -15,6 +15,7 @@ import net.minecraft.world.entity.schedule.Activity
class SetDefaultActivity : BehaviourConfig {
val activity: Activity = Activity.IDLE
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
behaviourConfigurationContext.defaultActivity = activity
@@ -23,7 +23,6 @@ class SetVariablesConfig : BehaviourConfig {
var variableValues = mutableMapOf<String, ExpressionLike>()
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.OneShot
import net.minecraft.world.entity.schedule.Activity
class ActivityChangeTaskConfig : SingleTaskConfig {
val activity: Activity = Activity.IDLE
val condition: ExpressionLike = "false".asExpressionLike()
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> = emptyList()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
return object : OneShot<LivingEntity>() {
override fun trigger(serverLevel: ServerLevel, livingEntity: LivingEntity, l: Long): Boolean {
runtime.withQueryValue("entity", livingEntity.asMostSpecificMoLangValue())
if (condition.resolveBoolean(runtime)) {
livingEntity.brain.setActiveActivityIfPossible(activity)
return true
} else {
return false
}
}
}
}
}
@@ -8,6 +8,7 @@
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.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
@@ -47,13 +48,15 @@ class AirWanderTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, MemoryModuleType.LOOK_TARGET, CobblemonMemories.PATH_COOLDOWN)
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
return BehaviorBuilder.create {
it.group(
it.absent(MemoryModuleType.WALK_TARGET),
it.registered(MemoryModuleType.LOOK_TARGET)
).apply(it) { walkTarget, lookTarget ->
it.registered(MemoryModuleType.LOOK_TARGET),
it.absent(CobblemonMemories.PATH_COOLDOWN)
).apply(it) { walkTarget, lookTarget, pathCooldown ->
Trigger { world, entity, time ->
if (entity !is PathfinderMob || entity.isInWater) {
return@Trigger false
@@ -64,6 +67,7 @@ class AirWanderTaskConfig : SingleTaskConfig {
if (wanderChance <= 0 || world.random.nextFloat() > wanderChance) return@Trigger false
val rotVec = entity.getViewVector(0F)
pathCooldown.setWithExpiry(true, 60L)
val target = HoverRandomPos.getPos(entity, horizontalRange.resolveInt(), verticalRange.resolveInt(), rotVec.x, rotVec.y, 1.5707964f, minUpwardsMovement.resolveInt(), minDownwardsMovement.resolveInt())
?: return@Trigger false
walkTarget.set(WalkTarget(target, speedMultiplier.resolveFloat(), 3))
@@ -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.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
@@ -23,19 +21,14 @@ class AllOfTaskConfig : TaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val tasks: List<TaskConfig> = emptyList()
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
return if (checkCondition(entity, condition))
tasks.flatMap { it.getVariables(entity) } + listOf(condition).asVariables()
else
listOf(condition).asVariables()
}
override fun getVariables(entity: LivingEntity) = tasks.flatMap { it.getVariables(entity) }
override fun createTasks(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): List<BehaviorControl<in LivingEntity>> {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return emptyList()
return tasks.flatMap { it.createTasks(entity, behaviourConfigurationContext) }
}
}
@@ -8,24 +8,21 @@
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.asVariables
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.ai.AttackAngryAtTask
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class AttackAngryAtTaskConfig : SingleTaskConfig {
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "should_attack_angry_at", true).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
behaviourConfigurationContext.addMemories(MemoryModuleType.ANGRY_AT, MemoryModuleType.ATTACK_TARGET, CobblemonMemories.POKEMON_SLEEPING)
return AttackAngryAtTask.create()
}
}
@@ -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())
}
}
@@ -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.asVariables
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.VillagerCalmDown
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.sensing.SensorType
class CalmDownTaskConfig : SingleTaskConfig {
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(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
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()
}
}
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
import kotlin.jvm.optionals.getOrNull
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
/**
* Checks nearby entities and counts how many have nominated this entity as their leader.
*
* @author Hiroku
* @since June 17th, 2025
*/
class CountFollowersTaskConfig : SingleTaskConfig {
val checkTicks: ExpressionOrEntityVariable = Either.left("10".asExpression())
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
return listOf(checkTicks).asVariables()
}
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
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 ->
instance.group(
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
instance.registered(CobblemonMemories.HERD_SIZE)
).apply(instance) { nearbyEntities, herdCount ->
Trigger { world, entity, _ ->
if (world.gameTime % checkTicksValue != 0L) {
return@Trigger false
}
val myUUID = entity.uuid.toString()
val followersCount = instance.get(nearbyEntities).findAll {
it is PokemonEntity
&& it.brain.hasMemoryValue(CobblemonMemories.HERD_LEADER)
&& it.brain.getMemory(CobblemonMemories.HERD_LEADER).getOrNull() == myUUID
}.count()
if (followersCount == 0) {
herdCount.erase()
} else {
herdCount.set(followersCount)
}
return@Trigger true
}
}
}
}
}
@@ -23,7 +23,7 @@ class DoNothingTaskConfig : SingleTaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val minDurationTicks: ExpressionOrEntityVariable = Either.left("40".asExpression())
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("80".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(condition, minDurationTicks, maxDurationTicks).asVariables()
override fun getVariables(entity: LivingEntity) = listOf(minDurationTicks, maxDurationTicks).asVariables()
override fun createTask(
entity: LivingEntity,
@@ -8,6 +8,7 @@
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.WrapperLivingEntityTask
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 net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class EatGrassTaskConfig : SingleTaskConfig {
companion object {
@@ -47,6 +49,8 @@ class EatGrassTaskConfig : SingleTaskConfig {
return null
}
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, CobblemonMemories.RECENTLY_ATE_GRASS)
return WrapperLivingEntityTask(
EatGrassTask(
chance,
@@ -9,6 +9,7 @@
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.asVariables
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.Trigger
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.sensing.SensorType
class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
var condition = booleanVariable(SharedEntityVariables.BATTLING_CATEGORY, "exit_battle_when_hurt", true).asExpressible()
@@ -36,10 +38,19 @@ class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
val includePassiveDamage = includePassiveDamage.resolveBoolean()
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) {
behaviourConfigurationContext.addMemories(CobblemonMemories.NPC_BATTLING)
behaviourConfigurationContext.addSensors(CobblemonSensors.NPC_BATTLING)
fun cancelNPCBattles(npcEntity: NPCEntity): Boolean {
val battles = npcEntity.battleIds.mapNotNull(BattleRegistry::getBattle)
battles.forEach { it.end() }
@@ -58,6 +69,7 @@ class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
}
}
} else if (entity is PokemonEntity) {
behaviourConfigurationContext.addMemories(CobblemonMemories.POKEMON_BATTLE)
fun cancelPokemonBattle(pokemonEntity: PokemonEntity): Boolean {
val battle = BattleRegistry.getBattle(pokemonEntity.battleId ?: return false)
battle?.end()
@@ -43,6 +43,10 @@ class FindAirTaskConfig : SingleTaskConfig {
if (entity !is PathfinderMob) {
return null
}
behaviourConfigurationContext.addMemories(
MemoryModuleType.WALK_TARGET,
CobblemonMemories.PATH_COOLDOWN
)
return BehaviorBuilder.create {
it.group(
it.absent(MemoryModuleType.WALK_TARGET),
@@ -0,0 +1,127 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.api.storage.party.PartyStore
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.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.NearestVisibleLivingEntities
import net.minecraft.world.entity.ai.sensing.SensorType
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.
val checkTicks: ExpressionOrEntityVariable = Either.left("60".asExpression())
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
return listOf(checkTicks).asVariables()
}
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
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())
val checkTicksValue = checkTicks.resolveInt()
return BehaviorBuilder.create { instance ->
instance.group(
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
instance.absent(CobblemonMemories.HERD_LEADER)
).apply(instance) { nearbyEntities, herdLeader ->
Trigger { world, entity, _ ->
if (world.gameTime % checkTicksValue != 0L) {
return@Trigger false
}
entity as PokemonEntity
val bestLeader = getBestHerdLeader(
currentLeader = null,
nearbyEntities = instance.get(nearbyEntities),
entity = entity
) ?: return@Trigger false
herdLeader.set(bestLeader.uuid.toString())
bestLeader.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
return@Trigger true
}
}
}
}
}
@@ -8,6 +8,8 @@
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.ExpressionOrEntityVariable
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 net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class FindRestingPlaceTaskConfig : SingleTaskConfig {
val horizontalSearchDistance: ExpressionOrEntityVariable = Either.left("16".asExpression())
@@ -28,6 +31,13 @@ class FindRestingPlaceTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
behaviourConfigurationContext.addMemories(
CobblemonMemories.PATH_COOLDOWN,
CobblemonMemories.POKEMON_DROWSY,
MemoryModuleType.WALK_TARGET
)
behaviourConfigurationContext.addSensors(CobblemonSensors.POKEMON_DROWSY)
return WrapperLivingEntityTask(
FindRestingPlaceTask.create(horizontalSearchDistance.resolveInt(), verticalSearchDistance.resolveInt()),
PokemonEntity::class.java
@@ -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.SetWalkTargetAwayFrom
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.sensing.SensorType
class FleeAttackerTaskConfig : SingleTaskConfig {
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "flee_attacker", true).asExpressible()
@@ -38,6 +39,10 @@ class FleeAttackerTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
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 desiredDistance = desiredDistance.resolveInt()
return WrapperLivingEntityTask(
@@ -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.SetWalkTargetAwayFrom
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.sensing.SensorType
class FleeNearestHostileTaskConfig : SingleTaskConfig {
var condition = booleanVariable(SharedEntityVariables.FEAR_CATEGORY, "flee_nearest_hostile", true).asExpressible()
@@ -34,6 +35,8 @@ class FleeNearestHostileTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
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 desiredDistance = desiredDistance.resolveInt()
return WrapperLivingEntityTask(
@@ -0,0 +1,71 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask.Companion.wrapped
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.config.task.WanderTaskConfig.Companion.WANDER
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.ai.CircleAroundTask
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class FlyInCirclesTaskConfig : SingleTaskConfig {
val poseTypes: Set<PoseType> = setOf(
PoseType.FLY,
PoseType.HOVER
)
val minAngularVelocityDegrees = numberVariable(WANDER, "min_fly_circling_angular_velocity", 0.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 verticalSpeed: ExpressionOrEntityVariable = Either.left("0.0".asExpression())
val minDurationTicks: ExpressionOrEntityVariable = Either.left("60".asExpression())
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("180".asExpression())
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
return listOf(
minAngularVelocityDegrees,
maxAngularVelocityDegrees,
speed,
verticalSpeed,
minDurationTicks,
maxDurationTicks
).asVariables()
}
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, MemoryModuleType.PATH)
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
return CircleAroundTask(
poseTypes = poseTypes,
minTurnAngleDegrees = minAngularVelocityDegrees.resolveFloat(),
maxTurnAngleDegrees = maxAngularVelocityDegrees.resolveFloat(),
speed = speed.resolveFloat(),
verticalSpeed = verticalSpeed.resolveFloat(),
minDurationTicks = minDurationTicks.resolveFloat().toInt(),
maxDurationTicks = maxDurationTicks.resolveFloat().toInt()
).wrapped<PokemonEntity>()
}
}
@@ -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.task
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.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.ai.FollowHerdLeaderTask
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class FollowHerdLeaderTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
return listOf()
}
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
behaviourConfigurationContext.addMemories(CobblemonMemories.HERD_LEADER, MemoryModuleType.WALK_TARGET)
return FollowHerdLeaderTask().wrapped<PokemonEntity>()
}
}
@@ -20,6 +20,7 @@ import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class FollowWalkTargetTaskConfig : SingleTaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
@@ -30,6 +31,7 @@ class FollowWalkTargetTaskConfig : SingleTaskConfig {
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, MemoryModuleType.PATH, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)
return WrapperLivingEntityTask(
FollowWalkTargetTask(minRunTicks.resolveInt(), maxRunTicks.resolveInt()),
PathfinderMob::class.java
@@ -16,6 +16,8 @@ import com.cobblemon.mod.common.entity.ai.GetAngryAtAttackerTask
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.sensing.SensorType
class GetAngryAtAttackerTaskConfig : SingleTaskConfig {
companion object {
@@ -32,6 +34,11 @@ class GetAngryAtAttackerTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.HURT_BY_ENTITY,
MemoryModuleType.ANGRY_AT,
)
behaviourConfigurationContext.addSensors(SensorType.HURT_BY)
return GetAngryAtAttackerTask.create()
}
}
@@ -8,6 +8,8 @@
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.ExpressionOrEntityVariable
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 net.minecraft.world.entity.LivingEntity
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 {
val condition = booleanVariable(SELF_HEALING, USE_HEALING_MACHINES, true).asExpressible()
@@ -39,7 +43,12 @@ class GoToHealingMachineTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.WALK_TARGET,
MemoryModuleType.LOOK_TARGET,
CobblemonMemories.NPC_BATTLING
)
behaviourConfigurationContext.addSensors(CobblemonSensors.NPC_BATTLING)
return GoToHealingMachineTask.create(
horizontalSearchRange = horizontalSearchRange.asExpression(),
verticalSearchRange = verticalSearchRange.asExpression(),
@@ -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.asVariables
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.OmniPathingEntity
import com.cobblemon.mod.common.util.closestPosition
import kotlin.math.ceil
import kotlin.math.floor
@@ -43,7 +44,10 @@ class GoToLandTaskConfig : SingleTaskConfig {
if (entity !is PathfinderMob) {
return null
}
behaviourConfigurationContext.addMemories(
MemoryModuleType.WALK_TARGET,
CobblemonMemories.PATH_COOLDOWN
)
return BehaviorBuilder.create {
it.group(
it.absent(MemoryModuleType.WALK_TARGET),
@@ -56,6 +60,8 @@ class GoToLandTaskConfig : SingleTaskConfig {
entity as PathfinderMob
val walkSpeedValue = walkSpeed.resolveFloat()
val iterable = BlockPos.betweenClosed(
Mth.floor(entity.x - 8.0),
entity.blockY,
@@ -71,7 +77,7 @@ class GoToLandTaskConfig : SingleTaskConfig {
isSafeLandPosAround(entity.level() as ServerLevel, it, entity)
} ?: return@Trigger false
walkTarget.set(WalkTarget(blockPos.above(), 0.35F, 1))
walkTarget.set(WalkTarget(blockPos.above(), walkSpeedValue, 0))
return@Trigger true
}
}
@@ -82,7 +88,7 @@ class GoToLandTaskConfig : SingleTaskConfig {
val blockState = world.getBlockState(pos)
val isFluid = world.getFluidState(pos.above()).isEmpty.not()
val solidBelow = blockState.isSolid
val solidBelow = blockState.isSolid || (mob is OmniPathingEntity && mob.canFly())
if (isFluid || !solidBelow) {
return false
@@ -8,6 +8,8 @@
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.WrapperLivingEntityTask
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 net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class GoToSleepTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
@@ -22,6 +25,15 @@ class GoToSleepTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): 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)
}
}
@@ -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
}
}
}
}
}
@@ -8,6 +8,8 @@
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.ExpressionOrEntityVariable
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 net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class HealUsingHealingMachineTaskConfig : SingleTaskConfig {
val condition = booleanVariable(SELF_HEALING, USE_HEALING_MACHINES, true).asExpressible()
@@ -34,6 +37,8 @@ class HealUsingHealingMachineTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, CobblemonMemories.NPC_BATTLING,)
behaviourConfigurationContext.addSensors(CobblemonSensors.NPC_BATTLING)
return HealUsingHealingMachineTask(horizontalUseRange.asExpression(), verticalUseRange.asExpression())
}
}
@@ -8,6 +8,8 @@
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.ExpressionOrEntityVariable
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 net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class LookAtBattlingPokemonTaskConfig : SingleTaskConfig {
companion object {
@@ -40,6 +43,11 @@ class LookAtBattlingPokemonTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!resolveBooleanVariable(LOOK_AT_BATTLING_POKEMON)) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.LOOK_TARGET,
CobblemonMemories.BATTLING_POKEMON
)
behaviourConfigurationContext.addSensors(CobblemonSensors.BATTLING_POKEMON)
return LookAtBattlingPokemonTask.create(
minDurationTicks = minDurationTicks.resolveInt(),
maxDurationTicks = maxDurationTicks.resolveInt()
@@ -16,6 +16,8 @@ import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.sensing.SensorType
class LookAtEntitiesTaskConfig : SingleTaskConfig {
companion object {
@@ -36,6 +38,8 @@ class LookAtEntitiesTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
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())
}
}
@@ -8,15 +8,19 @@
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.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.npc.ai.LookAtSpeakerTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class LookAtSpeakerTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = LookAtSpeakerTask.create()
) = LookAtSpeakerTask.create().also {
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET, CobblemonMemories.DIALOGUES)
}
}
@@ -20,6 +20,8 @@ import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.Mob
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.LookAtTargetSink
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.sensing.SensorType
class LookAtTargetTaskConfig : SingleTaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
@@ -38,6 +40,8 @@ class LookAtTargetTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES)
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
return WrapperLivingEntityTask(LookAtTargetSink(minDurationTicks.resolveInt(), maxDurationTicks.resolveInt()), Mob::class.java)
}
}
@@ -8,6 +8,7 @@
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.WrapperLivingEntityTask
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 net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class LookAtTargetedBattlePokemonTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
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)
}
}
@@ -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.entity.ai.LookInDirectionTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class LookInDirectionTaskConfig : SingleTaskConfig {
var condition = booleanVariable(LOOKING_CATEGORY, "locked_rotation", true).asExpressible()
@@ -32,5 +33,7 @@ class LookInDirectionTaskConfig : SingleTaskConfig {
shouldLock = condition.asExpression(),
yaw = yaw.asExpression(),
pitch = pitch.asExpression()
)
).also {
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET)
}
}
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
import java.util.UUID
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
/**
* Task that looks around for a better herd leader or gives up on a leader
* that is themselves following a different Pokémon.
*
* @author Hiroku
* @since June 16th, 2025
*/
class MaintainHerdLeaderTaskConfig : SingleTaskConfig {
// How frequently to check for a better herd leader
val checkTicks: ExpressionOrEntityVariable = Either.left("60".asExpression())
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
return listOf(checkTicks).asVariables()
}
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
behaviourConfigurationContext.addMemories(
CobblemonMemories.HERD_LEADER,
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
)
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
val checkTicks = checkTicks.resolveInt()
return BehaviorBuilder.create { instance ->
instance.group(
instance.present(CobblemonMemories.HERD_LEADER),
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES)
).apply(instance) { herdLeader, nearbyEntities ->
Trigger { world, entity, _ ->
entity as PokemonEntity
if (world.gameTime % checkTicks != 0L) {
return@Trigger false
}
val leader = instance.get(herdLeader).let(UUID::fromString).let(world::getEntity) as? PokemonEntity
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)
return@Trigger true // No leader, so we erase the memory
} else {
val bestLeader = FindHerdLeaderTaskConfig.getBestHerdLeader(
currentLeader = (leader to currentLeaderDefinition),
nearbyEntities = instance.get(nearbyEntities),
entity = entity
)
if (bestLeader != null && bestLeader != leader) {
bestLeader.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
entity.brain.setMemory(CobblemonMemories.HERD_LEADER, bestLeader.uuid.toString())
}
}
return@Trigger true
}
}
}
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.ManageFlightInBattleTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class ManageFlightInBattleTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
behaviourConfigurationContext.addMemories(CobblemonMemories.POKEMON_BATTLE)
return ManageFlightInBattleTask.create()
}
}
@@ -15,11 +15,12 @@ import com.cobblemon.mod.common.entity.npc.ai.MeleeAttackTask
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class MeleeAttackTaskConfig : SingleTaskConfig {
val condition = booleanVariable(SharedEntityVariables.ATTACKING_CATEGORY, "attacks_melee", true).asExpressible()
val range = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_range", 1.5F).asExpressible()
val cooldownTicks = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_cooldown", 30).asExpressible()
val cooldownTicks = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_cooldown", 20).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
condition,
@@ -33,7 +34,10 @@ class MeleeAttackTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.ATTACK_TARGET,
MemoryModuleType.ATTACK_COOLING_DOWN
)
return MeleeAttackTask.create(
range = range.asExpression(),
cooldownTicks = cooldownTicks.asExpression()
@@ -0,0 +1,82 @@
/*
* 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.ast.StringExpression
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.Cobblemon
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.entity.npc.NPCEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.mojang.datafixers.util.Either
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.Behavior
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.MemoryStatus
/**
* A task that modifies the aspects of a Pokémon or NPC based on a memory module.
* If the memory is registered, the aspect is added; if it is absent, the aspect is removed.
*
* @author Hiroku
* @since July 6th, 2025
*/
class MemoryAspectTaskConfig : SingleTaskConfig {
var memory: MemoryModuleType<*> = MemoryModuleType.DUMMY
var aspect: ExpressionOrEntityVariable = Either.left(StringExpression(StringValue("")))
override fun getVariables(entity: LivingEntity) = listOf(aspect).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity && entity !is NPCEntity) {
return null
} else if (memory == MemoryModuleType.DUMMY) {
Cobblemon.LOGGER.error("MemoryAspectTaskConfig: Memory module type is not set for ${entity.name.string}.")
return null
} else if (aspect.left().orElse(null)?.originalString == "") {
Cobblemon.LOGGER.error("MemoryAspectTaskConfig: Aspect is not set for ${entity.name.string}.")
return null
}
val aspect = aspect.resolveString()
return object : Behavior<LivingEntity>(
mapOf(memory to MemoryStatus.REGISTERED),
Int.MAX_VALUE,
Int.MAX_VALUE
) {
override fun canStillUse(level: ServerLevel, entity: LivingEntity, gameTime: Long) = true
override fun tick(level: ServerLevel, owner: LivingEntity, gameTime: Long) {
val hasMemory = !owner.brain.hasMemoryValue(memory)
if (owner is PokemonEntity) {
if (!hasMemory && aspect in owner.pokemon.forcedAspects) {
owner.pokemon.forcedAspects -= aspect
} else if (hasMemory && aspect !in owner.pokemon.forcedAspects) {
owner.pokemon.forcedAspects += aspect
} else return
owner.pokemon.updateAspects()
} else if (owner is NPCEntity) {
if (!hasMemory && aspect in owner.appliedAspects) {
owner.appliedAspects -= aspect
} else if (hasMemory && aspect !in owner.appliedAspects) {
owner.appliedAspects += aspect
} else return
owner.updateAspects()
}
}
}
}
}
@@ -0,0 +1,156 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.ai.CobblemonWalkTarget
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.closestPosition
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
import java.util.function.Predicate
import net.minecraft.core.BlockPos
import net.minecraft.tags.FluidTags
import net.minecraft.util.Mth
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.level.material.FluidState
/**
* Used to get entities to move into whatever their preferred fluid is, like fish
* stranded on land trying to get back into water.
*
* @author Hiroku
* @since June 15th, 2025
*/
class MoveIntoFluidTaskConfig : SingleTaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val movesIntoWater: ExpressionOrEntityVariable = Either.left("true".asExpression())
val movesIntoLava: ExpressionOrEntityVariable = Either.left("false".asExpression())
val speedModifier: ExpressionOrEntityVariable = Either.left("0.5".asExpression())
val horizontalSearchRange: ExpressionOrEntityVariable = Either.left("8".asExpression())
val verticalSearchRange: ExpressionOrEntityVariable = Either.left("8".asExpression())
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
return listOf(
condition,
movesIntoWater,
movesIntoLava,
speedModifier,
horizontalSearchRange,
verticalSearchRange
).asVariables()
}
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.WALK_TARGET,
CobblemonMemories.PATH_COOLDOWN
)
val movesIntoWater = this@MoveIntoFluidTaskConfig.movesIntoWater.resolveBoolean()
val movesIntoLava = movesIntoLava.resolveBoolean()
val speedModifier = speedModifier.resolveFloat()
val horizontalSearchRange = horizontalSearchRange.resolveInt()
val verticalSearchRange = verticalSearchRange.resolveInt()
return BehaviorBuilder.create {
it.group(
it.absent(MemoryModuleType.WALK_TARGET),
it.absent(CobblemonMemories.PATH_COOLDOWN)
).apply(it) { walkTarget, pathCooldown ->
Trigger { world, entity, _ ->
val isInWater = entity.isInWater
val isInLava = entity.isInLava
// If it's already in a place it wants to be, then we're fine.
if (isInWater && movesIntoWater || isInLava && movesIntoLava) {
return@Trigger false
}
pathCooldown.setWithExpiry(true, 20L * 5L) // 5 seconds cooldown
val target = findTarget(
entity = entity,
movesIntoWater = movesIntoWater,
movesIntoLava = movesIntoLava,
horizontalSearchRange = horizontalSearchRange,
verticalSearchRange = verticalSearchRange
)
if (target == null) {
return@Trigger false
}
walkTarget.set(
CobblemonWalkTarget(
pos = target,
speedModifier = speedModifier,
completionRange = 0
)
)
return@Trigger true
}
}
}
}
private fun findTarget(
entity: LivingEntity,
movesIntoWater: Boolean,
movesIntoLava: Boolean,
horizontalSearchRange: Int,
verticalSearchRange: Int
): BlockPos? {
val predicate: Predicate<FluidState> = Predicate { fluid ->
(movesIntoWater && fluid.`is`(FluidTags.WATER)) || (movesIntoLava && fluid.`is`(FluidTags.LAVA))
}
val iterable = BlockPos.betweenClosed(
Mth.floor(entity.x - horizontalSearchRange),
Mth.floor(entity.y - verticalSearchRange),
Mth.floor(entity.z - horizontalSearchRange),
Mth.floor(entity.x + horizontalSearchRange),
entity.blockY + verticalSearchRange,
Mth.floor(entity.z + horizontalSearchRange)
)
val box = entity.boundingBox
val blockPos = entity.closestPosition(iterable) { pos ->
val maxX = pos.x + Mth.ceil(box.xsize) - 1
val maxY = pos.y - 1 + Mth.ceil(box.ysize) - 1
val maxZ = pos.z + Mth.ceil(box.zsize) - 1
val mutable = BlockPos.MutableBlockPos()
for (x in pos.x..maxX) {
for (y in (pos.y - 1)..maxY) {
for (z in pos.z..maxZ) {
if (!entity.level().isFluidAtPosition(mutable.set(x, y, z), predicate)) {
return@closestPosition false
}
}
}
}
return@closestPosition true
}
return blockPos
}
}
@@ -15,10 +15,11 @@ import com.cobblemon.mod.common.entity.ai.MoveToAttackTargetTask
import com.cobblemon.mod.common.util.asExpression
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class MoveToAttackTargetTaskConfig : SingleTaskConfig {
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(
speedMultiplier,
@@ -31,5 +32,10 @@ class MoveToAttackTargetTaskConfig : SingleTaskConfig {
) = MoveToAttackTargetTask.create(
speedMultiplier = speedMultiplier.asExpression(),
closeEnoughDistance = closeEnoughDistance.asExpression()
)
).also {
behaviourConfigurationContext.addMemories(
MemoryModuleType.ATTACK_TARGET,
MemoryModuleType.WALK_TARGET
)
}
}
@@ -18,6 +18,7 @@ import com.cobblemon.mod.common.util.asExpression
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class MoveToOwnerTaskConfig : SingleTaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
@@ -38,6 +39,10 @@ class MoveToOwnerTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
behaviourConfigurationContext.addMemories(
MemoryModuleType.WALK_TARGET,
MemoryModuleType.LOOK_TARGET
)
return WrapperLivingEntityTask(
MoveToOwnerTask.create(
condition = condition.asExpression(),
@@ -9,12 +9,12 @@
package com.cobblemon.mod.common.api.ai.config.task
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.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.toDF
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.RunOne
@@ -35,14 +35,14 @@ class OneOfTaskConfig : SingleTaskConfig {
val task: TaskConfig = SingleTaskConfig.nothing()
}
val condition: ExpressionLike = "true".asExpressionLike()
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val options = mutableListOf<OneOfTaskOption>()
override fun getVariables(entity: LivingEntity) = options.flatMap { it.task.getVariables(entity) }
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<in LivingEntity>? {
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 })
}
}
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.PathToBeeHiveTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class PathToBeeHiveTaskConfig : SingleTaskConfig {
companion object {
const val HONEY = "honey"
}
val condition = booleanVariable(HONEY, "can_add_honey", true).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
condition,
).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
if (!checkCondition(entity, condition)) {
return null
}
return PathToBeeHiveTask.create()
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.CobblemonSensors
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.PathToFlowerTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class PathToFlowerTaskConfig : SingleTaskConfig {
companion object {
const val POLLINATE = "pollinate"
}
val condition = booleanVariable(POLLINATE, "can_pollinate", true).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
condition
).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
if (!checkCondition(entity, condition)) {
return null
}
behaviourConfigurationContext.addMemories(
CobblemonMemories.NEARBY_FLOWERS,
CobblemonMemories.HIVE_COOLDOWN,
CobblemonMemories.HIVE_LOCATION,
CobblemonMemories.POLLINATED
)
behaviourConfigurationContext.addSensors(CobblemonSensors.NEARBY_BEE_HIVE, CobblemonSensors.NEARBY_FLOWER)
return PathToFlowerTask.create()
}
}
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.PlaceHoneyInHiveTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class PlaceHoneyInHiveTaskConfig : SingleTaskConfig {
companion object {
const val HONEY = "honey"
}
val condition = booleanVariable(HONEY, "can_add_honey", true).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
condition
).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
if (!checkCondition(entity, condition)) {
return null
}
return PlaceHoneyInHiveTask.create()
}
}

Some files were not shown because too many files have changed in this diff Show More