Compare commits

...
Author SHA1 Message Date
Gertimoshka 2401985688 Stadium Block Rotation and Center defenitions 2025-05-14 13:31:55 +03:00
Gertimoshka 28e59f8bf9 Refactor Stadium Terminal (Block) to be Stadium Block 2025-04-30 08:38:04 +03:00
Gertimoshka 902f602354 Merge up-to-date branch 'main' into stadium-block-gert 2025-04-27 12:24:00 +03:00
Gertimoshka 8d8ac066f4 Merge Main into Stadium-Block-Gert 2025-04-27 12:12:32 +03:00
Gertimoshka bf53763443 Begginings of Stadium Block itself 2025-04-27 12:04:31 +03:00
Hiroku db573455ea Merge branch 'cross-dimensional-packets' into 'main'
Prevent Cross Dimensional Packets

See merge request cable-mc/cobblemon!1630
2025-04-27 00:06:22 +00:00
Hiroku 3af002a39c Changelog 2025-04-26 23:55:04 +00:00
Polymeta a15c44325d Merge branch 'riding-error-handling' into 'main'
Fail gracefully on riding deserialization errors

See merge request cable-mc/cobblemon!1639
2025-04-26 22:07:06 +00:00
Apion 33fc67ed58 Merge branch 'npc-gibberspeak' into 'main'
NPC gibberish

See merge request cable-mc/cobblemon!1616
2025-04-26 21:22:22 +00:00
Apion b9f2bcc3a3 Fix missing import causing compile error 2025-04-26 17:10:59 -04:00
Apion 8a5a88b4f1 Merge branch 'particle-reorg' into 'main'
𝕿𝖍𝖊 𝕲𝖗𝖊𝖆𝖙 𝕻𝖆𝖗𝖙𝖎𝖈𝖑𝖊 𝕽𝖊𝖔𝖗𝖌 𝖔𝖋 2025

See merge request cable-mc/cobblemon!1627
2025-04-26 21:01:01 +00:00
Apion af6b1190c1 Merge branch 'main' into npc-gibberspeak
# Conflicts:
#	common/src/main/resources/cobblemon-common.accesswidener
#	common/src/main/resources/mixins.cobblemon-common.json
2025-04-26 16:37:58 -04:00
Apion 7f0a6d4d48 Merge branch 'no-rolling' into 'main'
Option to disable rolling is now functional. I would not use this on anything...

See merge request cable-mc/cobblemon!1592
2025-04-26 20:22:15 +00:00
Apion d7e4298a91 Fix compile error from flashback MR 2025-04-26 15:42:44 -04:00
Landon Wills 923b4e4266 Change from throwing exception to logging warning when we fail to deserialize riding behaviour 2025-04-26 12:08:33 -04:00
Hiroku 30f82bbad6 Merge branch 'flashback-compat' into 'main'
Fix flashback crash

See merge request cable-mc/cobblemon!1629
2025-04-26 07:45:13 +00:00
Hiroku 1823eb4979 Merge branch 'npc-stealth' into 'main'
[molang] easy access npc hiding

See merge request cable-mc/cobblemon!1573
2025-04-26 04:09:36 +00:00
Apion ae4af68797 Fix compile errors 2025-04-25 21:55:26 -04:00
Polymeta da7f4a2682 Merge branch 'oopsies-fix-cake-texture' into 'main'
Add new cooking pot recipes, fix EV yield berry effects, fix other recipes,...

See merge request cable-mc/cobblemon!1637
2025-04-25 22:27:50 +00:00
Polymeta 73c4762801 Merge branch 'new-recipes-fix-recipes-fix-baits-color-cakes' into 'main'
Add new cooking pot recipes, fix EV yield berry effects, fix other recipes,...

See merge request cable-mc/cobblemon!1636
2025-04-25 21:21:49 +00:00
Plastered_Crab 43abfa3c17 New Lure/Poke Cake item sprites for tinting 2025-04-25 14:20:07 -07:00
Plastered_Crab fb87220fe9 Add new cooking pot recipes, fix EV yield berry effects, fix other recipes, add color to Lure/Poke Cake item texture 2025-04-25 13:33:59 -07:00
Sterrezo 07bba37c03 Restored and relocated assets 2025-04-25 20:00:00 +02:00
Sterrezo 5896a74d1f Added generic gibber sound 2025-04-25 19:14:45 +02:00
Landon 2a0de32854 Merge branch 'fix-species-config' into 'main'
Fix misconfigured riding behaviours preventing world load

See merge request cable-mc/cobblemon!1635
2025-04-25 17:07:45 +00:00
Landon Wills 406097c1ff Fix misconfigured riding behaviours preventing world load 2025-04-25 12:27:28 -04:00
Landon 14ec3c00e6 Merge branch 'cleanup-camera-mixin' into 'main'
Cleanup camera mixin

See merge request cable-mc/cobblemon!1633
2025-04-25 16:26:09 +00:00
Landon 18b17b0638 Merge branch 'riding-behaviour-additions-01' into 'main'
Refine air behaviour controls. rideAltPose now returns a ResourceLocation for unique pose control. Update...

See merge request cable-mc/cobblemon!1626
2025-04-25 16:09:33 +00:00
Jackson Bowes 59c96fe30d Merge branch 'main' into 'riding-behaviour-additions-01'
# Conflicts:
#   common/src/main/kotlin/com/cobblemon/mod/common/api/riding/behaviour/types/GliderAirBehaviour.kt
2025-04-25 09:34:23 -05:00
JacksonB 565667aa1c Address MR comments 2025-04-25 09:29:17 -05:00
Polymeta 3955283425 Merge branch 'treeafying-saccharine' into 'main'
Tree-afying the Saccharine Tree to reflect vanilla tree behaviour

See merge request cable-mc/cobblemon!1631
2025-04-25 12:50:31 +00:00
AramandPolymeta beee02033c Tree-afying the Saccharine Tree to reflect vanilla tree behaviour 2025-04-25 12:50:30 +00:00
Polymeta 86902b69e1 fix duplicate mixin entry and server error when unlocking wallpapers
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-25 00:29:24 +01:00
JPAK 2ac102a3b6 Fix issue with pivot offset & update licenses. 2025-04-24 16:23:04 -05:00
Polymeta a54ff5f0a7 Merge branch 'fix-server-crash' into 'main'
Move client code in PlayerMixin to LocalPlayerMixin to fix crash.

See merge request cable-mc/cobblemon!1632
2025-04-24 19:53:36 +00:00
JPAK edc5ae741c Move large amounts of render code from CameraMixin to new MountedCameraRenderer.kt 2025-04-24 14:50:29 -05:00
JPAK 70bed4f299 Move client code in PlayerMixin to LocalPlayerMixin to fix crash. 2025-04-24 14:10:41 -05:00
Polymeta e24b20546d Merge branch 'first_person_poser' into 'main'
Add poser option to offset first person camera while riding. This is in...

See merge request cable-mc/cobblemon!1600
2025-04-24 11:54:47 +00:00
Polymeta eb071d4d01 Merge branch 'we_are_cooking_now' into 'main'
Cooking

See merge request cable-mc/cobblemon!1535
2025-04-24 11:42:56 +00:00
Polymeta 625a31e7e8 fix another server-side error
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-24 11:41:52 +01:00
Polymeta 2b14931709 licenses
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-24 11:15:32 +01:00
Polymeta 2c32b50182 fix server crash and small cleanup
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-24 11:12:41 +01:00
Plastered_Crab b5230a8d3c Merge with main and register IncenseSweetProspector 2025-04-23 16:39:14 -07:00
Plastered_Crab 5ff3d163c0 Merge branch 'main' into we_are_cooking_now
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/spawn/SpawnPokemonPacket.kt
#	common/src/main/resources/mixins.cobblemon-common.json
2025-04-23 16:06:41 -07:00
Plastered_Crab 82e6e01978 Add Sweet Incense to the POI system and add Prospector and Influence 2025-04-23 16:01:10 -07:00
JPAK a6b5f2d64c Add thirdPersonPivotOffset to posers. Meant to be the player's location relative to the base of the pokemon when the pokemon's center is too far from the player. 2025-04-23 14:44:48 -05:00
JPAK 6408b60dde Merge branch 'main' into riding-render-and-stuff 2025-04-23 13:59:56 -05:00
Polymeta b6308e6c6c rideable pokemon are also allowed to turn their heads if no one is actually riding them
Closes #1530

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-22 15:28:54 +01:00
Gertimoshka 7e553c440e Renamed a lot of classes as Stadium Cameras is just Battle Camera, and the system is not directly connected to Stadium Block 2025-04-22 14:18:44 +03:00
Gertimoshka be2e576df6 Battle Camera System can now be provided with center and yRot and all the Cameras applied will be offset by them 2025-04-22 13:55:10 +03:00
CeeJay da7dbeaaec add check for player dimension 2025-04-22 00:26:37 -04:00
Apion 84a0ceb7e1 Remove flashback dep (again) 2025-04-21 17:45:05 -04:00
Apion ccde7ffbb1 Merge branch 'main' into flashback-compat 2025-04-21 17:41:35 -04:00
apionandApion 4e79ed9f7e Remove flashback dep 2025-04-21 17:41:09 -04:00
321retrogamer dea2ad4b12 𝕿𝖍𝖊 𝕲𝖗𝖊𝖆𝖙 𝕻𝖆𝖗𝖙𝖎𝖈𝖑𝖊 𝕽𝖊𝖔𝖗𝖌 𝖔𝖋 2025
Completely reworks particle texture pathways and alters particles to direct to those pathways. All existing 1.6.1 particles (as well as the new Protect activation particles, which are also here) have been altered to fit this reorganization effort.

All particle textures have also been renamed to match the guidelines of the reorg, as they are now seen in the assets repo.
2025-04-20 23:28:39 -05:00
JacksonB ecefea005d Merge branch 'main' into riding-behaviour-additions-01 2025-04-20 23:13:46 -05:00
JacksonB 4c787f547c Bird is finally feeling how it was always meant to feel!! 2025-04-20 22:27:36 -05:00
JacksonB f0755cc73f Merge branch 'riding-debug-ui' into riding-behaviour-additions-01 2025-04-20 22:27:04 -05:00
Hiroku e215d751c4 Merge branch 'ouch_fire_blocks' into 'main'
Floating Pokemon really float, and Fire Immunity attribute

See merge request cable-mc/cobblemon!1612
2025-04-21 02:05:29 +00:00
CeejayandHiroku aac4669ec1 Floating Pokemon really float, and Fire Immunity attribute 2025-04-21 02:05:28 +00:00
Landon 7b0b41d192 Merge branch 'riding-debug-ui' into 'main'
Riding Debug UI

See merge request cable-mc/cobblemon!1623
2025-04-21 01:33:18 +00:00
JacksonB 7e38fefa14 various controller tweaks 2025-04-20 17:00:21 -05:00
plastered_crab c1491daf63 Placing honey on Saccharine Logs now gives higher chance of Hidden Abilities nearby 2025-04-20 11:09:58 -07:00
Polymeta 068b55be7b Merge branch 'josh/dynamic-light-integration' into 'main'
Josh/dynamic light integration

See merge request cable-mc/cobblemon!1621
2025-04-20 13:52:34 +00:00
JoshandPolymeta 3f6bd52d43 Josh/dynamic light integration 2025-04-20 13:52:34 +00:00
Polymeta 4ca3f25ab2 Merge branch 'translucent-culling' into 'main'
Translucent Culling Parameter

See merge request cable-mc/cobblemon!1606
2025-04-20 09:47:02 +00:00
GertimoshkaandPolymeta 70e81f1cbe Translucent Culling Parameter 2025-04-20 09:47:02 +00:00
Polymeta df8abf4ddb Merge branch 'josh/left-handed-item-fix' into 'main'
Item position adjustment to perfectly line up hand-held items

See merge request cable-mc/cobblemon!1610
2025-04-20 09:46:28 +00:00
JoshandPolymeta 26dd0b9d42 Item position adjustment to perfectly line up hand-held items 2025-04-20 09:46:28 +00:00
plastered_crab 307d8bad1d Added new Honey Log and Lure Cakes can have more bites 2025-04-20 00:16:07 -07:00
Landon Wills 866332e62c Remove composite logic from debug gui 2025-04-19 23:17:59 -04:00
Landon Wills c54466f6b1 Merge branch 'refs/heads/main' into riding-debug-ui 2025-04-19 23:14:18 -04:00
Landon Wills fb570404c0 Update licenses 2025-04-19 22:29:34 -04:00
Landon Wills d22602dac5 Update visibility of debug variables 2025-04-19 22:26:27 -04:00
Aram 63da8fed2d Removed the Sweet Sap item 2025-04-20 02:42:43 +02:00
Paul 2f16ba5470 Don't play quirks in battle GUI 2025-04-20 08:53:39 +10:00
Aram af36d4a365 Saccharine Log now has code for when you use items on it 2025-04-20 00:52:58 +02:00
Aram d153ec155b Beehive only generates in Saccharine tree if theres a flower when it grows up 2025-04-20 00:31:59 +02:00
Aram 7ca7cc089a Removed the Age in the Saccharine Stripped Log 2025-04-19 23:36:48 +02:00
Landon cbdfbc9745 Merge branch 'pc-box-name-limit' into 'main'
Adds name character length restriction to PC box name.

See merge request cable-mc/cobblemon!1620
2025-04-19 11:28:15 +00:00
Hiroku ac210e027b Merge branch 'windows-12' into 'main'
more pc stat displays

See merge request cable-mc/cobblemon!1617
2025-04-19 11:04:57 +00:00
TestandHiroku 1fc91a794f more pc stat displays 2025-04-19 11:04:57 +00:00
Landon f78b289171 Merge branch 'riding-dismount' into 'main'
Created the Pokemon Dismount Logic

See merge request cable-mc/cobblemon!1613
2025-04-19 10:47:16 +00:00
AramandLandon c46461c843 Created the Pokemon Dismount Logic 2025-04-19 10:47:16 +00:00
Deltric 386a897295 Adds name character length restriction to PC box name. 2025-04-19 05:46:22 -05:00
Hiroku 8328f741d8 Merge branch 'spawn-pool-observable' into 'main'
Observable in SpawnPool was not emitted on reload.

See merge request cable-mc/cobblemon!1618
2025-04-19 09:07:56 +00:00
Deltric 2b19943416 Observable in SpawnPool was not emitted on reload. 2025-04-19 03:30:50 -05:00
Paul 7dd38bf043 Ratified dialogue gibberish with cool toys 2025-04-19 14:29:47 +10:00
Test 4caba2fbeb gibber sounds 2025-04-19 03:58:20 +00:00
plastered_crab 5239de2cea Merge branch 'refs/heads/we_are_cooking_now(Seasoning-Bait-Testing)' into we_are_cooking_now 2025-04-18 17:13:13 -07:00
JacksonB 296355f744 Ride stat reversions 2025-04-18 12:04:38 -05:00
JacksonB e9d9a109c0 Squashed commit of the following:
commit 8960c6dddc
Author: Landon Wills <landonjwdev@gmail.com>
Date:   Fri Apr 18 03:11:19 2025 -0400

    Fix issue with ride stat calc

commit bc1f9f8cb4
Author: Landon Wills <landonjwdev@gmail.com>
Date:   Fri Apr 18 02:54:42 2025 -0400

    Add riding debug UI
2025-04-18 10:49:50 -05:00
JacksonB 8a3789fc35 Merge branch 'main' into riding-behaviour-additions-01 2025-04-18 10:45:36 -05:00
JacksonB 05fd7bec36 Line up land walk with animation walk speed 2025-04-18 10:36:21 -05:00
Paul e6b1529f27 Gradual reveal of text while gibbering 2025-04-18 22:16:53 +10:00
Paul 550b99be36 Merge remote-tracking branch 'origin/main' into lang-updates 2025-04-18 22:01:33 +10:00
Landon Wills a42ba8de43 Make dialogues play gibberish as a NPC POC 2025-04-18 06:07:18 -04:00
Landon Wills 8960c6dddc Fix issue with ride stat calc 2025-04-18 03:11:19 -04:00
Polymeta bfbee7b1d7 Merge branch 'loot-fix' into 'main'
Improved parity with vanilla mobs' drop behavior

See merge request cable-mc/cobblemon!1576
2025-04-18 07:02:45 +00:00
Landon Wills bc1f9f8cb4 Add riding debug UI 2025-04-18 02:54:42 -04:00
Test f5d71390dd Merge branch 'dex-zoom' into 'main'
A few dex scanner fixes/improvements, closes #1328

Closes #1328

See merge request cable-mc/cobblemon!1608
2025-04-18 05:06:31 +00:00
CraterandTest 6ff5d3df06 A few dex scanner fixes/improvements, closes #1328 2025-04-18 05:06:30 +00:00
gruxor 988766894a Review resolutions 2025-04-18 00:08:43 -04:00
Polymeta 34805ea496 oop typo - allow dragon breath to be used in a restoration tank
Closes #1539

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-18 00:25:39 +01:00
Polymeta b670d44e21 reorder delegate molang functions to be added first so they are overridden by more specific functions
Also allow PoseableState sound molang to play without an entity present (in UIs)

Closes #1529

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-18 00:08:59 +01:00
Polymeta 159905eb3b Merge branch 'josh/left-handed-item-fix' into 'main'
Corrected item rotation for left hand display context

See merge request cable-mc/cobblemon!1609
2025-04-17 20:32:11 +00:00
Josh c10213480b Flip rotations when display context is left hand 2025-04-17 15:22:11 -04:00
gruxor 3d5a365a6e Added a configuration option for drops' behavior upon Pokémon death 2025-04-17 14:06:33 -04:00
gruxor 4b64b4307a Changelog update 2025-04-17 14:04:16 -04:00
gruxor 382f741db8 Improved parity with vanilla mobs' drop behavior 2025-04-17 14:04:16 -04:00
TeggyandWeblate 6d62d911d6 Translated using Weblate (Spanish)
Currently translated at 96.6% (6787 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-17 11:38:28 +00:00
Alexis SalgueiroandWeblate a1d40084c5 Translated using Weblate (French)
Currently translated at 92.2% (6479 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-04-17 04:04:45 +00:00
TeggyandWeblate 8b1b63e110 Translated using Weblate (Spanish)
Currently translated at 96.4% (6775 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-17 04:04:44 +00:00
JacksonB a7956531ff Forgot this 2025-04-16 18:04:54 -05:00
JacksonB 4b0919223b rideAltPose now returns a ResourceLocation for unique pose control. Update molang function naming issues. Add transformToTick field in poser jsons so that a pose can specify the transformTick of any pose transitioning to the given one. 2025-04-16 18:03:10 -05:00
Polymeta baf3cd5f30 Merge branch 'moon-ball-fix-🌕🌒🌓🌔🌑🌘🌗🌖' into 'main'
Fix the messed up Moon Phase code for the Moon Ball catch rate

See merge request cable-mc/cobblemon!1605
2025-04-16 17:16:36 +00:00
Plastered_Crab 2327f1aa2c Add this to make Polymeta happy 2025-04-16 09:46:11 -07:00
plastered_crab 62036c0ac6 Fix the messed up Moon Phase code for the Moon Ball catch rate 2025-04-16 07:57:00 -07:00
TeggyandWeblate 9e2e95e287 Translated using Weblate (Spanish)
Currently translated at 96.0% (6744 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-16 09:42:42 +00:00
Landon 2db494ff5e Merge branch 'Dex-Species-Forms' into 'main'
Update English Lang with official values and preliminary species form support for the dex

See merge request cable-mc/cobblemon!1454
2025-04-16 04:43:43 +00:00
Konoha 7fe1415551 Clean InfoWidget form parsing. 2025-04-15 23:24:56 -04:00
Konoha ca4d4ed3be Re-Run Lang Key Scrape & Changelog 2025-04-15 09:02:29 -04:00
Konoha 700227be41 Merge branch 'main' into Dex-Species-Forms
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2025-04-15 08:39:33 -04:00
Konoha 985a4f65dc Re-Run Lang Key Scrape & Changelog 2025-04-15 08:16:41 -04:00
Konoha e117100e34 Re-Run Lang Key Scrape & Changelog 2025-04-15 08:06:10 -04:00
Konoha 93ea13fa4d Merge branch 'main' into Dex-Species-Forms 2025-04-15 07:57:01 -04:00
Gertimoshka 5bc056d28e Breaking my head working on this, but steady progress finalizing the camera system itself 2025-04-15 11:54:29 +03:00
TeggyandWeblate 6694680c50 Translated using Weblate (Spanish)
Currently translated at 95.9% (6735 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-15 05:11:49 +00:00
Polymeta cd14881d17 Merge branch 'immersive-tweaks' into 'main'
Foods and Recipes

See merge request cable-mc/cobblemon!1554
2025-04-14 20:45:41 +00:00
dhi_holoandPolymeta 1393cc3ef3 Foods and Recipes 2025-04-14 20:45:40 +00:00
Konoha 23ebd0573a Merge branch 'implement_pokemon' into Dex-Species-Forms
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2025-04-14 08:05:18 -04:00
Polymeta 6447c2e2eb Merge branch 'per-world-gamerule-support' into 'main'
Add per-level gamerule support for doPokemonSpawning

See merge request cable-mc/cobblemon!1593
2025-04-14 11:32:54 +00:00
TeggyandWeblate 8cafce0a4a Translated using Weblate (Spanish)
Currently translated at 95.7% (6724 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-14 10:33:04 +00:00
BlackBeltPanda 039a18a2bf Update CHANGELOG.md 2025-04-14 04:46:06 -04:00
Watuneni iteiteandWeblate de271f81b1 Translated using Weblate (Japanese)
Currently translated at 76.4% (5365 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-04-14 06:50:20 +00:00
TeggyandWeblate feb78c5c58 Translated using Weblate (Spanish)
Currently translated at 95.3% (6698 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-14 06:50:19 +00:00
JacksonB 8aedac3474 More gyarados tests 2025-04-14 00:05:25 -05:00
FrankTheFarmer 71736341f0 Merge branch 'main' into implement_pokemon 2025-04-14 13:55:12 +10:00
JacksonB ca133a20c0 Jet input decay, new wip behaviour, gyarados ride body tests. 2025-04-13 17:57:06 -05:00
Landon bb6e5607f1 Merge branch 'stop-head-pitch' into 'main'
Make head moving actually stop this time.

See merge request cable-mc/cobblemon!1596
2025-04-13 04:55:00 +00:00
Landon 4603f5ac7a Merge branch 'riding-animation-01' into 'main'
Riding dynamic animation, riding fixes, and controller tweaks

See merge request cable-mc/cobblemon!1599
2025-04-12 23:59:31 +00:00
Jackson BowesandLandon c683294227 Riding dynamic animation, riding fixes, and controller tweaks 2025-04-12 23:59:31 +00:00
JPAK acc601d414 Add poser option to offset first person camera while riding. This is in addition to the locator and shouldn't need to be used often. 2025-04-12 17:12:20 -05:00
JPAK f29c2343e6 Merge remote-tracking branch 'origin/stop-head-pitch' into stop-head-pitch 2025-04-12 16:41:40 -05:00
JPAK 3a2da5a87d Make head moving actually stop this time. 2025-04-12 16:41:13 -05:00
QriviateA 27d1de8e4e Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-04-12 17:14:04 +01:00
MiaandWeblate e5d052a6bf Translated using Weblate (German)
Currently translated at 86.7% (6090 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/de/
2025-04-12 10:41:09 +00:00
Landon 1c13ab24e8 Merge branch 'even-more-riding-tweaks' into 'main'
Even more riding tweaks

See merge request cable-mc/cobblemon!1597
2025-04-12 03:07:36 +00:00
Paul 380cf0ea71 You? You're meant to be dead! 2025-04-12 12:29:44 +10:00
Paul 8ded7334bb Refactor forcedTick handling in PosableEntityModel 2025-04-12 12:23:17 +10:00
Hiroku 2e05b25061 Merge branch 'main' into 'no-rolling'
# Conflicts:
#   common/src/main/java/com/cobblemon/mod/common/mixin/client/CameraMixin.java
2025-04-12 02:01:46 +00:00
QriviateA 8af62f800b Updated changelog 2025-04-12 01:27:10 +01:00
QriviateA a50da47a8e Updated Kangaskhan model + anims 2025-04-12 01:26:47 +01:00
QriviateA f690781b0d Updated Cinderace model + anims 2025-04-12 01:26:16 +01:00
FrankTheFarmer 6a7fc67ae1 Merge branch 'main' into implement_pokemon 2025-04-12 08:10:08 +10:00
Polymeta 0ac34bf1a4 Merge branch 'locator-rotation-player-rendering' into 'main'
Lock player model to seat locator's rotation when riding

See merge request cable-mc/cobblemon!1598
2025-04-11 19:41:47 +00:00
Landon Wills 9716ea0806 Fix rotation of player when using custom camera 2025-04-11 06:13:47 -04:00
Landon Wills ffea94f3b2 Rotate player depending on seat locator's rotation 2025-04-11 03:39:49 -04:00
Landon Wills 3061ba69e2 Riding momentum is maintained when window is not active 2025-04-11 03:17:26 -04:00
Landon Wills 741e38d606 Fix issue where same-species pokemon will sync animations on multiplayer environments 2025-04-11 02:01:28 -04:00
Landon Wills 02f2c072c9 Fix issues with pre-animation logic 2025-04-11 01:29:49 -04:00
Paul cf9d794fe1 I demand you compile 2025-04-11 11:57:23 +10:00
Paul 14a3e7afb1 Merge remote-tracking branch 'origin/main' into we_are_cooking_now
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonItems.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/RidingManager.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/PosableState.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/spawn/SpawnPokemonPacket.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/riding/controllers/GliderAirController.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/riding/controllers/VehicleLandController.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/DataKeys.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/codec/internal/ClientPokemonP3.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/util/codec/internal/PokemonP3.kt
#	common/src/main/resources/mixins.cobblemon-common.json
2025-04-11 10:08:28 +10:00
JPAK 4722defec2 Make head moving actually stop this time. 2025-04-10 13:14:32 -05:00
Polymeta c54849f415 Merge branch 'implement_pokemon' into 'main'
Few mons added for testing

See merge request cable-mc/cobblemon!1595
2025-04-10 13:46:35 +00:00
Frank The FarmerandPolymeta d44e625e9d Few mons added for testing 2025-04-10 13:46:35 +00:00
FrankTheFarmer 7b7acb97d1 Changelog 2025-04-10 23:05:56 +10:00
FrankTheFarmer 53af92f254 Implemented Metagross with locators for testing 2025-04-10 23:04:07 +10:00
FrankTheFarmer 91bce4b153 Merge branch 'main' into implement_pokemon 2025-04-10 22:32:31 +10:00
BlackBeltPanda 511130d353 Remove redundant check for player UUID in spawnersForPlayers and early return in registerPlayerSpawner 2025-04-10 05:42:10 -04:00
BlackBeltPanda 476c3e54f1 Return early in CobbledWorldSpawnerManager#onDimensionChange when DO_POKEMON_SPAWNING gamerule is equal in origin and destination levels 2025-04-10 05:40:13 -04:00
Polymeta 6a74d5982a Merge branch 'more-riding-tweaks' into 'main'
Riding tweaks / fixes

See merge request cable-mc/cobblemon!1594
2025-04-10 09:13:32 +00:00
Landon Wills 03905c77d2 Add license 2025-04-10 03:12:53 -04:00
FrankTheFarmer 4bfe8b808c Implemented Magnezone with locators for testing 2025-04-10 16:36:21 +10:00
FrankTheFarmer 8db943d2a9 Merge branch 'main' into implement_pokemon 2025-04-10 16:34:54 +10:00
FrankTheFarmer fdff6ecfa5 Implemented Magnezone with locators for testing 2025-04-10 16:33:51 +10:00
BlackBeltPanda 2eb698969d Add onDimensionChange method to CobbledWorldSpawnerManager 2025-04-10 01:52:12 -04:00
BlackBeltPanda bba60f0098 Check DO_POKEMON_SPAWNING gamerule for the correct Level in SpawnerManager#onServerTick and CobbledWorldSpawnerManager#onPLayerLogin 2025-04-10 01:50:33 -04:00
BlackBeltPanda 8ee2c95853 Add unregisterPlayerSpawner and registerPlayerSpawner methods to CobbledWorldSpawnerManager 2025-04-10 01:45:43 -04:00
BlackBeltPanda 77db2ce17a Add origin and destination ServerLevel properties to ChangeDimensionEvent 2025-04-10 01:43:59 -04:00
Landon Wills da9558f5f9 Fix camera riding momentum not occurring when in chat or screens 2025-04-10 01:40:44 -04:00
JPAK 8aeb7a43c8 Option to disable rolling is now functional. I would not use this on anything and do flips as the camera does not handle it well.
Also fixed issue where camera Forward and Left would be improperly set in third person reverse.
2025-04-09 22:52:00 -05:00
Landon Wills 5c65dffac8 Improve rendering of ridden pokemon substantially on low or inconsistent FPS 2025-04-09 23:36:21 -04:00
Landon Wills b67b37c99e Fix some issues with merge 2025-04-09 22:54:23 -04:00
Landon Wills fbb7ee31c5 Merge branch 'refs/heads/main' into water-mount-behaviours 2025-04-09 22:38:45 -04:00
Polymeta d3ef26976b Merge branch 'composite-behaviour-refactor' into 'main'
Composite behaviour refactor

See merge request cable-mc/cobblemon!1584
2025-04-09 15:58:55 +00:00
Landon Wills dac01a3730 Fix issue with crashing on packet decode before player is initialized 2025-04-09 03:30:55 -04:00
Landon Wills ddb05768e4 Remove redundant riding behaviour, rename ride style option from misc to composite 2025-04-09 03:17:31 -04:00
Polymeta 5374940d24 Merge branch 'spicy-molang' into 'main'
Added `spawn_pokemon` and `attempt_wild_battle` as available MoLang functions

Closes #1237

See merge request cable-mc/cobblemon!1586
2025-04-09 07:13:00 +00:00
SpicyandPolymeta 1fd6a660dd Added spawn_pokemon and attempt_wild_battle as available MoLang functions 2025-04-09 07:13:00 +00:00
Landon Wills fd45934775 Fix issue with canRide condition, remove duplicate riding config in aerodactyl 2025-04-09 03:09:04 -04:00
Polymeta 5e0ffd8bd3 Merge branch 'josh/item-molang-fixes' into 'main'
Small fixes for molang functions related to item rendering.

See merge request cable-mc/cobblemon!1590
2025-04-08 16:02:48 +00:00
JoshandPolymeta b4b315360d Small fixes for molang functions related to item rendering. 2025-04-08 16:02:48 +00:00
Polymeta a44c70648b actually return held item to player again
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-08 16:07:20 +01:00
Polymeta c41b0cdca2 Merge branch 'negative-config-values' into 'main'
Allow negative numbers in config GUI

See merge request cable-mc/cobblemon!1588
2025-04-08 12:01:45 +00:00
lionandPolymeta 88f743ee48 Allow negative numbers in config GUI 2025-04-08 12:01:44 +00:00
Polymeta 15b9afacf8 remove client logic from common code MoLang functions
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-08 12:59:36 +01:00
TeggyandWeblate 0ea4641536 Translated using Weblate (Spanish)
Currently translated at 95.3% (6696 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-08 10:41:46 +00:00
Polymeta babcf7430b don't error when heldItem nbt is not present
Closes #1505

Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-08 11:38:05 +01:00
Polymeta 3439ca2011 [skip-ci] fix tag docs formatting
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-08 10:55:48 +01:00
FrankTheFarmer ff5ea6fa21 Merge branch 'main' into implement_pokemon 2025-04-08 19:42:22 +10:00
Polymeta 6539f3dea1 Merge branch 'josh/3d-wearable-items' into 'main'
Start of wearable item implementation.

See merge request cable-mc/cobblemon!1579
2025-04-08 09:16:24 +00:00
FrankTheFarmer 4820d78416 Implemented Jolteon's item holding animation 2025-04-08 19:05:35 +10:00
FrankTheFarmer 2f417e953c Added placeholder cry to the eeveelution animations 2025-04-08 18:38:39 +10:00
FrankTheFarmer 8fde0ed4f6 Added rootbone and cry back to the eeveelution posers 2025-04-08 18:38:08 +10:00
FrankTheFarmer 6715874a8f Merge branch 'main' into implement_pokemon 2025-04-08 16:00:52 +10:00
RedGenesectNinja 31f88a1f68 Implemented Druddigon 2025-04-08 00:37:09 -05:00
Landon Wills 1677598ec0 Merge branch 'refs/heads/main' into water-mount-behaviours
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/client/CameraMixin.java
2025-04-08 01:36:01 -04:00
Landon fcde1eb171 Merge branch 'hitbox-and-hit' into 'main'
Position hitbox on client to be accurate to the locator and make looking at...

See merge request cable-mc/cobblemon!1589
2025-04-08 03:26:26 +00:00
Josh a30a5644df Okay, this is it this time for real 2025-04-07 23:03:30 -04:00
JPAK a5672a38b9 Switch to using delegates to position riders. 2025-04-07 21:37:42 -05:00
JPAK 3b14ea319b Position hitbox on client to be accurate to the locator and make looking at stuff align to the camera. 2025-04-07 21:12:01 -05:00
Landon Wills 57e2765f90 Clean up some method signatures in CameraMixin 2025-04-07 21:57:20 -04:00
Josh a090c90831 Merge branch 'main' into josh/3d-wearable-items 2025-04-07 20:55:41 -04:00
FrankTheFarmer f80aa2769a Restored Treecko line cries 2025-04-08 10:55:39 +10:00
FrankTheFarmer 20aa4d43b8 Delphox wand animation tweaks 2025-04-08 09:19:10 +10:00
FrankTheFarmer 9bec3e088f Changelog moment 2025-04-08 08:42:49 +10:00
FrankTheFarmer 5b4dbe1957 Imported old placeholder walk and cry for Braixen and Delphox 2025-04-08 08:36:19 +10:00
FrankTheFarmer 48f248d481 Fixed a crash caused by cosmetic remodels for Braixen and Delphox. 2025-04-08 08:36:00 +10:00
FrankTheFarmer d726c4d0ed Merge branch 'main' into implement_pokemon
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/models/blockbench/repository/VaryingModelRepository.kt
2025-04-08 08:19:12 +10:00
Josh 5dcc9ba46d Edit CHANGELOG.md 2025-04-07 21:21:05 +00:00
Josh f8e4ea70df Removed debug models. 2025-04-07 17:09:15 -04:00
Josh 5dc1c749f3 Replaced WearableItemModel enum with WearableItem class. Instances of this class should have a corresponding 3D model in models/item/wearable/ 2025-04-07 16:35:46 -04:00
Polymeta 3accfa29b7 Merge branch 'josh/joint-transform-command' into 'main'
Changed command "changejointscale" into "transformmodelpart". Allows you to easily add model transformations in-game.

See merge request cable-mc/cobblemon!1587
2025-04-07 17:18:56 +00:00
Josh 1af1569f63 Updated CHANGELOG.md 2025-04-07 11:13:27 -04:00
FrankTheFarmer c9c421ba2a Fixed Sneasler model issues from previous update for cosmetic basket. 2025-04-07 21:00:12 +10:00
FrankTheFarmer 2436a8ddcc Fixed Tropius typo in changelog 2025-04-07 20:04:13 +10:00
FrankTheFarmer 3364944c26 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-04-07 19:57:12 +10:00
FrankTheFarmer 9e6a6eabc7 Fixed the wrong type of Crocs mentioned in the changelog 2025-04-07 19:55:57 +10:00
FrankTheFarmer 78def7318e Treecko my beloved. Gave json poser and fixed t-pose 2025-04-07 19:55:09 +10:00
FrankTheFarmer fdf062bd4c oops, fixed dex number for grovyle poser 2025-04-07 19:44:37 +10:00
FrankTheFarmer ef5a682adb Fixed stick related Grovyle crash and gave it a JSON poser 2025-04-07 19:41:11 +10:00
Polymeta dbd2f5d340 Merge branch 'implement_pokemon' into 'main'
Implemented many pokemon

See merge request cable-mc/cobblemon!1585
2025-04-07 09:35:47 +00:00
Frank The FarmerandPolymeta 86bf413f00 Implemented many pokemon 2025-04-07 09:35:46 +00:00
Polymeta f76d28d29e updated changelog 2025-04-07 09:35:20 +00:00
FrankTheFarmer 9c70aad64d Fixed stick related Sceptile crash and gave it a JSON poser 2025-04-07 19:17:56 +10:00
FrankTheFarmer 25de1ad180 Merge branch 'main' into implement_pokemon 2025-04-07 15:13:02 +10:00
FrankTheFarmer f967d1ec11 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-04-07 15:12:10 +10:00
FrankTheFarmer efd0497de1 Fixed Garchomp using battle idle in its portrait and profile 2025-04-07 15:00:47 +10:00
Landon f13e7d03a1 Merge branch 'camera-changes-third-person' into 'main'
Riding Third Person Camera

See merge request cable-mc/cobblemon!1582
2025-04-07 02:51:07 +00:00
JordanandLandon 4a025ac65e Riding Third Person Camera 2025-04-07 02:51:07 +00:00
Josh 8a0c98c9ab Renamed command to transformmodelpart 2025-04-06 18:58:13 -04:00
Josh 36c5fe2419 Properly display name of model part. 2025-04-06 18:52:15 -04:00
Josh 0c79d102cf Changed changejointscale command into transformpartcommand with can cahnge the position rotation and scale of any joint on a model. 2025-04-06 18:31:39 -04:00
Polymeta b14b25ae19 Merge branch 'SaferSendouts' into 'main'
Safer sendouts

See merge request cable-mc/cobblemon!1458
2025-04-06 20:58:09 +00:00
Kenji_64 b30c0a4a9a Adjusted Nosepass' walk speed. (Thanks Lennie and Frank!) 2025-04-06 22:21:25 +02:00
Kenji_64 c99b26a44b Added animations to Nosepass and Probopass. Made new JSON posers and replaced the Kotlin ones (thanks Lennie!) 2025-04-06 21:06:37 +02:00
Josh bd8f644b9a Add scaling as an option when creating transformedParts 2025-04-06 10:56:10 -04:00
Josh 7c84cdb05d transformedParts must add to the model part rather than replacing it with set() 2025-04-06 10:54:00 -04:00
FrankTheFarmer b19bc1e4c7 updated changelog 2025-04-06 21:21:37 +10:00
FrankTheFarmer bc5ffda1a5 Expedited crobat with locators 2025-04-06 21:19:09 +10:00
FrankTheFarmer 491d6c9fd6 Expedited salamence with locators 2025-04-06 21:19:01 +10:00
FrankTheFarmer ccc6ad77a5 Garchomp and perchance the craziest poser that ever lived 2025-04-06 19:47:02 +10:00
FrankTheFarmer 00fd9d1278 oopsies forgot portrait and profile data on honchkrow 2025-04-06 19:47:02 +10:00
FrankTheFarmer 01464f8b71 Expediting more models for reasons the government will not allow me to explain 2025-04-06 19:47:01 +10:00
FrankTheFarmer d91fe0b876 Merge branch 'main' into implement_pokemon 2025-04-06 18:56:00 +10:00
Landon Wills 0293c0e811 Update licenses 2025-04-06 04:02:10 -04:00
Landon 125975e25f Merge branch 'item-with-components-swap' into 'main'
Fixed not being able to swap held item of the same type, but have different components.

See merge request cable-mc/cobblemon!1580
2025-04-06 05:42:42 +00:00
Landon Wills c7223ae898 Fix some issues with the new composite system, move assets to new system 2025-04-06 01:35:46 -04:00
Landon baf766298a Merge branch 'riding-ground-render-revert' into 'main'
revert broken ground rendering code. Correctly set stale yrot value on return...

See merge request cable-mc/cobblemon!1583
2025-04-06 05:11:30 +00:00
Jackson BowesandLandon 83580e7e8b revert broken ground rendering code. Correctly set stale yrot value on return... 2025-04-06 05:11:30 +00:00
plastered_crab 4de32b8bf4 Tweak rarity bucket calculating 2025-04-05 21:19:40 -07:00
Landon Wills 38f5c12dce Remove some redundant casting 2025-04-05 23:59:47 -04:00
Landon Wills e6a9a27692 Forgot to remove some code I refactored 2025-04-05 23:59:21 -04:00
Landon Wills 7ff413c401 Add support for custom behaviour settings for different composite strategies 2025-04-05 23:57:30 -04:00
plastered_crab 9d6447af9a Rarity bucket bait effect combines with Luck of the Sea 2025-04-05 20:39:17 -07:00
Test 90335ccb2d hide mark scroll when unused 2025-04-05 17:26:09 -04:00
plastered_crab 7eb5f93595 Added bait effects for enchanted gold apple, gold carrot, and glistening melon slice 2025-04-05 12:47:20 -07:00
plastered_crab 3b54fa488e Added bait effects for enchanted gold apple, gold carrot, and glistening melon slice 2025-04-05 12:43:05 -07:00
plastered_crab 69e9cb3f22 Tweaks to the Rarity Bucket effect on Gapple item 2025-04-05 12:31:33 -07:00
plastered_crab 4eb268c4af More tweaks to the rarity bucket effect 2025-04-05 12:23:02 -07:00
plastered_crab 909b5b7f7f Alter Rarity Bucket Effects and block merging of rarity bucket effects 2025-04-05 12:01:30 -07:00
plastered_crab e2c28ab5a0 Merge branch 'refs/heads/we_are_cooking_now' into we_are_cooking_now(Seasoning-Bait-Testing)
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/spawning/influence/SpawnBaitInfluence.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/tooltips/FishingBaitTooltipGenerator.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/item/crafting/BaitSeasoningProcessor.kt
2025-04-05 11:09:08 -07:00
plastered_crab 890d0a2099 New Rarity Bucket bait effect can cooked into Lures/Bait + tooltips 2025-04-05 01:58:13 -07:00
Gertimoshka 3033adcc2f IT MOVES 2025-04-05 11:55:07 +03:00
Landon Wills 603f99e5f3 Refactor composite behaviours 2025-04-05 04:24:19 -04:00
plastered_crab 74075e6be9 Merge remote-tracking branch 'origin/we_are_cooking_now(Seasoning-Bait-Testing)' into we_are_cooking_now(Seasoning-Bait-Testing)
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/spawning/spawner/TickingSpawner.kt
2025-04-05 00:45:17 -07:00
plastered_crab b8ae6aa889 Ground work for testing a new bait type that can affect rarity of spawn buckets 2025-04-05 00:43:23 -07:00
Landon Wills 1b53a127af Add lapras assets 2025-04-05 01:39:02 -04:00
plastered_crab a499e8593a Cooking now combines similar bait effects, letting you make some effects more powerful 2025-04-04 22:10:42 -07:00
Gertimoshka 252634bfde Setup the code that will handle the camera data and apply it 2025-04-05 08:04:24 +03:00
Josh 9679929694 Merge branch 'main' into 'item-with-components-swap'
# Conflicts:
#   common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
2025-04-05 02:01:27 +00:00
Landon fd6fb5db47 Merge branch 'riding-friction-change' into 'main'
Decouple minecraft friction logic for better feeling controllers. Limit speed...

See merge request cable-mc/cobblemon!1581
2025-04-05 00:21:27 +00:00
Jackson BowesandLandon a80ada8590 Decouple minecraft friction logic for better feeling controllers. Limit speed... 2025-04-05 00:21:27 +00:00
FrankTheFarmer 3f6faf7796 Merge branch 'main' into implement_pokemon 2025-04-05 09:24:40 +10:00
Plastered_Crab 08633c223e Example code for combining similar bait effects. Needs review if we want to do this. 2025-04-04 15:50:56 -07:00
Landon c4a4b9cb86 Merge branch 'multiplayer-riding' into 'main'
Multiplayer support for riding

See merge request cable-mc/cobblemon!1578
2025-04-04 21:15:55 +00:00
Josh 5af96e75eb Fixed message when swapping items.
Used `displayName` rather than `hoverName` for more dynamic text in message.
2025-04-04 13:35:09 -04:00
Sterrezo d5efdeee68 More adjustments to the cry checker script 2025-04-04 19:06:22 +02:00
Josh 023a01befd Can now swap pokemon's held items if the components are different. 2025-04-04 13:03:49 -04:00
Polymeta 4912a89e6e pokemon are allowed to turn their heads when they are not ridden
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-04 13:12:16 +01:00
Polymeta f2e10d1b01 Merge branch 'refs/heads/main' into multiplayer-riding
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/entity/pokemon/PokemonEntity.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/net/messages/client/spawn/SpawnPokemonPacket.kt
2025-04-04 12:54:10 +01:00
Hiroku 25eb197491 Merge branch 'ribs' into 'main'
🎀

See merge request cable-mc/cobblemon!1566
2025-04-04 10:13:58 +00:00
TestandHiroku 8de233b572 🎀 2025-04-04 10:13:58 +00:00
Landon Wills 83972ca9e6 Hook up a couple more pokemon for bird controller 2025-04-04 03:50:34 -04:00
Landon Wills 35e2190cae Reset orientation properly on landing 2025-04-04 02:33:23 -04:00
Landon Wills b966cd2db0 Fix issue with orientation tracking for rendering 2025-04-04 02:06:06 -04:00
queao 57f446260c just gonna drop these in here (added remodels for eevee and all eeveelutions) 2025-04-04 15:53:56 +10:00
Landon Wills 3e492541cc Fix issue with registry sync on riding properties 2025-04-04 01:40:27 -04:00
JazzMcNade cc2022ed59 Merge branch 'main' into SaferSendouts 2025-04-03 20:30:24 -05:00
Josh 298fdf45d5 Adjusted default position and scale values for wearables. Any additional transformations for a specific pokemon should be done in its posers. 2025-04-03 20:47:09 -04:00
Polymeta 4e9541d7f5 licenses
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-03 23:24:11 +01:00
Josh 1dab5b8c7c Added debug models to help with aligning wearable items on pokemon. 2025-04-03 17:03:26 -04:00
Landon Wills 2875e9efa9 Temporary fix to crashing issue due to pokemon sticking around when they shouldnt be 2025-04-03 16:27:44 -04:00
Landon Wills 2b42fff66b Fix issue with players sometimes launching at odd angles when riding 2025-04-03 16:26:54 -04:00
Landon Wills 643a33a643 Prevent crouching moving the player when riding pokemon 2025-04-03 16:26:34 -04:00
Landon Wills e348c48eff Fix reversed third person camera 2025-04-03 14:25:03 -04:00
Landon Wills 473f58cab9 No more random render flickers yippee 2025-04-03 13:49:18 -04:00
Kenji_64 d4cf44f8f0 Removed the old Three Segment Aspect 2025-04-03 18:54:29 +02:00
Kenji_64 a074ebbcce It has been du-dune: Implemented Dunsparce + Dudunsparce (2 & 3 Segment Form) 2025-04-03 18:54:00 +02:00
Landon Wills 987b8619a3 Specify side for riding state management, add multiplayer wing flap for charizard 2025-04-03 05:11:33 -04:00
Landon Wills 87632941e8 Fix issue with player not rotating on mount 2025-04-03 02:25:11 -04:00
queao 6578ed55e3 whoopsies 2025-04-03 16:12:39 +10:00
Landon Wills 041acab7ca Optimize change detection on riding sync 2025-04-03 02:06:23 -04:00
Landon Wills b3de7d1c1a Synchronize riding state to clients 2025-04-03 01:25:30 -04:00
Landon Wills afcb2dd77c Use render orientation instead of raw orientation for local players 2025-04-03 00:12:36 -04:00
Landon Wills a7bd6d2bf4 Update Garchomp, change translation in mounted player rendering 2025-04-02 23:54:22 -04:00
Landon Wills b096cb60a3 Use more precise orientation for posable model if player is local 2025-04-02 23:16:34 -04:00
Tyzillion f567ceadd8 Implemented Cosmetics for Gurdurr, Conkeldurr, Squirtle Line, Sneasler, Sandle line, Treecko line, Braixen, Delphox, and Dragonite.
Removed Shulker aspect and replaced it with cosmetic_item-shulker_shell.
Shulker shell Forretress is now a cosmetic rather than a special evo.
2025-04-02 18:03:11 -04:00
FrankTheFarmer 5de92f78c6 Changelog 👨‍🌾🔫🐲 2025-04-02 22:50:23 +10:00
FrankTheFarmer a2402f78e7 Added Sandaconda 🐍🐍🐍 2025-04-02 22:47:37 +10:00
FrankTheFarmer 1ad6d63137 Added Silicobra 🪱 2025-04-02 22:45:54 +10:00
FrankTheFarmer 39d417c651 Added Bronzong 👁🔔👁 2025-04-02 22:44:14 +10:00
FrankTheFarmer ce1bf9f4f2 Added Bronzor 🔷 2025-04-02 22:43:41 +10:00
FrankTheFarmer a6136906f8 Added Musharna 💤🐖 2025-04-02 22:42:44 +10:00
FrankTheFarmer 37a99b528e Added Munna 🐖 2025-04-02 22:40:46 +10:00
FrankTheFarmer 048b237302 Added Zebstrika ⚡🦓⚡ 2025-04-02 22:38:17 +10:00
FrankTheFarmer 131773f9c8 Added Blitzle ⚡🦓 2025-04-02 22:37:56 +10:00
FrankTheFarmer 22e55b7e77 Added Arboliva 🌵 2025-04-02 22:36:29 +10:00
FrankTheFarmer 6c288f9cc8 Added Dolliv 🫒🦵 2025-04-02 22:31:52 +10:00
FrankTheFarmer b5e86a9460 Added Smoliv 🫒 2025-04-02 22:30:53 +10:00
FrankTheFarmer f199e7c1c0 Added Froslass ✨👩‍🦳❄ 2025-04-02 22:29:05 +10:00
FrankTheFarmer 4161d96707 Added Glalie ⚪ 2025-04-02 22:27:35 +10:00
FrankTheFarmer 59927dd701 Added Snorunt 📐 2025-04-02 22:26:58 +10:00
FrankTheFarmer 220d8ddc0f Added Grumpig 🐖🔮 2025-04-02 22:25:53 +10:00
FrankTheFarmer 0dd143e67e Added Spoink 🔮🐷 2025-04-02 22:24:57 +10:00
JPAK 7f1c0c3d4c Fixed culling. It really was that easy xd 2025-04-02 07:23:26 -05:00
FrankTheFarmer d83eb62821 Added Garbodor 🤮 2025-04-02 22:22:52 +10:00
FrankTheFarmer a716fda023 Added Trubbish 🤢 2025-04-02 22:22:25 +10:00
FrankTheFarmer d14aad787c Added Orthworm 🪱♥❓🥺 2025-04-02 22:19:01 +10:00
FrankTheFarmer 2eb7b60dd1 Added Drampa 👴🐉🔥🏠 2025-04-02 22:11:41 +10:00
TeggyandWeblate bc4699e354 Translated using Weblate (Spanish)
Currently translated at 95.1% (6683 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-04-02 11:09:46 +00:00
Landon Wills a4f0bf9d2f Fix issue with the world ocasionally playing hide and seek when rolling in first person 2025-04-02 01:57:40 -04:00
JacksonB f46c748e9f Add forgotten bird logic 2025-04-02 00:07:37 -05:00
Landon Wills 065479c58c Make rendering smooth for rolling players & entities 2025-04-02 00:16:05 -04:00
JacksonB eee3d46a2d Keep a render orientation that interpolates behind the last received orientation and damp the slerp by a static amount frame to frame. 2025-04-01 21:07:21 -05:00
Plastered_Crab c50b149e83 Add some notes to TickingSpawner to where we might want to alter rarity buckets if we added an effect for that 2025-04-01 16:19:53 -07:00
FrankTheFarmer d79ffc631b Merge branch 'main' into implement_pokemon 2025-04-02 08:41:27 +10:00
Plastered_Crab 63252f4d35 Swap placeholder sugar Seasoning Item with Golden Apple 2025-04-01 15:10:42 -07:00
Plastered_Crab 1c024f881e Swap placeholder sugar Seasoning Item with Golden Apple 2025-04-01 14:49:57 -07:00
Plastered_Crab 93f0337399 Got Seasoning-only Bait effects working 2025-04-01 14:44:33 -07:00
Hiroku d7b43fcbfc Merge branch 'spicy-molang' into 'main'
Added `pokemon` as an available Molang function for the `battleActor` functions

See merge request cable-mc/cobblemon!1577
2025-04-01 20:21:18 +00:00
Plastered_Crab 7e8fb07f55 Clean up doo doo commented out code 2025-04-01 12:13:53 -07:00
Plastered_Crab 7a8856c34c Fix Poke Bait fishing bait losing their Component data upon getting a bite 2025-04-01 12:12:19 -07:00
Landon Wills c82e011f73 Pull together riding branches, trying to fix render stuttering 2025-04-01 13:18:50 -04:00
Spicy bf1b996962 Added pokemon as an available Molang function for the battleActor functions 2025-04-01 09:12:16 -05:00
Guilherme Pereira 63d516953a fix cakes not loading additional data upon reentering the world 2025-04-01 10:33:14 -03:00
Landon Wills fc46cdcda0 Merge remote-tracking branch 'refs/remotes/origin/camera-changes' into test
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/client/CameraMixin.java
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/player/MountedPlayerRenderer.kt
2025-04-01 09:24:11 -04:00
Landon Wills 4e7b029afb Merge remote-tracking branch 'refs/remotes/origin/multiplayer-roll-sync' into test 2025-04-01 09:22:19 -04:00
Landon Wills 5430f02770 Add much more context to pose provider, optimize velocity tracking, add sync to server 2025-04-01 09:20:51 -04:00
Gertimoshka 0f38c6b00e Setup Data Handling and Syncing for Stadium Cameras 2025-04-01 15:27:22 +03:00
Landon Wills 6a51abe3ee Axe more of the old system, fix some issues with deserialization 2025-04-01 06:48:21 -04:00
Landon Wills 008652b442 Forgot a change 2025-04-01 06:32:11 -04:00
Landon Wills c1e088eb33 Hook new riding infrastructure up to serialization, axe the old controllers 2025-04-01 06:31:33 -04:00
Landon Wills 1669a2f428 Make all riding behaviour settings encodable 2025-04-01 05:44:18 -04:00
Landon Wills 2ba63f4641 Redirect PokemonEntity and mixins to new riding system 2025-04-01 05:29:17 -04:00
plastered_crab 07faf6600f Just some testing with some Seasoning-Only bait effects items (items that can't go on rod but can cook for bait effects) 2025-04-01 01:56:01 -07:00
Landon Wills 41b9e9001d Refactor riding system 2025-04-01 03:48:45 -04:00
JacksonB 679920b786 Rolling is now displayed on remote clients while riding. 2025-03-31 23:15:44 -05:00
Landon Wills f058d6e635 More work on controllers. Poses borked again 2025-03-31 20:46:11 -04:00
Plastered_Crab 08e79d71bf Added in code to trigger bites on a Lure Cake if it's effects are used to spawn something 2025-03-31 17:11:14 -07:00
Landon Wills f9377b7489 Some progress on data transfer for ride controllers (currently not functional) 2025-03-31 17:55:59 -04:00
TeggyandWeblate 9270119675 Translated using Weblate (Spanish)
Currently translated at 95.1% (6682 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-31 15:23:52 +00:00
Polymeta e59b5094ad correctly warp world as holder inside spawnfilters
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-03-31 11:50:54 +01:00
JacksonB c8ec4e6f1f commit to not lose anything because paranoid the computer explodes 2025-03-31 00:20:21 -05:00
Josh a2fef9f1be Moved WearableItemModel functions out of HeldItemRenderer.kt 2025-03-30 21:24:13 -04:00
Josh 3d4df2c098 Fixed item rendering not falling back to the item locator if other locators are not present. 2025-03-30 21:11:05 -04:00
Josh 7557cab03d Fixed item visibility button not showing the right icon when opening summary or switching pokemon. 2025-03-30 20:55:28 -04:00
TeggyandWeblate 0058906022 Translated using Weblate (Spanish)
Currently translated at 95.1% (6678 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-31 00:16:23 +00:00
Josh f1018b1da9 Simplified HeldItemRenderer to use only one render function that renders an Item on a PosableModel. And fixed the item lighting in the summary menu. 2025-03-30 20:03:07 -04:00
FrankTheFarmer 7cd1870f23 Merge branch 'main' into implement_pokemon 2025-03-31 07:42:53 +10:00
Landon Wills cbcc6abe40 Fix issue with poses not changing properly in multiplayer riding 2025-03-30 17:04:36 -04:00
Josh 5af4e3bddb Added placeholder models for wearable items and logic to register the models. 2025-03-30 02:03:44 -04:00
plastered_crab 6c836663f4 Cakes now get bites taken out of them when their influence gets used for spawning 2025-03-29 18:24:03 -07:00
Landon Wills 64c9d47b0f Fix multiplayer issue where pokemon other player's were riding would not rotate 2025-03-29 21:10:42 -04:00
Josh 1f519cae50 Fixed rotation of items rending in PokemonOnShoulderRenderer and ModelWidget 2025-03-29 20:01:04 -04:00
Landon Wills c0d2803f61 Fix multiplayer issues with clients not recognizing ridden pokemon on login 2025-03-29 15:55:34 -04:00
Gertimoshka f711f748a8 A lot of Stadium Camera Data for the Data Gods before implementation 2025-03-29 10:27:34 +02:00
Landon Wills e249d5238f Fix issue with orientation not getting reset on ride dismount 2025-03-29 02:34:00 -04:00
Landon Wills e32e505e95 Fix issue with sprint not getting recognized on RunUpToJetFlightCompositeController 2025-03-29 02:14:40 -04:00
Landon 7642a84108 Merge branch 'ride-controller-server-crash-fix' into 'multiplayer-riding'
Ride controller server crash fix

See merge request cable-mc/cobblemon!1575
2025-03-29 04:58:25 +00:00
JacksonB b6e20d69cc fix to crouch but sprint during riding is still broken 2025-03-28 15:18:10 -05:00
JacksonB 9d04e20a30 Remove client only code causing server crash and replace with proper code. 2025-03-28 14:51:33 -05:00
Landon Wills d2624813f7 Merge branch 'refs/heads/bug-fixes' into multiplayer-riding 2025-03-28 13:36:22 -04:00
Landon Wills a2789e70ed Use readString in readExpression to be a bit more clear on it's function 2025-03-28 13:35:05 -04:00
Guilherme Pereira eeae26492e Merge branch 'we_are_cooking_now' into candle-cake 2025-03-28 07:25:47 -03:00
Guilherme Pereira 9e67a82816 Merge branch 'we_are_cooking_now' into cooking-pot-jei 2025-03-28 06:56:21 -03:00
Guilherme Pereira c09295231c remove dead code and print statements 2025-03-28 06:19:03 -03:00
Guilherme Pereira 6c7d61c9f2 prevent cooking pot cooked items stacking above their stack limit 2025-03-28 06:12:55 -03:00
Guilherme Pereira 01f8a5c6d7 fix some cooking pot crashes 2025-03-28 06:12:15 -03:00
Landon Wills f6f607904e Merge branch 'refs/heads/bug-fixes' into multiplayer-riding 2025-03-28 01:53:19 -04:00
Landon Wills 22ea0296c0 Fix issues with riding controller packet decoding 2025-03-28 01:52:03 -04:00
Landon Wills 24ae2f5324 Fix issue with registering species on servers 2025-03-28 01:51:38 -04:00
Landon Wills 9284497cec Refactor Rollable interface, fix issue with mixins crossing sides, causing server to fail to load 2025-03-28 00:21:26 -04:00
Landon Wills 36cb12952a Move more functions out of Rollable to mouse handling 2025-03-27 21:55:29 -04:00
Landon Wills 2700dc7f39 Refactor function to get angular velocity out of Rollable 2025-03-27 21:23:12 -04:00
KyoandWeblate 14d2a76211 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/vi/
2025-03-27 12:41:50 +00:00
Watuneni iteiteandWeblate 7669000962 Translated using Weblate (Japanese)
Currently translated at 76.3% (5358 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-03-27 12:41:46 +00:00
Sterrezo 716d1b848e Fixed and renamed cries for Galarian Ponyta, Galarian Rapidash and Alolan Raichu 2025-03-26 16:19:26 +01:00
Sterrezo 4878fc517d Updated and cleaned up the cry checker script 2025-03-26 16:00:57 +01:00
Sterrezo 4d9d543110 STOP BREAKING THE SPREADSHEET
fixed script
2025-03-26 14:26:15 +01:00
Polymeta c9d27d46b6 license header
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-03-26 11:39:18 +00:00
amo f11f88c71a npc hide logic 2025-03-26 02:07:10 +00:00
FrankTheFarmer 718a9b922b Merge branch 'main' into implement_pokemon 2025-03-26 08:28:53 +10:00
Polymeta b68756378c Merge branch 'Box-count-command' into 'main'
Added /boxcount

See merge request cable-mc/cobblemon!1565
2025-03-25 17:01:22 +00:00
Polymeta 1ff1880951 Merge branch 'main' into 'Box-count-command'
# Conflicts:
#   common/src/main/kotlin/com/cobblemon/mod/common/api/permission/CobblemonPermissions.kt
2025-03-25 16:59:25 +00:00
Polymeta fea2d32de8 Merge branch 'spectate-command' into 'main'
Added a spectate battle command.

See merge request cable-mc/cobblemon!1264
2025-03-25 16:56:49 +00:00
Conan e3e6d4452c # 2025-03-25 14:12:49 +01:00
Conan f687e8e658 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into spectate-command
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonCommands.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/permission/CobblemonPermissions.kt
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2025-03-25 14:07:49 +01:00
GenotypeXD-Dev e2a152aeb3 Model Fixes didnt push 2025-03-24 19:34:11 -06:00
GenotypeXD-Dev 3e21226b27 Implemented Hawlucha + fixed z fighting on Noibat and scaled down to 0.6 2025-03-24 19:30:16 -06:00
queao c46c5b806c IT'S TIIIIIIIIIIME (implemented noibat and noivern - implementation work done by genotype) 2025-03-24 18:49:07 +10:00
FrankTheFarmer 3c37d93046 Merge branch 'main' into implement_pokemon 2025-03-24 16:40:53 +10:00
Hiroku 2413981f6f Merge branch 'charizardmarketing' into 'main'
Updated Charizard with the latest model and animations to be used for marketing on the main branch.

See merge request cable-mc/cobblemon!1572
2025-03-24 01:23:40 +00:00
Tyzillion 4ac244003a -6+ ?????? 2025-03-23 21:22:47 -04:00
Tyzillion 9ac92a084f Updated Charizard with new locators. 2025-03-23 21:18:31 -04:00
Apion aacbcb1f28 Merge branch 'jackowes/concrete_bird' into 'main'
Overhaul of bird and fix of jet velocity bug

See merge request cable-mc/cobblemon!1563
2025-03-23 23:37:47 +00:00
Jackson BowesandApion 39ff7e418c Overhaul of bird and fix of jet velocity bug 2025-03-23 23:37:47 +00:00
Hiroku 58498a091d Merge branch 'josh/npc-item-rendering' into 'main'
Molang for rendering items during animations.

See merge request cable-mc/cobblemon!1570
2025-03-23 23:12:06 +00:00
Hiroku a806f77aff Merge branch 'entity-scale' into 'main'
Pokemon hitboxes scale with attribute generic.scale

Closes #1410

See merge request cable-mc/cobblemon!1529
2025-03-23 22:05:38 +00:00
JordanandHiroku 60ae9e3a55 Pokemon hitboxes scale with attribute generic.scale 2025-03-23 22:05:37 +00:00
Hiroku 03ddc35d36 Merge branch 'Fix-pokemon-loadFrom' into 'main'
Fixed Pokemon.loadFrom[JSON/NBT]

Closes #1507

See merge request cable-mc/cobblemon!1571
2025-03-23 03:22:17 +00:00
ShiroFenixandHiroku 1b8e9b9b36 Fixed Pokemon.loadFrom[JSON/NBT] 2025-03-23 03:22:17 +00:00
Paul e52ac956f0 Added q.entity.is_holding_item for pokemon posers to use 2025-03-23 12:40:59 +10:00
Gertimoshka c2fb914e08 Working on Networking for Stadium 2025-03-22 23:33:35 +02:00
Josh 4bfe147730 Merge branch 'main' into josh/npc-item-rendering 2025-03-22 12:41:31 -04:00
TeggyandWeblate 8912911800 Translated using Weblate (Spanish)
Currently translated at 94.3% (6621 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-22 01:16:22 +00:00
Hiroku 493664bef2 Merge branch 'mealam/pokeballlocation' into 'main'
fix: Adjust `NPCEntity` pokeball throw positioning to account for `baseScale`

See merge request cable-mc/cobblemon!1568
2025-03-21 23:50:33 +00:00
AramandHiroku 981e3e5efc fix: Adjust NPCEntity pokeball throw positioning to account for baseScale 2025-03-21 23:50:33 +00:00
Gertimoshka 7947e19337 Fixed Errors with Mergin Main into branch 2025-03-21 21:56:49 +02:00
Gertimoshka 5bde172731 Detached the Camera from the player 2025-03-21 21:43:59 +02:00
Josh 963614f5fa Updated CHANGELOG.md 2025-03-21 11:51:18 -04:00
Josh 7fdb70e3c3 Updated trainer npcs for testing 2025-03-21 11:20:24 -04:00
Gertimoshka 496e04a779 Merging Main into stadium-block-gert 2025-03-21 14:50:22 +02:00
Gertimoshka ff4192b43c Preparing to handle starting Stadium Battles 2025-03-21 14:47:27 +02:00
Gertimoshka 415591a443 Stadium Block now can innitate a 1v1 battle 2025-03-21 14:47:26 +02:00
Gertimoshka efb1eaf3e1 Setup to prepare to develop Stadium Block Functionality 2025-03-21 14:47:26 +02:00
Plastered_CrabandGertimoshka 7ebd2bdb94 Render Rotom drone camera to start orbiting around + try to avoid collisions using raycast point cloud 2025-03-21 14:47:24 +02:00
FlarkinaterandGertimoshka e07579bf0a Fix drone animation 2025-03-21 14:47:23 +02:00
FlarkinaterandGertimoshka 0695117549 Revert debug change 2025-03-21 14:47:22 +02:00
FlarkinaterandGertimoshka d6cd04e2a4 Attempt to debug the animation issue 2025-03-21 14:47:21 +02:00
FlarkinaterandGertimoshka 8240cd10e2 Attempt to make the drone animated (WIP) 2025-03-21 14:47:19 +02:00
FlarkinaterandGertimoshka 2a1e749787 Refactor - move most drone assets into bedrock/drone 2025-03-21 14:47:18 +02:00
FlarkinaterandGertimoshka 6d9daf692d Fix upside-down drone 2025-03-21 14:47:17 +02:00
FlarkinaterandGertimoshka 1f7df20e77 Render the drone in-game 2025-03-21 14:47:16 +02:00
FlarkinaterandGertimoshka 02a4b91778 Add Rotom drone model/texture/animation placeholders 2025-03-21 14:47:15 +02:00
FlarkinaterandGertimoshka a37da4d4f2 Remove placeholder model, we'll just use some "dev art" for now 2025-03-21 14:47:14 +02:00
FlarkinaterandGertimoshka 66817b5e9b Update deprecated methods, imports, and formatting 2025-03-21 14:47:10 +02:00
FlarkinaterandGertimoshka fd54e3a7e0 Rebase old stadium camera test branch 2025-03-21 14:47:08 +02:00
Gertimoshka 79f2b67bf9 Preparing to send client reqired info about Stadium Battle 2025-03-21 14:44:34 +02:00
Paul 660be08eea Overhauled cooking and fishing baits, added ride boosts, added aprijuice stat handling, probably added lots of bugs 2025-03-21 14:28:22 +10:00
阿鱼andWeblate 62ecfaf54a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-20 23:47:02 +00:00
TeggyandWeblate 6684177236 Translated using Weblate (Spanish)
Currently translated at 94.2% (6615 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-20 23:47:00 +00:00
Watuneni iteiteandWeblate deca5cf55b Translated using Weblate (Japanese)
Currently translated at 76.1% (5350 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-03-20 23:46:59 +00:00
Josh 37e8f0eab6 multiple items can render on a model per locator and the render_item() molang function now supports items with components 2025-03-20 16:14:16 -04:00
Gertimoshka 2352dae6e0 Preparing to handle starting Stadium Battles 2025-03-20 18:35:46 +02:00
Gertimoshka 9ec100f9ea Stadium Block now can innitate a 1v1 battle 2025-03-20 12:36:12 +02:00
ShiroFenixlm a6d17659f8 Added removeListOfBoxes to PCStore 2025-03-19 23:31:43 -04:00
Josh 05edafa5c4 NPC Trainers send out/return animation are able to show the correct ball. 2025-03-19 22:35:00 -04:00
ShiroFenixlm 997a6de23b Remove and Set now only delete empty boxes unless forced 2025-03-19 21:52:08 -04:00
Hiroku c15350e647 Merge branch 'mealam/1499' into 'main'
fix: Adjust `NPCEntity` beam positioning to account for `baseScale`

Closes #1499

See merge request cable-mc/cobblemon!1567
2025-03-20 00:36:12 +00:00
AramandHiroku f9e5784b10 fix: Adjust NPCEntity beam positioning to account for baseScale 2025-03-20 00:36:12 +00:00
Josh cea600617e Added render_item() molang function for PosableState. Allows rendering dummy items for animations. 2025-03-19 18:47:11 -04:00
ShiroFenixlm c948b6d885 Added force remove button 2025-03-18 19:40:53 -04:00
Paul 769a9ac845 Merge remote-tracking branch 'origin/we_are_cooking_now' into we_are_cooking_now 2025-03-18 15:11:46 +10:00
FrankTheFarmer 7b2790de50 Changelog setup for 1.7 implementation stuff 2025-03-18 09:20:30 +10:00
FrankTheFarmer 7f2bb84c85 Merge branch 'main' into implement_pokemon 2025-03-18 09:12:06 +10:00
阿鱼andWeblate 0f75797759 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-17 21:03:49 +00:00
Gertimoshka 17c524ab9e Setup to prepare to develop Stadium Block Functionality 2025-03-17 22:30:28 +02:00
ShiroFenixlm 5508980384 Final Cleanup, i hope 2025-03-17 15:24:02 -04:00
ShiroFenixlm e39dee01e5 Cleanup 2025-03-17 15:16:06 -04:00
ShiroFenixlm a81412e176 Merge remote-tracking branch 'origin/Box-count-command' into Box-count-command
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/command/ChangePCBoxesCommand.kt
2025-03-17 15:15:01 -04:00
ShiroFenixlm 09f9dd91aa Fixed some issues and added error handling when removing too many boxes 2025-03-17 15:08:07 -04:00
ShiroFenixlm 2efc3c72ac Fixed some issues and added error handling when removing too many boxes 2025-03-17 15:02:57 -04:00
ShiroFenix a92fb03093 Updated command logic to improve legibility 2025-03-17 12:56:15 -04:00
ShiroFenix ad5847983f Updated command logic to improve legibility 2025-03-17 12:55:59 -04:00
WhiteFenix19 bb25300513 Updated command logic to improve legibility 2025-03-17 12:32:46 -04:00
WhiteFenix19 de33804eb4 Updated command logic to improve legibility 2025-03-17 12:19:47 -04:00
WhiteFenix19 de042f71dd Updated command logic to improve legibility 2025-03-17 12:18:28 -04:00
WhiteFenix19 5a1e85bbf4 Added /boxcount command 2025-03-17 00:47:00 -04:00
ShiroFenix 3489e0df74 Revert "Added /boxcount"
This reverts commit afe8eec343
2025-03-17 03:59:02 +00:00
ShiroFenix afe8eec343 Added /boxcount 2025-03-17 03:43:32 +00:00
Hiroku 2f4b861f98 Merge branch 'implement_pokemon' into 'main'
Dragonite and Gyarados models with locators for testing on main

See merge request cable-mc/cobblemon!1564
2025-03-16 00:20:05 +00:00
Frank The FarmerandHiroku a7022268c1 Dragonite and Gyarados models with locators for testing on main 2025-03-16 00:20:05 +00:00
FrankTheFarmer 331e1371d4 Illegal imports of Dragonite and Gyarados models with locators for testing 2025-03-16 09:42:56 +10:00
FrankTheFarmer bdd57ba1a4 Merge branch 'main' into implement_pokemon 2025-03-16 08:53:37 +10:00
Alexis SalgueiroandWeblate c194aefce5 Translated using Weblate (French)
Currently translated at 91.5% (6425 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-15 14:17:58 +00:00
Aiser(CCHusky)andWeblate f4798c8783 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-15 14:17:57 +00:00
chronicenandWeblate 2178a5f10e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-15 14:17:57 +00:00
Gertimoshka f5e3945cf6 Spawning Influence Prospector can now have 2 methods of providing data 2025-03-15 14:00:03 +02:00
BuildTools bb121cbee7 Made Lure Cakes use Poi System to allow better range of effect 2025-03-15 12:40:39 +02:00
Hiroku 3082600e11 Merge branch 'meowscarada-fix' into 'main'
Fixed Meowscarada's resolver having the wrong name

See merge request cable-mc/cobblemon!1562
2025-03-15 08:48:41 +00:00
gruxor a348cfd338 Fixed Meowscarada's resolver having the wrong name 2025-03-15 04:19:38 -04:00
Paul cee9adc782 Merge remote-tracking branch 'origin/main' into we_are_cooking_now
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/particle/ParticleStorm.kt
2025-03-15 13:37:59 +10:00
Paul 35bfc7bf6c Merge remote-tracking branch 'origin/main' 2025-03-15 13:22:28 +10:00
Paul ae87c3dd84 Fixed downward correction of spawning, closes #1498 2025-03-15 13:22:04 +10:00
Hiroku d944803571 Merge branch 'jackowes/concrete_jet/01' into 'main'
Full Base Jet Controller

See merge request cable-mc/cobblemon!1560
2025-03-15 01:14:00 +00:00
Jackson BowesandHiroku 2c3b474c01 Full Base Jet Controller 2025-03-15 01:13:59 +00:00
TeggyandWeblate bc145a56d5 Translated using Weblate (Spanish)
Currently translated at 93.6% (6575 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-14 17:00:49 +00:00
Paul c2538560e1 Added check for activate_ action effects, implemented protect blocking effect 2025-03-14 10:23:50 +10:00
Paul d10c058c74 Added properties map to posers and look for item display contexts from there as a first try for item rendering 2025-03-14 09:55:31 +10:00
Paul d1b6d95d57 Fixed interpolation being applied to full model transformed parts 2025-03-14 09:17:34 +10:00
Paul 977387a184 Merge remote-tracking branch 'origin/main' 2025-03-13 20:26:35 +10:00
Paul 69bbc09d6a Updated fabric version, fixed our is_overworld including end biomes 2025-03-13 20:26:23 +10:00
Hiroku 46b04ad462 Merge branch 'async-player-data-saving' into 'main'
Moved player data saving to do the heavier work on a worker thread,...

See merge request cable-mc/cobblemon!1559
2025-03-13 05:03:28 +00:00
FrankTheFarmer 670e7e9ca1 Merge branch 'main' into implement_pokemon 2025-03-13 13:55:26 +10:00
Paul a1b6fd3d1a Fixed silent pokemon still playing shiny sounds and particles, closes #1316 2025-03-13 11:19:10 +10:00
Paul fb9ed28b74 Moved player data saving to do the heavier work on a worker thread, potentially fixing storages not saving in race conditions 2025-03-13 11:01:51 +10:00
Paul 4bfc2a97dd Fixed base entity functions not being added to pokemon structs, messing with a lot of things 2025-03-13 09:47:12 +10:00
Nick a2cf66fbc1 Merge branch 'seat-generator' into 'main'
Seat generator

See merge request cable-mc/cobblemon!1558
2025-03-12 16:10:03 -07:00
HirokuandNick 5bda81a5c4 Seat generator 2025-03-12 16:10:03 -07:00
Nico MerenqandWeblate 476ef3bb2f Translated using Weblate (Russian)
Currently translated at 73.9% (5189 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-12 13:19:09 +00:00
Test 32ccd15121 biome test bg 2025-03-12 03:56:25 +00:00
Hiroku a51cda998b Merge branch 'Adainish-main-patch-50806' into 'main'
Fixes a deserialisation issue due to IVS/EVS being required

See merge request cable-mc/cobblemon!1557
2025-03-12 02:25:20 +00:00
Adenydd Stuut || Winglet 9dc14eff7c Edit PokemonProperties.kt 2025-03-12 01:48:15 +00:00
Hiroku 4b1690c62e Merge branch 'observe-less' into 'main'
Removed heaps of observables from Pokemon because they weren't needed and it added heaps to the RAM

See merge request cable-mc/cobblemon!1555
2025-03-11 22:57:49 +00:00
Hiroku d02251b67d Edit CHANGELOG.md 2025-03-11 11:57:07 +00:00
Hiroku 54c8cbfbe8 Merge branch 'unlockable-wallpapers' into 'main'
Added unlockable PC box wallpapers

See merge request cable-mc/cobblemon!1525
2025-03-11 09:49:11 +00:00
Paul 2d8ce63dcd Changelog 2025-03-11 15:53:02 +10:00
Paul 1a92af2cd6 Removed heaps of observables from Pokemon because they weren't needed and it added heaps to the RAM 2025-03-11 15:51:45 +10:00
Paul 7e088bdeec @JvmStatic on all the permissions so the interop isn't whack 2025-03-11 13:30:01 +10:00
Paul 6142049d51 Added uuid function to pokemonStore molang 2025-03-11 12:57:38 +10:00
Alexis SalgueiroandWeblate 460050289b Translated using Weblate (French)
Currently translated at 90.7% (6373 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-10 15:04:25 +00:00
Hiroku d031f339c6 Merge branch 'spawning-improvements' into 'main'
Spawning performance improvements

See merge request cable-mc/cobblemon!1553
2025-03-10 11:33:39 +00:00
Paul 3ddbc9b313 Unmark wallpapers as new once you try them 2025-03-10 20:59:42 +10:00
Paul dd2c1ddbc6 Regenerate the validBiomes lists when data is reloaded (yknow, for when that works) 2025-03-10 20:34:31 +10:00
Paul badd7e8c2e Merge remote-tracking branch 'origin/main' into spawning-improvements 2025-03-10 20:27:48 +10:00
Paul 0a2e9f6530 Removed some unused stuff 2025-03-10 17:37:17 +10:00
Nico MerenqandWeblate 01fd4dcc68 Translated using Weblate (Russian)
Currently translated at 73.8% (5182 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-09 18:06:58 +00:00
Nico MerenqandWeblate 0392eb3b7e Translated using Weblate (Russian)
Currently translated at 73.6% (5172 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-09 15:29:58 +00:00
Paul 038a21556e Merge remote-tracking branch 'origin/main' into we_are_cooking_now 2025-03-09 21:01:24 +10:00
阿鱼andWeblate 493f423a2f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-09 10:54:04 +00:00
阿鱼andWeblate cbcfa1bbfb Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (7021 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-09 10:45:17 +00:00
Nico MerenqandWeblate 17a3ff15db Translated using Weblate (Russian)
Currently translated at 73.6% (5171 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-09 10:30:06 +00:00
阿鱼andWeblate 9c14cccc98 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.9% (7017 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-09 10:30:05 +00:00
Paul d7c4380cc2 oop 2025-03-09 20:09:00 +10:00
Paul 57539775e0 A lot of bait and cake cleanup, implemented world sliced spawning influences and made the lure cake block apply them 2025-03-09 20:08:44 +10:00
Paul eb71a20a19 Merge remote-tracking branch 'origin/main' into we_are_cooking_now
# Conflicts:
#	common/src/main/resources/cobblemon-common.accesswidener
2025-03-09 17:56:20 +10:00
Paul 7fc26ab939 Fixed held items being given with "Air" as the name oops 2025-03-09 14:50:08 +10:00
Paul 37f430ddf7 Fixed issues with unseen wallpapers not communicating properly to the client 2025-03-09 14:42:29 +10:00
Hiroku f0a2182149 Merge branch 'riding-settings' into 'main'
Added riding config options and implemented the invert mouse options on current controllers.

See merge request cable-mc/cobblemon!1550
2025-03-09 04:14:47 +00:00
Paul 9605775f1e Merge remote-tracking branch 'origin/main' into spawning-improvements 2025-03-09 11:00:56 +10:00
Paul f251bc20c1 Fixed species feature lookups not targeting code features first because of a funnybug 2025-03-09 11:00:29 +10:00
Paul a02b3d74b8 Fixed species additions not being able to add implemented, closes #779 2025-03-09 10:58:18 +10:00
Paul 7f3a4c20b3 Added biome precalculation to the spawning system, improved RegistryLikeCondition performance 2025-03-09 10:39:10 +10:00
Weblate 850cfbe755 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-03-08 22:51:12 +00:00
TeggyandWeblate 28afa6a9e8 Translated using Weblate (Spanish)
Currently translated at 93.1% (6538 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-08 22:51:08 +00:00
阿鱼andWeblate 7a76d95ce7 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.7% (6936 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 22:51:07 +00:00
TeggyandWeblate 54707d0618 Translated using Weblate (Spanish)
Currently translated at 92.1% (6470 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-08 15:08:19 +00:00
Aiser(CCHusky)andWeblate 307c400e28 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.6% (6929 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 15:08:18 +00:00
阿鱼andWeblate 5c9b3ab25d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.6% (6929 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 15:08:18 +00:00
阿鱼andWeblate 532e991fb2 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.1% (6890 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 11:31:35 +00:00
Nico MerenqandWeblate b1bf817329 Translated using Weblate (Russian)
Currently translated at 73.6% (5171 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ru/
2025-03-08 11:31:34 +00:00
TeggyandWeblate c091f90487 Translated using Weblate (Spanish)
Currently translated at 91.7% (6445 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-08 08:23:13 +00:00
阿鱼andWeblate a49d4715ff Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 97.0% (6816 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-08 08:23:12 +00:00
Hiroku e76999c611 Merge branch 'Fix-NPCs-using-pokemon-outside-Pool' into 'main'
Fixing NPCs using pokemon outside of their Pool

Closes #1482

See merge request cable-mc/cobblemon!1552
2025-03-07 23:30:04 +00:00
WhiteFenix19 c2771bcb95 Fixed Formatting 2025-03-07 19:27:51 -04:00
WhiteFenix19 5b858b5982 Merge remote-tracking branch 'origin/Fix-NPCs-using-pokemon-outside-Pool' into Fix-NPCs-using-pokemon-outside-Pool 2025-03-07 17:09:29 -04:00
WhiteFenix19 7082220e29 Fixed NPCs using Pokémon outside of their pool when a Pokémon name had a typo. (Fixed indentations) 2025-03-07 17:08:52 -04:00
WhiteFenix19 1a87830a52 Fixed NPCs using Pokémon outside of their pool when a Pokémon name had a typo. 2025-03-07 17:02:54 -04:00
WhiteFenix19 9eff6dcced Fixed NPCs using Pokémon outside of their pool when a Pokémon name had a typo. 2025-03-07 15:05:48 -04:00
WhiteFenix19 52690c3aa6 Added check to avoid random Pokémon on Pool, added warning if species wrong or party empty 2025-03-07 13:59:40 -04:00
阿鱼andWeblate 652b15532e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.9% (6807 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-07 04:18:30 +00:00
TeggyandWeblate e4064897b0 Translated using Weblate (Spanish)
Currently translated at 91.5% (6430 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-03-07 04:18:29 +00:00
Paul 8f0780c5f6 I'm autistic 2025-03-07 12:34:59 +10:00
阿鱼andWeblate f9ca8222da Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.7% (6793 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-06 12:30:15 +00:00
FrankTheFarmer 3ae349aea5 Merge branch 'main' into implement_pokemon 2025-03-06 18:28:14 +10:00
JazzMcNade 91864b13d0 Moved GetSendOutPosition into ActiveBattlePokemon.kt 2025-03-06 01:45:58 -06:00
阿鱼andWeblate 67480a945f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.5% (6708 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-06 06:42:04 +00:00
Alexis SalgueiroandWeblate e6e811e6e6 Translated using Weblate (French)
Currently translated at 90.0% (6320 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-06 06:41:58 +00:00
Watuneni iteiteandWeblate 4635c531b9 Translated using Weblate (Japanese)
Currently translated at 73.7% (5178 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-03-06 06:41:56 +00:00
Test 465a7fbe73 update changelog, alt icons for descending sort 2025-03-05 17:47:42 -05:00
Watuneni iteiteandWeblate 3bdfac9a46 Translated using Weblate (Japanese)
Currently translated at 71.7% (5039 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-03-05 13:53:19 +00:00
chronicenandWeblate 2b7a71cb1c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 91.4% (6424 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-05 13:53:19 +00:00
阿鱼andWeblate d47a500a0e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 91.4% (6424 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-05 13:53:19 +00:00
Hiroku 6b5abfa319 Merge branch 'fix-interpolation' into 'main'
Fixed interpolation breaking with non emissive textures

See merge request cable-mc/cobblemon!1551
2025-03-05 11:31:37 +00:00
Paul 39197adebb Why'd I format that like that 2025-03-05 18:45:00 +10:00
BuildTools 4b1e192705 Fixed interpolation breaking with non emmisive textures 2025-03-05 10:32:54 +02:00
Test a3fa3d4b82 Merge branch 'unlockable-wallpapers' of https://gitlab.com/cable-mc/cobblemon into unlockable-wallpapers 2025-03-05 02:44:32 -05:00
Test c5ad7a0fb7 refactor pc updates 2025-03-05 02:44:11 -05:00
Paul d17f94c0d6 Reworked way pokemon are blocked from spawning on rails to not be as intensive 2025-03-05 14:27:02 +10:00
FrankTheFarmer 13650f98f9 Merge remote-tracking branch 'origin/implement_pokemon' into implement_pokemon 2025-03-05 14:23:08 +10:00
FrankTheFarmer d3379557fd 2 more Gen 5 monkeys jumping on the bed 2025-03-05 14:22:28 +10:00
FrankTheFarmer 143c2683fe Added placeholder animations to Pansage and Simisage 2025-03-05 14:21:54 +10:00
FrankTheFarmer 72d64d36e5 Changed panpour scale and hitbox size to match that of the other monkeys 2025-03-05 14:21:17 +10:00
Wi2tert c0b52c38e3 "implemented": Panpour、Simipour 💧🐒 2025-03-05 12:11:22 +08:00
JazzMcNade adc8e9921a Updated Changelog 2025-03-04 21:54:23 -06:00
JazzMcNade 5e5473acae Muted timing console logging 2025-03-04 21:50:28 -06:00
FrankTheFarmer 12a0ee309e Merge branch 'main' into implement_pokemon 2025-03-05 08:01:14 +10:00
阿鱼andWeblate 33e6dbb4c1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 87.4% (6143 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/zh_Hans/
2025-03-04 15:50:25 +00:00
RedGenesectNinja 824e37effd Implemented Pansage and Simisage 2025-03-03 23:12:27 -06:00
JazzMcNade 3509944f1a Comment, fixed indentation 2025-03-03 20:53:42 -06:00
JPAK 398bff4c15 Fix some formatting. 2025-03-03 20:48:45 -06:00
JPAK e0655df5f0 Merge remote-tracking branch 'origin/riding-settings' into riding-settings
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/riding/controller/RideController.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/riding/controllers/BirdAirController.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/riding/controllers/HelicopterAirController.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/pokemon/riding/controllers/JetAirController.kt
2025-03-03 20:44:58 -06:00
JazzMcNade 8a5489f805 Merge branch 'main' into SaferSendouts 2025-03-03 20:44:26 -06:00
JPAK 9174aac64c Added Config options and implemented the invert mouse options on current controllers. 2025-03-03 20:43:35 -06:00
JPAK 3cdc4c7d97 Added Config options and implemented the invert mouse options on current controllers. 2025-03-03 17:35:32 -06:00
Alexis SalgueiroandWeblate 482c57dd2e Translated using Weblate (French)
Currently translated at 89.1% (6259 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-03 19:14:47 +00:00
Alexis SalgueiroandWeblate 503c62d78d Translated using Weblate (French)
Currently translated at 87.8% (6169 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-03-03 09:30:43 +00:00
Seonho LeeandWeblate 708d0ab6d3 Translated using Weblate (Korean)
Currently translated at 70.0% (4915 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ko/
2025-03-03 09:30:42 +00:00
Polymeta 9ce6acc44d Merge branch 'fix-hide-additional-tooltip' into 'main'
hide_additional_tooltip working for Pokerod and Bait

See merge request cable-mc/cobblemon!1547
2025-03-03 08:44:49 +00:00
Polymeta f170ed726b Merge branch 'jackowes/riding/02' into 'main'
Fix: Whole json object being passed to deserialize rather than the single JsonElement.

See merge request cable-mc/cobblemon!1549
2025-03-02 18:11:14 +00:00
JacksonB 979d6f02a6 Fix: Whole json object being passed to deserialize rather than the single JsonElement. 2025-03-02 11:32:38 -06:00
BuildTools 3fbe80cb1a Changelog 2025-03-02 17:02:07 +02:00
Polymeta 8fdb32273d Merge branch 'nuggets-of-nuggets' into 'main'
Fling

See merge request cable-mc/cobblemon!1548
2025-03-02 13:11:56 +00:00
dhi_holo d5c9d8d5b1 Fling
Blocks of Gold now can be flung for 150 BP
2025-03-02 20:57:37 +10:00
BuildTools 752c9c234e hide_additional_tooltip working for Pokerod and Bait 2025-03-02 12:10:28 +02:00
Hiroku b7b6185ada Merge branch 'jackowes/ride_cleanup' into 'main'
WIP jet, bird, and helicopter controller

See merge request cable-mc/cobblemon!1543
2025-03-02 09:31:46 +00:00
Jackson BowesandHiroku 211b886bf3 WIP jet, bird, and helicopter controller 2025-03-02 09:31:45 +00:00
Paul 36d1008f29 Minor code cleanup and added interpolate property to changelog 2025-03-02 15:39:02 +10:00
Hiroku 1441625a6b Merge branch 'animated-texures-interpolation' into 'main'
Animated Texture Interpolation for Cobblemon

See merge request cable-mc/cobblemon!1545
2025-03-02 05:28:00 +00:00
Paul 3859eb574e Another tweak for Polymeta 2025-03-02 15:25:12 +10:00
Paul b4a29214a7 Minor changes to unlockable wallpapers code for Poly's happiness 2025-03-02 15:24:05 +10:00
Gertimoshka 6ca16a0161 Resolve Conflicts 2025-03-01 03:46:18 +00:00
Plastered_Crab 86d48df9fe Render Rotom drone camera to start orbiting around + try to avoid collisions using raycast point cloud 2025-02-28 16:59:03 -08:00
TeggyandWeblate 19727542bd Translated using Weblate (Spanish)
Currently translated at 91.4% (6424 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-28 22:02:07 +00:00
Alexis SalgueiroandWeblate c4e6714a95 Translated using Weblate (French)
Currently translated at 87.6% (6153 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/fr/
2025-02-28 02:41:41 +00:00
TeggyandWeblate c116e612c6 Translated using Weblate (Spanish)
Currently translated at 90.4% (6354 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-28 02:41:41 +00:00
Fiestorra ISVandWeblate 215a055ce6 Translated using Weblate (Spanish)
Currently translated at 90.4% (6354 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-28 02:41:40 +00:00
BuildTools 2f31db2232 Insane Person Presents: INTERPOLATION 2025-02-27 18:04:48 +02:00
Fiestorra ISVandWeblate 9c0b6b8d26 Translated using Weblate (Spanish)
Currently translated at 87.3% (6134 of 7021 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-25 22:27:22 +00:00
Fiestorra ISVandWeblate 5c4462ee94 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-25 18:48:01 +00:00
TeggyandWeblate 04edd6f9e2 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-25 18:48:01 +00:00
Polymeta 52821cc051 Merge branch 'main' into lang-updates 2025-02-25 18:38:33 +00:00
Watuneni iteiteandWeblate 0029deb029 Translated using Weblate (Japanese)
Currently translated at 81.6% (5218 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-02-23 23:03:25 +00:00
TeggyandWeblate c6360e2a36 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-23 23:03:24 +00:00
Fiestorra ISVandWeblate 2e77c647b6 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-23 23:03:22 +00:00
Test ed0e0fc65a Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into unlockable-wallpapers 2025-02-23 11:04:13 -05:00
Guilherme Pereira ee28cf554a add cooking progress sprite to campfire pot jei 2025-02-23 08:18:34 -03:00
Polymeta 30dcb9a4da initial mixin sorting
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-02-21 23:15:14 +00:00
Polymeta ffc9fdfa6d Merge branch 'refs/heads/main' into we_are_cooking_now
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/resources/cobblemon-common.accesswidener
#	common/src/main/resources/mixins.cobblemon-common.json
2025-02-21 23:02:08 +00:00
Watuneni iteiteandWeblate c3d3b19788 Translated using Weblate (Japanese)
Currently translated at 81.3% (5200 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-02-21 08:11:08 +00:00
Fiestorra ISVandWeblate 219cd61beb Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-21 08:11:07 +00:00
Paul c5dcfc57ea Added toast for unlocking PC wallpapers, fixed some molang issues for living entities 2025-02-21 10:26:13 +10:00
TeggyandWeblate 207e5a9142 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-19 13:03:51 +00:00
apion 4f86c6f322 Flashback no longer crashes the game 2025-02-18 20:02:36 -05:00
Watuneni iteiteandWeblate c721fb534d Translated using Weblate (Japanese)
Currently translated at 81.2% (5191 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/ja/
2025-02-18 15:00:29 +00:00
iván SeguraandWeblate dba2622fd7 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-18 15:00:28 +00:00
Guilherme Pereira 33c8ecd908 add seasonings to cooking pot jei integration 2025-02-18 01:51:49 -03:00
Guilherme Pereira 93367fb0e8 add jei integration to cooking pot 2025-02-17 23:18:06 -03:00
Guilherme Pereira 694f74be13 add candle cake 2025-02-17 17:11:49 -03:00
Paul 9997a5c4b4 Touch-ups to wallpaper unlocked flow and the right click platform event flows 2025-02-17 20:29:43 +10:00
Paul 2b70e5614c Merge remote-tracking branch 'origin/main' into unlockable-wallpapers
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonFlows.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/molang/MoLangFunctions.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/events/FlowHandler.kt
2025-02-17 20:18:29 +10:00
JazzMcNade 3b7d56ff45 Merge branch 'main' into SaferSendouts 2025-02-16 20:53:08 -06:00
Guilherme Pereira 79d097b17c add support for diferent cake variants 2025-02-16 19:14:50 -03:00
Guilherme Pereira 7ef30653bb refactor cake rendering 2025-02-16 17:14:35 -03:00
Guilherme Pereira 1ecb13f7fc Merge branch 'main' into we_are_cooking_now 2025-02-16 13:14:27 -03:00
iván SeguraandWeblate da68675133 Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-16 12:57:27 +00:00
Flarkinater 3401ba9cbb Fix drone animation 2025-02-15 21:48:29 -05:00
Flarkinater dac9ccb461 Revert debug change 2025-02-15 21:47:59 -05:00
Flarkinater 191a62f693 Attempt to debug the animation issue 2025-02-15 16:50:52 -05:00
Flarkinater d8d410e539 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into stadium-block 2025-02-15 15:37:37 -05:00
Flarkinater b7c6e1ea77 Attempt to make the drone animated (WIP) 2025-02-15 15:35:48 -05:00
Test 589c5381e2 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into unlockable-wallpapers 2025-02-15 15:14:40 -05:00
Test 4539703497 prevent filenotfoundexception; update colors 2025-02-15 15:14:23 -05:00
Kenji_64 975cdf050f Fixed Charcadet's cry sound event not being there and head pivot 2025-02-15 15:34:34 +01:00
iván SeguraandWeblate 9aea5a7daf Translated using Weblate (Spanish)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/es/
2025-02-15 13:26:10 +00:00
Test d19878edf6 refactor pot 2025-02-14 16:00:56 -05:00
Flarkinater 186812d6fd Refactor - move most drone assets into bedrock/drone 2025-02-14 12:23:27 -05:00
Test 4f98d1e054 Merge branch 'we_are_cooking_now' of https://gitlab.com/cable-mc/cobblemon into we_are_cooking_now
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonItems.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/cooking/CookingComponentColorHelper.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/CampfireBlockEntityRenderer.kt
2025-02-13 18:54:15 -05:00
Test 7b8e07aef3 refactor pot 2025-02-13 18:44:11 -05:00
Gustavo PuerariandWeblate 10402575fb Translated using Weblate (Portuguese (Brazil))
Currently translated at 68.3% (4369 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-13 23:43:36 +00:00
João Pedro Silva AfonsoandWeblate 0f82ade57c Translated using Weblate (Portuguese (Brazil))
Currently translated at 68.3% (4369 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-13 23:43:35 +00:00
Flarkinater 1c0bdc766a Fix upside-down drone 2025-02-12 14:55:41 -05:00
Flarkinater c697bcd2e9 Render the drone in-game 2025-02-12 01:17:42 -05:00
Gustavo PuerariandWeblate 450b041118 Translated using Weblate (Portuguese (Brazil))
Currently translated at 65.1% (4166 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-11 21:12:32 +00:00
Flarkinater 9d6ff01d80 Add Rotom drone model/texture/animation placeholders 2025-02-10 20:20:24 -05:00
Flarkinater 1691853a19 Remove placeholder model, we'll just use some "dev art" for now 2025-02-10 20:20:12 -05:00
Flarkinater 4e9a4e1e5a Update deprecated methods, imports, and formatting 2025-02-10 20:20:03 -05:00
Flarkinater 6450255a0b Rebase old stadium camera test branch 2025-02-10 20:19:13 -05:00
Paul 0152bc2e32 Added event for unlocking wallpapers, added flows for advancement_earned, right_clicked_entity, right_clicked_block, player_died, wallpaper_unlocked 2025-02-10 18:13:27 +10:00
Paul e175c44118 Added unlockable PC box wallpapers 2025-02-10 15:36:46 +10:00
Weblate 770c349ac4 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-02-10 00:41:50 +00:00
Gustavo PuerariandWeblate f76648b6f2 Translated using Weblate (Portuguese (Brazil))
Currently translated at 59.8% (3826 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-10 00:41:46 +00:00
Gustavo PuerariandWeblate 56e60667db Translated using Weblate (Portuguese (Brazil))
Currently translated at 51.5% (3297 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-07 00:29:47 +00:00
Guilherme Pereira 1442bf5c34 fix merge 2025-02-06 03:47:13 -03:00
Guilherme Pereira 2ac37f6c4d Merge branch 'main' into we_are_cooking_now 2025-02-06 03:46:51 -03:00
Guilherme Pereira 9795dce227 remove campfire pot trap 2025-02-06 03:34:02 -03:00
Gustavo PuerariandWeblate c4a60951c5 Translated using Weblate (Portuguese (Brazil))
Currently translated at 49.7% (3178 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-05 07:22:58 +00:00
KyoandWeblate 814eee8125 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (6391 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/vi/
2025-02-03 09:44:44 +00:00
Gustavo PuerariandWeblate 2a9ff3bfbd Translated using Weblate (Portuguese (Brazil))
Currently translated at 47.9% (3064 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-02-03 09:44:43 +00:00
Konoha 8fe2042127 Merge Basculin game evolutions 2025-02-02 08:17:05 -05:00
Konoha 538ad883ab Correct Spewpa evo tag reference in evolution to tag format 2025-02-02 08:02:49 -05:00
Konoha 136cb86492 Correct the consumption of held items on non-applicable item evolutions 2025-02-01 08:22:12 -05:00
Konoha e4eb1251d1 Fix Goomy & Bergmite branch evolutions, branching stone anticondition conflict. 2025-02-01 07:51:39 -05:00
Weblate 83350cb0db Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-01-31 22:57:44 +00:00
Patch Notes GuyandWeblate 778761dbee Translated using Weblate (Vietnamese)
Currently translated at 99.1% (6335 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/vi/
2025-01-31 22:57:39 +00:00
Gustavo PuerariandWeblate e9881b748a Translated using Weblate (Portuguese (Brazil))
Currently translated at 46.4% (2971 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-01-31 22:57:25 +00:00
Guilherme Pereira d9cf802a9e fix saccharine trees natural world generation 2025-01-31 11:27:59 -03:00
Weblate dabaeefa23 Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/
2025-01-31 09:41:51 +00:00
Patch Notes GuyandWeblate 0e0bec2712 Added translation using Weblate (Vietnamese) 2025-01-31 09:41:47 +00:00
Gustavo PuerariandWeblate 48fe160334 Translated using Weblate (Portuguese (Brazil))
Currently translated at 45.1% (2887 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-01-31 03:10:48 +00:00
Valerie Rice 1bc83d9045 poison frog man (only the little one) 2025-01-28 16:22:21 +10:00
Gustavo PuerariandWeblate 7d599e12d0 Translated using Weblate (Portuguese (Brazil))
Currently translated at 42.7% (2731 of 6391 strings)

Translation: Cobblemon/Mod
Translate-URL: http://lang.cobblemon.com/projects/cobblemon/mod/pt_BR/
2025-01-27 23:30:11 +00:00
Konoha 98775ffc1e Merge branch 'main' into Dex-Species-Forms
# Conflicts:
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
2025-01-27 09:26:48 -05:00
Guilherme Pereira 3fbf2595cc add wool particles to cake breaking 2025-01-26 13:58:57 -03:00
Guilherme Pereira 6665285253 refactor cakes 2025-01-25 19:06:11 -03:00
Guilherme Pereira 61ae29b745 add candied apple, fried rice and potato mochi 2025-01-21 18:29:15 -03:00
Guilherme Pereira a17bf5eeeb update licenses 2025-01-21 17:42:03 -03:00
Guilherme Pereira c71d91a46d add mochis 2025-01-21 17:40:44 -03:00
Konoha bbeb3d45f0 Merge branch 'implement_pokemon' into Dex-Species-Forms 2025-01-21 11:37:28 -05:00
Guilherme Pereira c86103fd31 add player edible cake 2025-01-20 18:49:18 -03:00
Plastered_Crab 5190bbe723 Prep for adding new cooking recipe items 2025-01-18 22:08:16 -08:00
Plastered_Crab 3663ce2555 Merge remote-tracking branch 'origin/we_are_cooking_now' into we_are_cooking_now 2025-01-18 15:00:46 -08:00
Plastered_Crab b5fc52d9b1 Merge branch 'main' into we_are_cooking_now
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/api/tags/CobblemonBlockTags.kt
#	common/src/main/resources/data/cobblemon/recipe/cooking_pot/whipped_dream_from_cooking_pot.json
#	common/src/main/resources/data/minecraft/tags/block/logs.json
#	common/src/main/resources/data/minecraft/tags/item/logs.json
#	common/src/main/resources/data/minecraft/tags/item/logs_that_burn.json
2025-01-18 14:59:52 -08:00
Konoha 8fd854f7f7 Merge branch 'main' into Dex-Species-Forms 2025-01-18 16:48:07 -05:00
Konoha f449cf27c5 Merge branch 'implement_pokemon' into Dex-Species-Forms 2025-01-18 10:59:31 -05:00
Guilherme Pereira ca79b70815 add shapes to lure cakes 2025-01-17 13:05:37 -03:00
Guilherme Pereira 898c956f17 add rendering for the inner part of the cake 2025-01-16 17:01:37 -03:00
Guilherme Pereira 2ce48c9dff add custom lure cake color based on seasonings 2025-01-16 10:36:33 -03:00
Guilherme Pereira f64ec12a6a update licenses 2025-01-15 19:55:56 -03:00
Guilherme Pereira 474d3f3b55 add campfire pot bubbles color 2025-01-15 19:54:26 -03:00
Guilherme Pereira c87e6a391d refactor cooking pot renderer 2025-01-15 18:34:43 -03:00
Guilherme Pereira 192fd4dba7 make campfire pot bubbles disapear on lid close 2025-01-15 17:22:10 -03:00
plastered_crab c26786c644 Put water back to how it was 2025-01-14 21:19:22 -08:00
Plastered_Crab ebb0277d80 Merge remote-tracking branch 'origin/we_are_cooking_now' into we_are_cooking_now
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/client/render/block/CampfireBlockEntityRenderer.kt
2025-01-14 17:20:34 -08:00
Plastered_Crab 2a73efa479 Create custom render type to allow Cooking Pot water pane to show particles through it (wip) 2025-01-14 17:19:53 -08:00
Guilherme Pereira 6e68d22d4a update campfire pot models (again) 2025-01-14 20:39:49 -03:00
Guilherme Pereira dee08e6572 fix cooking pot rotation 2025-01-14 18:38:34 -03:00
Guilherme Pereira 2383686e42 update campfire pot models 2025-01-14 17:54:16 -03:00
Guilherme Pereira b8de9c415e Merge branch 'we_are_cooking_now' of gitlab.com:cable-mc/cobblemon into we_are_cooking_now 2025-01-14 16:59:09 -03:00
Guilherme Pereira f0269a3638 fix cooking pot items not being properly synched with the client 2025-01-14 16:58:54 -03:00
Plastered_Crab dbbbd309dc Added TransparentColorMixer method 2025-01-14 11:06:07 -08:00
plastered_crab b7a905ad79 Remove old bubbles 2025-01-14 06:59:23 -08:00
plastered_crab 60c8049459 More water bubble changes for cooking pot 2025-01-14 06:13:50 -08:00
plastered_crab 8c395b6fee Reduce and raise the particles for bubbling water in cooking pot 2025-01-13 22:21:14 -08:00
plastered_crab e9935a41e3 Start to add particles for bubbling water in cooking pot 2025-01-13 21:45:14 -08:00
Guilherme Pereira f0ecd4d50d add seasoning color to cooking pot water 2025-01-13 23:30:07 -03:00
Guilherme Pereira c0661022ab i hate bubbles 2025-01-13 21:50:30 -03:00
Guilherme Pereira e7305a3dfb improve seasonings spin on the cooking pot 2025-01-13 20:24:41 -03:00
Guilherme Pereira 86f52f176a make cooking pot seasonings spin 2025-01-13 20:01:25 -03:00
Guilherme Pereira beb9796e75 add water liquid to open cooking pot 2025-01-13 19:20:20 -03:00
Guilherme Pereira 6bb55adebc add campfire pot open/close variants 2025-01-13 13:41:37 -03:00
Guilherme Pereira 011bc85d18 Merge branch 'main' into we_are_cooking_now 2025-01-12 19:44:19 -03:00
Guilherme Pereira fad75c498b make cooking pot drop items on remove 2025-01-10 14:22:00 -03:00
Guilherme Pereira 915c69b443 improve cooking pot sounds 2025-01-10 11:06:49 -03:00
Guilherme Pereira 05b574543c add more constants to cooking pot 2025-01-10 10:30:01 -03:00
Guilherme Pereira 5198b2a709 render preview item on cooking pot 2025-01-10 09:35:14 -03:00
Guilherme Pereira 509973a027 add button to open/close the cooking pot lid 2025-01-10 07:58:58 -03:00
Guilherme Pereira 0253475f50 make cooking pot work similar to a furnace 2025-01-09 14:00:25 -03:00
Guilherme Pereira 6961c92c8d fix container data of cooking pot 2025-01-08 17:41:43 -03:00
Plastered_Crab 906d7b361d Lure Cakes now show their Bait Effects on their tooltip 2025-01-07 15:45:32 -08:00
Plastered_Crab 54121199b6 Merge remote-tracking branch 'origin/we_are_cooking_now' into we_are_cooking_now 2025-01-07 15:29:39 -08:00
Plastered_Crab 78b3e0a1aa Lure Cakes now are grey (colors coming later) and get eaten in bits as pokemon spawn 2025-01-07 15:29:17 -08:00
Guilherme Pereira aa45795944 add cooking pot sounds 2025-01-07 19:55:57 -03:00
Guilherme Pereira 353209c72c Merge branch 'we_are_cooking_now' of gitlab.com:cable-mc/cobblemon into we_are_cooking_now 2025-01-07 18:28:39 -03:00
Guilherme Pereira d07eaefdd4 lil cooking pot refactoring 2025-01-07 18:28:21 -03:00
Sterrezo 2ead9f6f02 Added campfire pot sounds 2025-01-07 21:58:05 +01:00
Plastered_Crab 472a349709 Merge remote-tracking branch 'origin/we_are_cooking_now' into we_are_cooking_now 2025-01-07 12:40:06 -08:00
Plastered_Crab 9043520364 Lure Cakes now store CookingComponent data, render, and can use BaitEffects 2025-01-07 12:39:41 -08:00
Guilherme Pereira 88ea77e2f3 ad quality tooltip to aprijuices 2025-01-07 15:56:49 -03:00
Guilherme Pereira a609e2d561 add separate aprijuice tooltip generator 2025-01-07 15:28:52 -03:00
Guilherme Pereira 6f1c791df4 add shift click functionality to cooking pot 2025-01-07 08:47:53 -03:00
plastered_crab dc41e7b50f Lure cakes work now with new (maybe temporary) spawn context "bait" 2025-01-06 23:00:33 -08:00
Plastered_Crab 1b22da8bd9 Merge remote-tracking branch 'origin/we_are_cooking_now' into we_are_cooking_now 2025-01-06 17:27:28 -08:00
Plastered_Crab 773eb9e1c3 So close to having Lure Cakes spawning pokemon 2025-01-06 17:27:07 -08:00
Guilherme Pereira 87deea9748 make cooking pot items persistent 2025-01-06 21:13:47 -03:00
Guilherme Pereira 556636f41e Merge branch 'we_are_cooking_now' of gitlab.com:cable-mc/cobblemon into we_are_cooking_now 2025-01-06 20:48:27 -03:00
Guilherme Pereira daab3dd3dd fix bait vanishing 2025-01-06 20:48:17 -03:00
Plastered_Crab 5535390298 Lure Cakes are real!! 2025-01-06 15:13:19 -08:00
Guilherme Pereira f54eaf3101 make baits update sprite and tooltip while crafting on the cooking pot 2025-01-06 19:18:57 -03:00
Guilherme Pereira 1d86ace385 no more food waste 2025-01-06 18:32:49 -03:00
Guilherme Pereira 4a02a0a67d add leaf color based on quality to aprijuices 2025-01-06 17:33:14 -03:00
Guilherme Pereira 7f193c11e1 add flavor tooltip to aprijuices 2025-01-06 16:26:44 -03:00
plastered_crab 9f90a08276 Added preliminary foundation for Lure/Bait spawns 2025-01-06 09:58:30 -08:00
Guilherme Pereira f49a114f0f make aprijuice mix colors base on flavors 2025-01-06 14:00:30 -03:00
Guilherme Pereira 281fc300a6 fix merge 2025-01-06 14:00:20 -03:00
plastered_crab ea7078b749 Merge branch 'refs/heads/main' into we_are_cooking_now
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonItems.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonNetwork.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/client/CobblemonBakingOverrides.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/item/interactive/PokerodItem.kt
#	common/src/main/resources/assets/cobblemon/lang/en_us.json
#	common/src/main/resources/data/cobblemon/tags/block/flowers.json
#	common/src/main/resources/data/minecraft/tags/block/flowers.json
#	fabric/src/main/kotlin/com/cobblemon/mod/fabric/CobblemonFabric.kt
2025-01-06 08:03:32 -08:00
plastered_crab 03aabb55ca Merge remote-tracking branch 'origin/we_are_cooking_now' into we_are_cooking_now 2025-01-06 07:33:30 -08:00
plastered_crab 078da5b213 Adjust tooltip info for "seasoning" ingredients 2025-01-06 07:33:19 -08:00
Guilherme Pereira 22af77c7e6 add aprijuice item color provider 2025-01-06 12:21:32 -03:00
Guilherme Pereira 7ee7a6624f add dynamic rendering for poke baits based on seasonings 2025-01-06 10:19:43 -03:00
plastered_crab 85c9fcd28e Added test tooltip info for "seasoning" ingredients to show flavor data (thank you Tim) 2025-01-05 23:16:51 -08:00
plastered_crab 619da2e19a All berry seasoning files are done now! So many flavors! 2025-01-05 21:49:06 -08:00
plastered_crab c457cdfe5e Edit the seasoning files to include accurate berry flavors 2025-01-05 18:19:24 -08:00
plastered_crab a87c319d10 Fishing Bait combining works now! Fish be warned! 2025-01-04 23:53:18 -08:00
plastered_crab db5bdb0ef1 You can now combine fishing bait! (kind of) 2025-01-04 18:38:20 -08:00
JazzMcNade 50c567d264 Clean up, scale look radius with size 2025-01-04 18:35:14 -06:00
plastered_crab adc79a34d1 Gordon Ramsey is with me like the movie Ghost 2025-01-04 02:52:00 -08:00
plastered_crab 8776dffed4 What's that? are we close to cooking with Seasoning Slots?? I think so! 2025-01-04 01:49:57 -08:00
plastered_crab 77f5434b78 Started work on potential CookingComponent 2025-01-04 00:49:41 -08:00
JazzMcNade d4964e41d3 Clean up, fixed fluid handling 2025-01-03 22:04:23 -06:00
JazzMcNade 41b1c169c3 Merge branch 'main' into SaferSendouts 2025-01-03 20:49:13 -06:00
JazzMcNade 49e2001004 clean up 2025-01-03 20:48:28 -06:00
Konoha bf5fd5eed8 Merge remote-tracking branch 'origin/main' 2025-01-03 19:19:26 -05:00
Konoha facead5f0b Preliminary species form support for Pokedex 2025-01-03 19:12:31 -05:00
plastered_crab 0191373ff5 Slight tweak to RICE placement in shallow water 🌾 2025-01-03 12:09:41 -08:00
plastered_crab 0daf995c70 The RICE it grooooooows in water babyyy 🌾 2025-01-03 09:13:29 -08:00
plastered_crab dd9437c663 Fix the bounding box shape of the RICE and allow it to be waterlogged🌾 2025-01-03 01:29:17 -08:00
plastered_crab 752675ffb0 Can you smell what the RICE is cooking?!? 🌾🌾🍚🍙🌾🌾 2025-01-03 00:24:50 -08:00
JazzMcNade 66393f9293 Merge branch 'main' into SaferSendouts 2025-01-02 21:11:07 -06:00
Plastered_Crab 5bcc0fb343 Alcremie Sweets are cookable + honey bottles return glass bottles when cooked with 2025-01-02 16:34:59 -08:00
Plastered_Crab 2cd726c003 Aprijuice is coming (for real this time) 2025-01-02 16:12:00 -08:00
Plastered_Crab f911ad57b9 Aprijuice is coming 🚨🚨🚨 2025-01-02 16:10:21 -08:00
Plastered_Crab bc2a547b86 Yeah boi we cooking with some recipes now 🧑🏻‍🍳 2025-01-02 13:53:48 -08:00
Plastered_Crab d5ba9bc3f5 Shapeless recipes go brrrr 🧑🏻‍🍳 2025-01-02 11:37:32 -08:00
plastered_crab 3dc8493b76 Start to getting Cooking Pot Shapeless recipes working 2025-01-01 20:13:56 -08:00
Plastered_Crab 0b991c4ae3 Let's gooooooo! Cooking Pot seasoning slots and renderer working so good now 🧑🏻‍🍳 2025-01-01 13:14:17 -08:00
Plastered_Crab 1352508070 Yeah baby CookingPot stays rendered now and Components work properly now 😎 2025-01-01 12:49:58 -08:00
plastered_crab 87d467ec67 My God I'm dumb. It works now lmao 2025-01-01 00:37:17 -08:00
plastered_crab c020deb728 Please god end this suffering. Why won't this work 💀 2024-12-31 23:15:39 -08:00
JazzMcNade 7b3b6146a1 Single raycast to avoid spawning in walls, setPositionSafely can no longer path into a wall 2024-12-30 20:44:32 -06:00
plastered_crab d5e15f7bf2 Attempting to store data on Campfire Block Entity via Components 2024-12-30 17:04:09 -08:00
JazzMcNade e1452244c2 Merge branch 'main' into SaferSendouts 2024-12-30 12:50:24 -06:00
plastered_crab 59622a1bfb Additional fixes for crafting grid syncing 2024-12-30 10:50:12 -08:00
Conan 8913d3df11 Reworked SpectateBattleHandler.kt 2024-12-30 18:23:58 +01:00
plastered_crab 1c237503a0 Cooking Pot syncs with crafting slots finally 2024-12-29 22:22:43 -08:00
plastered_crab 138a83c844 More fixes and syncing 2024-12-29 16:57:39 -08:00
plastered_crab e8c86f4b4e Cooking Pot clears crafting slots when result item is taken 2024-12-29 16:45:16 -08:00
plastered_crab 344d2ae3e6 plz pot 2024-12-29 16:08:58 -08:00
plastered_crab 19a571147b I hate this pot 2024-12-29 14:59:34 -08:00
plastered_crab 2f369fb6ee More work trying to get the Cooking Pot to behave 2024-12-29 14:24:31 -08:00
Conan 3a55965704 Merge branch 'main' of https://gitlab.com/cable-mc/cobblemon into spectate-command
# Conflicts:
#	common/src/main/kotlin/com/cobblemon/mod/common/CobblemonCommands.kt
#	common/src/main/kotlin/com/cobblemon/mod/common/api/permission/CobblemonPermissions.kt
2024-12-29 12:30:54 +01:00
plastered_crab c1d16f5185 Redo how crafting slots are initialized for Cooking Pot (result = 0 crafting 1-9) and add more debug 2024-12-28 22:36:11 -08:00
plastered_crab 2382895a42 Add minecraft:potion id for crafting medicinal brew 2024-12-27 18:09:39 -08:00
plastered_crab 68adae082b Additional recipes for the Cooking Pot 2024-12-27 17:12:49 -08:00
Erusel eac1b573c9 trying to debugs these ***** slots (i think ?) 2024-12-27 22:42:38 +01:00
JazzMcNade 5358414a0c Merge branch 'main' into SaferSendouts 2024-12-24 15:27:25 -06:00
JazzMcNade d691373919 Capped collision box size. Added trace to help prevent attempts to send outs going into walls 2024-12-15 20:14:30 -06:00
JazzMcNade 038f13e6fa Merge branch 'main' into SaferSendouts 2024-12-15 00:52:31 -06:00
Erusel a29a17a28b Added Cooking Pot ( globally ) 2024-12-13 00:09:33 +01:00
JazzMcNade dd288a3b0c SetPositionSafely now implements BFS WIP 2024-12-08 21:39:17 -06:00
Erusel 4805659a68 Started furnace like crafting 2024-12-03 09:42:54 +01:00
Erusel fbdcfb20ed Cooking Pot now keep items inside 2024-11-30 12:11:28 +01:00
Erusel 4a2b186ef7 Merge remote-tracking branch 'origin/we_are_cooking_now' into we_are_cooking_now 2024-11-30 12:10:48 +01:00
Plastered_Crab fa41b30a4c Add 2 test overlays for Poke Bait 2024-11-29 18:42:38 -08:00
Plastered_Crab 505282986e Add better texture for Poke Bait 2024-11-29 17:13:15 -08:00
Plastered_Crab 9e6e74db7c Add test recipe for Poke Bait 2024-11-29 14:03:01 -08:00
Plastered_Crab cf68e88103 Add test Poke Bait sprite for testing new combining bait system 2024-11-29 12:44:59 -08:00
Plastered_Crab 84ae73d0d1 Add test Pokepuff sprites for testing 2024-11-29 12:35:38 -08:00
Erusel 9bb0f13793 Added cooking pot to the block group 2024-11-29 16:51:16 +01:00
Erusel 912485067b Working cooking pot recipe book 2024-11-29 12:10:59 +01:00
Plastered_Crab 128f7c15a6 Add debug chaos to try to help see why registering recipes doesnt work 2024-11-28 00:44:05 -08:00
Erusel 5d67d0fdfc - i want to die 2024-11-28 03:12:45 +01:00
Erusel 3f90d19801 - Added Cooking Pot block
- Added Sweety things
- Started cooking pot handled things
2024-11-26 22:28:05 +01:00
Conan 7112c74bf2 Reworked spectate command. 2024-11-09 22:37:11 +01:00
Conan faa1906290 Added a spectate battle command. 2024-11-09 17:30:01 +01:00
Plastered_Crab 897e1651c5 Remove unneeded file 2024-11-05 14:49:17 -08:00
Plastered_Crab 9c5bb2fcdb Start to implementing Sweet Incense block 2024-11-05 12:14:47 -08:00
Plastered_Crab 8ee8d84c8b Add missing bugwort textures and blockstates 2024-11-04 15:43:56 -08:00
Plastered_Crab b25fbf42ab Bugwort plants now grow and behave properly 2024-11-04 15:40:23 -08:00
Plastered_Crab f9f3392901 Leaves drip honey down below to other leaves more often 2024-11-04 11:33:14 -08:00
Plastered_Crab 35249f5804 Stripped Saccharine Logs now give Sweet Sap again 2024-11-03 23:34:12 -08:00
Plastered_Crab b32fdeda9c Merge remote-tracking branch 'origin/we_are_cooking_now' into we_are_cooking_now 2024-11-03 23:07:07 -08:00
tmetcalfe89 1d033701ed fix leaf block
keys in the ignition, bonemeal on, redundant props removed
2024-11-03 22:53:31 -08:00
Plastered_Crab 6422cffde3 Merge branch 'main' into we_are_cooking_now 2024-11-03 14:35:58 -08:00
Plastered_Crab e8588370e5 Remove not needed tag additions for leaves 2024-11-03 13:39:11 -08:00
Plastered_Crab a96692e5cf Bees now like the Saccharine Leaves again and added more old files back that were missing 2024-11-03 13:24:58 -08:00
Nick 81c272778f Merge branch 'we_are_cooking_now' of gitlab.com:cable-mc/pokemon-cobbled into we_are_cooking_now 2024-11-02 01:11:33 -07:00
Nick 31351116b5 Include a configuration for maxShiftBy 2024-11-02 01:11:18 -07:00
Plastered_Crab fd18e4d7f1 Remove unneeded tags in saccharine_leaves json block tag 2024-11-02 00:35:32 -07:00
Plastered_Crab 7eb5364ba7 Add BeeEntityMixin to mixins.cobblemon-common json file 2024-11-02 00:10:03 -07:00
Plastered_Crab 97b679bbe0 Add saccharine_leaves block tags 2024-11-01 23:32:14 -07:00
Plastered_Crab 85dc3ad1d7 Add Saccharine Trees to bee_growables list 2024-11-01 23:18:40 -07:00
Plastered_Crab a90e9544be More remappings and trying to get Bees to fertilize Saccharine Leaves again 2024-11-01 17:14:46 -07:00
Plastered_Crab 6261163728 Add old Abstract CookingPot ScreenHandler to new branch to be remapped 2024-10-31 16:42:52 -07:00
Plastered_Crab 9288ae8776 More work fixing up some remappings 2024-10-31 16:35:13 -07:00
Plastered_Crab f887f678f1 - Add back more missing files from old branch that need re-mapped 2024-10-28 12:20:26 -07:00
Plastered_Crab 59ba74606e - Add textures for real real this time 2024-10-25 14:44:44 -07:00
Plastered_Crab 130b1c99db - Add textures for missing Saccharine items and add missing recipes for Saccharine items. Set stage for re-adding bugwort, saccharine saplings, cooking pot, etc 2024-10-25 14:24:00 -07:00
Plastered_Crab adc4b424c5 Merge branch 'main' into we_are_cooking_now 2024-10-25 12:22:57 -07:00
Erusel 4ad140f7a3 saccharines bases blocks 2024-09-06 20:48:52 +02:00
2963 changed files with 163557 additions and 38844 deletions
+11
View File
@@ -0,0 +1,11 @@
### Additions
- Added the Campfire Pot, made from apricorns and placed onto campfires.
- This pot can be used to make bait for fishing, Poké Cakes, Lure Cakes, local specialties, and potions (less efficiently than a brewing stand).
- There is a different pot for each apricorn colour because at this point I think we may have an addiction.
- Added Aprijuice, made from the Campfire Pot using apricorns with seasoning to give flavours.
- Aprijuice can be fed to ride-able Pokémon to improve their riding characteristics, depending on the flavour and the Pokémon's nature.
### Datapack and Addon Changes
- Renamed the fishing_baits datapack folder to spawn_bait_effects.
- Added `seasonings` datapack folder for controlling usable items in the campfire pot and what colour and flavour they apply.
- Added campfire pot recipe type, which you could use to make anything work as fishing bait.
+12
View File
@@ -0,0 +1,12 @@
### Additions
- Added functionality for marks.
- Added data for all marks and all title ribbons from 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.
- Added `/giveallmarks <player> <partySlot>` command to give all available marks to a Pokémon.
### MoLang & Datapacks
- Added Flows for `bobber_spawn_pokemon_post`, `pokemon_entity_spawn`, and `fossil_revived`.
- Added `marks` datapack folder.
- Added MoLang functions `entity.is_in_rain`, `pokemon.add_marks(Mark...)`, `pokemon.add_potential_marks(Mark...)`, `pokemon.add_marks_with_chance(Mark...)`, `pokemon.apply_potential_marks`, and `world.is_snowing_at(x, y, z)`.
+18 -12
View File
@@ -1,16 +1,22 @@
### Additions
- Added ability to rename PC Boxes by clicking on the name of a box
- Added ability to set wallpapers per PC Box by clicking the button right to the box name
- Added sorting by Name, Level and type by clicking the button left of the box name (shift reverses order)
- Added filtering/search functionality in PC UI, which also supports pokemon properties (e.g. shiny=yes shows all shinies)
- Added /changewallpaper <player> <boxNumber> <wallpaper> command to change a wallpaper through commands
- Added /renamebox <player> <boxNumber> <name> command to rename a PC box through commands
- 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.
- Added filter functionality in PC UI, which supports `PokemonProperties` (e.g. `shiny=yes` shows all shiny Pokémon).
- 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.
### Developer
- Added `RenamePCBoxEvent.Pre` and `RenamePCBoxEvent.Post` events to prevent players from renaming a box or changing their input.
- Added `ChangePCBoxWallpaperEvent.Pre` and `ChangePCBoxWallpaperEvent.Post` to prevent players from changing wallpapers or changing their selection.
- Added `WallpaperCollectionEvent` which gets called when clients connect to a server, allowing the server to handle which of the client-found wallpapers it's allowed to move (collected wallpapers can be removed for example to make it "vanish" client-side).
- Added `WallpaperUnlockedEvent`.
- Renamed `SetPCBoxPokemonPacket` and the respective handler to `SetPCBoxPacket`.
- Added RenamePCBoxEvent.Pre/Post events to prevent players from renaming a box or change their input
- Added ChangePCBoxWallpaperEvent.Pre/Post to prevent players from changing to a wallpaper or change their selection
- Added WallpaperCollectionEvent which gets called when clients connect to a server, allowing the server which of the clients found wallpapers it's allowed to move (collected wallpapers can be removed for example to make it "vanish" client-side)
- Wallpapers are loaded from `assets/<namespace>/textures/gui/pc/wallpaper/` and all wallpapers in this folder are available to the client to choose by default
- Renamed `SetPCBoxPokemonPacket` and the respective handler to `SetPCBoxPacket`
### Addons
- Added Flows for `player_tick_pre`, `player_tick_post`, `advancement_earned`, `right_clicked_entity`, `right_clicked_block`, `player_died`, `wallpaper_unlocked`.
- Flows now have `q.` for any context properties in addition to the `c.` properties, making it a bit more convenient when calling other scripts from Flows.
- Added `unlockable_pc_box_wallpapers` datapack folder for wallpapers that need to be unlocked before they're usable.
- Wallpapers are loaded from `assets/<namespace>/textures/gui/pc/wallpaper/` and all wallpapers in this folder are available to the client to choose by default.
+2 -1
View File
@@ -1,3 +1,4 @@
### Additions
- Added the ability to ride Pokémon by shift-right clicking and selecting the ride option.
- Added the ability to ride Pokémon by shift-right clicking and selecting the ride option.
- Added /calculateseatpositions command for approximating hitbox locations for riding configurations.
+162 -4
View File
@@ -2,6 +2,7 @@
## [1.7.0 (Month xth, 2025)](#1-7-0)
### Additions
- Added `/spectateBattle <player>` command to spectate battles without having to manually walk up to the target.
- Added an in-game configuration screen, allowing all settings from `main.json` to be edited directly in-game.
- Added `/cobblemonconfig reload` command to reload `main.json` configuration. **Note:** Some settings require a server restart to take effect; use this command cautiously.
- Added `blacklisted_items_to_hold` and `whitelisted_items_to_hold` tags to allow for controlling which items players can give to their Pokémon. If the whitelist is empty, it will consider all item as allowed (unless they are in the blacklist).
@@ -10,9 +11,129 @@
- 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 `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 lang keys for all moves and abilities up to Generation 9.
- Fixed Moon Ball moon phase logic to actually work correctly
- Added `translucent_cull` boolean option into resolver's layer to allow for translucent textures with culling
- Added [LambDynamicLights](https://modrinth.com/mod/lambdynamiclights) support for items held by Pokémon.
### Pokémon Added
#### Gen 2
- Dunsparce
#### Gen 3
- Spoink
- Grumpig
- Snorunt
- Glalie
#### Gen 4
- Bronzor
- Bronzong
- Croagunk
- Froslass
#### Gen 5
- Pansage
- Simisage
- Pansear
- Simisear
- Panpour
- Simipour
- Munna
- Musharna
- Blitzle
- Zebstrika
- Trubbish
- Garbodor
#### Gen 6
- Noibat
- Noivern
#### Gen 7
- Drampa
#### Gen 8
- Silicobra
- Sandaconda
#### Gen 9
- Smoliv
- Dolliv
- Arboliva
- Orthworm
- Dudunsparce
### Animation updates for the following Pokémon
- Garchomp
- Tropius
- Torpius
- Nosepass
- Probopass
- Sneasler
- Braixen
- Delphox
- Cinderace
- Kangaskhan
### Model updates for the following Pokémon
- Gyarados
- Dragonite
- Eevee
- Vaporeon
- Jolteon
- Flareon
- Espeon
- Umbreon
- Leafeon
- Glaceon
- Sylveon
- Treecko
- Grovyle
- Sceptile
- Honchkrow
- Garchomp
- Pidgeot
- Nosepass
- Probopass
- Kangaskhan
- Cinderace
- Magnezone
- Metagross
- Added Syrupy Apples.
### Changes
- Renamed `chargeGainedPerTick` config to `secondsToChargeHealingMachine`.
- Made Blocks of Gold count as Big Nuggets when held by a Pokémon (for Fling functionality)
- Players can now eat Sweet and Tart Apples, Whipped Dreams, and the Alcremie Sweets.
- Updated Sweet and Tart Apple sprites
- Updated the following recipes: Air Balloon, Assault Vest, Binding Band, Black Belt, Blunder Policy, Choice Band, Choice Scarf, Cleanse Tag, Covert Cloak, Destiny Knot, Eject Button, Expert Belt, Focus Band, Focus Sash, Magnet, Metronome, Muscle Band, Power Anklet, Power Band, Power Belt, Power Bracer, Power Lens, Power Weight, Protective Pads, Protein, Punching Glove, Reaper Cloth, Rocky Helmet, Room Service, Sachet, Safety Goggles, Silk Scarf, Spell Tag, Utility Umbrella, Weakness Policy, Zinc
- Added alternate ingredient options to the following recipes: Cell Battery, Charcoal Stick, Dragon Fang, Miracle Seed, Mystic Water, Never Melt Ice, Twisted Spoon, Damp Rock, Heat Rock, Icy Rock, Smooth Rock
- Grouped together some recipes within the Recipe Book. Groups include: the seven basic Poké Balls, the seven basic Ancient Poké Balls, Gilded Chests, Pokedexes, and the Weather Rocks.
- Updated some item tags to better integrate behaviours between Cobblemon, Vanilla Minecraft, and other mods
- Removed Cooked Meat, Raw Meat, Protein Ingredients, and Zinc Ingredients, the first two are now using `c` namespace tags, the latter have better integrated use of tags within their recipes which removes need for custom tags.
- Added our seeds tag into `#c:seeds`, which is now made use of for the Miracle Seed recipe.
- Tweaked the Natural Materials Vanilla file to fit with the changes to tags
- Substantially optimised spawning checks mainly by front-loading biome filtering.
- When using the `cobblemon` or `generation_9` capture calculators a critical capture with a single shake will always play for successful captures when you've already registered the Pokémon as caught in your Pokédex.
- Improved the performance of saving Pokédex and player data.
- Pokémon hitbox now scales with entity attribute `generic.scale`.
- Removed Shulker aspect and replaced it with cosmetic_item-shulker_shell.
- Shulker shell Forretress is now a cosmetic rather than a special evo and thus all shulker Forretress will revert back to normal until a shulker shell is put in their cosmetic slot.
- Updated `doPokemonSpawning` gamerule to support per-dimension configurations.
- The Pokedex now displays a form name of a "normal" Pokémon for when the base form is still a named form.
- Improved the zoom functionality of the Pokédex Scanner by giving the levels logarithmic scaling.
- Added a subtle rotation effect to the Pokédex Scanner's wheel when zooming.
- Improved parity with vanilla mobs' drop behavior; loot and XP drop on death instead of after the entire death sequence finishes.
- Quirk animations no longer play in the battle GUI since they were pretty distracting.
- A number of Pokemon that float above the ground visually (Gastly, Klingklang, etc.) are no longer considered to be touching the ground
### Fixes
- Fixed Particles sometimes facing the wrong direction (looking at you, Swords Dance)
@@ -34,6 +155,17 @@
- Fixed owned Pokémon sometimes being un-interactable after the player relogs fast
- Fixed field name in evolution requirements for Spewpa Pokeball.
- Fixed LevelUpCriterion logic to correctly check that the Pokémon is a preEvo.
- Fixed `hide_additional_tooltip` vanilla flag not properly hiding tooltips on pokerod and bait items
- Removed a number of scenarios in which a Pokémon battle may send out a Pokémon into collision geometry.
- Fixed NPCs using Pokémon outside of their pool when a Pokémon name had a typo.
- Fixed an issue with datapacked species features not being applied properly when relogging.
- Fixed Pokémon marked as silent still playing shiny sounds and effects.
- Fixed an issue with newer versions of Fabric API where underground Pokémon were spawning in The End.
- Fixed spawning not working well when you're at high points surrounded by lower altitude spawning areas, such as flying.
- Fixed certain Pokémon with forms not having appropriate stock Pokédex entries.
- Fixed issue with Pokédex Scanner that caused the open/close overlay to have the wrong opacity values
- Fixed dragon's breath not being usable on the restoration tank when it should be
- Fixed some effects like particles from fishing rods appearing for players in the same coordinates in another world.
### Developer
- A finished battle now has winners and losers set inside of `PokemonBattle` instead of them always being empty.
@@ -44,16 +176,41 @@
- Removed the NbtItemPredicate class, all the mod usages now use the vanilla item predicate solution, this causes breaking changes on Fossil, HeldItemRequirement & ItemInteractionEvolution
- 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.
### Changes
- When using the `cobblemon` or `generation_9` capture calculators a critical capture with a single shake will always play for successful captures when you've already registered the Pokémon as caught in your Pokédex.
- 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.
- 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`
- Added new item class, `WearableItem`. Instances of this class should have a corresponding 3D model. These models render when the items display context is `HEAD`.
- Pokemon now have a fireImmune attribute in their behaviour that can be set to true to ignore all fire damage (lava, magma blocks, etc.)
`JSON
{
"behaviour": {
"fireImmune": true
}
}
`
### 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
- The `itemCondition` for a held item evolution requirement
- The `fossils` for a fossil entry
- Added MoLang flows for `poke_ball_capture_calculated`, `evolution_tested`, `evolution_accepted`, `evolution_completed`
- Added `interpolate` boolean property to animated textures to allow gradual colour changes between frames.
- Fixed species additions not being capable of changing implemented status.
- Added support for action effects that are triggered by `|-activate|` Showdown instructions. `activate_{effect_id}` is the syntax.
- Added MoLang functions for rendering items `render_item(item_id, locator_name)` and `clear_items()`.
- Fixed location spawn filter components causing crashes
- Added `pokemon` as an available MoLang function for the `battleActor` functions.
- Added `spawn_pokemon` as an available MoLang function for the `worldHolder` functions.
- Added `attempt_wild_battle` as an available MoLang function.
- Added `pokemon` as an available Molang function for the `battleActor` functions.
- Fixed `heldItem` property inside spawn files not working and causing crashes
- Fixed `spawn_bedrock_particles` MoLang causing crashes when used in a server environment
- The Pokédex form lang key definition now follows `cobblemon.ui.pokedex.info.form.{species}-{formname}` instead of `cobblemon.ui.pokedex.info.form.{formname}`.
## [1.6.1 (January 26th, 2025)](#1-6-1)
@@ -159,6 +316,7 @@
- Geodude
- Graveler
- Golem
- Magnezone
### Cry updates for the following Pokémon
- Sceptile
+3 -2
View File
@@ -1,8 +1,9 @@
import utilities.isSnapshot
import utilities.version
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import utilities.isSnapshot
import utilities.version
/*
*
@@ -0,0 +1,24 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import net.minecraft.util.Mth;
import net.minecraft.util.SmoothDouble;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix3f;
import org.joml.Vector3f;
import java.util.function.Function;
public interface OrientationControllable {
OrientationController getOrientationController();
}
@@ -1,124 +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;
import net.minecraft.util.Mth;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix3f;
import org.joml.Vector3f;
import java.util.function.Function;
public interface Rollable {
// From Minecraft's Camera
Vector3f FORWARDS = new Vector3f(0.0F, 0.0F, -1.0F);
Vector3f UP = new Vector3f(0.0F, 1.0F, 0.0F);
Vector3f LEFT = new Vector3f(-1.0F, 0.0F, 0.0F);
@Nullable Matrix3f getOrientation();
Rollable updateOrientation(Function<Matrix3f, Matrix3f> update);
/**
* @return The forward vector (0, 0, -1) after the rotation matrix is applied.
*/
default Vector3f getForwardVector() {
if (getOrientation() == null) return new Vector3f(FORWARDS);
return getOrientation().transform(FORWARDS, new Vector3f());
}
/**
* @return The left vector (-1, 0, 0) after the rotation matrix is applied.
*/
default Vector3f getLeftVector() {
if (getOrientation() == null) return new Vector3f(LEFT);
return getOrientation().transform(LEFT, new Vector3f());
}
/**
* @return The up vector (0, 1, 0) after the rotation matrix is applied.
*/
default Vector3f getUpVector() {
if (getOrientation() == null) return new Vector3f(UP);
return getOrientation().transform(UP, new Vector3f());
}
/**
*
* @param yaw change in degrees
* @return The Rollable object this method was called on
*/
default Rollable rotateYaw(float yaw) {
return updateOrientation(prev -> prev.rotateY((float) Math.toRadians(-yaw)));
}
/**
*
* @param pitch change in degrees
* @return The Rollable object this method was called on
*/
default Rollable rotatePitch(float pitch) {
return updateOrientation(prev -> prev.rotateX((float) Math.toRadians(-pitch)));
}
/**
*
* @param roll change in degrees
* @return The Rollable object this method was called on
*/
default Rollable rotateRoll(float roll) {
return updateOrientation(prev -> prev.rotateZ((float) Math.toRadians(-roll)));
}
/**
* Order matters when rotating an object. If you need a different order, individually call rotateYaw, rotatePitch, and rotateRoll
*
* @param yaw change in degrees
* @param pitch change in degrees
* @param roll change in degrees
* @return The Rollable object this method was called on
*/
default Rollable rotate(float yaw, float pitch, float roll) {
return rotateYaw(yaw).rotatePitch(pitch).rotateRoll(roll);
}
/**
* @return The pitch angle in degrees as a float.
* Value is between [-180, 180] with 0 being South, 90 being West, 180/-180 being North, and -90 being East
*/
default float getYaw() {
return (float) Mth.wrapDegrees(-Math.toDegrees(FORWARDS.angleSigned(getForwardVector(), UP)) + 180);
}
/**
* @return The yaw angle in degrees as a float.
* Value is between [-90, 90] with 0 being straight forward, 90 being straight down, and -90 being straight up
*/
default float getPitch() {
return (float) Mth.wrapDegrees(-Math.toDegrees(Math.asin(getForwardVector().y)));
}
/**
* @return The roll angle in degrees as a float.
* Value is between [-180, 180] with 0 being no roll (normal), 90 being 90 degrees CW, 180/-180 being 180 degrees CW/CCW, and -90 being 90 degrees CCW
*/
default float getRoll() {
//Cobblemon.LOGGER.info("{}", (float) Math.toDegrees(getUpVector().angleSigned(UP, getForwardVector())));
return (float) Mth.wrapDegrees(-Math.toDegrees(getUpVector().angleSigned(UP, getForwardVector())));
}
boolean shouldRoll();
void clearRotation();
}
@@ -13,10 +13,12 @@ import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
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;
@@ -53,15 +55,19 @@ public class LambDynamicLightsCompat {
private static int resolvedPokemonLightLevel(PokemonEntity pokemon) {
var underwater = !pokemon.level().getFluidState(BlockPos.containing(pokemon.getX(), pokemon.getEyeY(), pokemon.getZ())).isEmpty();
return extractFormLightLevel(pokemon.getForm(), underwater).orElse(0);
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 resolvedShoulderLightLevel(Player player) {
final var shoulderDataPair = PokemonOnShoulderRenderer.shoulderDataOf(player);
var underwater = !player.level().getFluidState(BlockPos.containing(player.getX(), player.getEyeY(), player.getZ())).isEmpty();
final Optional<Integer> leftLightLevel = extractShoulderLightLevel(shoulderDataPair.getFirst(), underwater);
final Optional<Integer> rightLightLevel = extractShoulderLightLevel(shoulderDataPair.getSecond(), underwater);
return Math.max(leftLightLevel.orElse(0), rightLightLevel.orElse(0));
final int leftLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityLeft()), underwater);
final int rightLightLevel = extractShoulderLightLevel(PokemonOnShoulderRenderer.shoulderDataFrom(player.getShoulderEntityRight()), underwater);
return Math.max(leftLightLevel, rightLightLevel);
}
private static Optional<Integer> extractFormLightLevel(@NotNull FormData form, boolean underwater) {
@@ -71,11 +77,16 @@ public class LambDynamicLightsCompat {
return Optional.of(form.getLightingData().getLightLevel());
}
private static Optional<Integer> extractShoulderLightLevel(@Nullable PokemonOnShoulderRenderer.ShoulderData shoulderData, boolean underwater) {
private static int extractShoulderLightLevel(@Nullable PokemonOnShoulderRenderer.ShoulderData shoulderData, boolean underwater) {
if (shoulderData == null) {
return Optional.empty();
return 0;
}
return extractFormLightLevel(shoulderData.getForm(), underwater);
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 boolean liquidGlowModeSupport(@NotNull LightingData.LiquidGlowMode liquidGlowMode, boolean underwater) {
@@ -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.block.SaccharineLeafBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Desc;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(targets = "net.minecraft.world.entity.animal.Bee$BeeGrowCropGoal")
public abstract class BeeEntityMixin {
@Unique
private BlockState cobblemon$result = null;
@Inject(method = "tick()V", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/level/block/BonemealableBlock;performBonemeal(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/util/RandomSource;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V",
shift = At.Shift.BY,
by = 2
),
locals = LocalCapture.CAPTURE_FAILHARD
)
private void injectCustomGrowth(CallbackInfo ci, int i, BlockPos blockPos, BlockState blockState, Block block) {
if (block instanceof SaccharineLeafBlock) {
int age = blockState.getValue(SaccharineLeafBlock.Companion.getAGE());
if (age < 2) {
this.cobblemon$result = blockState.setValue(SaccharineLeafBlock.Companion.getAGE(), age + 1);
}
}
}
@ModifyVariable(method = "tick", at = @At(value = "LOAD", ordinal = 0), index = 5)
private BlockState applyCustomBlockState(BlockState before) {
if(this.cobblemon$result != null && before == null) {
BlockState result = this.cobblemon$result;
this.cobblemon$result = null;
return result;
}
return before;
}
}
@@ -0,0 +1,119 @@
/*
* 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.OrientationControllable;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import com.cobblemon.mod.common.api.riding.Seat;
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate;
import com.cobblemon.mod.common.client.render.MatrixWrapper;
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState;
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel;
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.mojang.authlib.GameProfile;
import net.minecraft.client.CameraType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.joml.Matrix3f;
import org.joml.Vector3f;
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.CallbackInfoReturnable;
import java.util.Map;
@Mixin(LocalPlayer.class)
public abstract class LocalPlayerMixin extends AbstractClientPlayer implements OrientationControllable {
@Shadow
private float jumpRidingScale;
public LocalPlayerMixin(ClientLevel clientLevel, GameProfile gameProfile) {
super(clientLevel, gameProfile);
}
@Inject(method = "getJumpRidingScale", at = @At("HEAD"), cancellable = true)
public void modifyJumpRidingScale(CallbackInfoReturnable<Float> cir) {
LocalPlayer player = (LocalPlayer) (Object) this;
if (player.isPassenger() && player.getVehicle() instanceof PokemonEntity pokemonEntity) {
var rideValue = pokemonEntity.<Float>ifRidingAvailableSupply(null, (behaviour, settings, state) -> {
if (behaviour.canJump(settings, state, pokemonEntity, player)) return null;
return behaviour.setRideBar(settings, state, pokemonEntity, player);
});
if (rideValue != null) {
cir.setReturnValue(rideValue);
}
}
}
@Override
public HitResult pick(double hitDistance, float partialTicks, boolean hitFluids) {
Entity vehicle = this.getVehicle();
if (vehicle instanceof PokemonEntity pokemonEntity) {
int seatIndex = pokemonEntity.getPassengers().indexOf(this);
Seat seat = pokemonEntity.getSeats().get(seatIndex);
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemonEntity.getDelegate();
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
if (locator == null) {
super.pick(hitDistance, partialTicks, hitFluids);
}
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
OrientationController controller = this.getOrientationController();
float currEyeHeight = this.getEyeHeight();
Vector3f offset = new Vector3f(new Vector3f(0f, currEyeHeight - (this.getBbHeight() / 2), 0f));
if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON) {
PosableModel model = VaryingModelRepository.INSTANCE.getPoser(pokemonEntity.getPokemon().getSpecies().getResourceIdentifier(), new FloatingState());
offset.add(cobblemon$getFirstPersonOffset(model, seat));
}
Matrix3f orientation = controller.isActive() && controller.getOrientation() != null ? controller.getOrientation() : new Matrix3f();
Vec3 rotatedEyeHeight = new Vec3(orientation.transform(offset));
Vec3 eyePosition = locatorOffset.add(pokemonEntity.position()).add(rotatedEyeHeight);
Vec3 viewVector = this.getViewVector(partialTicks);
Vec3 viewDistanceVector = eyePosition.add(viewVector.x * hitDistance, viewVector.y * hitDistance, viewVector.z * hitDistance);
return this.level()
.clip(
new ClipContext(
eyePosition, viewDistanceVector, ClipContext.Block.OUTLINE, hitFluids ? net.minecraft.world.level.ClipContext.Fluid.ANY : net.minecraft.world.level.ClipContext.Fluid.NONE, this
)
);
}
return super.pick(hitDistance, partialTicks, hitFluids);
}
@Unique
private static @NotNull Vector3f cobblemon$getFirstPersonOffset(PosableModel model, Seat seat) {
Map<String, Vec3> cameraOffsets = model.getFirstPersonCameraOffset();
if (cameraOffsets.containsKey(seat.getLocator())) {
return cameraOffsets.get(seat.getLocator()).toVector3f();
} else {
return new Vector3f(0f, 0f, 0f);
}
}
}
@@ -0,0 +1,30 @@
/*
* 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.platform.events.PlatformEvents;
import com.cobblemon.mod.common.platform.events.ServerPlayerEvent;
import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.server.PlayerAdvancements;
import net.minecraft.server.level.ServerPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerAdvancements.class)
public class PlayerAdvancementsMixin {
@Shadow private ServerPlayer player;
@Inject(method = "award", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementRewards;grant(Lnet/minecraft/server/level/ServerPlayer;)V"))
private void cobblemon$award(AdvancementHolder advancement, String criterionKey, CallbackInfoReturnable<Boolean> cir) {
PlatformEvents.SERVER_PLAYER_ADVANCEMENT_EARNED.emit(new ServerPlayerEvent.AdvancementEarned(player, advancement));
}
}
@@ -10,11 +10,11 @@ package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.CobblemonItems;
import com.cobblemon.mod.common.Rollable;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.api.events.CobblemonEvents;
import com.cobblemon.mod.common.api.events.item.LeftoversCreatedEvent;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies;
import com.cobblemon.mod.common.api.riding.Rideable;
import com.cobblemon.mod.common.api.storage.party.PartyStore;
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore;
import com.cobblemon.mod.common.api.tags.CobblemonItemTags;
@@ -31,25 +31,24 @@ import com.cobblemon.mod.common.util.DataKeys;
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.food.FoodProperties;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix3f;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@@ -58,15 +57,11 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.*;
import java.util.stream.Collectors;
@Mixin(Player.class)
public abstract class PlayerMixin extends LivingEntity implements Rollable, ScannableEntity {
public abstract class PlayerMixin extends LivingEntity implements ScannableEntity, OrientationControllable {
@Shadow public abstract CompoundTag getShoulderEntityLeft();
@@ -84,7 +79,10 @@ public abstract class PlayerMixin extends LivingEntity implements Rollable, Scan
@Shadow public abstract void displayClientMessage(Component message, boolean overlay);
@Unique private Matrix3f orientation = null;
@Shadow @Final private static Map<Pose, EntityDimensions> POSES;
@Shadow @Final public static EntityDimensions STANDING_DIMENSIONS;
@Unique
private final OrientationController cobblemon$orientationController = new OrientationController(this);
protected PlayerMixin(EntityType<? extends LivingEntity> p_20966_, Level p_20967_) {
super(p_20966_, p_20967_);
@@ -112,6 +110,19 @@ public abstract class PlayerMixin extends LivingEntity implements Rollable, Scan
}
}
@Inject(method = "tick", at = @At("HEAD"))
private void cobblemon$updateRenderOrientation(CallbackInfo ci) {
this.cobblemon$orientationController.tick();
}
@Override
public EntityDimensions getDefaultDimensions(Pose pose) {
if (this.getVehicle() instanceof PokemonEntity) {
return STANDING_DIMENSIONS;
}
return POSES.getOrDefault(pose, STANDING_DIMENSIONS);
}
@Inject(
method = "removeEntitiesOnShoulder",
at = @At(
@@ -238,7 +249,7 @@ public abstract class PlayerMixin extends LivingEntity implements Rollable, Scan
@Override
public void absMoveTo(double x, double y, double z, float yaw, float pitch) {
if (shouldRoll()) {
if (cobblemon$orientationController.getActive()) {
this.absMoveTo(x, y, z);
this.setYRot(yaw % 360.0f);
this.setXRot(pitch % 360.0f);
@@ -251,65 +262,21 @@ public abstract class PlayerMixin extends LivingEntity implements Rollable, Scan
}
}
@Inject(method = "tick", at = @At("HEAD"))
public void tick(CallbackInfo ci) {
if (this.shouldRoll()) {
// Proof of concept for yaw movement
if (this.getMainHandItem().is(Items.STICK)) {
this.rotateYaw(2);
}
else if (this.getMainHandItem().is(Items.BLAZE_ROD)) {
this.rotateYaw(-2);
}
}
}
@Override
public Matrix3f getOrientation() {
return orientation;
}
@Override
public Rollable updateOrientation(Function<Matrix3f, Matrix3f> update) {
if (!shouldRoll()) return this;
if (this.orientation == null) {
this.orientation = new Matrix3f();
this.rotate(getYRot() - 180, getXRot(), 0);
}
this.orientation = update.apply(this.orientation);
setYRot(this.getYaw());
setXRot(this.getPitch());
return this;
}
@Override
public boolean shouldRoll() {
LocalPlayer player = Minecraft.getInstance().player;
if (!this.equals(player)) return false;
if (player.isHolding(Items.DIAMOND)) return true;
var playerVehicle = player.getVehicle();
if (playerVehicle == null) return false;
if (!(playerVehicle instanceof PokemonEntity pokemonEntity)) return false;
return pokemonEntity.getRiding().shouldRoll(pokemonEntity);
}
@Override
public void clearRotation() {
this.orientation = null;
}
@WrapOperation(
method = "rideTick()V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;wantsToStopRiding()Z")
)
public boolean delegateDismountToController(Player instance, Operation<Boolean> original) {
if (this.getVehicle() instanceof Rideable vehicle) {
return vehicle.getRiding().dismountOnShift() && original.call(instance);
if (this.getVehicle() instanceof PokemonEntity pokemonEntity) {
return pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) -> {
return behaviour.dismountOnShift(settings, state, pokemonEntity) && original.call(instance);
});
}
return original.call(instance);
}
@Override
public OrientationController getOrientationController() {
return cobblemon$orientationController;
}
}
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin;
import net.minecraft.stats.RecipeBookSettings;
import net.minecraft.world.inventory.RecipeBookType;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
@Mixin(RecipeBookSettings.class)
public class RecipeBookSettingsMixin {
@Shadow @Final public Map<RecipeBookType, RecipeBookSettings.TypeSettings> states;
@Inject(method = "<init>", at = @At("TAIL"))
private void cobblemon$init(CallbackInfo ci) {
states.put(RecipeBookType.valueOf("COOKING_POT"), new RecipeBookSettings.TypeSettings(true, true));
}
}
@@ -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;
import net.minecraft.world.inventory.RecipeBookType;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.gen.Invoker;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.ArrayList;
import java.util.List;
@Mixin(value = RecipeBookType.class)
public class RecipeBookTypeMixin {
@Final
@Mutable
@Shadow
private static RecipeBookType[] $VALUES; // moj
@Invoker("<init>")
private static RecipeBookType cobblemon$createBookType(String name, int ordinal) {
throw new AssertionError();
}
@Inject(
method = "<clinit>",
at = @At("TAIL")
)
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
ArrayList<RecipeBookType> types = new ArrayList<>(List.of($VALUES));
types.add(cobblemon$createBookType("COOKING_POT", $VALUES.length));
$VALUES = types.toArray(RecipeBookType[]::new);
}
}
@@ -0,0 +1,101 @@
/*
* 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.CobblemonNetwork;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.api.net.NetworkPacket;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.mixin.accessor.ChunkMapAccessor;
import com.cobblemon.mod.common.mixin.accessor.TrackedEntityAccessor;
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateOrientationPacket;
import com.cobblemon.mod.common.net.messages.client.pokemon.update.ClientboundUpdateRidingStatePacket;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.network.protocol.Packet;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerEntity;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerPlayerConnection;
import net.minecraft.world.entity.Entity;
import org.joml.Matrix3f;
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.Set;
import java.util.function.Consumer;
@Mixin(ServerEntity.class)
public abstract class ServerEntityMixin {
@Shadow
@Final
private Consumer<Packet<?>> broadcast;
@Shadow
@Final
private Entity entity;
@Unique
private Matrix3f cobblemon$lastSentOrientation;
@Unique
private boolean cobblemon$lastSentActive;
@Inject(method = "sendChanges", at = @At("TAIL"))
private void cobblemon$sendChanges(CallbackInfo ci) {
cobblemon$sendOrientationChanges();
cobblemon$sendRidingStateChanges();
}
private void cobblemon$sendRidingStateChanges() {
if (!(this.entity instanceof PokemonEntity pokemonEntity)) return;
if (pokemonEntity.getRidingState() == null) return;
if (pokemonEntity.getRiding() == null) return;
var ridingBehaviour = pokemonEntity.getRiding();
var ridingState = pokemonEntity.getRidingState();
var previousRidingState = pokemonEntity.getPreviousRidingState();
if (previousRidingState != null && !ridingState.shouldSync(previousRidingState)) return;
cobblemon$broadcast(new ClientboundUpdateRidingStatePacket(pokemonEntity.getId(), ridingBehaviour.getKey(), pokemonEntity.getRidingState(), null));
}
private void cobblemon$sendOrientationChanges() {
if (!(this.entity instanceof OrientationControllable controllable)) return;
OrientationController controller = controllable.getOrientationController();
Matrix3f currOrientation = controller.getOrientation();
boolean currActive = controller.getActive();
if (currOrientation == null || currOrientation.equals(cobblemon$lastSentOrientation) && (currActive == cobblemon$lastSentActive))
return;
cobblemon$lastSentOrientation = new Matrix3f(currOrientation);
cobblemon$lastSentActive = currActive;
cobblemon$broadcast(new ClientboundUpdateOrientationPacket(currOrientation, currActive, entity.getId()));
}
private void cobblemon$broadcast(NetworkPacket<?> packet) {
if (!(entity.level() instanceof ServerLevel level)) return;
ChunkMap chunkMap = level.getChunkSource().chunkMap;
Int2ObjectMap<?> entityMap = ((ChunkMapAccessor) chunkMap).getEntityMap();
Object tracked = entityMap.get(entity.getId());
if (!(tracked instanceof TrackedEntityAccessor tracker)) return;
Set<ServerPlayerConnection> seenBy = tracker.getSeenBy();
for (ServerPlayerConnection conn : seenBy) {
ServerPlayer player = conn.getPlayer();
if (player == entity) continue;
CobblemonNetwork.INSTANCE.sendPacketToPlayer(player, packet);
}
}
}
@@ -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;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.server.level.ServerPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerPlayer.class)
public abstract class ServerPlayerMixin {
@Inject(method = "rideTick", at = @At("HEAD"))
private void cobblemon$updateOrientationControllerRideTick(CallbackInfo ci) {
if (!(this instanceof OrientationControllable controllable)) return;
var shouldUseCustomOrientation = cobblemon$shouldUseCustomOrientation((ServerPlayer)(Object)this);
controllable.getOrientationController().setActive(shouldUseCustomOrientation);
}
@Unique
private boolean cobblemon$shouldUseCustomOrientation(ServerPlayer player) {
var playerVehicle = player.getVehicle();
if (playerVehicle == null) return false;
if (!(playerVehicle instanceof PokemonEntity pokemonEntity)) return false;
return pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) -> {
return behaviour.shouldRoll(settings, state, pokemonEntity);
});
}
@Inject(method = "stopRiding", at = @At("HEAD"))
public void cobblemon$resetOrientationOnDismount(CallbackInfo ci) {
if (!(this instanceof OrientationControllable controllable)) return;
controllable.getOrientationController().setActive(false);
}
}
@@ -0,0 +1,20 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.accessor;
import net.minecraft.client.Camera;
import net.minecraft.world.level.BlockGetter;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(Camera.class)
public interface CameraAccessor {
@Accessor("level")
BlockGetter getLevel();
}
@@ -0,0 +1,20 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.accessor;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.server.level.ChunkMap;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ChunkMap.class)
public interface ChunkMapAccessor {
@Accessor("entityMap")
Int2ObjectMap<?> getEntityMap();
}
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.accessor;
import net.minecraft.client.gui.components.StateSwitchingButton;
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
import net.minecraft.network.chat.Component;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(RecipeBookComponent.class)
public interface RecipeBookComponentAccessor {
@Accessor("filterButton")
StateSwitchingButton getFilterButton();
}
@@ -0,0 +1,21 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.accessor;
import net.minecraft.server.network.ServerPlayerConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.Set;
@Mixin(targets = "net.minecraft.server.level.ChunkMap$TrackedEntity")
public interface TrackedEntityAccessor {
@Accessor("seenBy")
Set<ServerPlayerConnection> getSeenBy();
}
@@ -9,8 +9,10 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.client.CobblemonClient;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.player.LocalPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -30,5 +32,13 @@ public class AbstractClientPlayerMixin {
if (usageContext.getScanningGuiOpen()) {
cir.setReturnValue(usageContext.getFovMultiplier());
}
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());
}
}
}
@@ -8,17 +8,18 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.Rollable;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import com.cobblemon.mod.common.api.riding.Rideable;
import com.cobblemon.mod.common.api.riding.Seat;
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate;
import com.cobblemon.mod.common.client.render.MatrixWrapper;
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController;
import com.cobblemon.mod.common.client.render.camera.MountedCameraRenderer;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.Vec3;
import org.joml.Matrix3f;
@@ -34,8 +35,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Camera.class)
public abstract class CameraMixin {
@Shadow @Final private static float DEFAULT_CAMERA_DISTANCE;
@Shadow private Entity entity;
@Shadow @Final private Quaternionf rotation;
@Shadow @Final private Vector3f forwards;
@@ -44,108 +43,103 @@ public abstract class CameraMixin {
@Shadow private float xRot;
@Shadow private float yRot;
@Shadow public abstract float getXRot();
@Shadow public abstract float getYRot();
@Shadow private Vec3 position;
@Shadow private float eyeHeight;
@Shadow private float eyeHeightOld;
@Shadow protected abstract void setPosition(Vec3 pos);
@Unique private float returnTimer = 0;
@Unique private float rollAngleStart = 0;
@Unique Minecraft minecraft = Minecraft.getInstance();
@Unique boolean disableRollableCameraDebug = false;
@Inject(method = "setRotation", at = @At("HEAD"), cancellable = true)
public void open_camera$setRotation(float f, float g, CallbackInfo ci) {
if (!(this.entity instanceof Rollable rollable) || disableRollableCameraDebug) return;
if (!rollable.shouldRoll() && rollable.getOrientation() != null) {
public void cobblemon$setRotation(float f, float g, CallbackInfo ci) {
if (!(this.entity instanceof OrientationControllable controllable) || Cobblemon.config.getDisableRoll()) return;
var controller = controllable.getOrientationController();
if (!controller.isActive() && controller.getOrientation() != null) {
if(this.returnTimer < 1) {
//Rotation is taken from entity since we no longer handle mouse ourselves
//Stops a period of time when you can't input anything.
rollable.getOrientation().set(
controller.getOrientation().set(
new Matrix3f()
.rotateY((float) Math.toRadians(180 - this.entity.getYRot()))
.rotateX((float) Math.toRadians(-this.entity.getXRot()))
);
if(rollAngleStart == 0){
this.returnTimer = 1;
rollable.clearRotation();
controller.reset();
return;
}
rollable.getOrientation().rotateZ((float) Math.toRadians(-rollAngleStart*(1-returnTimer)));
applyRotation();
controller.getOrientation().rotateZ((float) Math.toRadians(-rollAngleStart*(1-returnTimer)));
cobblemon$applyRotation();
this.returnTimer += .05F;
ci.cancel();
} else {
this.returnTimer = 1;
rollable.clearRotation();
controller.reset();
}
return;
}
if (rollable.getOrientation() == null) return;
applyRotation();
if (controller.getOrientation() == null) return;
cobblemon$applyRotation();
this.returnTimer = 0;
this.rollAngleStart = rollable.getRoll();
this.rollAngleStart = controller.getRoll();
ci.cancel();
}
//If you want to move this to a delagate you need an AW for position
@WrapOperation(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setPosition(DDD)V"))
public void positionCamera(Camera instance, double x, double y, double z, Operation<Void> original){
public void cobblemon$positionCamera(Camera instance, double x, double y, double z, Operation<Void> original, @Local(ordinal = 1, argsOnly = true) boolean thirdPersonReverse) {
Entity entity = instance.getEntity();
Entity vehicle = entity.getVehicle();
MountedPokemonAnimationRenderController.INSTANCE.reset();
if(vehicle instanceof Rideable){
//RidingCameraDelagate.INSTANCE.positionCamera(instance, x, y, z, original);
if(!(vehicle instanceof PokemonEntity)){
original.call(instance, x, y, z);
return;
}
PokemonEntity pokemon = (PokemonEntity) vehicle;
int seatIndex = pokemon.getPassengers().indexOf(entity);
Seat seat = pokemon.getSeats().get(seatIndex);
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemon.getDelegate();
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
if(locator == null){
original.call(instance, x, y, z);
return;
}
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
Vec3 entityPos = new Vec3(
Mth.lerp(instance.getPartialTickTime(), pokemon.xOld, pokemon.getX()),
Mth.lerp(instance.getPartialTickTime(), pokemon.yOld, pokemon.getY()),
Mth.lerp(instance.getPartialTickTime(), pokemon.zOld, pokemon.getZ())
Vec3 position = MountedCameraRenderer.INSTANCE.getCameraPosition(
instance,
entity,
vehicle,
x,
y,
z,
thirdPersonReverse,
eyeHeightOld,
eyeHeight
);
Rollable rollable = (Rollable) entity;
float currEyeHeight = Mth.lerp(instance.getPartialTickTime(), eyeHeightOld, eyeHeight);
Matrix3f orientation = rollable.shouldRoll() && rollable.getOrientation() != null ? rollable.getOrientation() : new Matrix3f();
Vec3 rotatedEyeHeight = new Vec3(orientation.transform(new Vector3f(0f, currEyeHeight, 0f)));
position = locatorOffset.add(entityPos).add(rotatedEyeHeight);
} else {
original.call(instance, x, y, z);
if(position != null){
setPosition(position);
return;
}
}
original.call(instance, x, y, z);
}
@Unique
private void applyRotation(){
if (!(this.entity instanceof Rollable rollable) || rollable.getOrientation() == null) return;
var newRotation = rollable.getOrientation().normal(new Matrix3f()).getNormalizedRotation(new Quaternionf());
private void cobblemon$applyRotation(){
if (!(this.entity instanceof OrientationControllable controllable) || controllable.getOrientationController().getOrientation() == null) return;
var controller = controllable.getOrientationController();
var newRotation = controller.getOrientation().normal(new Matrix3f()).getNormalizedRotation(new Quaternionf());
if (this.minecraft.options.getCameraType().isMirrored()) {
newRotation.rotateY((float)Math.toRadians(180));
}
this.rotation.set(newRotation);
this.xRot = rollable.getPitch();
this.yRot = rollable.getYaw();
this.forwards.set(rollable.getForwardVector());
this.up.set(rollable.getUpVector());
this.left.set(rollable.getLeftVector());
this.xRot = controller.getPitch();
this.yRot = controller.getYaw();
OrientationController.Companion.getFORWARDS().rotate(this.rotation, this.forwards);
OrientationController.Companion.getUP().rotate(this.rotation, this.up);
OrientationController.Companion.getLEFT().rotate(this.rotation, this.left);
}
@WrapOperation(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;move(FFF)V", ordinal = 0))
public void stopMoveIfRolling(Camera instance, float zoom, float dy, float dx, Operation<Void> original) {
Entity entity = instance.getEntity();
Entity vehicle = entity.getVehicle();
if (!(vehicle instanceof PokemonEntity) || Cobblemon.config.getThirdPersonViewBobbing()) {
original.call(instance, zoom, dy, dx);
}
}
}
@@ -0,0 +1,85 @@
/*
* 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.CobblemonRecipeCategories;
import com.cobblemon.mod.common.item.crafting.CookingPotBookCategory;
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe;
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import net.minecraft.client.ClientRecipeBook;
import net.minecraft.client.RecipeBookCategories;
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
import java.util.Map;
@Mixin(ClientRecipeBook.class)
public abstract class ClientRecipeBookMixin {
@Shadow
protected static Map<RecipeBookCategories, List<List<RecipeHolder<?>>>> categorizeAndGroupRecipes(Iterable<RecipeHolder<?>> recipes) {
return null;
}
@Shadow private Map<RecipeBookCategories, List<RecipeCollection>> collectionsByTab;
@Shadow private List<RecipeCollection> allCollections;
@Inject(method = "getCategory", at = @At(value = "HEAD"), cancellable = true)
private static void addCustomCategory(RecipeHolder<?> recipe, CallbackInfoReturnable<RecipeBookCategories> cir) {
Recipe<?> recipe2 = recipe.value();
if (recipe2 instanceof CookingPotRecipe || recipe2 instanceof CookingPotShapelessRecipe) {
CookingPotBookCategory category = recipe2 instanceof CookingPotRecipe
? ((CookingPotRecipe) recipe2).getCategory()
: ((CookingPotShapelessRecipe) recipe2).category();
RecipeBookCategories var7;
switch (category) {
case MISC -> var7 = CobblemonRecipeCategories.COOKING_POT_MISC.toVanillaCategory();
case FOODS -> var7 = CobblemonRecipeCategories.COOKING_POT_FOODS.toVanillaCategory();
case MEDICINES -> var7 = CobblemonRecipeCategories.COOKING_POT_MEDICINES.toVanillaCategory();
case BAITS -> var7 = CobblemonRecipeCategories.COOKING_POT_BAITS.toVanillaCategory();
default -> throw new MatchException(null, null);
}
cir.setReturnValue(var7);
}
}
@Inject(method = "setupCollections", at = @At("RETURN"))
private void addCustomAggregateCategories(Iterable<RecipeHolder<?>> recipes, RegistryAccess registryAccess, CallbackInfo ci) {
Map<RecipeBookCategories, List<List<RecipeHolder<?>>>> map = categorizeAndGroupRecipes(recipes);
Map<RecipeBookCategories, List<RecipeCollection>> map2 = Maps.newHashMap();
ImmutableList.Builder<RecipeCollection> builder = ImmutableList.builder();
map.forEach((recipeBookCategories, list) -> {
List<RecipeCollection> collections = list.stream()
.map(listx -> new RecipeCollection(registryAccess, listx))
.peek(builder::add)
.collect(ImmutableList.toImmutableList());
map2.put(recipeBookCategories, collections);
});
RecipeBookCategories.AGGREGATE_CATEGORIES.forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List)list.stream().flatMap((recipeBookCategoriesx) -> ((List)map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
CobblemonRecipeCategories.Companion.getCustomAggregateCategories().forEach((recipeBookCategories, list) -> map2.put(recipeBookCategories, (List)list.stream().flatMap((recipeBookCategoriesx) -> ((List)map2.getOrDefault(recipeBookCategoriesx, ImmutableList.of())).stream()).collect(ImmutableList.toImmutableList())));
this.collectionsByTab = ImmutableMap.copyOf(map2);
this.allCollections = builder.build();
}
}
@@ -9,10 +9,20 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.api.scheduling.ClientTaskTracker;
import com.cobblemon.mod.common.stadium.BattleCameraManagerClient;
import com.cobblemon.mod.common.util.CameraExtensionsKt;
import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.world.entity.Entity;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
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;
@@ -20,6 +30,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(GameRenderer.class)
public class GameRendererMixin {
@Shadow @Final Minecraft minecraft;
@Shadow float renderDistance;
@Shadow @Final private LightTexture lightTexture;
@Shadow private boolean renderHand;
@Shadow private double getFov(Camera activeRenderInfo, float partialTicks, boolean useFOVSetting) { return 0.0; }
@Shadow public void resetProjectionMatrix(Matrix4f matrix) {}
@Shadow public Matrix4f getProjectionMatrix(double fov) { return new Matrix4f(); }
@Shadow private void renderItemInHand(Camera camera, float partialTick, Matrix4f projectionMatrix) {}
@Shadow public void pick(float partialTicks) {}
@Unique
long lastTime = -1;
@@ -42,4 +63,44 @@ public class GameRendererMixin {
lastTime = newTime;
}
@Inject(method = "renderLevel", at = @At(value = "HEAD"), cancellable = true)
public void renderLevel(DeltaTracker deltaTracker, CallbackInfo ci) {
if (BattleCameraManagerClient.INSTANCE.shouldUseStadiumCamera()) {
float f = deltaTracker.getGameTimeDeltaPartialTick(true);
this.lightTexture.updateLightTexture(f);
if (this.minecraft.getCameraEntity() == null) {
this.minecraft.setCameraEntity(this.minecraft.player);
}
this.minecraft.getProfiler().push("camera");
Camera stadiumCamera = new Camera();
Entity entity = (Entity) this.minecraft.player;
stadiumCamera.setup(this.minecraft.level, entity, true, false, 1.0F);
//adjust camera
BattleCameraManagerClient.INSTANCE.updateCameraData(f);
stadiumCamera.setPosition(BattleCameraManagerClient.INSTANCE.getCameraPosition());
Vector3f rotations = BattleCameraManagerClient.INSTANCE.getCameraRotation();
CameraExtensionsKt.setRotation(stadiumCamera, rotations.x, rotations.y, rotations.z);
this.renderDistance = (float)(this.minecraft.options.getEffectiveRenderDistance() * 16);
double d = this.getFov(stadiumCamera, f, true);
Matrix4f matrix4f = this.getProjectionMatrix(d);
this.resetProjectionMatrix(matrix4f);
Quaternionf quaternionf = stadiumCamera.rotation().conjugate(new Quaternionf());
Matrix4f matrix4f2 = (new Matrix4f()).rotation(quaternionf);
this.minecraft.levelRenderer.prepareCullFrustum(stadiumCamera.getPosition(), matrix4f2, this.getProjectionMatrix(Math.max(d, (double)(Integer)this.minecraft.options.fov().get())));
this.minecraft.levelRenderer.renderLevel(deltaTracker, false, stadiumCamera, (GameRenderer) (Object) this, this.lightTexture, matrix4f2, matrix4f);
this.minecraft.getProfiler().pop();
ci.cancel();
}
}
@Inject(method = "tick", at = @At(value = "TAIL"))
public void tick(CallbackInfo ci) {
BattleCameraManagerClient.INSTANCE.tickCameraManager();
}
}
@@ -59,8 +59,21 @@ public class HumanoidModelMixin {
}
Entity vehicle = entity.getVehicle();
if (vehicle instanceof PokemonEntity && entity instanceof AbstractClientPlayer) {
MountedPlayerRenderer.INSTANCE.animate((PokemonEntity) vehicle, (AbstractClientPlayer) entity, relevantPartsByName, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
if (vehicle instanceof PokemonEntity pokemonEntity && entity instanceof AbstractClientPlayer) {
var shouldRotatePlayerHead = pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) -> {
return behaviour.shouldRotatePlayerHead(settings, state, pokemonEntity);
});
if (!shouldRotatePlayerHead) {
netHeadYaw = 0f;
headPitch = 0f;
if (this.head != null) {
this.head.yRot = 0f;
this.head.xRot = 0f;
}
}
MountedPlayerRenderer.INSTANCE.animate(pokemonEntity, (AbstractClientPlayer) entity, relevantPartsByName, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
}
}
}
@@ -8,7 +8,7 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.Rollable;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.item.PokedexItem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
@@ -31,14 +31,14 @@ public class ItemInHandRendererMixin {
if (abstractClientPlayer.isUsingItem() && abstractClientPlayer.getUseItem().getItem() instanceof PokedexItem) {
ci.cancel();
}
else if (abstractClientPlayer instanceof Rollable rollable && rollable.shouldRoll()) {
else if (abstractClientPlayer instanceof OrientationControllable controllable && controllable.getOrientationController().isActive()) {
}
}
@Redirect(method = "renderHandsWithItems", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/PoseStack;mulPose(Lorg/joml/Quaternionf;)V", ordinal = 1))
private void cobblemon$renderHandswithItems(PoseStack instance, Quaternionf quaternion) {
if (!(Minecraft.getInstance().player instanceof Rollable rollable && rollable.shouldRoll())) {
if (!(Minecraft.getInstance().player instanceof OrientationControllable controllable && controllable.getOrientationController().isActive())) {
instance.mulPose(quaternion);
}
}
@@ -12,6 +12,7 @@ import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.ModAPI;
import com.cobblemon.mod.common.item.PokeBallItem;
import com.cobblemon.mod.common.item.PokedexItem;
import com.cobblemon.mod.common.item.WearableItem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.ItemModelShaper;
@@ -54,17 +55,18 @@ public abstract class ItemRendererMixin {
)
private void cobblemon$overrideItemModel(ItemStack stack, ItemDisplayContext renderMode, boolean leftHanded, PoseStack matrices, MultiBufferSource multiBufferSource, int light, int overlay, BakedModel model, CallbackInfo ci) {
boolean shouldBe2d = renderMode == ItemDisplayContext.GUI || renderMode == ItemDisplayContext.FIXED;
ResourceLocation resourceLocation = null;
if (shouldBe2d) {
ResourceLocation resourceLocation = null;
if (stack.getItem() instanceof PokeBallItem pokeBallItem) resourceLocation = pokeBallItem.getPokeBall().getModel2d();
else if (stack.getItem() instanceof PokedexItem pokedexItem) resourceLocation = pokedexItem.getType().getItemSpritePath();
}
if (renderMode != ItemDisplayContext.HEAD && stack.getItem() instanceof WearableItem wearableItem) resourceLocation = wearableItem.getModel2d();
if (resourceLocation != null) {
BakedModel replacementModel = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(resourceLocation, "inventory"));
if (!cobblemon$isSameModel(model, replacementModel)) {
ci.cancel();
render(stack, renderMode, leftHanded, matrices, multiBufferSource, light, overlay, replacementModel);
}
if (resourceLocation != null) {
BakedModel replacementModel = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(resourceLocation, "inventory"));
if (!cobblemon$isSameModel(model, replacementModel)) {
ci.cancel();
render(stack, renderMode, leftHanded, matrices, multiBufferSource, light, overlay, replacementModel);
}
}
}
@@ -78,6 +80,7 @@ public abstract class ItemRendererMixin {
boolean canOpenScreen = entity != null && ((entity.getOffhandItem() == stack && !(entity.getMainHandItem().getItem() instanceof PokedexItem)) || entity.getMainHandItem() == stack);
resourceLocation = pokedexItem.getType().getItemModelPath(isScanModel ? "scanning" : (canOpenScreen ? null : "off"));
}
else if (stack.getItem() instanceof WearableItem wearableItem) resourceLocation = wearableItem.getModel3d();
if (resourceLocation != null) {
BakedModel model = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(resourceLocation, MODEL_PATH));
@@ -9,9 +9,14 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.CobblemonNetwork;
import com.cobblemon.mod.common.Rollable;
import com.cobblemon.mod.common.net.messages.server.orientation.C2SUpdateOrientationPacket;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.net.messages.server.orientation.ServerboundUpdateOrientationPacket;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import org.joml.Matrix3f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@@ -20,24 +25,55 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LocalPlayer.class)
public class LocalPlayerMixin {
public abstract class LocalPlayerMixin extends LivingEntity {
@Unique Matrix3f cobblemon$lastOrientation;
@Inject(method = "sendPosition", at = @At("TAIL"))
private void cobblemon_updateRotationMatrix(CallbackInfo ci) {
if (!(this instanceof Rollable rollable)) return;
if (rollable.getOrientation() == cobblemon$lastOrientation) return;
cobblemon$lastOrientation = rollable.getOrientation() != null ? new Matrix3f(rollable.getOrientation()) : null;
CobblemonNetwork.INSTANCE.sendToServer(new C2SUpdateOrientationPacket(rollable.getOrientation()));
protected LocalPlayerMixin(EntityType<? extends LivingEntity> entityType, Level level) {
super(entityType, level);
}
// @Inject(method = "sendPosition", at = @At("TAIL"))
// private void cobblemon$updateRotationMatrix(CallbackInfo ci) {
// if (!(this instanceof OrientationControllable controllable)) return;
// var controller = controllable.getOrientationController();
// if (!controller.isActive() || controller.getOrientation() == cobblemon$lastOrientation) return;
// cobblemon$lastOrientation = controller.getOrientation() != null ? new Matrix3f(controller.getOrientation()) : null;
// CobblemonNetwork.INSTANCE.sendToServer(new ServerboundUpdateOrientationPacket(controller.getOrientation()));
// }
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/ClientPacketListener;send(Lnet/minecraft/network/protocol/Packet;)V"))
private void cobblemon_updateRotationMatrixPassenger(CallbackInfo ci) {
if (!(this instanceof Rollable rollable)) return;
if (rollable.getOrientation() == cobblemon$lastOrientation) return;
cobblemon$lastOrientation = rollable.getOrientation() != null ? new Matrix3f(rollable.getOrientation()) : null;
CobblemonNetwork.INSTANCE.sendToServer(new C2SUpdateOrientationPacket(rollable.getOrientation()));
private void cobblemon$updateRotationMatrixPassenger(CallbackInfo ci) {
if (!(this instanceof OrientationControllable controllable)) return;
var controller = controllable.getOrientationController();
if (!controller.isActive() || controller.getOrientation() == cobblemon$lastOrientation) return;
cobblemon$lastOrientation = controller.getOrientation() != null ? new Matrix3f(controller.getOrientation()) : null;
CobblemonNetwork.INSTANCE.sendToServer(new ServerboundUpdateOrientationPacket(controller.getOrientation()));
}
@Inject(method = "rideTick", at = @At("HEAD"))
private void cobblemon$updateOrientationControllerRideTick(CallbackInfo ci) {
if (Minecraft.getInstance().player != (Object)this) return;
if (!(this instanceof OrientationControllable controllable)) return;
var shouldUseCustomOrientation = cobblemon$shouldUseCustomOrientation((LocalPlayer)(Object)this);
controllable.getOrientationController().setActive(shouldUseCustomOrientation);
}
@Unique
private boolean cobblemon$shouldUseCustomOrientation(LocalPlayer player) {
var playerVehicle = player.getVehicle();
if (playerVehicle == null) return false;
if (!(playerVehicle instanceof PokemonEntity pokemonEntity)) return false;
return pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) -> {
return behaviour.shouldRoll(settings, state, pokemonEntity);
});
}
@Override
public void stopRiding() {
super.stopRiding();
if (Minecraft.getInstance().player != (Object)this) return;
if (!(this instanceof OrientationControllable controllable)) return;
controllable.getOrientationController().setActive(false);
}
}
@@ -8,17 +8,20 @@
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.Rollable;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.client.CobblemonClient;
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.Blaze3D;
import net.minecraft.client.Minecraft;
import net.minecraft.client.MouseHandler;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.util.Mth;
import net.minecraft.util.SmoothDouble;
import net.minecraft.world.phys.Vec3;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@@ -27,14 +30,18 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(MouseHandler.class)
public class MouseHandlerMixin {
public abstract class MouseHandlerMixin {
@Shadow private double accumulatedScrollY;
@Shadow @Final private Minecraft minecraft;
@Unique SmoothDouble xMouseSmoother = new SmoothDouble();
@Unique SmoothDouble yMouseSmoother = new SmoothDouble();
@Unique SmoothDouble pitchSmoother = new SmoothDouble();
@Unique SmoothDouble rollSmoother = new SmoothDouble();
@Unique SmoothDouble yawSmoother = new SmoothDouble();
@Shadow @Final private SmoothDouble smoothTurnY;
@@ -44,6 +51,14 @@ public class MouseHandlerMixin {
@Shadow private double accumulatedDY;
@Shadow private double lastHandleMovementTime;
@Shadow public abstract boolean isMouseGrabbed();
@Shadow protected abstract void turnPlayer(double movementTime);
@Unique private double cobblemon$timeDelta;
@Inject(
method = "onScroll",
at = @At(
@@ -95,7 +110,13 @@ public class MouseHandlerMixin {
target = "Lnet/minecraft/client/player/LocalPlayer;turn(DD)V"
)
)
public boolean cobblemon$modifyRotation(LocalPlayer player, double cursorDeltaX, double cursorDeltaY, @Local(argsOnly = true) double d) {
public boolean cobblemon$modifyRotation(
LocalPlayer player,
double cursorDeltaX,
double cursorDeltaY,
@Local(argsOnly = true) double d,
@Local(argsOnly = true) double movementTime
) {
PokedexUsageContext usageContext = CobblemonClient.INSTANCE.getPokedexUsageContext();
if (usageContext.getScanningGuiOpen()) {
this.smoothTurnY.reset();
@@ -108,29 +129,121 @@ public class MouseHandlerMixin {
return false;
}
if (!(player instanceof Rollable rollable)) return true;
if (!rollable.shouldRoll()) {
if (!(player instanceof OrientationControllable controllable)) return true;
if (!controllable.getOrientationController().isActive()) {
xMouseSmoother.reset();
yMouseSmoother.reset();
pitchSmoother.reset();
rollSmoother.reset();
yawSmoother.reset();
return true;
}
var pitch = pitchSmoother.getNewDeltaValue(cursorDeltaY * 0.15f, d);
var roll = rollSmoother.getNewDeltaValue(cursorDeltaX * 0.15f, d);
rollable.rotate(0.0F, (float)pitch, (float)roll);
//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.
controllable.getOrientationController().rotate(
(float) angVecMouse.x,
(float) angVecMouse.y,
(float) angVecMouse.z
);
//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())
{
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
{
controllable.getOrientationController().rotate((float) (angRot.x * 10 * d), (float) (angRot.y * 10 * d), (float) (angRot.z * 10 * d));
}
return false;
}
@Inject(method = "handleAccumulatedMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MouseHandler;isMouseGrabbed()Z", ordinal = 0))
private void cobblemon$maintainMovementWhenInScreens(CallbackInfo ci, @Local(ordinal = 1) double e) {
if (minecraft.player == null) return;
if (!(minecraft.player instanceof Rollable rollable)) return;
if (!rollable.shouldRoll()) return;
if (minecraft.isPaused()) return;
@Inject(method = "handleAccumulatedMovement", at = @At("HEAD"))
private void cobblemon$maintainMovementWhenInScreens2(CallbackInfo ci) {
double time = Blaze3D.getTime();
cobblemon$timeDelta = time - this.lastHandleMovementTime;
}
var pitch = pitchSmoother.getNewDeltaValue(0, e);
var roll = rollSmoother.getNewDeltaValue(0, e);
rollable.rotate(0.0F, (float)pitch, (float)roll);
@Inject(method = "handleAccumulatedMovement", at = @At("TAIL"))
private void cobblemon$maintainMovementWhenInScreens(CallbackInfo ci) {
if (minecraft.player == null) return;
if (!(minecraft.player instanceof OrientationControllable controllable)) return;
if (!controllable.getOrientationController().isActive()) return;
if (minecraft.isPaused()) return;
if (isMouseGrabbed()) return;
this.turnPlayer(cobblemon$timeDelta);
}
@Unique
private Vec3 cobblemon$getAngularVelocity(double deltaTime) {
var player = minecraft.player;
if (player == null) return Vec3.ZERO;
if (!(player instanceof OrientationControllable)) return Vec3.ZERO;
var playerVehicle = player.getVehicle();
if (playerVehicle == null) return Vec3.ZERO;
if (!(playerVehicle instanceof PokemonEntity pokemonEntity)) return Vec3.ZERO;
return pokemonEntity.ifRidingAvailableSupply(Vec3.ZERO, (behaviour, settings, state) -> {
return behaviour.angRollVel(settings, state, pokemonEntity, player, deltaTime);
});
}
@Unique
private Vec3 cobblemon$getRideMouseRotation(double mouseX, double mouseY, double deltaTime) {
var player = minecraft.player;
if (player == null) return Vec3.ZERO;
var vehicle = player.getVehicle();
if (vehicle == null) return Vec3.ZERO;
if (!(vehicle instanceof PokemonEntity pokemonEntity)) return Vec3.ZERO;
var sensitivity = cobblemon$getRidingSensitivity();
return pokemonEntity.ifRidingAvailableSupply(Vec3.ZERO, (behaviour, settings, state) -> {
return behaviour.rotationOnMouseXY(
settings,
state,
pokemonEntity,
player,
mouseY,
mouseX,
yMouseSmoother,
xMouseSmoother,
sensitivity,
deltaTime
);
});
}
@Unique
private double cobblemon$getRidingSensitivity() {
var sensitivity = this.minecraft.options.sensitivity().get() * 0.6000000238418579 + 0.20000000298023224;
return Math.pow(sensitivity, 3);
}
@Unique
private boolean cobblemon$shouldUseAngVelSmoothing() {
var player = minecraft.player;
if (player == null) return true;
var playerVehicle = player.getVehicle();
if (playerVehicle == null) return true;
if (!(playerVehicle instanceof PokemonEntity pokemonEntity)) return true;
return pokemonEntity.ifRidingAvailableSupply(true, (behaviour, settings, state) -> {
return behaviour.useAngVelSmoothing(settings, state, pokemonEntity);
});
}
}
@@ -1,36 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.api.riding.Rideable;
import com.cobblemon.mod.common.api.riding.RidingManager;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
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(PlayerModel.class)
public class PlayerModelMixin {
@Inject(method = "setupAnim(Lnet/minecraft/world/entity/LivingEntity;FFFFF)V", at = @At(value = "HEAD"))
private void cobblemon$setHeadRotation(LivingEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, CallbackInfo ci){
if (!(entity instanceof Player)) return;
Entity vehicle = entity.getVehicle();
if (!(vehicle instanceof PokemonEntity)) return;
RidingManager ridingManager = ((Rideable) vehicle).getRiding();
if (ridingManager.shouldRotatePlayerHead((PokemonEntity) vehicle)) return;
netHeadYaw = 0f;
headPitch = 0f;
}
}
@@ -11,9 +11,15 @@ package com.cobblemon.mod.common.mixin.client;
import com.cobblemon.mod.common.client.render.ClientPlayerIcon;
import com.cobblemon.mod.common.client.render.player.MountedPlayerRenderer;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.model.EntityModel;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
@@ -23,12 +29,33 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PlayerRenderer.class)
public class PlayerRendererMixin {
public abstract class PlayerRendererMixin extends LivingEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> {
public PlayerRendererMixin(EntityRendererProvider.Context context, PlayerModel<AbstractClientPlayer> model, float shadowRadius) {
super(context, model, shadowRadius);
}
@Inject(method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", at = @At(value = "TAIL"))
public void cobblemon$clientPlayerIcon(LivingEntity entity, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight, CallbackInfo ci) {
ClientPlayerIcon.Companion.onRenderPlayer((Player) entity);
}
@WrapOperation(method = "getRenderOffset(Lnet/minecraft/client/player/AbstractClientPlayer;F)Lnet/minecraft/world/phys/Vec3;", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;isCrouching()Z"))
private boolean cobblemon$disableCrouchOffset(AbstractClientPlayer instance, Operation<Boolean> original) {
if (instance.isPassenger() && instance.getVehicle() instanceof PokemonEntity) {
return false;
}
return original.call(instance);
}
@Inject(method = "setModelProperties", at = @At("TAIL"))
private void cobblemon$setModelProperties(AbstractClientPlayer player, CallbackInfo ci) {
if (player.isPassenger() && player.getVehicle() instanceof PokemonEntity) {
PlayerModel<AbstractClientPlayer> playerModel = this.getModel();
playerModel.crouching = false;
}
}
@Inject(
method = "setupRotations(Lnet/minecraft/client/player/AbstractClientPlayer;Lcom/mojang/blaze3d/vertex/PoseStack;FFFF)V",
at = @At("HEAD")
@@ -0,0 +1,73 @@
/*
* 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.CobblemonItems;
import com.cobblemon.mod.common.CobblemonRecipeCategories;
import com.google.common.collect.ImmutableList;
import net.minecraft.client.RecipeBookCategories;
import net.minecraft.world.inventory.RecipeBookType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.gen.Invoker;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.ArrayList;
import java.util.List;
@Mixin(RecipeBookCategories.class)
public class RecipeBookCategoriesMixin {
@Final
@Mutable
@Shadow
private static RecipeBookCategories[] $VALUES;
@Invoker("<init>")
private static RecipeBookCategories cobblemon$createCategory(String name, int ordinal, ItemStack... icons) {
throw new AssertionError();
}
@Inject(
method = "<clinit>",
at = @At("TAIL")
)
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
ArrayList<RecipeBookCategories> types = new ArrayList<>(List.of($VALUES));
types.add(cobblemon$createCategory("COOKING_POT_SEARCH", $VALUES.length, new ItemStack(Items.COMPASS)));
types.add(cobblemon$createCategory("COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.ROASTED_LEEK)));
types.add(cobblemon$createCategory("COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.HP_UP)));
types.add(cobblemon$createCategory("COOKING_POT_BAITS", $VALUES.length + 3, new ItemStack(CobblemonItems.PERSIM_BERRY)));
types.add(cobblemon$createCategory("COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.MIRROR_HERB)));
$VALUES = types.toArray(RecipeBookCategories[]::new);
}
@Inject(method = "getCategories", at = @At("HEAD"), cancellable = true)
private static void modifyCategories(RecipeBookType recipeBookType, CallbackInfoReturnable<List<RecipeBookCategories>> cir) {
if (recipeBookType == RecipeBookType.valueOf("COOKING_POT")) {
List var10000 = ImmutableList.of(
CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory(),
CobblemonRecipeCategories.COOKING_POT_FOODS.toVanillaCategory(),
CobblemonRecipeCategories.COOKING_POT_MEDICINES.toVanillaCategory(),
CobblemonRecipeCategories.COOKING_POT_BAITS.toVanillaCategory(),
CobblemonRecipeCategories.COOKING_POT_MISC.toVanillaCategory());
cir.setReturnValue(var10000);
return;
}
}
}
@@ -0,0 +1,63 @@
/*
* 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.CobblemonRecipeCategories;
import net.minecraft.client.ClientRecipeBook;
import net.minecraft.client.Minecraft;
import net.minecraft.client.RecipeBookCategories;
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
import net.minecraft.client.gui.screens.recipebook.RecipeBookPage;
import net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(RecipeBookComponent.class)
public class RecipeBookComponentMixin {
@Shadow private ClientRecipeBook book;
@Shadow protected Minecraft minecraft;
@Shadow private int width;
@Shadow private int xOffset;
@Shadow private int height;
@Shadow @Final private RecipeBookPage recipeBookPage;
@Inject(method = "updateTabs", at = @At("HEAD"), cancellable = true)
private void customUpdateTabs(CallbackInfo ci) {
RecipeBookComponent instance = (RecipeBookComponent) (Object) this;
int i = (width - 147) / 2 - xOffset - 30;
int j = (height - 166) / 2 + 3;
int k = 27;
int l = 0;
for (RecipeBookTabButton recipeBookTabButton : instance.tabButtons) {
RecipeBookCategories recipeBookCategories = recipeBookTabButton.getCategory();
if (recipeBookCategories != RecipeBookCategories.CRAFTING_SEARCH && recipeBookCategories != RecipeBookCategories.FURNACE_SEARCH && recipeBookCategories != CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory()) {
if (recipeBookTabButton.updateVisibility(book)) {
recipeBookTabButton.setPosition(i, j + 27 * l++);
recipeBookTabButton.startAnimation(minecraft);
}
} else {
recipeBookTabButton.visible = true;
recipeBookTabButton.setPosition(i, j + k * l++);
}
}
ci.cancel();
}
}
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.mixin.client;
import net.minecraft.client.ClientRecipeBook;
import net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton;
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(RecipeBookTabButton.class)
public class RecipeBookTabButtonMixin {
@Inject(method = "updateVisibility", at = @At("HEAD"), cancellable = true)
private void customUpdateVisibility(ClientRecipeBook recipeBook, CallbackInfoReturnable<Boolean> cir) {
RecipeBookTabButton instance = (RecipeBookTabButton) (Object) this;
List<RecipeCollection> list = recipeBook.getCollection(instance.getCategory());
boolean visible = false;
if (list != null) {
for (RecipeCollection recipeCollection : list) {
if (recipeCollection.hasKnownRecipes() && recipeCollection.hasFitting()) {
visible = true;
break;
}
}
}
instance.visible = visible;
cir.setReturnValue(visible);
}
}
@@ -0,0 +1,53 @@
/*
* 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 net.minecraft.client.gui.screens.recipebook.RecipeCollection;
import net.minecraft.stats.RecipeBook;
import net.minecraft.world.entity.player.StackedContents;
import net.minecraft.world.item.crafting.RecipeHolder;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
import java.util.Set;
@Mixin(RecipeCollection.class)
public class RecipeCollectionMixin {
@Shadow @Final private Set<RecipeHolder<?>> fitsDimensions;
@Shadow @Final private Set<RecipeHolder<?>> craftable;
@Shadow @Final private List<RecipeHolder<?>> recipes;
@Inject(method = "canCraft", at = @At("HEAD"), cancellable = true)
private void customCanCraft(StackedContents handler, int width, int height, RecipeBook book, CallbackInfo ci) {
for (RecipeHolder<?> recipeHolder : recipes) {
boolean bl = recipeHolder.value().canCraftInDimensions(width, height) && book.contains(recipeHolder);
if (bl) {
fitsDimensions.add(recipeHolder);
} else {
fitsDimensions.remove(recipeHolder);
}
if (bl && handler.canCraft(recipeHolder.value(), null)) {
craftable.add(recipeHolder);
} else {
craftable.remove(recipeHolder);
}
}
ci.cancel();
}
}
@@ -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.TextClipping;
import net.minecraft.client.gui.Font;
import net.minecraft.network.chat.Style;
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;
/**
* This mixin facilitates the gradual reveal of text with NPC dialogue. If there is a better way
* to do this, I'd love to hear it.
*
* The idea is that somewhere static in the mod we have a control for how many characters can be drawn
* and how many have been drawn so far, and this mixin will add to the latter and stop drawing characters
* once it reaches the former.
*
* This relies STRONGLY on the code that sets the character cap to reset it to -1 after the text is rendered,
* otherwise all text in Minecraft will stop drawing.
*
* Sites that take advantage of this mixin will do the following:
* 1: Set the character cap, which resets the drawn counter to zero.
* 2: Call whatever Minecraft function draws your text.
* 3: Reset the character cap to -1, which will allow regular text to draw again.
*
* @author Hiroku
* @since April 18th, 2025
*/
@Mixin(Font.StringRenderOutput.class)
public class StringRenderOutputMixin {
@Inject(method = "accept", at = @At(value = "HEAD"), cancellable = true)
public void onAccept(int i, Style style, int j, CallbackInfoReturnable<Boolean> cir) {
if (!TextClipping.canDrawAnotherCharacter()) {
cir.setReturnValue(true);
}
}
}
@@ -19,6 +19,7 @@ import com.cobblemon.mod.common.api.drop.ItemDropEntry
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.CobblemonEvents.DATA_SYNCHRONIZED
import com.cobblemon.mod.common.api.interaction.RequestManager
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.permission.PermissionValidator
import com.cobblemon.mod.common.api.pokeball.catching.calculators.CaptureCalculator
import com.cobblemon.mod.common.api.pokeball.catching.calculators.CaptureCalculators
@@ -62,7 +63,11 @@ import com.cobblemon.mod.common.api.storage.player.adapter.PlayerDataMongoBacken
import com.cobblemon.mod.common.api.storage.player.factory.CachedPlayerDataStoreFactory
import com.cobblemon.mod.common.api.tags.CobblemonEntityTypeTags
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.battles.*
import com.cobblemon.mod.common.battles.BagItems
import com.cobblemon.mod.common.battles.BattleFormat
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.BattleSide
import com.cobblemon.mod.common.battles.ShowdownThread
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.client.CobblemonPack
@@ -86,11 +91,23 @@ import com.cobblemon.mod.common.pokemon.aspects.SHINY_ASPECT
import com.cobblemon.mod.common.pokemon.evolution.variants.BlockClickEvolution
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
import com.cobblemon.mod.common.pokemon.properties.*
import com.cobblemon.mod.common.pokemon.properties.AspectPropertyType
import com.cobblemon.mod.common.pokemon.properties.BattleCloneProperty
import com.cobblemon.mod.common.pokemon.properties.FreezeFrameProperty
import com.cobblemon.mod.common.pokemon.properties.HiddenAbilityPropertyType
import com.cobblemon.mod.common.pokemon.properties.NoAIProperty
import com.cobblemon.mod.common.pokemon.properties.UnaspectPropertyType
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.ifDedicatedServer
import com.cobblemon.mod.common.util.isLaterVersion
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.requestWallpapers
import com.cobblemon.mod.common.util.server
import com.cobblemon.mod.common.world.feature.CobblemonPlacedFeatures
import com.cobblemon.mod.common.world.feature.ore.CobblemonOrePlacedFeatures
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
@@ -98,27 +115,30 @@ import com.mongodb.ConnectionString
import com.mongodb.MongoClientSettings
import com.mongodb.client.MongoClient
import com.mongodb.client.MongoClients
import net.minecraft.client.Minecraft
import net.minecraft.commands.synchronization.SingletonArgumentInfo
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.world.item.NameTagItem
import net.minecraft.world.level.Level
import net.minecraft.world.level.storage.LevelResource
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.PrintWriter
import java.util.*
import java.util.UUID
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
import kotlin.properties.Delegates
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField
import net.minecraft.client.Minecraft
import net.minecraft.commands.synchronization.SingletonArgumentInfo
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.NameTagItem
import net.minecraft.world.level.Level
import net.minecraft.world.level.storage.LevelResource
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
object Cobblemon {
const val MODID = CobblemonBuildDetails.MOD_ID
@@ -152,7 +172,9 @@ object Cobblemon {
var permissionValidator: PermissionValidator by Delegates.observable(LaxPermissionValidator().also { it.initialize() }) { _, _, newValue -> newValue.initialize() }
var statProvider: StatProvider = CobblemonStatProvider
var seasonResolver: SeasonResolver = TagSeasonResolver
var wallpapers = mapOf<UUID, List<ResourceLocation>>()
var wallpapers = mutableMapOf<UUID, Set<ResourceLocation>>()
val serverPlayerStructs = mutableMapOf<UUID, ObjectValue<Player>>()
@JvmStatic
val builtinPacks = listOf<CobblemonPack>(
@@ -173,6 +195,8 @@ object Cobblemon {
this.LOGGER.info(" - Branch: ${CobblemonBuildDetails.BRANCH}")
}
implementation.registerRecipeSerializers()
implementation.registerRecipeTypes()
implementation.registerPermissionValidator()
implementation.registerSoundEvents()
implementation.registerDataComponents()
@@ -181,9 +205,11 @@ object Cobblemon {
implementation.registerEntityTypes()
implementation.registerEntityAttributes()
implementation.registerBlockEntityTypes()
implementation.registerPoiTypes()
implementation.registerVillagers()
implementation.registerWorldGenFeatures()
implementation.registerParticles()
implementation.registerMenu()
implementation.registerEntityDataSerializers()
implementation.registerCriteria()
implementation.registerEntitySubPredicates()
@@ -218,6 +244,7 @@ object Cobblemon {
storage.onPlayerDisconnect(it.player)
playerDataManager.onPlayerDisconnect(it.player)
RequestManager.onLogoff(it.player)
serverPlayerStructs.remove(it.player.uuid)
}
PlatformEvents.PLAYER_DEATH.subscribe {
PCLinkManager.removeLink(it.player.uuid)
@@ -387,9 +414,11 @@ object Cobblemon {
PlatformEvents.SERVER_STOPPED.subscribe {
storage.unregisterAll(it.server.registryAccess())
playerDataManager.saveAllStores()
playerDataManager.saveExecutor.shutdown()
playerDataManager.saveExecutor.awaitTermination(30L, TimeUnit.SECONDS)
}
PlatformEvents.SERVER_STARTED.subscribe {
bestSpawner.onServerStarted()
PlatformEvents.SERVER_STARTED.subscribe { event ->
bestSpawner.onServerStarted(event.server)
battleRegistry.onServerStarted()
}
PlatformEvents.SERVER_TICK_POST.subscribe { ServerTickHandler.onTick(it.server) }
@@ -537,6 +566,10 @@ object Cobblemon {
this.implementation.registerCommandArgument(cobblemonResource("form"), FormArgumentType::class, SingletonArgumentInfo.contextFree(FormArgumentType::form))
this.implementation.registerCommandArgument(cobblemonResource("dex"), DexArgumentType::class, SingletonArgumentInfo.contextFree (DexArgumentType::dex))
this.implementation.registerCommandArgument(cobblemonResource("npc_class"), NPCClassArgumentType::class, SingletonArgumentInfo.contextFree(NPCClassArgumentType::npcClass))
this.implementation.registerCommandArgument(cobblemonResource("wallpaper"), UnlockablePCBoxWallpaperArgumentType::class, SingletonArgumentInfo.contextFree(UnlockablePCBoxWallpaperArgumentType::wallpaper))
this.implementation.registerCommandArgument(cobblemonResource("mark"), MarkArgumentType::class, SingletonArgumentInfo.contextFree(MarkArgumentType::mark))
this.implementation.registerCommandArgument(cobblemonResource("transform_type"), TransformTypeArgumentType::class, SingletonArgumentInfo.contextFree(TransformTypeArgumentType::transformType))
this.implementation.registerCommandArgument(cobblemonResource("model_part"), ModelPartArgumentType::class, SingletonArgumentInfo.contextFree(ModelPartArgumentType::modelPart))
}
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.block.entity.PokeCakeBlockEntity
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
import com.cobblemon.mod.common.block.entity.HealingMachineBlockEntity
import com.cobblemon.mod.common.block.entity.PCBlockEntity
@@ -36,6 +37,9 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
@JvmField
val PC: BlockEntityType<PCBlockEntity> = this.create("pc", BlockEntityType.Builder.of(::PCBlockEntity, CobblemonBlocks.PC).build(null))
@JvmField
val STADIUM: BlockEntityType<StadiumBlockEntity> = this.create("stadium_block", BlockEntityType.Builder.of(::StadiumBlockEntity, CobblemonBlocks.STADIUM_BLOCK).build(null))
@JvmField
val LECTERN: BlockEntityType<LecternBlockEntity> = this.create("lectern", BlockEntityType.Builder.of(::LecternBlockEntity, CobblemonBlocks.LECTERN).build(null))
@@ -45,9 +49,9 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
@JvmField
val PASTURE: BlockEntityType<PokemonPastureBlockEntity> = this.create("pasture", BlockEntityType.Builder.of(::PokemonPastureBlockEntity, CobblemonBlocks.PASTURE).build(null))
@JvmField
val SIGN: BlockEntityType<CobblemonSignBlockEntity> = this.create("sign", BlockEntityType.Builder.of(::CobblemonSignBlockEntity, CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN).build(null))
val SIGN: BlockEntityType<CobblemonSignBlockEntity> = this.create("sign", BlockEntityType.Builder.of(::CobblemonSignBlockEntity, CobblemonBlocks.APRICORN_SIGN, CobblemonBlocks.APRICORN_WALL_SIGN, CobblemonBlocks.SACCHARINE_SIGN, CobblemonBlocks.SACCHARINE_WALL_SIGN).build(null))
@JvmField
val HANGING_SIGN: BlockEntityType<CobblemonHangingSignBlockEntity> = this.create("hanging_sign", BlockEntityType.Builder.of(::CobblemonHangingSignBlockEntity, CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN).build(null))
val HANGING_SIGN: BlockEntityType<CobblemonHangingSignBlockEntity> = this.create("hanging_sign", BlockEntityType.Builder.of(::CobblemonHangingSignBlockEntity, CobblemonBlocks.APRICORN_HANGING_SIGN, CobblemonBlocks.APRICORN_WALL_HANGING_SIGN, CobblemonBlocks.SACCHARINE_HANGING_SIGN, CobblemonBlocks.SACCHARINE_WALL_HANGING_SIGN).build(null))
@JvmField
val GILDED_CHEST: BlockEntityType<GildedChestBlockEntity> = this.create("chest", BlockEntityType.Builder.of(::GildedChestBlockEntity,
@@ -86,4 +90,36 @@ object CobblemonBlockEntities : PlatformRegistry<Registry<BlockEntityType<*>>, R
val DISPLAY_CASE: BlockEntityType<DisplayCaseBlockEntity> = this.create("display_case",
BlockEntityType.Builder.of(::DisplayCaseBlockEntity, CobblemonBlocks.DISPLAY_CASE).build(null)
)
@JvmField
val INCENSE_SWEET: BlockEntityType<SweetIncenseBlockEntity> = this.create("incense_sweet",
BlockEntityType.Builder.of(::SweetIncenseBlockEntity, CobblemonBlocks.INCENSE_SWEET).build(null)
)
@JvmField
val CAMPFIRE: BlockEntityType<CampfireBlockEntity> = this.create("campfire_pot",
BlockEntityType.Builder.of(::CampfireBlockEntity, CobblemonBlocks.CAMPFIRE).build(null)
)
/*@JvmField
val LURE_CAKE: BlockEntityType<LureCakeBlockEntity> =
BlockEntityType.Builder.of({ pos, state -> LureCakeBlockEntity(pos, state) },
CobblemonBlocks.LURE_CAKE
).build(null)*/
@JvmField
val LURE_CAKE: BlockEntityType<LureCakeBlockEntity> = this.create(
"lure_cake",
BlockEntityType.Builder.of(::LureCakeBlockEntity, CobblemonBlocks.LURE_CAKE).build(null)
)
@JvmField
val POKE_CAKE: BlockEntityType<PokeCakeBlockEntity> = this.create(
"poke_cake",
BlockEntityType.Builder.of(::PokeCakeBlockEntity, CobblemonBlocks.POKE_CAKE).build(null)
)
@JvmField
val CANDLE_POKE_CAKE: BlockEntityType<CandlePokeCakeBlockEntity> = this.create(
"candle_poke_cake",
BlockEntityType.Builder.of(::CandlePokeCakeBlockEntity, CobblemonBlocks.CANDLE_POKE_CAKE).build(null)
)
}
@@ -10,8 +10,10 @@ package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.apricorn.Apricorn
import com.cobblemon.mod.common.block.*
import com.cobblemon.mod.common.block.campfirepot.CampfireBlock
import com.cobblemon.mod.common.block.LecternBlock
import com.cobblemon.mod.common.block.MintBlock.MintType
import com.cobblemon.mod.common.block.campfirepot.CampfirePotBlock
import com.cobblemon.mod.common.block.chest.GildedChestBlock
import com.cobblemon.mod.common.block.sign.CobblemonHangingSignBlock
import com.cobblemon.mod.common.block.sign.CobblemonSignBlock
@@ -20,6 +22,7 @@ import com.cobblemon.mod.common.block.sign.CobblemonWallSignBlock
import com.cobblemon.mod.common.mixin.invoker.*
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.core.BlockPos
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
@@ -27,9 +30,13 @@ import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.valueproviders.UniformInt
import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.EntityType
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockBehaviour
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockSetType
import net.minecraft.world.level.block.state.properties.BlockStateProperties.LIT
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument
import net.minecraft.world.level.block.state.properties.WoodType
import net.minecraft.world.level.material.MapColor
@@ -43,6 +50,8 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val APRICORN_BLOCK_SET_TYPE = BlockSetType("apricorn")
val APRICORN_WOOD_TYPE = WoodType.register(WoodType("apricorn", APRICORN_BLOCK_SET_TYPE))
val SACCHARINE_BLOCK_SET_TYPE = BlockSetType("saccharine")
val SACCHARINE_WOOD_TYPE = WoodType.register(WoodType("saccharine", SACCHARINE_BLOCK_SET_TYPE))
// Evolution Ores
@JvmField
@@ -159,15 +168,80 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val YELLOW_APRICORN_SAPLING = this.create("yellow_apricorn_sapling", ApricornSaplingBlock(PLANT_PROPERTIES, Apricorn.YELLOW))
// Saccharines
@JvmField
val SACCHARINE_LOG = this.create("saccharine_log", SaccharineLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
@JvmField
val SACCHARINE_HONEY_LOG = this.create("saccharine_honey_log", SaccharineHoneyLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava()))
@JvmField
val STRIPPED_SACCHARINE_LOG = this.create("stripped_saccharine_log", SaccharineStrippedLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
@JvmField
val SACCHARINE_WOOD = log("saccharine_wood")
@JvmField
val STRIPPED_SACCHARINE_WOOD = this.create("stripped_saccharine_wood", SaccharineStrippedLogBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0F).sound(SoundType.WOOD).ignitedByLava())) //log("stripped_saccharine_log")
@JvmField
val SACCHARINE_PLANKS = this.create("saccharine_planks", Block(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_BLUE).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
@JvmField
val SACCHARINE_LEAVES = this.create("saccharine_leaves", SaccharineLeafBlock(
BlockBehaviour.Properties.of().mapColor(
MapColor.PLANT
).strength(0.2f).randomTicks().sound(SoundType.GRASS).noOcclusion()
.isValidSpawn { _: BlockState?, _: BlockGetter?, _: BlockPos?, entity: EntityType<*>? ->
entity === EntityType.OCELOT || entity === EntityType.PARROT
}.isSuffocating { _: BlockState?, _: BlockGetter?, _: BlockPos? ->
false
}.isViewBlocking { _: BlockState?, _: BlockGetter?, _: BlockPos? ->
false
}.ignitedByLava().pushReaction(PushReaction.DESTROY)
.isRedstoneConductor { _: BlockState?, _: BlockGetter?, _: BlockPos? ->
false
}))
@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_BUTTON = this.create("saccharine_button", BlocksInvoker.createWoodenButtonBlock(BlockSetType.OAK))
@JvmField
val SACCHARINE_PRESSURE_PLATE = this.create("saccharine_pressure_plate", PressurePlateBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).noCollission().strength(0.5f).sound(SoundType.WOOD)))
@JvmField
val SACCHARINE_SIGN = this.create("saccharine_sign", CobblemonSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_WALL_SIGN = this.create("saccharine_wall_sign", CobblemonWallSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_WALL_HANGING_SIGN = this.create("saccharine_wall_hanging_sign", CobblemonWallHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
@JvmField
val SACCHARINE_SLAB = this.create("saccharine_slab", SlabBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(2.0f, 3.0f).sound(SoundType.WOOD)))
@JvmField
val SACCHARINE_STAIRS = this.create("saccharine_stairs", StairsBlockInvoker.`cobblemon$create`(SACCHARINE_PLANKS.defaultBlockState(), BlockBehaviour.Properties.ofFullCopy(SACCHARINE_PLANKS)))
@JvmField
val SACCHARINE_DOOR = this.create("saccharine_door", DoorBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(SACCHARINE_PLANKS.defaultMapColor()).instrument(NoteBlockInstrument.BASS).strength(3.0F).sound(SoundType.WOOD).noOcclusion()))
@JvmField
val SACCHARINE_TRAPDOOR = this.create("saccharine_trapdoor", TrapdoorBlockInvoker.`cobblemon$create`(SACCHARINE_BLOCK_SET_TYPE, BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(3.0F).sound(SoundType.WOOD).noOcclusion()))
@JvmField
val SACCHARINE_SAPLING = this.create("saccharine_sapling", SaccharineSaplingBlock(PLANT_PROPERTIES))
@JvmField
val MEDICINAL_LEEK = this.create("medicinal_leek", MedicinalLeekBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.CRIMSON_NYLIUM).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MEDICINAL_LEEK_SOUNDS)))
@JvmField
val BUGWORT = this.create("bugwort", BugwortBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.COLOR_PURPLE).noCollission().randomTicks().instabreak().sound(CobblemonSounds.MEDICINAL_LEEK_SOUNDS)))
@JvmField
val ENERGY_ROOT = this.create("energy_root", EnergyRootBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.DIRT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.ENERGY_ROOT_SOUNDS)))
@JvmField
val BIG_ROOT = this.create("big_root", BigRootBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.PLANT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.BIG_ROOT_SOUNDS)))
@JvmField
val REVIVAL_HERB = this.create("revival_herb", RevivalHerbBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).mapColor(MapColor.PLANT).ignitedByLava().noCollission().instabreak().sound(CobblemonSounds.REVIVAL_HERB_SOUNDS)))
@JvmField
val LURE_CAKE = this.create("lure_cake", LureCakeBlock(BlockBehaviour.Properties.of().forceSolidOn().strength(0.5F).sound(SoundType.WOOL).pushReaction(PushReaction.DESTROY)))
@JvmField
val POKE_CAKE = this.create("poke_cake", PokeCakeBlock(BlockBehaviour.Properties.ofFullCopy(LURE_CAKE)))
@JvmField
val CANDLE_POKE_CAKE = this.create("candle_poke_cake", CandlePokeCakeBlock(BlockBehaviour.Properties.ofFullCopy(LURE_CAKE).lightLevel { blockState -> if (blockState.getValue(LIT) == true) 3 else 0 }))
@JvmField
val TUMBLESTONE_CLUSTER = tumblestoneBlock("tumblestone_cluster", GrowableStoneBlock.STAGE_3, 7, 3, null)
@JvmField
@@ -319,6 +393,60 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val YELLOW_APRICORN = apricornBlock("yellow_apricorn", Apricorn.YELLOW)
@JvmField
val BLACK_CAMPFIRE_POT = create("campfire_pot_black",
CampfirePotBlock(
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLACK).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
)
)
@JvmField
val BLUE_CAMPFIRE_POT = create("campfire_pot_blue",
CampfirePotBlock(
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BLUE).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
)
)
@JvmField
val GREEN_CAMPFIRE_POT = create("campfire_pot_green",
CampfirePotBlock(
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_GREEN).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
)
)
@JvmField
val PINK_CAMPFIRE_POT = create("campfire_pot_pink",
CampfirePotBlock(
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_PINK).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
)
)
@JvmField
val RED_CAMPFIRE_POT = create("campfire_pot_red",
CampfirePotBlock(
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_RED).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
)
)
@JvmField
val WHITE_CAMPFIRE_POT = create("campfire_pot_white",
CampfirePotBlock(
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_LIGHT_GRAY)
.sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS).strength(0.5F).pushReaction(PushReaction.BLOCK)
.noOcclusion()
)
)
@JvmField
val YELLOW_CAMPFIRE_POT = create("campfire_pot_yellow",
CampfirePotBlock(
BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_YELLOW).sound(CobblemonSounds.CAMPFIRE_POT_SOUNDS)
.strength(0.5F).pushReaction(PushReaction.BLOCK).noOcclusion()
)
)
@JvmField
val CAMPFIRE = create("campfire", CampfireBlock(BlockBehaviour.Properties.of().sound(SoundType.WOOD).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.PODZOL).strength(2.0F).lightLevel { if ((it.getValue(CampfireBlock.SOUL) as Boolean)) 9 else 14 }))
@JvmField
val RELIC_COIN_POUCH = create("relic_coin_pouch", CoinPouchBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.RELIC_COIN_POUCH_SOUNDS).pushReaction(PushReaction.DESTROY).noOcclusion(), true))
@JvmField
@@ -354,12 +482,18 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
@JvmField
val PC = create("pc", PCBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2F).noOcclusion().lightLevel { if ((it.getValue(PCBlock.ON) as Boolean) && (it.getValue(PCBlock.PART) == PCBlock.PCPart.TOP)) 10 else 0 }))
@JvmField
val STADIUM_BLOCK = create("stadium_block", StadiumBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).sound(SoundType.METAL).pushReaction(PushReaction.BLOCK).strength(2F)))
@JvmField
val LECTERN = create("lectern", LecternBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).sound(SoundType.WOOD).strength(2.5F).ignitedByLava()))
@JvmField
val DISPLAY_CASE = create("display_case", DisplayCaseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3F)))
@JvmField
val INCENSE_SWEET = create("incense_sweet", SweetIncenseBlock(BlockBehaviour.Properties.of().sound(CobblemonSounds.DISPLAY_CASE_SOUNDS).noOcclusion().pushReaction(PushReaction.BLOCK).mapColor(MapColor.STONE).strength(0.3f)))
@JvmField
val PASTURE = create("pasture", PastureBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_BROWN).sound(SoundType.WOOD).strength(2F).noOcclusion().pushReaction(PushReaction.BLOCK).lightLevel { if ((it.getValue(PastureBlock.ON) as Boolean) && (it.getValue(PastureBlock.PART) == PastureBlock.PasturePart.TOP)) 10 else 0 }))
@@ -381,6 +515,8 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
val PEP_UP_FLOWER = this.create("pep_up_flower", FlowerBlock(MobEffects.LEVITATION, 10F, BlockBehaviour.Properties.of().mapColor(MapColor.PLANT).noCollission().instabreak().sound(SoundType.GRASS).offsetType(BlockBehaviour.OffsetType.XZ).pushReaction(PushReaction.DESTROY)))
@JvmField
val POTTED_PEP_UP_FLOWER = this.create("potted_pep_up_flower", BlocksInvoker.createFlowerPotBlock(PEP_UP_FLOWER))
@JvmField
val HEARTY_GRAINS = this.create("hearty_grains", HeartyGrainsBlock(BlockBehaviour.Properties.of().pushReaction(PushReaction.DESTROY).ignitedByLava().mapColor(MapColor.PLANT).noCollission().randomTicks().instabreak().sound(CobblemonSounds.VIVICHOKE_SOUNDS)))
/**
* Returns a map of all the blocks that can be stripped with an axe in the format of input - output.
@@ -389,7 +525,10 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
*/
fun strippedBlocks(): Map<Block, Block> = mapOf(
APRICORN_WOOD to STRIPPED_APRICORN_WOOD,
APRICORN_LOG to STRIPPED_APRICORN_LOG
APRICORN_LOG to STRIPPED_APRICORN_LOG,
SACCHARINE_WOOD to STRIPPED_SACCHARINE_WOOD,
SACCHARINE_LOG to STRIPPED_SACCHARINE_LOG,
SACCHARINE_HONEY_LOG to STRIPPED_SACCHARINE_LOG
)
@@ -23,7 +23,7 @@ object CobblemonCommands {
ChangeEyeHeight.register(dispatcher)
ChangeScaleAndSize.register(dispatcher)
ChangeWalkSpeed.register(dispatcher)
ChangeJointScaleCommand.register(dispatcher)
TransformModelPartCommand.register(dispatcher)
TestCommand.register(dispatcher)
ReloadShowdownCommand.register(dispatcher)
ClickTextCommand.register(dispatcher)
@@ -60,10 +60,17 @@ object CobblemonCommands {
RenameBoxCommand.register(dispatcher)
ChangeBoxWallpaperCommand.register(dispatcher)
RunMolangScriptCommand.register(dispatcher)
SpectateBattleCommand.register(dispatcher)
CobblemonConfigCommand.register(dispatcher)
UnlockPCBoxWallpaperCommand.register(dispatcher)
ChangePCBoxesCommand.register(dispatcher)
MarkGiveCommand.register(dispatcher)
MarkTakeCommand.register(dispatcher)
MarkGiveAllCommand.register(dispatcher)
// Possibly lock down registration if and only if under dev environment or running in an environment
// with a certain system environment variable set
CobblemonInfoCommand.register(dispatcher)
CalculateSeatPositionCommand.register(dispatcher)
}
}
@@ -99,6 +99,9 @@ object CobblemonFlows : DataRegistry {
runtime.environment.query.addFunction("cancel") { cancelable }
}
// Most places in the mod use query structs so it's probably nicer to present the things as query values.
context.forEach { (key, value) -> runtime.environment.query.addFunction(key) { return@addFunction value } }
functions.forEach { (name, function) -> runtime.environment.query.addFunction(name, function) }
flows[eventResourceLocation]?.forEach {
@@ -94,12 +94,17 @@ interface CobblemonImplementation {
*/
fun registerBlockEntityTypes()
fun registerPoiTypes()
/**
* TODO
*
*/
fun registerVillagers()
fun registerRecipeSerializers()
fun registerRecipeTypes()
/**
* TODO
*
@@ -108,6 +113,8 @@ interface CobblemonImplementation {
fun registerParticles()
fun registerMenu()
fun registerEntitySubPredicates()
@@ -8,9 +8,13 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.block.PotComponent
import com.cobblemon.mod.common.item.components.BaitEffectsComponent
import com.cobblemon.mod.common.item.components.FlavourComponent
import com.cobblemon.mod.common.item.components.FoodColourComponent
import com.cobblemon.mod.common.item.components.HeldItemCapableComponent
import com.cobblemon.mod.common.item.components.PokemonItemComponent
import com.cobblemon.mod.common.item.RodBaitComponent
import com.cobblemon.mod.common.item.components.RodBaitComponent
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.component.DataComponentType
@@ -36,11 +40,34 @@ object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>
.networkSynchronized(RodBaitComponent.PACKET_CODEC)
.build())
val POT_DATA: DataComponentType<PotComponent> = create("cooking_pot_item", DataComponentType.builder<PotComponent>()
.persistent(PotComponent.CODEC)
.networkSynchronized(PotComponent.PACKET_CODEC)
.build())
val BAIT_EFFECTS: DataComponentType<BaitEffectsComponent> = create("bait_effects", DataComponentType.builder<BaitEffectsComponent>()
.persistent(BaitEffectsComponent.CODEC)
.networkSynchronized(BaitEffectsComponent.PACKET_CODEC)
.build())
val FLAVOUR: DataComponentType<FlavourComponent> = create("flavour", DataComponentType.builder<FlavourComponent>()
.persistent(FlavourComponent.CODEC)
.networkSynchronized(FlavourComponent.PACKET_CODEC)
.build())
val FOOD_COLOUR: DataComponentType<FoodColourComponent> = create("food_colour", DataComponentType.builder<FoodColourComponent>()
.persistent(FoodColourComponent.CODEC)
.networkSynchronized(FoodColourComponent.PACKET_CODEC)
.build())
fun register() {
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:pokemon_item"), POKEMON_ITEM)
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:bait"), BAIT)
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:cooking_pot_item"), POT_DATA)
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:bait_effects"), BAIT_EFFECTS)
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:flavour"), FLAVOUR)
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:food_colour"), FOOD_COLOUR)
}
override val registry = BuiltInRegistries.DATA_COMPONENT_TYPE
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.apricorn.Apricorn
import com.cobblemon.mod.common.api.item.ability.AbilityChanger
import com.cobblemon.mod.common.api.mulch.MulchVariant
import com.cobblemon.mod.common.api.pokeball.PokeBalls
@@ -26,9 +27,14 @@ import com.cobblemon.mod.common.item.armor.CobblemonArmorTrims
import com.cobblemon.mod.common.item.battle.DireHitItem
import com.cobblemon.mod.common.item.battle.GuardSpecItem
import com.cobblemon.mod.common.item.battle.XStatItem
import com.cobblemon.mod.common.item.berry.*
import com.cobblemon.mod.common.item.berry.BerryItem
import com.cobblemon.mod.common.item.berry.FriendshipRaisingBerryItem
import com.cobblemon.mod.common.item.berry.HealingBerryItem
import com.cobblemon.mod.common.item.berry.PPRestoringBerryItem
import com.cobblemon.mod.common.item.berry.PortionHealingBerryItem
import com.cobblemon.mod.common.item.berry.StatusCuringBerryItem
import com.cobblemon.mod.common.item.berry.VolatileCuringBerryItem
import com.cobblemon.mod.common.item.interactive.*
import com.cobblemon.mod.common.item.interactive.PotionItem
import com.cobblemon.mod.common.item.interactive.ability.AbilityChangeItem
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.pokeball.PokeBall
@@ -44,7 +50,14 @@ import net.minecraft.world.effect.MobEffectInstance
import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.food.FoodProperties
import net.minecraft.world.item.*
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.HangingSignItem
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.item.Rarity
import net.minecraft.world.item.SignItem
import net.minecraft.world.item.SmithingTemplateItem
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
@@ -171,6 +184,25 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val POKEDEX_WHITE = pokedexItem(PokedexType.WHITE)
val campfire_pots = mutableListOf<CampfirePotItem>()
@JvmField
val CAMPFIRE_POT_BLACK = campfirePotItem(CobblemonBlocks.BLACK_CAMPFIRE_POT, "black")
@JvmField
val CAMPFIRE_POT_BLUE = campfirePotItem(CobblemonBlocks.BLUE_CAMPFIRE_POT, "blue")
@JvmField
val CAMPFIRE_POT_GREEN = campfirePotItem(CobblemonBlocks.GREEN_CAMPFIRE_POT, "green")
@JvmField
val CAMPFIRE_POT_PINK = campfirePotItem(CobblemonBlocks.PINK_CAMPFIRE_POT, "pink")
@JvmField
val CAMPFIRE_POT_RED = campfirePotItem(CobblemonBlocks.RED_CAMPFIRE_POT, "red")
@JvmField
val CAMPFIRE_POT_WHITE = campfirePotItem(CobblemonBlocks.WHITE_CAMPFIRE_POT, "white")
@JvmField
val CAMPFIRE_POT_YELLOW = campfirePotItem(CobblemonBlocks.YELLOW_CAMPFIRE_POT, "yellow")
@JvmField
val Hearty_Grains = compostableItem("hearty_grains", HeartyGrainsItem(CobblemonBlocks.HEARTY_GRAINS))
@JvmField
val VIVICHOKE = compostableItem("vivichoke")
@@ -261,6 +293,321 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val GIMMIGHOUL_CHEST = this.create("gimmighoul_chest", BlockItem(CobblemonBlocks.GIMMIGHOUL_CHEST, Item.Properties()))
// Saccharines
@JvmField
val SACCHARINE_LOG = blockItem("saccharine_log", CobblemonBlocks.SACCHARINE_LOG)
@JvmField
val SACCHARINE_HONEY_LOG = blockItem("saccharine_honey_log", CobblemonBlocks.SACCHARINE_HONEY_LOG)
@JvmField
val STRIPPED_SACCHARINE_LOG = blockItem("stripped_saccharine_log", CobblemonBlocks.STRIPPED_SACCHARINE_LOG)
@JvmField
val SACCHARINE_WOOD = blockItem("saccharine_wood", CobblemonBlocks.SACCHARINE_WOOD)
@JvmField
val STRIPPED_SACCHARINE_WOOD = blockItem("stripped_saccharine_wood", CobblemonBlocks.STRIPPED_SACCHARINE_WOOD)
@JvmField
val SACCHARINE_PLANKS = blockItem("saccharine_planks", CobblemonBlocks.SACCHARINE_PLANKS)
@JvmField
val SACCHARINE_LEAVES = compostableBlockItem("saccharine_leaves", CobblemonBlocks.SACCHARINE_LEAVES)
@JvmField
val SACCHARINE_BOAT = create("saccharine_boat", CobblemonBoatItem(CobblemonBoatType.SACCHARINE, false, Item.Properties().stacksTo(1)))
@JvmField
val SACCHARINE_CHEST_BOAT = create("saccharine_chest_boat", CobblemonBoatItem(CobblemonBoatType.SACCHARINE, true, Item.Properties().stacksTo(1)))
@JvmField
val SACCHARINE_DOOR = blockItem("saccharine_door", CobblemonBlocks.SACCHARINE_DOOR)
@JvmField
val SACCHARINE_TRAPDOOR = blockItem("saccharine_trapdoor", CobblemonBlocks.SACCHARINE_TRAPDOOR)
@JvmField
val SACCHARINE_FENCE = blockItem("saccharine_fence", CobblemonBlocks.SACCHARINE_FENCE)
@JvmField
val SACCHARINE_FENCE_GATE = blockItem("saccharine_fence_gate", CobblemonBlocks.SACCHARINE_FENCE_GATE)
@JvmField
val SACCHARINE_BUTTON = blockItem("saccharine_button", CobblemonBlocks.SACCHARINE_BUTTON)
@JvmField
val SACCHARINE_PRESSURE_PLATE = blockItem("saccharine_pressure_plate", CobblemonBlocks.SACCHARINE_PRESSURE_PLATE)
@JvmField
val SACCHARINE_SLAB = blockItem("saccharine_slab", CobblemonBlocks.SACCHARINE_SLAB)
@JvmField
val SACCHARINE_STAIRS = blockItem("saccharine_stairs", CobblemonBlocks.SACCHARINE_STAIRS)
@JvmField
val SACCHARINE_SIGN = this.create("saccharine_sign", SignItem(Item.Properties().stacksTo(16), CobblemonBlocks.SACCHARINE_SIGN, CobblemonBlocks.SACCHARINE_WALL_SIGN))
@JvmField
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", HangingSignItem(CobblemonBlocks.SACCHARINE_HANGING_SIGN, CobblemonBlocks.SACCHARINE_WALL_HANGING_SIGN, Item.Properties().stacksTo(16)))
@JvmField
val SACCHARINE_SAPLING = saccharineSaplingItem("saccharine_sapling", SaccharineSaplingItem(CobblemonBlocks.SACCHARINE_SAPLING))
@JvmField
val BUGWORT = bugwortItem("bugwort", BugwortItem(CobblemonBlocks.BUGWORT))
@JvmField
val POKE_BAIT = noSettingsItem("poke_bait")
@JvmField
val LURE_CAKE = blockItem("lure_cake", CobblemonBlocks.LURE_CAKE)
@JvmField
val POKE_CAKE = blockItem("poke_cake", CobblemonBlocks.POKE_CAKE)
val aprijuices = mutableListOf<AprijuiceItem>()
@JvmField
val APRIJUICE_BLACK = aprijuiceItem(Apricorn.BLACK)
@JvmField
val APRIJUICE_RED = aprijuiceItem(Apricorn.RED)
@JvmField
val APRIJUICE_BLUE = aprijuiceItem(Apricorn.BLUE)
@JvmField
val APRIJUICE_GREEN = aprijuiceItem(Apricorn.GREEN)
@JvmField
val APRIJUICE_YELLOW = aprijuiceItem(Apricorn.YELLOW)
@JvmField
val APRIJUICE_WHITE = aprijuiceItem(Apricorn.WHITE)
@JvmField
val APRIJUICE_PINK = aprijuiceItem(Apricorn.PINK)
@JvmField
val POKE_PUFF = noSettingsItem("poke_puff") // todo make a PokePuffItem class for friendship boosting purposes
// FOODS
@JvmField
val SWEET_HEART = noSettingsItem("sweet_heart") // todo make a SweetHeartItem class for breeding purposes
@JvmField
val PEWTER_CRUNCHIES = create("pewter_crunchies", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val RAGE_CANDY_BAR = create("rage_candy_bar", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val LAVA_COOKIE = create("lava_cookie", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val OLD_GATEAU = create("old_gateau", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val CASTELIACONE = create("casteliacone", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val SHALOR_SABLE = create("shalor_sable", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val LUMIOSE_GALETTE = create("lumiose_galette", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val BIG_MALASADA = create("big_malasada", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
/*@JvmField // todo see what we are doing for these (are there different kinds?)
val CURRY = create("curry", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.usingConvertsTo(Items.BOWL)
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})*/
@JvmField
val JUBILIFE_MUFFIN = create("jubilife_muffin", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
/*@JvmField // todo see what we are doing for these (are there different kinds?)
val SANDWICH = create("sandwich", object : Item(Properties().stacksTo(16) // todo add all the effects and/or an item class for it for special interactions?
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.usingConvertsTo(Items.BOWL)
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})*/
// todo we might need to wait on these for later?
/*@JvmField
val CHOICE_DUMPLING = noSettingsItem("choice_dumpling") // todo make a ChoiceDumpingItem class for breeding purposes
@JvmField
val SWAP_SNACK = noSettingsItem("swap_snack") // todo make a SwapSnackItem class for breeding purposes
@JvmField
val TWICE_SPICED_BEETROOT = noSettingsItem("twice_spiced_beetroot") // todo make a TwiceSpiceBeetrootItem class for breeding purposes
*/
@JvmField
val POTATO_MOCHI = create("potato_mochi", object : Item(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val FRIED_RICE = create("fried_rice", object : Item(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val CANDIED_APPLE = create("candied_apple", object : Item(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val CANDIED_BERRY = create("candied_berry", object : Item(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
@JvmField
val JELLY_DOUGHNUT = create("jelly_doughnut", object : Item(Properties().stacksTo(16)
.food(FoodProperties.Builder()
.nutrition(10)
.saturationModifier(1.2F)
.effect(MobEffectInstance(MobEffects.ABSORPTION, 900, 0), 1F)
.alwaysEdible()
.build())) {
override fun finishUsingItem(stack: ItemStack, world: Level, user: LivingEntity): ItemStack {
user.removeAllEffects()
return super.finishUsingItem(stack, world, user)
}
})
// todo etc?
//@JvmField
//val SCATTER_BANG = this.create("scatter_bang", ScatterBangItem(Item.Settings()))
//@JvmField
//val STICKY_GLOB = this.create("sticky_glob", StickyGlobItem(Item.Settings()))
@JvmField
val RESTORATION_TANK = blockItem("restoration_tank", CobblemonBlocks.RESTORATION_TANK)
@JvmField
@@ -272,16 +619,18 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val PC = blockItem("pc", CobblemonBlocks.PC)
@JvmField
val STADIUM_BLOCK = blockItem("stadium_block", CobblemonBlocks.STADIUM_BLOCK)
@JvmField
val PASTURE = blockItem("pasture", CobblemonBlocks.PASTURE)
@JvmField
val DISPLAY_CASE = blockItem("display_case", CobblemonBlocks.DISPLAY_CASE)
@JvmField
val LECTERN = blockItem("lectern", CobblemonBlocks.LECTERN)
val INCENSE_SWEET = blockItem("incense_sweet", CobblemonBlocks.INCENSE_SWEET)
// Evolution items
@JvmField val LINK_CABLE = create("link_cable", LinkCableItem())
@JvmField val DRAGON_SCALE = noSettingsItem("dragon_scale")
@JvmField val KINGS_ROCK = noSettingsItem("kings_rock")
@JvmField val METAL_COAT = noSettingsItem("metal_coat")
@JvmField val UPGRADE = noSettingsItem("upgrade")
@JvmField val DUBIOUS_DISC = noSettingsItem("dubious_disc")
@@ -294,20 +643,21 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField val REAPER_CLOTH = noSettingsItem("reaper_cloth")
@JvmField val PRISM_SCALE = noSettingsItem("prism_scale")
@JvmField val SACHET = noSettingsItem("sachet")
@JvmField val WHIPPED_DREAM = noSettingsItem("whipped_dream")
@JvmField val STRAWBERRY_SWEET = noSettingsItem("strawberry_sweet")
@JvmField val LOVE_SWEET = noSettingsItem("love_sweet")
@JvmField val BERRY_SWEET = noSettingsItem("berry_sweet")
@JvmField val CLOVER_SWEET = noSettingsItem("clover_sweet")
@JvmField val FLOWER_SWEET = noSettingsItem("flower_sweet")
@JvmField val STAR_SWEET = noSettingsItem("star_sweet")
@JvmField val RIBBON_SWEET = noSettingsItem("ribbon_sweet")
@JvmField val WHIPPED_DREAM = create("whipped_dream", foodItem(8, 0.3f))
@JvmField val STRAWBERRY_SWEET = create("strawberry_sweet", foodItem(6, 0.125f))
@JvmField val LOVE_SWEET = create("love_sweet", foodItem(6, 0.125f))
@JvmField val BERRY_SWEET = create("berry_sweet", foodItem(6, 0.125f))
@JvmField val CLOVER_SWEET = create("clover_sweet", foodItem(6, 0.125f))
@JvmField val FLOWER_SWEET = create("flower_sweet", foodItem(6, 0.125f))
@JvmField val STAR_SWEET = create("star_sweet", foodItem(6, 0.125f))
@JvmField val RIBBON_SWEET = create("ribbon_sweet", foodItem(6, 0.125f))
@JvmField val CHIPPED_POT = noSettingsItem("chipped_pot")
@JvmField val CRACKED_POT = noSettingsItem("cracked_pot")
@JvmField val MASTERPIECE_TEACUP = noSettingsItem("masterpiece_teacup")
@JvmField val UNREMARKABLE_TEACUP = noSettingsItem("unremarkable_teacup")
@JvmField val SWEET_APPLE = noSettingsItem("sweet_apple")
@JvmField val TART_APPLE = noSettingsItem("tart_apple")
@JvmField val SWEET_APPLE = create("sweet_apple", foodItem(4, 0.3f))
@JvmField val TART_APPLE = create("tart_apple", foodItem(4, 0.3f))
@JvmField val SYRUPY_APPLE = create("syrupy_apple", foodItem(4, 0.3f))
@JvmField val GALARICA_CUFF = noSettingsItem("galarica_cuff")
@JvmField val GALARICA_WREATH = noSettingsItem("galarica_wreath")
@JvmField val BLACK_AUGURITE = noSettingsItem("black_augurite")
@@ -421,6 +771,20 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val ZINC = create("zinc", VitaminItem(Stats.SPECIAL_DEFENCE))
@JvmField
val HEALTH_MOCHI = create("health_mochi", MochiItem(Stats.HP))
@JvmField
val MUSCLE_MOCHI = create("muscle_mochi", MochiItem(Stats.ATTACK))
@JvmField
val RESIST_MOCHI = create("resist_mochi", MochiItem(Stats.DEFENCE))
@JvmField
val GENIUS_MOCHI = create("genius_mochi", MochiItem(Stats.SPECIAL_ATTACK))
@JvmField
val CLEVER_MOCHI = create("clever_mochi", MochiItem(Stats.SPECIAL_DEFENCE))
@JvmField
val SWIFT_MOCHI = create("swift_mochi", MochiItem(Stats.SPEED))
@JvmField
val FRESH_START_MOCHI = create("fresh_start_mochi", FreshStartMochiItem())
@JvmField
val GENIUS_FEATHER = create("genius_feather", FeatherItem(Stats.SPECIAL_ATTACK))
@JvmField
val SWIFT_FEATHER = create("swift_feather", FeatherItem(Stats.SPEED))
@@ -660,6 +1024,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val WATER_STONE = noSettingsItem("water_stone")
val wearables = mutableListOf<WearableItem>()
//Wearable items (these items should have a corresponding 3D model)
@JvmField val BLACK_GLASSES = wearableItem("black_glasses")
@JvmField val CHOICE_BAND = wearableItem("choice_band")
@JvmField val CHOICE_SPECS = wearableItem("choice_specs")
@JvmField val EXP_SHARE = wearableItem("exp_share")
@JvmField val FOCUS_BAND = wearableItem("focus_band")
@JvmField val KINGS_ROCK = wearableItem("kings_rock")
@JvmField val MUSCLE_BAND = wearableItem("muscle_band")
@JvmField val ROCKY_HELMET = wearableItem("rocky_helmet")
@JvmField val SAFETY_GOGGLES = wearableItem("safety_goggles")
@JvmField val WISE_GLASSES = wearableItem("wise_glasses")
// Held Items
@JvmField
val ABILITY_SHIELD = heldItem("ability_shield")
@@ -676,8 +1053,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val BLACK_BELT = heldItem("black_belt")
@JvmField
val BLACK_GLASSES = heldItem("black_glasses")
@JvmField
val BLACK_SLUDGE = heldItem("black_sludge")
@JvmField
val BLUNDER_POLICY = heldItem("blunder_policy")
@@ -686,12 +1061,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val CHARCOAL = heldItem("charcoal_stick", remappedName = "charcoal")
@JvmField
val CHOICE_BAND = heldItem("choice_band")
@JvmField
val CHOICE_SCARF = heldItem("choice_scarf")
@JvmField
val CHOICE_SPECS = heldItem("choice_specs")
@JvmField
val CLEANSE_TAG = heldItem("cleanse_tag")
// @JvmField
// val CLEAR_AMULET = heldItem("clear_amulet")
@@ -712,8 +1083,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val EVIOLITE = heldItem("eviolite")
@JvmField
val EXP_SHARE = heldItem("exp_share")
@JvmField
val EXPERT_BELT = heldItem("expert_belt")
@JvmField
val FAIRY_FEATHER = heldItem("fairy_feather")
@@ -722,8 +1091,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val FLOAT_STONE = heldItem("float_stone")
@JvmField
val FOCUS_BAND = heldItem("focus_band")
@JvmField
val FOCUS_SASH = heldItem("focus_sash")
@JvmField
val GRASSY_SEED = heldItem("grassy_seed")
@@ -758,8 +1125,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val MIRACLE_SEED = heldItem("miracle_seed")
@JvmField
val MUSCLE_BAND = heldItem("muscle_band")
@JvmField
val MYSTIC_WATER = heldItem("mystic_water")
@JvmField
val NEVER_MELT_ICE = heldItem("never_melt_ice")
@@ -790,12 +1155,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val RING_TARGET = heldItem("ring_target")
@JvmField
val ROCKY_HELMET = heldItem("rocky_helmet")
@JvmField
val ROOM_SERVICE = heldItem("room_service")
@JvmField
val SAFETY_GOGGLES = heldItem("safety_goggles")
@JvmField
val SCOPE_LENS = heldItem("scope_lens")
@JvmField
val SHARP_BEAK = heldItem("sharp_beak")
@@ -832,8 +1193,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val WIDE_LENS = heldItem("wide_lens")
@JvmField
val WISE_GLASSES = heldItem("wise_glasses")
@JvmField
val ZOOM_LENS = heldItem("zoom_lens")
@JvmField
val MENTAL_HERB = compostableHeldItem("mental_herb", null, 1F)
@@ -1263,6 +1622,28 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
return item
}
private fun wearableItem(name: String, heldItemRemappedName: String? = null): CobblemonItem = create(
name,
WearableItem(name).also {
wearables.add(it)
if (heldItemRemappedName != null) {
CobblemonHeldItemManager.registerRemap(it, heldItemRemappedName)
}
}
)
private fun campfirePotItem(block: Block, type: String): CampfirePotItem {
val item = create("campfire_pot_${type}", CampfirePotItem(block))
campfire_pots.add(item)
return item
}
private fun aprijuiceItem(type: Apricorn): AprijuiceItem {
val item = create("aprijuice_${type.name.lowercase()}", AprijuiceItem(type))
aprijuices.add(item)
return item
}
private fun heldItem(name: String, remappedName: String? = null): CobblemonItem = create(
name,
CobblemonItem(Item.Properties()).also {
@@ -1278,6 +1659,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
CobblemonHeldItemManager.registerRemap(it, remappedName)
CobblemonHeldItemManager.registerRemap(Items.BONE, "thickclub")
CobblemonHeldItemManager.registerRemap(Items.SNOWBALL, "snowball")
CobblemonHeldItemManager.registerRemap(Items.GOLD_BLOCK, "bignugget")
}
}
)
@@ -1321,6 +1703,21 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
return item
}
private fun saccharineSaplingItem(name: String, saccharineSaplingItem: SaccharineSaplingItem): SaccharineSaplingItem {
val finalName = "saccharine_sapling"
val item = this.create(finalName, saccharineSaplingItem)
compostable(item, .65f)
return item
}
private fun bugwortItem(name: String, bugwortItem: BugwortItem): BugwortItem {
val finalName = "bugwort"
val item = this.create(finalName, bugwortItem)
compostable(item, .65f)
return item
}
private fun mintSeed(name: String, mintBlock: MintBlock): Item {
val finalName = "${name}_mint_seeds"
val item = this.blockItem(finalName, mintBlock)
@@ -1353,4 +1750,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
return createdItem
}
private fun foodItem(nutrition: Int, saturationModifier: Float): Item {
return Item(Item.Properties().food(FoodProperties.Builder().nutrition(nutrition).saturationModifier(saturationModifier).build()))
}
}
@@ -0,0 +1,30 @@
/*
* 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
import com.cobblemon.mod.common.block.campfirepot.CookingPotMenu
import com.cobblemon.mod.common.client.gui.cookingpot.CookingPotScreen
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.client.gui.screens.MenuScreens
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.world.inventory.MenuType
object CobblemonMenuType : PlatformRegistry<Registry<MenuType<*>>, ResourceKey<Registry<MenuType<*>>>, MenuType<*>>() {
val COOKING_POT = MenuType.register("cooking_pot", ::CookingPotMenu)
override val registry: Registry<MenuType<*>>
get() = BuiltInRegistries.MENU
override val resourceKey: ResourceKey<Registry<MenuType<*>>>
get() = Registries.MENU
}
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.client.net.CalculateSeatPositionsHandler
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
@@ -16,6 +17,7 @@ import com.cobblemon.mod.common.client.net.battle.*
import com.cobblemon.mod.common.client.net.callback.move.OpenMoveCallbackHandler
import com.cobblemon.mod.common.client.net.callback.party.OpenPartyCallbackHandler
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
@@ -28,11 +30,13 @@ import com.cobblemon.mod.common.client.net.gui.PokedexUIPacketHandler
import com.cobblemon.mod.common.client.net.gui.SummaryUIPacketHandler
import com.cobblemon.mod.common.client.net.npc.CloseNPCEditorHandler
import com.cobblemon.mod.common.client.net.npc.OpenNPCEditorHandler
import com.cobblemon.mod.common.client.net.orientation.S2CUpdateOrientationHandler
import com.cobblemon.mod.common.client.net.pasture.ClosePastureHandler
import com.cobblemon.mod.common.client.net.pasture.OpenPastureHandler
import com.cobblemon.mod.common.client.net.pasture.PokemonPasturedHandler
import com.cobblemon.mod.common.client.net.pasture.PokemonUnpasturedHandler
import com.cobblemon.mod.common.client.net.pokedex.ServerConfirmedRegisterHandler
import com.cobblemon.mod.common.client.net.pokemon.update.ClientboundUpdateRidingStateHandler
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
import com.cobblemon.mod.common.client.net.settings.OpenCobblemonConfigEditorHandler
import com.cobblemon.mod.common.client.net.settings.ServerSettingsPacketHandler
@@ -56,6 +60,7 @@ 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.CalculateSeatPositionsPacket
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
@@ -63,6 +68,8 @@ import com.cobblemon.mod.common.net.messages.client.battle.*
import com.cobblemon.mod.common.net.messages.client.callback.OpenMoveCallbackPacket
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyCallbackPacket
import com.cobblemon.mod.common.net.messages.client.callback.OpenPartyMoveCallbackPacket
import com.cobblemon.mod.common.net.messages.client.cooking.SeasoningRegistrySyncPacket
import com.cobblemon.mod.common.net.messages.client.cooking.ToggleCookingPotLidPacket
import com.cobblemon.mod.common.net.messages.client.data.*
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueClosedPacket
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
@@ -71,6 +78,7 @@ import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityP
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
import com.cobblemon.mod.common.net.messages.client.npc.CloseNPCEditorPacket
import com.cobblemon.mod.common.net.messages.client.npc.OpenNPCEditorPacket
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateOrientationPacket
import com.cobblemon.mod.common.net.messages.client.pasture.ClosePasturePacket
import com.cobblemon.mod.common.net.messages.client.pasture.OpenPasturePacket
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonPasturedPacket
@@ -104,6 +112,7 @@ import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCPokemonPacke
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.ChangePCBoxWallpaperPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.RequestPCBoxWallpapersPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.SetPCBoxWallpapersPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.UnlockPCBoxWallpaperPacket
import com.cobblemon.mod.common.net.messages.client.toast.ToastPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeAcceptanceChangedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeCancelledPacket
@@ -136,10 +145,12 @@ 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.ServerboundUpdateRidingStatRangePacket
import com.cobblemon.mod.common.net.messages.server.debug.ServerboundUpdateRidingStatsPacket
import com.cobblemon.mod.common.net.messages.server.dialogue.EscapeDialoguePacket
import com.cobblemon.mod.common.net.messages.server.dialogue.InputToDialoguePacket
import com.cobblemon.mod.common.net.messages.server.npc.SaveNPCPacket
import com.cobblemon.mod.common.net.messages.server.orientation.C2SUpdateOrientationPacket
import com.cobblemon.mod.common.net.messages.server.orientation.ServerboundUpdateOrientationPacket
import com.cobblemon.mod.common.net.messages.server.pasture.PasturePokemonPacket
import com.cobblemon.mod.common.net.messages.server.pasture.UnpastureAllPokemonPacket
import com.cobblemon.mod.common.net.messages.server.pasture.UnpasturePokemonPacket
@@ -148,6 +159,9 @@ import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.StartScannin
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.evolution.AcceptEvolutionPacket
import com.cobblemon.mod.common.net.messages.server.starter.RequestStarterScreenPacket
import com.cobblemon.mod.common.net.messages.server.storage.SwapPCPartyPokemonPacket
@@ -177,6 +191,8 @@ 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.ServerboundUpdateRidingStatRangeHandler
import com.cobblemon.mod.common.net.serverhandling.debug.ServerboundUpdateRidingStatsHandler
import com.cobblemon.mod.common.net.serverhandling.dialogue.EscapeDialogueHandler
import com.cobblemon.mod.common.net.serverhandling.dialogue.InputToDialogueHandler
import com.cobblemon.mod.common.net.serverhandling.evolution.AcceptEvolutionHandler
@@ -190,6 +206,9 @@ import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.StartScanning
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.starter.RequestStarterScreenHandler
import com.cobblemon.mod.common.net.serverhandling.starter.SelectStarterPacketHandler
import com.cobblemon.mod.common.net.serverhandling.storage.BenchMoveHandler
@@ -206,6 +225,10 @@ import com.cobblemon.mod.common.net.serverhandling.trade.ChangeTradeAcceptanceHa
import com.cobblemon.mod.common.net.serverhandling.trade.OfferTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.PerformTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
import com.cobblemon.mod.common.stadium.BattleCamerasSyncPacket
import com.cobblemon.mod.common.stadium.BattleCameraSetupHandler
import com.cobblemon.mod.common.stadium.BattleCameraPacket
import com.cobblemon.mod.common.stadium.BattleCameraManagersSyncPacket
import com.cobblemon.mod.common.util.server
import net.minecraft.server.level.ServerPlayer
@@ -262,6 +285,14 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(DmaxLevelUpdatePacket.ID, DmaxLevelUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(GmaxFactorUpdatePacket.ID, GmaxFactorUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(CosmeticItemUpdatePacket.ID, CosmeticItemUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(ActiveMarkUpdatePacket.ID, ActiveMarkUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(MarkAddUpdatePacket.ID, MarkAddUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(MarkRemoveUpdatePacket.ID, MarkRemoveUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(MarkPotentialAddUpdatePacket.ID, MarkPotentialAddUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(MarksUpdatePacket.ID, MarksUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(MarksPotentialUpdatePacket.ID, MarksPotentialUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(MarkingsUpdatePacket.ID, MarkingsUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(RideBoostsUpdatePacket.ID, RideBoostsUpdatePacket::decode, PokemonUpdatePacketHandler()))
// Evolution start
list.add(PacketRegisterInfo(AddEvolutionPacket.ID, AddEvolutionPacket::decode, PokemonUpdatePacketHandler()))
@@ -287,6 +318,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(RequestPCBoxWallpapersPacket.ID, RequestPCBoxWallpapersPacket::decode, RequestPCBoxWallpapersHandler))
list.add(PacketRegisterInfo(SetPCBoxWallpapersPacket.ID, SetPCBoxWallpapersPacket::decode, SetPCBoxWallpapersHandler))
list.add(PacketRegisterInfo(ChangePCBoxWallpaperPacket.ID, ChangePCBoxWallpaperPacket::decode, ChangePCBoxWallpaperHandler))
list.add(PacketRegisterInfo(UnlockPCBoxWallpaperPacket.ID, UnlockPCBoxWallpaperPacket::decode, UnlockPCBoxWallpaperHandler))
// UI Packets
list.add(PacketRegisterInfo(SummaryUIPacket.ID, SummaryUIPacket::decode, SummaryUIPacketHandler))
@@ -350,9 +382,13 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(ScriptRegistrySyncPacket.ID, ScriptRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(PokedexDexSyncPacket.ID, PokedexDexSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(DexEntrySyncPacket.ID, DexEntrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(FishingBaitRegistrySyncPacket.ID, FishingBaitRegistrySyncPacket::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(CosmeticItemAssignmentSyncPacket.ID, CosmeticItemAssignmentSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(BattleCamerasSyncPacket.ID, BattleCamerasSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(BattleCameraManagersSyncPacket.ID, BattleCameraManagersSyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(MarkRegistrySyncPacket.ID, MarkRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
// Effects
list.add(PacketRegisterInfo(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler))
@@ -383,6 +419,9 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(PokemonPasturedPacket.ID, PokemonPasturedPacket::decode, PokemonPasturedHandler))
list.add(PacketRegisterInfo(PokemonUnpasturedPacket.ID, PokemonUnpasturedPacket::decode, PokemonUnpasturedHandler))
// Orientation
list.add(PacketRegisterInfo(ClientboundUpdateOrientationPacket.ID, ClientboundUpdateOrientationPacket::decode, S2CUpdateOrientationHandler))
// Behaviours
list.add(PacketRegisterInfo(PlayPosableAnimationPacket.ID, PlayPosableAnimationPacket::decode, PlayPosableAnimationHandler))
@@ -405,6 +444,16 @@ object CobblemonNetwork {
// Pokédex scanning
list.add(PacketRegisterInfo(ServerConfirmedRegisterPacket.ID, ServerConfirmedRegisterPacket::decode, ServerConfirmedRegisterHandler))
// Debug / cheats
list.add(PacketRegisterInfo(CalculateSeatPositionsPacket.ID, CalculateSeatPositionsPacket::decode, CalculateSeatPositionsHandler))
// Stadium packets
list.add(PacketRegisterInfo(BattleCameraPacket.ID, BattleCameraPacket::decode, BattleCameraSetupHandler))
// Riding
list.add(PacketRegisterInfo(ClientboundUpdateRidingStatePacket.ID, ClientboundUpdateRidingStatePacket::decode, ClientboundUpdateRidingStateHandler))
return list
}
@@ -413,6 +462,8 @@ object CobblemonNetwork {
// Pokemon Update Packets
list.add(PacketRegisterInfo(SetNicknamePacket.ID, SetNicknamePacket::decode, SetNicknameHandler))
list.add(PacketRegisterInfo(SetItemHiddenPacket.ID, SetItemHiddenPacket::decode, SetItemHiddenHandler))
list.add(PacketRegisterInfo(SetActiveMarkPacket.ID, SetActiveMarkPacket::decode, SetActiveMarkHandler))
list.add(PacketRegisterInfo(SetMarkingsPacket.ID, SetMarkingsPacket::decode, SetMarkingsHandler))
// Evolution Packets
list.add(PacketRegisterInfo(AcceptEvolutionPacket.ID, AcceptEvolutionPacket::decode, AcceptEvolutionHandler))
@@ -440,6 +491,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(RequestRenamePCBoxPacket.Companion.ID, RequestRenamePCBoxPacket.Companion::decode, RequestRenamePCBoxHandler))
list.add(PacketRegisterInfo(PCBoxWallpapersPacket.ID, PCBoxWallpapersPacket::decode, PCBoxWallpapersHandler))
list.add(PacketRegisterInfo(RequestChangePCBoxWallpaperPacket.ID, RequestChangePCBoxWallpaperPacket::decode, RequestChangePCBoxWallpaperHandler))
list.add(PacketRegisterInfo(MarkPCBoxWallpapersSeenPacket.ID, MarkPCBoxWallpapersSeenPacket::decode, MarkPCBoxWallpapersSeenHandler))
// Starter packets
list.add(PacketRegisterInfo(SelectStarterPacket.ID, SelectStarterPacket::decode, SelectStarterPacketHandler))
@@ -499,8 +551,14 @@ object CobblemonNetwork {
// NPC packets
list.add(PacketRegisterInfo(SaveNPCPacket.ID, SaveNPCPacket::decode, SaveNPCHandler))
// Orientation packet(s)
list.add(PacketRegisterInfo(C2SUpdateOrientationPacket.ID, C2SUpdateOrientationPacket::decode, OrientationPacketHandler))
// Riding packet(s)
list.add(PacketRegisterInfo(ServerboundUpdateOrientationPacket.ID, ServerboundUpdateOrientationPacket::decode, OrientationPacketHandler))
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatePacket.ID, ServerboundUpdateRidingStatePacket::decode, ServerboundUpdateRidingStateHandler))
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatsPacket.ID, ServerboundUpdateRidingStatsPacket::decode, ServerboundUpdateRidingStatsHandler))
list.add(PacketRegisterInfo(ServerboundUpdateRidingStatRangePacket.ID, ServerboundUpdateRidingStatRangePacket::decode, ServerboundUpdateRidingStatRangeHandler))
// Cooking
list.add(PacketRegisterInfo(ToggleCookingPotLidPacket.ID, ToggleCookingPotLidPacket::decode, ToggleCookingPotLidHandler))
return list
}
@@ -19,7 +19,7 @@ import net.minecraft.world.entity.ai.village.poi.PoiType
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.BlockState
object CobblemonVillagerPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Registry<PoiType>>, PoiType>() {
object CobblemonPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKey<Registry<PoiType>>, PoiType>() {
override val registry: Registry<PoiType> = BuiltInRegistries.POINT_OF_INTEREST_TYPE
override val resourceKey: ResourceKey<Registry<PoiType>> = Registries.POINT_OF_INTEREST_TYPE
@@ -27,8 +27,24 @@ object CobblemonVillagerPoiTypes: PlatformRegistry<Registry<PoiType>, ResourceKe
val NURSE_KEY: ResourceKey<PoiType> = createKey("nurse")
@JvmField
val NURSE = create(NURSE_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.HEALING_MACHINE), 1, 1))
@JvmField
val LURE_CAKE_KEY: ResourceKey<PoiType> = createKey("lure_cake")
@JvmField
val LURE_CAKE = create(LURE_CAKE_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.LURE_CAKE), 0, 1))
@JvmField
val SACCHARINE_HONEY_LOG_KEY: ResourceKey<PoiType> = createKey("saccharine_honey_log")
@JvmField
val SACCHARINE_HONEY_LOG = create(SACCHARINE_HONEY_LOG_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.SACCHARINE_HONEY_LOG), 0, 1))
@JvmField
val INCENSE_SWEET_KEY: ResourceKey<PoiType> = createKey("saccharine_honey_log")
@JvmField
val INCENSE_SWEET = create(INCENSE_SWEET_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.INCENSE_SWEET), 0, 1))
@JvmField
val STADIUM_BLOCK_KEY: ResourceKey<PoiType> = createKey("stadium_block")
@JvmField
val STADIUM_BLOCK = create(STADIUM_BLOCK_KEY.location().path, PoiType(getBlockStates(CobblemonBlocks.STADIUM_BLOCK), 0, 1))
private fun createKey(string: String): ResourceKey<PoiType> = ResourceKey.create(Registries.POINT_OF_INTEREST_TYPE, cobblemonResource(string))
private fun getBlockStates(block: Block): Set<BlockState> = ImmutableSet.copyOf(block.stateDefinition.possibleStates)
}
}
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common
import net.minecraft.client.RecipeBookCategories
enum class CobblemonRecipeCategories {
COOKING_POT_SEARCH("COOKING_POT_SEARCH"),
COOKING_POT_FOODS("COOKING_POT_FOODS"),
COOKING_POT_MEDICINES("COOKING_POT_MEDICINES"),
COOKING_POT_BAITS("COOKING_POT_BAITS"),
COOKING_POT_MISC("COOKING_POT_MISC");
companion object {
val customAggregateCategories: Map<RecipeBookCategories, List<RecipeBookCategories>> = mapOf(
COOKING_POT_SEARCH.toVanillaCategory() to listOf(
COOKING_POT_FOODS.toVanillaCategory(), COOKING_POT_MISC.toVanillaCategory(), COOKING_POT_MEDICINES.toVanillaCategory(), COOKING_POT_BAITS.toVanillaCategory()
)
)
}
var id: String
constructor(id: String) {
this.id = id
}
fun toVanillaCategory(): RecipeBookCategories {
return RecipeBookCategories.valueOf(this.id)
}
}
@@ -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
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.world.item.crafting.Recipe
import net.minecraft.world.item.crafting.RecipeSerializer
object CobblemonRecipeSerializers : PlatformRegistry<Registry<RecipeSerializer<*>>, ResourceKey<Registry<RecipeSerializer<*>>>, RecipeSerializer<*>>() {
val COOKING_POT_COOKING: RecipeSerializer<*> = register("cobblemon:cooking_pot", CookingPotRecipe.Serializer())
val COOKING_POT_SHAPELESS: RecipeSerializer<*> = register("cobblemon:cooking_pot_shapeless", CookingPotShapelessRecipe.Serializer())
override val registry: Registry<RecipeSerializer<*>>
get() = BuiltInRegistries.RECIPE_SERIALIZER
override val resourceKey: ResourceKey<Registry<RecipeSerializer<*>>>
get() = Registries.RECIPE_SERIALIZER
fun <S : RecipeSerializer<T>, T : Recipe<*>> register(key: String, recipeSerializer: S): S {
return Registry.register(BuiltInRegistries.RECIPE_SERIALIZER, key, recipeSerializer) as S
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common
import com.cobblemon.mod.common.item.crafting.CookingPotRecipe
import com.cobblemon.mod.common.item.crafting.CookingPotShapelessRecipe
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.world.item.crafting.Recipe
import net.minecraft.world.item.crafting.RecipeType
object CobblemonRecipeTypes : PlatformRegistry<Registry<RecipeType<*>>, ResourceKey<Registry<RecipeType<*>>>, RecipeType<*>>() {
val COOKING_POT_COOKING: RecipeType<CookingPotRecipe> = register("cobblemon:cooking_pot")
val COOKING_POT_SHAPELESS: RecipeType<CookingPotShapelessRecipe> = register("cobblemon:cooking_pot_shapeless")
override val registry: Registry<RecipeType<*>>
get() = BuiltInRegistries.RECIPE_TYPE
override val resourceKey: ResourceKey<Registry<RecipeType<*>>>
get() = Registries.RECIPE_TYPE
fun <T : Recipe<*>> register(identifier: String): RecipeType<T> {
return Registry.register(
BuiltInRegistries.RECIPE_TYPE,
identifier,
object : RecipeType<T> {
override fun toString(): String {
return identifier
}
}
)
}
}
@@ -40,9 +40,21 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
val PC_RELEASE = this.create("pc.release")
@JvmField
val PC_CLICK = this.create("pc.click")
@JvmField
val PC_WALLPAPER_UNLOCK = this.create("pc.wallpaper.unlock")
@JvmField
val NPC_GIBBER_GENERIC = this.create("entity.npc.gibber.generic")
@JvmField
val NPC_GIBBER_SPEECH_TYPE_1_1 = this.create("entity.npc.gibber.speech_type_1_1")
@JvmField
val NPC_GIBBER_SPEECH_TYPE_1_2 = this.create("entity.npc.gibber.speech_type_1_2")
@JvmField
val NPC_GIBBER_SPEECH_TYPE_1_3 = this.create("entity.npc.gibber.speech_type_1_3")
@JvmField
val VILLAGER_WORK_NURSE = this.create("entity.villager.work_nurse")
@JvmField
val HEALING_MACHINE_ACTIVE = this.create("block.healing_machine.active")
@@ -110,6 +122,8 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
val MEDICINE_SPRAY_USE = this.create("item.medicine.spray.use")
@JvmField
val MEDICINE_FEATHER_USE = this.create("item.medicine.feather.use")
@JvmField
val MOCHI_USE = this.create("item.medicine.feather.use")
@JvmField
val MULCH_PLACE = this.create("block.mulch.place")
@@ -423,5 +437,37 @@ object CobblemonSounds : PlatformRegistry<Registry<SoundEvent>, ResourceKey<Regi
DISPLAY_CASE_STEP
)
@JvmField
val CAMPFIRE_POT_PLACE_CAMPFIRE = this.create("block.campfire_pot.place_campfire")
@JvmField
val CAMPFIRE_POT_RETRIEVE = this.create("block.campfire_pot.retrieve")
@JvmField
val CAMPFIRE_POT_OPEN = this.create("block.campfire_pot.open")
@JvmField
val CAMPFIRE_POT_CLOSE = this.create("block.campfire_pot.close")
@JvmField
val CAMPFIRE_POT_USE = this.create("block.campfire_pot.use")
@JvmField
val CAMPFIRE_POT_COOK = this.create("block.campfire_pot.cook")
@JvmField
val CAMPFIRE_POT_CRAFT = this.create("block.campfire_pot.craft")
@JvmField
val CAMPFIRE_POT_PLACE = this.create("block.campfire_pot.place")
@JvmField
val CAMPFIRE_POT_BREAK = this.create("block.campfire_pot.break")
@JvmField
val CAMPFIRE_POT_HIT = this.create("block.campfire_pot.hit")
@JvmField
val CAMPFIRE_POT_STEP = this.create("block.campfire_pot.step")
@JvmField
val CAMPFIRE_POT_SOUNDS = SoundType(1f, 1.1f,
CAMPFIRE_POT_BREAK,
CAMPFIRE_POT_STEP,
CAMPFIRE_POT_PLACE,
CAMPFIRE_POT_HIT,
CAMPFIRE_POT_STEP
)
private fun create(name: String): SoundEvent = this.create(name, SoundEvent.createVariableRangeEvent(cobblemonResource(name)))
}
}
@@ -0,0 +1,63 @@
/*
* 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
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.api.storage.pc.UnlockablePCWallpaper
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.TextAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
/**
* A data registry for unlockable wallpapers that can be applied to a PC box. This is different to a resource packed
* wallpaper, as those are purely client-side and don't require any unlocking.
*
* See docs/pc_wallpapers.md
*
* @author Hiroku
* @since February 9th, 2025
*/
object CobblemonUnlockableWallpapers : JsonDataRegistry<UnlockablePCWallpaper> {
override val gson: Gson = GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.registerTypeAdapter(Component::class.java, TextAdapter)
.create()
override val typeToken = TypeToken.get(UnlockablePCWallpaper::class.java)
override val resourcePath = "unlockable_pc_box_wallpapers"
override val id: ResourceLocation = cobblemonResource("unlockable_pc_box_wallpapers")
override val type = PackType.SERVER_DATA
override val observable = SimpleObservable<CobblemonUnlockableWallpapers>()
val unlockableWallpapers = mutableMapOf<ResourceLocation, UnlockablePCWallpaper>()
override fun sync(player: ServerPlayer) { /* These don't sync, they're applied to a PC instance from which they're hooked into RequestChangePCBoxWallpaperHandler. */ }
override fun reload(data: Map<ResourceLocation, UnlockablePCWallpaper>) {
unlockableWallpapers.clear()
data.forEach { (id, value) -> value.id = id }
unlockableWallpapers.putAll(data)
observable.emit(this)
}
}
@@ -24,7 +24,7 @@ object CobblemonVillagerProfessions: PlatformRegistry<Registry<VillagerProfessio
override val resourceKey: ResourceKey<Registry<VillagerProfession>> = Registries.VILLAGER_PROFESSION
@JvmField
val NURSE = profession(CobblemonVillagerPoiTypes.NURSE_KEY, CobblemonSounds.VILLAGER_WORK_NURSE)
val NURSE = profession(CobblemonPoiTypes.NURSE_KEY, CobblemonSounds.VILLAGER_WORK_NURSE)
/**
* Register a villager profession texture override for Cobblemon villagers of the given [VillagerProfession] for specified names.
@@ -28,7 +28,7 @@ class BattleCountableCriterion(
val CODEC: Codec<BattleCountableCriterion> = RecordCodecBuilder.create { it.group(
ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(BattleCountableCriterion::playerCtx),
Codec.STRING.listOf().optionalFieldOf("battle_types", listOf("any")).forGetter(BattleCountableCriterion::battleTypes),
Codec.INT.optionalFieldOf( "count", 0).forGetter(BattleCountableCriterion::count)
Codec.INT.optionalFieldOf("count", 0).forGetter(BattleCountableCriterion::count)
).apply(it, ::BattleCountableCriterion) }
}
@@ -20,8 +20,8 @@ import net.minecraft.resources.ResourceLocation
class CastPokeRodContext(val baitId: ResourceLocation)
class CastPokeRodCriterionCondition(
playerCtx: Optional<ContextAwarePredicate>,
val baitId: String
playerCtx: Optional<ContextAwarePredicate>,
val baitId: String
): SimpleCriterionCondition<CastPokeRodContext>(playerCtx) {
companion object {
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.api.apricorn
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.cooking.Flavour
import com.cobblemon.mod.common.block.ApricornBlock
import com.cobblemon.mod.common.block.ApricornSaplingBlock
import com.cobblemon.mod.common.item.ApricornItem
@@ -27,15 +28,43 @@ import net.minecraft.world.level.material.MapColor
* @author Licious
* @since October 29th, 2022
*/
enum class Apricorn : StringRepresentable {
enum class Apricorn(
/** A value of true means it buffs that flavour, a value of false means it weakens that flavour. */
val flavourStrength: Map<Flavour, Boolean> = emptyMap()
) : StringRepresentable {
BLACK,
BLUE,
GREEN,
PINK,
RED,
BLUE(
mapOf(
Flavour.DRY to true,
Flavour.BITTER to false
)
),
GREEN(
mapOf(
Flavour.BITTER to true,
Flavour.SWEET to false
)
),
PINK(
mapOf(
Flavour.SWEET to true,
Flavour.SPICY to false
)
),
RED(
mapOf(
Flavour.SPICY to true,
Flavour.SOUR to false
)
),
WHITE,
YELLOW;
YELLOW(
mapOf(
Flavour.SOUR to true,
Flavour.DRY to false
)
);
fun item(): ApricornItem = when(this) {
BLACK -> CobblemonItems.BLACK_APRICORN
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.berry
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonItems
import com.cobblemon.mod.common.api.berry.spawncondition.BerrySpawnCondition
import com.cobblemon.mod.common.api.cooking.Flavour
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.berry.BerryYieldCalculationEvent
import com.cobblemon.mod.common.api.mulch.MulchVariant
@@ -20,16 +21,10 @@ import com.cobblemon.mod.common.item.berry.BerryItem
import com.cobblemon.mod.common.pokemon.Nature
import com.cobblemon.mod.common.util.readBox
import com.cobblemon.mod.common.util.readEnumConstant
import com.cobblemon.mod.common.util.readEnumSet
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.readList
import com.cobblemon.mod.common.util.readMap
import com.cobblemon.mod.common.util.writeBox
import com.cobblemon.mod.common.util.writeCollection
import com.cobblemon.mod.common.util.writeEnumConstant
import com.cobblemon.mod.common.util.writeEnumSet
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.writeMap
import com.google.gson.annotations.SerializedName
import net.minecraft.core.BlockPos
import net.minecraft.network.RegistryFriendlyByteBuf
@@ -38,6 +33,7 @@ import java.util.EnumSet
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.TagKey
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.item.DyeColor
import net.minecraft.world.level.Level
import net.minecraft.world.level.biome.Biome
import net.minecraft.world.level.block.Block
@@ -61,7 +57,7 @@ import net.minecraft.world.phys.shapes.VoxelShape
* @property growthPoints A collection of [GrowthPoint]s for the berry flowers and fruit.
* @property sproutShapeBoxes A collection of [Box]es that make up the tree [VoxelShape] during the sprouting stages.
* @property matureShapeBoxes A collection of [Box]es that make up the tree [VoxelShape] during the mature stages.
* @property flavors The [Flavor] values.
* @property flavours The [com.cobblemon.mod.common.api.cooking.Flavour] values.
* @property tintIndexes Determines tints at specific indexes if any.
* @property flowerModelIdentifier The [ResourceLocation] for the model of the berry in flower form.
* @property flowerTexture The [ResourceLocation] for the texture of the berry in flower form. This is resolved into a [ModelPart] on the client.
@@ -87,7 +83,10 @@ class Berry(
private val sproutShapeBoxes: Collection<AABB>,
@SerializedName("matureShape")
private val matureShapeBoxes: Collection<AABB>,
private val flavors: Map<Flavor, Int>,
@SerializedName("flavours", alternate = ["flavor"])
val flavours: Map<Flavour, Int>,
@SerializedName("colour", alternate = ["color"])
val colour: DyeColor,
val tintIndexes: Map<Int, Color>,
@SerializedName("flowerModel")
val flowerModelIdentifier: ResourceLocation,
@@ -144,13 +143,13 @@ class Berry(
/**
* Query the value of a certain flavor.
*
* @param flavor The [Flavor] being queried.
* @param flavour The [Flavour] being queried.
* @return The value if any or 0.
*/
fun flavor(flavor: Flavor): Int = this.flavors[flavor] ?: 0
fun flavor(flavour: Flavour): Int = this.flavours[flavour] ?: 0
fun dislikedBy(nature: Nature): Boolean {
val dislikedFlavor = nature.dislikedFlavor ?: return false
val dislikedFlavor = nature.dislikedFlavour ?: return false
return flavor(dislikedFlavor) > 0
}
@@ -281,7 +280,8 @@ class Berry(
buffer.writeCollection(this.matureShapeBoxes) { writer, value ->
writer.writeBox(value)
}
buffer.writeMap(this.flavors, { writer, key -> writer.writeEnumConstant(key) }, { writer, value -> writer.writeInt(value) })
buffer.writeMap(this.flavours, { writer, key -> writer.writeEnumConstant(key) }, { writer, value -> writer.writeInt(value) })
buffer.writeEnumConstant(colour)
buffer.writeMap(this.tintIndexes, { writer, key -> writer.writeInt(key) }, { writer, value -> writer.writeInt(value.rgb) })
buffer.writeIdentifier(this.flowerModelIdentifier)
buffer.writeIdentifier(this.flowerTexture)
@@ -353,7 +353,8 @@ class Berry(
val mutations = buffer.readMap({ reader -> reader.readIdentifier() }, { reader -> reader.readIdentifier() })
val sproutShapeBoxes = buffer.readList { it.readBox() }
val matureShapeBoxes = buffer.readList { it.readBox() }
val flavors = buffer.readMap({ reader -> reader.readEnumConstant(Flavor::class.java) }, { reader -> reader.readInt() })
val flavors = buffer.readMap({ reader -> reader.readEnumConstant(Flavour::class.java) }, { reader -> reader.readInt() })
val colour = buffer.readEnumConstant(DyeColor::class.java)
val tintIndexes = buffer.readMap({ reader -> reader.readInt() }, { reader -> Color(reader.readInt()) })
val flowerModelIdentifier = buffer.readIdentifier()
val flowerTexture = buffer.readIdentifier()
@@ -361,7 +362,7 @@ class Berry(
val fruitTexture = buffer.readIdentifier()
val stageOneYPos = GrowthPoint(Vec3(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()), Vec3(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()))
val boneMealChance = buffer.readFloat()
return Berry(identifier, baseYield, emptyList(), growthTime, refreshRate, favMulchs, emptySet(), emptyList(), growthPoints, randomizedGrowthPoints, mutations, sproutShapeBoxes, matureShapeBoxes, flavors, tintIndexes, flowerModelIdentifier, flowerTexture, fruitModelIdentifier, fruitTexture, stageOneYPos, 0F, boneMealChance)
return Berry(identifier, baseYield, emptyList(), growthTime, refreshRate, favMulchs, emptySet(), emptyList(), growthPoints, randomizedGrowthPoints, mutations, sproutShapeBoxes, matureShapeBoxes, flavors, colour, tintIndexes, flowerModelIdentifier, flowerTexture, fruitModelIdentifier, fruitTexture, stageOneYPos, 0F, boneMealChance)
}
}
@@ -1,24 +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.berry
/**
* Represents the different flavors associated with berries and other Pokémon consumables.
* See the [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Flavor) article for more information.
*
* @author Licious
* @since November 28th, 2022
*/
enum class Flavor(val colour: Int) {
SPICY(0x00FF00),
DRY(0xFF0000),
SWEET(0x0000FF),
BITTER(0xFFFF00),
SOUR(0xFF00FF);
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.api.conditional
import net.minecraft.core.Holder
import net.minecraft.core.Registry
/**
@@ -17,5 +18,10 @@ import net.minecraft.core.Registry
* @since July 16th, 2022
*/
interface RegistryLikeCondition<T> {
fun fits(t: T, registry: Registry<T>): Boolean
fun fits(t: T, registry: Registry<T>): Boolean {
val holder = registry.wrapAsHolder(t)
return holder != null && fits(holder)
}
fun fits(holder: Holder<T>): Boolean
}
@@ -9,7 +9,7 @@
package com.cobblemon.mod.common.api.conditional
import com.google.gson.JsonElement
import net.minecraft.core.Registry
import net.minecraft.core.Holder
import net.minecraft.resources.ResourceLocation
/**
@@ -24,5 +24,6 @@ open class RegistryLikeIdentifierCondition<T : Any>(val identifier: ResourceLoca
constructor: (ResourceLocation) -> RegistryLikeIdentifierCondition<T>
): (JsonElement) -> RegistryLikeIdentifierCondition<T>? = { constructor(ResourceLocation.parse(it.asString)) }
}
override fun fits(t: T, registry: Registry<T>) = registry.getKey(t) == identifier
override fun fits(t: Holder<T>) = t.`is`(identifier)
}
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.api.conditional
import com.google.gson.JsonElement
import net.minecraft.core.Holder
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
@@ -39,16 +40,5 @@ open class RegistryLikeTagCondition<T : Any>(val tag: TagKey<T>) : RegistryLikeC
}
}
override fun fits(t: T, registry: Registry<T>): Boolean {
// val registryHasTag = registry.containsTag(tag)
// if (!registryHasTag) {
//// LOGGER.warn("No tag in registry: ${tag.id}")
// return false
// }
return registry.getResourceKey(t)
.flatMap(registry::getHolder)
.map { entry -> entry.`is`(tag) }
.orElse(false)
}
override fun fits(t: Holder<T>) = t.`is`(tag)
}
@@ -0,0 +1,32 @@
/*
* 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.cooking
import net.minecraft.ChatFormatting
import net.minecraft.util.StringRepresentable
/**
* Represents the different flavors associated with berries and other Pokémon consumables.
* See the [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Flavor) article for more information.
*
* @author Licious
* @since November 28th, 2022
*/
enum class Flavour(val colour: Int, val chatFormatting: ChatFormatting): StringRepresentable {
SPICY(0x00FF00, ChatFormatting.RED),
DRY(0xFF0000, ChatFormatting.DARK_AQUA),
SWEET(0x0000FF, ChatFormatting.LIGHT_PURPLE),
BITTER(0xFFFF00, ChatFormatting.GREEN),
SOUR(0xFF00FF, ChatFormatting.YELLOW);
override fun getSerializedName() = name
companion object {
val CODEC = StringRepresentable.fromEnum<Flavour> { Flavour.entries.toTypedArray() }
}
}
@@ -0,0 +1,63 @@
/*
* 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.cooking
import net.minecraft.util.FastColor
import net.minecraft.world.item.ItemStack
private val colourMap = mapOf(
Flavour.SPICY to 0xFEB37D,
Flavour.DRY to 0x8AE9FC,
Flavour.SWEET to 0xFFBEED,
Flavour.BITTER to 0x9EED8F,
Flavour.SOUR to 0xFCF38A
)
private val bubbleColourMap = mapOf(
Flavour.SPICY to 0xFFD9AD,
Flavour.DRY to 0xBCF8FE,
Flavour.SWEET to 0xFEE3F9,
Flavour.BITTER to 0xC8F7BC,
Flavour.SOUR to 0xFDFAB8
)
fun getColourMixFromSeasonings(seasonings: List<ItemStack>, forBubbles: Boolean = false): Int? {
val flavors = seasonings
.flatMap { Seasonings.getFlavoursFromItemStack(it).entries }
.groupingBy { it.key }
.fold(0) { acc, entry -> acc + entry.value }
val maxFlavorValue = flavors.values.maxOrNull()
val dominantFlavors = flavors.filter { it.value == maxFlavorValue }.map { it.key }
return getColourMixFromFlavours(dominantFlavors, forBubbles)
}
fun getColourMixFromFlavours(dominantFlavours: List<Flavour>, forBubbles: Boolean = false): Int? {
val colors =
dominantFlavours.mapNotNull { if (forBubbles) bubbleColourMap[it] else colourMap[it] }
.map { FastColor.ARGB32.opaque(it) }
if (colors.isEmpty()) return null
val (alphaSum, redSum, greenSum, blueSum) = colors.fold(IntArray(4)) { acc, color ->
acc[0] += FastColor.ARGB32.alpha(color)
acc[1] += FastColor.ARGB32.red(color)
acc[2] += FastColor.ARGB32.green(color)
acc[3] += FastColor.ARGB32.blue(color)
acc
}
return FastColor.ARGB32.color(
alphaSum / colors.size,
redSum / colors.size,
greenSum / colors.size,
blueSum / colors.size
)
}
@@ -0,0 +1,53 @@
/*
* 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.cooking
import com.cobblemon.mod.common.api.conditional.ITEM_REGISTRY_LIKE_CODEC
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.conditional.RegistryLikeIdentifierCondition
import com.cobblemon.mod.common.api.fishing.SpawnBait
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.annotations.SerializedName
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import io.netty.buffer.ByteBuf
import net.minecraft.network.codec.ByteBufCodecs
import net.minecraft.network.codec.StreamCodec
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.Item
data class Seasoning(
val ingredient: RegistryLikeCondition<Item>,
@SerializedName("flavours", alternate = ["flavors"])
val flavours: Map<Flavour, Int>,
@SerializedName("colour", alternate = ["color"])
val colour: DyeColor,
@SerializedName("baitEffects")
val baitEffects: List<SpawnBait.Effect> = emptyList()
) {
companion object {
val CODEC: Codec<Seasoning> = RecordCodecBuilder.create { builder ->
builder.group(
ITEM_REGISTRY_LIKE_CODEC.fieldOf("ingredient").forGetter { it.ingredient },
Codec.unboundedMap(Flavour.CODEC, Codec.INT).fieldOf("flavours").forGetter { it.flavours }, // Use map codec
DyeColor.CODEC.fieldOf("colour").forGetter { it.colour },
SpawnBait.Effect.CODEC.listOf().optionalFieldOf("baitEffects", emptyList()).forGetter { it.baitEffects }
).apply(builder, ::Seasoning)
}
val STREAM_CODEC: StreamCodec<ByteBuf, Seasoning> = ByteBufCodecs.fromCodec(CODEC)
val BLANK_SEASONING = Seasoning(
ingredient = RegistryLikeIdentifierCondition<Item>(cobblemonResource("blank")),
flavours = Flavour.entries.associate { it to 0 },
colour = DyeColor.WHITE,
baitEffects = emptyList()
)
}
}
@@ -0,0 +1,92 @@
/*
* 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.cooking
import com.cobblemon.mod.common.CobblemonItemComponents
import com.cobblemon.mod.common.api.berry.Berries
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.conditional.RegistryLikeIdentifierCondition
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.fishing.SpawnBait
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.cooking.SeasoningRegistrySyncPacket
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.ItemLikeConditionAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
object Seasonings : JsonDataRegistry<Seasoning> {
override val id = cobblemonResource("seasonings")
override val type = PackType.SERVER_DATA
override val observable = SimpleObservable<Seasonings>()
override val typeToken: TypeToken<Seasoning> = TypeToken.get(Seasoning::class.java)
override val resourcePath = "seasonings"
override val gson: Gson = GsonBuilder()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
.setPrettyPrinting()
.create()
val seasonings = mutableListOf<Seasoning>()
val BLANK_SEASONING = Seasoning(
ingredient = RegistryLikeIdentifierCondition<Item>(cobblemonResource("blank")),
flavours = emptyMap(),
colour = DyeColor.WHITE
)
override fun sync(player: ServerPlayer) {
SeasoningRegistrySyncPacket(seasonings.toList()).sendToPlayer(player)
}
override fun reload(data: Map<ResourceLocation, Seasoning>) {
// this needs to sideload the berry data so we don't get duplicate JSONs.
val finalData = Berries.all().associate {
it.identifier to Seasoning(
ingredient = RegistryLikeIdentifierCondition(it.identifier),
flavours = it.flavours.toMap(),
colour = it.colour
)
}.toMutableMap()
finalData.putAll(data)
seasonings.addAll(finalData.values)
}
fun reloadEntries(seasonings: Collection<Seasoning>) {
this.seasonings.clear()
this.seasonings.addAll(seasonings)
}
fun getFlavoursFromItemStack(stack: ItemStack): Map<Flavour, Int> {
val holder = stack.itemHolder
val seasoning = seasonings.find { it.ingredient.fits(holder) } ?: BLANK_SEASONING
val inherentFlavours = stack.get(CobblemonItemComponents.FLAVOUR)?.flavours ?: emptyMap()
return seasoning.flavours.mapValues { (flavour, value) -> inherentFlavours.getOrDefault(flavour, 0) + value }
}
fun getBaitEffectsFromItemStack(stack: ItemStack): List<SpawnBait.Effect> {
return getFromItemStack(stack)?.baitEffects ?: emptyList()
}
fun getFromItemStack(stack: ItemStack): Seasoning? {
val holder = stack.itemHolder
return seasonings.find { it.ingredient.fits(holder) }
}
fun isSeasoning(stack: ItemStack) = getFromItemStack(stack) != null
}
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.dialogue
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.resources.ResourceLocation
/**
* Settings for the gibbering sound effect that plays gradually as dialogue appears.
*
* @author Hiroku, landonjw
* @since April 19th, 2025
*/
class DialogueGibber(
/** Whether text will gradually appear while the gibbering occurs. */
val graduallyShowText: Boolean = true,
/** Whether clicking will make the gibber skip to the end. */
val allowSkip: Boolean = true,
/** The space between gibbers in terms of characters. 'Holy cow' would play 2 sounds if step = 4. */
val step: Int = 4,
/** The time (in seconds) between gibbers. The smaller this is, the faster the text will progress. */
val interval: Double = 0.1,
val minPitch: Float = 0.9F,
val maxPitch: Float = 1.1F,
val minVolume: Float = 0.9F,
val maxVolume: Float = 1.0F,
/** The possible sounds to play when gibbering. */
val sounds: List<ResourceLocation> = listOf(
cobblemonResource("entity.npc.gibber.generic")
)
)
@@ -31,6 +31,7 @@ class DialoguePage(
var lines: MutableList<DialogueText> = mutableListOf(),
var input: DialogueInput = DialogueNoInput(),
var background: ResourceLocation? = null,
var gibber: DialogueGibber? = null,
var clientActions: MutableList<Expression> = mutableListOf(),
var escapeAction: DialogueAction? = null,
) {
@@ -42,6 +43,7 @@ class DialoguePage(
speaker: String? = null,
lines: Iterable<MutableComponent>,
input: DialogueInput = DialogueNoInput(),
gibber: DialogueGibber? = null,
background: ResourceLocation? = null,
clientActions: Iterable<Expression> = emptyList(),
/** The thing to do when the player presses ESC while on this page. If null, falls back to the same property on [Dialogue]. */
@@ -52,6 +54,7 @@ class DialoguePage(
speaker = speaker,
lines = lines.map { WrappedDialogueText(it) }.toMutableList(),
input = input,
gibber = gibber,
background = background,
clientActions = clientActions.toMutableList(),
escapeAction = escapeAction?.let { func -> FunctionDialogueAction { activeDialogue, _ -> func(activeDialogue) } }
@@ -19,7 +19,16 @@ import net.minecraft.network.chat.MutableComponent
*/
class DialogueSpeaker(
val name: DialogueText? = null,
val face: DialogueFaceProvider? = null
val face: DialogueFaceProvider? = null,
val gibber: DialogueGibber? = null
) {
fun of(name: MutableComponent = "".text(), face: DialogueFaceProvider? = null) = DialogueSpeaker(WrappedDialogueText(name), face)
fun of(
name: MutableComponent = "".text(),
face: DialogueFaceProvider? = null,
gibber: DialogueGibber? = null
) = DialogueSpeaker(
name = WrappedDialogueText(name),
face = face,
gibber = gibber
)
}
@@ -20,4 +20,4 @@ interface EntitySideDelegate<T : Entity> {
fun tick(entity: T) {}
fun onSyncedDataUpdated(data: EntityDataAccessor<*>) {}
fun addToStruct(struct: QueryStruct) {}
}
}
@@ -21,4 +21,6 @@ interface PokemonSideDelegate : EntitySideDelegate<PokemonEntity> {
fun updatePostDeath() {}
fun handleStatus(status: Byte) {}
fun spawnShinyParticle(player: Player) {}
}
fun positionRider(passenger: Entity, positionUpdater: MoveFunction)
fun updateAge(age: Int) {}
}
@@ -46,6 +46,7 @@ import com.cobblemon.mod.common.api.events.storage.ChangePCBoxWallpaperEvent
import com.cobblemon.mod.common.api.events.storage.ReleasePokemonEvent
import com.cobblemon.mod.common.api.events.storage.RenamePCBoxEvent
import com.cobblemon.mod.common.api.events.storage.WallpaperCollectionEvent
import com.cobblemon.mod.common.api.events.storage.WallpaperUnlockedEvent
import com.cobblemon.mod.common.api.events.world.BigRootPropagatedEvent
import com.cobblemon.mod.common.api.reactive.CancelableObservable
import com.cobblemon.mod.common.api.reactive.EventObservable
@@ -179,6 +180,8 @@ object CobblemonEvents {
@JvmField
val WALLPAPER_COLLECTION_EVENT = EventObservable<WallpaperCollectionEvent>()
@JvmField
val WALLPAPER_UNLOCKED_EVENT = CancelableObservable<WallpaperUnlockedEvent>()
@JvmField
val CHANGE_PC_BOX_WALLPAPER_EVENT_PRE = CancelableObservable<ChangePCBoxWallpaperEvent.Pre>()
@@ -252,6 +255,11 @@ object CobblemonEvents {
@JvmField
val BAIT_EFFECT_REGISTRATION = EventObservable<BaitEffectFunctionRegistryEvent>()
// Baits and Lures
@JvmField
val BAIT_SPAWN_POKEMON_MODIFY = EventObservable<BaitSpawnPokemonEvent.Modify>()
@JvmField
val COLLECT_EGG = CancelableObservable<CollectEggEvent>()
@JvmField
@@ -8,19 +8,19 @@
package com.cobblemon.mod.common.api.events.fishing
import com.cobblemon.mod.common.api.fishing.FishingBait
import com.cobblemon.mod.common.api.fishing.SpawnBait
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.resources.ResourceLocation
/**
* Event to register code-based functions for bait effects.
* @see FishingBait.Effect
* @see FishingBait.Effects
* @see SpawnBait.Effect
* @see SpawnBait.Effects
*/
class BaitEffectFunctionRegistryEvent {
val functions = mutableMapOf<ResourceLocation, (PokemonEntity, FishingBait.Effect) -> Unit>()
val functions = mutableMapOf<ResourceLocation, (PokemonEntity, SpawnBait.Effect) -> Unit>()
fun registerFunction(id: ResourceLocation, function: (PokemonEntity, FishingBait.Effect) -> Unit) {
fun registerFunction(id: ResourceLocation, function: (PokemonEntity, SpawnBait.Effect) -> Unit) {
functions[id] = function
}
}
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.events.fishing
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.api.spawning.SpawnBucket
import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.world.item.ItemStack
/**
* Event that is fired when a Pokemon is spawned by a bobber.
*/
interface BaitSpawnPokemonEvent {
/**
* Event that is fired before a Pokemon is spawned by a bobber.
* @param bobber The PokeRodFishingBobberEntity that is spawning the Pokemon.
* @param chosenBucket The bucket that is chosen.
* @param rod The ItemStack of the rod that the bobber is attached to.
*/
data class Pre(
val bobber: PokeRodFishingBobberEntity, // todo replace this with the bait entity
val chosenBucket: SpawnBucket,
val rod: ItemStack
) : Cancelable(), BobberSpawnPokemonEvent
/**
* Event that is fired when a Pokemon is modified before it is spawned by a bobber.
* @param chosenBucket The bucket that is chosen.
* @param rod The ItemStack of the rod that the bobber is attached to.
* @param pokemon The Pokemon that is modified.
*/
data class Modify(
val chosenBucket: SpawnBucket,
val rod: ItemStack,
val pokemon: PokemonEntity
) : BobberSpawnPokemonEvent
/**
* Event that is fired after a Pokemon is spawned by a bobber.
* @param bobber The PokeRodFishingBobberEntity that is spawning the Pokemon.
* @param chosenBucket The bucket that is chosen.
* @param bait The ItemStack of the bait that is set on the rod.
* @param pokemon The Pokemon that is spawned.
*/
data class Post(
val bobber: PokeRodFishingBobberEntity,
val chosenBucket: SpawnBucket,
val bait: ItemStack,
val pokemon: PokemonEntity
) : BobberSpawnPokemonEvent
}
@@ -8,10 +8,16 @@
package com.cobblemon.mod.common.api.events.fishing
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.spawning.SpawnBucket
import com.cobblemon.mod.common.entity.fishing.PokeRodFishingBobberEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.itemRegistry
import net.minecraft.core.registries.Registries
import net.minecraft.world.item.ItemStack
/**
@@ -55,5 +61,11 @@ interface BobberSpawnPokemonEvent {
val chosenBucket: SpawnBucket,
val bait: ItemStack,
val pokemon: PokemonEntity
) : BobberSpawnPokemonEvent
) : BobberSpawnPokemonEvent {
val context = mutableMapOf<String, MoValue>(
"chosen_bucket" to ObjectValue(chosenBucket, { it.name }),
"bait" to pokemon.level().itemRegistry.wrapAsHolder(bait.item).asMoLangValue(Registries.ITEM),
"pokemon_entity" to pokemon.asMoLangValue()
)
}
}
@@ -8,10 +8,18 @@
package com.cobblemon.mod.common.api.events.pokemon
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.server.level.ServerPlayer
data class FossilRevivedEvent (
val pokemon: Pokemon,
val player: ServerPlayer?
)
) {
val context = mutableMapOf<String, MoValue>(
"pokemon" to pokemon.struct,
"player" to (player?.asMoLangValue() ?: DoubleValue.ZERO)
)
}
@@ -31,7 +31,7 @@ data class PokemonInteractionGUICreationEvent(
private fun getNextFreeOrientation(): Orientation {
var largest = Orientation.TOP_LEFT
for(orientation in Orientation.values()) {
for (orientation in Orientation.entries) {
if(!options.containsKey(orientation)) {
return orientation
} else {
@@ -22,5 +22,5 @@ import net.minecraft.server.level.ServerPlayer
*/
data class WallpaperCollectionEvent(
val player: ServerPlayer,
val wallpapers: MutableList<ResourceLocation>
val wallpapers: MutableSet<ResourceLocation>
)
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.events.storage
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.moLangFunctionMap
import com.cobblemon.mod.common.api.storage.pc.PCStore
import com.cobblemon.mod.common.api.storage.pc.UnlockablePCWallpaper
import com.cobblemon.mod.common.util.asArrayValue
import com.cobblemon.mod.common.util.getBoolean
import net.minecraft.server.level.ServerPlayer
/**
* Event fired when a wallpaper is unlocked for a PC. Typically, this will have a single player, but it is not
* technically guaranteed to due to shared PCs and offline support.
*
* @author Hiroku
* @since February 10th, 2025
*/
data class WallpaperUnlockedEvent(
val pc: PCStore,
val wallpaper: UnlockablePCWallpaper,
var shouldNotify: Boolean
): Cancelable() {
/** For shared PCs with multiple players online, and for offline PC access, the player will be null. */
val player: ServerPlayer?
get() = pc.getObservingPlayers().takeIf { it.size == 1 }?.first()
/** All online, observing players for the PC. This would typically have a single player in it. */
val players = pc.getObservingPlayers()
val context: MutableMap<String, MoValue>
get() = mutableMapOf(
"pc" to pc.struct,
"wallpaper" to wallpaper.struct,
"player" to (player?.asMoLangValue() ?: DoubleValue.ZERO),
"players" to players.asArrayValue { it.asMoLangValue() },
"should_notify" to DoubleValue(shouldNotify)
)
val functions = moLangFunctionMap(
cancelFunc,
"set_should_notify" to { params ->
shouldNotify = params.getBoolean(0)
DoubleValue.ONE
}
)
}
@@ -1,114 +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.fishing
import com.cobblemon.mod.common.CobblemonItemComponents
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.data.FishingBaitRegistrySyncPacket
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.world.item.ItemStack
object FishingBaits : JsonDataRegistry<FishingBait>{
override val id = cobblemonResource("fishing_baits")
override val type = PackType.SERVER_DATA
override val observable = SimpleObservable<FishingBaits>()
override val typeToken: TypeToken<FishingBait> = TypeToken.get(FishingBait::class.java)
override val resourcePath = "fishing_baits"
override val gson: Gson = GsonBuilder()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.setPrettyPrinting()
.create()
private val itemMap = mutableMapOf<ResourceLocation, FishingBait>()
override fun sync(player: ServerPlayer) {
FishingBaitRegistrySyncPacket(this.itemMap.values.toList()).sendToPlayer(player)
}
override fun reload(data: Map<ResourceLocation, FishingBait>) {
itemMap.clear()
data.forEach { id, bait ->
itemMap[bait.item] = bait
}
}
fun getFromRodItemStack(stack: ItemStack): FishingBait? {
return stack.components.get(CobblemonItemComponents.BAIT)?.bait
}
fun getFromBaitItemStack(stack: ItemStack): FishingBait? {
return getFromIdentifier(BuiltInRegistries.ITEM.getKey(stack.item))
}
fun getFromIdentifier(identifier: ResourceLocation): FishingBait? {
return itemMap[identifier]
}
fun isFishingBait(stack: ItemStack) = itemMap.containsKey(BuiltInRegistries.ITEM.getKey(stack.item))
//
//
// fun getBaitSubcategory(item: ItemStack): String? {
// val itemId = Registries.ITEM.getId(item.item)
// if (itemId in itemMap.keys) {
// return itemMap[itemId]?.subcategory
// }
// val tag = tagMap.keys.firstOrNull { it.fits(item.item, Registries.ITEM) }
// if (tag != null) {
// return tagMap[tag]?.subcategory
// }
// return null
// }
//
// fun getBaitSuccessChance(item: ItemStack): Double? {
// val itemId = Registries.ITEM.getId(item.item)
// if (itemId in itemMap.keys) {
// return itemMap[itemId]?.chance
// }
// val tag = tagMap.keys.firstOrNull { it.fits(item.item, Registries.ITEM) }
// if (tag != null) {
// return tagMap[tag]?.chance
// }
// return null
// }
//
// fun getBaitEffectValue(item: ItemStack): Double? {
// val itemId = Registries.ITEM.getId(item.item)
// if (itemId in itemMap.keys) {
// return itemMap[itemId]?.value
// }
// val tag = tagMap.keys.firstOrNull { it.fits(item.item, Registries.ITEM) }
// if (tag != null) {
// return tagMap[tag]?.value
// }
// return null
// }
//
//
// fun getBaitNote(item: ItemStack): String? {
// val itemId = Registries.ITEM.getId(item.item)
// if (itemId in itemMap.keys) {
// return itemMap[itemId]?.note
// }
// val tag = tagMap.keys.firstOrNull { it.fits(item.item, Registries.ITEM) }
// if (tag != null) {
// return tagMap[tag]?.note
// }
// return null
// }
}
@@ -8,6 +8,8 @@
package com.cobblemon.mod.common.api.fishing
import com.cobblemon.mod.common.api.conditional.ITEM_REGISTRY_LIKE_CODEC
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.fishing.BaitEffectFunctionRegistryEvent
import com.cobblemon.mod.common.api.spawning.fishing.FishingSpawnCause
@@ -16,18 +18,14 @@ import com.cobblemon.mod.common.util.cobblemonResource
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import java.util.Optional
import net.minecraft.core.Registry
import net.minecraft.network.codec.ByteBufCodecs
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
data class FishingBait(
val item: ResourceLocation,
class SpawnBait(
val item: RegistryLikeCondition<Item>,
val effects: List<Effect>,
) {
fun toItemStack(itemRegistry: Registry<Item>) = item.let(itemRegistry::get)?.let { ItemStack(it) } ?: ItemStack.EMPTY
data class Effect(
val type: ResourceLocation,
val subcategory: ResourceLocation?,
@@ -49,19 +47,14 @@ data class FishingBait(
}
companion object {
val CODEC = RecordCodecBuilder.create<FishingBait> { instance ->
val CODEC = RecordCodecBuilder.create<SpawnBait> { instance ->
instance.group(
ResourceLocation.CODEC.fieldOf("item").forGetter { it.item },
ITEM_REGISTRY_LIKE_CODEC.fieldOf("item").forGetter { it.item },
Effect.CODEC.listOf().fieldOf("effects").forGetter {it.effects}
).apply(instance, ::FishingBait)
).apply(instance, ::SpawnBait)
}
val STREAM_CODEC = ByteBufCodecs.fromCodec(CODEC)
val BLANK_BAIT = FishingBait(
cobblemonResource("blank"),
emptyList()
)
}
object Effects {
@@ -78,7 +71,7 @@ data class FishingBait(
val HIDDEN_ABILITY_CHANCE = cobblemonResource("ha_chance")
val POKEMON_CHANCE = cobblemonResource("pokemon_chance")
val FRIENDSHIP = cobblemonResource("friendship")
val INERT = cobblemonResource("inert")
val RARITY_BUCKET = cobblemonResource("rarity_bucket")
fun registerEffect(type: ResourceLocation, effect: (PokemonEntity, Effect) -> Unit) {
EFFECT_FUNCTIONS[type] = effect
@@ -89,15 +82,15 @@ data class FishingBait(
}
fun setupEffects() {
EFFECT_FUNCTIONS[NATURE] = { entity, effect -> FishingSpawnCause.alterNatureAttempt(entity, effect) }
EFFECT_FUNCTIONS[IV] = { entity, effect -> FishingSpawnCause.alterIVAttempt(entity, effect) }
EFFECT_FUNCTIONS[SHINY_REROLL] = { entity, effect -> FishingSpawnCause.shinyReroll(entity, effect) }
EFFECT_FUNCTIONS[GENDER_CHANCE] = { entity, effect -> FishingSpawnCause.alterGenderAttempt(entity, effect) }
EFFECT_FUNCTIONS[LEVEL_RAISE] = { entity, effect -> FishingSpawnCause.alterLevelAttempt(entity, effect) }
EFFECT_FUNCTIONS[HIDDEN_ABILITY_CHANCE] = { entity, _ -> FishingSpawnCause.alterHAAttempt(entity) }
EFFECT_FUNCTIONS[FRIENDSHIP] = { entity, effect -> FishingSpawnCause.alterFriendshipAttempt(entity, effect) }
registerEffect(NATURE) { entity, effect -> FishingSpawnCause.alterNatureAttempt(entity, effect) }
registerEffect(IV) { entity, effect -> FishingSpawnCause.alterIVAttempt(entity, effect) }
registerEffect(SHINY_REROLL) { entity, effect -> FishingSpawnCause.shinyReroll(entity, effect) }
registerEffect(GENDER_CHANCE) { entity, effect -> FishingSpawnCause.alterGenderAttempt(entity, effect) }
registerEffect(LEVEL_RAISE) { entity, effect -> FishingSpawnCause.alterLevelAttempt(entity, effect) }
registerEffect(HIDDEN_ABILITY_CHANCE) { entity, _ -> FishingSpawnCause.alterHAAttempt(entity) }
registerEffect(FRIENDSHIP) { entity, effect -> FishingSpawnCause.alterFriendshipAttempt(entity, effect) }
CobblemonEvents.BAIT_EFFECT_REGISTRATION.post(BaitEffectFunctionRegistryEvent()) { event ->
EFFECT_FUNCTIONS.putAll(event.functions)
event.functions.forEach { (type, function) -> registerEffect(type, function) }
}
}
}
@@ -0,0 +1,103 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.fishing
import com.cobblemon.mod.common.CobblemonItemComponents
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.conditional.RegistryLikeIdentifierCondition
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.data.SpawnBaitRegistrySyncPacket
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.adapters.ItemLikeConditionAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.core.Holder
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
object SpawnBaitEffects : JsonDataRegistry<SpawnBait> {
override val id = cobblemonResource("spawn_bait_effects")
override val type = PackType.SERVER_DATA
override val observable = SimpleObservable<SpawnBaitEffects>()
override val typeToken: TypeToken<SpawnBait> = TypeToken.get(SpawnBait::class.java)
override val resourcePath = "spawn_bait_effects"
override val gson: Gson = GsonBuilder()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
.setPrettyPrinting()
.create()
private val effectsMap = mutableMapOf<ResourceLocation, SpawnBait>()
override fun sync(player: ServerPlayer) {
SpawnBaitRegistrySyncPacket(this.effectsMap.toMap()).sendToPlayer(player)
}
override fun reload(data: Map<ResourceLocation, SpawnBait>) {
effectsMap.clear()
data.forEach { id, bait ->
effectsMap[id] = bait
}
}
fun getEffectsFromRodItemStack(stack: ItemStack): List<SpawnBait.Effect> {
return getEffectsFromItemStack(stack.components.get(CobblemonItemComponents.BAIT)?.stack ?: ItemStack.EMPTY)
}
fun getEffectsFromItemStack(stack: ItemStack): List<SpawnBait.Effect> {
val componentEffects = stack.get(CobblemonItemComponents.BAIT_EFFECTS)?.effects ?: emptyList()
return componentEffects.mapNotNull(::getFromIdentifier).flatMap { it.effects } +
getEffectsFromItem(stack.itemHolder)
}
fun getBaitIdentifiersFromItem(holder: Holder<Item>): List<ResourceLocation> {
return effectsMap.entries.filter { it.value.item.fits(holder) }.map { it.key }
}
fun getBaitFromItemStack(holder: Holder<Item>): List<SpawnBait> {
return effectsMap.values.filter { it.item.fits(holder) }
}
private fun getEffectsFromItem(holder: Holder<Item>): List<SpawnBait.Effect> {
return getBaitFromItemStack(holder).flatMap { it.effects }
}
fun getFromIdentifier(identifier: ResourceLocation): SpawnBait? {
// Check normal spawn bait registry
effectsMap[identifier]?.let { return it }
// check seasoning spawn bait registry
if (identifier.namespace == "seasonings") {
val seasoning = com.cobblemon.mod.common.api.cooking.Seasonings.seasonings.find {
it.ingredient is RegistryLikeIdentifierCondition &&
(it.ingredient as RegistryLikeIdentifierCondition<Item>).identifier.path == identifier.path
}
if (seasoning != null && seasoning.baitEffects.isNotEmpty()) {
return SpawnBait(
item = seasoning.ingredient,
effects = seasoning.baitEffects
)
}
}
return null
}
fun isFishingBait(stack: ItemStack): Boolean {
val holder = stack.itemHolder
return stack.has(CobblemonItemComponents.BAIT_EFFECTS) || effectsMap.values.any { it.item.fits(holder) }
}
}
@@ -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.fishing
object SpawnBaitUtils {
fun mergeEffects(effects: List<SpawnBait.Effect>): List<SpawnBait.Effect> {
val grouped = effects.groupBy { Pair(it.type, it.subcategory) }
return grouped.map { (key, groupEffects) ->
val (type, subcategory) = key
if (type == SpawnBait.Effects.RARITY_BUCKET) {
// we want to keep the highest rarity bucket effect instead of merging them
groupEffects.maxByOrNull { it.value }!!
} else {
val count = groupEffects.size
val totalChance = groupEffects.sumOf { it.chance }
val totalValue = groupEffects.sumOf { it.value }
val multiplier = when (count) {
2 -> 0.8
3 -> 0.9
else -> 1.0
}
val adjustedChance = (totalChance * multiplier).coerceAtMost(1.0)
val adjustedValue = totalValue * multiplier
SpawnBait.Effect(type, subcategory, adjustedChance, adjustedValue)
}
}
}
}
@@ -37,6 +37,8 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.util.FormattedCharSequence
import org.joml.Matrix4f
import org.joml.Vector3f
import org.lwjgl.opengl.GL30
import java.nio.ByteBuffer
@JvmOverloads
fun blitk(
@@ -213,6 +215,7 @@ fun drawPosablePortrait(
ageInTicks: Float = 0F,
headYaw: Float = 0F,
headPitch: Float = 0F,
doQuirks: Boolean = true,
r: Float = 1F,
g: Float = 1F,
b: Float = 1F,
@@ -238,6 +241,7 @@ fun drawPosablePortrait(
context.put(RenderContext.SPECIES, identifier)
context.put(RenderContext.ASPECTS, state.currentAspects)
context.put(RenderContext.POSABLE_STATE, state)
context.put(RenderContext.DO_QUIRKS, doQuirks)
val renderType = RenderType.entityCutout(texture)
@@ -364,4 +368,26 @@ fun renderSprite(matrixStack: PoseStack, sprite: ResourceLocation) {
buffer.addVertex(matrix, 2f, 2f, 0.0f).setUv(1f, 1f)
BufferUploader.drawWithShader(buffer.buildOrThrow())
}
}
fun getPixelRGB(x: Int, y: Int): Triple<Int, Int, Int> {
val window = Minecraft.getInstance().window
val scale = window.guiScale
val buffer = ByteBuffer.allocateDirect(4)
RenderSystem.readPixels(
(x * scale).toInt(),
(window.height - y * scale - scale).toInt(),
1,
1,
GL30.GL_RGBA,
GL30.GL_UNSIGNED_BYTE,
buffer
)
return Triple(
buffer[0].toInt() and 0xFF,
buffer[1].toInt() and 0xFF,
buffer[2].toInt() and 0xFF
)
}
@@ -82,7 +82,7 @@ interface PokemonAndMoveSelectingItem {
val bagItem = bagItem
if (!battlePokemon.actor.canFitForcedAction()) {
player.sendSystemMessage(battleLang("bagitem.cannot").red())
} else if (!bagItem!!.canUse(battle, battlePokemon)) {
} else if (!bagItem!!.canUse(stack, battle, battlePokemon)) {
player.sendSystemMessage(battleLang("bagitem.invalid").red())
} else {
battlePokemon.actor.forceChoose(BagItemActionResponse(bagItem, battlePokemon, move.template.name))
@@ -92,10 +92,10 @@ interface PokemonAndMoveSelectingItem {
}
}
fun canUseOnPokemon(pokemon: Pokemon): Boolean
fun canUseOnBattlePokemon(battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(battlePokemon.actor.battle, battlePokemon)
fun canUseOnMove(pokemon: Pokemon, move: Move): Boolean = canUseOnMove(move)
fun canUseOnMove(move: Move): Boolean
fun canUseOnPokemon(stack: ItemStack, pokemon: Pokemon): Boolean
fun canUseOnBattlePokemon(stack: ItemStack, battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(stack, battlePokemon.actor.battle, battlePokemon)
fun canUseOnMove(stack: ItemStack, pokemon: Pokemon, move: Move): Boolean = canUseOnMove(stack, move)
fun canUseOnMove(stack: ItemStack, move: Move): Boolean
fun interactWithSpecific(player: ServerPlayer, stack: ItemStack, pokemon: Pokemon): InteractionResultHolder<ItemStack>? {
@@ -106,18 +106,18 @@ interface PokemonAndMoveSelectingItem {
MoveSelectCallbacks.create(
player = player,
moves = pokemon.moveSet.toList(),
canSelect = ::canUseOnMove,
canSelect = { canUseOnMove(stack, it)},
handler = { move -> if (stack.isHeld(player)) applyToPokemon(player, stack, pokemon, move) }
)
return InteractionResultHolder.success(stack)
}
fun interactWithSpecificBattle(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon): InteractionResultHolder<ItemStack>? {
return if (canUseOnBattlePokemon(battlePokemon)) {
return if (canUseOnBattlePokemon(stack, battlePokemon)) {
MoveSelectCallbacks.create(
player = player,
moves = battlePokemon.moveSet.getMoves(),
canSelect = ::canUseOnMove,
canSelect = { canUseOnMove(stack, it) },
handler = { applyToBattlePokemon(player, stack, battlePokemon, it) }
)
InteractionResultHolder.success(stack)
@@ -131,8 +131,8 @@ interface PokemonAndMoveSelectingItem {
PartyMoveSelectCallbacks.createFromPokemon(
player = player,
pokemon = player.party().toList(),
canSelectPokemon = ::canUseOnPokemon,
canSelectMove = ::canUseOnMove,
canSelectPokemon = { canUseOnPokemon(stack, it) },
canSelectMove = { pokemon, move -> canUseOnMove(stack, pokemon, move) },
handler = { pk, mv -> if (stack.isHeld(player)) applyToPokemon(player, stack, pk, mv) }
)
@@ -144,8 +144,8 @@ interface PokemonAndMoveSelectingItem {
player = player,
pokemon = actor.pokemonList.map { it.effectedPokemon },
moves = { pk -> actor.pokemonList.find { it.effectedPokemon == pk }!!.moveSet.getMoves() },
canSelectPokemon = { pk -> canUseOnBattlePokemon(actor.pokemonList.find { it.effectedPokemon == pk }!!) },
canSelectMove = ::canUseOnMove,
canSelectPokemon = { pk -> canUseOnBattlePokemon(stack, actor.pokemonList.find { it.effectedPokemon == pk }!!) },
canSelectMove = { pokemon, move -> canUseOnMove(stack, pokemon, move) },
handler = { pk, mv -> applyToBattlePokemon(player, stack, actor.pokemonList.find { it.effectedPokemon == pk }!!, mv) }
)
@@ -92,7 +92,7 @@ interface PokemonSelectingItem {
val bagItem = bagItem
if (!battlePokemon.actor.canFitForcedAction()) {
player.sendSystemMessage(battleLang("bagitem.cannot").red())
} else if (!bagItem!!.canUse(battle, battlePokemon)) {
} else if (!bagItem!!.canUse(stack, battle, battlePokemon)) {
player.sendSystemMessage(battleLang("bagitem.invalid").red())
} else {
battlePokemon.actor.forceChoose(BagItemActionResponse(bagItem, battlePokemon))
@@ -105,11 +105,11 @@ interface PokemonSelectingItem {
}
}
fun canUseOnPokemon(pokemon: Pokemon): Boolean
fun canUseOnBattlePokemon(battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(battlePokemon.actor.battle, battlePokemon)
fun canUseOnPokemon(stack: ItemStack, pokemon: Pokemon): Boolean
fun canUseOnBattlePokemon(stack: ItemStack, battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(stack, battlePokemon.actor.battle, battlePokemon)
fun interactWithSpecificBattle(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon): InteractionResultHolder<ItemStack> {
return if (canUseOnBattlePokemon(battlePokemon)) {
return if (canUseOnBattlePokemon(stack, battlePokemon)) {
applyToBattlePokemon(player, stack, battlePokemon)
InteractionResultHolder.success(stack)
} else {
@@ -127,7 +127,7 @@ interface PokemonSelectingItem {
PartySelectCallbacks.createFromPokemon(
player = player,
pokemon = party,
canSelect = ::canUseOnPokemon,
canSelect = { pk -> canUseOnPokemon(stack, pk) },
handler = { pk ->
if (stack.isHeld(player)) {
applyToPokemon(player, stack, pk)
@@ -143,7 +143,7 @@ interface PokemonSelectingItem {
PartySelectCallbacks.createBattleSelect(
player = player,
pokemon = actor.pokemonList,
canSelect = { pk -> canUseOnBattlePokemon(actor.pokemonList.find { it.effectedPokemon == pk.effectedPokemon }!!) },
canSelect = { pk -> canUseOnBattlePokemon(stack, actor.pokemonList.find { it.effectedPokemon == pk.effectedPokemon }!!) },
handler = { pk -> applyToBattlePokemon(player, stack, actor.pokemonList.find { it.effectedPokemon == pk.effectedPokemon }!!) }
)
@@ -0,0 +1,87 @@
/*
* 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.mark
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.util.*
import com.google.gson.annotations.SerializedName
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.StringRepresentable
class Mark(
identifier: ResourceLocation,
val name: String,
val description: String,
val title: String?,
@SerializedName(value = "titleColor", alternate = ["titleColour"])
val titleColour: String?,
val texture: ResourceLocation,
val replace: List<ResourceLocation>?,
val group: String?,
val chance: Float = 0F,
val indexNumber: Int?
): StringRepresentable {
companion object {
internal fun decode(buffer: RegistryFriendlyByteBuf): Mark {
return Mark(
buffer.readIdentifier(),
buffer.readString(),
buffer.readString(),
buffer.readNullable { buffer.readString() },
buffer.readNullable { buffer.readString() },
buffer.readResourceLocation(),
buffer.readNullable { buffer.readList { buffer.readResourceLocation() } },
buffer.readNullable { buffer.readString() },
buffer.readFloat(),
buffer.readNullable { buffer.readInt() }
)
}
}
@Transient
var identifier: ResourceLocation = identifier
internal set
override fun getSerializedName(): String = identifier.toString()
fun getName(): MutableComponent = name.asTranslated()
fun getDescription(): MutableComponent = description.asTranslated()
fun getTitle(name: MutableComponent): MutableComponent {
title?.let {
try {
return if (titleColour != null) it.asTranslated(name.withColor(-1)).withColor(titleColour.toInt(16))
else it.asTranslated(name)
} catch (e: Exception) {
Cobblemon.LOGGER.error("Error parsing titleColor hexadecimal color code for {}", identifier, e)
return it.asTranslated(name)
}
}
return name
}
fun getChanceGroup(): Pair<String, Float> = Pair(group ?: chance.toString(), chance)
internal fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeIdentifier(identifier)
buffer.writeString(name)
buffer.writeString(description)
buffer.writeNullable(title) { _, v -> buffer.writeString(v) }
buffer.writeNullable(titleColour) { _, v -> buffer.writeString(v) }
buffer.writeResourceLocation(texture)
buffer.writeNullable(replace) { _, v -> buffer.writeCollection(v) { _, resource -> buffer.writeResourceLocation(resource) } }
buffer.writeNullable(group) { _, v -> buffer.writeString(v) }
buffer.writeFloat(chance)
buffer.writeNullable(indexNumber) { _, v -> buffer.writeInt(v) }
}
}
@@ -0,0 +1,68 @@
/*
* 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.mark
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.messages.client.data.MarkRegistrySyncPacket
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
object Marks: JsonDataRegistry<Mark> {
override val id: ResourceLocation = cobblemonResource("marks")
override val type: PackType = PackType.SERVER_DATA
override val observable = SimpleObservable<Marks>()
override val typeToken: TypeToken<Mark> = TypeToken.get(Mark::class.java)
override val resourcePath: String = "marks"
override val gson = GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
.create()
private val marks = hashMapOf<ResourceLocation, Mark>()
override fun reload(data: Map<ResourceLocation, Mark>) {
this.marks.clear()
data.forEach { (identifier, mark) ->
try {
mark.identifier = identifier
this.marks[identifier] = mark
} catch (e: Exception) {
Cobblemon.LOGGER.error("Skipped loading the {} mark", identifier, e)
}
}
Cobblemon.LOGGER.info("Loaded {} marks", this.marks.size)
this.observable.emit(this)
}
override fun sync(player: ServerPlayer) {
MarkRegistrySyncPacket(this.all()).sendToPlayer(player)
}
/**
* Gets all loaded [Mark]s.
*/
fun all() = this.marks.values.toList()
fun identifiers(): Collection<String> = marks.keys.toSet().map { it.toString() }
/**
* Gets a [Mark] by its [ResourceLocation].
* @param identifier The identifier of the mark.
* @return The [Mark] if loaded, otherwise null.
*/
fun getByIdentifier(identifier: ResourceLocation): Mark? = this.marks[identifier]
}
@@ -17,25 +17,17 @@ import com.bedrockk.molang.runtime.struct.VariableStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonActivities
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.*
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.battles.model.actor.ActorType
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
import com.cobblemon.mod.common.api.dialogue.PlayerDialogueFaceProvider
import com.cobblemon.mod.common.api.dialogue.ReferenceDialogueFaceProvider
import com.cobblemon.mod.common.api.mark.Marks
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import com.cobblemon.mod.common.api.moves.animations.NPCProvider
import com.cobblemon.mod.common.api.pokedex.AbstractPokedexManager
import com.cobblemon.mod.common.api.pokedex.CaughtCount
import com.cobblemon.mod.common.api.pokedex.CaughtPercent
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
import com.cobblemon.mod.common.api.pokedex.PokedexManager
import com.cobblemon.mod.common.api.pokedex.SeenCount
import com.cobblemon.mod.common.api.pokedex.SeenPercent
import com.cobblemon.mod.common.api.pokedex.*
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
import com.cobblemon.mod.common.api.pokemon.stats.Stats
@@ -46,11 +38,11 @@ import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore
import com.cobblemon.mod.common.api.storage.pc.PCPosition
import com.cobblemon.mod.common.api.storage.pc.PCStore
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
import com.cobblemon.mod.common.client.particle.BedrockParticleOptionsRepository
import com.cobblemon.mod.common.client.particle.ParticleStorm
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunctions
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.npc.NPCBattleActor
@@ -70,20 +62,14 @@ import com.cobblemon.mod.common.pokemon.evolution.variants.LevelUpEvolution
import com.cobblemon.mod.common.pokemon.evolution.variants.TradeEvolution
import com.cobblemon.mod.common.util.*
import com.mojang.datafixers.util.Either
import java.util.UUID
import kotlin.math.sqrt
import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.commands.arguments.EntityAnchorArgument
import net.minecraft.core.BlockPos
import net.minecraft.core.Holder
import net.minecraft.core.Registry
import net.minecraft.core.RegistryAccess
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.DoubleTag
import net.minecraft.nbt.ListTag
import net.minecraft.nbt.StringTag
import net.minecraft.nbt.Tag
import net.minecraft.nbt.*
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.MinecraftServer
@@ -92,22 +78,24 @@ import net.minecraft.server.level.ServerPlayer
import net.minecraft.tags.TagKey
import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.damagesource.DamageTypes
import net.minecraft.world.entity.EntityType
import net.minecraft.world.entity.LightningBolt
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.*
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.MemoryStatus
import net.minecraft.world.entity.ai.memory.WalkTarget
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.Level.ExplosionInteraction
import net.minecraft.world.level.biome.Biome
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.dimension.DimensionType
import net.minecraft.world.level.levelgen.Heightmap
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.Vec3
import java.util.*
import kotlin.math.sqrt
import kotlin.random.Random
/**
* Holds a bunch of useful MoLang trickery that can be used or extended in API
@@ -228,6 +216,22 @@ object MoLangFunctions {
val z = params.getInt(2)
return@put DoubleValue(world.isRainingAt(BlockPos(x, y, z)))
}
map.put("is_snowing_at") { params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
val blockPos = BlockPos(x, y, z)
if (!world.isRaining()) {
return@put DoubleValue.ZERO
} else if (!world.canSeeSky(blockPos)) {
return@put DoubleValue.ZERO
} else if (world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, blockPos).getY() > blockPos.getY()) {
return@put DoubleValue.ZERO
} else {
val biome = world.getBiome(blockPos).value() as Biome
return@put DoubleValue(biome.getPrecipitationAt(blockPos) == Biome.Precipitation.SNOW)
}
}
map.put("is_chunk_loaded_at") { params ->
val x = params.getInt(0)
val y = params.getInt(1)
@@ -283,16 +287,32 @@ object MoLangFunctions {
} as? ServerPlayer
val pos = Vec3(x, y, z)
if (world !is ClientLevel) {
val packet = SpawnSnowstormParticlePacket(particle, pos)
if (player != null) {
packet.sendToPlayer(player)
} else {
packet.sendToPlayersAround(x, y, z, 64.0, world.dimension())
}
val packet = SpawnSnowstormParticlePacket(particle, pos)
if (player != null) {
packet.sendToPlayer(player)
} else {
val effect = BedrockParticleOptionsRepository.getEffect(particle) ?: return@put DoubleValue.ZERO
ParticleStorm.createAtPosition(world, effect, pos).spawn()
packet.sendToPlayersAround(x, y, z, 64.0, world.dimension())
}
}
map.put("spawn_pokemon") { params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
val props = params.getString(3).toProperties()
val pos = BlockPos(x, y, z)
if (!Level.isInSpawnableBounds(pos)) {
return@put DoubleValue.ZERO
}
val pokemon = props.createEntity(world)
pokemon.moveTo(pos, pokemon.yRot, pokemon.xRot)
if (world.addFreshEntity(pokemon)) {
return@put pokemon.struct
} else {
return@put DoubleValue.ZERO
}
}
map.put("get_entities_around") { params ->
@@ -306,6 +326,11 @@ object MoLangFunctions {
.map { it.asMostSpecificMoLangValue() }
.asArrayValue()
}
map.put("is_healer_in_use") { params ->
val pos = params.get<ArrayStruct>(0).asBlockPos()
val healer = world.getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null) ?: return@put DoubleValue.ONE
return@put DoubleValue(healer.isInUse)
}
return@mutableListOf map
}
@@ -317,8 +342,8 @@ object MoLangFunctions {
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
map.put("username") { _ -> StringValue(player.gameProfile.name) }
map.put("uuid") { _ -> StringValue(player.gameProfile.id.toString()) }
map.put("main_held_item") { _ -> player.level().itemRegistry.wrapAsHolder(player.mainHandItem.item).asMoLangValue(Registries.ITEM) }
map.put("off_held_item") { _ -> player.level().itemRegistry.wrapAsHolder(player.offhandItem.item).asMoLangValue(Registries.ITEM) }
map.put("main_held_item") { _ -> player.mainHandItem.asMoLangValue(player.registryAccess()) }
map.put("off_held_item") { _ -> player.offhandItem.asMoLangValue(player.registryAccess()) }
map.put("face") { params -> ObjectValue(PlayerDialogueFaceProvider(player.uuid, params.getBooleanOrNull(0) != false)) }
map.put("swing_hand") { _ -> player.swing(player.usedItemHand) }
map.put("food_level") { _ -> DoubleValue(player.foodData.foodLevel) }
@@ -412,11 +437,39 @@ object MoLangFunctions {
return@put DoubleValue.ONE
}
map.put("pokedex") { player.pokedex().struct }
map.put("has_advancement") { params ->
val requiredAdvancement = ResourceLocation.parse(params.getString(0))
for (entry in player.advancements.progress) {
if (entry.key.id == requiredAdvancement && entry.value.isDone) {
return@put DoubleValue.ONE
}
}
return@put DoubleValue.ZERO
}
}
map
}
)
val entityFunctions: MutableList<(LivingEntity) -> HashMap<String, java.util.function.Function<MoParams, Any>>> = mutableListOf<(LivingEntity) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
val itemStackFunctions = mutableListOf<(ItemStack, RegistryAccess) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
{ stack, registryAccess ->
val itemRegistry = registryAccess.registryOrThrow(Registries.ITEM)
val holder = itemRegistry.wrapAsHolder(stack.item)
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
map.put("item") { _ -> holder.asMoLangValue(Registries.ITEM) }
map.put("count") { _ -> DoubleValue(stack.count.toDouble()) }
map.put("damage_value") { _ -> DoubleValue(stack.damageValue) }
map.put("max_damage") { _ -> DoubleValue(stack.maxDamage) }
map.put("is_empty") { _ -> DoubleValue(stack.isEmpty) }
map.put("shrink") { params -> stack.shrink(params.getInt(0)) }
map.put("grow") { params -> stack.grow(params.getInt(0)) }
map.put("is_of") { params -> DoubleValue(holder.`is`(params.getString(0).asIdentifierDefaultingNamespace())) }
map.put("is_in") { params -> DoubleValue(holder.`is`(TagKey.create(Registries.ITEM, params.getString(0).replace("#", "").asIdentifierDefaultingNamespace()))) }
return@mutableListOf map
}
)
val entityFunctions: MutableList<(Entity) -> HashMap<String, java.util.function.Function<MoParams, Any>>> = mutableListOf(
{ entity ->
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
map.put("uuid") { _ -> StringValue(entity.uuid.toString()) }
@@ -425,48 +478,23 @@ object MoLangFunctions {
val source = DamageSource(entity.level().registryAccess().registryOrThrow(Registries.DAMAGE_TYPE).getHolder(DamageTypes.GENERIC).get())
entity.hurt(source, amount.toFloat())
}
map.put("walk_to") { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
val speedMultiplier = params.getDoubleOrNull(3) ?: 0.35
if (entity is PathfinderMob) {
if (entity.brain.checkMemory(MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED)) {
entity.brain.setMemory(MemoryModuleType.WALK_TARGET, WalkTarget(Vec3(x, y, z), speedMultiplier.toFloat(), 1))
entity.brain.setMemory(MemoryModuleType.LOOK_TARGET, BlockPosTracker(Vec3(x, y + entity.eyeHeight, z)))
} else {
entity.navigation.moveTo(x, y, z, speedMultiplier)
entity.lookControl.setLookAt(Vec3(x, y + entity.eyeHeight, z))
}
}
}
map.put("has_walk_target") { _ ->
if (entity is PathfinderMob) {
DoubleValue(entity.brain.getMemory(MemoryModuleType.WALK_TARGET).isPresent || entity.isPathFinding)
} else {
DoubleValue.ZERO
}
}
map.put("is_sneaking") { _ -> DoubleValue(entity.isShiftKeyDown) }
map.put("is_sprinting") { _ -> DoubleValue(entity.isSprinting) }
map.put("is_flying") { _ -> DoubleValue(entity.isFallFlying) }
map.put("is_in_water") { _ -> DoubleValue(entity.isUnderWater) }
map.put("is_in_rain") { _ -> DoubleValue(entity.isInWaterOrRain && !entity.isInWater) }
map.put("is_touching_water_or_rain") { _ -> DoubleValue(entity.isInWaterRainOrBubble) }
map.put("is_touching_water") { _ -> DoubleValue(entity.isInWater) }
map.put("is_underwater") { DoubleValue(entity.getIsSubmerged()) }
map.put("is_in_lava") { _ -> DoubleValue(entity.isInLava) }
map.put("is_on_fire") { _ -> DoubleValue(entity.isOnFire) }
map.put("is_invisible") { _ -> DoubleValue(entity.isInvisible) }
map.put("is_sleeping") { _ -> DoubleValue(entity.isSleeping) }
map.put("is_riding") { _ -> DoubleValue(entity.isPassenger) }
map.put("health") { _ -> DoubleValue(entity.health) }
map.put("distance_to_pos") { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
return@put DoubleValue(sqrt(entity.distanceToSqr(Vec3(x, y, z))))
}
map.put("max_health") { _ -> DoubleValue(entity.maxHealth) }
map.put("name") { _ -> StringValue(entity.effectiveName().string) }
map.put("type") { _ ->
entity.registryAccess().registry(Registries.ENTITY_TYPE).get().getKey(entity.type)?.toString()?.let {
@@ -493,11 +521,6 @@ object MoLangFunctions {
map.put("world") { _ -> entity.level().worldRegistry.wrapAsHolder(entity.level()).asWorldMoLangValue() }
map.put("biome") { _ -> entity.level().getBiome(entity.blockPosition()).asBiomeMoLangValue() }
map.put("is_passenger") { DoubleValue(entity.isPassenger) }
map.put("is_healer_in_use") { params ->
val pos = params.get<ArrayStruct>(0).asBlockPos()
val healer = entity.level().getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null) ?: return@put DoubleValue.ONE
return@put DoubleValue(healer.isInUse)
}
map.put("find_nearby_block") { params ->
val type = params.getString(0).asIdentifierDefaultingNamespace(namespace = "minecraft")
val isTag = type.path.startsWith("#")
@@ -516,7 +539,7 @@ object MoLangFunctions {
val distance = params.getDouble(0)
val entities = entity.level().getEntities(entity, AABB.ofSize(entity.position(), distance, distance, distance))
return@put entities
.filterIsInstance<LivingEntity>()
.filterIsInstance<Entity>()
.map { it.asMostSpecificMoLangValue() }
.asArrayValue()
}
@@ -573,6 +596,45 @@ object MoLangFunctions {
packet.sendToPlayer(player)
}
}
return@mutableListOf map
}
)
val livingEntityFunctions: MutableList<(LivingEntity) -> HashMap<String, java.util.function.Function<MoParams, Any>>> = mutableListOf<(LivingEntity) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
{ entity ->
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
map.put("is_living_entity") { DoubleValue.ONE }
map.put("is_flying") { _ -> DoubleValue(entity.isFallFlying) }
map.put("is_sleeping") { _ -> DoubleValue(entity.isSleeping) }
map.put("health") { _ -> DoubleValue(entity.health) }
map.put("max_health") { _ -> DoubleValue(entity.maxHealth) }
if (entity is PathfinderMob) {
map.put("walk_to") { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
val speedMultiplier = params.getDoubleOrNull(3) ?: 0.35
if (entity.brain.checkMemory(MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED)) {
entity.brain.setMemory(
MemoryModuleType.WALK_TARGET,
WalkTarget(Vec3(x, y, z), speedMultiplier.toFloat(), 1)
)
entity.brain.setMemory(
MemoryModuleType.LOOK_TARGET,
BlockPosTracker(Vec3(x, y + entity.eyeHeight, z))
)
} else {
entity.navigation.moveTo(x, y, z, speedMultiplier)
entity.lookControl.setLookAt(Vec3(x, y + entity.eyeHeight, z))
}
}
map.put("has_walk_target") { _ ->
DoubleValue(entity.brain.getMemory(MemoryModuleType.WALK_TARGET).isPresent || entity.isPathFinding)
}
}
map
}
)
@@ -691,6 +753,8 @@ object MoLangFunctions {
map.put("npc") { battleActor.entity.struct }
} else if (battleActor is PlayerBattleActor) {
map.put("player") { battleActor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
} else if (battleActor is PokemonBattleActor) {
map.put("pokemon") { battleActor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
}
return@mutableListOf map
}
@@ -729,6 +793,34 @@ object MoLangFunctions {
DoubleValue.ONE
}
map.put("owner") { pokemon.getOwnerPlayer()?.asMoLangValue() ?: DoubleValue.ZERO }
map.put("add_marks") { params ->
for (param in params.params) {
val identifier = param.asString().asIdentifierDefaultingNamespace()
val mark = Marks.getByIdentifier(identifier)
if (mark != null) pokemon.exchangeMark(mark, true)
}
}
map.put("add_marks_with_chance") { params ->
for (param in params.params) {
val identifier = param.asString().asIdentifierDefaultingNamespace()
val mark = Marks.getByIdentifier(identifier)
mark?.let {
val probability = it.chance.coerceIn(0F, 1F) * 100
val randomValue = Random.nextDouble(0.0, 100.0)
if (randomValue < probability) pokemon.exchangeMark(it, true)
}
}
}
map.put("add_potential_marks") { params ->
for (param in params.params) {
val identifier = param.asString().asIdentifierDefaultingNamespace()
val mark = Marks.getByIdentifier(identifier)
if (mark != null) pokemon.addPotentialMark(mark)
}
}
map.put("apply_potential_marks") {
return@put DoubleValue(pokemon.applyPotentialMarks())
}
map
}
)
@@ -739,8 +831,19 @@ object MoLangFunctions {
map.put("in_battle") { DoubleValue(pokemonEntity.isBattling) }
map.put("is_moving") { DoubleValue((pokemonEntity.moveControl as? PokemonMoveControl)?.hasWanted() == true) }
map.put("is_flying") { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
map.put("is_flying") { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
map.put("get_alt_pose") { StringValue(pokemonEntity.getAltPose()) }
map.put("is_gliding") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("gliding"))) }
map.put("is_sprinting") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("sprinting"))) }
map.put("in_air") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("in_air"))) }
map.put("is_ridden") { DoubleValue(pokemonEntity.hasControllingPassenger()) }
map.put("has_aspect") { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
map.put("is_pokemon") { DoubleValue.ONE }
map.put("is_holding_item") { DoubleValue(!pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).let {
it.isEmpty || it.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS) || it.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
}) }
map.put("is_wearing_hat") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS)) }
map.put("is_wearing_face") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)) }
map
}
)
@@ -748,6 +851,7 @@ object MoLangFunctions {
val pokemonStoreFunctions = mutableListOf<(PokemonStore<*>) -> HashMap<String, java.util.function.Function<MoParams, Any>>>(
{ store ->
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
map.put("uuid") { StringValue(store.uuid.toString()) }
map.put("add") { params ->
val pokemon = params.get<ObjectValue<Pokemon>>(0)
return@put DoubleValue(store.add(pokemon.obj))
@@ -848,6 +952,17 @@ object MoLangFunctions {
return@put DoubleValue.ONE
}
map.put("get_box_count") { _ -> DoubleValue(pc.boxes.size.toDouble()) }
map.put("has_unlocked_wallpaper") { params ->
val wallpaper = params.getString(0).asIdentifierDefaultingNamespace()
return@put DoubleValue(pc.unlockedWallpapers.contains(wallpaper))
}
map.put("get_unlocked_wallpapers") { pc.unlockedWallpapers.asArrayValue { StringValue(it.toString()) } }
map.put("unlock_wallpaper") {
val wallpaper = it.getString(0).asIdentifierDefaultingNamespace()
val playSound = it.getBooleanOrNull(1) != false
CobblemonUnlockableWallpapers.unlockableWallpapers[wallpaper] ?: return@put DoubleValue.ZERO
return@put DoubleValue(pc.unlockWallpaper(wallpaper, playSound))
}
return@mutableListOf map
}
)
@@ -856,7 +971,7 @@ object MoLangFunctions {
{ spawningContext ->
val map = hashMapOf<String, java.util.function.Function<MoParams, Any>>()
val worldValue = spawningContext.world.registryAccess().registryOrThrow(Registries.DIMENSION).wrapAsHolder(spawningContext.world).asWorldMoLangValue()
val biomeValue = spawningContext.biomeRegistry.wrapAsHolder(spawningContext.biome).asBiomeMoLangValue()
val biomeValue = spawningContext.biomeHolder.asBiomeMoLangValue()
map.put("biome") { _ -> biomeValue }
map.put("world") { _ -> worldValue }
map.put("light") { _ -> DoubleValue(spawningContext.light.toDouble()) }
@@ -1084,18 +1199,35 @@ object MoLangFunctions {
}
)
fun ItemStack.asMoLangValue(registryAccess: RegistryAccess) = ObjectValue(this).addStandardFunctions().addFunctions(itemStackFunctions.flatMap { it(this, registryAccess).entries.map { it.key to it.value } }.toMap())
fun Holder<Biome>.asBiomeMoLangValue() = asMoLangValue(Registries.BIOME).addFunctions(biomeFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
fun Holder<Level>.asWorldMoLangValue() = asMoLangValue(Registries.DIMENSION).addFunctions(worldFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
fun Holder<Block>.asBlockMoLangValue() = asMoLangValue(Registries.BLOCK).addFunctions(blockFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
fun MinecraftServer.asMoLangValue() = ObjectValue(this).addStandardFunctions().addFunctions(serverFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
fun Holder<DimensionType>.asDimensionTypeMoLangValue() = asMoLangValue(Registries.DIMENSION_TYPE).addFunctions(dimensionTypeFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
fun Player.asMoLangValue(): ObjectValue<Player> {
if (this is ServerPlayer && uuid in Cobblemon.serverPlayerStructs) {
val existing = Cobblemon.serverPlayerStructs[uuid]!!
if (existing.obj == this) {
return existing
} else {
Cobblemon.serverPlayerStructs.remove(uuid)
}
}
val value = ObjectValue(
obj = this,
stringify = { it.effectiveName().string }
)
value.addFunctions(entityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
value.addFunctions(livingEntityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
value.addFunctions(playerFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
if (this is ServerPlayer) {
Cobblemon.serverPlayerStructs[uuid] = value
}
return value
}
@@ -1150,6 +1282,7 @@ object MoLangFunctions {
stringify = { it.name.string }
)
value.addFunctions(entityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
value.addFunctions(livingEntityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
value.addFunctions(npcFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
return value
}
@@ -1160,6 +1293,7 @@ object MoLangFunctions {
stringify = { it.pokemon.uuid.toString() }
)
value.addFunctions(entityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
value.addFunctions(livingEntityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
value.addFunctions(pokemonFunctions.flatMap { it(this.pokemon).entries.map { it.key to it.value } }.toMap()) // Convenience
value.addFunctions(pokemonEntityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
return value
@@ -1195,12 +1329,18 @@ object MoLangFunctions {
/**
* Different functions exist depending on
*/
fun LivingEntity.asMostSpecificMoLangValue(): ObjectValue<out LivingEntity> {
fun Entity.asMostSpecificMoLangValue(): ObjectValue<out Entity> {
return when (this) {
is Player -> asMoLangValue()
is PokemonEntity -> struct
is NPCEntity -> struct
else -> ObjectValue(this).also { it.addStandardFunctions().addFunctions(entityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap()) }
else -> ObjectValue(this).also {
it.addStandardFunctions()
it.addFunctions(entityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
if (this is LivingEntity) {
it.addFunctions(livingEntityFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap())
}
}
}
}
@@ -1225,7 +1365,7 @@ object MoLangFunctions {
return this
}
fun QueryStruct.addEntityFunctions(entity: LivingEntity): QueryStruct {
fun QueryStruct.addEntityFunctions(entity: Entity): QueryStruct {
val addedFunctions = entityFunctions
.flatMap { it.invoke(entity).entries }
.associate { it.key to it.value }
@@ -1233,6 +1373,14 @@ object MoLangFunctions {
return this
}
fun QueryStruct.addLivingEntityFunctions(entity: LivingEntity): QueryStruct {
val addedFunctions = livingEntityFunctions
.flatMap { it.invoke(entity).entries }
.associate { it.key to it.value }
functions.putAll(addedFunctions)
return this
}
fun QueryStruct.addPokedexFunctions(pokedexManager: AbstractPokedexManager): QueryStruct {
val addedFunctions = pokedexFunctions
.flatMap { it.invoke(pokedexManager).entries }
@@ -1342,4 +1490,4 @@ object MoLangFunctions {
}
}
fun Either<ResourceLocation, ExpressionLike>.runScript(runtime: MoLangRuntime) = map({ CobblemonScripts.run(it, runtime) }, { it.resolve(runtime) })
fun Either<ResourceLocation, ExpressionLike>.runScript(runtime: MoLangRuntime) = map({ CobblemonScripts.run(it, runtime) }, { it.resolve(runtime) })
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common.api.moves
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.IntSize
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.readSizedInt
@@ -24,7 +23,7 @@ import net.minecraft.nbt.ListTag
import net.minecraft.network.RegistryFriendlyByteBuf
class BenchedMoves : Iterable<BenchedMove> {
val observable = SimpleObservable<BenchedMoves>()
var changeFunction: ((BenchedMoves) -> Unit) = {}
private var emit = true
private val benchedMoves = mutableListOf<BenchedMove>()
@@ -50,7 +49,7 @@ class BenchedMoves : Iterable<BenchedMove> {
fun update() {
if (emit) {
observable.emit(this)
changeFunction(this)
}
}
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.api.moves
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.net.IntSize
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.readSizedInt
@@ -24,7 +23,7 @@ import com.mojang.serialization.Codec
import kotlin.math.min
class MoveSet : Iterable<Move> {
val observable = SimpleObservable<MoveSet>()
var changeFunction: (MoveSet) -> Unit = {}
private var emit = true
private val moves = arrayOfNulls<Move>(MOVE_COUNT)
@@ -153,7 +152,7 @@ class MoveSet : Iterable<Move> {
fun update() {
if (emit) {
observable.emit(this)
changeFunction(this)
}
}
@@ -166,7 +166,7 @@ open class MoveTemplate(
// TODO: Handle Liquid Voice: need to know what moves have the sound flag
// TODO: Handle weatherball, naturalgift, judgement, technoblast, terrainpulse, and terrablast
if (this.elementalType == ElementalTypes.NORMAL) {
if( this.damageCategory != DamageCategories.STATUS) {
if (this.damageCategory != DamageCategories.STATUS) {
return when (pokemon.ability.name) {
"pixilate" -> ElementalTypes.FAIRY
"aerilate" -> ElementalTypes.FLYING
@@ -19,4 +19,4 @@ interface Decodable {
*/
fun decode(buffer: RegistryFriendlyByteBuf)
}
}
@@ -25,4 +25,4 @@ interface Encodable {
*/
fun encode(buffer: RegistryFriendlyByteBuf)
}
}
@@ -76,6 +76,8 @@ interface NetworkPacket<T: NetworkPacket<T>> : CustomPacketPayload, Encodable {
server.playerList.players.filter { player ->
if (exclusionCondition.invoke(player))
return@filter false
if (player.level().dimension() != worldKey)
return@filter false
val xDiff = x - player.x
val yDiff = y - player.y
val zDiff = z - player.z
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.net.serializers
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readString
import com.cobblemon.mod.common.util.writeString
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.codec.StreamCodec
import net.minecraft.network.syncher.EntityDataSerializer
object RideBoostsDataSerializer : EntityDataSerializer<Map<RidingStat, Float>> {
val ID = cobblemonResource("ride_boosts")
fun read(buf: RegistryFriendlyByteBuf): Map<RidingStat, Float> {
return buf.readMap(
{ RidingStat.valueOf(it.readString()) },
{ it.readFloat() }
)
}
override fun copy(value: Map<RidingStat, Float>) = value.toMap()
fun write(buf: RegistryFriendlyByteBuf, value: Map<RidingStat, Float>) {
buf.writeMap(
value,
{ _, it -> buf.writeString(it.name) },
{ _, it -> buf.writeFloat(it) }
)
}
override fun codec() = StreamCodec.of(::write, ::read)
}
@@ -0,0 +1,15 @@
/*
* 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.net.serializers
object RidingStateSerializer {
}
@@ -7,27 +7,31 @@
*/
package com.cobblemon.mod.common.api.npc.partyproviders
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon.LOGGER
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.npc.NPCPartyProvider
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.storage.party.NPCPartyStore
import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.util.asArrayValue
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.resolveFloat
import com.cobblemon.mod.common.util.resolveInt
import com.cobblemon.mod.common.util.weightedSelection
import com.cobblemon.mod.common.util.withQueryValue
import com.cobblemon.mod.common.util.*
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import kotlin.random.Random
import net.minecraft.server.level.ServerPlayer
import kotlin.collections.List
import kotlin.collections.any
import kotlin.collections.filter
import kotlin.collections.first
import kotlin.collections.mutableListOf
import kotlin.collections.mutableMapOf
import kotlin.collections.randomOrNull
import kotlin.collections.set
import kotlin.collections.toMutableList
import kotlin.random.Random
/**
* A provider of a party for battling the NPC. It generates a party using a more complex process
@@ -60,9 +64,9 @@ class PoolPartyProvider : NPCPartyProvider {
json as JsonObject
this.minPokemon = json.getAsJsonPrimitive("minPokemon").asString?.asExpression() ?: "1".asExpression()
this.maxPokemon = json.getAsJsonPrimitive("maxPokemon").asString?.asExpression() ?: "6".asExpression()
this.pool = json.getAsJsonArray("pool").map {
this.pool = json.getAsJsonArray("pool").mapNotNull {
if (it is JsonPrimitive) {
return@map DynamicPokemon(
return@mapNotNull DynamicPokemon(
PokemonProperties.parse(it.asString),
"0".asExpression(),
null,
@@ -73,17 +77,26 @@ class PoolPartyProvider : NPCPartyProvider {
}
it as JsonObject
DynamicPokemon(
PokemonProperties.parse(it.get("pokemon").asString),
it.get("levelVariation")?.asString?.asExpression() ?: "0".asExpression(),
it.get("level")?.asString?.asExpression(),
it.get("npcLevels")?.asString?.split("-")?.let { it[0].toInt()..it[1].toInt() } ?: 1..100,
it.get("selectableTimes")?.asString?.asExpression() ?: "1".asExpression(),
it.get("weight")?.asString?.asExpression() ?: "1".asExpression()
)
val properties = PokemonProperties.parse(it.get("pokemon").asString)
// Checks for errors on Pokémon name, if not a valid species ignores it to avoid random Pokémon in the Pool.
if (properties.species == null) {
LOGGER.warn("Error making NPC pokemon pool. ${it.get("pokemon").asString.substringBefore(" ")} is not a valid species, ignoring")
null
}
else {
DynamicPokemon(
properties,
it.get("levelVariation")?.asString?.asExpression() ?: "0".asExpression(),
it.get("level")?.asString?.asExpression(),
it.get("npcLevels")?.asString?.split("-")?.let { it[0].toInt()..it[1].toInt() } ?: 1..100,
it.get("selectableTimes")?.asString?.asExpression() ?: "1".asExpression(),
it.get("weight")?.asString?.asExpression() ?: "1".asExpression()
)
}
}.toMutableList()
isStatic = json.get("isStatic").asBoolean
json.get("useFixedRandom")?.asBoolean?.let { useFixedRandom = it }
}
class DynamicPokemon(
@@ -137,6 +150,10 @@ class PoolPartyProvider : NPCPartyProvider {
val instance = selected.pokemon.copy().also { it.level = it.level ?: dictatedLevel ?: randomLevel }.create()
party.add(instance)
}
if (party.none()) {
LOGGER.error("${npc} has no Pokemon on Party")
}
}
override fun provide(npc: NPCEntity, level: Int, players: List<ServerPlayer>): NPCPartyStore {
@@ -0,0 +1,123 @@
/*
* 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.orientation
import com.cobblemon.mod.common.util.math.geometry.toDegrees
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.Mth
import net.minecraft.world.entity.LivingEntity
import org.joml.Matrix3f
import org.joml.Quaternionf
import org.joml.Vector3f
import kotlin.math.asin
import kotlin.math.sign
open class OrientationController(val entity: LivingEntity) {
companion object {
val FORWARDS: Vector3f = Vector3f(0.0f, 0.0f, -1.0f)
val UP: Vector3f = Vector3f(0.0f, 1.0f, 0.0f)
val LEFT: Vector3f = Vector3f(-1.0f, 0.0f, 0.0f)
}
open var active: Boolean = false
var orientation: Matrix3f? = null
private set
private var renderOrientationO: Matrix3f? = null
private var renderOrientation: Matrix3f? = null
/** Adding this simply because it irritates me seeing `getActive` when most of this is Java. */
fun isActive() = active
fun updateOrientation(fn: (Matrix3f) -> Matrix3f?) {
if (!active) return
if (orientation == null) {
orientation = Matrix3f()
rotate(entity.yRot - 180, entity.xRot, 0f)
}
orientation = fn(orientation!!)
entity.yRot = yaw
entity.xRot = pitch
}
fun reset() {
orientation = null
renderOrientationO = null
renderOrientation = null
active = false
}
fun rotate(yaw: Float, pitch: Float, roll: Float) {
rotateYaw(yaw)
rotatePitch(pitch)
rotateRoll(roll)
}
fun getRenderOrientation(delta: Float): Quaternionf {
val old = renderOrientationO ?: renderOrientation ?: orientation
val new = renderOrientation ?: old
val oldQuat = Quaternionf().setFromUnnormalized(old)
val newQuat = Quaternionf().setFromUnnormalized(new)
oldQuat.slerp(newQuat, delta)
return oldQuat
}
fun tick() {
if (!active || orientation == null) return
renderOrientationO = renderOrientation
val current = orientation
val renderMatrix = this.renderOrientation ?: current
val renderQuat = Quaternionf().setFromUnnormalized(renderMatrix)
val targetQuat = Quaternionf().setFromUnnormalized(current)
val dampingFactor = 0.66f // We can change this factor for faster transitions
renderQuat.slerp(targetQuat, dampingFactor)
val newRenderOrientation = Matrix3f()
renderQuat.get(newRenderOrientation)
renderOrientation = newRenderOrientation
}
val forwardVector: Vector3f
get() = orientation?.transform(FORWARDS, Vector3f()) ?: Vector3f(FORWARDS)
val leftVector: Vector3f
get() = orientation?.transform(LEFT, Vector3f()) ?: Vector3f(LEFT)
val upVector : Vector3f
get() = orientation?.transform(UP, Vector3f()) ?: Vector3f(UP)
fun rotateYaw(yaw: Float) = updateOrientation { it.rotateY(-yaw.toRadians()) }
fun rotatePitch(pitch: Float) = updateOrientation { it.rotateX(-pitch.toRadians()) }
fun rotateRoll(roll: Float) = updateOrientation { it.rotateZ(-roll.toRadians()) }
val yaw: Float
get() = Mth.wrapDegrees(-FORWARDS.angleSigned(forwardVector, UP).toDegrees() + 180)
val pitch: Float
get() = Mth.wrapDegrees(-asin(forwardVector.y).toDegrees())
val roll: Float
get() = Mth.wrapDegrees(-upVector.angleSigned(UP, forwardVector).toDegrees())
fun applyGlobalYaw(deltaYawDegrees: Float) = updateOrientation { original ->
return@updateOrientation original.rotateLocalY(-deltaYawDegrees.toRadians())
}
fun applyGlobalPitch(deltaPitchDegrees: Float) = updateOrientation { original ->
val currQuat = Quaternionf().setFromUnnormalized(original)
val horzLeftVector = Vector3f(this.leftVector.x, 0.0f, this.leftVector.z)
val globalPitch = Quaternionf().fromAxisAngleRad(horzLeftVector.normalize(), -deltaPitchDegrees.toRadians())
val resultQuat = globalPitch.mul(currQuat)
return@updateOrientation Matrix3f().set(resultQuat)
}
}
@@ -13,80 +13,130 @@ object CobblemonPermissions {
private const val COMMAND_PREFIX = "command."
private val permissions = arrayListOf<Permission>()
@JvmStatic
val CHANGE_EYE_HEIGHT = this.create("${COMMAND_PREFIX}changeeyeheight", PermissionLevel.ALL_COMMANDS)
@JvmStatic
val CHANGE_SCALE_AND_SIZE = this.create("${COMMAND_PREFIX}changescaleandsize", PermissionLevel.ALL_COMMANDS)
@JvmStatic
val CHANGE_WALK_SPEED = this.create("${COMMAND_PREFIX}changewalkspeed", PermissionLevel.ALL_COMMANDS)
val CHANGE_JOINT_SCALE = this.create("${COMMAND_PREFIX}changejointscale", PermissionLevel.ALL_COMMANDS)
@JvmStatic
val TRANSFORM_MODEL_PART = this.create("${COMMAND_PREFIX}transformmodelpart", PermissionLevel.ALL_COMMANDS)
@JvmStatic
val CHECKSPAWNS = this.create("${COMMAND_PREFIX}checkspawns", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val GET_NBT = this.create("${COMMAND_PREFIX}getnbt", PermissionLevel.ALL_COMMANDS)
private const val GIVE_POKEMON_BASE = "${COMMAND_PREFIX}givepokemon"
@JvmStatic
val GIVE_POKEMON_SELF = this.create("${GIVE_POKEMON_BASE}.self", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val GIVE_POKEMON_OTHER = this.create("${GIVE_POKEMON_BASE}.other", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
private const val HEAL_POKEMON_BASE = "${COMMAND_PREFIX}healpokemon"
@JvmStatic
val HEAL_POKEMON_SELF = this.create("$HEAL_POKEMON_BASE.self", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val HEAL_POKEMON_OTHER = this.create("$HEAL_POKEMON_BASE.other", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
private const val LEVEL_UP_BASE = "${COMMAND_PREFIX}levelup"
@JvmStatic
val LEVEL_UP_SELF = this.create("$LEVEL_UP_BASE.self", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val LEVEL_UP_OTHER = this.create("$LEVEL_UP_BASE.other", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val OPEN_STARTER_SCREEN = this.create("${COMMAND_PREFIX}openstarterscreen", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val BEDROCK_PARTICLE = this.create("${COMMAND_PREFIX}bedrockparticle", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val OPEN_DIALOGUE = this.create("${COMMAND_PREFIX}opendialogue", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val UNLOCK_PC_BOX_WALLPAPER = this.create("${COMMAND_PREFIX}unlockpcboxwallpaper", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
private const val POKEMON_EDIT_BASE = "${COMMAND_PREFIX}pokemonedit"
@JvmStatic
val POKEMON_EDIT_SELF = this.create("$POKEMON_EDIT_BASE.self", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val POKEMON_EDIT_OTHER = this.create("$POKEMON_EDIT_BASE.other", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val SPAWN_ALL_POKEMON = this.create("${COMMAND_PREFIX}spawnallpokemon", PermissionLevel.ALL_COMMANDS)
@JvmStatic
val GIVE_ALL_POKEMON = this.create("${COMMAND_PREFIX}giveallpokemon", PermissionLevel.ALL_COMMANDS)
@JvmStatic
val SPAWN_POKEMON = this.create("${COMMAND_PREFIX}spawnpokemon", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val SPAWN_NPC = this.create("${COMMAND_PREFIX}spawnnpc", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val STOP_BATTLE = this.create("${COMMAND_PREFIX}stopbattle", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val TAKE_POKEMON = this.create("${COMMAND_PREFIX}takepokemon", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val TEACH = this.create("${COMMAND_PREFIX}teach.base", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val TEACH_BYPASS_LEARNSET = this.create("${COMMAND_PREFIX}teach.bypass", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val FRIENDSHIP = this.create("${COMMAND_PREFIX}friendship", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val HELD_ITEM = this.create("${COMMAND_PREFIX}helditem", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
val PC = this.create("${COMMAND_PREFIX}pc", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val CHANGE_MARK = this.create("${COMMAND_PREFIX}changemark", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val PC = this.create("${COMMAND_PREFIX}pc", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val POKEBOX = this.create("${COMMAND_PREFIX}pokebox", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val RENAMEBOX = this.create("${COMMAND_PREFIX}renamebox", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val CHANGE_WALLPAPER = this.create("${COMMAND_PREFIX}changewallpaper", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val TEST_STORE = this.create("${COMMAND_PREFIX}teststore", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val QUERY_LEARNSET = this.create("${COMMAND_PREFIX}querylearnset", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val TEST_PC_SLOT = this.create("${COMMAND_PREFIX}testpcslot", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val TEST_PARTY_SLOT = this.create("${COMMAND_PREFIX}testpartyslot", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val CLEAR_PARTY = this.create("${COMMAND_PREFIX}clearparty", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val CLEAR_PC = this.create("${COMMAND_PREFIX}clearpc", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val POKEDEX = this.create("${COMMAND_PREFIX}pokedex", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val NPC_EDIT = this.create("${COMMAND_PREFIX}npcedit", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val NPC_DELETE = this.create("${COMMAND_PREFIX}npcdelete", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val FREEZE_POKEMON = this.create("${COMMAND_PREFIX}freezepokemon", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val APPLY_PLAYER_TEXTURE = this.create("${COMMAND_PREFIX}applyplayertexture", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val ABANDON_MULTITEAM = this.create("${COMMAND_PREFIX}abandonmultiteam", PermissionLevel.NONE)
@JvmStatic
val RUN_MOLANG_SCRIPT = this.create("${COMMAND_PREFIX}runmolangscript", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val COBBLEMON_CONFIG_RELOAD = this.create("${COMMAND_PREFIX}cobblemonconfig.reload", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val CALCULATE_SEAT_POSITIONS = this.create("${COMMAND_PREFIX}calculateseatpositions", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val CHANGE_BOX_COUNT = this.create("${COMMAND_PREFIX}boxcount", PermissionLevel.CHEAT_COMMANDS_AND_COMMAND_BLOCKS)
@JvmStatic
val SPECTATE_BATTLE = this.create("${COMMAND_PREFIX}spectatebattle", PermissionLevel.ALL_COMMANDS)
fun all(): Iterable<Permission> = this.permissions

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