Compare commits

...
Author SHA1 Message Date
Sterrezo a602df2fb8 Removed a missing sound from sounds.json 2025-09-27 12:11:09 +02:00
Sterrezo f4d64eb05b Merge branch 'main' into sterr/bugfixes 2025-09-27 12:08:56 +02:00
Hiroku ce3f703de2 Merge branch 'matrix-reloaded' into 'main'
Allow reload of some registries

See merge request cable-mc/cobblemon!1878
2025-09-27 08:31:10 +00:00
Hiroku 8ed68742df Merge branch 'exp-actionbar-fix' into 'main'
Fixes EXP gained actionbar not using the AddExperienceResult.

See merge request cable-mc/cobblemon!1875
2025-09-27 05:53:33 +00:00
Landon 16aa930735 Merge branch 'boat-tweaks' into 'main'
Boat tweaks

See merge request cable-mc/cobblemon!1879
2025-09-26 03:41:03 +00:00
Landon Wills 55733e8ad5 Add offset setting for determining surface level 2025-09-25 22:52:18 -04:00
Landon Wills 67591efdad Change sprint modifier expression, adjust acceleration formula 2025-09-25 22:26:15 -04:00
Paul 5d300c8157 Change how reloadability is checked for /reload, maybe this will fix server stuff 2025-09-26 11:46:25 +10:00
Test c77198a845 rm unused imports 2025-09-25 20:00:02 -04:00
Test bd32c07cc1 fix ride stat percentage 2025-09-25 19:59:23 -04:00
Hiroku 99cfc4f147 Merge branch 'stat' into 'main'
🏇🏻

Closes #1687 and #1684

See merge request cable-mc/cobblemon!1870
2025-09-25 12:38:18 +00:00
Paul 89281a1f6d Experimental reload support for various datapack folders 2025-09-25 21:31:42 +10:00
Paul ad044fb05c Aprijuice back to flat boost mechanics, UI corrections 2025-09-25 20:38:00 +10:00
Polymeta 7088ce3828 Merge branch 'fix-scanner-sensitivity' into 'main'
Fix the scanner sensitivity I broke a few hours ago.

See merge request cable-mc/cobblemon!1876
2025-09-25 06:08:39 +00:00
JPAKx4 fc6a712906 Fix the scanner sensitivity I broke a few hours ago. 2025-09-24 21:51:41 -05:00
Neovitalism 1d0397c399 Update Pokemon.kt 2025-09-24 21:13:14 -05:00
Polymeta 8ad443a4c5 Merge branch 'riding-behaviour-tweaks-four' into 'main'
Quick riding tweaks

See merge request cable-mc/cobblemon!1873
2025-09-24 21:31:07 +00:00
Jackson BowesandPolymeta 0d1f9a0093 Quick riding tweaks 2025-09-24 21:31:07 +00:00
Polymeta 7587344cb4 Merge branch 'NavigationAndWanderTargetImprovements' into 'main'
NavigationAndWanderTargetImprovements

Closes #1693

See merge request cable-mc/cobblemon!1872
2025-09-24 21:24:48 +00:00
Polymeta f0926d7524 Merge branch 'scan-ride-crash' into 'main'
Fix crash when you zoom in using a pokedex and begin rolling

See merge request cable-mc/cobblemon!1874
2025-09-24 21:16:53 +00:00
JPAKx4 7c3b17d841 Fix crash when you zoom in using a pokedex and begin rolling 2025-09-24 14:27:11 -05:00
Polymeta 263e3cd79f Merge branch 'caring-farmer' into 'main'
Tag Support for Interactions

See merge request cable-mc/cobblemon!1871
2025-09-23 06:37:15 +00:00
JazzMcNade 2ba8062915 clean up 2025-09-23 01:36:14 -05:00
JazzMcNade edc298bf64 Fixed water walkers targeting lava surfaces and vice versa 2025-09-23 01:32:57 -05:00
JazzMcNade aa1158fcfe Fixed null exception , fixed water walkers being unable to rise up in water. 2025-09-23 01:01:48 -05:00
JazzMcNade ab40ae81c4 Merge branch 'main' into NavigationAndWanderTargetImprovements 2025-09-22 20:37:21 -05:00
dhi_holo b5df1878ed Update furfrou.json
Now can use shears from anything
2025-09-22 21:30:43 +10:00
dhi_holo 800965cb40 Tag!
Added support for the Brushes and Fertilizer item tags in the Interactions (brushes interaction tested with More Brushes and a small datapack to confirm correct behaviours)
2025-09-22 21:20:43 +10:00
Polymeta b00f1d9352 fix typo in pokemon interactions
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-09-22 10:53:31 +01:00
Polymeta a588cfadf8 Merge branch 'riding-scrape' into 'main'
Riding scrape

See merge request cable-mc/cobblemon!1869
2025-09-22 09:29:38 +00:00
Polymeta 2eb4062f67 [skip-ci] re-add client config for consistency
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-09-22 10:23:14 +01:00
Polymeta 43321d8872 licenses
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-09-22 10:07:19 +01:00
Hiroku a5ea584b75 Merge branch 'held-item-datapack' into 'main'
Implemented user-driven held item effects

See merge request cable-mc/cobblemon!1811
2025-09-22 08:10:13 +00:00
CraterandHiroku 6a9edc2e67 Implemented user-driven held item effects 2025-09-22 08:10:13 +00:00
Test 12377deff7 Merge branch 'dynlight-refactor' into 'main'
Number pushing and Dynlight betterments

See merge request cable-mc/cobblemon!1864
2025-09-22 07:47:42 +00:00
Test 583377d39b Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into stat 2025-09-22 01:31:33 -04:00
Test 2c1da8df06 license 2025-09-22 01:31:21 -04:00
Paul 737ddd973b Tiny cleanup stuff dw about it [skip-ci] 2025-09-22 15:16:25 +10:00
Test d749b04261 fix cyclizar mount idle 2025-09-22 05:14:50 +00:00
Test 93deb3a669 fix stat bar 2025-09-22 00:33:30 -04:00
Test dca45a95e9 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into stat
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/RidingBehaviourSettings.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/air/GliderBehaviour.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/item/group/CobblemonItemGroups.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/Pokemon.kt
#	common/src/main/resources/data/cobblemon/recipe/campfire_pot/black_aprijuice.json
#	common/src/main/resources/data/cobblemon/recipe/campfire_pot/blue_aprijuice.json
#	common/src/main/resources/data/cobblemon/recipe/campfire_pot/green_aprijuice.json
#	common/src/main/resources/data/cobblemon/recipe/campfire_pot/pink_aprijuice.json
#	common/src/main/resources/data/cobblemon/recipe/campfire_pot/red_aprijuice.json
#	common/src/main/resources/data/cobblemon/recipe/campfire_pot/white_aprijuice.json
#	common/src/main/resources/data/cobblemon/recipe/campfire_pot/yellow_aprijuice.json
2025-09-21 21:42:19 -04:00
Test 0412f16460 ride stat 2025-09-21 20:20:45 -04:00
Landon Wills a62e5a6571 Revert Golurk changes 2025-09-21 18:54:27 -04:00
Landon Wills 0ec337ee6c Scrape riding updates 2025-09-21 18:20:32 -04:00
Carmendar 76df0a429d changelog 2025-09-21 16:58:50 -05:00
Carmendar 08ea9378de Dewgong ready to scrape. 2025-09-21 16:57:07 -05:00
Carmendar c2bd21ab96 Merge branch 'main' into implement_pokemon 2025-09-21 11:42:32 -05:00
Paul 5db8ccfad4 Fixed various things about aprijuice ride boosts 2025-09-21 22:39:55 +10:00
Polymeta aa206d386a Merge branch 'stop-the-disco-spin' into 'main'
Fixed Pokémon spinning a bunch when re-calculating a path to a moving target, closes #1703

Closes #1703

See merge request cable-mc/cobblemon!1868
2025-09-21 10:11:11 +00:00
Paul a235af6c01 Fixed fliers taking fall damage upon landing without a passenger, fixed rarely flying pokemon joining a herd and launching into space 2025-09-21 19:24:23 +10:00
Carmendar a666a74a32 Slaking jump seat fix. 2025-09-21 03:22:51 -05:00
Carmendar c285120ff4 Merge branch 'main' into implement_pokemon 2025-09-21 03:17:33 -05:00
Paul dbd2890120 oop 2025-09-21 18:09:17 +10:00
Carmendar a5db46cdc5 Rhyhorn line ready for scrape & ride overlays for Slaking. 2025-09-21 01:17:58 -05:00
Carmendar 765cf9b96a Send in the bulls. (Tauros is ready to scrape.) 2025-09-21 01:12:38 -05:00
Paul efe7952869 Fixed Pokémon spinning a bunch when re-calculating a path to a moving target, closes #1703 2025-09-21 14:29:30 +10:00
Carmendar 9e434de285 Implemented spicy chicken legs animations. 2025-09-20 22:11:22 -05:00
Carmendar 712fe2c250 Merge branch 'main' into implement_pokemon 2025-09-20 22:09:16 -05:00
Hiroku 5db5a2ed35 Merge branch 'root-bone-animations-in-riding' into 'main'
Root bone animations in riding

See merge request cable-mc/cobblemon!1866
2025-09-21 02:15:02 +00:00
Paul 49c96e6fc8 Merge remote-tracking branch 'origin/main' 2025-09-21 10:46:21 +10:00
Paul d56c9a3f5a put da aprijuice recipes back 2025-09-21 10:42:53 +10:00
JazzMcNade 6c4c973ed8 Fixed large mobs unable to climb blocks. Enabled wandering for seafloor, water surface, and lava surface walkers. 2025-09-20 18:10:55 -05:00
Carmendar a117303147 Merge branch 'main' into implement_pokemon 2025-09-20 17:50:10 -05:00
Landon dbf248a508 Merge branch 'riding-behaviour-tweaks-03' into 'main'
ride tweaks extended cut

See merge request cable-mc/cobblemon!1865
2025-09-20 17:40:28 +00:00
Jackson BowesandLandon 56d75b14fa ride tweaks extended cut 2025-09-20 17:40:27 +00:00
Paul 87311e2d7d Added default ride pose and use that instead of letting minecraft animate them 2025-09-20 22:03:44 +10:00
Hiroku 1b525ca3a5 Merge branch 'the-curse-of-gradle-island' into 'main'
Stop using Architectury Runtime Transfomers implicitly

See merge request cable-mc/cobblemon!1867
2025-09-20 10:27:52 +00:00
Nadja Reitzenstein 78ec9d3723 Stop using Architectury Runtime Transfomers implicitly
We don't use the Architectury Runtime Transformers in any of our direct code, so there is no downside for setting compile_only and entirely dropping them.
This necessitates the other implemented changes to our build system though as the transformers also inject code and resources from the :common project into the platform-specific ones in dev-env runs. Production jars use compile-time transformed and remapped jar shadowing for the same purpose so they are wholly unaffected by this removal.
Removing ART has several upsides: For one their dev-env injections have proven very unreliable so with this change a lot of caching issues have been fundamentally removed. They also inject deep into different parts of the JVM, making hot code reloads almost impossible to function so with this change reloads should be able to apply more often.
2025-09-20 11:42:14 +02:00
Paul afa5d22c8e Re-enabled aprijuice and made creative menu aprijuice 10 in all flavours because w/e 2025-09-20 18:50:02 +10:00
Paul bd63fb686d Support marking some seats as making the hands busy 2025-09-20 17:00:35 +10:00
Carmendar 0f9a422d44 no more garchomp quirks while mount flying. 2025-09-20 00:52:41 -05:00
Paul 32d18b47f9 Positional scaling fix for root-based ride player animation 2025-09-20 15:46:11 +10:00
Paul c618bf95fa Merge remote-tracking branch 'origin/main' into root-bone-animations-in-riding
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/client/HumanoidModelMixin.java
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/player/MountedPlayerRenderer.kt
#	common/src/main/resources/mixins.cobblemon-common.json
2025-09-20 14:46:37 +10:00
Paul 18a8aa12d1 Release the held pokemon before sorting, closes #1663 2025-09-20 14:16:21 +10:00
Paul 308ca6369d Fixed persistence issues for pokemon item pickup behaviours 2025-09-20 12:44:17 +10:00
Paul 79fd9f4e04 Fixed pokemon having the NPC dialogues memory 2025-09-20 12:28:06 +10:00
Paul 38219bbca2 Fixed pokemon in the party following and looking around while asleep, closes #1668 2025-09-20 12:27:48 +10:00
Paul 87de288777 Fixed crash when adding stationary Behaviour without a movement providing behaviour. Closes #1678 2025-09-20 11:25:04 +10:00
Paul b6f1d6c62e Fixed terralith:shrubland not counting as plains for pokemon spawning, closes #1685 2025-09-20 10:44:36 +10:00
Nadja Reitzenstein a7bd70e334 Make only held Pokedexes cast light 2025-09-19 13:10:12 +02:00
Polymeta 43310d3a3b tweak default stat ranges for some flying behaviours
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-09-19 10:29:34 +01:00
GenotypeXD-Dev d12bdc3745 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-18 21:53:03 -05:00
GenotypeXD-Dev 08c8623951 Flygon Size Fix 2025-09-18 21:38:51 -05:00
Paul 6ae375cf4e Added math.sign and math.copy_sigh molang dep update 2025-09-19 10:34:19 +10:00
Polymeta 29c65c18ff Merge branch 'what-a-grain' into 'main'
Grain Improvements

Closes #1702

See merge request cable-mc/cobblemon!1863
2025-09-18 17:10:08 +00:00
dhi_holoandPolymeta b90384fe08 Grain Improvements 2025-09-18 17:10:08 +00:00
Nadja Reitzenstein d2ff7e3748 Make Charmander glow 2025-09-18 17:48:30 +02:00
Nadja Reitzenstein ea6452287b Refactor dynamic light support to be future-proof 2025-09-18 17:48:28 +02:00
Nadja Reitzenstein b1f7731563 Update dependencies all around 2025-09-18 17:47:39 +02:00
Test 5ad881235f update fabric-permissions-api to 0.3.1 2025-09-18 04:53:02 +00:00
Landon 05796998e8 Merge branch 'riding-behaviour-tweaks-02' into 'main'
Behaviour tweaks

See merge request cable-mc/cobblemon!1862
2025-09-17 18:36:53 +00:00
Jackson BowesandLandon aaf1aad9a4 Behaviour tweaks 2025-09-17 18:36:53 +00:00
Polymeta b315fdcadc Merge branch 'sand-witches' into 'main'
Small Data Changes

See merge request cable-mc/cobblemon!1861
2025-09-17 18:23:42 +00:00
dhi_holo 5b95f0a1c7 Update mochis.json
Added missing and reorganised
2025-09-18 00:01:56 +10:00
dhi_holo 7641a839c2 Merge branch 'main' into sand-witches 2025-09-17 23:33:08 +10:00
dhi_holo 6ed6ca6937 IV Drip
Added new candy tags for IV Candies (additive, subtractive, general, and general candy that includes Exp Candies)
Added Vivichoke, Cobblemon Apples, and Beetroots to Sandwich Vegetable tag
Added advancement for using IV candy
2025-09-17 23:28:18 +10:00
Landon be106a465e Merge branch 'riding-debug-ui-tweaks-02' into 'main'
Ride settings editor

See merge request cable-mc/cobblemon!1858
2025-09-17 12:53:24 +00:00
Jackson BowesandLandon e7c0374c83 Ride settings editor 2025-09-17 12:53:24 +00:00
Polymeta 7fd1a443ac Merge branch 'riding-fix-air-dismount' into 'main'
Fix in air dismount

See merge request cable-mc/cobblemon!1831
2025-09-17 06:22:21 +00:00
Jackson BowesandPolymeta 31359077ed Fix in air dismount 2025-09-17 06:22:20 +00:00
Polymeta 7f683bd618 Merge branch 'riding-fix-waterwalk' into 'main'
Fix riding waterwalk

See merge request cable-mc/cobblemon!1838
2025-09-17 06:21:36 +00:00
Jackson BowesandPolymeta 012f15878e Fix riding waterwalk 2025-09-17 06:21:36 +00:00
Polymeta f406b9695d Merge branch 'main' into 'main'
Skip battle check if the mobTargetInBattle game rule is set to false

See merge request cable-mc/cobblemon!1857
2025-09-16 08:17:01 +00:00
Polymeta f6dbe40246 Merge branch 'implement_pokemon' into 'main'
lots o' implementing, animating and fixing.

See merge request cable-mc/cobblemon!1846
2025-09-16 08:15:52 +00:00
Polymeta a1f6e47f42 Merge branch 'fix-cooking-pot-button-color' into 'main'
Fix Campfire Pot Lid Button Sprite

See merge request cable-mc/cobblemon!1859
2025-09-16 08:15:13 +00:00
Polymeta 04f5dbfca0 swap out textures
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-09-16 09:11:38 +01:00
martin fd940b5549 Remove unnecessary check on resource 2025-09-15 16:12:36 +08:00
Hiroku 3e37c1af32 Merge branch 'animation-scale-shenanigan' into 'main'
Removed Animators/Engineer Frame Ghost Scale Jumpscare

See merge request cable-mc/cobblemon!1855
2025-09-15 01:15:16 +00:00
Paul 8b6b9ffede Changelog [skip-ci] 2025-09-15 10:07:03 +10:00
Hiroku 329a13867c Merge branch 'implemented-patch' into 'main'
Fixes PokemonSpecies.implemented not containing pokémon marked implemented via species additions.

See merge request cable-mc/cobblemon!1835
2025-09-15 00:02:47 +00:00
Carmendar 5c6632c3fb Forgor camera offsets for extra seats 2025-09-14 03:20:07 -05:00
Carmendar ebde125895 Bronzong ready to scrape. 2025-09-14 03:18:17 -05:00
martin c45c74c508 Fix double lid on campfire pot open sprites 2025-09-14 14:31:13 +08:00
martin cd6bc23825 Rename CookingPotColor to CampfirePotColor 2025-09-14 06:16:57 +00:00
martin 3df95df1f9 Add color property in CampfirePotItem
To make it really easy to get it in the future
2025-09-14 06:16:57 +00:00
martin ad3ee75c22 Sync cooking pot button color with open / closed state 2025-09-14 06:16:57 +00:00
martin ce3935950a Add cooking pot open sprites 2025-09-14 06:16:57 +00:00
Paul e1380df7d1 Fixed herd counts exceeding the max, smooth the following timing so it's less robotic 2025-09-14 14:03:13 +10:00
Carmendar cf8cfb8dad Nickel no longer defies gravity when sleeping & corrected underwater behaviors on wiglett line. 2025-09-13 18:52:42 -05:00
Instrafe 3729728124 Implemented locators for Omanyte & Omastar 2025-09-13 17:16:41 -04:00
MemencioPerez 3092abfdd0 Inline mobTargetInBattle game rule check in TargetingConditions mixin 2025-09-12 15:07:30 -04:00
Carmendar 3150f33e9e underwater walkers now walk underwater, and some swimmers now avoid land. (Crabrawler line avoids water entirely.) 2025-09-12 01:27:34 -05:00
Carmendar 40d7e7bccb Merge branch 'main' into implement_pokemon 2025-09-12 01:27:10 -05:00
MemencioPerez cdbe61843f Skip battle check if the mobTargetInBattle game rule is set to false 2025-09-11 23:00:53 -04:00
Paul b13c168347 Increased default PC box count from 30 to 40 2025-09-12 12:12:39 +10:00
Carmendar f77fa82e4f Implemented finalized Mochi sprites. 2025-09-11 19:02:26 -05:00
Konoha 2e2b10311d Implement Unown ! and ? lang 2025-09-11 17:36:42 -04:00
Gertimoshka 2af5de8ce4 Fixed issue where Animation Transition has a frame non zero scale render on a part that is scale 0 for both animations 2025-09-12 00:02:56 +03:00
Jerzykv 66eea576f3 comma 2025-09-11 10:45:55 +02:00
Carmendar 53a516266f Annihilape anims and particle! -- jump anims for Garchomp and Ursaring + jump fixes for a few other mons. 2025-09-11 02:43:41 -05:00
Carmendar f732442133 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-11 02:41:16 -05:00
GenotypeXD-Dev 34cad13f57 Pachirisu scale fix 2025-09-11 02:19:23 -05:00
GenotypeXD-Dev e879a755a4 Implemented Mew and Pachirisu Remodels, Updated gengars uv/textures 2025-09-11 02:16:58 -05:00
Carmendar 2ac9c827d4 Merge branch 'refs/heads/main' into implement_pokemon 2025-09-10 23:02:07 -05:00
Test a0ef46a18c Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2025-09-10 21:09:09 -04:00
Test 9dc15c9096 fix pasture scroll crash 2025-09-10 21:08:49 -04:00
Landon 346e2cd094 Merge branch 'horse-stepup-tweak' into 'main'
Vanilla-Like Horse Ride Style Stepup

See merge request cable-mc/cobblemon!1854
2025-09-10 20:08:24 +00:00
Konoha f7794d50dd Import for cleanliness 2025-09-10 15:24:04 -04:00
Konoha 3b8d67ce64 Tweak the Horse Ride-style "StepUp" to check for the ground similar to vanilla horses. 2025-09-10 14:52:57 -04:00
Test 105d3a7d90 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2025-09-09 20:15:56 -04:00
Tyzillion 8a685cefc0 Poodle trimmin tweaks. 2025-09-09 13:35:09 -04:00
Tyzillion 3ff536dc02 Updated Changelog. 2025-09-09 11:16:56 -04:00
Tyzillion 638ec03244 The trimming particles no longer glow. 2025-09-09 11:14:00 -04:00
Tyzillion 37438c9fdd CYAN AND LIGHT BLUE ARE NOT THE SAME. WAAAAAAAAAH 2025-09-09 09:58:30 -04:00
Tyzillion cbc4b52193 Finishing touches on Furfrou. 2025-09-09 09:48:18 -04:00
Tyzillion 9a760d8eae Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-09 08:36:17 -04:00
Tyzillion b7d26d99cd Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon
# Conflicts:
#	common/src/main/resources/data/cobblemon/cosmetic_items/dyes.json
2025-09-09 08:33:02 -04:00
Tyzillion 04c8b1e95b Let me pet dat dawg! Can I pet dat dawg? 2025-09-09 08:32:21 -04:00
Tyzillion e4149b2a5e Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2025-09-09 08:29:44 -04:00
HirokuandGitLab b446af166d Merge branch 'ImproveHoverWander' into 'main'
Improvements to hover (air) wandering

See merge request cable-mc/cobblemon!1845
2025-09-09 11:50:00 +00:00
Carmendar 3cdaa513f8 Lickilicky ready for scrape with placeholder controller, and various other small fixes and tweaks. 2025-09-09 03:09:19 -05:00
PolymetaandGitLab 75e0da38c4 Merge branch 'pot-jei-catalysts' into 'main'
Added JEI recipe catalysts for campfire pots

See merge request cable-mc/cobblemon!1848
2025-09-09 08:06:53 +00:00
GenotypeXD-Dev ca43fcf3a2 Implemented New cosmetics [Watermelon Electrodes, Pokemopolis alakazam, gengar, and jigglypuff, Dots Tinkatink, Tinkatuff, and Tinkaton, Golden Sudowoodo] 2025-09-09 01:39:33 -05:00
gruxor 4f71e11383 Added JEI recipe catalysts for campfire pots 2025-09-09 01:48:58 -04:00
Tyzillion 5b56a5758a Drednaw, more like, DredMAH THERE'S A WEIRD MF CAT OUTSIDE. 2025-09-08 21:54:46 -04:00
Tyzillion 424889e820 You know what, screw you. *Downgrades your Chewtle* 2025-09-08 21:24:10 -04:00
Tyzillion 6d3f00cd58 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2025-09-08 21:07:08 -04:00
Carmendar 1d375bdffa Last Bouffalant fix I swear... also Garchomp head fix in sand. 2025-09-08 19:23:24 -05:00
Carmendar e563bbee49 bouff blink fix 2025-09-08 18:05:22 -05:00
PolymetaandGitLab e2ccb20402 Merge branch 'hydrophobic-gates' into 'main'
Removed Hydrophobia from cobblemon gates + consistency changes

See merge request cable-mc/cobblemon!1847
2025-09-08 21:30:49 +00:00
Sterrezo 8fe2dc8304 Restored Golurk's ride sounds 2025-09-08 22:27:49 +02:00
Gertimoshka 4ddc167254 Gates no longer self destruct then open and near water at random rate, also can be ingited by lava 2025-09-08 23:22:16 +03:00
Lennie e3502ec320 Added wing flap sounds to updated noivern & volcarona animations, adjusted noivern's portrait 2025-09-08 10:20:00 +02:00
Carmendar d8d0ade350 luigi and netherite hoe controller updates. 2025-09-08 02:34:31 -05:00
GenotypeXD-Dev e2ac4449b3 Implemented Seedot line Remodels 2025-09-07 22:15:30 -05:00
GenotypeXD-Dev ecec7ccee3 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-07 21:16:30 -05:00
GenotypeXD-Dev 228282f083 Added regional caps for raichu and pichu, added ukulele pichu, and fixes for pikachu cap cosmetics 2025-09-07 21:15:25 -05:00
Carmendar 3bc7d39800 Forgor changelog 2025-09-07 21:06:30 -05:00
Carmendar 3dc5873642 Nickel line remodels, Garchomp anims, fixed Bouffalant battle_idle, fixed Noivern clipping, updated Volcarona anim file, implemented Chewtle line cries and Axew cry, removed reference to clobbopus cry anim (it doesn't have one), and fixed third person camera offset for some mons. 2025-09-07 21:03:52 -05:00
Lennie 8d6291c4c2 Fixed a crash due to a poser issue 2025-09-07 13:36:37 +02:00
Jerzykv 2b77d030e8 You can drive now! (Implemented Varoom & Revavroom remodels + placeholder ride data) 2025-09-07 11:45:27 +02:00
Carmendar 029927af6a Merge branch 'main' into implement_pokemon 2025-09-07 04:12:19 -05:00
Carmendar bf791dc4d1 Bouffalant can eepy. 2025-09-07 04:08:13 -05:00
PolymetaandGitLab 56ad481304 Merge branch 'implement_pokemon' into 'main'
Implement pokemon

See merge request cable-mc/cobblemon!1842
2025-09-07 09:04:19 +00:00
PolymetaandGitLab cc7a9ae44a Merge branch 'Move-Particles-1.7' into 'main'
YOU GET PARTICLES, YOU GET PARTICLES, AND YOU GET PARTICLES. SO MANY MOVES WITH PARTICLES.

See merge request cable-mc/cobblemon!1839
2025-09-07 09:02:16 +00:00
TyzillionandGitLab 664f79f3a7 YOU GET PARTICLES, YOU GET PARTICLES, AND YOU GET PARTICLES. SO MANY MOVES WITH PARTICLES. 2025-09-07 09:02:16 +00:00
JazzMcNade 9a2ed78b0d Improve air wanders 2025-09-07 03:54:55 -05:00
Carmendar 558907eb5c Drednaw cry and sobble also smol 2025-09-07 03:31:26 -05:00
Carmendar 370b689ab4 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-07 03:21:59 -05:00
Carmendar e2740babc5 Togetic smol 2025-09-07 03:21:15 -05:00
Lennie 3393ab17d8 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-07 09:06:05 +02:00
Lennie 645029a9c7 Fixed wings being invisible for wattrel in its battle stance 2025-09-07 09:05:41 +02:00
Carmendar f168744ccd Merge branch 'main' into implement_pokemon 2025-09-06 23:49:08 -05:00
Carmendar 67210cb5f9 Fixed Parasect crash. 2025-09-06 23:15:44 -05:00
Carmendar 779fbb4f38 Removed walking privileges from Hydreigon and Volcarona, and fixed Magnezone's magnets being too spinny. 2025-09-06 21:01:31 -05:00
LandonandGitLab ce04f546e7 Merge branch 'ride_pokemon_event' into 'main'
Molang and Flowback for Riding Pokemon

See merge request cable-mc/cobblemon!1843
2025-09-07 01:46:58 +00:00
LandonandGitLab a36437ea16 Merge branch 'riding-behaviour-tweaks-01' into 'main'
Ride behaviour tweaks based on team feedback

See merge request cable-mc/cobblemon!1844
2025-09-07 01:35:50 +00:00
Jackson BowesandGitLab aa5af84283 Ride behaviour tweaks based on team feedback 2025-09-07 01:35:50 +00:00
Konoha e3031d2618 Use 'this' in tryRidingPokemon instead of unnecessary parameter. 2025-09-06 21:34:03 -04:00
Konoha 9e44ba1fb1 Fix getRideBoost function call 2025-09-06 21:31:55 -04:00
Konoha 1af66d4175 Revert function refactoring, set rideBoosts to private. 2025-09-06 21:21:43 -04:00
Konoha 144213cee8 Remove redundant check in tryRidingPokemon 2025-09-06 21:17:40 -04:00
Konoha cc95b4450e Make set_ride_boost and add_ride_boost to case insensitive. 2025-09-06 21:04:37 -04:00
Konoha 4bda306a3b Refactor "getRideBoosts" helper to avoid signature conflict on public "rideBoosts" 2025-09-06 20:18:14 -04:00
Carmendar 2ee556dc31 Updated Bastiodon third person camera. 2025-09-06 18:21:05 -05:00
Carmendar 4457df9aba Updated Bastiodon ride overlays and fixed Magnezone portrait. 2025-09-06 18:15:47 -05:00
Konoha 6dfb073242 Add Ride Boost Molang Functions 2025-09-06 19:04:44 -04:00
Jakotens e1bd0d688f Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-06 17:00:23 -06:00
Jakotens 0bce2d8645 Fix third-person camera positions for most rideable Pokemon. 2025-09-06 17:00:14 -06:00
LandonandGitLab dfe240f1d3 Merge branch 'riding-scrape' into 'main'
More riding scrape stuff

See merge request cable-mc/cobblemon!1841
2025-09-06 22:11:16 +00:00
Landon Wills f1ac0fe99f Scrape riding updates 2025-09-06 17:27:08 -04:00
Landon Wills c2f575bf22 Add condition so boat jumps do not run land jump animations 2025-09-06 17:11:22 -04:00
Konoha 5f76966678 Implement event handling function on InteractPokemonHandler
Update licenses.
2025-09-06 17:09:14 -04:00
Carmendar beddea1ecb Merge branch 'main' into implement_pokemon 2025-09-06 16:08:48 -05:00
Carmendar 04236fcf33 Prepped Bouffalant for scrape. 2025-09-06 15:59:12 -05:00
LandonandGitLab 05e87b7faf Merge branch 'riding-scrape' into 'main'
Add new scraper files

See merge request cable-mc/cobblemon!1840
2025-09-06 20:55:34 +00:00
Landon Wills e9d298834a Merge branch 'riding-scrape' into implement_pokemon 2025-09-06 16:14:59 -04:00
Landon Wills ce113cbb80 Add new condition to poser for ride style 2025-09-06 16:11:13 -04:00
Tyzillion 61ebe7124a Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-06 16:01:04 -04:00
Tyzillion 462c0b35b8 Starly Line remodels implemented. 2025-09-06 16:00:51 -04:00
Carmendar 0b55c88ec4 Prepped Rampardos for scrape, includes placeholder controller. 2025-09-06 14:51:38 -05:00
Landon Wills 942da6b2f6 Merge branch 'implement_pokemon' into riding-scrape 2025-09-06 15:45:20 -04:00
Konoha 224c38e0a7 Ride Pokemon Event and Flowback 2025-09-06 15:36:10 -04:00
Landon Wills 056917f7df Adjust basic behaviour in scraper, run scraper 2025-09-06 15:28:15 -04:00
Carmendar 2aa9379987 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-06 14:06:16 -05:00
Carmendar 3a6a3253a3 Prepped Carracosta for scrape, removed controller from Unfezant. 2025-09-06 14:05:48 -05:00
Landon Wills 1580a06a8e Run scraper 2025-09-06 14:32:26 -04:00
Tyzillion e2bfdd3e76 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/repository/VaryingModelRepository.kt
2025-09-06 14:30:50 -04:00
Jerzykv 1d24565aa6 Changelog 2025-09-06 18:03:55 +02:00
Jerzykv 2d80402688 Added Gholdengo and Gimmighoul remodels/retextures + cosmetics 2025-09-06 16:13:13 +02:00
Carmendar 20614b6b07 Merge branch 'main' into implement_pokemon 2025-09-06 04:58:47 -05:00
Carmendar b32b5a66a4 Prepped Venusaur, Parasect and Dusknoir for scraping. Adjusted portraits for Squirtle and Wartortle. - updated changelog. 2025-09-06 04:57:38 -05:00
Carmendar ad92804fce Prepped Amaura, Bastiodon and Ursaring for Scraping. Includes placeholder controllers. 2025-09-06 01:08:35 -05:00
GenotypeXD-Dev ca93955134 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-06 00:55:37 -05:00
HirokuandGitLab 01d99676f9 Merge branch 'mo-molang-mo-problems' into 'main'
Add ability to specify file paths for MoLang stores

See merge request cable-mc/cobblemon!1744
2025-09-06 05:55:06 +00:00
GenotypeXD-Dev 2c8fd29cf1 Implemented Pikachu Cosmetics (Ash caps, Captain Cap, Hair Fluff) and added more usable leaves for hawluchas cosmetic [Detective pikachu and Partner Pikachu Tomorrow] 2025-09-06 00:55:06 -05:00
Carmendar a9eec5f568 Removed Hisuian Avalugg from evo selection. 2025-09-06 00:47:30 -05:00
Hiroku e54eaa728b Merge branch 'main' into 'mo-molang-mo-problems'
# Conflicts:
#   common/src/main/kotlin/com/cobblemon/mod/common/api/molang/MoLangFunctions.kt
2025-09-06 04:17:27 +00:00
Paul 4e550151e5 Merge remote-tracking branch 'origin/main' 2025-09-06 14:16:02 +10:00
Paul 67f5259742 Pokemon that don't defend themselves will instead run for their life when hurt 2025-09-06 14:15:52 +10:00
jackowes eb783e13ba un t-pose gyarados 2025-09-05 22:33:25 -05:00
HirokuandGitLab 68237e7161 Merge branch 'Special-Candy-Recipes-2-Electric-Boogaloo' into 'main'
Special candy balancing.

See merge request cable-mc/cobblemon!1832
2025-09-06 02:52:59 +00:00
Wi2tert ec9f7665e2 Push files!! 2025-09-06 10:16:19 +08:00
Wi2tert f19ae0120e Push files!! 2025-09-06 10:07:08 +08:00
Wi2tert d674ff1d40 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-06 10:01:51 +08:00
Wi2tert 37d6f58536 "Remodels": dusknoir 2025-09-06 10:00:26 +08:00
Jakotens 2ce23e072d Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-05 19:08:15 -06:00
Jakotens d37dfee032 Updated models and animations for Sneasel, Sneasel (Hisui), Weavile, and Sneasler. Added animations for Capsakid and Scovillain. Updated changelog to reflect previous changes. 2025-09-05 19:08:08 -06:00
HirokuandGitLab ee567a63b6 Merge branch 'hero-holo' into 'main'
Data Tweaks

See merge request cable-mc/cobblemon!1836
2025-09-05 23:45:13 +00:00
dhi_holoandGitLab 868dd9cc44 Data Tweaks 2025-09-05 23:45:12 +00:00
HirokuandGitLab 3f9b0002a9 Merge branch 'FixDespawns' into 'main'
Fixed despawning blocking on empty held items, fixed forced spawns having...

See merge request cable-mc/cobblemon!1834
2025-09-05 23:44:37 +00:00
Hiroku e07b15c8fc Use named parameters where same type arguments are chained 2025-09-05 23:41:40 +00:00
HirokuandGitLab 44c5c21fb5 Merge branch 'storage-saver' into 'main'
Protect the storages!

See merge request cable-mc/cobblemon!1837
2025-09-05 23:39:27 +00:00
HirokuandGitLab 9d13e86487 Merge branch 'wild-interact' into 'main'
Prevent interact wheel on wild pokemon

See merge request cable-mc/cobblemon!1833
2025-09-05 23:26:06 +00:00
Landon Wills afa395cfeb Just mount without interact UI for passengers 2025-09-05 15:00:29 -04:00
Konoha 831903b8e3 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-05 14:58:19 -04:00
Konoha d382f48e2d Implement stubbed item evo conditions for Duraludon and Kubfu 2025-09-05 14:57:59 -04:00
Landon Wills 2b2b44a535 Merge branch 'main' into wild-interact 2025-09-05 14:16:22 -04:00
GenotypeXD-Dev ac9d85929e Implemented Articuno, Zapdos, Moltres, And Mewtwo Remodels 2025-09-05 11:29:13 -05:00
GenotypeXD-Dev 88c981bd6a Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-05 09:33:32 -05:00
GenotypeXD-Dev f0baa21b1f Fearow line, Vulpix line, And hawlucha placeholder cries 2025-09-05 09:33:13 -05:00
Neovitalism 1d5d78b953 Protect the storages! 2025-09-05 04:29:14 -05:00
Neovitalism 2a62b49eab Update PokemonSpecies.kt 2025-09-04 21:10:49 -05:00
Paul f771248936 oop 2025-09-05 12:05:16 +10:00
JazzMcNade 35850ea996 Merge branch 'main' into FixDespawns 2025-09-04 20:31:04 -05:00
Landon Wills caaccf0e67 Prevent mounting if pokemon is in pasture 2025-09-04 21:29:45 -04:00
JazzMcNade e5de8bd26f Fixed despawning blocking on empty held items, fixed forced spawns having persistence do to having a held item. 2025-09-04 20:28:33 -05:00
Landon Wills 9528d375f4 Prevent interact wheel on wild pokemon 2025-09-04 21:21:24 -04:00
Paul 9aac7dc8e3 Fixed crash when baiting rods on servers 2025-09-05 11:12:12 +10:00
Paul 0bebd2a71e Fixed sleepers not waking up properly in battle if they were sleeping before 2025-09-05 11:09:51 +10:00
Hiroku 55874e6a84 Merge branch 'poser-tpconvb' into 'main'
Add new offset option for third person offset + renamed the third person...

See merge request cable-mc/cobblemon!1817
2025-09-05 00:38:11 +00:00
Paul cda0e10524 Combee can herd after Vespiquen specifically (because it's funnier this way) 2025-09-05 10:24:50 +10:00
Paul 153f888cf5 Don't follow drowsy pokemon (get a designated driver smh) 2025-09-05 10:14:01 +10:00
Paul 6972b7d49d Eject passengers from pokemon the moment it starts getting recalled, combee no herd 2025-09-05 10:10:26 +10:00
Hiroku d7f442e2d0 Merge branch 'main' into 'poser-tpconvb'
# Conflicts:
#   common/src/main/resources/assets/cobblemon/bedrock/pokemon/posers/0967_cyclizar/cyclizar.json
2025-09-04 23:51:50 +00:00
Carmendar cc15c0a487 Special candy balancing. 2025-09-04 18:10:29 -05:00
Landon a37828e288 Merge branch 'riding-birddolphin-polish-01' into 'main'
Polish and improve bird ride

See merge request cable-mc/cobblemon!1829
2025-09-04 22:21:59 +00:00
Jackson BowesandLandon 91d00cb864 Polish and improve bird ride 2025-09-04 22:21:59 +00:00
Lennie 4ee628ea7a Implemented riding animations & temp ride controller for piloswine 2025-09-05 00:04:30 +02:00
Lennie 64c0001aff Implemented wing flapping sounds for volcarona 2025-09-04 23:17:55 +02:00
Lennie 320b2ff528 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-04 23:08:35 +02:00
Lennie cf8a1f5447 Implemented Mamoswine animation changes & model edits and added placeholder ride controller 2025-09-04 23:08:19 +02:00
Sterrezo 696d98f7cd Rebalanced wing flap sound volumes and properly added sounds for large chitin wings 2025-09-04 23:07:42 +02:00
Sterrezo 909b90aea1 Update gyarados_cry.ogg 2025-09-04 22:56:39 +02:00
GenotypeXD-Dev 04296ae04e Implemented Hawlucha Tweaks+Forest Champion Mask Cosmetic 2025-09-04 14:24:02 -05:00
Kenji_64 025dea4201 Dragapult remodels! (will come back for new poser and anims for Draga) 2025-09-04 15:21:00 +02:00
Sterrezo a0630ff738 Added sounds for large chitin wings and updated medium steel wing sounds 2025-09-04 14:43:57 +02:00
Polymeta 5b5de641cb poof and its gone
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-09-04 11:28:33 +01:00
Polymeta 5a8101e535 fix hydreigon behaviour and horse settings sync
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-09-04 11:02:54 +01:00
Polymeta 054c841ec7 Merge branch 'implement_pokemon' into 'main'
mergin' imp to main

See merge request cable-mc/cobblemon!1830
2025-09-04 08:25:24 +00:00
Carmendar b02ac04fe3 rabsca crash fix & prep for lugia scrape. 2025-09-04 00:44:33 -05:00
Landon 57b4159691 Merge branch 'Special-Candy-Recipes' into 'main'
Special candy recipes

See merge request cable-mc/cobblemon!1826
2025-09-04 02:31:36 +00:00
Landon 41e3b61657 Merge branch 'riding-scraper-3' into 'main'
Scrape new rideable pokemon

See merge request cable-mc/cobblemon!1828
2025-09-04 02:06:16 +00:00
Landon f48cd648fc Merge branch 'boat-expressions' into 'main'
Add expressions to behaviour settings for boat

See merge request cable-mc/cobblemon!1827
2025-09-04 01:57:05 +00:00
Landon Wills 76c457dcbc Update scraped pokemon 2025-09-03 21:20:49 -04:00
Landon Wills cae828dc48 Merge branch 'main' into riding-scraper-3 2025-09-03 21:16:34 -04:00
Landon 39aa9d3ff1 Merge branch 'riding-scraper-ranges' into 'main'
Update scraped data

See merge request cable-mc/cobblemon!1823
2025-09-04 01:15:57 +00:00
Landon Wills 43d4b127ae Merge branch 'implement_pokemon' into riding-scraper-3 2025-09-03 21:12:07 -04:00
Landon Wills 008c75d591 Add expressions to behaviour settings for boat 2025-09-03 21:09:53 -04:00
Landon c32d8a5389 Merge branch 'boat-changes' into 'main'
Modify stamina logic, add 'sprint' to boat

See merge request cable-mc/cobblemon!1825
2025-09-03 23:14:02 +00:00
Landon Wills 24bbfdf038 Modify stamina logic, add 'sprint' to boat 2025-09-03 12:10:56 -04:00
Polymeta b3590eb49b Merge branch 'Mo-Functions-MOLANG' into 'main'
Battle Themes Fixed and A BUNCH of MoLang.

Closes #1468

See merge request cable-mc/cobblemon!1797
2025-09-03 08:31:43 +00:00
Carmendar 0b51e0fe48 Typo fix 2025-09-03 00:29:46 -05:00
Carmendar 68c144e366 Added recipes for... candy. 2025-09-02 21:05:00 -05:00
Carmendar 506b0e8c70 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-02 17:55:09 -05:00
Carmendar 5091abc8ef Implemented new animations for Baltoy & Claydol. 2025-09-02 17:54:30 -05:00
Tyzillion 2a7503db06 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2025-09-02 15:55:55 -04:00
Tyzillion 1480bd97c2 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/repository/VaryingModelRepository.kt
2025-09-02 15:55:42 -04:00
Segfault Guy 11239ff856 Add flag to BattleMusicPacket to determine whether a sound is restarted if played consecutively. 2025-09-02 15:36:27 -04:00
Polymeta eaca59a420 Merge branch 'cooking-fixes-never-stop' into 'main'
Another Serving of Cooking Pot Fixes

See merge request cable-mc/cobblemon!1820
2025-09-02 14:47:59 +00:00
Gertimoshka 6e5a09d74d Silly Eevee make silly mistake - Fixed cooking pot cooking only then open instead of closed 2025-09-02 16:47:06 +03:00
Jerzykv 79d6f4de1f Bellibolt species file fix 2025-09-02 11:27:40 +02:00
violet 3e212a8eb1 bellibolt fixes + houndour & houndoom placeholder cries 2025-09-02 04:45:19 -04:00
Polymeta 1084f40282 Merge branch 'snack' into 'main'
♨️

See merge request cable-mc/cobblemon!1815
2025-09-02 08:34:49 +00:00
Polymeta e82609176f Merge branch 'client-on-server-bug' into 'main'
Fix bug with LivingEntityMixin$pick() on server with riding.

See merge request cable-mc/cobblemon!1816
2025-09-02 08:30:20 +00:00
Carmendar 169464ca47 Merge branch 'main' into implement_pokemon 2025-09-02 00:27:51 -05:00
Gertimoshka 3a3a505e92 Fixed Merge Conflicts 2025-09-02 05:03:19 +00:00
Konoha df727d8619 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-01 21:50:03 -04:00
Konoha c44e2f43f8 Fix conflicting regional evolution anticonditions.
Implement Galarian Weezing evolution.
Stub Hisuian Avalugg evolution.
2025-09-01 21:49:50 -04:00
Carmendar 7223bd77d9 Updated Zweilous model. 2025-09-01 20:46:09 -05:00
Konoha 59cb3017a2 Implement Bergmite Hisuian Evolution 2025-09-01 20:12:13 -04:00
Landon Wills 1f00890cec Remove debug logs from scraper 2025-09-01 18:20:29 -04:00
Landon Wills c7e01ae07b Update ride stats for real this time 2025-09-01 18:19:42 -04:00
Landon Wills f0fa87e06a Update script for new columns and stat ranges, update scraped riding stats 2025-09-01 17:19:12 -04:00
Landon Wills b4c211ac08 Merge branch 'implement_pokemon' into riding-scraper-ranges 2025-09-01 17:08:38 -04:00
Landon 82da0e8337 Merge branch 'riding-bug-fixes' into 'main'
Riding bug fixes

See merge request cable-mc/cobblemon!1822
2025-09-01 20:43:40 +00:00
Landon Wills 75bb5d8ac7 Reset animation data on driver dismount 2025-09-01 15:59:40 -04:00
Landon 2ae3da859a Merge branch 'riding-rocket-polish-01' into 'main'
Finalize rocket functionality

See merge request cable-mc/cobblemon!1803
2025-09-01 19:39:46 +00:00
Jackson BowesandLandon ef3e49529b Finalize rocket functionality 2025-09-01 19:39:46 +00:00
Landon 121afaf478 Merge branch 'riding-jet-polish-01' into 'main'
Jet Polish

See merge request cable-mc/cobblemon!1819
2025-09-01 19:39:44 +00:00
Jackson BowesandLandon a6128cd36a Jet Polish 2025-09-01 19:39:44 +00:00
Landon c8cd9adb4f Merge branch 'riding-hover-polish-01' into 'main'
Hover Ride polish

See merge request cable-mc/cobblemon!1818
2025-09-01 19:39:27 +00:00
Jackson BowesandLandon b2d5b9d6a2 Hover Ride polish 2025-09-01 19:39:27 +00:00
Landon Wills ab6051f88a Fix boats behaviours sinking, fix boat mount logic if submerged 2025-09-01 15:34:22 -04:00
Landon Wills 98800f695a Prevent transitions to air if pokemon does not have air behaviour 2025-09-01 15:24:20 -04:00
Gertimoshka fdebf4db73 General cleanup of unused/redundant code of cooking pot related stuff 2025-09-01 20:25:22 +03:00
Lennie 5f21a50e7e Animation updates for Klink, Klang & Klinklang
Implemented a temporary ride controller for klinklang
2025-09-01 18:41:34 +02:00
Gertimoshka 0d233f109d Fixed the Achievement for placing cooking pot on the campfire 2025-09-01 19:36:08 +03:00
Gertimoshka 467a6901c7 Fixed the raycast collision of campfire with pot not counting pot 2025-09-01 19:12:10 +03:00
Kenji_64 d4cd6b0ac6 Updated Pikachu line's emissives + minor head rotation adjustments for Alolan Raichu 2025-09-01 15:59:43 +02:00
Gertimoshka ee7e0b2e91 Fixed default color broth bubbles not apearing as well as fixing some new blockstate caused minor bugs 2025-09-01 16:31:49 +03:00
Jerzykv 1da1cdcb10 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-01 15:00:07 +02:00
Jerzykv 35c5e2fec6 Unmuted Abra and Kadabra 2025-09-01 14:59:42 +02:00
Kenji_64 efa1a9f383 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-09-01 14:13:15 +02:00
Paul 6bb749d806 Duplicate JSON keys in Unown oops 2025-09-01 20:15:57 +10:00
Carmendar 104755343b Texture updates for Weedle. 2025-08-31 21:13:11 -05:00
Carmendar 9e0ab5363f Animations added for Deino line and Slaking, and added placeholder ride controllers. 2025-08-31 20:26:28 -05:00
Paul 19d5903e2c Fixed R-bind misbehaving 2025-09-01 10:47:38 +10:00
Lennie dbd55b9382 Corrected a typo in dwebble's poser 2025-09-01 00:12:35 +02:00
JPAKx4 3bb5ecd2b6 Add new offset option for third person offset + renamed the third person offset with no view bobbing. 2025-08-31 16:59:38 -05:00
JPAKx4 def44930e4 Fix bug with pick() on server with riding. 2025-08-31 16:05:22 -05:00
Jakotens 3d7b95d7fe Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-31 13:23:27 -06:00
Jakotens 0f44b40d21 Added riding animations to Dragonite. Implemented animations for Serperior. 2025-08-31 13:23:20 -06:00
Lennie 987c1e2244 Removed kotlin posers for espathra, flygon, larvesta and volcarona 2025-08-31 20:49:16 +02:00
Lennie 1b184af306 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-31 20:24:48 +02:00
Lennie fc37cf403b Implemented espathra ride animations and placeholder ride controller 2025-08-31 20:24:30 +02:00
Jerzykv ae160cca80 Implemented Kadabra and Alakazam animations + locators for the whole line. Fixed Abra's portrait. Kadabra can sleep now 2025-08-31 18:04:47 +02:00
Kenji_64 ea21596460 Changelog for the Pikas 2025-08-31 15:25:17 +02:00
Kenji_64 32233737c1 Implemented Pikachu line remodels and some clean-up for their regional bias forms! 2025-08-31 15:24:30 +02:00
Kenji_64 f0ab01ed0c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-31 15:19:56 +02:00
Konoha 3a8354fb1f Legacy Learnable move MoLang query implementation 2025-08-31 09:08:52 -04:00
Kenji_64 25493b521e Fixed Spinarak's shoulder pose position 2025-08-31 14:16:01 +02:00
Gertimoshka df5407e200 Lid and Cooking is now Blockstates for the Campfire with Pot fixing several bugs as well as introducing additional observer interactions 2025-08-31 13:15:06 +03:00
Lennie 2bdc29873a Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-31 10:30:35 +02:00
Lennie 6ca89e1091 Implemented animations and placeholder ride controller for flygon 2025-08-31 10:30:12 +02:00
violet 92c488861c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-31 04:24:43 -04:00
violet 259bf693b6 ⭐ Added Cleffa, Clefairy, and Clefable's remodels 2025-08-31 04:24:34 -04:00
Test 43dbfc772e Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon 2025-08-30 22:06:27 -04:00
GenotypeXD-Dev ab8dd5f477 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-30 19:23:59 -05:00
GenotypeXD-Dev f1d2145359 Implemented Remodels for the Spearow line, Nidoking, Vulpix line, and Grimer line 2025-08-30 19:21:50 -05:00
Test 52a74bd182 Merge branch 'sterr/wind-noises-lite' into 'main'
Updated ambient ride sounds

See merge request cable-mc/cobblemon!1814
2025-08-30 23:21:45 +00:00
Sterrezo ef9f84d127 Updated ambient ride sounds 2025-08-31 00:07:25 +02:00
Test d27a30d5f1 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into snack 2025-08-30 17:59:40 -04:00
Test c1b4d98b6d ender pearl cosmetic mixin, kingler bubbles 2025-08-30 17:59:26 -04:00
Tyzillion e14e44a1c5 Mime.Jr and Mr.Mime model updated, Mr.Mime animations updated. 2025-08-30 17:58:00 -04:00
Test eb64aa3207 add particles for poke snack, update item sprite for differentiation 2025-08-30 17:50:59 -04:00
Tyzillion 46cc276e2e Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-30 17:17:52 -04:00
Jakotens d663461c51 Added riding animations to Mudsdale. Implemented animations for Rookidee, Corvisquire, and riding animations for Corviknight. Adjusted third-person riding camera offsets for Skiddo, Gogoat, Girafarig, Farigiraf, Braviary, Braviary-Hisuian, and Cyclizar. 2025-08-30 14:55:14 -06:00
Kenji_64 8c1d4f9790 Backtracked and made Dudunsparce rideable! (with placeholder stats) 2025-08-30 21:23:49 +02:00
Kenji_64 82bf374cad Replaced the placeholder cry for Cyclizar with the approved cry! 2025-08-30 18:16:33 +02:00
Kenji_64 5c9c42705a Added placeholder cry for Cyclizar! 2025-08-30 16:42:39 +02:00
Kenji_64 4c77dba0b5 Tadbulb base texture fix 2025-08-30 15:49:45 +02:00
Kenji_64 dcd431c699 Shiny Tirtouga palette fix 2025-08-30 15:49:34 +02:00
Kenji_64 165b137de2 Shiny Emboar nose fix 2025-08-30 15:49:18 +02:00
Kenji_64 e40a2386c2 Latias and Latios are rideable again (with placeholder stats) 2025-08-30 15:48:32 +02:00
Kenji_64 8933bab24f New metal textures for Beldum line 2025-08-30 15:47:52 +02:00
Lennie b7b58019cd Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-30 14:29:32 +02:00
Lennie edffb938d6 Implemented animations for dwebble and crustle 2025-08-30 14:28:39 +02:00
Paul 3a074bff8a Fixed dummy moves from removed addons corrupting pokemon stores 2025-08-30 21:35:08 +10:00
Jerzykv 0e33023517 Fixed Politoed's drop 2025-08-30 13:35:06 +02:00
Paul 3874e21c65 Fixed dummy abilities from removed addons corrupting pokemon stores 2025-08-30 21:21:20 +10:00
Jerzykv 5132b47427 Leavanny no longer ominously t-poses when walking 2025-08-30 11:56:41 +02:00
Jerzykv 526b1d145b Adjusted Sewaddle line hitboxes 2025-08-30 11:56:13 +02:00
Hiroku 70659cd818 Merge branch 'events_plus' into 'main'
Community Event Improvements

See merge request cable-mc/cobblemon!1798
2025-08-30 09:28:51 +00:00
AramandHiroku acdd6692c8 Community Event Improvements 2025-08-30 09:28:51 +00:00
violet 5607eb0bd8 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-30 05:24:30 -04:00
Jerzykv 5634b94c35 Forgot changelog 2025-08-30 10:56:51 +02:00
Jerzykv 272209c268 Unovan Zorua and Zoroark model and texture updates 2025-08-30 10:53:30 +02:00
violet f26b3242d5 added togetic animations + togepi placeholder cry 2025-08-30 04:45:02 -04:00
Paul b6ea8f728e Merge remote-tracking branch 'origin/main' into flows-be-callbacks 2025-08-30 17:20:23 +10:00
Paul e76818d7d8 Renamed "Flows" to Callbacks so it's less eccentric 2025-08-30 17:20:01 +10:00
Hiroku bcf379f218 Merge branch 'recipe-obtainment' into 'main'
Recipe Obtainment Fixes

Closes #1661

See merge request cable-mc/cobblemon!1813
2025-08-30 05:21:57 +00:00
Test 6cb0f296ce Fix summary name text cursor 2025-08-30 01:20:46 -04:00
Hiroku 433f4f6ca5 Merge branch 'pokemon-form-abilities-fix' into 'main'
Fix 'Forced' tag on Abilities for Alternate Forms

Closes #1649

See merge request cable-mc/cobblemon!1787
2025-08-30 05:09:27 +00:00
Paul dc8d55a7d2 Changelog oopsies [skip-ci] 2025-08-30 11:02:44 +10:00
Konoha 219bbbe077 Implement Galarian Mr. Mime evo 2025-08-29 20:26:24 -04:00
Konoha 70704b6330 Implement Galarian Weezing evo 2025-08-29 20:25:17 -04:00
dhi_holo 7f511a391c Recipe Obtainment Fixes
Fixes some campfire pot recipes not showing up in the recipe book

Closes #1661
2025-08-30 10:03:58 +10:00
Lennie 932f366c83 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-30 00:43:35 +02:00
Lennie 434218dda3 Implemented animations for Larvesta & Volcarona
Implemented placeholder ride stats for volcarona
2025-08-30 00:43:06 +02:00
Polymeta e4dbba026c Merge branch 'josh/model-widget-fixes' into 'main'
Model Widget Item Fixes

See merge request cable-mc/cobblemon!1812
2025-08-29 20:56:26 +00:00
Jakotens db1834f6bc Tweaked pokemon_follows_owner behavior so that Pokemon follow you more closely and don't teleport until you are much further away. 2025-08-29 14:49:44 -06:00
Jakotens dbbf96bb36 Updated Cyclizar animations and ride controller. 2025-08-29 13:11:40 -06:00
Josh 3a23f7a239 added item MoLang queries to Shoulder Mounts 2025-08-29 12:32:09 -04:00
Polymeta 9f6de64089 fix dolphins crashing... still looks odd, but progress
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-08-29 17:22:20 +01:00
Polymeta e86ee8a7d4 forcefully stop player sneaking when mounting pokemon
Fixes #1534

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-08-29 16:30:43 +01:00
Josh 7829e83ba0 fixed item visibility button 2025-08-29 11:03:31 -04:00
Josh ab3747a0c4 added MoLang queries to ModelWidget.kt 2025-08-29 11:02:43 -04:00
Polymeta 501d81e4a6 fix cooking achievement not working on soul campfire
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-08-29 15:53:59 +01:00
Polymeta f62b566610 fix some particles not appearing on owned pokemon when thrown out
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-08-29 15:52:56 +01:00
Kenji_64 32a847af34 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-29 14:44:34 +02:00
Kenji_64 1d28672978 New posers for Plusle and Minun 2025-08-29 14:44:13 +02:00
Kenji_64 74a2a2b0ee Implemented Sobble line remodels! 2025-08-29 14:43:46 +02:00
Jerzykv 354ef66d2a Fixed oopsie with Murkrow poser 2025-08-29 14:43:38 +02:00
Kenji_64 a6f1182f02 Plusle and Minun remodels + animations! 2025-08-29 14:42:27 +02:00
Jerzykv 8825e7af3d Added Murkrow remodel and Honchkrow animations. Gave Honchkrow placeholder ride stats 2025-08-29 14:35:28 +02:00
Kenji_64 bcf119bf5d Fixed Bronzor's sleep not looping 2025-08-29 14:32:27 +02:00
Jerzykv d9cb59ca37 Changed Golurk's hitbox and made it able to breathe underwater 2025-08-29 14:21:00 +02:00
Jerzykv e33960effb Fixed Low-Key Toxtricity having no shiny 2025-08-29 14:11:46 +02:00
violet a20eae7cd8 fixed luigi's poser, labeled croagunk and toxicroak as implemented, gave alolan muk and grimer proper scales, fixed unown d's shiny 2025-08-29 04:15:54 -04:00
Hiroku 4adf40c5ec Merge branch 'LessRestrictiveWanders' into 'main'
Water Pathing Improvements

See merge request cable-mc/cobblemon!1807
2025-08-29 06:53:57 +00:00
Jakotens a27e0ffc7f Implemented riding animation for Drifblim. Implemented animations for Girafarig and Farigiraf. 2025-08-29 00:30:11 -06:00
JazzMcNade 3bea35eea2 Replace isInWater with isInLiquid 2025-08-29 01:04:06 -05:00
Jakotens 3db7ecd71f Temporary tweaks to Drifblim. 2025-08-28 19:26:09 -06:00
Paul 723eccc88a Fixed hypertrain IV fix running on already-converted data, causing random entities. Closes #1634 2025-08-29 11:08:43 +10:00
Paul 75785e0706 Fixed global species features not working, closes #810 2025-08-29 10:15:18 +10:00
Paul f21da15591 Fixed model sharing across posers causing cascading animation stacking 2025-08-29 09:53:39 +10:00
Polymeta 1be44c75d5 fix ride sound deserialization
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-08-29 00:50:30 +01:00
Jakotens cfea52f488 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-28 16:24:44 -06:00
Jakotens 53e94365ad Minor tweaks to Skiddo and Gogoat. 2025-08-28 16:24:34 -06:00
SamIr0n e393fd7a47 Teddiursa, Ursaring & Ursaluna Implementation
- Ride Mon Ursaluna
- Anims/Posers for all 3
- Fixed File Naming conventions
2025-08-28 22:57:24 +01:00
Polymeta 63eb0a1d9c Merge branch 'hoppers-like-vanilla' into 'main'
Revert Brewing Stand-Hopper interaction to Vanilla behavior

Closes #1658

See merge request cable-mc/cobblemon!1810
2025-08-28 21:29:55 +00:00
Jakotens 7a5908a0d3 Fixes to Braviary and Braviary-Hisuian posers. 2025-08-28 13:37:50 -06:00
Jakotens c234291e8c Temporary tweaks to Braviary and Braviary-Hisuian posers. Corrected sizes for Whirlipede and Scolipede. 2025-08-28 13:02:18 -06:00
Lennie b97115f1bd Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-28 19:55:24 +02:00
Lennie 8720a682c3 Created more personal space for the player when riding noivern 2025-08-28 19:55:10 +02:00
Sterrezo fd0d811b47 Retimed Noivern's wing flaps 2025-08-28 19:39:07 +02:00
Lennie 520341dfd3 Added animations, wing flap sounds and riding sounds for noivern.
More poser tweaks for zebstrika (he deserves it)
2025-08-28 19:14:17 +02:00
CeeJay d66b8d04c7 Change hopper removing from brewing stand to vanilla Minecraft
Resolves #1658
2025-08-28 11:51:40 -04:00
Tyzillion 5418407d1e Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into Mo-Functions-MOLANG 2025-08-28 09:55:19 -04:00
Kenji_64 4606d9e1c5 Magnezone flight animation added! 2025-08-28 15:54:31 +02:00
Kenji_64 4f839a2589 Added new animations for the Metagross line! 2025-08-28 15:54:01 +02:00
Kenji_64 257c362765 Added dive animation for Togekiss 2025-08-28 15:36:35 +02:00
Lennie 009a8c34e5 Tweaked seat positions for tropius and zebstrika
Small poser fixes to tropius, zebstrika and blitzle
2025-08-28 15:09:39 +02:00
Tyzillion 7e0ddb5b79 Now using readNullable and writeNullable. I made an attempt to fix the possible race condition but I don't know if it even fixed it. Removed the rideable check. I'll mess with that when I add the Riding flows. 2025-08-28 07:47:11 -04:00
Gertimoshka 8b5ef32d93 Fixed cooking pot JEI integration still allowing progress arrow to be pressed causing a crash without JEI 2025-08-28 14:22:11 +03:00
Polymeta 6acf2655b8 Merge branch 'main' into implement_pokemon 2025-08-28 12:16:35 +01:00
Lennie 0e40f0f3ad Updated changelog 2025-08-28 13:11:11 +02:00
Polymeta dfb2e21721 tweak golurk poser to show correct poses inside summary and pokedex GUI
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-08-28 12:10:36 +01:00
Polymeta 67cda56be5 Merge branch 'riding-scraper-2' into 'main'
Add scraper and results

See merge request cable-mc/cobblemon!1808
2025-08-28 11:06:48 +00:00
Polymeta b15545148b always run molang pose conditions instead of only when entity is attached, leaving control over this to the actual poser molang via q.has_entity
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-08-28 12:02:43 +01:00
Lennie b37a70c5db Updated changelog
Made unfezant un-ridable
Made kilowattrel ridable for testing purposes
Added ride_dive molang to tropius and kilowattrel posers
2025-08-28 12:58:40 +02:00
Landon Wills 0b9e0ac9c7 Add new scraped pokemon after implementation merge 2025-08-28 06:22:46 -04:00
Landon Wills f5383665f8 ridingSounds => rideSounds 2025-08-28 06:21:17 -04:00
Lennie 35bef5a008 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-28 12:17:51 +02:00
Lennie 17c25def97 Implemented unfezant line remodels
Implemented unfezant line animations
Made unfezant ridable for testing purposes
2025-08-28 12:14:10 +02:00
Landon Wills 5f9088dbf5 Merge branch 'implement_pokemon' into riding-scraper-2
# Conflicts:
#	common/src/main/resources/data/cobblemon/species/generation8a/wyrdeer.json
2025-08-28 06:11:56 -04:00
Landon Wills 8748ef6884 Add scraper and results 2025-08-28 06:09:01 -04:00
GenotypeXD-Dev ee270f59e1 Added Implemented Tag To Ho-oh 2025-08-28 04:42:31 -05:00
GenotypeXD-Dev a2c5866026 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-28 04:40:49 -05:00
GenotypeXD-Dev ab408c4246 Kentucky Fried Combusken 2025-08-28 04:40:21 -05:00
GenotypeXD-Dev 9e9a98b6f7 Implemented Ho-oh 2025-08-28 04:19:13 -05:00
violet 0b5fbb4d55 Added Luigi. 2025-08-28 05:07:25 -04:00
JazzMcNade d7a8e0fe92 Fix maths. Removed references to isSwimming b/c it empirically does not occur, even when the pokemon is actively traversing underwater. 2025-08-28 03:47:09 -05:00
JazzMcNade 3bd5867143 swimming wander can now target blocks without a solid below position. Fixed a bug in AABB.getRanges() for negative coordinates 2025-08-28 02:05:38 -05:00
Jakotens c8ab370720 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-27 20:49:09 -06:00
Jakotens 4a0ab9f092 Implemented animations and ride animations for Skiddo and Gogoat. Fixed ride animations for Braviary and Braviary-Hisuian. Implemented remodels and animations for Staryu, Starmie, Venipede, Whirlipede, and ride animations for Scolipede. 2025-08-27 20:49:02 -06:00
Jakotens a565f1cdb7 Revert "Implemented animations and ride animations for Skiddo and Gogoat. Fixed ride animations for Braviary and Braviary-Hisuian. Implemented remodels and animations for Staryu, Starmie, Venipede, Whirlipede, and ride animations for Scolipede."
This reverts commit 3a2075d00c.
2025-08-27 20:47:48 -06:00
Jakotens 3a2075d00c Implemented animations and ride animations for Skiddo and Gogoat. Fixed ride animations for Braviary and Braviary-Hisuian. Implemented remodels and animations for Staryu, Starmie, Venipede, Whirlipede, and ride animations for Scolipede. 2025-08-27 20:46:48 -06:00
Polymeta 9ef3caef53 Merge branch 'universal-healer-care' into 'main'
Healing at a healer heals PC Pokemon

Closes #731

See merge request cable-mc/cobblemon!1806
2025-08-27 21:07:28 +00:00
CeejayandPolymeta c449b84fff Healing at a healer heals PC Pokemon 2025-08-27 21:07:27 +00:00
Kenji_64 bcf429589a Some extra poser adjustments for Galarian Corsola 2025-08-27 23:05:54 +02:00
Kenji_64 4282445359 Added riding molang to Wyrdeer 2025-08-27 22:26:04 +02:00
Kenji_64 3e449ae1f5 Yoshi's Island looked different- Tyrantrum is now rideable! (+ attack anims) 2025-08-27 22:24:36 +02:00
Lennie 8510290e87 Implemented tropius animation updates & flapping sounds. Updated zebstrika's ride molang implementation 2025-08-27 21:30:05 +02:00
Tyzillion c854fc5745 Added q.player.riding_pokemon Molang function. Made an attempt of adding a Molang check for if a Pokemon is rideable but no luck. 2025-08-27 15:01:41 -04:00
Tyzillion 1a3a6443d8 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into Mo-Functions-MOLANG 2025-08-27 14:58:36 -04:00
Kenji_64 b461dbce62 You unlocked Ariados as a mount! (+ new animations for the whole line) 2025-08-27 20:01:48 +02:00
Kenji_64 86e33b3ffd You unlocked Togekiss as a mount! 2025-08-27 19:56:05 +02:00
Kenji_64 78c34fb7d0 You unlocked Wyrdeer as a mount! (+ animation update) 2025-08-27 19:53:53 +02:00
Kenji_64 2ce993718b You unlocked Zebstrika as a mount! 2025-08-27 19:47:38 +02:00
Tyzillion eee3296120 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2025-08-27 09:54:51 -04:00
Polymeta 9cf8b57457 Merge branch 'do-the-brew-fixes' into 'main'
Cobblemon Brewing Fixes

Closes #1656 and #1631

See merge request cable-mc/cobblemon!1805
2025-08-27 13:44:26 +00:00
CeejayandPolymeta 208937defc Cobblemon Brewing Fixes 2025-08-27 13:44:25 +00:00
Polymeta 3e9b6cffdb Merge branch 'pot' into 'main'
Pot, PC

See merge request cable-mc/cobblemon!1800
2025-08-27 13:31:53 +00:00
JazzMcNade 2cf253a1fe Allow amphibious pokemon to wander water. Allow walking pokemon to wander air. 2025-08-27 02:57:58 -05:00
Tyzillion 29bb481363 Added q.pokemon.is_busy Molang Function. 2025-08-26 21:52:59 -04:00
Tyzillion 1f3589a592 Added q.entity.make_intangible() Molang Function. 2025-08-26 21:31:35 -04:00
Jakotens 66d697aa69 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-26 16:11:17 -06:00
Jakotens f93ebf19b0 Fixed Rufflet, Braviary, and Braviary-Hisuian not having their sleep poses set or resting behaviors defined. 2025-08-26 16:11:06 -06:00
Lennie b7a30d8f62 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-26 23:26:53 +02:00
Lennie e75e54e7ff Added seat_1 locator to kilowattrel and updated changelog 2025-08-26 23:25:45 +02:00
Kenji_64 65707cbfde Finalized Golurk's poser with attacks + minor fixes! 2025-08-26 23:01:00 +02:00
Lennie 680bc25983 Added animations for wattrel and kilowattrel 2025-08-26 22:46:21 +02:00
Lennie f4a1e67f9b Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-26 22:35:16 +02:00
Lennie c269a808ea Added animations for wattrel and kilowattrel 2025-08-26 22:34:15 +02:00
Jakotens dbec251408 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-26 14:18:24 -06:00
Jakotens 1f9466412b Implemented animations for Rufflet, Braviary, and Braviary (Hisuian). Also fixed sounds.json to correctly include Braviary (Hisuian)'s cry. 2025-08-26 14:18:01 -06:00
Lennie aa6038c704 Riding animation edits for zebstrika, and tweaks for blitzle 2025-08-26 21:16:00 +02:00
Tyzillion 0d5c84c396 Changed battle theme related soundevents to all be resourcelocations instead. No more casting, yayyyy!
q.force_evolve now does just that.
Moved some variables in Battle Builder.
Updated Changelogs!
2025-08-26 13:24:24 -04:00
Tyzillion dd9bc0d1d5 Merge remote-tracking branch 'origin/Mo-Functions-MOLANG' into Mo-Functions-MOLANG 2025-08-26 13:00:43 -04:00
Tyzillion 8aa00c1c31 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into Mo-Functions-MOLANG 2025-08-26 13:00:16 -04:00
Jakotens eaec3ea2c8 Added animations for Rufflet, Braviary, and, Braviary (Hisuian) 2025-08-26 10:30:12 -06:00
Jakotens efd32d2eee Merge branch 'implement_pokemon' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2025-08-26 10:27:01 -06:00
Jakotens 49580bd65b Added animations for Rufflet, Braviary, and, Braviary (Hisuian) 2025-08-26 10:26:35 -06:00
Jakotens 7b761bfa8e Added animations for Rufflet, Braviary, and, Braviary (Hisuian) 2025-08-26 10:25:28 -06:00
Polymeta f7a82a5725 Merge branch 'implement_pokemon' into 'main'
more mons

See merge request cable-mc/cobblemon!1804
2025-08-26 10:42:03 +00:00
Polymeta 04384bb4f2 Edit CHANGELOG.md 2025-08-26 10:37:17 +00:00
Polymeta 9cd8a492a5 Merge branch 'main' into 'implement_pokemon'
# Conflicts:
#   common/src/main/resources/data/cobblemon/species/generation2/corsola.json
#   common/src/main/resources/data/cobblemon/species/generation8/cursola.json
2025-08-26 09:55:22 +00:00
Polymeta f340a5193a Merge branch 'riding-horse-polish-01' into 'main'
Riding horse polish

See merge request cable-mc/cobblemon!1796
2025-08-26 08:16:09 +00:00
Jackson BowesandPolymeta d7a444d884 Riding horse polish 2025-08-26 08:16:09 +00:00
Polymeta eb632362e9 Merge branch 'riding-dive-molang' into 'main'
Riding dive molang

See merge request cable-mc/cobblemon!1795
2025-08-26 08:12:42 +00:00
Jackson BowesandPolymeta 01fff25f39 Riding dive molang 2025-08-26 08:12:42 +00:00
Konoha 2ef1c7b855 Fix Drednaw hitbox, walk-speed, and anim. 2025-08-25 20:57:25 -04:00
Tyzillion caa46e8bbf Added spawn_npc Molang! 2025-08-25 17:55:41 -04:00
Konoha eeca593427 Resolve issue with Squawkabilly-White shiny.
Chewtle and Drednaw to CHANGELOG.md
2025-08-25 17:44:15 -04:00
Polymeta dee15861f0 [skip-ci] changelog
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-08-25 22:07:33 +01:00
Polymeta a1df2788be Merge branch 'main' into 'main'
Port recipes of botanypots to MC1.21.1

See merge request cable-mc/cobblemon!1793
2025-08-25 21:06:07 +00:00
Lennie 23d29c7309 Fixed drilbur poser referring to excadrill (oops) 2025-08-25 22:54:20 +02:00
Lennie 71312fd22b Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-25 22:27:58 +02:00
Lennie 02c7be92dc Implemented animations for drilbur and excadrill 2025-08-25 22:25:31 +02:00
Tyzillion 047172e30f Battle theme handling now uses ResourceLocation directly and added a Fading check to resolve issue of prior battle music instance not being reset for next battle. 2025-08-25 12:12:59 -04:00
Tyzillion 923d6f2a4d Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into Mo-Functions-MOLANG 2025-08-25 12:11:49 -04:00
Polymeta f7afdf6808 Merge branch 'riding-no-roll-options-01' into 'main'
Move and improve no roll compatibility for rolling controllers (dolphin wip)

See merge request cable-mc/cobblemon!1802
2025-08-25 15:45:21 +00:00
Jackson BowesandPolymeta 0c92fbf952 Move and improve no roll compatibility for rolling controllers (dolphin wip) 2025-08-25 15:45:21 +00:00
Tyzillion 21646d4646 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into Mo-Functions-MOLANG 2025-08-25 09:44:17 -04:00
Paul da29055309 Changelog 2025-08-25 20:03:26 +10:00
Paul 66e4390c79 Scraped herding species data and fixed a lil bug in the scraper 2025-08-25 20:03:18 +10:00
violet 0fbb97a9b9 Unknown. 2025-08-25 03:56:06 -04:00
Polymeta 93242c3025 Merge branch 'more-configs-for-riding' into 'main'
Riding: Mouse Control changes

See merge request cable-mc/cobblemon!1801
2025-08-24 21:26:58 +00:00
Test 11f7158e8e changelog 2025-08-24 17:22:15 -04:00
Test 5d503a90f7 add shading to berries on berry trees 2025-08-24 17:19:26 -04:00
Test 116db0aa7c update mark molang conditions 2025-08-24 16:59:57 -04:00
Test b90e700538 fixed background field, added textColor field for dialogues 2025-08-24 15:44:36 -04:00
Charzard4261 7074b310e6 Move riding pitch/yaw inversion to the MouseHandlerMixin
Added per-axis sensitivity and axes swapping to MouseHandlerMixin
Correct mixup in the invert pitch/yaw tooltip in en_us.json
2025-08-24 15:54:34 +01:00
Charzard4261 9a23eab208 Merge branch 'main' into more-configs-for-riding
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/air/BirdBehaviour.kt
2025-08-24 13:03:55 +01:00
violet b035cc7ca7 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-24 05:26:43 -04:00
violet f1b9a3dc00 added axew, fraxure,and haxorus 2025-08-24 05:26:15 -04:00
Test 57372335b3 add alternate wallpapers, assets 2025-08-24 01:14:02 -04:00
Hiroku 8563d27429 Merge branch 'riding-statsDebugGUI-fix' into 'main'
Fix issue with saving off all stats with the speed changes.

See merge request cable-mc/cobblemon!1799
2025-08-24 05:04:00 +00:00
jackowes 0b284b8b9a Fix issue with saving off all stats with the speed changes. 2025-08-23 21:31:35 -05:00
Tyzillion cd06bc9903 Varibles goes brrrrrr 2025-08-23 17:53:22 -04:00
Tyzillion a2531d359a Merged in Amo's branch that allows resourcepack sounds in battle music. Made it compatible with BattleBuilder.kt. I think I fixed BattleMusicController.music only letting the battle theme play for one battle? 2025-08-23 16:50:52 -04:00
Tyzillion 1ee12c592b Merge remote-tracking branch 'origin/battle-music-fix' into Mo-Functions-MOLANG 2025-08-23 14:41:48 -04:00
Tyzillion f52e31c770 You can now add a battle theme to a player and NPC through Molang. 2025-08-23 12:41:21 -04:00
Test f5debdb14f update pot to use model+tint instead of texture atlas 2025-08-23 12:34:57 -04:00
Test 25544681ae update pot to use model+tint instead of texture atlas 2025-08-23 12:32:49 -04:00
Tyzillion 529df4e8b4 Added Molang for checking if an entity is a certain thing and added the ability to apply, remove, and check effects of an entity. 2025-08-23 06:33:37 -04:00
Tyzillion d2bc8613c9 Added Molang evolution check and forcing an evolution. 2025-08-23 05:47:47 -04:00
Tyzillion 1706b7c516 Player Molang functions to control Battle Music. 2025-08-23 03:30:03 -04:00
Tyzillion c1263ad674 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into Mo-Functions-MOLANG 2025-08-23 02:52:27 -04:00
Paul 738a3e9446 KotlinExpression subclass of ExpressionLike, handy 2025-08-23 16:30:12 +10:00
Polymeta e18347ea75 Merge branch 'riding-revavroom' into 'main'
Unrideable Revavroom, for now

Closes #1650

See merge request cable-mc/cobblemon!1792
2025-08-22 23:05:19 +00:00
CeejayandPolymeta d064927715 Unrideable Revavroom, for now 2025-08-22 23:05:18 +00:00
CeeJay 32ef93d79d update changelog 2025-08-22 22:19:30 +00:00
CeeJay 5a06602503 make sure form setting happens before checking ability legality for applying Pokemon properties 2025-08-22 22:19:30 +00:00
Tyzillion 24a68fefa7 Added more Molang functions.
You can now check if the player is in survival, seen the credits, is in a dialogue and you can obtain the active dialogue.
Also check if an entity is looking at a certain entity.
2025-08-22 17:43:55 -04:00
Tyzillion b0dec54576 Added a creative and spectator mode check for the player via Molang. 2025-08-22 16:31:10 -04:00
Tyzillion fb7712a5ce Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into Mo-Functions-MOLANG 2025-08-22 16:28:19 -04:00
Polymeta 752941a5da Merge branch 'LionsFoxesAndWolvesOhMy' into 'main'
Configurable Pokemon Item Pickup and Consumption

See merge request cable-mc/cobblemon!1776
2025-08-22 09:48:29 +00:00
lsxuan12138 c6d63c42d2 delete load_conditions 2025-08-22 17:18:49 +08:00
Paul 975cba482a Collection<ObtainableItem>.findMatchingEntry requires a registry access 2025-08-22 18:54:48 +10:00
Paul 8a580ac75b Use mainThreadRuntime in a bunch of places 2025-08-22 18:46:27 +10:00
Paul bc5a858fe9 Merge remote-tracking branch 'origin/main' into LionsFoxesAndWolvesOhMy 2025-08-22 18:46:00 +10:00
lsxuan12138 bc40b101f1 Port recipes of botanypots to MC1.21.1 2025-08-22 16:41:22 +08:00
JazzMcNade 2b6fa0a38e Typo 2025-08-21 21:43:57 -05:00
JazzMcNade b1e9cddaa3 Fixed unsafe brain memory check 2025-08-21 21:38:39 -05:00
JazzMcNade 9983f44449 Missed a spot 2025-08-21 20:46:22 -05:00
JazzMcNade 6aa2a0db3d Peer Review changes 2025-08-21 20:40:49 -05:00
Sterrezo 384afd77ca Added wing flap sounds to Farfetch'd 2025-08-22 01:11:32 +02:00
Sterrezo d9b2a88040 Implemented wing flaps for Beedrill, Zubat and Venomoth 2025-08-22 00:46:43 +02:00
Kenji_64 88010bac6a Fixed G. Corsola line's walk speed (FR THIS TIME!!) 2025-08-21 23:54:51 +02:00
Landon b59b64153c Merge branch 'implement_pokemon' into 'main'
Merge implemented pokemon

See merge request cable-mc/cobblemon!1791
2025-08-21 16:38:53 +00:00
Kenji_64 db61586f0f Added cry sounds to Slowpoke line + Galarian! 2025-08-21 15:18:47 +02:00
Kenji_64 07aca28b10 Fixed a resolver issue with the Kommo-o line 2025-08-21 15:01:52 +02:00
Kenji_64 9a2737722e Fixed the cry sound event for G. Corsola being wrong 2025-08-21 15:01:29 +02:00
Kenji_64 7210ed8ad3 Previously forgotten Changelog entries 2025-08-21 14:42:25 +02:00
Kenji_64 62e3f30eba Added placeholder cries back for Honedge line remodels 2025-08-21 14:41:35 +02:00
Kenji_64 84c2beb5c8 Added placeholder cries + sounds for Sewaddle line 2025-08-21 14:39:44 +02:00
Kenji_64 5204704e47 Tiny interpolation fix for Togekiss' special animation 2025-08-21 14:39:03 +02:00
Kenji_64 6eac615a67 Implemented Blitzle and Zebstrika animations! (Thank you Lennie!) 2025-08-21 13:46:58 +02:00
Kenji_64 c791b8a16d Fixed Alolan Raichu's and Galarian Rapidash's sound event being wrong 2025-08-21 13:41:39 +02:00
violet 0360e2eb88 added houndour & houndoom 🔥 2025-08-21 04:42:31 -04:00
violet 5ecd69b3ce added togepi, togetic, togekiss (+ corsola animations) 2025-08-21 00:51:11 -04:00
Konoha 3489389d79 chore: asset directory errors and typo corrections 2025-08-20 13:16:53 -04:00
Instrafe 4e417c0b19 Implemented locators for Remoraid & Octillery 2025-08-20 11:40:17 -04:00
Kenji_64 7aba5dc962 Fixed Altaria's cry sound event 2025-08-20 16:52:13 +02:00
Instrafe a5126f2158 Implemented locators for the Elemental Monkeys 2025-08-19 22:44:04 -04:00
Sterrezo 0ca9f3a3ad Finalized wing flap audio assets 2025-08-18 15:11:49 +02:00
violet c5c10e0eec i forgot to update the changelog 🫶 2025-08-18 02:48:32 -04:00
violet 274ce14e0f added clouds ☁️🕊️ 2025-08-18 02:38:36 -04:00
JazzMcNade a08bb419dc Fixed issue in which pokemon would repeatedly exchange for an identical item. Fixed item sensor from repeatedly evaluator the priority of its held item 2025-08-17 17:45:41 -05:00
Tyzillion fa07b93d54 Splitting an atom has never been easier. 2025-08-17 18:39:02 -04:00
Kenji_64 9ad9c4643b Some fixes to Porygon's portrait animations acting up. This should hopefully work now 2025-08-17 21:37:33 +02:00
Kenji_64 a7065e5c06 Fixed a tiny oopsie with posers I did 2025-08-17 20:33:15 +02:00
Kenji_64 edf74d9ef4 Implemented attack animations for the Porygon line + made them no longer need air to breathe 2025-08-17 17:02:26 +02:00
Paul c5547c9041 Merge remote-tracking branch 'origin/LionsFoxesAndWolvesOhMy' into LionsFoxesAndWolvesOhMy 2025-08-17 09:32:24 +10:00
Paul 8be9088888 Fixed the basic molang query functions not being registered for run_script task configs 2025-08-17 09:32:13 +10:00
JazzMcNade a0e66c4bf6 Merge branch 'main' into LionsFoxesAndWolvesOhMy 2025-08-16 13:42:43 -05:00
JazzMcNade f0fb3fa946 Fix timings for giving up on searching for berry bushes 2025-08-15 22:08:25 -05:00
JazzMcNade da444f401b Banned pokemon from eating potions by default. Fixed a bug in which pokemon would give up going to an item too early. Reduced eating cooldown. 2025-08-15 21:38:56 -05:00
Instrafe eb0365d7ce Implemented Escavalier remodel 2025-08-14 16:52:32 -04:00
Kenji_64 97c2b46192 Implemented Togedemaru! 2025-08-14 13:59:40 +02:00
Kenji_64 847e5d7647 Tiny interpolation fix on Ceruledge's battle_cry 2025-08-14 13:28:38 +02:00
Kenji_64 43e05ef7e7 Urgent Dunsparce line poser fixes that caused a crash (so sorry) 2025-08-14 13:28:19 +02:00
Kenji_64 b14eed17eb G.Corsola walk speed fixes, sound fixes and tiny adjustments to the icons 2025-08-14 13:27:41 +02:00
violet 069d9df3be Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-14 05:37:47 -04:00
violet 7c40d4298d added meditite and medicham <3 2025-08-14 05:32:56 -04:00
Kenji_64 1a2c5851f4 Fixed the clipping of the ectoplasm overlay for G. Corsola + Cursola 2025-08-14 11:31:58 +02:00
RedGenesectNinja 5bf962897f Implemented animations for Hoppip, Skiploom and Jumpluff 2025-08-14 00:59:04 -05:00
JazzMcNade c1a18e91c3 Allow pokemon to give up on hard to reach items 2025-08-13 22:03:31 -05:00
JazzMcNade 881e57cbd2 Small refactor and comment 2025-08-13 20:34:33 -05:00
GenotypeXD-Dev 08c49d36db Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-13 17:43:35 -05:00
GenotypeXD-Dev 74cd758a0b Implemented Galarian Mr.Mime 2025-08-13 17:43:02 -05:00
Kenji_64 9af0879359 Added animations and placeholder riding data for the Dunsparce line 2025-08-13 22:16:53 +02:00
Kenji_64 c42e6bb963 Added animations and sounds to G. Corsola + Cursola 2025-08-13 22:13:44 +02:00
Kenji_64 c12e6fd3ed Implemented Klink line retexture + locators 2025-08-13 22:12:42 +02:00
Kenji_64 78f97984c7 Added implemented: true tag and scales to a whole bunch of Mons 2025-08-13 19:23:20 +02:00
JazzMcNade 984d8c3e9d Restored dropping items with negative priority 2025-08-13 01:25:30 -05:00
RedGenesectNinja ef3623534c Updated changelog 2025-08-12 20:09:21 -05:00
Instrafe e4554faa4f Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-12 21:02:58 -04:00
Instrafe 0e32b20bbd Implemented the remodel for Shelmet 2025-08-12 21:01:02 -04:00
Konoha b1135e334c Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-12 11:23:17 -04:00
Konoha 6cdeea39c3 Implement Chewtle and Drednaw 2025-08-12 11:19:15 -04:00
Paul 5150de74c8 Added a preconfigure step and finally fully resolved fox behaviour configuration 2025-08-12 22:38:53 +10:00
Polymeta 8cf58d22f9 Merge branch 'main' into implement_pokemon 2025-08-11 22:16:32 +01:00
JPAKx4 50cb670eee Merge remote-tracking branch 'origin/mo-molang-mo-problems' into mo-molang-mo-problems
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/molang/MoLangFunctions.kt
2025-08-11 11:33:57 -05:00
JPAK cfd3eb6c4c Add ability to access a global MoLang Store (multiserver for example) 2025-08-11 11:33:27 -05:00
Konoha 6eccc0e3e3 Use those pesky unused Rotom form assets 2025-08-11 10:30:07 -04:00
Konoha efa8f6a81e Conform texture references for Alolan Grimer line 2025-08-11 09:09:45 -04:00
Paul 46b9eccfb1 Migrated last of species-modifying from fox logic and auto-applied pickup tasks where it's needed 2025-08-10 21:34:03 +10:00
Paul 1936c8a0be Migrated the pickup items for foxes and stuff to the config struct 2025-08-10 19:13:35 +10:00
Paul 99b99a803c Streamlined item pickup / fox behaviours 2025-08-10 13:12:11 +10:00
Konoha 9081dc3a19 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-09 22:49:07 -04:00
Konoha c2b6421ff9 Source data error corrections (G-Weezing is not base stage and should not receive Aromatherapy as an egg move, Silvally is not limited to Grass Pledge outside of a coding error) 2025-08-09 22:48:03 -04:00
Konoha 99af478165 Pumpkaboo Line Portrait/Profile Size Variation 2025-08-09 22:39:10 -04:00
RedGenesectNinja 873028d8e8 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-09 21:02:53 -05:00
RedGenesectNinja 2db8728560 Implemented Toedscool and Toedscruel 2025-08-09 21:00:01 -05:00
Tyzillion d0dbbe7850 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-09 17:38:25 -04:00
Tyzillion a6280d223a Implemented Alolan Grimer line, Sewaddle line, Tadbulb line, and Capsakid line. 2025-08-09 17:37:52 -04:00
GenotypeXD-Dev 4187b31daf gogoat poser fix+changelog 2025-08-09 14:05:30 -05:00
GenotypeXD-Dev ea33d86dbd Implemented Tynamo line and Skorupi Line 2025-08-09 13:45:05 -05:00
Tyzillion 8dc5c19210 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2025-08-09 14:15:11 -04:00
Paul d37a928630 Merge remote-tracking branch 'origin/main' into LionsFoxesAndWolvesOhMy 2025-08-09 16:13:32 +10:00
GenotypeXD-Dev 3499111c92 Changelog 2025-08-09 00:35:41 -05:00
GenotypeXD-Dev 28cd404bef Implemented Espurr line and Morpeko, Poser fixes for hisuian braviary and galarian weezing 2025-08-09 00:34:41 -05:00
Paul d2e6be2c5f Merge remote-tracking branch 'origin/main' into LionsFoxesAndWolvesOhMy 2025-08-09 15:16:47 +10:00
GenotypeXD-Dev 407c4baff2 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-08-08 21:20:12 -05:00
GenotypeXD-Dev d0653c5b13 Implemented Weezing-Galar, Braviary-Hisui, Mr. Rime. Added the implemented tag to some of the elemental monkeys, skiddo line, and munna line. Fixed Toxtricity Battle Pose, Fixed Skiddo Line posers 2025-08-08 21:19:29 -05:00
Charzard4261 3faa5913ad [TEMP] Test sensitivity and axis swapping on BirdBehaviour 2025-08-08 17:48:45 +01:00
Charzard4261 56927a7af5 Add config properties 2025-08-08 17:48:00 +01:00
JazzMcNade a1aff7b457 Merge branch 'main' into LionsFoxesAndWolvesOhMy 2025-08-07 20:28:40 -05:00
JazzMcNade a1d3e4577f Allow pokemon to give up on seeking an unreachable berry bush 2025-08-05 00:57:45 -05:00
RedGenesectNinja 12212605cd Implemented Hoppip, Skiploom and Jumpluff 2025-08-04 19:01:29 -05:00
JazzMcNade 82963f273a Refactored PokemonItemSensor 2025-08-03 21:27:13 -05:00
JazzMcNade 88c5c1e224 Removed non null assertions 2025-08-03 20:32:23 -05:00
JazzMcNade d8b661ed0b more licenses 2025-08-03 19:18:00 -05:00
JazzMcNade 03c1d560bc Clean up and licenses 2025-08-03 16:48:35 -05:00
JazzMcNade 02c347d22f Pokemon that pick up an item in the world are now persistent 2025-08-03 01:58:03 -05:00
JazzMcNade d296194cc7 Merge branch 'main' into LionsFoxesAndWolvesOhMy 2025-08-02 17:30:22 -05:00
JazzMcNade 57daf3e860 Pickup items can now be specified with molang, lifted fox pickup list to pokemon_fox.json 2025-08-02 17:29:59 -05:00
Kenji_64 dfc130cf55 Killed the oceans - added G. Corsola and Cursola 2025-07-31 15:13:26 +02:00
Kenji_64 7a7eed9c45 Implemented remodels for Mudkip, Marshtomp and Swampert 2025-07-31 15:12:35 +02:00
Tyzillion 37c4d4c7fe Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2025-07-29 15:07:22 -04:00
Tyzillion 2b5cac4361 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-07-29 15:07:03 -04:00
JazzMcNade 7232b2cd26 Moved some fox configuration into pokemon_fox.json 2025-07-28 01:37:58 -05:00
GenotypeXD-Dev c19a94a2d3 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-07-27 21:17:33 -05:00
GenotypeXD-Dev fbe6328f97 Implemented Skiddo and gogoat 2025-07-27 21:13:43 -05:00
JazzMcNade bb926e2dc8 Refactoring item detection into a sensor, more refactoring 2025-07-27 15:05:00 -05:00
GenotypeXD-Dev d205650373 deleted accidentally duplicated files, added skwovet resolver 2025-07-27 14:36:30 -05:00
GenotypeXD-Dev eb4fa676ca Added Elektrike, Manectric, Yungoos, Gumshoos, Skwovet, Greedent, Toxel, Toxtricity Amped/Lowkey 2025-07-27 14:36:29 -05:00
GenotypeXD-Dev 2ec6ba382c deleted accidentally duplicated files, added skwovet resolver 2025-07-27 14:27:22 -05:00
GenotypeXD-Dev 65203b6d57 Added Elektrike, Manectric, Yungoos, Gumshoo, Skwovet, Greedent, Toxel, Toxtricity Amped/Lowkey 2025-07-27 14:22:39 -05:00
JazzMcNade e39564667e Merge branch 'main' into LionsFoxesAndWolvesOhMy 2025-07-27 11:36:51 -05:00
JazzMcNade d5bfaf2331 Changed underlying datastructure to preserve key order when iterating. 2025-07-26 20:47:23 -05:00
JazzMcNade a1790120a1 Added option to filter items via molang 2025-07-26 20:31:51 -05:00
JazzMcNade 0a4b6e08b5 Merge branch 'main' into LionsFoxesAndWolvesOhMy 2025-07-26 15:23:51 -05:00
JazzMcNade 9152ded2cb refactor immuneToSweetBerryBushBlock to BlockInteract, added canStandOnPowderSnow option 2025-07-26 15:20:26 -05:00
JazzMcNade 714666df1c Added configuration support for Pokemon to pickup and consume items 2025-07-26 14:27:44 -05:00
JazzMcNade 1f60d8f413 Merge branch 'main' into LionsFoxesAndWolvesOhMy 2025-07-26 03:20:18 -05:00
JazzMcNade 7366e82bd1 Added the ability for pokemon to remember if they've been given an item by a player. 2025-07-21 00:27:49 -05:00
Hiroku 1e573f80bb Merge branch 'cvnty_gyarados' into 'implement_pokemon'
Fixed issue with gyarados_female.geo.json where it was a duplicate of gyarados_male.geo.json, now allowing for correct Implementation of Female Gyarados!

See merge request cable-mc/cobblemon!1747
2025-07-18 06:30:46 +00:00
SamIr0n 819630a8db Gyarados can be female again 👀 2025-07-17 23:19:18 +01:00
Konoha 583e4360cf Stub base form aspects for Dudunsparce and Squawkabilly's shiny
Fix texture reference error on Heatmor shiny
2025-07-17 09:18:35 -04:00
Konoha 7972662537 Fix Marill shiny texture path 2025-07-16 20:16:04 -04:00
Konoha a4fd86fc95 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-07-16 18:19:05 -04:00
Kenji_64 47417a309f Fixed Quaxly's animations showing hidden sets of wings 2025-07-16 15:30:24 +02:00
JPAK 38cfd7eca8 Add ability to access a global MoLang Store (multiserver for example) 2025-07-15 15:03:04 -05:00
JazzMcNade d0293ad177 Fox sweet/glow berry harvesting and eating 2025-07-14 21:23:00 -05:00
JPAK 2ba2eea801 Add functions to remove entity and spawn NPCs for Molangs 2025-07-13 13:16:44 -05:00
Konoha 4d11bd0ed8 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-07-11 16:47:06 -04:00
Tyzillion 5a7da67d67 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2025-07-05 21:26:47 -04:00
Tyzillion 60feb21e49 Removed Drowzee line hard coded posers. 2025-07-05 19:03:10 -04:00
Tyzillion 00d7db6f48 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-07-05 19:02:12 -04:00
Carmendar 5f7990a899 Implemented Azurizz line and fixed Tropius, Shellder line and Shroomish animations. 2025-07-05 16:23:06 -05:00
JazzMcNade 4890e857f4 Added new mixin behaviors with vanilla mobs, added a flag for fox pokemon to avoid sweet berry bush damage. 2025-07-03 02:14:56 -05:00
Tyzillion d112475c97 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into implement_pokemon 2025-07-02 15:54:57 -04:00
Tyzillion b652235791 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-07-02 15:54:16 -04:00
Polymeta 00e695a0e7 Merge branch 'legacy_and_event_moves' into 'implement_pokemon'
Legacy and event move support

See merge request cable-mc/cobblemon!1512
2025-06-29 23:13:15 +00:00
Konoha d933adfaf1 Merge remote-tracking branch 'origin/legacy_and_event_moves' into implement_pokemon 2025-06-25 21:21:12 -04:00
Tyzillion cb86c8d4dd Implemented Drowzee Line Remodels. 2025-06-23 17:55:46 -04:00
Paul be5ee8a6a3 Potentially got root bone animation working for players on pokes 2025-05-16 22:22:05 +10:00
amo 44c27be590 oops 2025-05-08 17:53:42 +01:00
amo a704972dea oops 2025-05-06 04:33:11 +01:00
amo 0b43342a5c fix battle music attempting to use registered sound events instead of just creating and using one from the id (allows resourcepackable etc) 2025-05-06 04:32:59 +01:00
Sterrezo 21e5ac6b96 Removed licenses from particle texture folders 2025-04-28 17:21:37 +02:00
Sterrezo d67eca46e6 Merge branch 'main' into sterr/bugfixes 2025-04-28 17:19:11 +02:00
Sterrezo ebbd92fb7a Even less redundancy 2024-12-06 19:15:37 +01:00
Sterrezo 60c4423ab7 Fixed the overlap but without redundancy this time 2024-12-06 18:14:40 +01:00
Sterrezo 82dbbc7f9f Accidental import 2024-12-06 14:49:50 +01:00
Sterrezo 534307df87 Fixed the overlap but efficiently this time 2024-12-06 14:47:57 +01:00
Sterrezo 6c4738fe82 Fixed the overlap but properly this time 2024-12-05 13:36:05 +01:00
Sterrezo 6dcddb612e Adjusted portrait space detection in the Pokedex to prevent overlap
Closes #1055
2024-12-04 17:14:45 +01:00
4159 changed files with 639735 additions and 71614 deletions
+4
View File
@@ -6,6 +6,7 @@
- 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.
- Some Pokémon herd together.
- 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.
@@ -14,6 +15,9 @@
- 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(...)`
### Fixes
- Fixed Pokémon with a moving walk target frequently spinning in place as they re-calculate their path.
### MoLang & Datapacks
- Added a `behaviours` datapack folder which motivates the Behaviour Editor screen on NPCs and Pokémon.
- Added "callback" support on PokemonEntity and NPCEntity that allows MoLang scripts to be executed in response to certain scenarios.
+2 -1
View File
@@ -1,6 +1,7 @@
### Additions
- Added functionality for marks.
- Added data for all marks and all title ribbons from Pokémon.
- Added data for all marks and ribbons from the mainline Pokémon games.
- Implemented fishing, personality, weather, and time related marks, that can rarely be granted to a wild-spawned Pokémon.
- Added marks screen within the summary UI.
- Added `/givemark <player> <partySlot> <mark>` command to give a mark to a Pokémon.
- Added `/takemark <player> <partySlot> <mark>` command to remove a mark from a Pokémon.
+11 -2
View File
@@ -1,19 +1,28 @@
### Additions
- Added ability to rename PC Boxes by clicking on the name of a box.
- Added box options buttons for boxes, toggleable by clicking the right icon button in the bottom bar.
- The button on the right allows for changing the box wallpaper.
- The option buttons on the left side allow for sorting the box by name, level, Pokédex number, gender, and type. Shift clicking allows for sorting in reverse order.
- The button on the right allows for changing the box wallpaper.
- 10 additional color-based wallpapers have been added.
- 5 unlockable biome-based wallpapers have been added, which can be unlocked by visiting:
- Forest biome
- Ocean biome
- Cave Biome
- The End
- The Nether
- 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.
- Added ability to change boxes by scrolling.
- The displays can be cycled through by scrolling when the display is hovered over.
- Added ability to cycle through boxes by scrolling when the box is hovered over.
- 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.
- Increased the default PC box count from 30 to 40 to accommodate the fact that we have way more Pokémon now. If you've changed this config option then you'll need to edit it again after starting up with 1.7!
### Developer
- Added `RenamePCBoxEvent.Pre` and `RenamePCBoxEvent.Post` events to prevent players from renaming a box or changing their input.
+1
View File
@@ -4,6 +4,7 @@
### Fixes
- Fixed the "enabled" property in spawn files not actually being respected. Where do they find these devs?
- Fixed Terralith's shrubland not counting as plains for spawning purposes the way it was intended to.
### Developer
- Spawning Influences now have the context of what the other buckets are when adjusting bucket weights. This will break existing influences that do bucket weight adjustment.
+407 -17
View File
@@ -11,11 +11,11 @@
- 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.
- Added cosmetics for Spoink, Gurdurr, Conkeldurr, Squirtle Line, Sneasler, Sandile line, Treecko line, Braixen, Delphox, and Dragonite.
- Added Gilded Chest cosmetics for Chest Gimmighoul and Gholdengo
- Added `visibility/hidden`, `visibility/hat` and `visibility/face` tags to control where and how certain items are rendered.
- Added Pokémon markings, toggleable within the summary.
- Added `/boxcount` command to change PC boxes amount
- Added cosmetics for Gurdurr, Conkeldurr, Squirtle Line, Sneasler, Sandile line, Treecko line, Braixen, Delphox, and Dragonite.
- 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.
@@ -23,7 +23,7 @@
- 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, 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 Recipes for Masterpiece Cup, Eject Pack.
- Added modification to Minecraft Creative Inventory search to account for item names that contain `poké` when input contains `poke`.
- Added Campfire Pot as well as loads of new food items (Poke Puffs, Ponigiri, Sinister Tea, etc)
- Added Hearty Grains, a new crop used in the new cooking mechanic
@@ -39,21 +39,48 @@
- 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 optional `filePath` parameter to MoLang functions to allow for global stores (ex. `../global/`). Path must end in a forward slash.
- 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.
- Some Pokémon now pitch their bodies in the direction they're moving.
- Added new advancements Didn't Stop To Think, We Need To Cook, and Pokémon Jockey!.
- Berries can now be smelted into their respective dyes.
- Added Syrupy Apples.
- Added `/runmolang <molang> [<npc>|<player>|<pokemon>]` command that executes a MoLang expression with the provided options as environment variables, as well as the entity (as `q.entity`) that executed the command.
- Added bubble quirk to Kingler; like Krabby, Kingler will blows bubbles during dusk.
- Added `.Pre` and `.Post` to the following events:
- `PokemonRecallEvent`
- `TradeEvent`
- Added a new gamerule, 'healerHealsPC', when set to true a successful use of a healer will also heal all of the Pokemon in that player's PC.
### Pokémon Added
#### Gen 2
- Marill
- Azumarill
- Hoppip
- Skiploom
- Jumpluff
- Dunsparce
- Togepi
- Togetic
- Unown
- Houndour
- Houndoom
- Ho-Oh
- Lugia
- Alola Bias Pichu (built-in resourcepack)
#### Gen 3
- Azurill
- Meditite
- Medicham
- Electrike
- Manectric
- Spoink
- Grumpig
- Swablu
- Altaria
- Snorunt
- Glalie
- Latias
@@ -67,6 +94,9 @@
- Froslass
- Glameow
- Purugly
- Skorupi
- Drapion
- Togekiss
#### Gen 5
- Pansage
@@ -89,25 +119,60 @@
- Solosis
- Duosion
- Reuniclus
- Tynamo
- Eelektrik
- Eelektross
- Axew
- Fraxure
- Haxorus
- Mienfoo
- Mienshao
- Sewaddle
- Swadloon
- Leavanny
- Druddigon
#### Gen 6
- Skiddo
- Gogoat
- Espurr
- Meowstic
- Inkay
- Malamar
- Hawlucha
- Dedenne
- Noibat
- Noivern
- Furfrou
- You can change Furfrou's form by using shears on it while it holds a certain dye in its cosmetic slot.
#### Gen 7
- Yungoos
- Gumshoos
- Drampa
- Alolan Grimer
- Alolan Muk
- Togedemaru
#### Gen 8
- Skwovet
- Greedent
- Chewtle
- Drednaw
- Toxel
- Toxtricity
- Morpeko
- Silicobra
- Sandaconda
- Sinistea
- Polteageist
- Galarian Corsola
- Cursola
- Mr. Rime
- Galarian Mr. Mime
- Clobbopus
- Grapploct
- Galarian Weezing
#### Gen 9
- Smoliv
@@ -120,13 +185,24 @@
- Cyclizar
- Poltchageist
- Sinistcha
- Capsakid
- Scovillain
- Tadbulb
- Bellibolt
- Toedscool
- Toedscruel
- Rellor
- Rabsca
- Bramblin
- Brambleghast
### Animation updates for the following Pokémon
- Garchomp
- Tropius
- Torpius
- Nosepass
- Probopass
- Sneasel
- Weavile
- Sneasler
- Braixen
- Delphox
@@ -141,8 +217,86 @@
- Dratini
- Dragonair
- Dragonite
- G. Corsola
- Cursola
- Dunsparce
- Dudunsparce (both forms)
- Porygon
- Porygon2
- Porygon-Z
- Wattrel
- Kilowattrel
- Golurk
- Spinarak
- Ariados
- Wyrdeer
- Tyrantrum
- Pidove
- Tranquill
- Unfezant
- Beldum
- Metang
- Metagross
- Plusle
- Minun
- Murkrow
- Honchkrow
- Larvesta
- Volcarona
- Dwebble
- Crustle
- Mr. Mime
- Flygon
- Pichu
- Pikachu
- Raichu
- Alolan Raichu
- Espathra
- Abra
- Kadabra
- Alakazam
- Deino
- Zweilous
- Hydreigon
- Slaking
- Klink
- Klang
- Klinklang
- Baltoy
- Claydol
- Mamoswine
- Rufflet
- Braviary
- Girafarig
- Farigiraf
- Rookidee
- Corvisquire
- Corviknight
- Venipede
- Whirlipede
- Scolipede
- Venusaur
- Parasect
- Bastiodon
- Amaura
- Varoom
- Revavroom
- Bouffalant
- Lickilicky
- Blaziken
- Rhyhorn
- Rhydon
- Rhyperior
- Tauros
- Tauros - Paldea Aqua
- Tauros - Paldea Blaze
- Tauros - Paldea Combat
- Dewgong
### Model updates for the following Pokémon
- Cleffa
- Clefairy
- Clefable
- Gyarados
- Dragonite
- Eevee
@@ -188,12 +342,66 @@
- Cacturne
- Taillow
- Swellow
- Added Syrupy Apples.
- Seel
- Dewgong
- Honedge
- Doublade
- Aegislash
- Drowzee
- Hypno
- Mudkip
- Marshtomp
- Swampert
- Shelmet
- Escavalier
- Klink
- Klank
- Klinklang
- Spinarak
- Ariados
- Pidove
- Tranquill
- Unfezant
- Sobble
- Drizzile
- Inteleon
- Plusle
- Minun
- Murkrow
- Zorua
- Zoroark
- Mime.Jr
- Mr. Mime
- Pichu
- Pikachu
- Raichu
- Alolan Raichu
- Dusknoir
- Deino
- Zweilous
- Hydreigon
- Dreepy
- Drakloak
- Dragapult
- Mamoswine
- Rookidee
- Corvisquire
- Corviknight
- Venipede
- Whirlipede
- Scolipede
- Farigiraf
- Staryu
- Starmie
- Gimmighoul
- Gholdengo
- Starly
- Staravia
- Staraptor
- Varoom
- Revavroom
- Nickit
- Thievul
### Changes
- Changed pokemon caught and seen count to update based on the current pokedex being looked
@@ -249,6 +457,15 @@
- MoLang `run_action_effect` now works on Pokémon.
- Changed MoLang entity function `is_standing_on` to allow for block tags in the list.
- Added entity (as `q.entity`) that executed the command to the `executemolangscript` command.
- Refactored the following events to `.Pre` and `.Post` for consistency:
- `PokemonSentEvent`
- `ExperienceGainedEvent`
- `BattleStartedEvent`
- Updated `PokemonSentEvent` parameters to include the Position and Level of the Pokémon being sent out.
- Updated `EvolutionCompleteEvent` parameters to include the Source Pokemon that evolved.
- Updated `HatchEggEvent.Post` to include the Pokemon that hatched.
- Roseli Berry Trees now naturally generate in their preferred biomes.
- Refactored dynamic lights compat to be more future proof. The dynamic light support is only tested with LambDynamicLights, on NeoForged use that mod in combination with Sinytra Connector
### Fixes
- Fixed game crashing when removing national pokedex using datapacks
@@ -292,8 +509,8 @@
- 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 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
@@ -311,13 +528,27 @@
- 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 recoil eyes on Shellder & Cloyster.
- Fixed Shroomish spinning at lightning speed when fainting (no longer allowed to let it rip.)
- Fixed Pokédex Scanner not respecting the "Invert Mouse" option.
- Fixed a crash due to a ConcurrentModificationException that could occur during world generation.
- Fixed Quaxly's animations showing hidden wing sets
- 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.
- Fixed BotanyPots built-in integration
- Fixed shading of berries on berry trees.
- Fixed static text cursor for nickname input in summary.
- Fixed Cobblemon brewing recipes placing result into all slots, and not just slots with correct ingredients inside the brewing stand.
- Fixed an issue where hoppers and brewing stands were not recognizing Cobblemon brewing recipes.
- Fixed global species features... not working. Since they were created. Oops.
- Fixed Pokémon with alternate forms being created with an incorrect 'forced' tag on their ability.
- Fixed busted abilities and moves in Pokémon data due to removed datapacks etc. causing storage corruption. It now just rerolls their ability / uses Tackle.
- Fixed singular Pokémon corruption causing entire storage corruption. Storages will now skip corrupted Pokémon and print an error to console.
- Fixed species additions not being able to properly mark a species as implemented.
### Developer
- A finished battle now has winners and losers set inside of `PokemonBattle` instead of them always being empty.
@@ -329,9 +560,8 @@
- Renamed Cobblemon's creative tabs to start with "Cobblemon: " to distinguish Cobblemon's tabs from tabs for other mods.
- Various items now have a rarity value.
- Reworked observable handling in `Pokemon.kt` to cut down on RAM usage and clarify the file.
- Note: This will break mods that used our observable functionality there or in MoveSet, IVs, EVs, or BenchedMoves.
- Note: This will break mods that used our observable functionality there or in MoveSet, IVs, EVs, or BenchedMoves.
- Using `Pokemon#onChange()` is now the way to mark a Pokémon as needing a save.
- Using `[Pokemon].changeObservable` is now the way to get an `Observable` for any save-worthy changes.
- Updated NPCEntity beam positioning to properly account for the baseScale property.
- 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`
@@ -360,7 +590,7 @@
- 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)
- The `requiredContext` for an item interaction evolution
@@ -412,6 +642,166 @@
- Added `is_included`, `to_lower`, `to_upper`, and `string_length` as available Molang functions.
- Fixed a crash that would occur during battles if the opponent wild Pokémon species comes from a namespace other than cobblemon
- Fixed `clientActions` inside Dialogue pages being executed twice
- Added `q.split_string(<text>, <delimiter/comma>)` Outputs an array with the divided text.
- Added `q.spawn_npc(<x>, <y>, <z>, <npc>)` Spawns an NPC at the given coordinates and returns the NPC.
- Added `q.player.seen_credits` Returns whether the player has seen the end credits.
- Added `q.player.is_in_dialogue` Returns whether the player is currently in a dialogue.
- Added `q.player.active_dialogue` Returns the active dialogue of the player, or null if none.
- Added `q.player.is_spectator` Returns whether the player is in spectator mode.
- Added `q.player.is_adventure` Returns whether the player is in adventure mode.
- Added `q.player.is_creative` Returns whether the player is in creative mode.
- Added `q.player.is_survival` Returns whether the player is in survival mode.
- Added `q.player.set_battle_theme(<sound resource>)` Sets the player's battle theme to the given theme.
- Added `q.player.battle_music(<sound_resource>, <volume>, <pitch>)` Plays the given battle music for the player.
- Added `q.player.stop_battle_music()` Stops any currently playing battle music for the player. (With a fade out).
- Added `q.player.riding_pokemon` Returns the Pokémon the player is currently riding.
- Added `q.entity.is_player` Returns whether the entity is a player.
- Added `q.entity.is_pokemon` Returns whether the entity is a Pokémon.
- Added `q.entity.is_npc` Returns whether the entity is an NPC.
- Added `q.entity.is_mob` Returns whether the entity is a vanilla mob.
- Added `q.entity.is_animal` Returns whether the entity is an animal.
- Added `q.entity.is_hostile` Returns whether the entity is a hostile mob.
- Added `q.entity.is_baby` Returns whether the entity is a baby.
- Added `q.entity.is_adult` Returns whether the entity is an adult.
- Added `q.entity.is_tamable` Returns whether the entity is tamable.
- Added `q.entity.is_tamed` Returns whether the entity is tamed.
- Added `q.entity.add_effect(<effect>, <duration>, <amplifier>, <ambient> <show_particles>)` Adds a status effect to the entity.
- Added `q.entity.remove_effect(<effect>)` Removes a status effect from the entity.
- Added `q.entity.has_effect(<effect>)` Returns whether the entity has the given status effect.
- Added `q.entity.is_looking_at(<entity>)` Returns whether the entity is looking at the given entity.
- Added `q.entity.tags` Returns an array of the entity's tags.
- Added `q.entity.add_tag(<tag>)` Adds the given tag to the entity.
- Added `q.entity.remove_tag(<tag>)` Removes the given tag from the entity.
- Added `q.entity.has_tag(<tag>)` Returns whether the entity has the given tag.
- Added `q.entity.make_intangible(<true/false>)` Makes the entity intangible.
- Added `q.pokemon.force_evolve(<index>)` Forces the Pokémon at the given index.
- Added `q.pokemon.can_evolve` Returns whether the Pokémon at the given index can evolve.
- Added `q.pokemon.is_busy` Returns whether the Pokémon is busy.
- Added `q.pokemon.is_rideable` Returns whether the Pokémon is rideable.
- Fixed `background` field and added `textColor` field for dialogues.
- Added support to reload some data registries:
- MoLang scripts
- Callbacks
- Spawn Detail Presets
- Spawn Pools
- Spawn Rules
- Cosmetic Items
- Dialogues
- Fossils
- Natural Materials
- Action Effects
- Mechanics
- Unlockable Wallpapers
- Starter Data
### Particles
Added new/updated particles for the following moves:
- Absorb
- Acid
- Acid Spray
- Aerial Ace
- Amnesia
- Aurora Beam
- Bite
- Body Slam
- Bubble
- Bubble Beam
- Bulldoze
- Bullet Punch
- Close Combat
- Confusion
- Crunch
- Cotton Guard
- Double Team
- Dragon Claw
- Egg Bomb
- Ember
- Eruption
- Explosion
- Fire Blast
- Fire Punch
- Fire Spin
- Flame Burst
- Flame Charge
- Flamethrower
- Flame Wheel
- Frost Breath
- Frustration
- Giga Drain
- Growl
- Haze
- Hidden Power
- Horn Attack
- Hyper Fang
- Hypnosis
- Ice Beam
- Ice Punch
- Ice Shard
- Icy Wind
- Infestation
- Kinesis
- Lava Plume
- Leech Life
- Leech Seed
- Leer
- Lick
- Magical Leaf
- Mega Drain
- Minimize
- Mist
- Mud Bomb
- MudSport
- Mystical Fire
- Nasty Plot
- Poison Fang
- Poison Gas
- Poison Powder
- Population Bomb
- Pound
- Powder
- Powder Snow
- Present
- Protect
- Psybeam
- Psychic
- Pursuit
- Quick Attack
- Rage Powder
- Razor Leaf
- Return
- Rock Throw
- Sand Attack
- Scary Face
- Scratch
- Seed Bomb
- Seismic Toss
- Self Destruct
- Shadow Ball
- Shadow Claw
- Sing
- Sleep Powder
- Sludge Bomb
- Smokescreen
- Spike
- Spore
- Stomp
- String Shot
- Stun Spore
- Super Fang
- Swords Dance
- Tackle
- Tail Whip
- Thunder
- Thunder Punch
- Thunderbolt
- Thunder Shock
- Thunder Wave
- Toxic
- Water Gun
- Water Pulse
- Water Sport
- Will-O-Wisp
- Withdraw
## [1.6.1 (January 26th, 2025)](#1-6-1)
@@ -424,7 +814,7 @@
- Added optional box argument to the /pc command.
- Pokédex and Dialogue screens now close when the inventory keybind is pressed.
- Added config setting `maxPokedexScanningDetectionRange` to control from what distance the player can scan Pokémon using the Pokédex.
- Added config setting `hideUnimplementedPokemonInThePokedex` which hides unimplemented Pokémon from the Pokédex when set to true.
- Added config setting `hideUnimplementedPokemonInThePokedex` which hides unimplemented Pokémon from the Pokédex when set to true.
- Added debug renderer for posable entity locators.
- Added crossover paintings from Close Combat, Premonition, Altar, Slumber, and Nomad.
- Added optional box argument to the /pc command
@@ -578,7 +968,7 @@
- Fixed Vivichoke Dip and Leek & Potato Stew not returning a bowl upon consumption.
- Fixed Fossil Restoration Tank not accepting Hay Bales as organic material.
- Fixed Potion items applying double their intended healing value.
- Fixed Fast Ball capture bonuses applying to all Pokémon, making it the Best Ball instead of the Mediocre Edge-Case Ball.
- Fixed Fast Ball capture bonuses applying to all Pokémon, making it the Best Ball instead of the Mediocre Edge-Case Ball.
- Fixed "learned new move" messages appearing for already-known moves on Pokémon evolutions.
- Fixed Pokémon Item Models breaking shadows nearby when being placed in Display Cases or Item Frames.
- Fixed berries not giving bonus yields when planted in their preferred biomes. I'm sure we've fixed that 5 times now.
@@ -587,7 +977,7 @@
- Fixed players with shouldered Pokémon not being able to rejoin their 1.5.2 worlds using 1.6.
- Fixed `PokemonProperties` utilizing `ability=<some ability>` being treated as a forced ability even when it is a legal ability for the Pokémon.
- Fixed type formatting in Pokédex scanner mode when dual types require two lines.
- Fixed trading sometimes crashing the game or server.
- Fixed trading sometimes crashing the game or server.
- Fixed Wild shiny sounds not respecting the `shinyNoticeParticlesDistance` config setting.
- Fixed Pokémon being able to evolve mid-battle.
- Fixed NPC held items being able to be stolen by players. Don't be a thief!
@@ -681,7 +1071,7 @@
- Stonjourner Henge Ruins, Luna Henge Ruins, and Sol Henge Ruins.
- Submerged Shipwreck Cove and Lush Shipwreck Cove.
- Pokémon Centers to all 5 village types.
### Pokémon Added
#### Gen 1
- Alola Bias Cubone (built-in resource pack)
@@ -1004,7 +1394,7 @@
- Big Roots and Energy Roots now share the same sounds as intended.
- Fixed sounds made by blocks playing at a lower pitch than intended.
- Fixed Chimchar and Monferno comically T posing whenever they sleep.
- Fixed Cetitan's cry breaking its walk and sleep animations.
- Fixed Cetitan's cry breaking its walk and sleep animations.
- Fixed the Magby line not having any placeholder walk animations.
- Fixed Duskull and Dusclops using skylight levels for their nether spawn data. There is no sun in the Nether!
- Fixed Hisuian Zoroark using base Zoroark stats.
@@ -1020,7 +1410,7 @@
- Fixed Trevenant T-posing after 8 seconds of sleeping. I also do that.
- Fixed Bewear T-posing for a bit if a wild one faints where you can see.
- Fixed Noctowl's placeholder fly animation.
- Corrected Lotad blinking animation.
- Corrected Lotad blinking animation.
- Fixed reviving items causing errors when used in battle.
- Fixed messages for Focus Sash, Confusion, Mummy, Ice Face, Own Tempo, and Revive.
- Improve error handling when loading spawn-sets to ensure invalid configurations don't crash the server.
@@ -1110,7 +1500,7 @@
- Added a new universal locator called "top".
- Added `eggs_collected` and `eggs_hatched` Advancement triggers.
- Added missing `minYaw` configuration to the `q.look()` function for JSON posers.
- Some pose condition names have been changed:
- Some pose condition names have been changed:
- `isTouchingWaterOrRain` has been changed to `isInWaterOrRain`
- `isSubermegedInWater` has been changed to `isUnderWater`
+8 -1
View File
@@ -31,6 +31,7 @@ repositories {
maven(url = "${rootProject.projectDir}/deps")
maven(url = "https://api.modrinth.com/maven")
maven(url = "https://maven.neoforged.net/releases")
maven(url = "https://maven.gegy.dev")
mavenLocal()
}
@@ -44,6 +45,12 @@ dependencies {
modCompileOnly(libs.bundles.common.integrations.compileOnly) {
isTransitive = false
}
// LambDynamicLights is handled differently because we need the Mojang-mappings version of it.
modCompileOnly(libs.lambDynamicLights) {
capabilities {
requireCapability("dev.lambdaurora.lambdynamiclights:api-mojmap")
}
}
// Flywheel has no common dep so just pick one and don't use any platform specific code in common
// modCompileOnly(libs.flywheelFabric)
@@ -94,4 +101,4 @@ sourceSets {
}
}
}
}
}
@@ -1,102 +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.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;
import dev.lambdaurora.lambdynlights.api.DynamicLightHandler;
import dev.lambdaurora.lambdynlights.api.DynamicLightHandlers;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import net.minecraft.world.entity.player.Player;
// Java class due to relying on entrypoint on Fabric side
public class LambDynamicLightsCompat {
// This is all called on client side
// These things are checked every tick so try to keep it as free as possible
// That being said it's unlikely school Toshiba person is running dynamic lighting and shaders to enjoy this
// Make sure not to call anything Fabric specific :)
public static void hookCompat() {
// Pokémon entities
DynamicLightHandlers.registerDynamicLightHandler(
CobblemonEntities.POKEMON,
DynamicLightHandler.makeHandler(
LambDynamicLightsCompat::resolvedPokemonLightLevel,
pokemon -> false
)
);
// Shouldered Pokémon
DynamicLightHandlers.registerDynamicLightHandler(
EntityType.PLAYER,
DynamicLightHandler.makeHandler(
LambDynamicLightsCompat::resolvedPlayerLightLevel,
player -> false
)
);
}
private static int resolvedPokemonLightLevel(PokemonEntity pokemon) {
var underwater = !pokemon.level().getFluidState(BlockPos.containing(pokemon.getX(), pokemon.getEyeY(), pokemon.getZ())).isEmpty();
ItemStack item = pokemon.getShownItem();
int itemLightLevel = item.isEmpty()?0:LambDynLights.getLuminanceFromItemStack(item, underwater);
int formLightLevel = extractFormLightLevel(pokemon.getForm(), underwater).orElse(0);
return Math.max(itemLightLevel, formLightLevel);
}
private static int resolvedPlayerLightLevel(Player player) {
var underwater = !player.level().getFluidState(BlockPos.containing(player.getX(), player.getEyeY(), player.getZ())).isEmpty();
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) {
if (form.getLightingData() == null || !liquidGlowModeSupport(form.getLightingData().getLiquidGlowMode(), underwater)) {
return Optional.empty();
}
return Optional.of(form.getLightingData().getLightLevel());
}
private static int extractShoulderLightLevel(@Nullable PokemonOnShoulderRenderer.ShoulderData shoulderData, boolean underwater) {
if (shoulderData == null) {
return 0;
}
ItemStack item = shoulderData.getShownItem();
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,28 @@
/*
* 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.compat.lambdynamiclights;
import com.cobblemon.mod.common.pokemon.FormData;
import com.cobblemon.mod.common.pokemon.lighthing.LightingData;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
public abstract class CustomLuminance {
protected static Optional<Integer> extractFormLightLevel(@NotNull FormData form, boolean underwater) {
if (form.getLightingData() == null || !liquidGlowModeSupport(form.getLightingData().getLiquidGlowMode(), underwater)) {
return Optional.empty();
}
return Optional.of(form.getLightingData().getLightLevel());
}
protected static boolean liquidGlowModeSupport(@NotNull LightingData.LiquidGlowMode liquidGlowMode, boolean underwater) {
return underwater ? liquidGlowMode.getGlowsUnderwater() : liquidGlowMode.getGlowsInLand();
}
}
@@ -0,0 +1,42 @@
/*
* 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.compat.lambdynamiclights;
import com.cobblemon.mod.common.Cobblemon;
import dev.lambdaurora.lambdynlights.api.DynamicLightsContext;
import dev.lambdaurora.lambdynlights.api.DynamicLightsInitializer;
import dev.lambdaurora.lambdynlights.api.entity.luminance.EntityLuminance;
import dev.lambdaurora.lambdynlights.api.item.ItemLightSourceManager;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
public class LambDynamicLightsInitializer implements DynamicLightsInitializer {
public static final EntityLuminance.Type POKEMON_LUMINANCE = EntityLuminance.Type.registerSimple(
ResourceLocation.fromNamespaceAndPath(Cobblemon.MODID, "pokemon"),
PokemonLuminance.INSTANCE
);
public static final EntityLuminance.Type PLAYER_LUMINANCE = EntityLuminance.Type.registerSimple(
ResourceLocation.fromNamespaceAndPath(Cobblemon.MODID, "shoulder"),
PlayerLuminance.INSTANCE
);
@Override
public void onInitializeDynamicLights(DynamicLightsContext context) {
Cobblemon.LOGGER.info("Lamb Dynamic Lights compatibility enabled");
context.entityLightSourceManager().onRegisterEvent().register(ctx -> {
ctx.register(EntityType.PLAYER, PlayerLuminance.INSTANCE);
});
}
@SuppressWarnings({"removal", "UnstableApiUsage"})
@Override
public void onInitializeDynamicLights(ItemLightSourceManager itemLightSourceManager) {}
}
@@ -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.compat.lambdynamiclights;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer;
import dev.lambdaurora.lambdynlights.api.entity.luminance.EntityLuminance;
import dev.lambdaurora.lambdynlights.api.item.ItemLightSourceManager;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Range;
public final class PlayerLuminance extends CustomLuminance implements EntityLuminance {
public static final PlayerLuminance INSTANCE = new PlayerLuminance();
private static final TagKey<Item> POKEDEX = TagKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(Cobblemon.MODID, "pokedex"));
@Override
public @NotNull Type type() {
return LambDynamicLightsInitializer.PLAYER_LUMINANCE;
}
@Override
public @Range(from = 0L, to = 15L) int getLuminance(@NotNull ItemLightSourceManager itemLightSourceManager, @NotNull Entity entity) {
if (entity instanceof Player player) {
final int shoulderLightLevel = shoulderLuminance(itemLightSourceManager, player);
final int itemLightLevel = player.isHolding(stack -> stack.is(POKEDEX)) ? 13 : 0;
return Math.max(shoulderLightLevel, itemLightLevel);
} else {
return 0;
}
}
private @Range(from = 0L, to = 15L) static int shoulderLuminance(@NotNull ItemLightSourceManager itemLightSourceManager, @NotNull Player player) {
final var leftShoulder = PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityLeft());
final var rightShoulder = PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityRight());
if (leftShoulder == null && rightShoulder == null) {
return 0;
}
final int leftShoulderLightLevel = extractShoulderLightLevel(leftShoulder, itemLightSourceManager, player.isUnderWater());
final int rightShoulderLightLevel = extractShoulderLightLevel(rightShoulder, itemLightSourceManager, player.isUnderWater());
return Math.max(leftShoulderLightLevel, rightShoulderLightLevel);
}
private static int extractShoulderLightLevel(@Nullable PokemonOnShoulderRenderer.ShoulderData shoulderData, @NotNull ItemLightSourceManager itemLightSourceManager, boolean underwater) {
if (shoulderData == null) {
return 0;
}
ItemStack item = shoulderData.getShownItem();
int itemLightLevel = item.isEmpty() ? 0 : itemLightSourceManager.getLuminance(item, underwater);
int formLightLevel = extractFormLightLevel(shoulderData.getForm(), underwater).orElse(0);
return Math.max(itemLightLevel, formLightLevel);
}
}
@@ -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.compat.lambdynamiclights;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import dev.lambdaurora.lambdynlights.api.entity.luminance.EntityLuminance;
import dev.lambdaurora.lambdynlights.api.item.ItemLightSourceManager;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range;
public final class PokemonLuminance extends CustomLuminance implements EntityLuminance {
public static final PokemonLuminance INSTANCE = new PokemonLuminance();
private PokemonLuminance() {}
@Override
public @NotNull Type type() {
return LambDynamicLightsInitializer.POKEMON_LUMINANCE;
}
@Override
public @Range(from = 0L, to = 15L) int getLuminance(
@NotNull ItemLightSourceManager itemLightSourceManager,
@NotNull Entity entity
) {
if (entity instanceof PokemonEntity pokemon) {
boolean underwater = pokemon.isUnderWater();
ItemStack item = pokemon.getShownItem();
int itemLightLevel = item.isEmpty() ? 0 : itemLightSourceManager.getLuminance(item, underwater);
int formLightLevel = extractFormLightLevel(pokemon.getForm(), underwater).orElse(0);
return Math.max(itemLightLevel, formLightLevel);
} else {
return 0;
}
}
}
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.EnderpearlItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
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.Comparator;
@Mixin(EnderpearlItem.class)
public abstract class EnderPearlItemMixin {
@Inject(method = "use", at = @At(value = "HEAD"), cancellable = true)
private void cobblemon$use(Level level, Player player, InteractionHand usedHand, CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir) {
double range = player.entityInteractionRange();
Entity closestEntity = level.getEntities(player, AABB.ofSize(player.position(), range, range, range)).stream()
.filter(entity -> isLookingAt(player, entity))
.min(Comparator.comparingDouble(entity -> entity.distanceTo(player)))
.orElse(null);
if (closestEntity instanceof PokemonEntity pokemonEntity) {
if (player.isCrouching() && pokemonEntity.getOwnerUUID() == player.getUUID()) {
cir.cancel();
}
}
}
public boolean isLookingAt(Player player, Entity other) {
float maxDistance = 10F;
float stepDistance = 0.1F;
double step = stepDistance;
Vec3 startPos = player.getEyePosition();
Vec3 direction = player.getLookAngle();
while (step <= maxDistance) {
Vec3 location = startPos.add(direction.scale(step));
step += stepDistance;
if (other.getBoundingBox().contains(location)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokemon.ai.EntityBehaviour;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.goal.AvoidEntityGoal;
import net.minecraft.world.entity.animal.Fox;
import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Fox.class)
public class EntityFoxMixin extends Mob {
private EntityFoxMixin(net.minecraft.world.entity.EntityType<? extends Creeper> entityType, Level world) {
super(entityType, world);
}
@Inject(method = "registerGoals", at = @At(value = "TAIL"), cancellable = false)
private void cobblemon$initGoals(CallbackInfo callbackInfo) {
final Fox fox = (Fox) (Object) this;
// Pokemon Entities
this.goalSelector.addGoal(
4,
new AvoidEntityGoal<>(
fox,
PokemonEntity.class,
8.0f,
1.6,
1.4,
entity -> ((PokemonEntity)entity).getBehaviour().getEntityInteract().getAvoidedByFox() && ((PokemonEntity)entity).getBeamMode() != 1
)
);
// Players with shoulder mounted Pokemon
this.goalSelector.addGoal(
3,
new AvoidEntityGoal<>(
fox,
ServerPlayer.class,
8.0f,
1.6,
1.4,
entity -> EntityBehaviour.Companion.hasFoxFearedShoulderMount((ServerPlayer)entity)
)
);
}
}
@@ -58,11 +58,9 @@ public abstract class LivingEntityMixin extends Entity implements OrientationCon
@Override
public @NotNull HitResult pick(double hitDistance, float partialTicks, boolean hitFluids) {
Entity vehicle = this.getVehicle();
if (vehicle instanceof PokemonEntity pokemonEntity) {
if (vehicle instanceof PokemonEntity pokemonEntity && pokemonEntity.getDelegate() instanceof PokemonClientDelegate delegate) {
int seatIndex = pokemonEntity.getPassengers().indexOf(this);
Seat seat = pokemonEntity.getSeats().get(seatIndex);
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemonEntity.getDelegate();
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
@@ -0,0 +1,28 @@
/*
* 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.bedrockk.molang.runtime.value.DoubleValue;
import com.cobblemon.mod.common.entity.MoLangScriptingEntity;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.PowderSnowBlock;
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(PowderSnowBlock.class)
public abstract class PowderSnowBlockMixin {
@Inject(method = "canEntityWalkOnPowderSnow", at = @At(value = "RETURN"), cancellable = true)
private static void cobblemon$canEntityWalkOnPowderSnow(Entity entity, CallbackInfoReturnable<Boolean> ci) {
if (ci.getReturnValue() == false && entity instanceof MoLangScriptingEntity) {
ci.setReturnValue(((MoLangScriptingEntity) entity).getConfig().getMap().getOrDefault("can_stand_on_powder_snow", DoubleValue.ZERO).asDouble() == 1.0);
}
}
}
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import com.bedrockk.molang.runtime.value.DoubleValue;
import com.cobblemon.mod.common.entity.MoLangScriptingEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.SweetBerryBushBlock;
import net.minecraft.world.level.block.state.BlockState;
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(SweetBerryBushBlock.class)
public abstract class SweetBerryBushBlockMixin {
@Inject(method = "entityInside", at = @At(value = "HEAD"), cancellable = true)
private void cobblemon$entityInside(BlockState state, Level level, BlockPos pos, Entity entity, CallbackInfo callbackInfo) {
if (entity instanceof MoLangScriptingEntity) {
if (((MoLangScriptingEntity) entity).getConfig().getMap().getOrDefault("immune_to_sweet_berry_bush_block", DoubleValue.ZERO).asDouble() == 1.0) {
callbackInfo.cancel();
}
}
}
}
@@ -25,9 +25,9 @@ public class TargetingConditionsMixin {
@Inject(method = "test", at = @At("HEAD"), cancellable = true)
public void test(@Nullable LivingEntity baseEntity, LivingEntity targetEntity, CallbackInfoReturnable<Boolean> ci) {
if (targetEntity instanceof ServerPlayer player) {
boolean canTargetInBattle = player.level().getGameRules().getBoolean(CobblemonGameRules.MOB_TARGET_IN_BATTLE);
if (player.level().getGameRules().getBoolean(CobblemonGameRules.MOB_TARGET_IN_BATTLE)) return;
boolean targetInBattle = Cobblemon.INSTANCE.getBattleRegistry().getBattleByParticipatingPlayer(player) != null;
if (!canTargetInBattle && targetInBattle) ci.setReturnValue(false);
if (targetInBattle) ci.setReturnValue(false);
}
}
}
@@ -15,9 +15,11 @@ 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.Direction;
import net.minecraft.core.NonNullList;
import net.minecraft.world.Containers;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionBrewing;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeManager;
@@ -27,6 +29,8 @@ 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 org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
import java.util.Optional;
@@ -43,7 +47,9 @@ public class BrewingStandBlockEntityMixin {
//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());
if (!slots.get(i).isEmpty()){
slots.set(i, recipe.getResult().copy());
}
}
itemStack.shrink(1);
@@ -91,4 +97,35 @@ public class BrewingStandBlockEntityMixin {
return recipeHolder.map(RecipeHolder::value).orElse(null);
}
@Inject(method = "canPlaceItem", at = @At("HEAD"), cancellable = true)
private void cobblemon$canPlaceItem(int slot, ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
if (stack == null || stack.isEmpty()) return;
BrewingStandBlockEntity self = (BrewingStandBlockEntity) (Object) this;
Level level = self.getLevel();
if (level != null) {
var rm = level.getRecipeManager();
//Input slot
if (slot == 3) {
if (BrewingStandRecipe.Companion.isInput(stack, rm)) {
cir.setReturnValue(true);
return;
}
}
// Output slots
if (slot >= 0 && slot < 3) {
if (BrewingStandRecipe.Companion.isBottle(stack, rm)) {
if (self.getItem(slot).isEmpty()) {
cir.setReturnValue(true);
} else {
cir.setReturnValue(false);
}
}
}
}
}
}
@@ -31,14 +31,15 @@ public class AbstractClientPlayerMixin {
PokedexUsageContext usageContext = CobblemonClient.INSTANCE.getPokedexUsageContext();
if (usageContext.getScanningGuiOpen()) {
cir.setReturnValue(usageContext.getFovMultiplier());
}
} else {
// Only modify fov through riding if the pokedex is not open
LocalPlayer player = (LocalPlayer) (Object) this;
if (player != null && player.isPassenger() && player.getVehicle() instanceof PokemonEntity) {
PokemonEntity ride = (PokemonEntity) player.getVehicle();
LocalPlayer player = (LocalPlayer) (Object) this;
if (player != null && player.isPassenger() && player.getVehicle() instanceof PokemonEntity) {
PokemonEntity ride = (PokemonEntity) player.getVehicle();
//Return custom fov mult
cir.setReturnValue(ride.rideFovMult());
// Return custom fov mult for riding
cir.setReturnValue(ride.rideFovMult());
}
}
}
}
@@ -0,0 +1,46 @@
/*
* 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;
import com.cobblemon.mod.common.client.render.player.MountedPlayerRenderer;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.model.AgeableListModel;
import net.minecraft.client.model.HumanoidModel;
import net.minecraft.client.model.Model;
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;
/**
* This mixin adds to the head of the renderToBuffer function and allows us to detect if it is a HumanoidModel and
* is being rendered as part of a player in the world who is riding a PokemonEntity. If so we need to obey any
* root animations that have been applied earlier.
*
* @author Hiroku
* @since May 16, 2025
*/
@Mixin(AgeableListModel.class)
public class AgeableListModelMixin {
@Inject(method = "renderToBuffer", at = @At("HEAD"))
private void cobblemon$renderToBuffer(
PoseStack poseStack,
VertexConsumer vertexConsumer,
int packedLight,
int packedOverlay,
int colour,
CallbackInfo ci
) {
Model model = (Model) (Object) this;
if (model instanceof HumanoidModel<?> && MountedPlayerRenderer.shouldApplyRootAnimation) {
MountedPlayerRenderer.INSTANCE.animateRoot(poseStack);
}
}
}
@@ -55,7 +55,7 @@ public abstract class CameraMixin {
@Inject(method = "setRotation", at = @At("HEAD"), cancellable = true)
public void cobblemon$setRotation(float f, float g, CallbackInfo ci) {
if (!(this.entity instanceof OrientationControllable controllable) || Cobblemon.config.getDisableRoll()) return;
if (!(this.entity instanceof OrientationControllable controllable)) return;
var controller = controllable.getOrientationController();
if (!controller.isActive() && controller.getOrientation() != null) {
if(this.returnTimer < 1) {
@@ -19,20 +19,17 @@ import net.minecraft.world.entity.LivingEntity;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
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.HashMap;
@Mixin(HumanoidModel.class)
public class HumanoidModelMixin {
@Unique HashMap<String, ModelPart> relevantPartsByName = new HashMap<>();
@Shadow @Final
public ModelPart head;
@Shadow @Final
public ModelPart hat;
@Shadow @Final
public ModelPart rightArm;
@Shadow @Final
public ModelPart leftArm;
@@ -40,6 +37,8 @@ public class HumanoidModelMixin {
public ModelPart rightLeg;
@Shadow @Final
public ModelPart leftLeg;
@Shadow @Final
public ModelPart body;
@Inject(method = "setupAnim*", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/model/geom/ModelPart;copyFrom(Lnet/minecraft/client/model/geom/ModelPart;)V", shift = At.Shift.BEFORE))
public void cobblemon$animateRiders(
@@ -51,19 +50,23 @@ public class HumanoidModelMixin {
float headPitch,
CallbackInfo ci
) {
if (relevantPartsByName.isEmpty()) {
relevantPartsByName.put("arm_left", leftArm);
relevantPartsByName.put("arm_right", rightArm);
relevantPartsByName.put("leg_left", leftLeg);
relevantPartsByName.put("leg_right", rightLeg);
relevantPartsByName.put("head", head);
MountedPlayerRenderer.shouldApplyRootAnimation = false;
if (MountedPlayerRenderer.relevantPartsByName.size() <= 1) {
MountedPlayerRenderer.relevantPartsByName.put("arm_left", leftArm);
MountedPlayerRenderer.relevantPartsByName.put("arm_right", rightArm);
MountedPlayerRenderer.relevantPartsByName.put("leg_left", leftLeg);
MountedPlayerRenderer.relevantPartsByName.put("leg_right", rightLeg);
MountedPlayerRenderer.relevantPartsByName.put("head", head);
MountedPlayerRenderer.relevantPartsByName.put("hat", hat);
MountedPlayerRenderer.relevantPartsByName.put("torso", body);
}
Entity vehicle = entity.getVehicle();
if (vehicle instanceof PokemonEntity pokemonEntity && entity instanceof OrientationControllable) {
var shouldRotatePlayerHead = pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) -> {
return behaviour.shouldRotateRiderHead(settings, state, pokemonEntity);
});
var shouldRotatePlayerHead = pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) ->
behaviour.shouldRotateRiderHead(settings, state, pokemonEntity)
);
if (!shouldRotatePlayerHead) {
netHeadYaw = 0f;
@@ -76,7 +79,8 @@ public class HumanoidModelMixin {
if (!(entity instanceof AbstractClientPlayer player)) return;
MountedPlayerRenderer.INSTANCE.animate(pokemonEntity, player, relevantPartsByName, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
MountedPlayerRenderer.shouldApplyRootAnimation = true;
MountedPlayerRenderer.INSTANCE.animate((HumanoidModel<AbstractClientPlayer>)(Object)this, pokemonEntity, player, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
}
}
}
@@ -174,6 +174,16 @@ public abstract class LocalPlayerMixin extends AbstractClientPlayer implements O
return this.cobblemon$isDoubleJumping;
}
@Inject(method = "isHandsBusy", at = @At("HEAD"), cancellable = true)
private void cobblemon$isHandsBusy(CallbackInfoReturnable<Boolean> cir) {
Entity vehicle = this.getVehicle();
if (vehicle instanceof PokemonEntity pokemonEntity) {
int seatIndex = pokemonEntity.getPassengers().indexOf(this);
Seat seat = pokemonEntity.getSeats().get(seatIndex);
cir.setReturnValue(seat.getHandsBusy());
}
}
@Override
public HitResult pick(double hitDistance, float partialTicks, boolean hitFluids) {
Entity vehicle = this.getVehicle();
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.client.CobblemonClient;
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding;
@@ -116,6 +117,8 @@ public abstract class MouseHandlerMixin {
@Local(argsOnly = true) double d,
@Local(argsOnly = true) double movementTime
) {
boolean returnValue = true;
PokedexUsageContext usageContext = CobblemonClient.INSTANCE.getPokedexUsageContext();
if (usageContext.getScanningGuiOpen()) {
this.smoothTurnY.reset();
@@ -126,7 +129,12 @@ public abstract class MouseHandlerMixin {
var sensitivity = Mth.lerp(usageContext.getFovMultiplier(), spyglassSensitivity, lookSensitivity);
var yRotationFlip = this.minecraft.options.invertYMouse().get() ? -1 : 1;
player.turn(this.accumulatedDX * sensitivity, (this.accumulatedDY * sensitivity * yRotationFlip));
return false;
returnValue = false;
}
// Clamp player rotation if riding and the vehicle demands it
if (player.isPassenger() && player.getVehicle() instanceof PokemonEntity vehicle) {
vehicle.clampPassengerRotation(player);
}
if (!(player instanceof OrientationControllable controllable)) return true;
@@ -137,35 +145,33 @@ public abstract class MouseHandlerMixin {
pitchSmoother.reset();
rollSmoother.reset();
yawSmoother.reset();
return true;
return returnValue;
}
//Send mouse input to be interpreted into rotation
//deltas by the ride controller
// Send mouse input to be interpreted into rotation
// deltas by the ride controller
Vec3 angVecMouse = cobblemon$getRideMouseRotation(cursorDeltaX, cursorDeltaY, movementTime);
//Perform Rotation using mouse influenced rotation deltas.
// Perform Rotation using mouse influenced rotation deltas.
controllable.getOrientationController().rotate(
(float) angVecMouse.x,
(float) angVecMouse.y,
(float) angVecMouse.z
);
//Gather and apply the current rotation deltas
// Gather and apply the current rotation deltas
var angRot = cobblemon$getAngularVelocity(movementTime);
//Apply smoothing if requested by the controller.
//This Might be best if done by the controller itself?
if(cobblemon$shouldUseAngVelSmoothing())
{
// Apply smoothing if requested by the controller.
// This Might be best if done by the controller itself?
if(cobblemon$shouldUseAngVelSmoothing()) {
var yaw = yawSmoother.getNewDeltaValue(angRot.x * 0.5f, d);
var pitch = pitchSmoother.getNewDeltaValue(angRot.y * 0.5f, d);
var roll = rollSmoother.getNewDeltaValue(angRot.z * 0.5f, d);
controllable.getOrientationController().rotate((float) yaw, (float) pitch, (float) roll);
}
//Otherwise simply apply the smoothing
else
{
// Otherwise simply apply the smoothing
else {
controllable.getOrientationController().rotate((float) (angRot.x * 10 * d), (float) (angRot.y * 10 * d), (float) (angRot.z * 10 * d));
}
return false;
@@ -210,6 +216,18 @@ public abstract class MouseHandlerMixin {
if (vehicle == null) return Vec3.ZERO;
if (!(vehicle instanceof PokemonEntity pokemonEntity)) return Vec3.ZERO;
var invertYaw = Cobblemon.config.getInvertYaw();
var invertPitch = Cobblemon.config.getInvertPitch();
var xValue = mouseX * Cobblemon.config.getXAxisSensitivity();
var yValue = mouseY * Cobblemon.config.getYAxisSensitivity();
var swapXAndY = Cobblemon.config.getSwapXAndYAxes();
var yaw = (swapXAndY ? yValue : xValue) * (invertYaw? -1.0f : 1.0f);
var pitch = (swapXAndY ? xValue : yValue) * (invertPitch? -1.0f : 1.0f);
var sensitivity = cobblemon$getRidingSensitivity();
return pokemonEntity.ifRidingAvailableSupply(Vec3.ZERO, (behaviour, settings, state) -> {
return behaviour.rotationOnMouseXY(
@@ -217,8 +235,8 @@ public abstract class MouseHandlerMixin {
state,
pokemonEntity,
player,
mouseY,
mouseX,
pitch,
yaw,
yMouseSmoother,
xMouseSmoother,
sensitivity,
@@ -9,12 +9,18 @@
package com.cobblemon.mod.common.mixin.entity;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Entity.class)
@@ -29,4 +35,27 @@ public abstract class EntityMixin {
}
}
@WrapOperation(
method = "collide(Lnet/minecraft/world/phys/Vec3;)Lnet/minecraft/world/phys/Vec3;",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/Entity;onGround()Z"
)
)
public boolean cobblemon$forceOnGroundForStepUp(Entity entity, Operation<Boolean> original) {
if (entity instanceof PokemonEntity && entity.hasControllingPassenger()) {
BlockPos below = entity.blockPosition().below();
Level level = entity.level();
var blockStateBelow = level.getBlockState(below);
boolean isAirOrLiquid = blockStateBelow.isAir() || !blockStateBelow.getFluidState().isEmpty();
boolean canSupportEntity = blockStateBelow.isFaceSturdy(level, below, Direction.UP);
boolean standingOnSolid = canSupportEntity && !isAirOrLiquid;
if (standingOnSolid) {
return true;
}
}
return original.call(entity);
}
}
@@ -76,7 +76,7 @@ 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.CallbackHandler
import com.cobblemon.mod.common.events.PokedexHandler
import com.cobblemon.mod.common.events.ServerTickHandler
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
@@ -313,7 +313,7 @@ object Cobblemon {
CobblemonEvents.POKEMON_PROPERTY_INITIALISED.emit(Unit)
FlowHandler.setup()
CallbackHandler.setup()
EntityCallbackHandler.setup()
ifDedicatedServer {
@@ -128,7 +128,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val APRICORN_FENCE = this.create("apricorn_fence", FenceBlock(BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
@JvmField
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(APRICORN_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
val APRICORN_FENCE_GATE = this.create("apricorn_fence_gate", FenceGateBlock(APRICORN_WOOD_TYPE, BlockBehaviour.Properties.of().mapColor(APRICORN_PLANKS.defaultMapColor()).strength(2.0f, 3.0f).sound(SoundType.WOOD).ignitedByLava().forceSolidOn()))
@JvmField
val APRICORN_BUTTON = this.create("apricorn_button", BlocksInvoker.createWoodenButtonBlock(APRICORN_BLOCK_SET_TYPE))
@JvmField
@@ -205,7 +205,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
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)))
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).ignitedByLava().forceSolidOn()))
@JvmField
val SACCHARINE_BUTTON = this.create("saccharine_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
@JvmField
@@ -18,72 +18,78 @@ import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.net.messages.client.data.FlowRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.data.CallbackRegistrySyncPacket
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.endsWith
import java.util.concurrent.ExecutionException
import java.util.function.Predicate
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.server.packs.resources.ResourceManager
/**
* Holds all the flows that are loaded from the server's data packs. A flow is foldered under the event identifier,
* Holds all the callbacks that are loaded from the server's data packs. A callback is foldered under the event identifier,
* which can be Cobblemon's namespace but can also be minecraft or any other namespace someone has added hooks for.
* The value of the map is a list of MoLang scripts that will execute when that event occurs.
*
* @author Hiroku
* @since February 24th, 2024
*/
object CobblemonFlows : DataRegistry {
override val id = cobblemonResource("flows")
override val observable = SimpleObservable<CobblemonFlows>()
object CobblemonCallbacks : DataRegistry {
override val id = cobblemonResource("callbacks")
override val observable = SimpleObservable<CobblemonCallbacks>()
override val type = PackType.SERVER_DATA
override fun sync(player: ServerPlayer) {
player.sendPacket(FlowRegistrySyncPacket(clientFlows.entries))
player.sendPacket(CallbackRegistrySyncPacket(clientCallbacks.entries))
}
val runtime by lazy { MoLangRuntime().setup() } // Lazy for if someone adds to generalFunctions in MoLangFunctions
val clientFlows = hashMapOf<ResourceLocation, MutableList<ExpressionLike>>()
val flows = hashMapOf<ResourceLocation, MutableList<ExpressionLike>>()
val clientCallbacks = hashMapOf<ResourceLocation, MutableList<ExpressionLike>>()
val callbacks = hashMapOf<ResourceLocation, MutableList<ExpressionLike>>()
override fun reload(manager: ResourceManager) {
clientFlows.clear()
flows.clear()
clientCallbacks.clear()
callbacks.clear()
val unsortedFlows = mutableMapOf<ResourceLocation, MutableList<Pair<String, ExpressionLike>>>()
val unsortedCallbacks = mutableMapOf<ResourceLocation, MutableList<Pair<String, ExpressionLike>>>()
val folderBeforeNameRegex = ".*\\/([^\\/]+)\\/[^\\/]+\$".toRegex()
manager.listResources("flows") { path -> path.endsWith(CobblemonScripts.MOLANG_EXTENSION) }.forEach { (identifier, resource) ->
resource.openAsReader().use { stream ->
stream.buffered().use { reader ->
try {
val expression = reader.readText().asExpressionLike()
val predicate: Predicate<ResourceLocation> = Predicate { path -> path.endsWith(CobblemonScripts.MOLANG_EXTENSION) }
val event = folderBeforeNameRegex.find(identifier.path)?.groupValues?.get(1)
?: throw IllegalArgumentException("Invalid flow path: $identifier. Should have a folder structure that includes the name of the event being flowed.")
manager.listResources("callbacks", predicate)
.plus(manager.listResources("flows", predicate)) // old name
.forEach { (identifier, resource) ->
resource.openAsReader().use { stream ->
stream.buffered().use { reader ->
try {
val expression = reader.readText().asExpressionLike()
val flowKey = ResourceLocation.fromNamespaceAndPath(identifier.namespace, event)
unsortedFlows.putIfAbsent(flowKey, mutableListOf())
unsortedFlows[flowKey]!!.add(identifier.path to expression)
} catch (exception: Exception) {
throw ExecutionException("Error loading MoLang script for flow: $identifier", exception)
val event = folderBeforeNameRegex.find(identifier.path)?.groupValues?.get(1)
?: throw IllegalArgumentException("Invalid callback path: $identifier. Should have a folder structure that includes the name of the event to callback.")
val callbackKey = ResourceLocation.fromNamespaceAndPath(identifier.namespace, event)
unsortedCallbacks.putIfAbsent(callbackKey, mutableListOf())
unsortedCallbacks[callbackKey]!!.add(identifier.path to expression)
} catch (exception: Exception) {
throw ExecutionException("Error loading MoLang script for callback: $identifier", exception)
}
}
}
}
}
unsortedFlows.forEach { (key, value) ->
unsortedCallbacks.forEach { (key, value) ->
value.sortBy { it.first }
if (key.path.startsWith("flows/client/")) {
clientFlows.getOrPut(key) { mutableListOf() }.addAll(value.map { it.second })
if (key.path.startsWith("flows/client/") || key.path.startsWith("callbacks/client/")) {
clientCallbacks.getOrPut(key) { mutableListOf() }.addAll(value.map { it.second })
} else {
flows.getOrPut(key) { mutableListOf() }.addAll(value.map { it.second })
callbacks.getOrPut(key) { mutableListOf() }.addAll(value.map { it.second })
}
}
Cobblemon.LOGGER.info("Loaded ${flows.size} flows and ${clientFlows.size} client flows")
Cobblemon.LOGGER.info("Loaded ${callbacks.size} callbacks and ${clientCallbacks.size} client callbacks")
observable.emit(this)
}
@@ -93,7 +99,7 @@ object CobblemonFlows : DataRegistry {
functions: Map<String, (MoParams) -> Any> = emptyMap(),
cancelable: Cancelable? = null
) {
if (eventResourceLocation !in flows) return
if (eventResourceLocation !in callbacks) return
if (cancelable == null) {
runtime.environment.query.functions.remove("cancel")
@@ -106,7 +112,7 @@ object CobblemonFlows : DataRegistry {
functions.forEach { (name, function) -> runtime.environment.query.addFunction(name, function) }
flows[eventResourceLocation]?.forEach {
callbacks[eventResourceLocation]?.forEach {
if (cancelable != null && cancelable.isCanceled) {
return
}
@@ -26,10 +26,10 @@ object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>
.networkSynchronized(PokemonItemComponent.PACKET_CODEC)
.build())
val HELD_ITEM_REP: DataComponentType<HeldItemCapableComponent> = DataComponentType.builder<HeldItemCapableComponent>()
.persistent(HeldItemCapableComponent.CODEC)
.networkSynchronized(HeldItemCapableComponent.PACKET_CODEC)
.build()
val HELD_ITEM_EFFECT: DataComponentType<HeldItemEffectComponent> = create("held_item_effect", DataComponentType.builder<HeldItemEffectComponent>()
.persistent(HeldItemEffectComponent.CODEC)
.networkSynchronized(HeldItemEffectComponent.PACKET_CODEC)
.build())
val BAIT: DataComponentType<RodBaitComponent> = create("bait", DataComponentType.builder<RodBaitComponent>()
.persistent(RodBaitComponent.CODEC)
@@ -86,6 +86,7 @@ object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:ingredient"), INGREDIENT)
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:food"), FOOD)
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:mob_effects"), MOB_EFFECTS)
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:held_item_effect"), HELD_ITEM_EFFECT)
}
override val registry = BuiltInRegistries.DATA_COMPONENT_TYPE
@@ -22,6 +22,7 @@ import com.cobblemon.mod.common.block.BerryBlock
import com.cobblemon.mod.common.block.MintBlock
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.client.pokedex.PokedexType
import com.cobblemon.mod.common.block.campfirepot.CampfirePotColor
import com.cobblemon.mod.common.entity.boat.CobblemonBoatType
import com.cobblemon.mod.common.item.*
import com.cobblemon.mod.common.item.armor.CobblemonArmorTrims
@@ -192,19 +193,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val campfire_pots = mutableListOf<CampfirePotItem>()
@JvmField
val CAMPFIRE_POT_RED = campfirePotItem(CobblemonBlocks.RED_CAMPFIRE_POT, "red")
val CAMPFIRE_POT_RED = campfirePotItem(CobblemonBlocks.RED_CAMPFIRE_POT, CampfirePotColor.RED)
@JvmField
val CAMPFIRE_POT_YELLOW = campfirePotItem(CobblemonBlocks.YELLOW_CAMPFIRE_POT, "yellow")
val CAMPFIRE_POT_YELLOW = campfirePotItem(CobblemonBlocks.YELLOW_CAMPFIRE_POT, CampfirePotColor.YELLOW)
@JvmField
val CAMPFIRE_POT_GREEN = campfirePotItem(CobblemonBlocks.GREEN_CAMPFIRE_POT, "green")
val CAMPFIRE_POT_GREEN = campfirePotItem(CobblemonBlocks.GREEN_CAMPFIRE_POT, CampfirePotColor.GREEN)
@JvmField
val CAMPFIRE_POT_BLUE = campfirePotItem(CobblemonBlocks.BLUE_CAMPFIRE_POT, "blue")
val CAMPFIRE_POT_BLUE = campfirePotItem(CobblemonBlocks.BLUE_CAMPFIRE_POT, CampfirePotColor.BLUE)
@JvmField
val CAMPFIRE_POT_PINK = campfirePotItem(CobblemonBlocks.PINK_CAMPFIRE_POT, "pink")
val CAMPFIRE_POT_PINK = campfirePotItem(CobblemonBlocks.PINK_CAMPFIRE_POT, CampfirePotColor.PINK)
@JvmField
val CAMPFIRE_POT_BLACK = campfirePotItem(CobblemonBlocks.BLACK_CAMPFIRE_POT, "black")
val CAMPFIRE_POT_BLACK = campfirePotItem(CobblemonBlocks.BLACK_CAMPFIRE_POT, CampfirePotColor.BLACK)
@JvmField
val CAMPFIRE_POT_WHITE = campfirePotItem(CobblemonBlocks.WHITE_CAMPFIRE_POT, "white")
val CAMPFIRE_POT_WHITE = campfirePotItem(CobblemonBlocks.WHITE_CAMPFIRE_POT, CampfirePotColor.WHITE)
@JvmField
val HEARTY_GRAINS = compostableItem("hearty_grains", ItemNameBlockItem(CobblemonBlocks.HEARTY_GRAINS, Properties().rarity(Rarity.COMMON)))
@@ -400,7 +401,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val OLD_GATEAU = regionalFoodItem("old_gateau", 64, 9, 0.1335f, false)
@JvmField
val CASTELIACONE = regionalFoodItem("casteliacone", 64, 5, .28f, false)
val CASTELIACONE = regionalFoodItem("casteliacone", 64, 5, 0.28f, false)
@JvmField
val LUMIOSE_GALETTE = regionalFoodItem("lumiose_galette", 64, 4, 0.4f, false)
@JvmField
@@ -695,7 +696,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val SUPERB_REMEDY = compostableItem("superb_remedy", RemedyItem(RemedyItem.SUPERB), 0.85f)
@JvmField
val MOOMOO_MILK = create("moomoo_milk", CobblemonItem(Item.Properties().craftRemainder(Items.GLASS_BOTTLE)))
val MOOMOO_MILK = create("moomoo_milk", CobblemonItem(Item.Properties().craftRemainder(Items.GLASS_BOTTLE).stacksTo((16))))
@JvmField
val POTION = create("potion", PotionItem(PotionType.POTION))
@@ -1500,8 +1501,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
}
)
private fun campfirePotItem(block: Block, type: String): CampfirePotItem {
val item = create("campfire_pot_${type}", CampfirePotItem(block))
private fun campfirePotItem(block: Block, color: CampfirePotColor): CampfirePotItem {
val item = create("campfire_pot_${color.suffix}", CampfirePotItem(block, color))
campfire_pots.add(item)
return item
}
@@ -1648,4 +1649,4 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
private fun foodItem(nutrition: Int, saturationModifier: Float): Item {
return CobblemonItem(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
}
}
}
@@ -43,6 +43,10 @@ object CobblemonMemories {
val TARGETED_BATTLE_POKEMON = register<UUID>("targeted_battle_pokemon")
val NEAREST_VISIBLE_ATTACKER = register<LivingEntity>("nearest_visible_attacker")
val NEARBY_GROWABLE_CROPS = register<BlockPos>("nearby_growable_crops")
val NEARBY_SWEET_BERRY_BUSH = register<BlockPos>("nearest_sweet_berry_bush")
val DISABLE_WALK_TO_BERRY_BUSH = register<Boolean>("disable_walk_to_berry_bush")
val TIME_TRYING_TO_REACH_BERRY_BUSH = register<Int>("time_trying_to_reach_berry_bush")
val IS_CONSUMING_ITEM = register<Boolean>("is_consuming_item")
val RECENTLY_ATE_GRASS = register<Boolean>("recently_ate_grass")
val HIVE_LOCATION = register<BlockPos>("hive_location")
val HIVE_COOLDOWN = register<Boolean>("hive_cooldown")
@@ -54,6 +58,8 @@ object CobblemonMemories {
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")
val DISABLE_WALK_TO_WANTED_ITEM = register<Boolean>("disable_walk_to_wanted_item")
val TIME_TRYING_TO_REACH_WANTED_ITEM = register<Int>("time_trying_to_wanted_item")
fun <U> register(id: String, codec: Codec<U>): MemoryModuleType<U> {
val memoryModule = MemoryModuleType(Optional.of(codec))
@@ -9,8 +9,8 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.client.net.OpenBehaviourEditorHandler
import com.cobblemon.mod.common.client.net.CalculateSeatPositionsHandler
import com.cobblemon.mod.common.client.net.OpenBehaviourEditorHandler
import com.cobblemon.mod.common.client.net.PlayerInteractOptionsHandler
import com.cobblemon.mod.common.client.net.SetClientPlayerDataHandler
import com.cobblemon.mod.common.client.net.animation.PlayPosableAnimationHandler
@@ -20,7 +20,6 @@ import com.cobblemon.mod.common.client.net.callback.party.OpenPartyCallbackHandl
import com.cobblemon.mod.common.client.net.callback.partymove.OpenPartyMoveCallbackHandler
import com.cobblemon.mod.common.client.net.cooking.ToggleCookingPotLidHandler
import com.cobblemon.mod.common.client.net.data.DataRegistrySyncPacketHandler
import com.cobblemon.mod.common.client.net.data.UnlockReloadPacketHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueClosedHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueOpenedHandler
import com.cobblemon.mod.common.client.net.effect.PokeSnackBlockParticlesHandler
@@ -65,8 +64,8 @@ import com.cobblemon.mod.common.client.net.trade.TradeProcessStartedHandler
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
import com.cobblemon.mod.common.net.PacketRegisterInfo
import com.cobblemon.mod.common.net.messages.client.OpenBehaviourEditorPacket
import com.cobblemon.mod.common.net.messages.client.CalculateSeatPositionsPacket
import com.cobblemon.mod.common.net.messages.client.OpenBehaviourEditorPacket
import com.cobblemon.mod.common.net.messages.client.PlayerInteractOptionsPacket
import com.cobblemon.mod.common.net.messages.client.SetClientPlayerDataPacket
import com.cobblemon.mod.common.net.messages.client.animation.PlayPosableAnimationPacket
@@ -157,6 +156,7 @@ import com.cobblemon.mod.common.net.messages.server.callback.party.PartyPokemonS
import com.cobblemon.mod.common.net.messages.server.callback.party.PartySelectCancelledPacket
import com.cobblemon.mod.common.net.messages.server.callback.partymove.PartyMoveSelectCancelledPacket
import com.cobblemon.mod.common.net.messages.server.callback.partymove.PartyPokemonMoveSelectedPacket
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingSettingsPacket
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingStatRangePacket
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingStatsPacket
import com.cobblemon.mod.common.net.messages.server.dialogue.EscapeDialoguePacket
@@ -170,11 +170,11 @@ import com.cobblemon.mod.common.net.messages.server.pasture.UnpasturePokemonPack
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.FinishScanningPacket
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.StartScanningPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.interact.InteractPokemonPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetItemHiddenPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetActiveMarkPacket
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.SetActiveMarkPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetItemHiddenPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetMarkingsPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.evolution.AcceptEvolutionPacket
import com.cobblemon.mod.common.net.messages.server.riding.DismountPokemonPacket
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateDriverInputPacket
@@ -208,6 +208,7 @@ import com.cobblemon.mod.common.net.serverhandling.callback.party.PartyPokemonSe
import com.cobblemon.mod.common.net.serverhandling.callback.party.PartySelectCancelledHandler
import com.cobblemon.mod.common.net.serverhandling.callback.partymove.PartyMoveSelectCancelledHandler
import com.cobblemon.mod.common.net.serverhandling.callback.partymove.PartyPokemonMoveSelectedHandler
import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRidingSettingsHandler
import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRidingStatRangeHandler
import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRidingStatsHandler
import com.cobblemon.mod.common.net.serverhandling.dialogue.EscapeDialogueHandler
@@ -222,11 +223,11 @@ import com.cobblemon.mod.common.net.serverhandling.pasture.UnpasturePokemonHandl
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.FinishScanningHandler
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.StartScanningHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.interact.InteractPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetItemHiddenHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetNicknameHandler
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.pokemon.update.SetActiveMarkHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetItemHiddenHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetMarkingsHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetNicknameHandler
import com.cobblemon.mod.common.net.serverhandling.riding.DismountPokemonPacketHandler
import com.cobblemon.mod.common.net.serverhandling.riding.DriverInputPacketHandler
import com.cobblemon.mod.common.net.serverhandling.starter.RequestStarterScreenHandler
@@ -388,7 +389,6 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(SpeciesRegistrySyncPacket.ID, SpeciesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(PropertiesCompletionRegistrySyncPacket.ID, PropertiesCompletionRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(UnlockReloadPacket.ID, UnlockReloadPacket::decode, UnlockReloadPacketHandler))
list.add(PacketRegisterInfo(StandardSpeciesFeatureSyncPacket.ID, StandardSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(GlobalSpeciesFeatureSyncPacket.ID, GlobalSpeciesFeatureSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(SpeciesFeatureAssignmentSyncPacket.ID, SpeciesFeatureAssignmentSyncPacket::decode, DataRegistrySyncPacketHandler()))
@@ -401,7 +401,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(DexEntrySyncPacket.ID, DexEntrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(SpawnBaitRegistrySyncPacket.ID, SpawnBaitRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(SeasoningRegistrySyncPacket.ID, SeasoningRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(FlowRegistrySyncPacket.ID, FlowRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(CallbackRegistrySyncPacket.ID, CallbackRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(CosmeticItemAssignmentSyncPacket.ID, CosmeticItemAssignmentSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(BehaviourSyncPacket.ID, BehaviourSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(MarkRegistrySyncPacket.ID, MarkRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
@@ -578,6 +578,7 @@ 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(ServerboundUpdateRidingSettingsPacket.ID, ServerboundUpdateRidingSettingsPacket::decode, ServerboundUpdateRidingSettingsHandler))
list.add(PacketRegisterInfo(DismountPokemonPacket.ID, DismountPokemonPacket::decode, DismountPokemonPacketHandler))
list.add(PacketRegisterInfo(ServerboundUpdateDriverInputPacket.ID, ServerboundUpdateDriverInputPacket::decode, DriverInputPacketHandler))
@@ -37,6 +37,10 @@ object CobblemonSensors {
val NEARBY_FLOWER = register("nearby_flower", ::FlowerSensor)
val NEARBY_SWEET_BERRY_BUSH = register("nearby_sweet_berry_bush", ::SweetBerryBushSensor)
val POKEMON_NEARBY_WANTED_ITEM = register("pokemon_nearby_wanted_item", ::PokemonItemSensor)
fun <E : Entity, U : Sensor<E>> register(id: String, supplier: Supplier<U>): SensorType<U> {
val sensor = SensorType(supplier)
sensors[id] = sensor
@@ -78,6 +78,7 @@ object Abilities : DataRegistry {
fun all() = this.abilityMap.values.toList()
fun first() = this.abilityMap.values.first()
fun get(name: String) = abilityMap[name.lowercase()]
fun getOrDummy(name: String) = get(name) ?: DUMMY
fun getOrException(name: String) = get(name) ?: throw IllegalArgumentException("Unable to find ability of name: $name")
fun count() = this.abilityMap.size
@@ -49,10 +49,9 @@ class AbilityTemplate(
@JvmStatic
val CODEC: Codec<AbilityTemplate> = CodecUtils.createByStringCodec(
Abilities::get,
Abilities::getOrDummy,
AbilityTemplate::name
) { id -> "No ability for ID $id" }
}
}
@@ -9,23 +9,34 @@
package com.cobblemon.mod.common.api.ai
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
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.addStandardFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
import com.cobblemon.mod.common.util.activityRegistry
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Pair
import com.mojang.serialization.Dynamic
import net.minecraft.resources.ResourceLocation
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
import net.minecraft.world.entity.schedule.Activity
import net.minecraft.world.entity.schedule.Schedule
class BehaviourConfigurationContext {
val runtime = MoLangRuntime().setup()
var appliedBehaviours: Set<ResourceLocation> = setOf()
var defaultActivity = Activity.IDLE
@@ -35,7 +46,6 @@ class BehaviourConfigurationContext {
val memories = mutableSetOf<MemoryModuleType<*>>()
val sensors = mutableSetOf<SensorType<*>>()
val onAddScripts = mutableListOf<ResourceLocation>()
val onAdd = mutableListOf<ExpressionLike>()
fun getOrCreateActivity(activity: Activity): ActivityConfigurationContext {
@@ -58,32 +68,27 @@ class BehaviourConfigurationContext {
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<*>) {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
runtime.withQueryValue("brain", createBrainStruct(entity, this))
if (entity is MoLangScriptingEntity) {
entity.registerVariables(behaviourConfigs.flatMap { it.getVariables(entity) })
entity.registerVariables(behaviourConfigs.flatMap { it.getVariables(entity, this) })
entity.initializeScripting()
}
// Setup the brain config
behaviourConfigs.forEach { it.preconfigure(entity, this) }
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) }
@@ -92,4 +97,43 @@ class BehaviourConfigurationContext {
brain.schedule = schedule
brain.setActiveActivityIfPossible(defaultActivity)
}
fun createBrainStruct(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): QueryStruct {
return QueryStruct(hashMapOf()).addStandardFunctions()
.addFunction("entity") { entity.asMostSpecificMoLangValue() }
.addFunction("create_activity") { params ->
val name = params.getString(0).asIdentifierDefaultingNamespace()
val activity = entity.level().activityRegistry.get(name) ?: return@addFunction run {
Cobblemon.LOGGER.error("Tried loading activity $name as part of an entity brain but that activity does not exist")
DoubleValue.ZERO
}
val existingActivityBuilder = behaviourConfigurationContext.activities.find { it.activity == activity }
if (existingActivityBuilder != null) {
return@addFunction createActivityStruct(existingActivityBuilder)
} else {
val activityConfigurationContext = ActivityConfigurationContext(activity)
behaviourConfigurationContext.activities.add(activityConfigurationContext)
return@addFunction createActivityStruct(activityConfigurationContext)
}
}
.addFunction("set_core_activities") { params ->
behaviourConfigurationContext.coreActivities = params.params.map { (it as ObjectValue<ActivityConfigurationContext>).obj.activity }.toSet()
return@addFunction DoubleValue.ONE
}
.addFunction("set_default_activity") { params ->
behaviourConfigurationContext.defaultActivity = params.get<ObjectValue<ActivityConfigurationContext>>(0).obj.activity
return@addFunction DoubleValue.ONE
}
}
fun createActivityStruct(activityConfigurationContext: ActivityConfigurationContext): ObjectValue<ActivityConfigurationContext> {
val struct = ObjectValue(activityConfigurationContext)
struct.addStandardFunctions()
.addFunction("add_task") { params ->
val priority = params.getInt(0)
val task = params.get(1) as ObjectValue<BehaviorControl<in LivingEntity>>
activityConfigurationContext.tasks.add(Pair(priority, task.obj))
}
return struct
}
}
@@ -33,19 +33,13 @@ class CobblemonBehaviour(
// 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) }
}
@@ -53,9 +47,6 @@ class CobblemonBehaviour(
fun onRemove(entity: LivingEntity) {
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (onRemoveScript != null) {
CobblemonScripts.run(onRemoveScript, runtime)
}
if (onRemove != null) {
runtime.resolve(onRemove)
}
@@ -13,6 +13,22 @@ import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.mojang.datafixers.util.Either
import kotlin.jvm.optionals.getOrNull
/**
* The issue in a lot of the behaviour datapacking is that there are times when a property should be exposed to
* the user and other times that you want to fix the value in place. The remedy to this is using an [Either] where
* one side is an Expression, ergo a value that is not exposed to the user, and the other side is a fully defined
* configuration variable.
*
* When users are editing JSONs they can have a simple expression, or they can declare full variable to show to the
* user. Similarly, the classes for tasks and brain configurations can have defaults that hide from the user or
* defaults that are properly defined variables. One example where this is useful is Wander tasks which might be reused
* in panic activities where the walk speed is tuned up. When specifying the task in the panic activity, the value of
* the walk speed would be set (overriding the default which is the walk_speed MoLang variable) to a separate config
* variable that is exposed to the user. Pretty neat!
*
* @author Hiroku
* @since January 4th, 2025
*/
typealias ExpressionOrEntityVariable = Either<Expression, MoLangConfigVariable>
/**
@@ -12,6 +12,7 @@ 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.cobblemon.mod.common.util.resolveBoolean
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.memory.MemoryModuleType
@@ -28,9 +29,9 @@ class AddMemoriesAndSensorsConfig : BehaviourConfig {
val memories: Set<MemoryModuleType<*>> = emptySet()
val sensors: Set<SensorType<*>> = mutableSetOf()
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(condition).asVariables()
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (!checkCondition(entity, condition)) return
if (!checkCondition(behaviourConfigurationContext, condition)) return
behaviourConfigurationContext.addMemories(memories)
behaviourConfigurationContext.addSensors(sensors)
}
@@ -24,9 +24,13 @@ class AddTasksToActivity : BehaviourConfig {
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, behaviourConfigurationContext: BehaviourConfigurationContext) = tasksByPriority.values
.flatten()
.flatMap {
it.getVariables(entity, behaviourConfigurationContext)
} + listOf(condition).asVariables()
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (!checkCondition(entity, condition)) return
if (!checkCondition(behaviourConfigurationContext, condition)) return
val activities = if (activity != null) (activities + activity) else activities
@@ -13,7 +13,7 @@ import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import net.minecraft.world.entity.LivingEntity
class AddVariablesConfig(val variables: List<MoLangConfigVariable> = emptyList()) : BehaviourConfig {
override fun getVariables(entity: LivingEntity) = variables
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = variables
// Configuration happens naturally through the override on variables
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {}
@@ -25,18 +25,27 @@ class ApplyBehaviours : BehaviourConfig {
@SerializedName("behaviours", alternate = ["behaviors"])
val behaviours = mutableListOf<ResourceLocation>()
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
return if (checkCondition(entity, condition)) {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return if (checkCondition(behaviourConfigurationContext, condition)) {
behaviours.flatMap {
CobblemonBehaviours.behaviours[it]?.configurations?.flatMap { it.getVariables(entity) } ?: emptyList()
CobblemonBehaviours.behaviours[it]?.configurations?.flatMap { it.getVariables(entity, behaviourConfigurationContext) } ?: emptyList()
} + listOf(condition).asVariables()
} else {
listOf(condition).asVariables()
}
}
override fun preconfigure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (!checkCondition(behaviourConfigurationContext, condition)) return
val configurations = behaviours.map { CobblemonBehaviours.behaviours[it]?.takeIf { it.canBeApplied(entity) } ?: return }
configurations.forEach {
it.configurations.forEach { it.preconfigure(entity, behaviourConfigurationContext) }
}
}
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (!checkCondition(entity, condition)) return
if (!checkCondition(behaviourConfigurationContext, condition)) return
val configurations = behaviours.map { CobblemonBehaviours.behaviours[it]?.takeIf { it.canBeApplied(entity) } ?: return Cobblemon.LOGGER.warn("Behaviour $it not found") }
// Why not just add the presets to the context directly?
@@ -37,7 +37,6 @@ interface BehaviourConfig {
companion object {
val types = mutableMapOf<ResourceLocation, Class<out BehaviourConfig>>(
cobblemonResource("script") to ScriptBehaviourConfig::class.java,
cobblemonResource("custom_script") to CustomScriptBehaviourConfig::class.java,
cobblemonResource("add_tasks_to_activity") to AddTasksToActivity::class.java,
cobblemonResource("apply_behaviours") to ApplyBehaviours::class.java,
cobblemonResource("set_default_activity") to SetDefaultActivity::class.java,
@@ -48,12 +47,16 @@ interface BehaviourConfig {
)
}
fun checkCondition(entity: LivingEntity, expressionOrEntityVariable: ExpressionOrEntityVariable): Boolean {
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
return runtime.resolveBoolean(expressionOrEntityVariable.map({ it }, { "q.entity.config.${it.variableName}".asExpression() }))
/** Literally just here for shorthand. */
fun checkCondition(behaviourConfigurationContext: BehaviourConfigurationContext, expressionOrEntityVariable: ExpressionOrEntityVariable): Boolean {
return behaviourConfigurationContext.runtime.resolveBoolean(expressionOrEntityVariable.map({ it }, { "q.entity.config.${it.variableName}".asExpression() }))
}
fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable>
fun preconfigure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
// Default implementation does nothing, can be overridden if needed
}
fun getVariables(entity: LivingEntity): List<MoLangConfigVariable>
fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext)
}
@@ -1,46 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
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 {
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)
}
}
@@ -117,7 +117,7 @@ Example behaviour (`uses_healing_machine.json`):
"configurations": [
{
"type": "add_tasks_to_activity",
"activity": "idle",
"activity": "minecraft:idle",
"tasksByPriority": {
"1": [
"heal_using_healing_machine",
@@ -177,27 +177,26 @@ Example:
### script
The `script` type executes a registered MoLang script which will apply some changes to the brain or entity. This can be
useful if the goal is to apply some kind of configuration to the entity that would otherwise be performed by an NPC preset
or NPC class. `q.entity` will refer to the entity. This is powerful when combined with [add_variables](#add_variables)
configs in the same behaviour preset.
useful for complex variable configuration. `q.entity` will refer to the entity.
- `executeEarly`: If true, the script will be executed in the variable phase which occurs before tasks are added to the brain. Use this when your script might influence which tasks are put onto the brain.
- `script`: Either a resource location for the `molang` datapack folder or a MoLang expression that will be executed.
- `variables`: A list of variables that can be configured in the UI. Each variable has the same properties as in `add_variables`.
Example:
```json
{
"type": "script",
"script": "cobblemon:configure_npc_party"
}
```
### custom_script
The `custom_script` type executes a custom MoLang script from this config which will apply some changes to the brain or
entity. This is useful for when you want to apply some kind of configuration to the entity that would otherwise be
by an NPC preset or NPC class. `q.entity` will refer to the entity.
Example:
```json
{
"type": "custom_script",
"script": "q.entity.set_pathfinding_malus('WATER', -1);"
"executeEarly": true,
"script": "cobblemon:configure_npc_party",
"variables": [
{
"variableName": "party_size",
"defaultValue": "3",
"displayName": "Party Size",
"description": "The number of Pokémon in the NPC's party.",
"type": "NUMBER"
}
]
}
```
@@ -9,94 +9,50 @@
package com.cobblemon.mod.common.api.ai.config
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.QueryStruct
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.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.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.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.asExpressionLike
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
/**
* Runs a MoLang script as part of the entity's behaviour configuration. Variables can be configured here for convenience.
*
* When [executeEarly] is true, the script will run in an earlier phase than most configs, allowing it to get ahead of
* other behaviour configurations that might depend on the changes made by the script.
*
* @author Hiroku
* @since August 11th, 2025
*/
class ScriptBehaviourConfig : BehaviourConfig {
/** If true, the script will execute as part of the getVariables phase. */
val executeEarly: Boolean = false
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val script = cobblemonResource("dummy")
val script: ExpressionLike = "0".asExpressionLike()
val variables = mutableListOf<MoLangConfigVariable>()
val memories = emptySet<MemoryModuleType<*>>()
val sensors = emptySet<SensorType<*>>()
override fun getVariables(entity: LivingEntity) = variables
private fun runScript(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (!checkCondition(behaviourConfigurationContext, condition)) return
script.resolve(behaviourConfigurationContext.runtime)
}
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = variables
override fun preconfigure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (executeEarly) {
runScript(entity = entity, behaviourConfigurationContext = behaviourConfigurationContext)
}
}
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
if (!checkCondition(entity, condition)) return
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
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))
}
fun createBrainStruct(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): QueryStruct {
return QueryStruct(hashMapOf()).addStandardFunctions()
.addFunction("entity") { entity.asMostSpecificMoLangValue() }
.addFunction("create_activity") { params ->
val name = params.getString(0).asIdentifierDefaultingNamespace()
val activity = entity.level().activityRegistry.get(name) ?: return@addFunction run {
Cobblemon.LOGGER.error("Tried loading activity $name as part of an entity brain but that activity does not exist")
DoubleValue.ZERO
}
val existingActivityBuilder = behaviourConfigurationContext.activities.find { it.activity == activity }
if (existingActivityBuilder != null) {
return@addFunction createActivityStruct(existingActivityBuilder)
} else {
val activityConfigurationContext = ActivityConfigurationContext(activity)
behaviourConfigurationContext.activities.add(activityConfigurationContext)
return@addFunction createActivityStruct(activityConfigurationContext)
}
}
.addFunction("set_core_activities") { params ->
behaviourConfigurationContext.coreActivities = params.params.map { (it as ObjectValue<ActivityConfigurationContext>).obj.activity }.toSet()
return@addFunction DoubleValue.ONE
}
.addFunction("set_default_activity") { params ->
behaviourConfigurationContext.defaultActivity = params.get<ObjectValue<ActivityConfigurationContext>>(0).obj.activity
return@addFunction DoubleValue.ONE
}
}
fun createActivityStruct(activityConfigurationContext: ActivityConfigurationContext): ObjectValue<ActivityConfigurationContext> {
val struct = ObjectValue(activityConfigurationContext)
struct.addStandardFunctions()
.addFunction("add_task") { params ->
val priority = params.getInt(0)
val task = params.get(1) as ObjectValue<BehaviorControl<in LivingEntity>>
activityConfigurationContext.tasks.add(Pair(priority, task.obj))
}
return struct
if (!executeEarly) {
runScript(entity = entity, behaviourConfigurationContext = behaviourConfigurationContext)
}
}
}
@@ -15,7 +15,7 @@ import net.minecraft.world.entity.schedule.Activity
class SetCoreActivities : BehaviourConfig {
val activities = mutableListOf<Activity>()
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
behaviourConfigurationContext.coreActivities = activities.toSet()
}
@@ -16,7 +16,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 getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
behaviourConfigurationContext.defaultActivity = activity
}
@@ -8,27 +8,21 @@
package com.cobblemon.mod.common.api.ai.config
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
class SetVariablesConfig : BehaviourConfig {
var variableValues = mutableMapOf<String, ExpressionLike>()
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun configure(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) {
val runtime = MoLangRuntime().setup()
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (entity is MoLangScriptingEntity) {
variableValues.forEach { (variableName, valueExpression) ->
entity.config.setDirectly(variableName, runtime.resolve(valueExpression))
entity.config.setDirectly(variableName, behaviourConfigurationContext.runtime.resolve(valueExpression))
}
}
}
@@ -13,6 +13,7 @@ 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.mainThreadRuntime
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.LivingEntity
@@ -24,16 +25,16 @@ class ActivityChangeTaskConfig : SingleTaskConfig {
val activity: Activity = Activity.IDLE
val condition: ExpressionLike = "false".asExpressionLike()
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> = emptyList()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> = emptyList()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
): 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)) {
mainThreadRuntime.withQueryValue("entity", livingEntity.asMostSpecificMoLangValue())
if (condition.resolveBoolean(mainThreadRuntime)) {
livingEntity.brain.setActiveActivityIfPossible(activity)
return true
} else {
@@ -16,6 +16,7 @@ import com.cobblemon.mod.common.api.ai.config.task.WanderTaskConfig.Companion.WA
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.mainThreadRuntime
import com.cobblemon.mod.common.util.resolveFloat
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
@@ -38,7 +39,7 @@ class AirWanderTaskConfig : SingleTaskConfig {
val minUpwardsMovement: ExpressionOrEntityVariable = Either.left("3.0".asExpression())
val minDownwardsMovement: ExpressionOrEntityVariable = Either.left("3.0".asExpression())
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf(condition, wanderChance, horizontalRange, verticalRange, speedMultiplier, minUpwardsMovement, minDownwardsMovement).asVariables()
}
@@ -46,8 +47,7 @@ class AirWanderTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, MemoryModuleType.LOOK_TARGET, CobblemonMemories.PATH_COOLDOWN)
val wanderChanceExpression = wanderChance.asSimplifiedExpression(entity)
@@ -62,15 +62,16 @@ class AirWanderTaskConfig : SingleTaskConfig {
return@Trigger false
}
val runtime = mainThreadRuntime
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
val wanderChance = runtime.resolveFloat(wanderChanceExpression)
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())
val target = HoverRandomPos.getPos(entity, horizontalRange.resolveInt(runtime), verticalRange.resolveInt(runtime), rotVec.x, rotVec.y, 1.5707964f, minUpwardsMovement.resolveInt(runtime), minDownwardsMovement.resolveInt(runtime))
?: return@Trigger false
walkTarget.set(WalkTarget(target, speedMultiplier.resolveFloat(), 3))
walkTarget.set(WalkTarget(target, speedMultiplier.resolveFloat(runtime), 3))
lookTarget.set(BlockPosTracker(target))
return@Trigger true
}
@@ -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.molang.MoLangFunctions.asMostSpecificMoLangValue
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
@@ -21,14 +19,12 @@ class AllOfTaskConfig : TaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val tasks: List<TaskConfig> = emptyList()
override fun getVariables(entity: LivingEntity) = tasks.flatMap { it.getVariables(entity) }
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = tasks.flatMap { it.getVariables(entity, behaviourConfigurationContext) }
override fun createTasks(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): List<BehaviorControl<in LivingEntity>> {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return emptyList()
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return emptyList()
return tasks.flatMap { it.createTasks(entity, behaviourConfigurationContext) }
}
}
@@ -17,7 +17,7 @@ import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class AttackAngryAtTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
@@ -16,8 +16,8 @@ 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 getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return emptyList()
}
override fun createTask(
@@ -10,11 +10,8 @@ package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.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
@@ -24,13 +21,12 @@ import net.minecraft.world.entity.ai.sensing.SensorType
class CalmDownTaskConfig : SingleTaskConfig {
var condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.HURT_BY,
MemoryModuleType.HURT_BY_ENTITY,
@@ -12,11 +12,9 @@ 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
@@ -27,7 +25,9 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.sensing.SensorType
/**
* Checks nearby entities and counts how many have nominated this entity as their leader.
* Checks nearby entities and counts how many have nominated this entity as their leader. We normally update this
* as people join and leave the herd, but this is a fallback to make sure we don't get stuck with an incorrect value
* like if the entities die or whatever.
*
* @author Hiroku
* @since June 17th, 2025
@@ -35,7 +35,7 @@ import net.minecraft.world.entity.ai.sensing.SensorType
class CountFollowersTaskConfig : SingleTaskConfig {
val checkTicks: ExpressionOrEntityVariable = Either.left("10".asExpression())
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf(checkTicks).asVariables()
}
@@ -43,8 +43,7 @@ class CountFollowersTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
val checkTicksValue = checkTicks.resolveInt()
val checkTicksValue = checkTicks.resolveInt(behaviourConfigurationContext.runtime)
behaviourConfigurationContext.addMemories(
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
CobblemonMemories.HERD_SIZE,
@@ -23,14 +23,14 @@ 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(minDurationTicks, maxDurationTicks).asVariables()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(minDurationTicks, maxDurationTicks).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
return DoNothing(minDurationTicks.resolveInt(), maxDurationTicks.resolveInt())
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
return DoNothing(minDurationTicks.resolveInt(behaviourConfigurationContext.runtime), maxDurationTicks.resolveInt(behaviourConfigurationContext.runtime))
}
}
@@ -29,7 +29,7 @@ class EatGrassTaskConfig : SingleTaskConfig {
val cooldown = numberVariable(category = EATING_GRASS, name = COOLDOWN, default = 20 * 20).asExpressible()
val eatGrassChance = numberVariable(category = EATING_GRASS, name = EAT_GRASS_CHANCE, default = 1 / (20 * 20F)).asExpressible()
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf(
cooldown,
eatGrassChance
@@ -44,7 +44,7 @@ class EatGrassTaskConfig : SingleTaskConfig {
return null
}
val chance = eatGrassChance.resolveFloat()
val chance = eatGrassChance.resolveFloat(behaviourConfigurationContext.runtime)
if (chance == 0F) {
return null
}
@@ -54,7 +54,7 @@ class EatGrassTaskConfig : SingleTaskConfig {
return WrapperLivingEntityTask(
EatGrassTask(
chance,
cooldown.resolveInt().toLong()
cooldown.resolveInt(behaviourConfigurationContext.runtime).toLong()
),
PokemonEntity::class.java
)
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.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.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.EatHeldItemTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
class EatHeldItemTaskConfig : SingleTaskConfig {
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
behaviourConfigurationContext.addMemories(
CobblemonMemories.IS_CONSUMING_ITEM,
)
return EatHeldItemTask(entity).wrapped<PokemonEntity>()
}
}
@@ -28,7 +28,7 @@ class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
var condition = booleanVariable(SharedEntityVariables.BATTLING_CATEGORY, "exit_battle_when_hurt", true).asExpressible()
var includePassiveDamage = booleanVariable(SharedEntityVariables.BATTLING_CATEGORY, "exit_battle_from_passive_damage", true).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
includePassiveDamage
).asVariables()
@@ -37,10 +37,9 @@ class ExitBattleWhenHurtTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
val includePassiveDamage = includePassiveDamage.resolveBoolean()
val includePassiveDamage = includePassiveDamage.resolveBoolean(behaviourConfigurationContext.runtime)
behaviourConfigurationContext.addMemories(
MemoryModuleType.HURT_BY,
@@ -32,7 +32,7 @@ import net.minecraft.world.level.pathfinder.PathComputationType
*/
class FindAirTaskConfig : SingleTaskConfig {
val walkSpeed = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, SharedEntityVariables.WALK_SPEED, 0.35).asExpressible()
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf(walkSpeed).asVariables()
}
@@ -53,7 +53,7 @@ class FindAirTaskConfig : SingleTaskConfig {
it.absent(CobblemonMemories.PATH_COOLDOWN)
).apply(it) { walkTarget, pathCooldown ->
Trigger { world, entity, time ->
if (!entity.getIsSubmerged()) {
if (!entity.getIsSubmerged() || entity.isInLava) {
return@Trigger false
}
@@ -8,17 +8,16 @@
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.Cobblemon
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
@@ -53,24 +52,25 @@ class FindHerdLeaderTaskConfig : SingleTaskConfig {
it is PokemonEntity &&
it != currentLeader &&
it.pokemon.storeCoordinates.get()?.store !is PartyStore &&
it.getHerdSize() < it.behaviour.herd.maxSize
it.getHerdSize() < it.behaviour.herd.maxSize &&
!it.brain.hasMemoryValue(CobblemonMemories.POKEMON_DROWSY)
}.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) {
val bestMatchingHerdLeader = entity.behaviour.herd.bestMatchLeader(entity, possibleLeader) ?: return@forEach
val possibleLeaderIsAlreadyALeader = possibleLeader.brain.hasMemoryValue(CobblemonMemories.HERD_SIZE)
val currentLeaderHerdTier = currentLeaderEntity?.getHerdTier() ?: entity.getHerdTier()
if (currentLeaderHerdTier >= bestMatchingHerdLeader.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) {
if (bestMatchingHerdLeader.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) {
} else if ((distance > bestDistance && !possibleLeaderIsAlreadyALeader) && bestMatchingHerdLeader.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
bestTier = bestMatchingHerdLeader.tier
}
}
return bestLeader ?: currentLeaderEntity
@@ -80,7 +80,7 @@ class FindHerdLeaderTaskConfig : SingleTaskConfig {
// 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> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf(checkTicks).asVariables()
}
@@ -98,8 +98,7 @@ class FindHerdLeaderTaskConfig : SingleTaskConfig {
MemoryModuleType.WALK_TARGET
)
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
val checkTicksValue = checkTicks.resolveInt()
val checkTicksValue = checkTicks.resolveInt(behaviourConfigurationContext.runtime)
return BehaviorBuilder.create { instance ->
instance.group(
instance.present(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES),
@@ -119,6 +118,7 @@ class FindHerdLeaderTaskConfig : SingleTaskConfig {
herdLeader.set(bestLeader.uuid.toString())
bestLeader.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
bestLeader.adjustHerdSize(1)
return@Trigger true
}
}
@@ -14,23 +14,34 @@ import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.FindRestingPlaceTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.resolveBoolean
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 condition: ExpressionLike = "true".asExpressionLike()
val horizontalSearchDistance: ExpressionOrEntityVariable = Either.left("16".asExpression())
val verticalSearchDistance: ExpressionOrEntityVariable = Either.left("5".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(horizontalSearchDistance, verticalSearchDistance).asVariables()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(horizontalSearchDistance, verticalSearchDistance).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
if (!behaviourConfigurationContext.runtime.resolveBoolean(condition)) {
return null
}
behaviourConfigurationContext.addMemories(
CobblemonMemories.PATH_COOLDOWN,
CobblemonMemories.POKEMON_DROWSY,
@@ -39,7 +50,7 @@ class FindRestingPlaceTaskConfig : SingleTaskConfig {
behaviourConfigurationContext.addSensors(CobblemonSensors.POKEMON_DROWSY)
return WrapperLivingEntityTask(
FindRestingPlaceTask.create(horizontalSearchDistance.resolveInt(), verticalSearchDistance.resolveInt()),
FindRestingPlaceTask.create(horizontalSearchDistance.resolveInt(behaviourConfigurationContext.runtime), verticalSearchDistance.resolveInt(behaviourConfigurationContext.runtime)),
PokemonEntity::class.java
)
}
@@ -9,45 +9,36 @@
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
import com.cobblemon.mod.common.api.ai.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.FLEE_DESIRED_DISTANCE
import com.cobblemon.mod.common.api.ai.config.task.SharedEntityVariables.FLEE_SPEED_MULTIPLIER
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.util.withQueryValue
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.ai.FleeFromAttackerTask
import com.cobblemon.mod.common.util.asExpression
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.behavior.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()
var speedMultiplier = numberVariable(SharedEntityVariables.FEAR_CATEGORY, FLEE_SPEED_MULTIPLIER, 0.5).asExpressible()
var desiredDistance = numberVariable(SharedEntityVariables.FEAR_CATEGORY, FLEE_DESIRED_DISTANCE, 9).asExpressible()
val avoidDurationTicks: ExpressionOrEntityVariable = Either.left("600".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(
condition,
speedMultiplier,
desiredDistance
).asVariables()
override fun getVariables(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): List<MoLangConfigVariable> {
return listOf(avoidDurationTicks).asVariables()
}
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): 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(
SetWalkTargetAwayFrom.entity(MemoryModuleType.HURT_BY_ENTITY, speedMultiplier, desiredDistance, false),
PathfinderMob::class.java
): BehaviorControl<in LivingEntity> {
behaviourConfigurationContext.addMemories(
MemoryModuleType.HURT_BY_ENTITY,
MemoryModuleType.AVOID_TARGET
)
behaviourConfigurationContext.addSensors(SensorType.HURT_BY)
return FleeFromAttackerTask.create(avoidDurationTicks.asExpression())
}
}
@@ -27,18 +27,17 @@ class FleeNearestHostileTaskConfig : SingleTaskConfig {
var speedMultiplier = numberVariable(SharedEntityVariables.FEAR_CATEGORY, FLEE_SPEED_MULTIPLIER, 0.5).asExpressible()
var desiredDistance = numberVariable(SharedEntityVariables.FEAR_CATEGORY, FLEE_DESIRED_DISTANCE, 9).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(condition, speedMultiplier, desiredDistance).asVariables()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(condition, speedMultiplier, desiredDistance).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean() || entity !is PathfinderMob) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime) || 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()
val speedMultiplier = speedMultiplier.resolveFloat(behaviourConfigurationContext.runtime)
val desiredDistance = desiredDistance.resolveInt(behaviourConfigurationContext.runtime)
return WrapperLivingEntityTask(
SetWalkTargetAwayFrom.entity(MemoryModuleType.NEAREST_HOSTILE, speedMultiplier, desiredDistance, false),
PathfinderMob::class.java
@@ -38,7 +38,7 @@ class FlyInCirclesTaskConfig : SingleTaskConfig {
val minDurationTicks: ExpressionOrEntityVariable = Either.left("60".asExpression())
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("180".asExpression())
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf(
minAngularVelocityDegrees,
maxAngularVelocityDegrees,
@@ -57,15 +57,14 @@ class FlyInCirclesTaskConfig : SingleTaskConfig {
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()
minTurnAngleDegrees = minAngularVelocityDegrees.resolveFloat(behaviourConfigurationContext.runtime),
maxTurnAngleDegrees = maxAngularVelocityDegrees.resolveFloat(behaviourConfigurationContext.runtime),
speed = speed.resolveFloat(behaviourConfigurationContext.runtime),
verticalSpeed = verticalSpeed.resolveFloat(behaviourConfigurationContext.runtime),
minDurationTicks = minDurationTicks.resolveFloat(behaviourConfigurationContext.runtime).toInt(),
maxDurationTicks = maxDurationTicks.resolveFloat(behaviourConfigurationContext.runtime).toInt()
).wrapped<PokemonEntity>()
}
}
@@ -19,7 +19,7 @@ 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> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf()
}
@@ -27,13 +27,12 @@ class FollowWalkTargetTaskConfig : SingleTaskConfig {
val minRunTicks: ExpressionOrEntityVariable = Either.left("150".asExpression())
val maxRunTicks: ExpressionOrEntityVariable = Either.left("250".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(minRunTicks, maxRunTicks).asVariables()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(minRunTicks, maxRunTicks).asVariables()
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()),
FollowWalkTargetTask(minRunTicks.resolveInt(behaviourConfigurationContext.runtime), maxRunTicks.resolveInt(behaviourConfigurationContext.runtime)),
PathfinderMob::class.java
)
}
@@ -26,14 +26,13 @@ class GetAngryAtAttackerTaskConfig : SingleTaskConfig {
val condition = booleanVariable(ATTACKING_CATEGORY, GET_ANGRY_AT_ATTACKER, true).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(condition).asVariables()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(condition).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.HURT_BY_ENTITY,
MemoryModuleType.ANGRY_AT,
@@ -30,7 +30,7 @@ class GoToHealingMachineTaskConfig : SingleTaskConfig {
val completionRange: ExpressionOrEntityVariable = Either.left("1".asExpression())
val walkSpeed = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, SharedEntityVariables.WALK_SPEED, 0.35).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(condition, walkSpeed, horizontalSearchRange, verticalSearchRange, completionRange).asVariables()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(condition, walkSpeed, horizontalSearchRange, verticalSearchRange, completionRange).asVariables()
companion object {
const val SELF_HEALING = "self_healing"
@@ -41,8 +41,7 @@ class GoToHealingMachineTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.WALK_TARGET,
MemoryModuleType.LOOK_TARGET,
@@ -11,9 +11,12 @@ 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.OmniPathingEntity
import com.cobblemon.mod.common.util.closestPosition
import com.cobblemon.mod.common.util.mainThreadRuntime
import com.cobblemon.mod.common.util.withQueryValue
import kotlin.math.ceil
import kotlin.math.floor
import net.minecraft.core.BlockPos
@@ -33,7 +36,7 @@ import net.minecraft.world.level.pathfinder.PathComputationType
*/
class GoToLandTaskConfig : SingleTaskConfig {
val walkSpeed = numberVariable(SharedEntityVariables.MOVEMENT_CATEGORY, SharedEntityVariables.WALK_SPEED, 0.35).asExpressible()
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf(walkSpeed).asVariables()
}
@@ -54,13 +57,14 @@ class GoToLandTaskConfig : SingleTaskConfig {
it.absent(CobblemonMemories.PATH_COOLDOWN)
).apply(it) { walkTarget, pathCooldown ->
Trigger { world, entity, time ->
if (!entity.isInLiquid) {
if (!entity.isInWater) {
return@Trigger false
}
entity as PathfinderMob
val walkSpeedValue = walkSpeed.resolveFloat()
mainThreadRuntime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
val walkSpeedValue = walkSpeed.resolveFloat(mainThreadRuntime)
val iterable = BlockPos.betweenClosed(
Mth.floor(entity.x - 8.0),
@@ -11,16 +11,21 @@ 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
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.GoToSleepTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.resolveBoolean
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 GoToSleepTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
var onlyFromStatus: ExpressionOrEntityVariable = Either.left("false".asExpression())
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
@@ -34,6 +39,6 @@ class GoToSleepTaskConfig : SingleTaskConfig {
CobblemonMemories.POKEMON_SLEEPING
)
behaviourConfigurationContext.addSensors(CobblemonSensors.POKEMON_DROWSY)
return WrapperLivingEntityTask(GoToSleepTask.create(), PokemonEntity::class.java)
return WrapperLivingEntityTask(GoToSleepTask.create(onlyFromStatus.resolveBoolean(behaviourConfigurationContext.runtime)), PokemonEntity::class.java)
}
}
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.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.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.HarvestSweetBerryBushTask
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class HarvestSweetBerryBushTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
behaviourConfigurationContext.addMemories(
CobblemonMemories.NEARBY_SWEET_BERRY_BUSH,
CobblemonMemories.DISABLE_WALK_TO_BERRY_BUSH,
CobblemonMemories.TIME_TRYING_TO_REACH_BERRY_BUSH,
MemoryModuleType.WALK_TARGET,
MemoryModuleType.LOOK_TARGET)
behaviourConfigurationContext.addSensors(CobblemonSensors.NEARBY_SWEET_BERRY_BUSH)
return HarvestSweetBerryBushTask()
}
}
@@ -14,6 +14,7 @@ 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.mainThreadRuntime
import com.cobblemon.mod.common.util.resolveBoolean
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
@@ -34,12 +35,12 @@ class HateEntityTaskConfig : SingleTaskConfig {
val entityCondition: Expression = "true".asExpression()
val range: ExpressionOrEntityVariable = Either.left("24".asExpression())
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
val range = range.resolveFloat()
val range = range.resolveFloat(behaviourConfigurationContext.runtime)
behaviourConfigurationContext.addMemories(
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
MemoryModuleType.ANGRY_AT
@@ -52,8 +53,8 @@ class HateEntityTaskConfig : SingleTaskConfig {
).apply(instance) { entities, angryAt ->
Trigger { world, entity, _ ->
val target = instance.get(entities).findClosest {
runtime.withQueryValue("entity", it.asMostSpecificMoLangValue())
return@findClosest runtime.resolveBoolean(entityCondition)
mainThreadRuntime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
return@findClosest mainThreadRuntime.resolveBoolean(entityCondition)
}.orElse(null)
if (target != null && target.distanceTo(entity) <= range) {
@@ -29,14 +29,13 @@ class HealUsingHealingMachineTaskConfig : SingleTaskConfig {
val horizontalUseRange: ExpressionOrEntityVariable = Either.left("2".asExpression())
val verticalUseRange: ExpressionOrEntityVariable = Either.left("1".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(condition, horizontalUseRange, verticalUseRange).asVariables()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(condition, horizontalUseRange, verticalUseRange).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
behaviourConfigurationContext.addMemories(MemoryModuleType.WALK_TARGET, CobblemonMemories.NPC_BATTLING,)
behaviourConfigurationContext.addSensors(CobblemonSensors.NPC_BATTLING)
return HealUsingHealingMachineTask(horizontalUseRange.asExpression(), verticalUseRange.asExpression())
@@ -8,15 +8,14 @@
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.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
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
import com.cobblemon.mod.common.entity.npc.ai.LookAtBattlingPokemonTask
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.withQueryValue
import com.mojang.datafixers.util.Either
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
@@ -31,7 +30,7 @@ class LookAtBattlingPokemonTaskConfig : SingleTaskConfig {
val minDurationTicks: ExpressionOrEntityVariable = Either.left("40".asExpression())
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("80".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
minDurationTicks,
maxDurationTicks
@@ -41,16 +40,15 @@ class LookAtBattlingPokemonTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!resolveBooleanVariable(LOOK_AT_BATTLING_POKEMON)) return null
if (!resolveBooleanVariable(LOOK_AT_BATTLING_POKEMON, behaviourConfigurationContext.runtime)) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.LOOK_TARGET,
CobblemonMemories.BATTLING_POKEMON
)
behaviourConfigurationContext.addSensors(CobblemonSensors.BATTLING_POKEMON)
return LookAtBattlingPokemonTask.create(
minDurationTicks = minDurationTicks.resolveInt(),
maxDurationTicks = maxDurationTicks.resolveInt()
minDurationTicks = minDurationTicks.resolveInt(behaviourConfigurationContext.runtime),
maxDurationTicks = maxDurationTicks.resolveInt(behaviourConfigurationContext.runtime)
)
}
}
@@ -27,7 +27,7 @@ class LookAtEntitiesTaskConfig : SingleTaskConfig {
val condition = booleanVariable(SharedEntityVariables.LOOKING_CATEGORY, LOOK_AT_ENTITIES, true).asExpressible()
val maxDistance = numberVariable(SharedEntityVariables.LOOKING_CATEGORY, SEE_DISTANCE, 15).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
maxDistance
).asVariables()
@@ -36,10 +36,9 @@ class LookAtEntitiesTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
behaviourConfigurationContext.addMemories(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.LOOK_TARGET)
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
return SetEntityLookTarget.create(maxDistance.resolveFloat())
return SetEntityLookTarget.create(maxDistance.resolveFloat(behaviourConfigurationContext.runtime))
}
}
@@ -10,17 +10,28 @@ 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.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.entity.npc.ai.LookAtSpeakerTask
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 LookAtSpeakerTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
) = LookAtSpeakerTask.create().also {
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET, CobblemonMemories.DIALOGUES)
): BehaviorControl<in LivingEntity>? {
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) {
return null
}
return LookAtSpeakerTask.create().also {
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET, CobblemonMemories.DIALOGUES)
}
}
}
@@ -28,7 +28,7 @@ class LookAtTargetTaskConfig : SingleTaskConfig {
val minDurationTicks: ExpressionOrEntityVariable = Either.left("80".asExpression())
val maxDurationTicks: ExpressionOrEntityVariable = Either.left("160".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
minDurationTicks,
maxDurationTicks
@@ -38,10 +38,9 @@ class LookAtTargetTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) 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)
return WrapperLivingEntityTask(LookAtTargetSink(minDurationTicks.resolveInt(behaviourConfigurationContext.runtime), maxDurationTicks.resolveInt(behaviourConfigurationContext.runtime)), Mob::class.java)
}
}
@@ -19,7 +19,7 @@ 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 getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
@@ -20,7 +20,7 @@ class LookInDirectionTaskConfig : SingleTaskConfig {
var yaw = numberVariable(LOOKING_CATEGORY, "locked_yaw", 0F).asExpressible()
var pitch = numberVariable(LOOKING_CATEGORY, "locked_pitch", 0F).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
yaw,
pitch
@@ -8,15 +8,14 @@
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.Cobblemon
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
@@ -37,7 +36,7 @@ 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> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf(checkTicks).asVariables()
}
@@ -53,8 +52,7 @@ class MaintainHerdLeaderTaskConfig : SingleTaskConfig {
MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES,
)
behaviourConfigurationContext.addSensors(SensorType.NEAREST_LIVING_ENTITIES)
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
val checkTicks = checkTicks.resolveInt()
val checkTicks = checkTicks.resolveInt(behaviourConfigurationContext.runtime)
return BehaviorBuilder.create { instance ->
instance.group(
instance.present(CobblemonMemories.HERD_LEADER),
@@ -83,6 +81,8 @@ class MaintainHerdLeaderTaskConfig : SingleTaskConfig {
if (bestLeader != null && bestLeader != leader) {
bestLeader.brain.eraseMemory(CobblemonMemories.HERD_LEADER)
entity.brain.setMemory(CobblemonMemories.HERD_LEADER, bestLeader.uuid.toString())
bestLeader.adjustHerdSize(1)
leader.adjustHerdSize(-1)
}
}
return@Trigger true
@@ -17,7 +17,7 @@ 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 getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
@@ -22,7 +22,7 @@ class MeleeAttackTaskConfig : SingleTaskConfig {
val range = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_range", 1.5F).asExpressible()
val cooldownTicks = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "melee_cooldown", 20).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
range,
cooldownTicks
@@ -32,8 +32,7 @@ class MeleeAttackTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
behaviourConfigurationContext.addMemories(
MemoryModuleType.ATTACK_TARGET,
MemoryModuleType.ATTACK_COOLING_DOWN
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.ast.StringExpression
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
@@ -16,6 +17,7 @@ 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.cobblemon.mod.common.util.resolveString
import com.mojang.datafixers.util.Either
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.LivingEntity
@@ -35,7 +37,7 @@ 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 getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(aspect).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
@@ -50,7 +52,7 @@ class MemoryAspectTaskConfig : SingleTaskConfig {
return null
}
val aspect = aspect.resolveString()
val aspect = behaviourConfigurationContext.runtime.resolveString(aspect.asExpression())
return object : Behavior<LivingEntity>(
mapOf(memory to MemoryStatus.REGISTERED),
@@ -12,12 +12,10 @@ 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
@@ -46,7 +44,7 @@ class MoveIntoFluidTaskConfig : SingleTaskConfig {
val horizontalSearchRange: ExpressionOrEntityVariable = Either.left("8".asExpression())
val verticalSearchRange: ExpressionOrEntityVariable = Either.left("8".asExpression())
override fun getVariables(entity: LivingEntity): List<MoLangConfigVariable> {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): List<MoLangConfigVariable> {
return listOf(
condition,
movesIntoWater,
@@ -61,23 +59,22 @@ class MoveIntoFluidTaskConfig : SingleTaskConfig {
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) 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()
val movesIntoWater = this@MoveIntoFluidTaskConfig.movesIntoWater.resolveBoolean(behaviourConfigurationContext.runtime)
val movesIntoLava = movesIntoLava.resolveBoolean(behaviourConfigurationContext.runtime)
val speedModifier = speedModifier.resolveFloat(behaviourConfigurationContext.runtime)
val horizontalSearchRange = horizontalSearchRange.resolveInt(behaviourConfigurationContext.runtime)
val verticalSearchRange = verticalSearchRange.resolveInt(behaviourConfigurationContext.runtime)
return BehaviorBuilder.create {
it.group(
it.absent(MemoryModuleType.WALK_TARGET),
it.absent(CobblemonMemories.PATH_COOLDOWN)
).apply(it) { walkTarget, pathCooldown ->
Trigger { world, entity, _ ->
Trigger { _, entity, _ ->
val isInWater = entity.isInWater
val isInLava = entity.isInLava
// If it's already in a place it wants to be, then we're fine.
@@ -21,7 +21,7 @@ class MoveToAttackTargetTaskConfig : SingleTaskConfig {
val speedMultiplier = numberVariable(SharedEntityVariables.ATTACKING_CATEGORY, "attacking_movement_speed", 0.5).asExpressible()
val closeEnoughDistance: ExpressionOrEntityVariable = Either.left("0".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
speedMultiplier,
closeEnoughDistance
).asVariables()
@@ -0,0 +1,58 @@
/*
* 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.ExpressionOrEntityVariable
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.MoveToItemTask
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 MoveToItemTaskConfig : SingleTaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
var speedMultiplier: ExpressionOrEntityVariable = Either.left("0.6".asExpression())
var maxDistance: ExpressionOrEntityVariable = Either.left("7.0".asExpression())
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
speedMultiplier,
maxDistance
).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
behaviourConfigurationContext.addMemories(
MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM,
MemoryModuleType.WALK_TARGET,
MemoryModuleType.LOOK_TARGET,
CobblemonMemories.TIME_TRYING_TO_REACH_WANTED_ITEM,
CobblemonMemories.DISABLE_WALK_TO_WANTED_ITEM)
behaviourConfigurationContext.addSensors(CobblemonSensors.POKEMON_NEARBY_WANTED_ITEM)
return WrapperLivingEntityTask(
MoveToItemTask.create(
condition = condition.asExpression(),
speedMultiplier = speedMultiplier.asExpression(),
maxDistance = maxDistance.asExpression()
),
PokemonEntity::class.java
)
}
}
@@ -27,7 +27,7 @@ class MoveToOwnerTaskConfig : SingleTaskConfig {
var teleportDistance: ExpressionOrEntityVariable = Either.left("24.0".asExpression())
var maxDistance: ExpressionOrEntityVariable = Either.left("14.0".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
completionRange,
speedMultiplier,
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.ai.config.task
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.CobblemonSensors
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.MoveToSweetBerryBushTask
import net.minecraft.util.valueproviders.UniformInt
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
import net.minecraft.world.entity.ai.memory.MemoryModuleType
class MoveToSweetBerryBushTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
if (entity !is PokemonEntity) {
return null
}
behaviourConfigurationContext.addMemories(CobblemonMemories.NEARBY_SWEET_BERRY_BUSH, CobblemonMemories.DISABLE_WALK_TO_BERRY_BUSH,
CobblemonMemories.TIME_TRYING_TO_REACH_BERRY_BUSH, MemoryModuleType.WALK_TARGET, MemoryModuleType.LOOK_TARGET)
behaviourConfigurationContext.addSensors(CobblemonSensors.NEARBY_SWEET_BERRY_BUSH)
return MoveToSweetBerryBushTask.create(UniformInt.of(0, 10), 0.6f)
}
}
@@ -38,11 +38,10 @@ class OneOfTaskConfig : SingleTaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val options = mutableListOf<OneOfTaskOption>()
override fun getVariables(entity: LivingEntity) = options.flatMap { it.task.getVariables(entity) }
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = options.flatMap { it.task.getVariables(entity, behaviourConfigurationContext) }
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<in LivingEntity>? {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return null
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return null
return RunOne(options.map { it.task.createTasks(entity, behaviourConfigurationContext).first() toDF it.weight })
}
}
@@ -22,7 +22,7 @@ class PathToBeeHiveTaskConfig : SingleTaskConfig {
val condition = booleanVariable(HONEY, "can_add_honey", true).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
).asVariables()
@@ -33,7 +33,7 @@ class PathToBeeHiveTaskConfig : SingleTaskConfig {
if (entity !is PokemonEntity) {
return null
}
if (!checkCondition(entity, condition)) {
if (!checkCondition(behaviourConfigurationContext.runtime, condition)) {
return null
}
return PathToBeeHiveTask.create()
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.CobblemonSensors
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
@@ -24,7 +25,7 @@ class PathToFlowerTaskConfig : SingleTaskConfig {
val condition = booleanVariable(POLLINATE, "can_pollinate", true).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition
).asVariables()
@@ -36,7 +37,7 @@ class PathToFlowerTaskConfig : SingleTaskConfig {
return null
}
if (!checkCondition(entity, condition)) {
if (!checkCondition(behaviourConfigurationContext.runtime, condition)) {
return null
}
behaviourConfigurationContext.addMemories(
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.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
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.PickUpItemTask
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 PickUpItemTaskConfig : SingleTaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
var maxReach: ExpressionOrEntityVariable = Either.left("1.0".asExpression())
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition,
maxReach
).asVariables()
override fun createTask(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): BehaviorControl<in LivingEntity>? {
behaviourConfigurationContext.addMemories(
MemoryModuleType.WALK_TARGET,
MemoryModuleType.LOOK_TARGET,
MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM
)
return WrapperLivingEntityTask(
PickUpItemTask.create(
condition = condition.asExpression(),
maxReach = maxReach.asExpression()
),
PokemonEntity::class.java
)
}
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.api.ai.config.task
import com.bedrockk.molang.runtime.MoLangRuntime
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
import com.cobblemon.mod.common.api.ai.asVariables
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
@@ -22,7 +23,7 @@ class PlaceHoneyInHiveTaskConfig : SingleTaskConfig {
val condition = booleanVariable(HONEY, "can_add_honey", true).asExpressible()
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition
).asVariables()
@@ -33,7 +34,7 @@ class PlaceHoneyInHiveTaskConfig : SingleTaskConfig {
if (entity !is PokemonEntity) {
return null
}
if (!checkCondition(entity, condition)) {
if (!checkCondition(behaviourConfigurationContext.runtime, condition)) {
return null
}
return PlaceHoneyInHiveTask.create()
@@ -20,7 +20,7 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.phys.Vec3
class PointToSpawnTaskConfig : SingleTaskConfig {
override fun getVariables(entity: LivingEntity) = emptyList<MoLangConfigVariable>()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = emptyList<MoLangConfigVariable>()
override fun createTask(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext): BehaviorControl<in LivingEntity>? {
behaviourConfigurationContext.addMemories(MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET)
return BehaviorBuilder.create {
@@ -34,7 +34,7 @@ class PollinateFlowerTaskConfig : SingleTaskConfig {
val condition = booleanVariable(POLLINATE, "can_pollinate", true).asExpressible()
val durationTicks: ExpressionOrEntityVariable = Either.left("30".asExpression())
override fun getVariables(entity: LivingEntity) = listOf(
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(
condition
).asVariables()
@@ -45,7 +45,7 @@ class PollinateFlowerTaskConfig : SingleTaskConfig {
if (entity !is PokemonEntity) {
return null
}
if (!checkCondition(entity, condition)) {
if (!checkCondition(behaviourConfigurationContext.runtime, condition)) {
return null
}
@@ -162,11 +162,11 @@ on the entity type and this piggy-backs off the Minecraft list of aggressive mob
The 'calm_down' type creates a task that will make the entity calm down when it is no longer being hurt and is far from hostiles and its attacker.
- `condition`: A MoLang expression (with `q.entity` as the entity) that determines if this entire task should exist on the entity or not. This runs at the time of entity creation, not on tick.
### flee_attacker
The 'flee_attacker' type creates a task that will make the entity flee from its attacker when it is hurt.
### walk_away_from_avoid_target
The 'flee_attacker' type creates a task that will make the entity flee from its avoid target.
- `condition`: A MoLang expression (with `q.entity` as the entity) that determines if this entire task should exist on the entity or not. This runs at the time of entity creation, not on tick.
- `speedMultiplier`: A MoLang expression that determines the speed multiplier for fleeing from the attacker. Defaults to 0.5 which is an elevated speed to usual.
- `desiredDistance`: A MoLang expression that determines the distance from the attacker that the entity should try to maintain. Defaults to 9.
- `speedMultiplier`: A MoLang expression that determines the speed multiplier for fleeing from the avoid target. Defaults to 0.5 which is an elevated speed to usual.
- `desiredDistance`: A MoLang expression that determines the distance from the target that the entity should try to maintain. Defaults to 9.
### flee_nearest_hostile
The 'flee_nearest_hostile' type creates a task that will make the entity flee from the nearest hostile entity when it is hurt.
@@ -42,13 +42,12 @@ class RandomTaskConfig : TaskConfig {
val condition: ExpressionOrEntityVariable = Either.left("true".asExpression())
val choices = mutableListOf<RandomTaskChoice>()
override fun getVariables(entity: LivingEntity) = choices.flatMap { it.task.getVariables(entity) } + listOf(condition).asVariables()
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = choices.flatMap { it.task.getVariables(entity, behaviourConfigurationContext) } + listOf(condition).asVariables()
override fun createTasks(
entity: LivingEntity,
behaviourConfigurationContext: BehaviourConfigurationContext
): List<BehaviorControl<in LivingEntity>> {
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
if (!condition.resolveBoolean()) return emptyList()
if (!condition.resolveBoolean(behaviourConfigurationContext.runtime)) return emptyList()
val task = choices.weightedSelection { it.weight }?.task ?: throw IllegalStateException("No tasks to choose from in random_task config")
return task.createTasks(entity, behaviourConfigurationContext)
}
@@ -15,6 +15,7 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangV
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.mainThreadRuntime
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.behavior.BehaviorControl
@@ -42,7 +43,7 @@ class RunScript : SingleTaskConfig {
val memories = emptySet<MemoryModuleType<*>>()
val sensors = emptySet<SensorType<*>>()
override fun getVariables(entity: LivingEntity) = listOf(script).asVariables() + variables
override fun getVariables(entity: LivingEntity, behaviourConfigurationContext: BehaviourConfigurationContext) = listOf(script).asVariables() + variables
override fun createTask(
entity: LivingEntity,
@@ -54,10 +55,10 @@ class RunScript : SingleTaskConfig {
it.registered(MemoryModuleType.LOOK_TARGET) // I think I need to have at least something here?
).apply(it) { _ ->
Trigger { world, entity, _ ->
runtime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
mainThreadRuntime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
return@Trigger CobblemonScripts.run(
identifier = script.resolveString().asIdentifierDefaultingNamespace(),
runtime = runtime
identifier = script.resolveString(mainThreadRuntime).asIdentifierDefaultingNamespace(),
runtime = mainThreadRuntime
) == DoubleValue.ONE
}
}

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